Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.cc

Issue 9432029: GTK Keyboard Support for New Autofill (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.h ('k') | chrome/chrome_tests.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "autofill_popup_view_gtk.h" 5 #include "autofill_popup_view_gtk.h"
6 6
7 #include <gdk/gdkkeysyms.h>
8
7 #include "base/logging.h" 9 #include "base/logging.h"
8 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/autofill/autofill_external_delegate.h" 11 #include "chrome/browser/autofill/autofill_external_delegate.h"
10 #include "chrome/browser/ui/gtk/gtk_util.h" 12 #include "chrome/browser/ui/gtk/gtk_util.h"
13 #include "content/public/browser/render_view_host.h"
14 #include "content/public/browser/web_contents.h"
11 #include "ui/base/gtk/gtk_compat.h" 15 #include "ui/base/gtk/gtk_compat.h"
12 #include "ui/base/gtk/gtk_hig_constants.h" 16 #include "ui/base/gtk/gtk_hig_constants.h"
13 #include "ui/base/gtk/gtk_windowing.h" 17 #include "ui/base/gtk/gtk_windowing.h"
14 #include "ui/gfx/native_widget_types.h" 18 #include "ui/gfx/native_widget_types.h"
15 #include "ui/gfx/rect.h" 19 #include "ui/gfx/rect.h"
16 20
17 namespace { 21 namespace {
18 const GdkColor kBorderColor = GDK_COLOR_RGB(0xc7, 0xca, 0xce); 22 const GdkColor kBorderColor = GDK_COLOR_RGB(0xc7, 0xca, 0xce);
19 const GdkColor kHoveredBackgroundColor = GDK_COLOR_RGB(0x0CD, 0xCD, 0xCD); 23 const GdkColor kHoveredBackgroundColor = GDK_COLOR_RGB(0x0CD, 0xCD, 0xCD);
20 const GdkColor kTextColor = GDK_COLOR_RGB(0x00, 0x00, 0x00); 24 const GdkColor kTextColor = GDK_COLOR_RGB(0x00, 0x00, 0x00);
(...skipping 15 matching lines...) Expand all
36 } 40 }
37 41
38 } // namespace 42 } // namespace
39 43
40 AutofillPopupViewGtk::AutofillPopupViewGtk( 44 AutofillPopupViewGtk::AutofillPopupViewGtk(
41 content::WebContents* web_contents, 45 content::WebContents* web_contents,
42 AutofillExternalDelegate* external_delegate, 46 AutofillExternalDelegate* external_delegate,
43 GtkWidget* parent) 47 GtkWidget* parent)
44 : AutofillPopupView(web_contents, external_delegate), 48 : AutofillPopupView(web_contents, external_delegate),
45 parent_(parent), 49 parent_(parent),
46 window_(gtk_window_new(GTK_WINDOW_POPUP)) { 50 window_(gtk_window_new(GTK_WINDOW_POPUP)),
51 render_view_host_(web_contents->GetRenderViewHost()) {
47 CHECK(parent != NULL); 52 CHECK(parent != NULL);
48 gtk_window_set_resizable(GTK_WINDOW(window_), FALSE); 53 gtk_window_set_resizable(GTK_WINDOW(window_), FALSE);
49 gtk_widget_set_app_paintable(window_, TRUE); 54 gtk_widget_set_app_paintable(window_, TRUE);
50 gtk_widget_set_double_buffered(window_, TRUE); 55 gtk_widget_set_double_buffered(window_, TRUE);
51 56
52 // Setup the window to ensure it receives the expose event. 57 // Setup the window to ensure it receives the expose event.
53 gtk_widget_add_events(window_, GDK_BUTTON_MOTION_MASK | 58 gtk_widget_add_events(window_, GDK_BUTTON_MOTION_MASK |
54 GDK_BUTTON_RELEASE_MASK | 59 GDK_BUTTON_RELEASE_MASK |
55 GDK_EXPOSURE_MASK | 60 GDK_EXPOSURE_MASK |
56 GDK_POINTER_MOTION_MASK); 61 GDK_POINTER_MOTION_MASK);
(...skipping 10 matching lines...) Expand all
67 72
68 row_height_ = font_.GetHeight(); 73 row_height_ = font_.GetHeight();
69 } 74 }
70 75
71 AutofillPopupViewGtk::~AutofillPopupViewGtk() { 76 AutofillPopupViewGtk::~AutofillPopupViewGtk() {
72 g_object_unref(layout_); 77 g_object_unref(layout_);
73 gtk_widget_destroy(window_); 78 gtk_widget_destroy(window_);
74 } 79 }
75 80
76 void AutofillPopupViewGtk::ShowInternal() { 81 void AutofillPopupViewGtk::ShowInternal() {
77 // Find out the maximum bounds required by the popup.
78 // TODO(csharp): Once the icon is also displayed it will affect the required
79 // size so it will need to be included in the calculation.
80 int popup_width = element_bounds().width();
81 DCHECK_EQ(autofill_values().size(), autofill_labels().size());
82 for (size_t i = 0; i < autofill_values().size(); ++i) {
83 popup_width = std::max(popup_width,
84 font_.GetStringWidth(autofill_values()[i]) +
85 kMiddlePadding +
86 font_.GetStringWidth(autofill_labels()[i]));
87 }
88
89 gint origin_x, origin_y; 82 gint origin_x, origin_y;
90 gdk_window_get_origin(gtk_widget_get_window(parent_), &origin_x, &origin_y); 83 gdk_window_get_origin(gtk_widget_get_window(parent_), &origin_x, &origin_y);
91 84
85 int popup_width = GetPopupRequiredWidth();
86
92 // Move the popup to appear right below the text field it is using. 87 // Move the popup to appear right below the text field it is using.
93 bounds_.SetRect( 88 bounds_.SetRect(
94 origin_x + element_bounds().x(), 89 origin_x + element_bounds().x(),
95 origin_y + element_bounds().y() + element_bounds().height(), 90 origin_y + element_bounds().y() + element_bounds().height(),
96 popup_width, 91 popup_width,
97 row_height_ * autofill_values().size()); 92 row_height_ * autofill_values().size());
98 93
99 gtk_window_move(GTK_WINDOW(window_), bounds_.x(), bounds_.y()); 94 gtk_window_move(GTK_WINDOW(window_), bounds_.x(), bounds_.y());
100 95
101 gtk_widget_set_size_request( 96 gtk_widget_set_size_request(
102 window_, 97 window_,
103 popup_width, 98 popup_width,
104 row_height_ * autofill_values().size()); 99 row_height_ * autofill_values().size());
105 100
101 render_view_host_->AddKeyboardListener(this);
102
106 gtk_widget_show(window_); 103 gtk_widget_show(window_);
107 104
108 GtkWidget* toplevel = gtk_widget_get_toplevel(parent_); 105 GtkWidget* toplevel = gtk_widget_get_toplevel(parent_);
109 CHECK(gtk_widget_is_toplevel(toplevel)); 106 CHECK(gtk_widget_is_toplevel(toplevel));
110 ui::StackPopupWindow(window_, toplevel); 107 ui::StackPopupWindow(window_, toplevel);
111 } 108 }
112 109
113 void AutofillPopupViewGtk::HideInternal() { 110 void AutofillPopupViewGtk::HideInternal() {
111 render_view_host_->RemoveKeyboardListener(this);
112
114 gtk_widget_hide(window_); 113 gtk_widget_hide(window_);
115 } 114 }
116 115
117 void AutofillPopupViewGtk::InvalidateRow(size_t row) { 116 void AutofillPopupViewGtk::InvalidateRow(size_t row) {
118 GdkRectangle row_rect = GetRectForRow( 117 GdkRectangle row_rect = GetRectForRow(
119 row, bounds_.width(), row_height_).ToGdkRectangle(); 118 row, bounds_.width(), row_height_).ToGdkRectangle();
120 GdkWindow* gdk_window = gtk_widget_get_window(window_); 119 GdkWindow* gdk_window = gtk_widget_get_window(window_);
121 gdk_window_invalidate_rect(gdk_window, &row_rect, FALSE); 120 gdk_window_invalidate_rect(gdk_window, &row_rect, FALSE);
122 } 121 }
123 122
124 gboolean AutofillPopupViewGtk::HandleButtonRelease(GtkWidget* widget, 123 gboolean AutofillPopupViewGtk::HandleButtonRelease(GtkWidget* widget,
125 GdkEventButton* event) { 124 GdkEventButton* event) {
126 // We only care about the left click. 125 // We only care about the left click.
127 if (event->button != 1) 126 if (event->button != 1)
128 return FALSE; 127 return FALSE;
129 128
130 size_t line = LineFromY(event->y); 129 DCHECK_EQ(selected_line(), LineFromY(event->y));
131 DCHECK_LT(line, autofill_values().size());
132 130
133 external_delegate()->DidAcceptAutofillSuggestions( 131 AcceptSelectedLine();
134 autofill_values()[line],
135 autofill_unique_ids()[line],
136 line);
137 132
138 return TRUE; 133 return TRUE;
139 } 134 }
140 135
141 gboolean AutofillPopupViewGtk::HandleExpose(GtkWidget* widget, 136 gboolean AutofillPopupViewGtk::HandleExpose(GtkWidget* widget,
142 GdkEventExpose* event) { 137 GdkEventExpose* event) {
143 gfx::Rect window_rect = GetWindowRect(event->window); 138 gfx::Rect window_rect = GetWindowRect(event->window);
144 gfx::Rect damage_rect = gfx::Rect(event->area); 139 gfx::Rect damage_rect = gfx::Rect(event->area);
145 140
146 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(gtk_widget_get_window(widget))); 141 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(gtk_widget_get_window(widget)));
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 212
218 gboolean AutofillPopupViewGtk::HandleMotion(GtkWidget* widget, 213 gboolean AutofillPopupViewGtk::HandleMotion(GtkWidget* widget,
219 GdkEventMotion* event) { 214 GdkEventMotion* event) {
220 int line = LineFromY(event->y); 215 int line = LineFromY(event->y);
221 216
222 SetSelectedLine(line); 217 SetSelectedLine(line);
223 218
224 return TRUE; 219 return TRUE;
225 } 220 }
226 221
222 bool AutofillPopupViewGtk::HandleKeyPressEvent(GdkEventKey* event) {
223 switch (event->keyval) {
224 case GDK_Up:
225 SelectPreviousLine();
226 return true;
227 case GDK_Down:
228 SelectNextLine();
229 return true;
230 case GDK_Page_Up:
231 SetSelectedLine(0);
232 return true;
233 case GDK_Page_Down:
234 SetSelectedLine(autofill_values().size() - 1);
235 return true;
236 case GDK_Escape:
237 Hide();
238 return true;
239 case GDK_Delete:
240 case GDK_KP_Delete:
Ilya Sherman 2012/03/24 00:53:21 Also, it looks like this is still checking for jus
csharp 2012/03/26 14:13:45 Sorry, I'd missed your comment on how normal Autoc
241 if (selected_line() != kNoSelection) {
Ilya Sherman 2012/03/23 22:31:13 nit: I was suggesting that this check be part of R
csharp 2012/03/26 14:13:45 Done.
242 return RemoveSelectedLine();
243 }
244 break;
245 case GDK_Return:
246 case GDK_KP_Enter:
247 if (selected_line() != kNoSelection) {
Ilya Sherman 2012/03/23 22:31:13 nit: Ditto
csharp 2012/03/26 14:13:45 Done.
248 return AcceptSelectedLine();
249 }
250 break;
251 }
252
253 return false;
254 }
255
227 void AutofillPopupViewGtk::SetupLayout(const gfx::Rect& window_rect, 256 void AutofillPopupViewGtk::SetupLayout(const gfx::Rect& window_rect,
228 const GdkColor& text_color) { 257 const GdkColor& text_color) {
229 int allocated_content_width = window_rect.width(); 258 int allocated_content_width = window_rect.width();
230 pango_layout_set_width(layout_, allocated_content_width * PANGO_SCALE); 259 pango_layout_set_width(layout_, allocated_content_width * PANGO_SCALE);
231 pango_layout_set_height(layout_, row_height_ * PANGO_SCALE); 260 pango_layout_set_height(layout_, row_height_ * PANGO_SCALE);
232 261
233 PangoAttrList* attrs = pango_attr_list_new(); 262 PangoAttrList* attrs = pango_attr_list_new();
234 263
235 PangoAttribute* fg_attr = pango_attr_foreground_new(text_color.red, 264 PangoAttribute* fg_attr = pango_attr_foreground_new(text_color.red,
236 text_color.green, 265 text_color.green,
237 text_color.blue); 266 text_color.blue);
238 pango_attr_list_insert(attrs, fg_attr); // Ownership taken. 267 pango_attr_list_insert(attrs, fg_attr); // Ownership taken.
239 268
240 269
241 pango_layout_set_attributes(layout_, attrs); // Ref taken. 270 pango_layout_set_attributes(layout_, attrs); // Ref taken.
242 pango_attr_list_unref(attrs); 271 pango_attr_list_unref(attrs);
243 } 272 }
244 273
274 int AutofillPopupViewGtk::GetPopupRequiredWidth() {
275 // TODO(csharp): Once the icon is also displayed it will affect the required
276 // size so it will need to be included in the calculation.
277 int popup_width = element_bounds().width();
278 DCHECK_EQ(autofill_values().size(), autofill_labels().size());
279 for (size_t i = 0; i < autofill_values().size(); ++i) {
280 popup_width = std::max(popup_width,
281 font_.GetStringWidth(autofill_values()[i]) +
282 kMiddlePadding +
283 font_.GetStringWidth(autofill_labels()[i]));
284 }
285
286 return popup_width;
287 }
288
245 int AutofillPopupViewGtk::LineFromY(int y) { 289 int AutofillPopupViewGtk::LineFromY(int y) {
246 return y / row_height_; 290 return y / row_height_;
247 } 291 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.h ('k') | chrome/chrome_tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698