Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "views/controls/textfield/native_textfield_views.h" | 5 #include "views/controls/textfield/native_textfield_views.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 52 const char NativeTextfieldViews::kViewClassName[] = | 52 const char NativeTextfieldViews::kViewClassName[] = |
| 53 "views/NativeTextfieldViews"; | 53 "views/NativeTextfieldViews"; |
| 54 | 54 |
| 55 NativeTextfieldViews::NativeTextfieldViews(Textfield* parent) | 55 NativeTextfieldViews::NativeTextfieldViews(Textfield* parent) |
| 56 : textfield_(parent), | 56 : textfield_(parent), |
| 57 model_(new TextfieldViewsModel()), | 57 model_(new TextfieldViewsModel()), |
| 58 text_border_(new TextfieldBorder()), | 58 text_border_(new TextfieldBorder()), |
| 59 text_offset_(0), | 59 text_offset_(0), |
| 60 insert_(true), | 60 insert_(true), |
| 61 is_cursor_visible_(false), | 61 is_cursor_visible_(false), |
| 62 ALLOW_THIS_IN_INITIALIZER_LIST(cursor_timer_(this)) { | 62 ALLOW_THIS_IN_INITIALIZER_LIST(cursor_timer_(this)), |
| 63 last_mouse_press_time_(base::Time::FromInternalValue(0)), | |
| 64 tracking_double_click_(false), | |
| 65 tracking_triple_click_(false) { | |
| 63 set_border(text_border_); | 66 set_border(text_border_); |
| 64 | 67 |
| 65 // Multiline is not supported. | 68 // Multiline is not supported. |
| 66 DCHECK_NE(parent->style(), Textfield::STYLE_MULTILINE); | 69 DCHECK_NE(parent->style(), Textfield::STYLE_MULTILINE); |
| 67 // Lowercase is not supported. | 70 // Lowercase is not supported. |
| 68 DCHECK_NE(parent->style(), Textfield::STYLE_LOWERCASE); | 71 DCHECK_NE(parent->style(), Textfield::STYLE_LOWERCASE); |
| 69 | 72 |
| 70 SetContextMenuController(this); | 73 SetContextMenuController(this); |
| 71 } | 74 } |
| 72 | 75 |
| 73 NativeTextfieldViews::~NativeTextfieldViews() { | 76 NativeTextfieldViews::~NativeTextfieldViews() { |
| 74 } | 77 } |
| 75 | 78 |
| 76 //////////////////////////////////////////////////////////////////////////////// | 79 //////////////////////////////////////////////////////////////////////////////// |
| 77 // NativeTextfieldViews, View overrides: | 80 // NativeTextfieldViews, View overrides: |
| 78 | 81 |
| 79 bool NativeTextfieldViews::OnMousePressed(const views::MouseEvent& e) { | 82 bool NativeTextfieldViews::OnMousePressed(const views::MouseEvent& e) { |
| 80 textfield_->RequestFocus(); | 83 textfield_->RequestFocus(); |
| 81 if (e.IsLeftMouseButton()) { | 84 if (DetectAndHandleDoubleAndTripleClick(e)) { |
| 85 SchedulePaint(); | |
| 86 } else if (e.IsLeftMouseButton()) { | |
| 82 size_t pos = FindCursorPosition(e.location()); | 87 size_t pos = FindCursorPosition(e.location()); |
| 83 if (model_->MoveCursorTo(pos, false)) { | 88 if (model_->MoveCursorTo(pos, false)) { |
|
oshima
2011/01/25 19:31:59
It's probably better to move this logic to GetClic
varunjain
2011/01/25 20:10:40
Done.
| |
| 84 UpdateCursorBoundsAndTextOffset(); | 89 UpdateCursorBoundsAndTextOffset(); |
| 85 SchedulePaint(); | 90 SchedulePaint(); |
| 86 } | 91 } |
| 87 } | 92 } |
| 88 return true; | 93 return true; |
| 89 } | 94 } |
| 90 | 95 |
| 91 bool NativeTextfieldViews::OnMouseDragged(const views::MouseEvent& e) { | 96 bool NativeTextfieldViews::OnMouseDragged(const views::MouseEvent& e) { |
| 92 size_t pos = FindCursorPosition(e.location()); | 97 size_t pos = FindCursorPosition(e.location()); |
| 93 if (model_->MoveCursorTo(pos, true)) { | 98 if (model_->MoveCursorTo(pos, true)) { |
| (...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 777 } else if (pivot == x) { | 782 } else if (pivot == x) { |
| 778 return pivot_pos; | 783 return pivot_pos; |
| 779 } else { | 784 } else { |
| 780 right = pivot; | 785 right = pivot; |
| 781 right_pos = pivot_pos; | 786 right_pos = pivot_pos; |
| 782 } | 787 } |
| 783 } | 788 } |
| 784 return left_pos; | 789 return left_pos; |
| 785 } | 790 } |
| 786 | 791 |
| 792 bool NativeTextfieldViews::DetectAndHandleDoubleAndTripleClick( | |
| 793 const views::MouseEvent& e) { | |
| 794 switch(GetClickAction(e)) { | |
| 795 case SELECT_WORD: | |
| 796 model_->SelectWord(); | |
| 797 return true; | |
| 798 case SELECT_ALL: | |
| 799 model_->SelectAll(); | |
| 800 return true; | |
| 801 case CURSOR_SELECT: | |
| 802 tracking_double_click_ = true; | |
| 803 return false; | |
| 804 default: | |
| 805 return false; | |
| 806 } | |
| 807 } | |
| 808 | |
| 809 NativeTextfieldViews::ClickAction NativeTextfieldViews::GetClickAction( | |
| 810 const views::MouseEvent& e) { | |
| 811 base::TimeDelta time_delta = e.GetTimeStamp() - last_mouse_press_time_; | |
| 812 gfx::Point location_delta = e.location().Subtract(last_mouse_press_location_); | |
| 813 last_mouse_press_time_ = e.GetTimeStamp(); | |
| 814 last_mouse_press_location_ = e.location(); | |
| 815 if (e.IsOnlyLeftMouseButton()) { | |
| 816 if (!ExceededDragThreshold(location_delta.x(), location_delta.y()) | |
| 817 && time_delta.InMilliseconds() <= GetDoubleClickTimeMS()) { | |
| 818 // Multiple mouse press detected. Check for double or triple. | |
| 819 if (tracking_double_click_) { | |
|
oshima
2011/01/25 19:31:59
can't we make this simple state machine rather tha
varunjain
2011/01/25 20:10:40
Done.
| |
| 820 tracking_double_click_ = false; | |
| 821 tracking_triple_click_ = true; | |
| 822 return SELECT_WORD; | |
| 823 } else if (tracking_triple_click_) { | |
| 824 tracking_double_click_ = false; | |
| 825 tracking_triple_click_ = false; | |
| 826 return SELECT_ALL; | |
| 827 } else { | |
| 828 // The 4th click should be treated as a single click. | |
| 829 tracking_double_click_ = true; | |
| 830 tracking_triple_click_ = false; | |
| 831 return CURSOR_SELECT; | |
| 832 } | |
| 833 } else { | |
| 834 // Single mouse press. | |
| 835 tracking_double_click_ = true; | |
| 836 tracking_triple_click_ = false; | |
| 837 return CURSOR_SELECT; | |
| 838 } | |
| 839 } | |
| 840 return NONE; | |
| 841 } | |
| 842 | |
| 787 void NativeTextfieldViews::PropagateTextChange() { | 843 void NativeTextfieldViews::PropagateTextChange() { |
| 788 textfield_->SyncText(); | 844 textfield_->SyncText(); |
| 789 Textfield::Controller* controller = textfield_->GetController(); | 845 Textfield::Controller* controller = textfield_->GetController(); |
| 790 if (controller) | 846 if (controller) |
| 791 controller->ContentsChanged(textfield_, GetText()); | 847 controller->ContentsChanged(textfield_, GetText()); |
| 792 } | 848 } |
| 793 | 849 |
| 794 void NativeTextfieldViews::InitContextMenuIfRequired() { | 850 void NativeTextfieldViews::InitContextMenuIfRequired() { |
| 795 if (context_menu_menu_.get()) | 851 if (context_menu_menu_.get()) |
| 796 return; | 852 return; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 853 } | 909 } |
| 854 | 910 |
| 855 void NativeTextfieldViews::TextfieldBorder::SetInsets(int top, | 911 void NativeTextfieldViews::TextfieldBorder::SetInsets(int top, |
| 856 int left, | 912 int left, |
| 857 int bottom, | 913 int bottom, |
| 858 int right) { | 914 int right) { |
| 859 insets_.Set(top, left, bottom, right); | 915 insets_.Set(top, left, bottom, right); |
| 860 } | 916 } |
| 861 | 917 |
| 862 } // namespace views | 918 } // namespace views |
| OLD | NEW |