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

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

Issue 10408070: Upgrade Seperator in New Autofill UI (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 7 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
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> 7 #include <gdk/gdkkeysyms.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
11 #include "chrome/browser/autofill/autofill_external_delegate.h" 11 #include "chrome/browser/autofill/autofill_external_delegate.h"
12 #include "chrome/browser/ui/gtk/gtk_util.h" 12 #include "chrome/browser/ui/gtk/gtk_util.h"
13 #include "chrome/browser/ui/gtk/gtk_theme_service.h" 13 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
14 #include "content/public/browser/render_view_host.h" 14 #include "content/public/browser/render_view_host.h"
15 #include "content/public/browser/web_contents.h" 15 #include "content/public/browser/web_contents.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAutofillClient.h"
16 #include "ui/base/gtk/gtk_compat.h" 17 #include "ui/base/gtk/gtk_compat.h"
17 #include "ui/base/gtk/gtk_hig_constants.h" 18 #include "ui/base/gtk/gtk_hig_constants.h"
18 #include "ui/base/gtk/gtk_windowing.h" 19 #include "ui/base/gtk/gtk_windowing.h"
19 #include "ui/gfx/native_widget_types.h" 20 #include "ui/gfx/native_widget_types.h"
20 #include "ui/gfx/rect.h" 21 #include "ui/gfx/rect.h"
21 22
23 using WebKit::WebAutofillClient;
24
22 namespace { 25 namespace {
23 const GdkColor kBorderColor = GDK_COLOR_RGB(0xc7, 0xca, 0xce); 26 const GdkColor kBorderColor = GDK_COLOR_RGB(0xc7, 0xca, 0xce);
24 const GdkColor kHoveredBackgroundColor = GDK_COLOR_RGB(0x0CD, 0xCD, 0xCD); 27 const GdkColor kHoveredBackgroundColor = GDK_COLOR_RGB(0x0CD, 0xCD, 0xCD);
25 const GdkColor kTextColor = GDK_COLOR_RGB(0x00, 0x00, 0x00); 28 const GdkColor kTextColor = GDK_COLOR_RGB(0x00, 0x00, 0x00);
26 29
27 // The vertical height of each row in pixels. 30 // The vertical height of each row in pixels.
28 const int kRowHeight = 24; 31 const int kRowHeight = 24;
29 32
33 // The bertical height of a separator in pixels.
Ilya Sherman 2012/05/23 18:58:08 nit: "bertical" -> "vertical"
csharp 2012/05/24 13:40:10 Done.
34 const int kSeparatorHeight = 1;
35
30 // The amount of minimum padding between the Autofill value and label in pixels. 36 // The amount of minimum padding between the Autofill value and label in pixels.
31 const int kMiddlePadding = 10; 37 const int kMiddlePadding = 10;
32 38
33 // The amount of padding between the label and icon or edge and icon in pixels. 39 // The amount of padding between the label and icon or edge and icon in pixels.
34 const int kIconPadding = 5; 40 const int kIconPadding = 5;
35 41
36 // We have a 1 pixel border around the entire results popup. 42 // We have a 1 pixel border around the entire results popup.
37 const int kBorderThickness = 1; 43 const int kBorderThickness = 1;
38 44
39 // Width of the icons in pixels. 45 // Width of the icons in pixels.
40 const int kIconWidth = 25; 46 const int kIconWidth = 25;
41 47
42 // Height of the icons in pixels. 48 // Height of the icons in pixels.
43 const int kIconHeight = 16; 49 const int kIconHeight = 16;
44 50
45 gfx::Rect GetWindowRect(GdkWindow* window) { 51 gfx::Rect GetWindowRect(GdkWindow* window) {
46 return gfx::Rect(gdk_window_get_width(window), 52 return gfx::Rect(gdk_window_get_width(window),
47 gdk_window_get_height(window)); 53 gdk_window_get_height(window));
48 } 54 }
49 55
50 // Returns the rectangle containing the item at position |index| in the popup. 56 int GetRowHeight(int unique_id) {
51 gfx::Rect GetRectForRow(size_t index, int width) { 57 if (unique_id == WebAutofillClient::MenuItemIDSeparator)
52 return gfx::Rect(0, (index * kRowHeight), width, kRowHeight); 58 return kSeparatorHeight;
59
60 return kRowHeight;
53 } 61 }
54 62
55 } // namespace 63 } // namespace
56 64
57 AutofillPopupViewGtk::AutofillPopupViewGtk( 65 AutofillPopupViewGtk::AutofillPopupViewGtk(
58 content::WebContents* web_contents, 66 content::WebContents* web_contents,
59 GtkThemeService* theme_service, 67 GtkThemeService* theme_service,
60 AutofillExternalDelegate* external_delegate, 68 AutofillExternalDelegate* external_delegate,
61 GtkWidget* parent) 69 GtkWidget* parent)
62 : AutofillPopupView(web_contents, external_delegate), 70 : AutofillPopupView(web_contents, external_delegate),
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 void AutofillPopupViewGtk::InvalidateRow(size_t row) { 123 void AutofillPopupViewGtk::InvalidateRow(size_t row) {
116 GdkRectangle row_rect = GetRectForRow(row, bounds_.width()).ToGdkRectangle(); 124 GdkRectangle row_rect = GetRectForRow(row, bounds_.width()).ToGdkRectangle();
117 GdkWindow* gdk_window = gtk_widget_get_window(window_); 125 GdkWindow* gdk_window = gtk_widget_get_window(window_);
118 gdk_window_invalidate_rect(gdk_window, &row_rect, FALSE); 126 gdk_window_invalidate_rect(gdk_window, &row_rect, FALSE);
119 } 127 }
120 128
121 void AutofillPopupViewGtk::ResizePopup() { 129 void AutofillPopupViewGtk::ResizePopup() {
122 gtk_widget_set_size_request( 130 gtk_widget_set_size_request(
123 window_, 131 window_,
124 GetPopupRequiredWidth(), 132 GetPopupRequiredWidth(),
125 kRowHeight * autofill_values().size()); 133 GetPopupRequiredHeight());
126 } 134 }
127 135
128 gboolean AutofillPopupViewGtk::HandleButtonRelease(GtkWidget* widget, 136 gboolean AutofillPopupViewGtk::HandleButtonRelease(GtkWidget* widget,
129 GdkEventButton* event) { 137 GdkEventButton* event) {
130 // We only care about the left click. 138 // We only care about the left click.
131 if (event->button != 1) 139 if (event->button != 1)
132 return FALSE; 140 return FALSE;
133 141
134 DCHECK_EQ(selected_line(), LineFromY(event->y)); 142 DCHECK_EQ(selected_line(), LineFromY(event->y));
135 143
(...skipping 26 matching lines...) Expand all
162 pango_layout_get_size(layout_, &actual_content_width, &actual_content_height); 170 pango_layout_get_size(layout_, &actual_content_width, &actual_content_height);
163 actual_content_width /= PANGO_SCALE; 171 actual_content_width /= PANGO_SCALE;
164 actual_content_height /= PANGO_SCALE; 172 actual_content_height /= PANGO_SCALE;
165 173
166 for (size_t i = 0; i < autofill_values().size(); ++i) { 174 for (size_t i = 0; i < autofill_values().size(); ++i) {
167 gfx::Rect line_rect = GetRectForRow(i, window_rect.width()); 175 gfx::Rect line_rect = GetRectForRow(i, window_rect.width());
168 // Only repaint and layout damaged lines. 176 // Only repaint and layout damaged lines.
169 if (!line_rect.Intersects(damage_rect)) 177 if (!line_rect.Intersects(damage_rect))
170 continue; 178 continue;
171 179
172 if (IsSeparatorIndex(i)) { 180 switch (autofill_unique_ids()[i]) {
Ilya Sherman 2012/05/23 18:58:08 nit: Since there are only two cases, I think this
csharp 2012/05/24 13:40:10 Done.
173 int line_y = i * kRowHeight; 181 case WebAutofillClient::MenuItemIDSeparator:
174 182 DrawSeparator(cr, line_rect);
175 cairo_save(cr); 183 break;
176 cairo_move_to(cr, 0, line_y); 184 default:
177 cairo_line_to(cr, window_rect.width(), line_y); 185 DrawAutofillEntry(cr, i, actual_content_height, line_rect);
178 cairo_stroke(cr);
179 cairo_restore(cr);
180 }
181
182 if (selected_line() == static_cast<int>(i)) {
183 gdk_cairo_set_source_color(cr, &kHoveredBackgroundColor);
184 cairo_rectangle(cr, line_rect.x(), line_rect.y(),
185 line_rect.width(), line_rect.height());
186 cairo_fill(cr);
187 }
188
189 // Center the text within the line.
190 int content_y = std::max(
191 line_rect.y(),
192 line_rect.y() + ((kRowHeight - actual_content_height) / 2));
193
194 // Draw the value.
195 gtk_util::SetLayoutText(layout_, autofill_values()[i]);
196
197 cairo_save(cr);
198 cairo_move_to(cr, 0, content_y);
199 pango_cairo_show_layout(cr, layout_);
200 cairo_restore(cr);
201
202 // Draw the label.
203 int x_align_left = window_rect.width() -
204 font_.GetStringWidth(autofill_labels()[i]);
205
206 if (!autofill_icons()[i].empty())
207 x_align_left -= 2 * kIconPadding + kIconWidth;
208
209 gtk_util::SetLayoutText(layout_, autofill_labels()[i]);
210
211 cairo_save(cr);
212 cairo_move_to(cr, x_align_left, content_y);
213 pango_cairo_show_layout(cr, layout_);
214 cairo_restore(cr);
215
216 // Draw the icon, if one exists
217 if (!autofill_icons()[i].empty()) {
218 int icon = GetIconResourceID(autofill_icons()[i]);
219 DCHECK_NE(-1, icon);
220 int icon_y = line_rect.y() + ((kRowHeight - kIconHeight) / 2);
221
222 cairo_save(cr);
223 gtk_util::DrawFullImage(cr,
224 window_,
225 theme_service_->GetImageNamed(icon),
226 window_rect.width() -
227 (kIconPadding + kIconWidth),
228 icon_y);
229 cairo_restore(cr);
230 } 186 }
231 } 187 }
232 188
233 cairo_destroy(cr); 189 cairo_destroy(cr);
234 190
235 return TRUE; 191 return TRUE;
236 } 192 }
237 193
238 gboolean AutofillPopupViewGtk::HandleMotion(GtkWidget* widget, 194 gboolean AutofillPopupViewGtk::HandleMotion(GtkWidget* widget,
239 GdkEventMotion* event) { 195 GdkEventMotion* event) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 PangoAttribute* fg_attr = pango_attr_foreground_new(text_color.red, 242 PangoAttribute* fg_attr = pango_attr_foreground_new(text_color.red,
287 text_color.green, 243 text_color.green,
288 text_color.blue); 244 text_color.blue);
289 pango_attr_list_insert(attrs, fg_attr); // Ownership taken. 245 pango_attr_list_insert(attrs, fg_attr); // Ownership taken.
290 246
291 247
292 pango_layout_set_attributes(layout_, attrs); // Ref taken. 248 pango_layout_set_attributes(layout_, attrs); // Ref taken.
293 pango_attr_list_unref(attrs); 249 pango_attr_list_unref(attrs);
294 } 250 }
295 251
252
253 void AutofillPopupViewGtk::DrawSeparator(cairo_t* cr,
254 const gfx::Rect& separator_rect) {
255 cairo_save(cr);
256 cairo_move_to(cr, 0, separator_rect.y());
257 cairo_line_to(cr,
258 separator_rect.width(),
259 separator_rect.y() + separator_rect.height());
260 cairo_stroke(cr);
261 cairo_restore(cr);
262 }
263
264 void AutofillPopupViewGtk::DrawAutofillEntry(cairo_t* cr,
265 size_t index,
266 int actual_content_height,
267 const gfx::Rect& entry_rect) {
268 if (selected_line() == static_cast<int>(index)) {
269 gdk_cairo_set_source_color(cr, &kHoveredBackgroundColor);
270 cairo_rectangle(cr, entry_rect.x(), entry_rect.y(),
271 entry_rect.width(), entry_rect.height());
272 cairo_fill(cr);
273 }
274
275 // Center the text within the line.
276 int content_y = std::max(
277 entry_rect.y(),
278 entry_rect.y() + ((kRowHeight - actual_content_height) / 2));
279
280 // Draw the value.
281 gtk_util::SetLayoutText(layout_, autofill_values()[index]);
282
283 cairo_save(cr);
284 cairo_move_to(cr, 0, content_y);
285 pango_cairo_show_layout(cr, layout_);
286 cairo_restore(cr);
287
288 // Draw the label.
289 int x_align_left = entry_rect.width() -
290 font_.GetStringWidth(autofill_labels()[index]);
291
292 if (!autofill_icons()[index].empty())
293 x_align_left -= 2 * kIconPadding + kIconWidth;
294
295 gtk_util::SetLayoutText(layout_, autofill_labels()[index]);
296
297 cairo_save(cr);
298 cairo_move_to(cr, x_align_left, content_y);
299 pango_cairo_show_layout(cr, layout_);
300 cairo_restore(cr);
301
302 // Draw the icon, if one exists
303 if (!autofill_icons()[index].empty()) {
304 int icon = GetIconResourceID(autofill_icons()[index]);
305 DCHECK_NE(-1, icon);
306 int icon_y = entry_rect.y() + ((kRowHeight - kIconHeight) / 2);
307
308 cairo_save(cr);
309 gtk_util::DrawFullImage(cr,
310 window_,
311 theme_service_->GetImageNamed(icon),
312 entry_rect.width() -
313 (kIconPadding + kIconWidth),
314 icon_y);
315 cairo_restore(cr);
316 }
317 }
318
319
296 void AutofillPopupViewGtk::SetBounds() { 320 void AutofillPopupViewGtk::SetBounds() {
297 gint origin_x, origin_y; 321 gint origin_x, origin_y;
298 gdk_window_get_origin(gtk_widget_get_window(parent_), &origin_x, &origin_y); 322 gdk_window_get_origin(gtk_widget_get_window(parent_), &origin_x, &origin_y);
299 323
300 GdkScreen* screen = gtk_widget_get_screen(parent_); 324 GdkScreen* screen = gtk_widget_get_screen(parent_);
301 gint screen_height = gdk_screen_get_height(screen); 325 gint screen_height = gdk_screen_get_height(screen);
302 326
303 int bottom_of_field = origin_y + element_bounds().y() + 327 int bottom_of_field = origin_y + element_bounds().y() +
304 element_bounds().height(); 328 element_bounds().height();
305 int popup_size = kRowHeight * autofill_values().size(); 329 int popup_height = GetPopupRequiredHeight();
306 330
307 // Find the correct top position of the popup so that is doesn't go off 331 // Find the correct top position of the popup so that is doesn't go off
308 // the screen. 332 // the screen.
309 int top_of_popup = 0; 333 int top_of_popup = 0;
310 if (screen_height < bottom_of_field + popup_size) { 334 if (screen_height < bottom_of_field + popup_height) {
311 // The popup must appear above the field. 335 // The popup must appear above the field.
312 top_of_popup = origin_y + element_bounds().y() - popup_size; 336 top_of_popup = origin_y + element_bounds().y() - popup_height;
313 } else { 337 } else {
314 // The popup can appear below the field. 338 // The popup can appear below the field.
315 top_of_popup = bottom_of_field; 339 top_of_popup = bottom_of_field;
316 } 340 }
317 341
318 bounds_.SetRect( 342 bounds_.SetRect(
319 origin_x + element_bounds().x(), 343 origin_x + element_bounds().x(),
320 top_of_popup, 344 top_of_popup,
321 GetPopupRequiredWidth(), 345 GetPopupRequiredWidth(),
322 popup_size); 346 popup_height);
323 } 347 }
324 348
325 int AutofillPopupViewGtk::GetPopupRequiredWidth() { 349 int AutofillPopupViewGtk::GetPopupRequiredWidth() {
326 int popup_width = element_bounds().width(); 350 int popup_width = element_bounds().width();
327 DCHECK_EQ(autofill_values().size(), autofill_labels().size()); 351 DCHECK_EQ(autofill_values().size(), autofill_labels().size());
328 for (size_t i = 0; i < autofill_values().size(); ++i) { 352 for (size_t i = 0; i < autofill_values().size(); ++i) {
329 int row_size = font_.GetStringWidth(autofill_values()[i]) + 353 int row_size = font_.GetStringWidth(autofill_values()[i]) +
330 kMiddlePadding + 354 kMiddlePadding +
331 font_.GetStringWidth(autofill_labels()[i]); 355 font_.GetStringWidth(autofill_labels()[i]);
332 356
333 // Add the icon size if required. 357 // Add the icon size if required.
334 if (!autofill_icons()[i].empty()) 358 if (!autofill_icons()[i].empty())
335 row_size += kIconWidth + 2 * kIconPadding; 359 row_size += kIconWidth + 2 * kIconPadding;
336 360
337 popup_width = std::max(popup_width, row_size); 361 popup_width = std::max(popup_width, row_size);
338 } 362 }
339 363
340 return popup_width; 364 return popup_width;
341 } 365 }
342 366
367 int AutofillPopupViewGtk::GetPopupRequiredHeight() {
368 int popup_height = 0;
369
370 for (size_t i = 0; i < autofill_unique_ids().size(); ++i) {
371 popup_height += GetRowHeight(autofill_unique_ids()[i]);
372 }
373
374 return popup_height;
375 }
376
343 int AutofillPopupViewGtk::LineFromY(int y) { 377 int AutofillPopupViewGtk::LineFromY(int y) {
344 return y / kRowHeight; 378 int current_height = 0;
379
380 for (size_t i = 0; i < autofill_unique_ids().size(); ++i) {
381 current_height += GetRowHeight(autofill_unique_ids()[i]);
382
383 if (y <= current_height)
384 return i;
385 }
386
387 // The y value goes beyond the popup so stop the selection at the last line.
388 return autofill_unique_ids().size() - 1;
Ilya Sherman 2012/05/23 18:58:08 Hmm, I think we might want to return "-1" in this
csharp 2012/05/24 13:40:10 I'm leaving this as is for now, but I've added a T
345 } 389 }
390
391 gfx::Rect AutofillPopupViewGtk::GetRectForRow(size_t row, int width) {
392 int top = 0;
393 for (size_t i = 0; i < row; ++i) {
394 top += GetRowHeight(autofill_unique_ids()[i]);
395 }
396
397 return gfx::Rect(0, top, width, GetRowHeight(autofill_unique_ids()[row]));
398 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698