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

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

Issue 2408623002: Views: Extract text selection code from Textfield. (Closed)
Patch Set: Check for |handles_selection_clipboard_| Created 4 years, 1 month 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"
46 #include "ui/views/style/platform_style.h" 45 #include "ui/views/style/platform_style.h"
47 #include "ui/views/views_delegate.h" 46 #include "ui/views/views_delegate.h"
48 #include "ui/views/widget/widget.h" 47 #include "ui/views/widget/widget.h"
49 48
50 #if defined(OS_WIN) 49 #if defined(OS_WIN)
51 #include "base/win/win_util.h" 50 #include "base/win/win_util.h"
52 #include "ui/base/win/osk_display_manager.h" 51 #include "ui/base/win/osk_display_manager.h"
53 #endif 52 #endif
(...skipping 24 matching lines...) Expand all
78 const SkColor kDefaultPlaceholderTextColor = SK_ColorLTGRAY; 77 const SkColor kDefaultPlaceholderTextColor = SK_ColorLTGRAY;
79 78
80 void ConvertRectToScreen(const View* src, gfx::Rect* r) { 79 void ConvertRectToScreen(const View* src, gfx::Rect* r) {
81 DCHECK(src); 80 DCHECK(src);
82 81
83 gfx::Point new_origin = r->origin(); 82 gfx::Point new_origin = r->origin();
84 View::ConvertPointToScreen(src, &new_origin); 83 View::ConvertPointToScreen(src, &new_origin);
85 r->set_origin(new_origin); 84 r->set_origin(new_origin);
86 } 85 }
87 86
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|. 87 // Get the default command for a given key |event|.
101 ui::TextEditCommand GetCommandForKeyEvent(const ui::KeyEvent& event) { 88 ui::TextEditCommand GetCommandForKeyEvent(const ui::KeyEvent& event) {
102 if (event.type() != ui::ET_KEY_PRESSED || event.IsUnicodeKeyCode()) 89 if (event.type() != ui::ET_KEY_PRESSED || event.IsUnicodeKeyCode())
103 return ui::TextEditCommand::INVALID_COMMAND; 90 return ui::TextEditCommand::INVALID_COMMAND;
104 91
105 const bool shift = event.IsShiftDown(); 92 const bool shift = event.IsShiftDown();
106 const bool control = event.IsControlDown(); 93 const bool control = event.IsControlDown();
107 const bool alt = event.IsAltDown() || event.IsAltGrDown(); 94 const bool alt = event.IsAltDown() || event.IsAltGrDown();
108 switch (event.key_code()) { 95 switch (event.key_code()) {
109 case ui::VKEY_Z: 96 case ui::VKEY_Z:
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 selection_text_color_(SK_ColorWHITE), 239 selection_text_color_(SK_ColorWHITE),
253 selection_background_color_(SK_ColorBLUE), 240 selection_background_color_(SK_ColorBLUE),
254 placeholder_text_color_(kDefaultPlaceholderTextColor), 241 placeholder_text_color_(kDefaultPlaceholderTextColor),
255 invalid_(false), 242 invalid_(false),
256 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT), 243 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT),
257 text_input_flags_(0), 244 text_input_flags_(0),
258 performing_user_action_(false), 245 performing_user_action_(false),
259 skip_input_method_cancel_composition_(false), 246 skip_input_method_cancel_composition_(false),
260 drop_cursor_visible_(false), 247 drop_cursor_visible_(false),
261 initiating_drag_(false), 248 initiating_drag_(false),
262 aggregated_clicks_(0), 249 selection_controller_(this),
263 drag_start_display_offset_(0), 250 drag_start_display_offset_(0),
264 touch_handles_hidden_due_to_scroll_(false), 251 touch_handles_hidden_due_to_scroll_(false),
265 use_focus_ring_(ui::MaterialDesignController::IsSecondaryUiMaterial()), 252 use_focus_ring_(ui::MaterialDesignController::IsSecondaryUiMaterial()),
266 weak_ptr_factory_(this) { 253 weak_ptr_factory_(this) {
267 set_context_menu_controller(this); 254 set_context_menu_controller(this);
268 set_drag_controller(this); 255 set_drag_controller(this);
269 GetRenderText()->SetFontList(GetDefaultFontList()); 256 GetRenderText()->SetFontList(GetDefaultFontList());
270 View::SetBorder(std::unique_ptr<Border>(new FocusableBorder())); 257 View::SetBorder(std::unique_ptr<Border>(new FocusableBorder()));
271 SetFocusBehavior(FocusBehavior::ALWAYS); 258 SetFocusBehavior(FocusBehavior::ALWAYS);
272 259
260 // On Linux, middle click should update or paste the selection clipboard.
261 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
262 selection_controller_.set_handles_selection_clipboard(true);
263 #endif
264
273 // These allow BrowserView to pass edit commands from the Chrome menu to us 265 // These allow BrowserView to pass edit commands from the Chrome menu to us
274 // when we're focused by simply asking the FocusManager to 266 // when we're focused by simply asking the FocusManager to
275 // ProcessAccelerator() with the relevant accelerators. 267 // ProcessAccelerator() with the relevant accelerators.
276 AddAccelerator(ui::Accelerator(ui::VKEY_X, ui::EF_CONTROL_DOWN)); 268 AddAccelerator(ui::Accelerator(ui::VKEY_X, ui::EF_CONTROL_DOWN));
277 AddAccelerator(ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN)); 269 AddAccelerator(ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN));
278 AddAccelerator(ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN)); 270 AddAccelerator(ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN));
279 } 271 }
280 272
281 Textfield::~Textfield() { 273 Textfield::~Textfield() {
282 if (GetInputMethod()) { 274 if (GetInputMethod()) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 model_->InsertText(new_text); 320 model_->InsertText(new_text);
329 UpdateAfterChange(true, true); 321 UpdateAfterChange(true, true);
330 } 322 }
331 323
332 base::string16 Textfield::GetSelectedText() const { 324 base::string16 Textfield::GetSelectedText() const {
333 return model_->GetSelectedText(); 325 return model_->GetSelectedText();
334 } 326 }
335 327
336 void Textfield::SelectAll(bool reversed) { 328 void Textfield::SelectAll(bool reversed) {
337 model_->SelectAll(reversed); 329 model_->SelectAll(reversed);
338 UpdateSelectionClipboard(); 330 if (HasSelection() && performing_user_action_)
331 UpdateSelectionClipboard();
339 UpdateAfterChange(false, true); 332 UpdateAfterChange(false, true);
340 } 333 }
341 334
342 void Textfield::SelectWordAt(const gfx::Point& point) { 335 void Textfield::SelectWordAt(const gfx::Point& point) {
343 model_->MoveCursorTo(point, false); 336 model_->MoveCursorTo(point, false);
344 model_->SelectWord(); 337 model_->SelectWord();
345 UpdateAfterChange(false, true); 338 UpdateAfterChange(false, true);
346 } 339 }
347 340
348 void Textfield::ClearSelection() { 341 void Textfield::ClearSelection() {
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 } 531 }
539 532
540 void Textfield::ClearEditHistory() { 533 void Textfield::ClearEditHistory() {
541 model_->ClearEditHistory(); 534 model_->ClearEditHistory();
542 } 535 }
543 536
544 void Textfield::SetAccessibleName(const base::string16& name) { 537 void Textfield::SetAccessibleName(const base::string16& name) {
545 accessible_name_ = name; 538 accessible_name_ = name;
546 } 539 }
547 540
548 bool Textfield::HasTextBeingDragged() {
549 return initiating_drag_;
550 }
551
552 //////////////////////////////////////////////////////////////////////////////// 541 ////////////////////////////////////////////////////////////////////////////////
553 // Textfield, View overrides: 542 // Textfield, View overrides:
554 543
555 gfx::Insets Textfield::GetInsets() const { 544 gfx::Insets Textfield::GetInsets() const {
556 gfx::Insets insets = View::GetInsets(); 545 gfx::Insets insets = View::GetInsets();
557 insets += gfx::Insets(kTextPadding, kTextPadding, kTextPadding, kTextPadding); 546 insets += gfx::Insets(kTextPadding, kTextPadding, kTextPadding, kTextPadding);
558 return insets; 547 return insets;
559 } 548 }
560 549
561 int Textfield::GetBaseline() const { 550 int Textfield::GetBaseline() const {
(...skipping 18 matching lines...) Expand all
580 } 569 }
581 570
582 gfx::NativeCursor Textfield::GetCursor(const ui::MouseEvent& event) { 571 gfx::NativeCursor Textfield::GetCursor(const ui::MouseEvent& event) {
583 bool in_selection = GetRenderText()->IsPointInSelection(event.location()); 572 bool in_selection = GetRenderText()->IsPointInSelection(event.location());
584 bool drag_event = event.type() == ui::ET_MOUSE_DRAGGED; 573 bool drag_event = event.type() == ui::ET_MOUSE_DRAGGED;
585 bool text_cursor = !initiating_drag_ && (drag_event || !in_selection); 574 bool text_cursor = !initiating_drag_ && (drag_event || !in_selection);
586 return text_cursor ? GetNativeIBeamCursor() : gfx::kNullCursor; 575 return text_cursor ? GetNativeIBeamCursor() : gfx::kNullCursor;
587 } 576 }
588 577
589 bool Textfield::OnMousePressed(const ui::MouseEvent& event) { 578 bool Textfield::OnMousePressed(const ui::MouseEvent& event) {
590 TrackMouseClicks(event); 579 bool handled = controller_ && controller_->HandleMouseEvent(this, event);
591 580 if (!handled &&
592 if (!controller_ || !controller_->HandleMouseEvent(this, event)) { 581 (event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton())) {
593 if (event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton()) { 582 RequestFocus();
594 RequestFocus(); 583 ShowImeIfNeeded();
595 ShowImeIfNeeded(); 584 }
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 585
621 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 586 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
622 if (event.IsOnlyMiddleMouseButton()) { 587 if (!handled && !HasFocus() && event.IsOnlyMiddleMouseButton())
623 if (GetRenderText()->IsPointInSelection(event.location())) { 588 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 589 #endif
634 }
635 590
636 return true; 591 return selection_controller_.OnMousePressed(event, handled);
637 } 592 }
638 593
639 bool Textfield::OnMouseDragged(const ui::MouseEvent& event) { 594 bool Textfield::OnMouseDragged(const ui::MouseEvent& event) {
640 last_drag_location_ = event.location(); 595 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 } 596 }
662 597
663 void Textfield::OnMouseReleased(const ui::MouseEvent& event) { 598 void Textfield::OnMouseReleased(const ui::MouseEvent& event) {
664 OnBeforeUserAction(); 599 selection_controller_.OnMouseReleased(event);
665 drag_selection_timer_.Stop(); 600 }
666 // Cancel suspected drag initiations, the user was clicking in the selection. 601
667 if (initiating_drag_) 602 void Textfield::OnMouseCaptureLost() {
668 MoveCursorTo(event.location(), false); 603 selection_controller_.OnMouseCaptureLost();
669 initiating_drag_ = false;
670 UpdateSelectionClipboard();
671 OnAfterUserAction();
672 } 604 }
673 605
674 WordLookupClient* Textfield::GetWordLookupClient() { 606 WordLookupClient* Textfield::GetWordLookupClient() {
675 return this; 607 return this;
676 } 608 }
677 609
678 bool Textfield::OnKeyPressed(const ui::KeyEvent& event) { 610 bool Textfield::OnKeyPressed(const ui::KeyEvent& event) {
679 ui::TextEditCommand edit_command = scheduled_text_edit_command_; 611 ui::TextEditCommand edit_command = scheduled_text_edit_command_;
680 scheduled_text_edit_command_ = ui::TextEditCommand::INVALID_COMMAND; 612 scheduled_text_edit_command_ = ui::TextEditCommand::INVALID_COMMAND;
681 613
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 // Textfield, WordLookupClient overrides: 1061 // Textfield, WordLookupClient overrides:
1130 1062
1131 bool Textfield::GetDecoratedWordAtPoint(const gfx::Point& point, 1063 bool Textfield::GetDecoratedWordAtPoint(const gfx::Point& point,
1132 gfx::DecoratedText* decorated_word, 1064 gfx::DecoratedText* decorated_word,
1133 gfx::Point* baseline_point) { 1065 gfx::Point* baseline_point) {
1134 return GetRenderText()->GetDecoratedWordAtPoint(point, decorated_word, 1066 return GetRenderText()->GetDecoratedWordAtPoint(point, decorated_word,
1135 baseline_point); 1067 baseline_point);
1136 } 1068 }
1137 1069
1138 //////////////////////////////////////////////////////////////////////////////// 1070 ////////////////////////////////////////////////////////////////////////////////
1071 // Textfield, SelectionControllerDelegate overrides:
1072
1073 bool Textfield::HasTextBeingDragged() const {
1074 return initiating_drag_;
1075 }
1076
1077 ////////////////////////////////////////////////////////////////////////////////
1139 // Textfield, ui::TouchEditable overrides: 1078 // Textfield, ui::TouchEditable overrides:
1140 1079
1141 void Textfield::SelectRect(const gfx::Point& start, const gfx::Point& end) { 1080 void Textfield::SelectRect(const gfx::Point& start, const gfx::Point& end) {
1142 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) 1081 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE)
1143 return; 1082 return;
1144 1083
1145 gfx::SelectionModel start_caret = GetRenderText()->FindCursorPosition(start); 1084 gfx::SelectionModel start_caret = GetRenderText()->FindCursorPosition(start);
1146 gfx::SelectionModel end_caret = GetRenderText()->FindCursorPosition(end); 1085 gfx::SelectionModel end_caret = GetRenderText()->FindCursorPosition(end);
1147 gfx::SelectionModel selection( 1086 gfx::SelectionModel selection(
1148 gfx::Range(start_caret.caret_pos(), end_caret.caret_pos()), 1087 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; 1533 skip_input_method_cancel_composition_ = false;
1595 1534
1596 UpdateAfterChange(true, true); 1535 UpdateAfterChange(true, true);
1597 OnAfterUserAction(); 1536 OnAfterUserAction();
1598 } 1537 }
1599 1538
1600 gfx::RenderText* Textfield::GetRenderText() const { 1539 gfx::RenderText* Textfield::GetRenderText() const {
1601 return model_->render_text(); 1540 return model_->render_text();
1602 } 1541 }
1603 1542
1543 gfx::Point Textfield::GetLastClickLocation() const {
1544 return selection_controller_.last_click_location();
1545 }
1546
1604 base::string16 Textfield::GetSelectionClipboardText() const { 1547 base::string16 Textfield::GetSelectionClipboardText() const {
1605 base::string16 selection_clipboard_text; 1548 base::string16 selection_clipboard_text;
1606 ui::Clipboard::GetForCurrentThread()->ReadText( 1549 ui::Clipboard::GetForCurrentThread()->ReadText(
1607 ui::CLIPBOARD_TYPE_SELECTION, &selection_clipboard_text); 1550 ui::CLIPBOARD_TYPE_SELECTION, &selection_clipboard_text);
1608 return selection_clipboard_text; 1551 return selection_clipboard_text;
1609 } 1552 }
1610 1553
1611 void Textfield::ExecuteTextEditCommand(ui::TextEditCommand command) { 1554 void Textfield::ExecuteTextEditCommand(ui::TextEditCommand command) {
1612 DestroyTouchSelection(); 1555 DestroyTouchSelection();
1613 1556
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1792 break; 1735 break;
1793 case ui::TextEditCommand::INSERT_TEXT: 1736 case ui::TextEditCommand::INSERT_TEXT:
1794 case ui::TextEditCommand::SET_MARK: 1737 case ui::TextEditCommand::SET_MARK:
1795 case ui::TextEditCommand::UNSELECT: 1738 case ui::TextEditCommand::UNSELECT:
1796 case ui::TextEditCommand::INVALID_COMMAND: 1739 case ui::TextEditCommand::INVALID_COMMAND:
1797 NOTREACHED(); 1740 NOTREACHED();
1798 break; 1741 break;
1799 } 1742 }
1800 1743
1801 cursor_changed |= GetSelectionModel() != selection_model; 1744 cursor_changed |= GetSelectionModel() != selection_model;
1802 if (cursor_changed) 1745 if (cursor_changed && HasSelection())
1803 UpdateSelectionClipboard(); 1746 UpdateSelectionClipboard();
1804 UpdateAfterChange(text_changed, cursor_changed); 1747 UpdateAfterChange(text_changed, cursor_changed);
1805 OnAfterUserAction(); 1748 OnAfterUserAction();
1806 } 1749 }
1807 1750
1808 //////////////////////////////////////////////////////////////////////////////// 1751 ////////////////////////////////////////////////////////////////////////////////
1809 // Textfield, private: 1752 // Textfield, private:
1810 1753
1754 ////////////////////////////////////////////////////////////////////////////////
1755 // Textfield, SelectionControllerDelegate overrides:
1756
1757 gfx::RenderText* Textfield::GetRenderTextForSelectionController() {
1758 return GetRenderText();
1759 }
1760
1761 bool Textfield::IsReadOnly() const {
1762 return read_only();
1763 }
1764
1765 void Textfield::SetTextBeingDragged(bool value) {
1766 initiating_drag_ = value;
1767 }
1768
1769 int Textfield::GetViewHeight() const {
1770 return height();
1771 }
1772
1773 int Textfield::GetViewWidth() const {
1774 return width();
1775 }
1776
1777 int Textfield::GetDragSelectionDelay() const {
1778 switch (ui::ScopedAnimationDurationScaleMode::duration_scale_mode()) {
1779 case ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION:
1780 return 100;
1781 case ui::ScopedAnimationDurationScaleMode::FAST_DURATION:
1782 return 25;
1783 case ui::ScopedAnimationDurationScaleMode::SLOW_DURATION:
1784 return 400;
1785 case ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION:
1786 return 1;
1787 case ui::ScopedAnimationDurationScaleMode::ZERO_DURATION:
1788 return 0;
1789 }
1790 return 100;
1791 }
1792
1793 void Textfield::OnBeforePointerAction() {
1794 OnBeforeUserAction();
1795 if (model_->HasCompositionText())
1796 model_->ConfirmCompositionText();
1797 }
1798
1799 void Textfield::OnAfterPointerAction(bool text_changed,
1800 bool selection_changed) {
1801 OnAfterUserAction();
1802 UpdateAfterChange(text_changed, selection_changed);
1803 }
1804
1805 bool Textfield::PasteSelectionClipboard() {
1806 DCHECK(performing_user_action_);
1807 DCHECK(!read_only());
1808 const base::string16 selection_clipboard_text = GetSelectionClipboardText();
1809 if (selection_clipboard_text.empty())
1810 return false;
1811
1812 model_->InsertText(selection_clipboard_text);
1813 return true;
1814 }
1815
1816 void Textfield::UpdateSelectionClipboard() {
1817 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
1818 if (text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD) {
1819 ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_SELECTION)
1820 .WriteText(GetSelectedText());
1821 if (controller_)
1822 controller_->OnAfterCutOrCopy(ui::CLIPBOARD_TYPE_SELECTION);
1823 }
1824 #endif
1825 }
1826
1811 void Textfield::AccessibilitySetValue(const base::string16& new_value) { 1827 void Textfield::AccessibilitySetValue(const base::string16& new_value) {
1812 if (!read_only()) { 1828 if (!read_only()) {
1813 SetText(new_value); 1829 SetText(new_value);
1814 ClearSelection(); 1830 ClearSelection();
1815 } 1831 }
1816 } 1832 }
1817 1833
1818 void Textfield::UpdateBackgroundColor() { 1834 void Textfield::UpdateBackgroundColor() {
1819 const SkColor color = GetBackgroundColor(); 1835 const SkColor color = GetBackgroundColor();
1820 if (ui::MaterialDesignController::IsSecondaryUiMaterial()) { 1836 if (ui::MaterialDesignController::IsSecondaryUiMaterial()) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1891 render_text->DrawCursor(canvas, drop_cursor_position_); 1907 render_text->DrawCursor(canvas, drop_cursor_position_);
1892 1908
1893 canvas->Restore(); 1909 canvas->Restore();
1894 } 1910 }
1895 1911
1896 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) { 1912 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) {
1897 if (model_->MoveCursorTo(point, select)) 1913 if (model_->MoveCursorTo(point, select))
1898 UpdateAfterChange(false, true); 1914 UpdateAfterChange(false, true);
1899 } 1915 }
1900 1916
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() { 1917 void Textfield::OnCaretBoundsChanged() {
1935 if (GetInputMethod()) 1918 if (GetInputMethod())
1936 GetInputMethod()->OnCaretBoundsChanged(this); 1919 GetInputMethod()->OnCaretBoundsChanged(this);
1937 if (touch_selection_controller_) 1920 if (touch_selection_controller_)
1938 touch_selection_controller_->SelectionChanged(); 1921 touch_selection_controller_->SelectionChanged();
1939 } 1922 }
1940 1923
1941 void Textfield::OnBeforeUserAction() { 1924 void Textfield::OnBeforeUserAction() {
1942 DCHECK(!performing_user_action_); 1925 DCHECK(!performing_user_action_);
1943 performing_user_action_ = true; 1926 performing_user_action_ = true;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1997 // IsCommandIdEnabled() as appropriate, for the commands added. 1980 // IsCommandIdEnabled() as appropriate, for the commands added.
1998 if (controller_) 1981 if (controller_)
1999 controller_->UpdateContextMenu(context_menu_contents_.get()); 1982 controller_->UpdateContextMenu(context_menu_contents_.get());
2000 } 1983 }
2001 context_menu_runner_.reset(new MenuRunner(context_menu_contents_.get(), 1984 context_menu_runner_.reset(new MenuRunner(context_menu_contents_.get(),
2002 MenuRunner::HAS_MNEMONICS | 1985 MenuRunner::HAS_MNEMONICS |
2003 MenuRunner::CONTEXT_MENU | 1986 MenuRunner::CONTEXT_MENU |
2004 MenuRunner::ASYNC)); 1987 MenuRunner::ASYNC));
2005 } 1988 }
2006 1989
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 { 1990 bool Textfield::ImeEditingAllowed() const {
2026 // Disallow input method editing of password fields. 1991 // Disallow input method editing of password fields.
2027 ui::TextInputType t = GetTextInputType(); 1992 ui::TextInputType t = GetTextInputType();
2028 return (t != ui::TEXT_INPUT_TYPE_NONE && t != ui::TEXT_INPUT_TYPE_PASSWORD); 1993 return (t != ui::TEXT_INPUT_TYPE_NONE && t != ui::TEXT_INPUT_TYPE_PASSWORD);
2029 } 1994 }
2030 1995
2031 void Textfield::RevealPasswordChar(int index) { 1996 void Textfield::RevealPasswordChar(int index) {
2032 GetRenderText()->SetObscuredRevealIndex(index); 1997 GetRenderText()->SetObscuredRevealIndex(index);
2033 SchedulePaint(); 1998 SchedulePaint();
2034 1999
2035 if (index != -1) { 2000 if (index != -1) {
2036 password_reveal_timer_.Start(FROM_HERE, GetPasswordRevealDuration(), 2001 password_reveal_timer_.Start(FROM_HERE, GetPasswordRevealDuration(),
2037 base::Bind(&Textfield::RevealPasswordChar, 2002 base::Bind(&Textfield::RevealPasswordChar,
2038 weak_ptr_factory_.GetWeakPtr(), -1)); 2003 weak_ptr_factory_.GetWeakPtr(), -1));
2039 } 2004 }
2040 } 2005 }
2041 2006
2042 void Textfield::CreateTouchSelectionControllerAndNotifyIt() { 2007 void Textfield::CreateTouchSelectionControllerAndNotifyIt() {
2043 if (!HasFocus()) 2008 if (!HasFocus())
2044 return; 2009 return;
2045 2010
2046 if (!touch_selection_controller_) { 2011 if (!touch_selection_controller_) {
2047 touch_selection_controller_.reset( 2012 touch_selection_controller_.reset(
2048 ui::TouchEditingControllerDeprecated::Create(this)); 2013 ui::TouchEditingControllerDeprecated::Create(this));
2049 } 2014 }
2050 if (touch_selection_controller_) 2015 if (touch_selection_controller_)
2051 touch_selection_controller_->SelectionChanged(); 2016 touch_selection_controller_->SelectionChanged();
2052 } 2017 }
2053 2018
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() { 2019 void Textfield::OnEditFailed() {
2084 PlatformStyle::OnTextfieldEditFailed(); 2020 PlatformStyle::OnTextfieldEditFailed();
2085 } 2021 }
2086 2022
2087 bool Textfield::ShouldShowCursor() const { 2023 bool Textfield::ShouldShowCursor() const {
2088 return HasFocus() && !HasSelection() && enabled() && !read_only() && 2024 return HasFocus() && !HasSelection() && enabled() && !read_only() &&
2089 !drop_cursor_visible_; 2025 !drop_cursor_visible_;
2090 } 2026 }
2091 2027
2092 bool Textfield::ShouldBlinkCursor() const { 2028 bool Textfield::ShouldBlinkCursor() const {
(...skipping 12 matching lines...) Expand all
2105 } 2041 }
2106 2042
2107 void Textfield::OnCursorBlinkTimerFired() { 2043 void Textfield::OnCursorBlinkTimerFired() {
2108 DCHECK(ShouldBlinkCursor()); 2044 DCHECK(ShouldBlinkCursor());
2109 gfx::RenderText* render_text = GetRenderText(); 2045 gfx::RenderText* render_text = GetRenderText();
2110 render_text->set_cursor_visible(!render_text->cursor_visible()); 2046 render_text->set_cursor_visible(!render_text->cursor_visible());
2111 RepaintCursor(); 2047 RepaintCursor();
2112 } 2048 }
2113 2049
2114 } // namespace views 2050 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698