OLD | NEW |
---|---|
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 | 8 |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "grit/ui_strings.h" | 10 #include "grit/ui_strings.h" |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
264 selection_text_color_(SK_ColorWHITE), | 264 selection_text_color_(SK_ColorWHITE), |
265 selection_background_color_(SK_ColorBLUE), | 265 selection_background_color_(SK_ColorBLUE), |
266 placeholder_text_color_(kDefaultPlaceholderTextColor), | 266 placeholder_text_color_(kDefaultPlaceholderTextColor), |
267 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT), | 267 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT), |
268 performing_user_action_(false), | 268 performing_user_action_(false), |
269 skip_input_method_cancel_composition_(false), | 269 skip_input_method_cancel_composition_(false), |
270 cursor_visible_(false), | 270 cursor_visible_(false), |
271 drop_cursor_visible_(false), | 271 drop_cursor_visible_(false), |
272 initiating_drag_(false), | 272 initiating_drag_(false), |
273 aggregated_clicks_(0), | 273 aggregated_clicks_(0), |
274 drag_start_display_offset_(0), | |
275 touch_handles_hidden_due_to_scroll_(false), | |
274 weak_ptr_factory_(this) { | 276 weak_ptr_factory_(this) { |
275 set_context_menu_controller(this); | 277 set_context_menu_controller(this); |
276 set_drag_controller(this); | 278 set_drag_controller(this); |
277 SetBorder(scoped_ptr<Border>(new FocusableBorder())); | 279 SetBorder(scoped_ptr<Border>(new FocusableBorder())); |
278 SetFocusable(true); | 280 SetFocusable(true); |
279 | 281 |
280 if (ViewsDelegate::views_delegate) { | 282 if (ViewsDelegate::views_delegate) { |
281 password_reveal_duration_ = ViewsDelegate::views_delegate-> | 283 password_reveal_duration_ = ViewsDelegate::views_delegate-> |
282 GetDefaultTextfieldObscuredRevealDuration(); | 284 GetDefaultTextfieldObscuredRevealDuration(); |
283 } | 285 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
333 base::string16 Textfield::GetSelectedText() const { | 335 base::string16 Textfield::GetSelectedText() const { |
334 return model_->GetSelectedText(); | 336 return model_->GetSelectedText(); |
335 } | 337 } |
336 | 338 |
337 void Textfield::SelectAll(bool reversed) { | 339 void Textfield::SelectAll(bool reversed) { |
338 model_->SelectAll(reversed); | 340 model_->SelectAll(reversed); |
339 UpdateSelectionClipboard(); | 341 UpdateSelectionClipboard(); |
340 UpdateAfterChange(false, true); | 342 UpdateAfterChange(false, true); |
341 } | 343 } |
342 | 344 |
345 void Textfield::SelectWordAt(const gfx::Point& point) { | |
346 model_->MoveCursorTo(point, false); | |
347 model_->SelectWord(); | |
348 UpdateAfterChange(false, true); | |
349 } | |
350 | |
343 void Textfield::ClearSelection() { | 351 void Textfield::ClearSelection() { |
344 model_->ClearSelection(); | 352 model_->ClearSelection(); |
345 UpdateAfterChange(false, true); | 353 UpdateAfterChange(false, true); |
346 } | 354 } |
347 | 355 |
348 bool Textfield::HasSelection() const { | 356 bool Textfield::HasSelection() const { |
349 return !GetSelectedRange().is_empty(); | 357 return !GetSelectedRange().is_empty(); |
350 } | 358 } |
351 | 359 |
352 SkColor Textfield::GetTextColor() const { | 360 SkColor Textfield::GetTextColor() const { |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
576 OnBeforeUserAction(); | 584 OnBeforeUserAction(); |
577 initiating_drag_ = false; | 585 initiating_drag_ = false; |
578 switch (aggregated_clicks_) { | 586 switch (aggregated_clicks_) { |
579 case 0: | 587 case 0: |
580 if (GetRenderText()->IsPointInSelection(event.location())) | 588 if (GetRenderText()->IsPointInSelection(event.location())) |
581 initiating_drag_ = true; | 589 initiating_drag_ = true; |
582 else | 590 else |
583 MoveCursorTo(event.location(), event.IsShiftDown()); | 591 MoveCursorTo(event.location(), event.IsShiftDown()); |
584 break; | 592 break; |
585 case 1: | 593 case 1: |
586 model_->MoveCursorTo(event.location(), false); | 594 SelectWordAt(event.location()); |
587 model_->SelectWord(); | |
588 UpdateAfterChange(false, true); | |
589 double_click_word_ = GetRenderText()->selection(); | 595 double_click_word_ = GetRenderText()->selection(); |
590 break; | 596 break; |
591 case 2: | 597 case 2: |
592 SelectAll(false); | 598 SelectAll(false); |
593 break; | 599 break; |
594 default: | 600 default: |
595 NOTREACHED(); | 601 NOTREACHED(); |
596 } | 602 } |
597 OnAfterUserAction(); | 603 OnAfterUserAction(); |
598 } | 604 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
686 return handled; | 692 return handled; |
687 } | 693 } |
688 | 694 |
689 ui::TextInputClient* Textfield::GetTextInputClient() { | 695 ui::TextInputClient* Textfield::GetTextInputClient() { |
690 return read_only_ ? NULL : this; | 696 return read_only_ ? NULL : this; |
691 } | 697 } |
692 | 698 |
693 void Textfield::OnGestureEvent(ui::GestureEvent* event) { | 699 void Textfield::OnGestureEvent(ui::GestureEvent* event) { |
694 switch (event->type()) { | 700 switch (event->type()) { |
695 case ui::ET_GESTURE_TAP_DOWN: | 701 case ui::ET_GESTURE_TAP_DOWN: |
696 OnBeforeUserAction(); | |
697 RequestFocus(); | 702 RequestFocus(); |
698 ShowImeIfNeeded(); | 703 ShowImeIfNeeded(); |
699 | |
700 // We don't deselect if the point is in the selection | |
701 // because TAP_DOWN may turn into a LONG_PRESS. | |
702 if (!GetRenderText()->IsPointInSelection(event->location())) | |
703 MoveCursorTo(event->location(), false); | |
704 OnAfterUserAction(); | |
705 event->SetHandled(); | |
706 break; | |
707 case ui::ET_GESTURE_SCROLL_UPDATE: | |
708 OnBeforeUserAction(); | |
709 MoveCursorTo(event->location(), true); | |
710 OnAfterUserAction(); | |
711 event->SetHandled(); | |
712 break; | |
713 case ui::ET_GESTURE_SCROLL_END: | |
714 case ui::ET_SCROLL_FLING_START: | |
715 CreateTouchSelectionControllerAndNotifyIt(); | |
716 event->SetHandled(); | 704 event->SetHandled(); |
717 break; | 705 break; |
718 case ui::ET_GESTURE_TAP: | 706 case ui::ET_GESTURE_TAP: |
719 if (event->details().tap_count() == 1) { | 707 if (event->details().tap_count() == 1) { |
720 CreateTouchSelectionControllerAndNotifyIt(); | 708 if (!GetRenderText()->IsPointInSelection(event->location())) { |
709 OnBeforeUserAction(); | |
710 MoveCursorTo(event->location(), false); | |
711 OnAfterUserAction(); | |
712 } | |
713 } else if (event->details().tap_count() == 2) { | |
714 OnBeforeUserAction(); | |
715 SelectWordAt(event->location()); | |
716 OnAfterUserAction(); | |
721 } else { | 717 } else { |
722 DestroyTouchSelection(); | |
723 OnBeforeUserAction(); | 718 OnBeforeUserAction(); |
724 SelectAll(false); | 719 SelectAll(false); |
725 OnAfterUserAction(); | 720 OnAfterUserAction(); |
726 event->SetHandled(); | |
727 } | 721 } |
722 CreateTouchSelectionControllerAndNotifyIt(); | |
728 #if defined(OS_WIN) | 723 #if defined(OS_WIN) |
729 if (!read_only()) | 724 if (!read_only()) |
730 base::win::DisplayVirtualKeyboard(); | 725 base::win::DisplayVirtualKeyboard(); |
731 #endif | 726 #endif |
727 event->SetHandled(); | |
732 break; | 728 break; |
733 case ui::ET_GESTURE_LONG_PRESS: | 729 case ui::ET_GESTURE_LONG_PRESS: |
734 // If long press happens outside selection, select word and show context | |
735 // menu (If touch selection is enabled, context menu is shown by the | |
736 // |touch_selection_controller_|, hence we mark the event handled. | |
737 // Otherwise, the regular context menu will be shown by views). | |
738 // If long press happens in selected text and touch drag drop is enabled, | |
739 // we will turn off touch selection (if one exists) and let views do drag | |
740 // drop. | |
741 if (!GetRenderText()->IsPointInSelection(event->location())) { | 730 if (!GetRenderText()->IsPointInSelection(event->location())) { |
731 // If long-press happens outside selection, select word and try to | |
732 // activate touch selection. | |
742 OnBeforeUserAction(); | 733 OnBeforeUserAction(); |
743 model_->SelectWord(); | 734 SelectWordAt(event->location()); |
744 touch_selection_controller_.reset( | |
745 ui::TouchSelectionController::create(this)); | |
746 UpdateAfterChange(false, true); | |
747 OnAfterUserAction(); | 735 OnAfterUserAction(); |
736 CreateTouchSelectionControllerAndNotifyIt(); | |
737 // If touch selection activated successfully, mark event as handled so | |
738 // that the regular context menu is not shown. | |
748 if (touch_selection_controller_) | 739 if (touch_selection_controller_) |
749 event->SetHandled(); | 740 event->SetHandled(); |
750 } else if (switches::IsTouchDragDropEnabled()) { | 741 } else { |
751 initiating_drag_ = true; | 742 // If long-press happens on the selection, deactivate touch selection |
743 // and try to initiate drag-drop. If drag-drop is not enabled, context | |
744 // menu will be shown. Event is not marked as handled to let Views | |
745 // handle drag-drop or context menu. | |
752 DestroyTouchSelection(); | 746 DestroyTouchSelection(); |
753 } else { | 747 initiating_drag_ = switches::IsTouchDragDropEnabled(); |
754 if (!touch_selection_controller_) | |
755 CreateTouchSelectionControllerAndNotifyIt(); | |
756 if (touch_selection_controller_) | |
757 event->SetHandled(); | |
758 } | 748 } |
759 return; | 749 break; |
760 case ui::ET_GESTURE_LONG_TAP: | 750 case ui::ET_GESTURE_LONG_TAP: |
761 if (!touch_selection_controller_) | |
762 CreateTouchSelectionControllerAndNotifyIt(); | |
763 | |
764 // If touch selection is enabled, the context menu on long tap will be | 751 // If touch selection is enabled, the context menu on long tap will be |
765 // shown by the |touch_selection_controller_|, hence we mark the event | 752 // shown by the |touch_selection_controller_|, hence we mark the event |
766 // handled so views does not try to show context menu on it. | 753 // handled so Views does not try to show context menu on it. |
767 if (touch_selection_controller_) | 754 if (touch_selection_controller_) |
768 event->SetHandled(); | 755 event->SetHandled(); |
769 break; | 756 break; |
757 case ui::ET_GESTURE_SCROLL_BEGIN: | |
758 touch_handles_hidden_due_to_scroll_ = touch_selection_controller_; | |
sky
2014/07/21 22:37:43
I'm surprised you don't get a compile warning here
mohsen
2014/07/21 23:07:56
Really? Didn't know it's not allowed. Fixed.
| |
759 DestroyTouchSelection(); | |
760 drag_start_location_ = event->location(); | |
761 drag_start_display_offset_ = | |
762 GetRenderText()->GetUpdatedDisplayOffset().x(); | |
763 event->SetHandled(); | |
764 break; | |
765 case ui::ET_GESTURE_SCROLL_UPDATE: { | |
766 int new_offset = drag_start_display_offset_ + event->location().x() - | |
767 drag_start_location_.x(); | |
768 GetRenderText()->SetDisplayOffset(new_offset); | |
769 SchedulePaint(); | |
770 event->SetHandled(); | |
771 break; | |
772 } | |
773 case ui::ET_GESTURE_SCROLL_END: | |
774 case ui::ET_SCROLL_FLING_START: | |
775 if (touch_handles_hidden_due_to_scroll_) { | |
776 CreateTouchSelectionControllerAndNotifyIt(); | |
777 touch_handles_hidden_due_to_scroll_ = false; | |
778 } | |
779 event->SetHandled(); | |
780 break; | |
770 default: | 781 default: |
771 return; | 782 return; |
772 } | 783 } |
773 } | 784 } |
774 | 785 |
775 void Textfield::AboutToRequestFocusFromTabTraversal(bool reverse) { | 786 void Textfield::AboutToRequestFocusFromTabTraversal(bool reverse) { |
776 SelectAll(false); | 787 SelectAll(false); |
777 } | 788 } |
778 | 789 |
779 bool Textfield::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) { | 790 bool Textfield::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) { |
(...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1778 const size_t length = selection_clipboard_text.length(); | 1789 const size_t length = selection_clipboard_text.length(); |
1779 range = gfx::Range(range.start() + length, range.end() + length); | 1790 range = gfx::Range(range.start() + length, range.end() + length); |
1780 } | 1791 } |
1781 model_->MoveCursorTo(gfx::SelectionModel(range, affinity)); | 1792 model_->MoveCursorTo(gfx::SelectionModel(range, affinity)); |
1782 UpdateAfterChange(true, true); | 1793 UpdateAfterChange(true, true); |
1783 OnAfterUserAction(); | 1794 OnAfterUserAction(); |
1784 } | 1795 } |
1785 } | 1796 } |
1786 | 1797 |
1787 } // namespace views | 1798 } // namespace views |
OLD | NEW |