diff options
author | suzhe@google.com <suzhe@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-23 22:34:21 +0000 |
---|---|---|
committer | suzhe@google.com <suzhe@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-23 22:34:21 +0000 |
commit | 8ca0956daa88097630611ee296a32e758305b067 (patch) | |
tree | b2c22f0ebb163e72e0db2d6d2dbdbf9b7f09492e /views | |
parent | 3dd6e99d51bef9124984ab8a6ba8cead6531108a (diff) | |
download | chromium_src-8ca0956daa88097630611ee296a32e758305b067.zip chromium_src-8ca0956daa88097630611ee296a32e758305b067.tar.gz chromium_src-8ca0956daa88097630611ee296a32e758305b067.tar.bz2 |
Refactor Textfield and AutocompleteEditViewViews.
Changes made by this CL:
1. Adds OnBeforeUserAction() and OnAfterUserAction() in TextfieldController.
2. Adds Textfield::HasSelection().
3. Changes NativeTextfieldViews to use KeyEvent::GetCharacter().
3. Refactors AutocompleteEditViewViews to use new TextfieldController methods.
BUG=75003
TEST=views_unittests --gtest_filter=*Textfield* and interactive_ui_tests --gtest_filter=AutocompleteEditViewViews*
Review URL: http://codereview.chromium.org/6685082
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79201 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r-- | views/controls/textfield/native_textfield_views.cc | 157 | ||||
-rw-r--r-- | views/controls/textfield/native_textfield_views.h | 14 | ||||
-rw-r--r-- | views/controls/textfield/textfield.cc | 7 | ||||
-rw-r--r-- | views/controls/textfield/textfield.h | 3 | ||||
-rw-r--r-- | views/controls/textfield/textfield_controller.h | 11 |
5 files changed, 67 insertions, 125 deletions
diff --git a/views/controls/textfield/native_textfield_views.cc b/views/controls/textfield/native_textfield_views.cc index f935193..17885ba 100644 --- a/views/controls/textfield/native_textfield_views.cc +++ b/views/controls/textfield/native_textfield_views.cc @@ -86,17 +86,21 @@ NativeTextfieldViews::~NativeTextfieldViews() { // NativeTextfieldViews, View overrides: bool NativeTextfieldViews::OnMousePressed(const views::MouseEvent& e) { + OnBeforeUserAction(); if (HandleMousePressed(e)) SchedulePaint(); + OnAfterUserAction(); return true; } bool NativeTextfieldViews::OnMouseDragged(const views::MouseEvent& e) { + OnBeforeUserAction(); size_t pos = FindCursorPosition(e.location()); if (model_->MoveCursorTo(pos, true)) { UpdateCursorBoundsAndTextOffset(); SchedulePaint(); } + OnAfterUserAction(); return true; } @@ -360,6 +364,7 @@ bool NativeTextfieldViews::GetAcceleratorForCommandId(int command_id, void NativeTextfieldViews::ExecuteCommand(int command_id) { bool text_changed = false; bool editable = !textfield_->read_only(); + OnBeforeUserAction(); switch (command_id) { case IDS_APP_CUT: if (editable) @@ -386,6 +391,7 @@ void NativeTextfieldViews::ExecuteCommand(int command_id) { // The cursor must have changed if text changed during cut/paste/delete. UpdateAfterChange(text_changed, text_changed); + OnAfterUserAction(); } // static @@ -531,6 +537,8 @@ bool NativeTextfieldViews::HandleKeyEvent(const KeyEvent& key_event) { // TODO(oshima): shift-tab does not work. Figure out why and fix. if (key_code == ui::VKEY_TAB) return false; + + OnBeforeUserAction(); bool editable = !textfield_->read_only(); bool selection = key_event.IsShiftDown(); bool control = key_event.IsControlDown(); @@ -619,138 +627,22 @@ bool NativeTextfieldViews::HandleKeyEvent(const KeyEvent& key_event) { default: break; } - char16 print_char = GetPrintableChar(key_event); - if (!control && print_char && editable) { + char16 ch = key_event.GetCharacter(); + if (editable && ShouldInsertChar(ch, key_event.flags())) { if (insert_) - model_->Insert(print_char); + model_->Insert(ch); else - model_->Replace(print_char); + model_->Replace(ch); text_changed = true; } UpdateAfterChange(text_changed, cursor_changed); + OnAfterUserAction(); return (text_changed || cursor_changed); } return false; } -char16 NativeTextfieldViews::GetPrintableChar(const KeyEvent& key_event) { - // TODO(oshima): IME, i18n support. - // This only works for UCS-2 characters. - ui::KeyboardCode key_code = key_event.key_code(); - bool shift = key_event.IsShiftDown(); - bool upper = shift ^ key_event.IsCapsLockDown(); - // TODO(oshima): We should have a utility function - // under app to convert a KeyboardCode to a printable character, - // probably in keyboard_code_conversion{.h, _x - switch (key_code) { - case ui::VKEY_NUMPAD0: - return '0'; - case ui::VKEY_NUMPAD1: - return '1'; - case ui::VKEY_NUMPAD2: - return '2'; - case ui::VKEY_NUMPAD3: - return '3'; - case ui::VKEY_NUMPAD4: - return '4'; - case ui::VKEY_NUMPAD5: - return '5'; - case ui::VKEY_NUMPAD6: - return '6'; - case ui::VKEY_NUMPAD7: - return '7'; - case ui::VKEY_NUMPAD8: - return '8'; - case ui::VKEY_NUMPAD9: - return '9'; - case ui::VKEY_MULTIPLY: - return '*'; - case ui::VKEY_ADD: - return '+'; - case ui::VKEY_SUBTRACT: - return '-'; - case ui::VKEY_DECIMAL: - return '.'; - case ui::VKEY_DIVIDE: - return '/'; - case ui::VKEY_SPACE: - return ' '; - case ui::VKEY_0: - return shift ? ')' : '0'; - case ui::VKEY_1: - return shift ? '!' : '1'; - case ui::VKEY_2: - return shift ? '@' : '2'; - case ui::VKEY_3: - return shift ? '#' : '3'; - case ui::VKEY_4: - return shift ? '$' : '4'; - case ui::VKEY_5: - return shift ? '%' : '5'; - case ui::VKEY_6: - return shift ? '^' : '6'; - case ui::VKEY_7: - return shift ? '&' : '7'; - case ui::VKEY_8: - return shift ? '*' : '8'; - case ui::VKEY_9: - return shift ? '(' : '9'; - - case ui::VKEY_A: - case ui::VKEY_B: - case ui::VKEY_C: - case ui::VKEY_D: - case ui::VKEY_E: - case ui::VKEY_F: - case ui::VKEY_G: - case ui::VKEY_H: - case ui::VKEY_I: - case ui::VKEY_J: - case ui::VKEY_K: - case ui::VKEY_L: - case ui::VKEY_M: - case ui::VKEY_N: - case ui::VKEY_O: - case ui::VKEY_P: - case ui::VKEY_Q: - case ui::VKEY_R: - case ui::VKEY_S: - case ui::VKEY_T: - case ui::VKEY_U: - case ui::VKEY_V: - case ui::VKEY_W: - case ui::VKEY_X: - case ui::VKEY_Y: - case ui::VKEY_Z: - return (upper ? 'A' : 'a') + (key_code - ui::VKEY_A); - case ui::VKEY_OEM_1: - return shift ? ':' : ';'; - case ui::VKEY_OEM_PLUS: - return shift ? '+' : '='; - case ui::VKEY_OEM_COMMA: - return shift ? '<' : ','; - case ui::VKEY_OEM_MINUS: - return shift ? '_' : '-'; - case ui::VKEY_OEM_PERIOD: - return shift ? '>' : '.'; - case ui::VKEY_OEM_2: - return shift ? '?' : '/'; - case ui::VKEY_OEM_3: - return shift ? '~' : '`'; - case ui::VKEY_OEM_4: - return shift ? '}' : ']'; - case ui::VKEY_OEM_5: - return shift ? '|' : '\\'; - case ui::VKEY_OEM_6: - return shift ? '{' : '['; - case ui::VKEY_OEM_7: - return shift ? '"' : '\''; - default: - return 0; - } -} - size_t NativeTextfieldViews::FindCursorPosition(const gfx::Point& point) const { // TODO(oshima): BIDI/i18n support. gfx::Font font = GetFont(); @@ -859,6 +751,29 @@ void NativeTextfieldViews::InitContextMenuIfRequired() { context_menu_menu_.reset(new Menu2(context_menu_contents_.get())); } +void NativeTextfieldViews::OnBeforeUserAction() { + TextfieldController* controller = textfield_->GetController(); + if (controller) + controller->OnBeforeUserAction(textfield_); +} + +void NativeTextfieldViews::OnAfterUserAction() { + TextfieldController* controller = textfield_->GetController(); + if (controller) + controller->OnAfterUserAction(textfield_); +} + +// static +bool NativeTextfieldViews::ShouldInsertChar(char16 ch, int flags) { + // Filter out all control characters, including tab and new line characters, + // and all characters with Alt modifier. But we need to allow characters with + // AltGr modifier. + // On Windows AltGr is represented by Alt+Ctrl, and on Linux it's a different + // flag that we don't care about. + return ((ch >= 0x20 && ch < 0x7F) || ch > 0x9F) && + (flags & ~(ui::EF_SHIFT_DOWN | ui::EF_CAPS_LOCK_DOWN)) != ui::EF_ALT_DOWN; +} + /////////////////////////////////////////////////////////////////////////////// // // TextifieldBorder diff --git a/views/controls/textfield/native_textfield_views.h b/views/controls/textfield/native_textfield_views.h index 1f80147..7cc8317f 100644 --- a/views/controls/textfield/native_textfield_views.h +++ b/views/controls/textfield/native_textfield_views.h @@ -169,10 +169,6 @@ class NativeTextfieldViews : public views::View, // Handle the keyevent. bool HandleKeyEvent(const KeyEvent& key_event); - // Utility function. Gets the character corresponding to a keyevent. - // Returns 0 if the character is not printable. - char16 GetPrintableChar(const KeyEvent& key_event); - // Find a cusor position for given |point| in this views coordinates. size_t FindCursorPosition(const gfx::Point& point) const; @@ -194,6 +190,16 @@ class NativeTextfieldViews : public views::View, // Utility function to create the context menu if one does not already exist. void InitContextMenuIfRequired(); + // Convenience method to call TextfieldController::OnBeforeUserAction(); + void OnBeforeUserAction(); + + // Convenience method to call TextfieldController::OnAfterUserAction(); + void OnAfterUserAction(); + + // Checks if a char is ok to be inserted into the textfield. The |ch| is a + // modified character, i.e., modifiers took effect when generating this char. + static bool ShouldInsertChar(char16 ch, int flags); + // The parent textfield, the owner of this object. Textfield* textfield_; diff --git a/views/controls/textfield/textfield.cc b/views/controls/textfield/textfield.cc index ec99e77..7dfa4da 100644 --- a/views/controls/textfield/textfield.cc +++ b/views/controls/textfield/textfield.cc @@ -141,6 +141,13 @@ void Textfield::ClearSelection() const { native_wrapper_->ClearSelection(); } +bool Textfield::HasSelection() const { + ui::Range range; + if (native_wrapper_) + native_wrapper_->GetSelectedRange(&range); + return !range.is_empty(); +} + void Textfield::SetTextColor(SkColor color) { text_color_ = color; use_default_text_color_ = false; diff --git a/views/controls/textfield/textfield.h b/views/controls/textfield/textfield.h index ca87bdf..bbea47d 100644 --- a/views/controls/textfield/textfield.h +++ b/views/controls/textfield/textfield.h @@ -89,6 +89,9 @@ class Textfield : public View { // Clears the selection within the edit field and sets the caret to the end. void ClearSelection() const; + // Checks if there is any selected text. + bool HasSelection() const; + // Accessor for |style_|. StyleFlags style() const { return style_; } diff --git a/views/controls/textfield/textfield_controller.h b/views/controls/textfield/textfield_controller.h index 53fe97c..ee8df1b 100644 --- a/views/controls/textfield/textfield_controller.h +++ b/views/controls/textfield/textfield_controller.h @@ -26,6 +26,17 @@ class TextfieldController { // further. If it returns false the processing continues. virtual bool HandleKeyEvent(Textfield* sender, const KeyEvent& key_event) = 0; + + // Called before performing a user action that may change the textfield. + // It's currently only supported by Views implementation. + virtual void OnBeforeUserAction(Textfield* sender) {} + + // Called after performing a user action that may change the textfield. + // It's currently only supported by Views implementation. + virtual void OnAfterUserAction(Textfield* sender) {} + + protected: + virtual ~TextfieldController() {} }; } // namespace views |