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

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

Issue 2408623002: Views: Extract text selection code from Textfield. (Closed)
Patch Set: Address nits. 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
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 model_->InsertText(new_text); 315 model_->InsertText(new_text);
329 UpdateAfterChange(true, true); 316 UpdateAfterChange(true, true);
330 } 317 }
331 318
332 base::string16 Textfield::GetSelectedText() const { 319 base::string16 Textfield::GetSelectedText() const {
333 return model_->GetSelectedText(); 320 return model_->GetSelectedText();
334 } 321 }
335 322
336 void Textfield::SelectAll(bool reversed) { 323 void Textfield::SelectAll(bool reversed) {
337 model_->SelectAll(reversed); 324 model_->SelectAll(reversed);
338 UpdateSelectionClipboard(); 325 if (HasSelection() && performing_user_action_)
326 UpdateSelectionClipboard();
339 UpdateAfterChange(false, true); 327 UpdateAfterChange(false, true);
340 } 328 }
341 329
342 void Textfield::SelectWordAt(const gfx::Point& point) { 330 void Textfield::SelectWordAt(const gfx::Point& point) {
343 model_->MoveCursorTo(point, false); 331 model_->MoveCursorTo(point, false);
344 model_->SelectWord(); 332 model_->SelectWord();
345 UpdateAfterChange(false, true); 333 UpdateAfterChange(false, true);
346 } 334 }
347 335
348 void Textfield::ClearSelection() { 336 void Textfield::ClearSelection() {
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 } 526 }
539 527
540 void Textfield::ClearEditHistory() { 528 void Textfield::ClearEditHistory() {
541 model_->ClearEditHistory(); 529 model_->ClearEditHistory();
542 } 530 }
543 531
544 void Textfield::SetAccessibleName(const base::string16& name) { 532 void Textfield::SetAccessibleName(const base::string16& name) {
545 accessible_name_ = name; 533 accessible_name_ = name;
546 } 534 }
547 535
548 bool Textfield::HasTextBeingDragged() {
549 return initiating_drag_;
550 }
551
552 //////////////////////////////////////////////////////////////////////////////// 536 ////////////////////////////////////////////////////////////////////////////////
553 // Textfield, View overrides: 537 // Textfield, View overrides:
554 538
555 gfx::Insets Textfield::GetInsets() const { 539 gfx::Insets Textfield::GetInsets() const {
556 gfx::Insets insets = View::GetInsets(); 540 gfx::Insets insets = View::GetInsets();
557 insets += gfx::Insets(kTextPadding, kTextPadding, kTextPadding, kTextPadding); 541 insets += gfx::Insets(kTextPadding, kTextPadding, kTextPadding, kTextPadding);
558 return insets; 542 return insets;
559 } 543 }
560 544
561 int Textfield::GetBaseline() const { 545 int Textfield::GetBaseline() const {
(...skipping 18 matching lines...) Expand all
580 } 564 }
581 565
582 gfx::NativeCursor Textfield::GetCursor(const ui::MouseEvent& event) { 566 gfx::NativeCursor Textfield::GetCursor(const ui::MouseEvent& event) {
583 bool in_selection = GetRenderText()->IsPointInSelection(event.location()); 567 bool in_selection = GetRenderText()->IsPointInSelection(event.location());
584 bool drag_event = event.type() == ui::ET_MOUSE_DRAGGED; 568 bool drag_event = event.type() == ui::ET_MOUSE_DRAGGED;
585 bool text_cursor = !initiating_drag_ && (drag_event || !in_selection); 569 bool text_cursor = !initiating_drag_ && (drag_event || !in_selection);
586 return text_cursor ? GetNativeIBeamCursor() : gfx::kNullCursor; 570 return text_cursor ? GetNativeIBeamCursor() : gfx::kNullCursor;
587 } 571 }
588 572
589 bool Textfield::OnMousePressed(const ui::MouseEvent& event) { 573 bool Textfield::OnMousePressed(const ui::MouseEvent& event) {
590 TrackMouseClicks(event); 574 bool handled = controller_ && controller_->HandleMouseEvent(this, event);
591 575 if (!handled &&
592 if (!controller_ || !controller_->HandleMouseEvent(this, event)) { 576 (event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton())) {
593 if (event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton()) { 577 RequestFocus();
594 RequestFocus(); 578 ShowImeIfNeeded();
595 ShowImeIfNeeded(); 579 }
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 580
621 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 581 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
622 if (event.IsOnlyMiddleMouseButton()) { 582 if (!handled && !HasFocus() && event.IsOnlyMiddleMouseButton())
623 if (GetRenderText()->IsPointInSelection(event.location())) { 583 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 584 #endif
634 }
635 585
636 return true; 586 return selection_controller_.OnMousePressed(event, handled);
637 } 587 }
638 588
639 bool Textfield::OnMouseDragged(const ui::MouseEvent& event) { 589 bool Textfield::OnMouseDragged(const ui::MouseEvent& event) {
640 last_drag_location_ = event.location(); 590 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 } 591 }
662 592
663 void Textfield::OnMouseReleased(const ui::MouseEvent& event) { 593 void Textfield::OnMouseReleased(const ui::MouseEvent& event) {
664 OnBeforeUserAction(); 594 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 } 595 }
673 596
674 WordLookupClient* Textfield::GetWordLookupClient() { 597 WordLookupClient* Textfield::GetWordLookupClient() {
675 return this; 598 return this;
676 } 599 }
677 600
678 bool Textfield::OnKeyPressed(const ui::KeyEvent& event) { 601 bool Textfield::OnKeyPressed(const ui::KeyEvent& event) {
679 ui::TextEditCommand edit_command = scheduled_text_edit_command_; 602 ui::TextEditCommand edit_command = scheduled_text_edit_command_;
680 scheduled_text_edit_command_ = ui::TextEditCommand::INVALID_COMMAND; 603 scheduled_text_edit_command_ = ui::TextEditCommand::INVALID_COMMAND;
681 604
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 // Textfield, WordLookupClient overrides: 1052 // Textfield, WordLookupClient overrides:
1130 1053
1131 bool Textfield::GetDecoratedWordAtPoint(const gfx::Point& point, 1054 bool Textfield::GetDecoratedWordAtPoint(const gfx::Point& point,
1132 gfx::DecoratedText* decorated_word, 1055 gfx::DecoratedText* decorated_word,
1133 gfx::Point* baseline_point) { 1056 gfx::Point* baseline_point) {
1134 return GetRenderText()->GetDecoratedWordAtPoint(point, decorated_word, 1057 return GetRenderText()->GetDecoratedWordAtPoint(point, decorated_word,
1135 baseline_point); 1058 baseline_point);
1136 } 1059 }
1137 1060
1138 //////////////////////////////////////////////////////////////////////////////// 1061 ////////////////////////////////////////////////////////////////////////////////
1062 // Textfield, SelectionControllerDelegate overrides:
1063
1064 bool Textfield::HasTextBeingDragged() const {
1065 return initiating_drag_;
1066 }
1067
1068 ////////////////////////////////////////////////////////////////////////////////
1139 // Textfield, ui::TouchEditable overrides: 1069 // Textfield, ui::TouchEditable overrides:
1140 1070
1141 void Textfield::SelectRect(const gfx::Point& start, const gfx::Point& end) { 1071 void Textfield::SelectRect(const gfx::Point& start, const gfx::Point& end) {
1142 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) 1072 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE)
1143 return; 1073 return;
1144 1074
1145 gfx::SelectionModel start_caret = GetRenderText()->FindCursorPosition(start); 1075 gfx::SelectionModel start_caret = GetRenderText()->FindCursorPosition(start);
1146 gfx::SelectionModel end_caret = GetRenderText()->FindCursorPosition(end); 1076 gfx::SelectionModel end_caret = GetRenderText()->FindCursorPosition(end);
1147 gfx::SelectionModel selection( 1077 gfx::SelectionModel selection(
1148 gfx::Range(start_caret.caret_pos(), end_caret.caret_pos()), 1078 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; 1524 skip_input_method_cancel_composition_ = false;
1595 1525
1596 UpdateAfterChange(true, true); 1526 UpdateAfterChange(true, true);
1597 OnAfterUserAction(); 1527 OnAfterUserAction();
1598 } 1528 }
1599 1529
1600 gfx::RenderText* Textfield::GetRenderText() const { 1530 gfx::RenderText* Textfield::GetRenderText() const {
1601 return model_->render_text(); 1531 return model_->render_text();
1602 } 1532 }
1603 1533
1534 gfx::Point Textfield::GetLastClickLocation() const {
1535 return selection_controller_.last_click_location();
1536 }
1537
1604 base::string16 Textfield::GetSelectionClipboardText() const { 1538 base::string16 Textfield::GetSelectionClipboardText() const {
1605 base::string16 selection_clipboard_text; 1539 base::string16 selection_clipboard_text;
1606 ui::Clipboard::GetForCurrentThread()->ReadText( 1540 ui::Clipboard::GetForCurrentThread()->ReadText(
1607 ui::CLIPBOARD_TYPE_SELECTION, &selection_clipboard_text); 1541 ui::CLIPBOARD_TYPE_SELECTION, &selection_clipboard_text);
1608 return selection_clipboard_text; 1542 return selection_clipboard_text;
1609 } 1543 }
1610 1544
1611 void Textfield::ExecuteTextEditCommand(ui::TextEditCommand command) { 1545 void Textfield::ExecuteTextEditCommand(ui::TextEditCommand command) {
1612 DestroyTouchSelection(); 1546 DestroyTouchSelection();
1613 1547
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1792 break; 1726 break;
1793 case ui::TextEditCommand::INSERT_TEXT: 1727 case ui::TextEditCommand::INSERT_TEXT:
1794 case ui::TextEditCommand::SET_MARK: 1728 case ui::TextEditCommand::SET_MARK:
1795 case ui::TextEditCommand::UNSELECT: 1729 case ui::TextEditCommand::UNSELECT:
1796 case ui::TextEditCommand::INVALID_COMMAND: 1730 case ui::TextEditCommand::INVALID_COMMAND:
1797 NOTREACHED(); 1731 NOTREACHED();
1798 break; 1732 break;
1799 } 1733 }
1800 1734
1801 cursor_changed |= GetSelectionModel() != selection_model; 1735 cursor_changed |= GetSelectionModel() != selection_model;
1802 if (cursor_changed) 1736 if (cursor_changed && HasSelection())
1803 UpdateSelectionClipboard(); 1737 UpdateSelectionClipboard();
1804 UpdateAfterChange(text_changed, cursor_changed); 1738 UpdateAfterChange(text_changed, cursor_changed);
1805 OnAfterUserAction(); 1739 OnAfterUserAction();
1806 } 1740 }
1807 1741
1808 //////////////////////////////////////////////////////////////////////////////// 1742 ////////////////////////////////////////////////////////////////////////////////
1809 // Textfield, private: 1743 // Textfield, private:
1810 1744
1745 ////////////////////////////////////////////////////////////////////////////////
1746 // Textfield, SelectionControllerDelegate overrides:
1747
1748 gfx::RenderText* Textfield::GetRenderTextForSelectionController() {
1749 return GetRenderText();
1750 }
1751
1752 bool Textfield::IsReadOnly() const {
1753 return read_only();
1754 }
1755
1756 void Textfield::SetTextBeingDragged(bool value) {
1757 initiating_drag_ = value;
1758 }
1759
1760 int Textfield::GetViewHeight() const {
1761 return height();
1762 }
1763
1764 int Textfield::GetViewWidth() const {
1765 return width();
1766 }
1767
1768 int Textfield::GetDragSelectionDelay() const {
1769 switch (ui::ScopedAnimationDurationScaleMode::duration_scale_mode()) {
1770 case ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION:
1771 return 100;
1772 case ui::ScopedAnimationDurationScaleMode::FAST_DURATION:
1773 return 25;
1774 case ui::ScopedAnimationDurationScaleMode::SLOW_DURATION:
1775 return 400;
1776 case ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION:
1777 return 1;
1778 case ui::ScopedAnimationDurationScaleMode::ZERO_DURATION:
1779 return 0;
1780 }
1781 return 100;
1782 }
1783
1784 void Textfield::OnBeforeMouseAction() {
1785 OnBeforeUserAction();
1786 if (model_->HasCompositionText())
1787 model_->ConfirmCompositionText();
1788 }
1789
1790 void Textfield::OnAfterMouseAction(bool text_changed, bool selection_changed) {
1791 OnAfterUserAction();
1792 UpdateAfterChange(text_changed, selection_changed);
1793 }
1794
1795 bool Textfield::PasteSelectionClipboard() {
1796 DCHECK(performing_user_action_);
1797 DCHECK(!read_only());
1798 const base::string16 selection_clipboard_text = GetSelectionClipboardText();
1799 if (selection_clipboard_text.empty())
1800 return false;
1801
1802 model_->InsertText(selection_clipboard_text);
1803 return true;
1804 }
1805
1806 void Textfield::UpdateSelectionClipboard() {
1807 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
1808 if (text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD) {
1809 ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_SELECTION)
1810 .WriteText(GetSelectedText());
1811 if (controller_)
1812 controller_->OnAfterCutOrCopy(ui::CLIPBOARD_TYPE_SELECTION);
1813 }
1814 #endif
1815 }
1816
1811 void Textfield::AccessibilitySetValue(const base::string16& new_value) { 1817 void Textfield::AccessibilitySetValue(const base::string16& new_value) {
1812 if (!read_only()) { 1818 if (!read_only()) {
1813 SetText(new_value); 1819 SetText(new_value);
1814 ClearSelection(); 1820 ClearSelection();
1815 } 1821 }
1816 } 1822 }
1817 1823
1818 void Textfield::UpdateBackgroundColor() { 1824 void Textfield::UpdateBackgroundColor() {
1819 const SkColor color = GetBackgroundColor(); 1825 const SkColor color = GetBackgroundColor();
1820 if (ui::MaterialDesignController::IsSecondaryUiMaterial()) { 1826 if (ui::MaterialDesignController::IsSecondaryUiMaterial()) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1891 render_text->DrawCursor(canvas, drop_cursor_position_); 1897 render_text->DrawCursor(canvas, drop_cursor_position_);
1892 1898
1893 canvas->Restore(); 1899 canvas->Restore();
1894 } 1900 }
1895 1901
1896 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) { 1902 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) {
1897 if (model_->MoveCursorTo(point, select)) 1903 if (model_->MoveCursorTo(point, select))
1898 UpdateAfterChange(false, true); 1904 UpdateAfterChange(false, true);
1899 } 1905 }
1900 1906
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() { 1907 void Textfield::OnCaretBoundsChanged() {
1935 if (GetInputMethod()) 1908 if (GetInputMethod())
1936 GetInputMethod()->OnCaretBoundsChanged(this); 1909 GetInputMethod()->OnCaretBoundsChanged(this);
1937 if (touch_selection_controller_) 1910 if (touch_selection_controller_)
1938 touch_selection_controller_->SelectionChanged(); 1911 touch_selection_controller_->SelectionChanged();
1939 } 1912 }
1940 1913
1941 void Textfield::OnBeforeUserAction() { 1914 void Textfield::OnBeforeUserAction() {
1942 DCHECK(!performing_user_action_); 1915 DCHECK(!performing_user_action_);
1943 performing_user_action_ = true; 1916 performing_user_action_ = true;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1997 // IsCommandIdEnabled() as appropriate, for the commands added. 1970 // IsCommandIdEnabled() as appropriate, for the commands added.
1998 if (controller_) 1971 if (controller_)
1999 controller_->UpdateContextMenu(context_menu_contents_.get()); 1972 controller_->UpdateContextMenu(context_menu_contents_.get());
2000 } 1973 }
2001 context_menu_runner_.reset(new MenuRunner(context_menu_contents_.get(), 1974 context_menu_runner_.reset(new MenuRunner(context_menu_contents_.get(),
2002 MenuRunner::HAS_MNEMONICS | 1975 MenuRunner::HAS_MNEMONICS |
2003 MenuRunner::CONTEXT_MENU | 1976 MenuRunner::CONTEXT_MENU |
2004 MenuRunner::ASYNC)); 1977 MenuRunner::ASYNC));
2005 } 1978 }
2006 1979
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 { 1980 bool Textfield::ImeEditingAllowed() const {
2026 // Disallow input method editing of password fields. 1981 // Disallow input method editing of password fields.
2027 ui::TextInputType t = GetTextInputType(); 1982 ui::TextInputType t = GetTextInputType();
2028 return (t != ui::TEXT_INPUT_TYPE_NONE && t != ui::TEXT_INPUT_TYPE_PASSWORD); 1983 return (t != ui::TEXT_INPUT_TYPE_NONE && t != ui::TEXT_INPUT_TYPE_PASSWORD);
2029 } 1984 }
2030 1985
2031 void Textfield::RevealPasswordChar(int index) { 1986 void Textfield::RevealPasswordChar(int index) {
2032 GetRenderText()->SetObscuredRevealIndex(index); 1987 GetRenderText()->SetObscuredRevealIndex(index);
2033 SchedulePaint(); 1988 SchedulePaint();
2034 1989
2035 if (index != -1) { 1990 if (index != -1) {
2036 password_reveal_timer_.Start(FROM_HERE, GetPasswordRevealDuration(), 1991 password_reveal_timer_.Start(FROM_HERE, GetPasswordRevealDuration(),
2037 base::Bind(&Textfield::RevealPasswordChar, 1992 base::Bind(&Textfield::RevealPasswordChar,
2038 weak_ptr_factory_.GetWeakPtr(), -1)); 1993 weak_ptr_factory_.GetWeakPtr(), -1));
2039 } 1994 }
2040 } 1995 }
2041 1996
2042 void Textfield::CreateTouchSelectionControllerAndNotifyIt() { 1997 void Textfield::CreateTouchSelectionControllerAndNotifyIt() {
2043 if (!HasFocus()) 1998 if (!HasFocus())
2044 return; 1999 return;
2045 2000
2046 if (!touch_selection_controller_) { 2001 if (!touch_selection_controller_) {
2047 touch_selection_controller_.reset( 2002 touch_selection_controller_.reset(
2048 ui::TouchEditingControllerDeprecated::Create(this)); 2003 ui::TouchEditingControllerDeprecated::Create(this));
2049 } 2004 }
2050 if (touch_selection_controller_) 2005 if (touch_selection_controller_)
2051 touch_selection_controller_->SelectionChanged(); 2006 touch_selection_controller_->SelectionChanged();
2052 } 2007 }
2053 2008
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() { 2009 void Textfield::OnEditFailed() {
2084 PlatformStyle::OnTextfieldEditFailed(); 2010 PlatformStyle::OnTextfieldEditFailed();
2085 } 2011 }
2086 2012
2087 bool Textfield::ShouldShowCursor() const { 2013 bool Textfield::ShouldShowCursor() const {
2088 return HasFocus() && !HasSelection() && enabled() && !read_only() && 2014 return HasFocus() && !HasSelection() && enabled() && !read_only() &&
2089 !drop_cursor_visible_; 2015 !drop_cursor_visible_;
2090 } 2016 }
2091 2017
2092 bool Textfield::ShouldBlinkCursor() const { 2018 bool Textfield::ShouldBlinkCursor() const {
(...skipping 12 matching lines...) Expand all
2105 } 2031 }
2106 2032
2107 void Textfield::OnCursorBlinkTimerFired() { 2033 void Textfield::OnCursorBlinkTimerFired() {
2108 DCHECK(ShouldBlinkCursor()); 2034 DCHECK(ShouldBlinkCursor());
2109 gfx::RenderText* render_text = GetRenderText(); 2035 gfx::RenderText* render_text = GetRenderText();
2110 render_text->set_cursor_visible(!render_text->cursor_visible()); 2036 render_text->set_cursor_visible(!render_text->cursor_visible());
2111 RepaintCursor(); 2037 RepaintCursor();
2112 } 2038 }
2113 2039
2114 } // namespace views 2040 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698