diff options
author | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-09 23:48:30 +0000 |
---|---|---|
committer | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-09 23:48:30 +0000 |
commit | 5c9e97acabd4cdab5adb20d2412a5766b3382856 (patch) | |
tree | ead11654548e0e110cf8c8dce962801d530d54f7 /views | |
parent | 7f01f83fd464fc13cbdb9d377493d1781decf363 (diff) | |
download | chromium_src-5c9e97acabd4cdab5adb20d2412a5766b3382856.zip chromium_src-5c9e97acabd4cdab5adb20d2412a5766b3382856.tar.gz chromium_src-5c9e97acabd4cdab5adb20d2412a5766b3382856.tar.bz2 |
First cut at implementation of FindBar for views / gtk
Also had to implement change notification for TextField on views / gtk
Review URL: http://codereview.chromium.org/200035
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25819 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r-- | views/controls/textfield/native_textfield_gtk.cc | 38 | ||||
-rw-r--r-- | views/controls/textfield/native_textfield_gtk.h | 11 | ||||
-rw-r--r-- | views/controls/textfield/textfield.cc | 55 | ||||
-rw-r--r-- | views/controls/textfield/textfield.h | 58 | ||||
-rw-r--r-- | views/view.cc | 8 | ||||
-rw-r--r-- | views/view_gtk.cc | 4 | ||||
-rw-r--r-- | views/view_win.cc | 8 | ||||
-rw-r--r-- | views/widget/root_view.cc | 8 | ||||
-rw-r--r-- | views/widget/widget_gtk.cc | 12 |
9 files changed, 136 insertions, 66 deletions
diff --git a/views/controls/textfield/native_textfield_gtk.cc b/views/controls/textfield/native_textfield_gtk.cc index 6ceaab4..ef7a67d 100644 --- a/views/controls/textfield/native_textfield_gtk.cc +++ b/views/controls/textfield/native_textfield_gtk.cc @@ -134,18 +134,50 @@ gfx::NativeView NativeTextfieldGtk::GetTestingHandle() const { return native_view(); } +// static +gboolean NativeTextfieldGtk::OnKeyPressEventHandler( + GtkWidget* entry, + GdkEventKey* event, + NativeTextfieldGtk* textfield) { + return textfield->OnKeyPressEvent(event); +} + +gboolean NativeTextfieldGtk::OnKeyPressEvent(GdkEventKey* event) { + Textfield::Controller* controller = textfield_->GetController(); + if (controller) { + Textfield::Keystroke ks(event); + return controller->HandleKeystroke(textfield_, ks); + } + return false; +} + +// static +gboolean NativeTextfieldGtk::OnChangedHandler( + GtkWidget* entry, + NativeTextfieldGtk* textfield) { + return textfield->OnChanged(); +} + +gboolean NativeTextfieldGtk::OnChanged() { + Textfield::Controller* controller = textfield_->GetController(); + if (controller) + controller->ContentsChanged(textfield_, GetText()); + return false; +} + //////////////////////////////////////////////////////////////////////////////// // NativeTextfieldGtk, NativeControlGtk overrides: void NativeTextfieldGtk::CreateNativeControl() { - // TODO(brettw) hook in an observer to get text change events so we can call - // the controller. NativeControlCreated(gtk_entry_new()); } void NativeTextfieldGtk::NativeControlCreated(GtkWidget* widget) { NativeControlGtk::NativeControlCreated(widget); - // TODO(port): post-creation init + g_signal_connect(widget, "changed", + G_CALLBACK(OnChangedHandler), this); + g_signal_connect(widget, "key-press-event", + G_CALLBACK(OnKeyPressEventHandler), this); } //////////////////////////////////////////////////////////////////////////////// diff --git a/views/controls/textfield/native_textfield_gtk.h b/views/controls/textfield/native_textfield_gtk.h index 9e10116..ef2f4fe 100644 --- a/views/controls/textfield/native_textfield_gtk.h +++ b/views/controls/textfield/native_textfield_gtk.h @@ -43,6 +43,17 @@ class NativeTextfieldGtk : public NativeControlGtk, private: Textfield* textfield_; + // Callback when the entry text changes. + static gboolean OnKeyPressEventHandler( + GtkWidget* entry, + GdkEventKey* event, + NativeTextfieldGtk* textfield); + gboolean OnKeyPressEvent(GdkEventKey* event); + static gboolean OnChangedHandler( + GtkWidget* entry, + NativeTextfieldGtk* textfield); + gboolean OnChanged(); + DISALLOW_COPY_AND_ASSIGN(NativeTextfieldGtk); }; diff --git a/views/controls/textfield/textfield.cc b/views/controls/textfield/textfield.cc index 3887697..97240c7 100644 --- a/views/controls/textfield/textfield.cc +++ b/views/controls/textfield/textfield.cc @@ -4,10 +4,15 @@ #include "views/controls/textfield/textfield.h" +#if defined(OS_LINUX) +#include <gdk/gdkkeysyms.h> +#endif + #include "app/gfx/insets.h" #if defined(OS_WIN) #include "app/win_util.h" #endif + #include "base/string_util.h" #include "views/controls/textfield/native_textfield_wrapper.h" #include "views/widget/widget.h" @@ -167,28 +172,6 @@ void Textfield::SyncText() { text_ = native_wrapper_->GetText(); } -// static -bool Textfield::IsKeystrokeEnter(const Keystroke& key) { -#if defined(OS_WIN) - return key.key == VK_RETURN; -#else - // TODO(port): figure out VK_constants - NOTIMPLEMENTED(); - return false; -#endif -} - -// static -bool Textfield::IsKeystrokeEscape(const Keystroke& key) { -#if defined(OS_WIN) - return key.key == VK_ESCAPE; -#else - // TODO(port): figure out VK_constants - NOTIMPLEMENTED(); - return false; -#endif -} - //////////////////////////////////////////////////////////////////////////////// // Textfield, View overrides: @@ -296,4 +279,32 @@ NativeTextfieldWrapper* Textfield::CreateWrapper() { return native_wrapper; } +base::KeyboardCode Textfield::Keystroke::GetKeyboardCode() const { +#if defined(OS_WIN) + return static_cast<base::KeyboardCode>(key_); +#else + return static_cast<base::KeyboardCode>(event_.keyval); +#endif +} + +#if defined(OS_WIN) +bool Textfield::Keystroke::IsControlHeld() const { + return GetKeyState(VK_CONTROL) >= 0; +} + +bool Textfield::Keystroke::IsShiftHeld() const { + return GetKeyState(VK_SHIFT) >= 0; +} +#else +bool Textfield::Keystroke::IsControlHeld() const { + return (event_.state & gtk_accelerator_get_default_mod_mask()) == + GDK_CONTROL_MASK; +} + +bool Textfield::Keystroke::IsShiftHeld() const { + return (event_.state & gtk_accelerator_get_default_mod_mask()) == + GDK_SHIFT_MASK; +} +#endif + } // namespace views diff --git a/views/controls/textfield/textfield.h b/views/controls/textfield/textfield.h index ecd16169..fd01cef 100644 --- a/views/controls/textfield/textfield.h +++ b/views/controls/textfield/textfield.h @@ -5,8 +5,13 @@ #ifndef VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_H_ #define VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_H_ +#if defined (OS_LINUX) +#include <gdk/gdk.h> +#endif + #include "app/gfx/font.h" #include "base/basictypes.h" +#include "base/keyboard_codes.h" #include "base/string16.h" #include "views/view.h" #include "third_party/skia/include/core/SkColor.h" @@ -30,29 +35,45 @@ class Textfield : public View { // Cross-platform code can use IsKeystrokeEnter/Escape to check for these // two common key events. // TODO(brettw) this should be cleaned up to be more cross-platform. + class Keystroke { + public: #if defined(OS_WIN) - struct Keystroke { - Keystroke(unsigned int m, + const Keystroke(unsigned int m, wchar_t k, int r, unsigned int f) - : message(m), - key(k), - repeat_count(r), - flags(f) { + : message_(m), + key_(k), + repeat_count_(r), + flags_(f) { } + unsigned int message() const { return message_; } + wchar_t key() const { return key_; } + int repeat_count() const { return repeat_count_; } + unsigned int flags() const { return flags_; } +#else + explicit Keystroke(GdkEventKey* event) + : event_(*event) { + } + const GdkEventKey* event() const { return &event_; } +#endif + base::KeyboardCode GetKeyboardCode() const; + bool IsControlHeld() const; + bool IsShiftHeld() const; - unsigned int message; - wchar_t key; - int repeat_count; - unsigned int flags; - }; + private: +#if defined(OS_WIN) + unsigned int message_; + wchar_t key_; + int repeat_count_; + unsigned int flags_; #else - struct Keystroke { - // TODO(brettw) figure out what this should be on GTK. - }; + GdkEventKey event_; #endif + DISALLOW_COPY_AND_ASSIGN(Keystroke); + }; + // This defines the callback interface for other code to be notified of // changes in the state of a text field. class Controller { @@ -157,15 +178,6 @@ class Textfield : public View { // been deleted during a window close. void SyncText(); - // Provides a cross-platform way of checking whether a keystroke is one of - // these common keys. Most code only checks keystrokes against these two keys, - // so the caller can be cross-platform by implementing the platform-specific - // parts in here. - // TODO(brettw) we should use a more cross-platform representation of - // keyboard events so these are not necessary. - static bool IsKeystrokeEnter(const Keystroke& key); - static bool IsKeystrokeEscape(const Keystroke& key); - #ifdef UNIT_TEST gfx::NativeView GetTestingHandle() const { return native_wrapper_ ? native_wrapper_->GetTestingHandle() : NULL; diff --git a/views/view.cc b/views/view.cc index 65e642e..e47dbea 100644 --- a/views/view.cc +++ b/views/view.cc @@ -276,6 +276,14 @@ bool View::HasFocus() { return false; } +void View::Focus() { + // Set the native focus to the root view window so it receives the keyboard + // messages. + FocusManager* focus_manager = GetFocusManager(); + if (focus_manager) + focus_manager->FocusNativeView(GetRootView()->GetWidget()->GetNativeView()); +} + void View::SetHotTracked(bool flag) { } diff --git a/views/view_gtk.cc b/views/view_gtk.cc index f04818d..655f88f 100644 --- a/views/view_gtk.cc +++ b/views/view_gtk.cc @@ -15,10 +15,6 @@ ViewAccessibilityWrapper* View::GetViewAccessibilityWrapper() { return NULL; } -void View::Focus() { - NOTIMPLEMENTED(); -} - int View::GetHorizontalDragThreshold() { static bool determined_threshold = false; static int drag_threshold = 8; diff --git a/views/view_win.cc b/views/view_win.cc index c03e908..cd9911c 100644 --- a/views/view_win.cc +++ b/views/view_win.cc @@ -22,14 +22,6 @@ ViewAccessibilityWrapper* View::GetViewAccessibilityWrapper() { return accessibility_.get(); } -void View::Focus() { - // Set the native focus to the root view window so it receives the keyboard - // messages. - FocusManager* focus_manager = GetFocusManager(); - if (focus_manager) - focus_manager->FocusNativeView(GetRootView()->GetWidget()->GetNativeView()); -} - int View::GetHorizontalDragThreshold() { static int threshold = -1; if (threshold == -1) diff --git a/views/widget/root_view.cc b/views/widget/root_view.cc index 4469051..9d11c27 100644 --- a/views/widget/root_view.cc +++ b/views/widget/root_view.cc @@ -360,11 +360,12 @@ bool RootView::OnMousePressed(const MouseEvent& e) { if (focus_on_mouse_pressed_) { #if defined(OS_WIN) HWND hwnd = GetWidget()->GetNativeView(); - if (::GetFocus() != hwnd) { + if (::GetFocus() != hwnd) ::SetFocus(hwnd); - } #else - NOTIMPLEMENTED(); + GtkWidget* widget = GetWidget()->GetNativeView(); + if (!gtk_widget_is_focus(widget)) + gtk_widget_grab_focus(widget); #endif } @@ -782,7 +783,6 @@ bool RootView::ProcessKeyEvent(const KeyEvent& event) { v->ShowContextMenu(screen_loc.x(), screen_loc.y(), false); return true; } - for (; v && v != this && !consumed; v = v->GetParent()) { consumed = (event.GetType() == Event::ET_KEY_PRESSED) ? v->OnKeyPressed(event) : v->OnKeyReleased(event); diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc index 89561cd..d1271f5 100644 --- a/views/widget/widget_gtk.cc +++ b/views/widget/widget_gtk.cc @@ -295,7 +295,6 @@ void WidgetGtk::Init(GtkWidget* parent, if (type_ == TYPE_CHILD) { if (parent) { WidgetGtk* parent_widget = GetViewForNative(parent); - parent_widget->AddChild(widget_); parent_widget->PositionChild(widget_, bounds.x(), bounds.y(), bounds.width(), bounds.height()); } @@ -459,7 +458,16 @@ ThemeProvider* WidgetGtk::GetThemeProvider() const { } FocusManager* WidgetGtk::GetFocusManager() { - return focus_manager_.get(); + if (focus_manager_.get()) + return focus_manager_.get(); + + Widget* root = GetRootWidget(); + if (root && root != this) { + // Widget subclasses may override GetFocusManager(), for example for + // dealing with cases where the widget has been unparented. + return root->GetFocusManager(); + } + return NULL; } void WidgetGtk::ViewHierarchyChanged(bool is_add, View *parent, |