diff options
author | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-03 23:04:48 +0000 |
---|---|---|
committer | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-03 23:04:48 +0000 |
commit | 5053965a859e26d6fe972406e3df1683f935a597 (patch) | |
tree | edc3236ab8b2f75467ca0857ea77c5634e176019 /views | |
parent | ab2eb9f93ef05af83491f309a5dc60291ad688c8 (diff) | |
download | chromium_src-5053965a859e26d6fe972406e3df1683f935a597.zip chromium_src-5053965a859e26d6fe972406e3df1683f935a597.tar.gz chromium_src-5053965a859e26d6fe972406e3df1683f935a597.tar.bz2 |
Refactor NativeTextfieldViews mouse handlers.
Add support methods for this and coming changes.
Simplify NativeTextfieldViewsTest.DoubleAndTripleClickTest.
Refactor TextfieldViewsModel::MoveCursorTo*.
Detect selection changes in TextfieldViewsModel::MoveCursorTo.
BUG=72040
TEST=--use-pure-views textfield interaction.
Review URL: http://codereview.chromium.org/6893096
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83991 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
4 files changed, 63 insertions, 94 deletions
diff --git a/views/controls/textfield/native_textfield_views.cc b/views/controls/textfield/native_textfield_views.cc index 4b6c2fd..3df14d8 100644 --- a/views/controls/textfield/native_textfield_views.cc +++ b/views/controls/textfield/native_textfield_views.cc @@ -66,9 +66,7 @@ NativeTextfieldViews::NativeTextfieldViews(Textfield* parent) insert_(true), is_cursor_visible_(false), skip_input_method_cancel_composition_(false), - ALLOW_THIS_IN_INITIALIZER_LIST(cursor_timer_(this)), - last_mouse_press_time_(base::Time::FromInternalValue(0)), - click_state_(NONE) { + ALLOW_THIS_IN_INITIALIZER_LIST(cursor_timer_(this)) { set_border(text_border_); // Multiline is not supported. @@ -87,19 +85,50 @@ NativeTextfieldViews::~NativeTextfieldViews() { bool NativeTextfieldViews::OnMousePressed(const MouseEvent& event) { OnBeforeUserAction(); - if (HandleMousePressed(event)) + RequestFocus(); + + if (event.IsOnlyLeftMouseButton()) { + static size_t aggregated_clicks = 0; + static base::Time last_click_time = base::Time::FromInternalValue(0); + static gfx::Point last_click_location; + static View* last_click_view = NULL; + base::TimeDelta time_delta = event.time_stamp() - last_click_time; + gfx::Point location_delta = event.location().Subtract(last_click_location); + if (time_delta.InMilliseconds() <= GetDoubleClickInterval() && + !ExceededDragThreshold(location_delta.x(), location_delta.y()) && + last_click_view == this) { + aggregated_clicks = (aggregated_clicks + 1) % 3; + } else { + aggregated_clicks = 0; + } + last_click_time = event.time_stamp(); + last_click_location = event.location(); + last_click_view = this; + + switch(aggregated_clicks) { + case 0: + MoveCursorTo(event.location(), event.IsShiftDown()); + break; + case 1: + model_->SelectWord(); + break; + case 2: + model_->SelectAll(); + break; + default: + NOTREACHED(); + } SchedulePaint(); + } + OnAfterUserAction(); return true; } bool NativeTextfieldViews::OnMouseDragged(const MouseEvent& event) { OnBeforeUserAction(); - size_t pos = FindCursorPosition(event.location()); - if (model_->MoveCursorTo(pos, true)) { - UpdateCursorBoundsAndTextOffset(); + if (MoveCursorTo(event.location(), true)) SchedulePaint(); - } OnAfterUserAction(); return true; } @@ -838,45 +867,20 @@ size_t NativeTextfieldViews::FindCursorPosition(const gfx::Point& point) const { return left_pos; } -bool NativeTextfieldViews::HandleMousePressed(const views::MouseEvent& e) { - textfield_->RequestFocus(); - base::TimeDelta time_delta = e.time_stamp() - last_mouse_press_time_; - gfx::Point location_delta = e.location().Subtract(last_mouse_press_location_); - last_mouse_press_time_ = e.time_stamp(); - last_mouse_press_location_ = e.location(); - if (e.IsLeftMouseButton()) { - if (!ExceededDragThreshold(location_delta.x(), location_delta.y()) - && time_delta.InMilliseconds() <= GetDoubleClickInterval()) { - // Multiple mouse press detected. Check for double or triple. - switch (click_state_) { - case TRACKING_DOUBLE_CLICK: - click_state_ = TRACKING_TRIPLE_CLICK; - model_->SelectWord(); - return true; - case TRACKING_TRIPLE_CLICK: - click_state_ = NONE; - model_->SelectAll(); - return true; - case NONE: - click_state_ = TRACKING_DOUBLE_CLICK; - SetCursorForMouseClick(e); - return true; - } - } else { - // Single mouse press. - click_state_ = TRACKING_DOUBLE_CLICK; - SetCursorForMouseClick(e); - return true; - } - } - return false; +bool NativeTextfieldViews::IsPointInSelection(const gfx::Point& point) const { + ui::Range range; + GetSelectedRange(&range); + size_t pos = FindCursorPosition(point); + return (pos >= range.GetMin() && pos < range.GetMax()); } -void NativeTextfieldViews::SetCursorForMouseClick(const views::MouseEvent& e) { - size_t pos = FindCursorPosition(e.location()); - if (model_->MoveCursorTo(pos, false)) { +bool NativeTextfieldViews::MoveCursorTo(const gfx::Point& point, bool select) { + size_t pos = FindCursorPosition(point); + if (model_->MoveCursorTo(pos, select)) { UpdateCursorBoundsAndTextOffset(); + return true; } + return false; } void NativeTextfieldViews::PropagateTextChange() { diff --git a/views/controls/textfield/native_textfield_views.h b/views/controls/textfield/native_textfield_views.h index e95c1a5..a31317d 100644 --- a/views/controls/textfield/native_textfield_views.h +++ b/views/controls/textfield/native_textfield_views.h @@ -38,7 +38,6 @@ class Menu2; // * X selection (only if we want to support). // * STYLE_MULTILINE, STYLE_LOWERCASE text. (These are not used in // chromeos, so we may not need them) -// * Double click to select word, and triple click to select all. // * Undo/Redo class NativeTextfieldViews : public View, public ContextMenuController, @@ -114,12 +113,6 @@ class NativeTextfieldViews : public View, // Enable/Disable TextfieldViews implementation for Textfield. static void SetEnableTextfieldViews(bool enabled); - enum ClickState { - TRACKING_DOUBLE_CLICK, - TRACKING_TRIPLE_CLICK, - NONE, - }; - protected: // View override. virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE; @@ -176,12 +169,11 @@ class NativeTextfieldViews : public View, // Find a cusor position for given |point| in this views coordinates. size_t FindCursorPosition(const gfx::Point& point) const; - // Mouse event handler. Returns true if textfield needs to be repainted. - bool HandleMousePressed(const MouseEvent& e); + // Returns true if the local point is over the selected range of text. + bool IsPointInSelection(const gfx::Point& point) const; - // Helper function that sets the cursor position at the location of mouse - // event. - void SetCursorForMouseClick(const views::MouseEvent& e); + // Helper function to call MoveCursorTo on the TextfieldViewsModel. + bool MoveCursorTo(const gfx::Point& point, bool select); // Utility function to inform the parent textfield (and its controller if any) // that the text in the textfield has changed. @@ -241,15 +233,6 @@ class NativeTextfieldViews : public View, // A runnable method factory for callback to update the cursor. ScopedRunnableMethodFactory<NativeTextfieldViews> cursor_timer_; - // Time of last LEFT mouse press. Used for tracking double/triple click. - base::Time last_mouse_press_time_; - - // Position of last LEFT mouse press. Used for tracking double/triple click. - gfx::Point last_mouse_press_location_; - - // State variable to track double and triple clicks. - ClickState click_state_; - // Context menu and its content list for the textfield. scoped_ptr<ui::SimpleMenuModel> context_menu_contents_; scoped_ptr<Menu2> context_menu_menu_; diff --git a/views/controls/textfield/native_textfield_views_unittest.cc b/views/controls/textfield/native_textfield_views_unittest.cc index 5c9db0f..4ed3407 100644 --- a/views/controls/textfield/native_textfield_views_unittest.cc +++ b/views/controls/textfield/native_textfield_views_unittest.cc @@ -189,10 +189,6 @@ class NativeTextfieldViewsTest : public ViewsTestBase, return textfield_view_->context_menu_menu_.get(); } - NativeTextfieldViews::ClickState GetClickState() { - return textfield_view_->click_state_; - } - protected: void SendKeyEvent(ui::KeyboardCode key_code, bool shift, @@ -538,26 +534,23 @@ TEST_F(NativeTextfieldViewsTest, ContextMenuDisplayTest) { TEST_F(NativeTextfieldViewsTest, DoubleAndTripleClickTest) { InitTextfield(Textfield::STYLE_DEFAULT); textfield_->SetText(ASCIIToUTF16("hello world")); - MouseEvent me(ui::ET_MOUSE_PRESSED, 0, 0, ui::EF_LEFT_BUTTON_DOWN); - EXPECT_EQ(NativeTextfieldViews::NONE, GetClickState()); + MouseEvent click(ui::ET_MOUSE_PRESSED, 0, 0, ui::EF_LEFT_BUTTON_DOWN); + MouseEvent double_click(ui::ET_MOUSE_PRESSED, 0, 0, + ui::EF_LEFT_BUTTON_DOWN | ui::EF_IS_DOUBLE_CLICK); // Test for double click. - textfield_view_->OnMousePressed(me); + textfield_view_->OnMousePressed(click); EXPECT_STR_EQ("", textfield_->GetSelectedText()); - EXPECT_EQ(NativeTextfieldViews::TRACKING_DOUBLE_CLICK, GetClickState()); - textfield_view_->OnMousePressed(me); + textfield_view_->OnMousePressed(double_click); EXPECT_STR_EQ("hello", textfield_->GetSelectedText()); - EXPECT_EQ(NativeTextfieldViews::TRACKING_TRIPLE_CLICK, GetClickState()); // Test for triple click. - textfield_view_->OnMousePressed(me); + textfield_view_->OnMousePressed(click); EXPECT_STR_EQ("hello world", textfield_->GetSelectedText()); - EXPECT_EQ(NativeTextfieldViews::NONE, GetClickState()); // Another click should reset back to single click. - textfield_view_->OnMousePressed(me); + textfield_view_->OnMousePressed(click); EXPECT_STR_EQ("", textfield_->GetSelectedText()); - EXPECT_EQ(NativeTextfieldViews::TRACKING_DOUBLE_CLICK, GetClickState()); } TEST_F(NativeTextfieldViewsTest, ReadOnlyTest) { diff --git a/views/controls/textfield/textfield_views_model.cc b/views/controls/textfield/textfield_views_model.cc index 6e3ebf7..583dc20 100644 --- a/views/controls/textfield/textfield_views_model.cc +++ b/views/controls/textfield/textfield_views_model.cc @@ -301,32 +301,21 @@ void TextfieldViewsModel::MoveCursorToNextWord(bool select) { } void TextfieldViewsModel::MoveCursorToHome(bool select) { - if (HasCompositionText()) - ConfirmCompositionText(); - cursor_pos_ = 0; - if (!select) - ClearSelection(); + MoveCursorTo(0, select); } void TextfieldViewsModel::MoveCursorToEnd(bool select) { - if (HasCompositionText()) - ConfirmCompositionText(); - cursor_pos_ = text_.length(); - if (!select) - ClearSelection(); + MoveCursorTo(text_.length(), select); } bool TextfieldViewsModel::MoveCursorTo(size_t pos, bool select) { if (HasCompositionText()) ConfirmCompositionText(); - bool cursor_changed = false; - if (cursor_pos_ != pos) { - cursor_pos_ = pos; - cursor_changed = true; - } + bool changed = cursor_pos_ != pos || select != HasSelection(); + cursor_pos_ = pos; if (!select) ClearSelection(); - return cursor_changed; + return changed; } gfx::Rect TextfieldViewsModel::GetCursorBounds(const gfx::Font& font) const { |