Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(300)

Side by Side Diff: ui/views/controls/textfield/textfield.cc

Issue 2408623002: Views: Extract text selection code from Textfield. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/controls/textfield/textfield.h" 5 #include "ui/views/controls/textfield/textfield.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/trace_event/trace_event.h" 10 #include "base/trace_event/trace_event.h"
(...skipping 22 matching lines...) Expand all
33 #include "ui/native_theme/native_theme.h" 33 #include "ui/native_theme/native_theme.h"
34 #include "ui/strings/grit/ui_strings.h" 34 #include "ui/strings/grit/ui_strings.h"
35 #include "ui/views/background.h" 35 #include "ui/views/background.h"
36 #include "ui/views/controls/focus_ring.h" 36 #include "ui/views/controls/focus_ring.h"
37 #include "ui/views/controls/focusable_border.h" 37 #include "ui/views/controls/focusable_border.h"
38 #include "ui/views/controls/label.h" 38 #include "ui/views/controls/label.h"
39 #include "ui/views/controls/menu/menu_runner.h" 39 #include "ui/views/controls/menu/menu_runner.h"
40 #include "ui/views/controls/native/native_view_host.h" 40 #include "ui/views/controls/native/native_view_host.h"
41 #include "ui/views/controls/textfield/textfield_controller.h" 41 #include "ui/views/controls/textfield/textfield_controller.h"
42 #include "ui/views/drag_utils.h" 42 #include "ui/views/drag_utils.h"
43 #include "ui/views/metrics.h"
44 #include "ui/views/native_cursor.h" 43 #include "ui/views/native_cursor.h"
45 #include "ui/views/painter.h" 44 #include "ui/views/painter.h"
45 #include "ui/views/selection_controller.h"
46 #include "ui/views/style/platform_style.h" 46 #include "ui/views/style/platform_style.h"
47 #include "ui/views/views_delegate.h" 47 #include "ui/views/views_delegate.h"
48 #include "ui/views/widget/widget.h" 48 #include "ui/views/widget/widget.h"
49 49
50 #if defined(OS_WIN) 50 #if defined(OS_WIN)
51 #include "base/win/win_util.h" 51 #include "base/win/win_util.h"
52 #include "ui/base/win/osk_display_manager.h" 52 #include "ui/base/win/osk_display_manager.h"
53 #endif 53 #endif
54 54
55 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 55 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
(...skipping 22 matching lines...) Expand all
78 const SkColor kDefaultPlaceholderTextColor = SK_ColorLTGRAY; 78 const SkColor kDefaultPlaceholderTextColor = SK_ColorLTGRAY;
79 79
80 void ConvertRectToScreen(const View* src, gfx::Rect* r) { 80 void ConvertRectToScreen(const View* src, gfx::Rect* r) {
81 DCHECK(src); 81 DCHECK(src);
82 82
83 gfx::Point new_origin = r->origin(); 83 gfx::Point new_origin = r->origin();
84 View::ConvertPointToScreen(src, &new_origin); 84 View::ConvertPointToScreen(src, &new_origin);
85 r->set_origin(new_origin); 85 r->set_origin(new_origin);
86 } 86 }
87 87
88 // Get the drag selection timer delay, respecting animation scaling for testing.
89 int GetDragSelectionDelay() {
90 switch (ui::ScopedAnimationDurationScaleMode::duration_scale_mode()) {
91 case ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION: return 100;
92 case ui::ScopedAnimationDurationScaleMode::FAST_DURATION: return 25;
93 case ui::ScopedAnimationDurationScaleMode::SLOW_DURATION: return 400;
94 case ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION: return 1;
95 case ui::ScopedAnimationDurationScaleMode::ZERO_DURATION: return 0;
96 }
97 return 100;
98 }
99
100 // Get the default command for a given key |event|. 88 // Get the default command for a given key |event|.
101 ui::TextEditCommand GetCommandForKeyEvent(const ui::KeyEvent& event) { 89 ui::TextEditCommand GetCommandForKeyEvent(const ui::KeyEvent& event) {
102 if (event.type() != ui::ET_KEY_PRESSED || event.IsUnicodeKeyCode()) 90 if (event.type() != ui::ET_KEY_PRESSED || event.IsUnicodeKeyCode())
103 return ui::TextEditCommand::INVALID_COMMAND; 91 return ui::TextEditCommand::INVALID_COMMAND;
104 92
105 const bool shift = event.IsShiftDown(); 93 const bool shift = event.IsShiftDown();
106 const bool control = event.IsControlDown(); 94 const bool control = event.IsControlDown();
107 const bool alt = event.IsAltDown() || event.IsAltGrDown(); 95 const bool alt = event.IsAltDown() || event.IsAltGrDown();
108 switch (event.key_code()) { 96 switch (event.key_code()) {
109 case ui::VKEY_Z: 97 case ui::VKEY_Z:
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 selection_text_color_(SK_ColorWHITE), 240 selection_text_color_(SK_ColorWHITE),
253 selection_background_color_(SK_ColorBLUE), 241 selection_background_color_(SK_ColorBLUE),
254 placeholder_text_color_(kDefaultPlaceholderTextColor), 242 placeholder_text_color_(kDefaultPlaceholderTextColor),
255 invalid_(false), 243 invalid_(false),
256 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT), 244 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT),
257 text_input_flags_(0), 245 text_input_flags_(0),
258 performing_user_action_(false), 246 performing_user_action_(false),
259 skip_input_method_cancel_composition_(false), 247 skip_input_method_cancel_composition_(false),
260 drop_cursor_visible_(false), 248 drop_cursor_visible_(false),
261 initiating_drag_(false), 249 initiating_drag_(false),
262 aggregated_clicks_(0), 250 selection_controller_(new SelectionController(this)),
263 drag_start_display_offset_(0), 251 drag_start_display_offset_(0),
264 touch_handles_hidden_due_to_scroll_(false), 252 touch_handles_hidden_due_to_scroll_(false),
265 use_focus_ring_(ui::MaterialDesignController::IsSecondaryUiMaterial()), 253 use_focus_ring_(ui::MaterialDesignController::IsSecondaryUiMaterial()),
266 weak_ptr_factory_(this) { 254 weak_ptr_factory_(this) {
267 set_context_menu_controller(this); 255 set_context_menu_controller(this);
268 set_drag_controller(this); 256 set_drag_controller(this);
269 GetRenderText()->SetFontList(GetDefaultFontList()); 257 GetRenderText()->SetFontList(GetDefaultFontList());
270 View::SetBorder(std::unique_ptr<Border>(new FocusableBorder())); 258 View::SetBorder(std::unique_ptr<Border>(new FocusableBorder()));
271 SetFocusBehavior(FocusBehavior::ALWAYS); 259 SetFocusBehavior(FocusBehavior::ALWAYS);
272 260
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 model_->InsertText(new_text); 316 model_->InsertText(new_text);
329 UpdateAfterChange(true, true); 317 UpdateAfterChange(true, true);
330 } 318 }
331 319
332 base::string16 Textfield::GetSelectedText() const { 320 base::string16 Textfield::GetSelectedText() const {
333 return model_->GetSelectedText(); 321 return model_->GetSelectedText();
334 } 322 }
335 323
336 void Textfield::SelectAll(bool reversed) { 324 void Textfield::SelectAll(bool reversed) {
337 model_->SelectAll(reversed); 325 model_->SelectAll(reversed);
338 UpdateSelectionClipboard(); 326 if (HasSelection() && performing_user_action_)
327 UpdateSelectionClipboard();
339 UpdateAfterChange(false, true); 328 UpdateAfterChange(false, true);
340 } 329 }
341 330
342 void Textfield::SelectWordAt(const gfx::Point& point) { 331 void Textfield::SelectWordAt(const gfx::Point& point) {
343 model_->MoveCursorTo(point, false); 332 model_->MoveCursorTo(point, false);
344 model_->SelectWord(); 333 model_->SelectWord();
345 UpdateAfterChange(false, true); 334 UpdateAfterChange(false, true);
346 } 335 }
347 336
348 void Textfield::ClearSelection() { 337 void Textfield::ClearSelection() {
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 } 527 }
539 528
540 void Textfield::ClearEditHistory() { 529 void Textfield::ClearEditHistory() {
541 model_->ClearEditHistory(); 530 model_->ClearEditHistory();
542 } 531 }
543 532
544 void Textfield::SetAccessibleName(const base::string16& name) { 533 void Textfield::SetAccessibleName(const base::string16& name) {
545 accessible_name_ = name; 534 accessible_name_ = name;
546 } 535 }
547 536
548 bool Textfield::HasTextBeingDragged() {
549 return initiating_drag_;
550 }
551
552 //////////////////////////////////////////////////////////////////////////////// 537 ////////////////////////////////////////////////////////////////////////////////
553 // Textfield, View overrides: 538 // Textfield, View overrides:
554 539
555 gfx::Insets Textfield::GetInsets() const { 540 gfx::Insets Textfield::GetInsets() const {
556 gfx::Insets insets = View::GetInsets(); 541 gfx::Insets insets = View::GetInsets();
557 insets += gfx::Insets(kTextPadding, kTextPadding, kTextPadding, kTextPadding); 542 insets += gfx::Insets(kTextPadding, kTextPadding, kTextPadding, kTextPadding);
558 return insets; 543 return insets;
559 } 544 }
560 545
561 int Textfield::GetBaseline() const { 546 int Textfield::GetBaseline() const {
(...skipping 18 matching lines...) Expand all
580 } 565 }
581 566
582 gfx::NativeCursor Textfield::GetCursor(const ui::MouseEvent& event) { 567 gfx::NativeCursor Textfield::GetCursor(const ui::MouseEvent& event) {
583 bool in_selection = GetRenderText()->IsPointInSelection(event.location()); 568 bool in_selection = GetRenderText()->IsPointInSelection(event.location());
584 bool drag_event = event.type() == ui::ET_MOUSE_DRAGGED; 569 bool drag_event = event.type() == ui::ET_MOUSE_DRAGGED;
585 bool text_cursor = !initiating_drag_ && (drag_event || !in_selection); 570 bool text_cursor = !initiating_drag_ && (drag_event || !in_selection);
586 return text_cursor ? GetNativeIBeamCursor() : gfx::kNullCursor; 571 return text_cursor ? GetNativeIBeamCursor() : gfx::kNullCursor;
587 } 572 }
588 573
589 bool Textfield::OnMousePressed(const ui::MouseEvent& event) { 574 bool Textfield::OnMousePressed(const ui::MouseEvent& event) {
590 TrackMouseClicks(event); 575 bool handled = controller_ && controller_->HandleMouseEvent(this, event);
591 576 if (!handled &&
592 if (!controller_ || !controller_->HandleMouseEvent(this, event)) { 577 (event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton())) {
593 if (event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton()) { 578 RequestFocus();
594 RequestFocus(); 579 ShowImeIfNeeded();
595 ShowImeIfNeeded(); 580 }
596 }
597
598 if (event.IsOnlyLeftMouseButton()) {
599 OnBeforeUserAction();
600 initiating_drag_ = false;
601 switch (aggregated_clicks_) {
602 case 0:
603 if (GetRenderText()->IsPointInSelection(event.location()))
604 initiating_drag_ = true;
605 else
606 MoveCursorTo(event.location(), event.IsShiftDown());
607 break;
608 case 1:
609 SelectWordAt(event.location());
610 double_click_word_ = GetRenderText()->selection();
611 break;
612 case 2:
613 SelectAll(false);
614 break;
615 default:
616 NOTREACHED();
617 }
618 OnAfterUserAction();
619 }
620 581
621 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 582 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
622 if (event.IsOnlyMiddleMouseButton()) { 583 if (!handled && !HasFocus() && event.IsOnlyMiddleMouseButton())
623 if (GetRenderText()->IsPointInSelection(event.location())) { 584 RequestFocus();
624 OnBeforeUserAction();
625 ClearSelection();
626 ui::ScopedClipboardWriter(
627 ui::CLIPBOARD_TYPE_SELECTION).WriteText(base::string16());
628 OnAfterUserAction();
629 } else if (!read_only()) {
630 PasteSelectionClipboard(event);
631 }
632 }
633 #endif 585 #endif
634 }
635 586
636 return true; 587 return selection_controller_->OnMousePressed(event, handled);
637 } 588 }
638 589
639 bool Textfield::OnMouseDragged(const ui::MouseEvent& event) { 590 bool Textfield::OnMouseDragged(const ui::MouseEvent& event) {
640 last_drag_location_ = event.location(); 591 return selection_controller_->OnMouseDragged(event);
641
642 // Don't adjust the cursor on a potential drag and drop.
643 if (initiating_drag_ || !event.IsOnlyLeftMouseButton())
644 return true;
645
646 // A timer is used to continuously scroll while selecting beyond side edges.
647 const int x = event.location().x();
648 if ((x >= 0 && x <= width()) || GetDragSelectionDelay() == 0) {
649 drag_selection_timer_.Stop();
650 SelectThroughLastDragLocation();
651 } else if (!drag_selection_timer_.IsRunning()) {
652 // Select through the edge of the visible text, then start the scroll timer.
653 last_drag_location_.set_x(std::min(std::max(0, x), width()));
654 SelectThroughLastDragLocation();
655 drag_selection_timer_.Start(
656 FROM_HERE, base::TimeDelta::FromMilliseconds(GetDragSelectionDelay()),
657 this, &Textfield::SelectThroughLastDragLocation);
658 }
659
660 return true;
661 } 592 }
662 593
663 void Textfield::OnMouseReleased(const ui::MouseEvent& event) { 594 void Textfield::OnMouseReleased(const ui::MouseEvent& event) {
664 OnBeforeUserAction(); 595 selection_controller_->OnMouseReleased(event);
665 drag_selection_timer_.Stop();
666 // Cancel suspected drag initiations, the user was clicking in the selection.
667 if (initiating_drag_)
668 MoveCursorTo(event.location(), false);
669 initiating_drag_ = false;
670 UpdateSelectionClipboard();
671 OnAfterUserAction();
672 } 596 }
673 597
674 WordLookupClient* Textfield::GetWordLookupClient() { 598 WordLookupClient* Textfield::GetWordLookupClient() {
675 return this; 599 return this;
676 } 600 }
677 601
678 bool Textfield::OnKeyPressed(const ui::KeyEvent& event) { 602 bool Textfield::OnKeyPressed(const ui::KeyEvent& event) {
679 ui::TextEditCommand edit_command = scheduled_text_edit_command_; 603 ui::TextEditCommand edit_command = scheduled_text_edit_command_;
680 scheduled_text_edit_command_ = ui::TextEditCommand::INVALID_COMMAND; 604 scheduled_text_edit_command_ = ui::TextEditCommand::INVALID_COMMAND;
681 605
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 // Textfield, WordLookupClient overrides: 1053 // Textfield, WordLookupClient overrides:
1130 1054
1131 bool Textfield::GetDecoratedWordAtPoint(const gfx::Point& point, 1055 bool Textfield::GetDecoratedWordAtPoint(const gfx::Point& point,
1132 gfx::DecoratedText* decorated_word, 1056 gfx::DecoratedText* decorated_word,
1133 gfx::Point* baseline_point) { 1057 gfx::Point* baseline_point) {
1134 return GetRenderText()->GetDecoratedWordAtPoint(point, decorated_word, 1058 return GetRenderText()->GetDecoratedWordAtPoint(point, decorated_word,
1135 baseline_point); 1059 baseline_point);
1136 } 1060 }
1137 1061
1138 //////////////////////////////////////////////////////////////////////////////// 1062 ////////////////////////////////////////////////////////////////////////////////
1063 // Textfield, SelectionControllerDelegate overrides:
1064
1065 bool Textfield::HasTextBeingDragged() const {
1066 return initiating_drag_;
1067 }
1068
1069 ////////////////////////////////////////////////////////////////////////////////
1139 // Textfield, ui::TouchEditable overrides: 1070 // Textfield, ui::TouchEditable overrides:
1140 1071
1141 void Textfield::SelectRect(const gfx::Point& start, const gfx::Point& end) { 1072 void Textfield::SelectRect(const gfx::Point& start, const gfx::Point& end) {
1142 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) 1073 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE)
1143 return; 1074 return;
1144 1075
1145 gfx::SelectionModel start_caret = GetRenderText()->FindCursorPosition(start); 1076 gfx::SelectionModel start_caret = GetRenderText()->FindCursorPosition(start);
1146 gfx::SelectionModel end_caret = GetRenderText()->FindCursorPosition(end); 1077 gfx::SelectionModel end_caret = GetRenderText()->FindCursorPosition(end);
1147 gfx::SelectionModel selection( 1078 gfx::SelectionModel selection(
1148 gfx::Range(start_caret.caret_pos(), end_caret.caret_pos()), 1079 gfx::Range(start_caret.caret_pos(), end_caret.caret_pos()),
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
1594 skip_input_method_cancel_composition_ = false; 1525 skip_input_method_cancel_composition_ = false;
1595 1526
1596 UpdateAfterChange(true, true); 1527 UpdateAfterChange(true, true);
1597 OnAfterUserAction(); 1528 OnAfterUserAction();
1598 } 1529 }
1599 1530
1600 gfx::RenderText* Textfield::GetRenderText() const { 1531 gfx::RenderText* Textfield::GetRenderText() const {
1601 return model_->render_text(); 1532 return model_->render_text();
1602 } 1533 }
1603 1534
1535 gfx::Point Textfield::GetLastClickLocation() const {
1536 return selection_controller_->last_click_location();
1537 }
1538
1604 base::string16 Textfield::GetSelectionClipboardText() const { 1539 base::string16 Textfield::GetSelectionClipboardText() const {
1605 base::string16 selection_clipboard_text; 1540 base::string16 selection_clipboard_text;
1606 ui::Clipboard::GetForCurrentThread()->ReadText( 1541 ui::Clipboard::GetForCurrentThread()->ReadText(
1607 ui::CLIPBOARD_TYPE_SELECTION, &selection_clipboard_text); 1542 ui::CLIPBOARD_TYPE_SELECTION, &selection_clipboard_text);
1608 return selection_clipboard_text; 1543 return selection_clipboard_text;
1609 } 1544 }
1610 1545
1611 void Textfield::ExecuteTextEditCommand(ui::TextEditCommand command) { 1546 void Textfield::ExecuteTextEditCommand(ui::TextEditCommand command) {
1612 DestroyTouchSelection(); 1547 DestroyTouchSelection();
1613 1548
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1792 break; 1727 break;
1793 case ui::TextEditCommand::INSERT_TEXT: 1728 case ui::TextEditCommand::INSERT_TEXT:
1794 case ui::TextEditCommand::SET_MARK: 1729 case ui::TextEditCommand::SET_MARK:
1795 case ui::TextEditCommand::UNSELECT: 1730 case ui::TextEditCommand::UNSELECT:
1796 case ui::TextEditCommand::INVALID_COMMAND: 1731 case ui::TextEditCommand::INVALID_COMMAND:
1797 NOTREACHED(); 1732 NOTREACHED();
1798 break; 1733 break;
1799 } 1734 }
1800 1735
1801 cursor_changed |= GetSelectionModel() != selection_model; 1736 cursor_changed |= GetSelectionModel() != selection_model;
1802 if (cursor_changed) 1737 if (cursor_changed && HasSelection())
1803 UpdateSelectionClipboard(); 1738 UpdateSelectionClipboard();
1804 UpdateAfterChange(text_changed, cursor_changed); 1739 UpdateAfterChange(text_changed, cursor_changed);
1805 OnAfterUserAction(); 1740 OnAfterUserAction();
1806 } 1741 }
1807 1742
1808 //////////////////////////////////////////////////////////////////////////////// 1743 ////////////////////////////////////////////////////////////////////////////////
1809 // Textfield, private: 1744 // Textfield, private:
1810 1745
1746 ////////////////////////////////////////////////////////////////////////////////
1747 // Textfield, SelectionControllerDelegate overrides:
1748
1749 gfx::RenderText* Textfield::GetRenderTextForSelectionController() {
1750 return GetRenderText();
1751 }
1752
1753 bool Textfield::IsReadOnly() const {
1754 return read_only();
1755 }
1756
1757 void Textfield::SetTextBeingDragged(bool value) {
1758 initiating_drag_ = value;
1759 }
1760
1761 int Textfield::GetViewHeight() const {
1762 return height();
1763 }
1764
1765 int Textfield::GetViewWidth() const {
1766 return width();
1767 }
1768
1769 int Textfield::GetDragSelectionDelay() const {
1770 switch (ui::ScopedAnimationDurationScaleMode::duration_scale_mode()) {
1771 case ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION:
1772 return 100;
1773 case ui::ScopedAnimationDurationScaleMode::FAST_DURATION:
1774 return 25;
1775 case ui::ScopedAnimationDurationScaleMode::SLOW_DURATION:
1776 return 400;
1777 case ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION:
1778 return 1;
1779 case ui::ScopedAnimationDurationScaleMode::ZERO_DURATION:
1780 return 0;
1781 }
1782 return 100;
1783 }
1784
1785 void Textfield::OnBeforeMouseAction() {
1786 OnBeforeUserAction();
1787 if (model_->HasCompositionText())
1788 model_->ConfirmCompositionText();
1789 }
1790
1791 void Textfield::OnAfterMouseAction(bool text_changed, bool selection_changed) {
1792 OnAfterUserAction();
1793 UpdateAfterChange(text_changed, selection_changed);
1794 }
1795
1796 bool Textfield::PasteSelectionClipboard() {
1797 DCHECK(performing_user_action_);
1798 DCHECK(!read_only());
1799 const base::string16 selection_clipboard_text = GetSelectionClipboardText();
1800 if (selection_clipboard_text.empty())
1801 return false;
1802
1803 model_->InsertText(selection_clipboard_text);
1804 return true;
1805 }
1806
1807 void Textfield::UpdateSelectionClipboard() {
1808 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
1809 if (text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD) {
1810 ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_SELECTION)
1811 .WriteText(GetSelectedText());
1812 if (controller_)
1813 controller_->OnAfterCutOrCopy(ui::CLIPBOARD_TYPE_SELECTION);
1814 }
1815 #endif
1816 }
1817
1811 void Textfield::AccessibilitySetValue(const base::string16& new_value) { 1818 void Textfield::AccessibilitySetValue(const base::string16& new_value) {
1812 if (!read_only()) { 1819 if (!read_only()) {
1813 SetText(new_value); 1820 SetText(new_value);
1814 ClearSelection(); 1821 ClearSelection();
1815 } 1822 }
1816 } 1823 }
1817 1824
1818 void Textfield::UpdateBackgroundColor() { 1825 void Textfield::UpdateBackgroundColor() {
1819 const SkColor color = GetBackgroundColor(); 1826 const SkColor color = GetBackgroundColor();
1820 if (ui::MaterialDesignController::IsSecondaryUiMaterial()) { 1827 if (ui::MaterialDesignController::IsSecondaryUiMaterial()) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1891 render_text->DrawCursor(canvas, drop_cursor_position_); 1898 render_text->DrawCursor(canvas, drop_cursor_position_);
1892 1899
1893 canvas->Restore(); 1900 canvas->Restore();
1894 } 1901 }
1895 1902
1896 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) { 1903 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) {
1897 if (model_->MoveCursorTo(point, select)) 1904 if (model_->MoveCursorTo(point, select))
1898 UpdateAfterChange(false, true); 1905 UpdateAfterChange(false, true);
1899 } 1906 }
1900 1907
1901 void Textfield::SelectThroughLastDragLocation() {
1902 OnBeforeUserAction();
1903
1904 const bool drags_to_end = PlatformStyle::kTextfieldDragVerticallyDragsToEnd;
1905 if (drags_to_end && last_drag_location_.y() < 0) {
1906 model_->MoveCursor(gfx::BreakType::LINE_BREAK,
1907 gfx::VisualCursorDirection::CURSOR_LEFT,
1908 gfx::SELECTION_RETAIN);
1909 } else if (drags_to_end && last_drag_location_.y() > height()) {
1910 model_->MoveCursor(gfx::BreakType::LINE_BREAK,
1911 gfx::VisualCursorDirection::CURSOR_RIGHT,
1912 gfx::SELECTION_RETAIN);
1913 } else {
1914 model_->MoveCursorTo(last_drag_location_, true);
1915 }
1916
1917 if (aggregated_clicks_ == 1) {
1918 model_->SelectWord();
1919 // Expand the selection so the initially selected word remains selected.
1920 gfx::Range selection = GetRenderText()->selection();
1921 const size_t min = std::min(selection.GetMin(),
1922 double_click_word_.GetMin());
1923 const size_t max = std::max(selection.GetMax(),
1924 double_click_word_.GetMax());
1925 const bool reversed = selection.is_reversed();
1926 selection.set_start(reversed ? max : min);
1927 selection.set_end(reversed ? min : max);
1928 model_->SelectRange(selection);
1929 }
1930 UpdateAfterChange(false, true);
1931 OnAfterUserAction();
1932 }
1933
1934 void Textfield::OnCaretBoundsChanged() { 1908 void Textfield::OnCaretBoundsChanged() {
1935 if (GetInputMethod()) 1909 if (GetInputMethod())
1936 GetInputMethod()->OnCaretBoundsChanged(this); 1910 GetInputMethod()->OnCaretBoundsChanged(this);
1937 if (touch_selection_controller_) 1911 if (touch_selection_controller_)
1938 touch_selection_controller_->SelectionChanged(); 1912 touch_selection_controller_->SelectionChanged();
1939 } 1913 }
1940 1914
1941 void Textfield::OnBeforeUserAction() { 1915 void Textfield::OnBeforeUserAction() {
1942 DCHECK(!performing_user_action_); 1916 DCHECK(!performing_user_action_);
1943 performing_user_action_ = true; 1917 performing_user_action_ = true;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1997 // IsCommandIdEnabled() as appropriate, for the commands added. 1971 // IsCommandIdEnabled() as appropriate, for the commands added.
1998 if (controller_) 1972 if (controller_)
1999 controller_->UpdateContextMenu(context_menu_contents_.get()); 1973 controller_->UpdateContextMenu(context_menu_contents_.get());
2000 } 1974 }
2001 context_menu_runner_.reset(new MenuRunner(context_menu_contents_.get(), 1975 context_menu_runner_.reset(new MenuRunner(context_menu_contents_.get(),
2002 MenuRunner::HAS_MNEMONICS | 1976 MenuRunner::HAS_MNEMONICS |
2003 MenuRunner::CONTEXT_MENU | 1977 MenuRunner::CONTEXT_MENU |
2004 MenuRunner::ASYNC)); 1978 MenuRunner::ASYNC));
2005 } 1979 }
2006 1980
2007 void Textfield::TrackMouseClicks(const ui::MouseEvent& event) {
2008 if (event.IsOnlyLeftMouseButton()) {
2009 base::TimeDelta time_delta = event.time_stamp() - last_click_time_;
2010 if (!last_click_time_.is_null() &&
2011 time_delta.InMilliseconds() <= GetDoubleClickInterval() &&
2012 !ExceededDragThreshold(event.location() - last_click_location_)) {
2013 // Upon clicking after a triple click, the count should go back to double
2014 // click and alternate between double and triple. This assignment maps
2015 // 0 to 1, 1 to 2, 2 to 1.
2016 aggregated_clicks_ = (aggregated_clicks_ % 2) + 1;
2017 } else {
2018 aggregated_clicks_ = 0;
2019 }
2020 last_click_time_ = event.time_stamp();
2021 last_click_location_ = event.location();
2022 }
2023 }
2024
2025 bool Textfield::ImeEditingAllowed() const { 1981 bool Textfield::ImeEditingAllowed() const {
2026 // Disallow input method editing of password fields. 1982 // Disallow input method editing of password fields.
2027 ui::TextInputType t = GetTextInputType(); 1983 ui::TextInputType t = GetTextInputType();
2028 return (t != ui::TEXT_INPUT_TYPE_NONE && t != ui::TEXT_INPUT_TYPE_PASSWORD); 1984 return (t != ui::TEXT_INPUT_TYPE_NONE && t != ui::TEXT_INPUT_TYPE_PASSWORD);
2029 } 1985 }
2030 1986
2031 void Textfield::RevealPasswordChar(int index) { 1987 void Textfield::RevealPasswordChar(int index) {
2032 GetRenderText()->SetObscuredRevealIndex(index); 1988 GetRenderText()->SetObscuredRevealIndex(index);
2033 SchedulePaint(); 1989 SchedulePaint();
2034 1990
2035 if (index != -1) { 1991 if (index != -1) {
2036 password_reveal_timer_.Start(FROM_HERE, GetPasswordRevealDuration(), 1992 password_reveal_timer_.Start(FROM_HERE, GetPasswordRevealDuration(),
2037 base::Bind(&Textfield::RevealPasswordChar, 1993 base::Bind(&Textfield::RevealPasswordChar,
2038 weak_ptr_factory_.GetWeakPtr(), -1)); 1994 weak_ptr_factory_.GetWeakPtr(), -1));
2039 } 1995 }
2040 } 1996 }
2041 1997
2042 void Textfield::CreateTouchSelectionControllerAndNotifyIt() { 1998 void Textfield::CreateTouchSelectionControllerAndNotifyIt() {
2043 if (!HasFocus()) 1999 if (!HasFocus())
2044 return; 2000 return;
2045 2001
2046 if (!touch_selection_controller_) { 2002 if (!touch_selection_controller_) {
2047 touch_selection_controller_.reset( 2003 touch_selection_controller_.reset(
2048 ui::TouchEditingControllerDeprecated::Create(this)); 2004 ui::TouchEditingControllerDeprecated::Create(this));
2049 } 2005 }
2050 if (touch_selection_controller_) 2006 if (touch_selection_controller_)
2051 touch_selection_controller_->SelectionChanged(); 2007 touch_selection_controller_->SelectionChanged();
2052 } 2008 }
2053 2009
2054 void Textfield::UpdateSelectionClipboard() const {
2055 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
2056 if (performing_user_action_ && HasSelection() &&
2057 text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD) {
2058 ui::ScopedClipboardWriter(
2059 ui::CLIPBOARD_TYPE_SELECTION).WriteText(GetSelectedText());
2060 if (controller_)
2061 controller_->OnAfterCutOrCopy(ui::CLIPBOARD_TYPE_SELECTION);
2062 }
2063 #endif
2064 }
2065
2066 void Textfield::PasteSelectionClipboard(const ui::MouseEvent& event) {
2067 DCHECK(event.IsOnlyMiddleMouseButton());
2068 DCHECK(!read_only());
2069 base::string16 selection_clipboard_text = GetSelectionClipboardText();
2070 OnBeforeUserAction();
2071 const gfx::SelectionModel mouse =
2072 GetRenderText()->FindCursorPosition(event.location());
2073 if (!HasFocus())
2074 RequestFocus();
2075 model_->MoveCursorTo(mouse);
karandeepb 2016/10/20 04:12:58 We were not calling UpdateAfterChange when only th
msw 2016/10/21 02:14:16 Thanks for noticing, filing a bug, and fixing this
2076 if (!selection_clipboard_text.empty()) {
2077 model_->InsertText(selection_clipboard_text);
2078 UpdateAfterChange(true, true);
2079 }
2080 OnAfterUserAction();
2081 }
2082
2083 void Textfield::OnEditFailed() { 2010 void Textfield::OnEditFailed() {
2084 PlatformStyle::OnTextfieldEditFailed(); 2011 PlatformStyle::OnTextfieldEditFailed();
2085 } 2012 }
2086 2013
2087 bool Textfield::ShouldShowCursor() const { 2014 bool Textfield::ShouldShowCursor() const {
2088 return HasFocus() && !HasSelection() && enabled() && !read_only() && 2015 return HasFocus() && !HasSelection() && enabled() && !read_only() &&
2089 !drop_cursor_visible_; 2016 !drop_cursor_visible_;
2090 } 2017 }
2091 2018
2092 bool Textfield::ShouldBlinkCursor() const { 2019 bool Textfield::ShouldBlinkCursor() const {
(...skipping 12 matching lines...) Expand all
2105 } 2032 }
2106 2033
2107 void Textfield::OnCursorBlinkTimerFired() { 2034 void Textfield::OnCursorBlinkTimerFired() {
2108 DCHECK(ShouldBlinkCursor()); 2035 DCHECK(ShouldBlinkCursor());
2109 gfx::RenderText* render_text = GetRenderText(); 2036 gfx::RenderText* render_text = GetRenderText();
2110 render_text->set_cursor_visible(!render_text->cursor_visible()); 2037 render_text->set_cursor_visible(!render_text->cursor_visible());
2111 RepaintCursor(); 2038 RepaintCursor();
2112 } 2039 }
2113 2040
2114 } // namespace views 2041 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698