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

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

Issue 2408623002: Views: Extract text selection code from Textfield. (Closed)
Patch Set: Rebase. 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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 use_default_selection_background_color_(true), 237 use_default_selection_background_color_(true),
250 text_color_(SK_ColorBLACK), 238 text_color_(SK_ColorBLACK),
251 background_color_(SK_ColorWHITE), 239 background_color_(SK_ColorWHITE),
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),
247 performing_mouse_action_(false),
259 skip_input_method_cancel_composition_(false), 248 skip_input_method_cancel_composition_(false),
260 drop_cursor_visible_(false), 249 drop_cursor_visible_(false),
261 initiating_drag_(false), 250 initiating_drag_(false),
262 aggregated_clicks_(0), 251 selection_controller_(new SelectionController(this)),
263 drag_start_display_offset_(0), 252 drag_start_display_offset_(0),
264 touch_handles_hidden_due_to_scroll_(false), 253 touch_handles_hidden_due_to_scroll_(false),
265 use_focus_ring_(ui::MaterialDesignController::IsSecondaryUiMaterial()), 254 use_focus_ring_(ui::MaterialDesignController::IsSecondaryUiMaterial()),
266 weak_ptr_factory_(this) { 255 weak_ptr_factory_(this) {
267 set_context_menu_controller(this); 256 set_context_menu_controller(this);
268 set_drag_controller(this); 257 set_drag_controller(this);
269 GetRenderText()->SetFontList(GetDefaultFontList()); 258 GetRenderText()->SetFontList(GetDefaultFontList());
270 View::SetBorder(std::unique_ptr<Border>(new FocusableBorder())); 259 View::SetBorder(std::unique_ptr<Border>(new FocusableBorder()));
271 SetFocusBehavior(FocusBehavior::ALWAYS); 260 SetFocusBehavior(FocusBehavior::ALWAYS);
272 261
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 model_->InsertText(new_text); 317 model_->InsertText(new_text);
329 UpdateAfterChange(true, true); 318 UpdateAfterChange(true, true);
330 } 319 }
331 320
332 base::string16 Textfield::GetSelectedText() const { 321 base::string16 Textfield::GetSelectedText() const {
333 return model_->GetSelectedText(); 322 return model_->GetSelectedText();
334 } 323 }
335 324
336 void Textfield::SelectAll(bool reversed) { 325 void Textfield::SelectAll(bool reversed) {
337 model_->SelectAll(reversed); 326 model_->SelectAll(reversed);
338 UpdateSelectionClipboard(); 327 if (HasSelection())
328 UpdateSelectionClipboard();
339 UpdateAfterChange(false, true); 329 UpdateAfterChange(false, true);
340 } 330 }
341 331
342 void Textfield::SelectWordAt(const gfx::Point& point) { 332 void Textfield::SelectWordAt(const gfx::Point& point) {
343 model_->MoveCursorTo(point, false); 333 model_->MoveCursorTo(point, false);
344 model_->SelectWord(); 334 model_->SelectWord();
345 UpdateAfterChange(false, true); 335 UpdateAfterChange(false, true);
346 } 336 }
347 337
348 void Textfield::ClearSelection() { 338 void Textfield::ClearSelection() {
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 } 528 }
539 529
540 void Textfield::ClearEditHistory() { 530 void Textfield::ClearEditHistory() {
541 model_->ClearEditHistory(); 531 model_->ClearEditHistory();
542 } 532 }
543 533
544 void Textfield::SetAccessibleName(const base::string16& name) { 534 void Textfield::SetAccessibleName(const base::string16& name) {
545 accessible_name_ = name; 535 accessible_name_ = name;
546 } 536 }
547 537
548 bool Textfield::HasTextBeingDragged() {
549 return initiating_drag_;
550 }
551
552 //////////////////////////////////////////////////////////////////////////////// 538 ////////////////////////////////////////////////////////////////////////////////
553 // Textfield, View overrides: 539 // Textfield, View overrides:
554 540
555 gfx::Insets Textfield::GetInsets() const { 541 gfx::Insets Textfield::GetInsets() const {
556 gfx::Insets insets = View::GetInsets(); 542 gfx::Insets insets = View::GetInsets();
557 insets += gfx::Insets(kTextPadding, kTextPadding, kTextPadding, kTextPadding); 543 insets += gfx::Insets(kTextPadding, kTextPadding, kTextPadding, kTextPadding);
558 return insets; 544 return insets;
559 } 545 }
560 546
561 int Textfield::GetBaseline() const { 547 int Textfield::GetBaseline() const {
(...skipping 18 matching lines...) Expand all
580 } 566 }
581 567
582 gfx::NativeCursor Textfield::GetCursor(const ui::MouseEvent& event) { 568 gfx::NativeCursor Textfield::GetCursor(const ui::MouseEvent& event) {
583 bool in_selection = GetRenderText()->IsPointInSelection(event.location()); 569 bool in_selection = GetRenderText()->IsPointInSelection(event.location());
584 bool drag_event = event.type() == ui::ET_MOUSE_DRAGGED; 570 bool drag_event = event.type() == ui::ET_MOUSE_DRAGGED;
585 bool text_cursor = !initiating_drag_ && (drag_event || !in_selection); 571 bool text_cursor = !initiating_drag_ && (drag_event || !in_selection);
586 return text_cursor ? GetNativeIBeamCursor() : gfx::kNullCursor; 572 return text_cursor ? GetNativeIBeamCursor() : gfx::kNullCursor;
587 } 573 }
588 574
589 bool Textfield::OnMousePressed(const ui::MouseEvent& event) { 575 bool Textfield::OnMousePressed(const ui::MouseEvent& event) {
590 TrackMouseClicks(event); 576 bool handled = controller_ && controller_->HandleMouseEvent(this, event);
591 577 if (!handled &&
592 if (!controller_ || !controller_->HandleMouseEvent(this, event)) { 578 (event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton())) {
593 if (event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton()) { 579 RequestFocus();
594 RequestFocus(); 580 ShowImeIfNeeded();
595 ShowImeIfNeeded();
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
621 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
622 if (event.IsOnlyMiddleMouseButton()) {
623 if (GetRenderText()->IsPointInSelection(event.location())) {
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
634 } 581 }
635 582 return selection_controller_->OnMousePressed(event, handled);
636 return true;
637 } 583 }
638 584
639 bool Textfield::OnMouseDragged(const ui::MouseEvent& event) { 585 bool Textfield::OnMouseDragged(const ui::MouseEvent& event) {
640 last_drag_location_ = event.location(); 586 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 } 587 }
662 588
663 void Textfield::OnMouseReleased(const ui::MouseEvent& event) { 589 void Textfield::OnMouseReleased(const ui::MouseEvent& event) {
664 OnBeforeUserAction(); 590 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 } 591 }
673 592
674 WordLookupClient* Textfield::GetWordLookupClient() { 593 WordLookupClient* Textfield::GetWordLookupClient() {
675 return this; 594 return this;
676 } 595 }
677 596
678 bool Textfield::OnKeyPressed(const ui::KeyEvent& event) { 597 bool Textfield::OnKeyPressed(const ui::KeyEvent& event) {
679 ui::TextEditCommand edit_command = scheduled_text_edit_command_; 598 ui::TextEditCommand edit_command = scheduled_text_edit_command_;
680 scheduled_text_edit_command_ = ui::TextEditCommand::INVALID_COMMAND; 599 scheduled_text_edit_command_ = ui::TextEditCommand::INVALID_COMMAND;
681 600
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 // Textfield, WordLookupClient overrides: 1048 // Textfield, WordLookupClient overrides:
1130 1049
1131 bool Textfield::GetDecoratedWordAtPoint(const gfx::Point& point, 1050 bool Textfield::GetDecoratedWordAtPoint(const gfx::Point& point,
1132 gfx::DecoratedText* decorated_word, 1051 gfx::DecoratedText* decorated_word,
1133 gfx::Point* baseline_point) { 1052 gfx::Point* baseline_point) {
1134 return GetRenderText()->GetDecoratedWordAtPoint(point, decorated_word, 1053 return GetRenderText()->GetDecoratedWordAtPoint(point, decorated_word,
1135 baseline_point); 1054 baseline_point);
1136 } 1055 }
1137 1056
1138 //////////////////////////////////////////////////////////////////////////////// 1057 ////////////////////////////////////////////////////////////////////////////////
1058 // Textfield, SelectionControllerDelegate overrides:
1059
1060 bool Textfield::HasTextBeingDragged() const {
1061 return initiating_drag_;
1062 }
1063
1064 ////////////////////////////////////////////////////////////////////////////////
1139 // Textfield, ui::TouchEditable overrides: 1065 // Textfield, ui::TouchEditable overrides:
1140 1066
1141 void Textfield::SelectRect(const gfx::Point& start, const gfx::Point& end) { 1067 void Textfield::SelectRect(const gfx::Point& start, const gfx::Point& end) {
1142 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) 1068 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE)
1143 return; 1069 return;
1144 1070
1145 gfx::SelectionModel start_caret = GetRenderText()->FindCursorPosition(start); 1071 gfx::SelectionModel start_caret = GetRenderText()->FindCursorPosition(start);
1146 gfx::SelectionModel end_caret = GetRenderText()->FindCursorPosition(end); 1072 gfx::SelectionModel end_caret = GetRenderText()->FindCursorPosition(end);
1147 gfx::SelectionModel selection( 1073 gfx::SelectionModel selection(
1148 gfx::Range(start_caret.caret_pos(), end_caret.caret_pos()), 1074 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; 1520 skip_input_method_cancel_composition_ = false;
1595 1521
1596 UpdateAfterChange(true, true); 1522 UpdateAfterChange(true, true);
1597 OnAfterUserAction(); 1523 OnAfterUserAction();
1598 } 1524 }
1599 1525
1600 gfx::RenderText* Textfield::GetRenderText() const { 1526 gfx::RenderText* Textfield::GetRenderText() const {
1601 return model_->render_text(); 1527 return model_->render_text();
1602 } 1528 }
1603 1529
1530 gfx::Point Textfield::GetLastClickLocation() const {
1531 return selection_controller_->last_click_location();
1532 }
1533
1604 base::string16 Textfield::GetSelectionClipboardText() const { 1534 base::string16 Textfield::GetSelectionClipboardText() const {
1605 base::string16 selection_clipboard_text; 1535 base::string16 selection_clipboard_text;
1606 ui::Clipboard::GetForCurrentThread()->ReadText( 1536 ui::Clipboard::GetForCurrentThread()->ReadText(
1607 ui::CLIPBOARD_TYPE_SELECTION, &selection_clipboard_text); 1537 ui::CLIPBOARD_TYPE_SELECTION, &selection_clipboard_text);
1608 return selection_clipboard_text; 1538 return selection_clipboard_text;
1609 } 1539 }
1610 1540
1611 void Textfield::ExecuteTextEditCommand(ui::TextEditCommand command) { 1541 void Textfield::ExecuteTextEditCommand(ui::TextEditCommand command) {
1612 DestroyTouchSelection(); 1542 DestroyTouchSelection();
1613 1543
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1792 break; 1722 break;
1793 case ui::TextEditCommand::INSERT_TEXT: 1723 case ui::TextEditCommand::INSERT_TEXT:
1794 case ui::TextEditCommand::SET_MARK: 1724 case ui::TextEditCommand::SET_MARK:
1795 case ui::TextEditCommand::UNSELECT: 1725 case ui::TextEditCommand::UNSELECT:
1796 case ui::TextEditCommand::INVALID_COMMAND: 1726 case ui::TextEditCommand::INVALID_COMMAND:
1797 NOTREACHED(); 1727 NOTREACHED();
1798 break; 1728 break;
1799 } 1729 }
1800 1730
1801 cursor_changed |= GetSelectionModel() != selection_model; 1731 cursor_changed |= GetSelectionModel() != selection_model;
1802 if (cursor_changed) 1732 if (cursor_changed && HasSelection())
1803 UpdateSelectionClipboard(); 1733 UpdateSelectionClipboard();
1804 UpdateAfterChange(text_changed, cursor_changed); 1734 UpdateAfterChange(text_changed, cursor_changed);
1805 OnAfterUserAction(); 1735 OnAfterUserAction();
1806 } 1736 }
1807 1737
1808 //////////////////////////////////////////////////////////////////////////////// 1738 ////////////////////////////////////////////////////////////////////////////////
1809 // Textfield, private: 1739 // Textfield, private:
1810 1740
1741 ////////////////////////////////////////////////////////////////////////////////
1742 // Textfield, SelectionControllerDelegate overrides:
1743
1744 gfx::RenderText* Textfield::GetRenderTextForSelectionController() {
1745 return GetRenderText();
1746 }
1747
1748 bool Textfield::IsReadOnly() const {
1749 return read_only();
1750 }
1751
1752 void Textfield::SetTextBeingDragged(bool value) {
1753 initiating_drag_ = value;
1754 }
1755
1756 int Textfield::GetViewHeight() const {
1757 return height();
1758 }
1759
1760 int Textfield::GetViewWidth() const {
1761 return width();
1762 }
1763
1764 int Textfield::GetDragSelectionDelay() const {
1765 switch (ui::ScopedAnimationDurationScaleMode::duration_scale_mode()) {
1766 case ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION:
1767 return 100;
1768 case ui::ScopedAnimationDurationScaleMode::FAST_DURATION:
1769 return 25;
1770 case ui::ScopedAnimationDurationScaleMode::SLOW_DURATION:
1771 return 400;
1772 case ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION:
1773 return 1;
1774 case ui::ScopedAnimationDurationScaleMode::ZERO_DURATION:
1775 return 0;
1776 }
1777 return 100;
1778 }
1779
1780 void Textfield::OnBeforeMouseAction() {
1781 OnBeforeUserAction();
1782 DCHECK(!performing_mouse_action_);
1783 performing_mouse_action_ = true;
1784 }
1785
1786 void Textfield::OnAfterMouseAction(bool text_changed, bool selection_changed) {
1787 OnAfterUserAction();
1788 DCHECK(performing_mouse_action_);
1789 performing_mouse_action_ = false;
1790 UpdateAfterChange(text_changed, selection_changed);
1791 }
1792
1793 void Textfield::OnBeforeSelectionUpdated() {
msw 2016/10/18 23:15:05 nit: rename these to OnBeforeSelectionUpdate and O
karandeepb 2016/10/20 04:12:57 Done. (Obsolete)
1794 DCHECK(performing_mouse_action_);
1795 if (model_->HasCompositionText())
1796 model_->ConfirmCompositionText();
1797 }
1798
1799 void Textfield::OnAfterSelectionUpdated() {
1800 DCHECK(performing_mouse_action_);
1801 UpdateAfterChange(false, true);
1802 }
1803
1804 void Textfield::PasteSelectionClipboard(const ui::MouseEvent& event) {
1805 if (!event.IsOnlyMiddleMouseButton() || read_only() ||
1806 !performing_user_action_)
1807 return;
1808 base::string16 selection_clipboard_text = GetSelectionClipboardText();
1809 const gfx::SelectionModel mouse =
1810 GetRenderText()->FindCursorPosition(event.location());
1811 if (!HasFocus())
1812 RequestFocus();
1813 model_->MoveCursorTo(mouse);
1814 if (!selection_clipboard_text.empty()) {
1815 model_->InsertText(selection_clipboard_text);
1816 UpdateAfterChange(true, true);
1817 }
1818 }
1819
1820 void Textfield::UpdateSelectionClipboard() {
1821 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
1822 if (performing_user_action_ &&
1823 text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD) {
1824 ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_SELECTION)
1825 .WriteText(GetSelectedText());
1826 if (controller_)
1827 controller_->OnAfterCutOrCopy(ui::CLIPBOARD_TYPE_SELECTION);
1828 }
1829 #endif
1830 }
1831
1811 void Textfield::AccessibilitySetValue(const base::string16& new_value) { 1832 void Textfield::AccessibilitySetValue(const base::string16& new_value) {
1812 if (!read_only()) { 1833 if (!read_only()) {
1813 SetText(new_value); 1834 SetText(new_value);
1814 ClearSelection(); 1835 ClearSelection();
1815 } 1836 }
1816 } 1837 }
1817 1838
1818 void Textfield::UpdateBackgroundColor() { 1839 void Textfield::UpdateBackgroundColor() {
1819 const SkColor color = GetBackgroundColor(); 1840 const SkColor color = GetBackgroundColor();
1820 if (ui::MaterialDesignController::IsSecondaryUiMaterial()) { 1841 if (ui::MaterialDesignController::IsSecondaryUiMaterial()) {
(...skipping 12 matching lines...) Expand all
1833 } 1854 }
1834 1855
1835 void Textfield::UpdateBorder() { 1856 void Textfield::UpdateBorder() {
1836 auto border = base::MakeUnique<views::FocusableBorder>(); 1857 auto border = base::MakeUnique<views::FocusableBorder>();
1837 if (invalid_) 1858 if (invalid_)
1838 border->SetColorId(ui::NativeTheme::kColorId_AlertSeverityHigh); 1859 border->SetColorId(ui::NativeTheme::kColorId_AlertSeverityHigh);
1839 View::SetBorder(std::move(border)); 1860 View::SetBorder(std::move(border));
1840 } 1861 }
1841 1862
1842 void Textfield::UpdateAfterChange(bool text_changed, bool cursor_changed) { 1863 void Textfield::UpdateAfterChange(bool text_changed, bool cursor_changed) {
1864 if (performing_mouse_action_)
1865 return;
1843 if (text_changed) { 1866 if (text_changed) {
1844 if (controller_) 1867 if (controller_)
1845 controller_->ContentsChanged(this, text()); 1868 controller_->ContentsChanged(this, text());
1846 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true); 1869 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true);
1847 } 1870 }
1848 if (cursor_changed) { 1871 if (cursor_changed) {
1849 GetRenderText()->set_cursor_visible(ShouldShowCursor()); 1872 GetRenderText()->set_cursor_visible(ShouldShowCursor());
1850 RepaintCursor(); 1873 RepaintCursor();
1851 if (ShouldBlinkCursor()) 1874 if (ShouldBlinkCursor())
1852 StartBlinkingCursor(); 1875 StartBlinkingCursor();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1891 render_text->DrawCursor(canvas, drop_cursor_position_); 1914 render_text->DrawCursor(canvas, drop_cursor_position_);
1892 1915
1893 canvas->Restore(); 1916 canvas->Restore();
1894 } 1917 }
1895 1918
1896 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) { 1919 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) {
1897 if (model_->MoveCursorTo(point, select)) 1920 if (model_->MoveCursorTo(point, select))
1898 UpdateAfterChange(false, true); 1921 UpdateAfterChange(false, true);
1899 } 1922 }
1900 1923
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() { 1924 void Textfield::OnCaretBoundsChanged() {
1935 if (GetInputMethod()) 1925 if (GetInputMethod())
1936 GetInputMethod()->OnCaretBoundsChanged(this); 1926 GetInputMethod()->OnCaretBoundsChanged(this);
1937 if (touch_selection_controller_) 1927 if (touch_selection_controller_)
1938 touch_selection_controller_->SelectionChanged(); 1928 touch_selection_controller_->SelectionChanged();
1939 } 1929 }
1940 1930
1941 void Textfield::OnBeforeUserAction() { 1931 void Textfield::OnBeforeUserAction() {
1942 DCHECK(!performing_user_action_); 1932 DCHECK(!performing_user_action_);
1943 performing_user_action_ = true; 1933 performing_user_action_ = true;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1997 // IsCommandIdEnabled() as appropriate, for the commands added. 1987 // IsCommandIdEnabled() as appropriate, for the commands added.
1998 if (controller_) 1988 if (controller_)
1999 controller_->UpdateContextMenu(context_menu_contents_.get()); 1989 controller_->UpdateContextMenu(context_menu_contents_.get());
2000 } 1990 }
2001 context_menu_runner_.reset(new MenuRunner(context_menu_contents_.get(), 1991 context_menu_runner_.reset(new MenuRunner(context_menu_contents_.get(),
2002 MenuRunner::HAS_MNEMONICS | 1992 MenuRunner::HAS_MNEMONICS |
2003 MenuRunner::CONTEXT_MENU | 1993 MenuRunner::CONTEXT_MENU |
2004 MenuRunner::ASYNC)); 1994 MenuRunner::ASYNC));
2005 } 1995 }
2006 1996
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 { 1997 bool Textfield::ImeEditingAllowed() const {
2026 // Disallow input method editing of password fields. 1998 // Disallow input method editing of password fields.
2027 ui::TextInputType t = GetTextInputType(); 1999 ui::TextInputType t = GetTextInputType();
2028 return (t != ui::TEXT_INPUT_TYPE_NONE && t != ui::TEXT_INPUT_TYPE_PASSWORD); 2000 return (t != ui::TEXT_INPUT_TYPE_NONE && t != ui::TEXT_INPUT_TYPE_PASSWORD);
2029 } 2001 }
2030 2002
2031 void Textfield::RevealPasswordChar(int index) { 2003 void Textfield::RevealPasswordChar(int index) {
2032 GetRenderText()->SetObscuredRevealIndex(index); 2004 GetRenderText()->SetObscuredRevealIndex(index);
2033 SchedulePaint(); 2005 SchedulePaint();
2034 2006
2035 if (index != -1) { 2007 if (index != -1) {
2036 password_reveal_timer_.Start(FROM_HERE, GetPasswordRevealDuration(), 2008 password_reveal_timer_.Start(FROM_HERE, GetPasswordRevealDuration(),
2037 base::Bind(&Textfield::RevealPasswordChar, 2009 base::Bind(&Textfield::RevealPasswordChar,
2038 weak_ptr_factory_.GetWeakPtr(), -1)); 2010 weak_ptr_factory_.GetWeakPtr(), -1));
2039 } 2011 }
2040 } 2012 }
2041 2013
2042 void Textfield::CreateTouchSelectionControllerAndNotifyIt() { 2014 void Textfield::CreateTouchSelectionControllerAndNotifyIt() {
2043 if (!HasFocus()) 2015 if (!HasFocus())
2044 return; 2016 return;
2045 2017
2046 if (!touch_selection_controller_) { 2018 if (!touch_selection_controller_) {
2047 touch_selection_controller_.reset( 2019 touch_selection_controller_.reset(
2048 ui::TouchEditingControllerDeprecated::Create(this)); 2020 ui::TouchEditingControllerDeprecated::Create(this));
2049 } 2021 }
2050 if (touch_selection_controller_) 2022 if (touch_selection_controller_)
2051 touch_selection_controller_->SelectionChanged(); 2023 touch_selection_controller_->SelectionChanged();
2052 } 2024 }
2053 2025
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);
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() { 2026 void Textfield::OnEditFailed() {
2084 PlatformStyle::OnTextfieldEditFailed(); 2027 PlatformStyle::OnTextfieldEditFailed();
2085 } 2028 }
2086 2029
2087 bool Textfield::ShouldShowCursor() const { 2030 bool Textfield::ShouldShowCursor() const {
2088 return HasFocus() && !HasSelection() && enabled() && !read_only() && 2031 return HasFocus() && !HasSelection() && enabled() && !read_only() &&
2089 !drop_cursor_visible_; 2032 !drop_cursor_visible_;
2090 } 2033 }
2091 2034
2092 bool Textfield::ShouldBlinkCursor() const { 2035 bool Textfield::ShouldBlinkCursor() const {
(...skipping 12 matching lines...) Expand all
2105 } 2048 }
2106 2049
2107 void Textfield::OnCursorBlinkTimerFired() { 2050 void Textfield::OnCursorBlinkTimerFired() {
2108 DCHECK(ShouldBlinkCursor()); 2051 DCHECK(ShouldBlinkCursor());
2109 gfx::RenderText* render_text = GetRenderText(); 2052 gfx::RenderText* render_text = GetRenderText();
2110 render_text->set_cursor_visible(!render_text->cursor_visible()); 2053 render_text->set_cursor_visible(!render_text->cursor_visible());
2111 RepaintCursor(); 2054 RepaintCursor();
2112 } 2055 }
2113 2056
2114 } // namespace views 2057 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698