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

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

Issue 9187009: Basic Drawn text for new GTK Autofill popup. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Responding to Comments Created 8 years, 11 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 | Annotate | Revision Log
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 "base/logging.h" 7 #include "base/logging.h"
8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/ui/gtk/gtk_util.h"
10 #include "ui/gfx/rect.h"
11 #include "ui/gfx/native_widget_types.h"
12 #include "ui/base/gtk/gtk_compat.h"
13 #include "ui/base/gtk/gtk_hig_constants.h"
8 #include "ui/base/gtk/gtk_windowing.h" 14 #include "ui/base/gtk/gtk_windowing.h"
15 #include "ui/gfx/font.h"
16
17 namespace {
18 const GdkColor kBorderColor = GDK_COLOR_RGB(0xc7, 0xca, 0xce);
19 const GdkColor kTextColor = GDK_COLOR_RGB(0x00, 0x00, 0x00);
20
21 // The amount of minimum padding between the autofill value and label in pixels.
Ilya Sherman 2012/01/20 07:26:47 nit: "autofill" -> "Autofill"
csharp 2012/01/20 16:20:44 Done.
22 const int kMiddlePadding = 10;
23
24 // We have a 1 pixel border around the entire results popup.
25 const int kBorderThickness = 1;
26
27 gfx::Rect GetWindowRect(GdkWindow* window) {
28 return gfx::Rect(gdk_window_get_width(window),
29 gdk_window_get_height(window));
30 }
31
32 // Returns the rectangle containing the item at position |index| in the popup.
33 gfx::Rect GetRectForRow(size_t index, int width, int height) {
34 return gfx::Rect(0, (index * height), width, height);
35 }
36
37 } // namespace
9 38
10 AutofillPopupViewGtk::AutofillPopupViewGtk(content::WebContents* web_contents, 39 AutofillPopupViewGtk::AutofillPopupViewGtk(content::WebContents* web_contents,
11 GtkWidget* parent) 40 GtkWidget* parent)
12 : AutofillPopupView(web_contents), 41 : AutofillPopupView(web_contents),
13 parent_(parent), 42 parent_(parent),
14 window_(gtk_window_new(GTK_WINDOW_POPUP)) { 43 window_(gtk_window_new(GTK_WINDOW_POPUP)) {
15 CHECK(parent != NULL); 44 CHECK(parent != NULL);
16 gtk_window_set_resizable(GTK_WINDOW(window_), FALSE); 45 gtk_window_set_resizable(GTK_WINDOW(window_), FALSE);
17 gtk_widget_set_app_paintable(window_, TRUE); 46 gtk_widget_set_app_paintable(window_, TRUE);
18 gtk_widget_set_double_buffered(window_, TRUE); 47 gtk_widget_set_double_buffered(window_, TRUE);
19 48
20 // Setup the window to ensure it recieves the expose event. 49 // Setup the window to ensure it recieves the expose event.
21 gtk_widget_add_events(window_, GDK_EXPOSURE_MASK); 50 gtk_widget_add_events(window_, GDK_EXPOSURE_MASK);
22 g_signal_connect(window_, "expose-event", 51 g_signal_connect(window_, "expose-event",
23 G_CALLBACK(HandleExposeThunk), this); 52 G_CALLBACK(HandleExposeThunk), this);
53
54 // Cache the layout so we don't have to create it for every expose.
55 layout_ = gtk_widget_create_pango_layout(window_, NULL);
56
57 row_height_ = font_.GetHeight();
24 } 58 }
25 59
26 AutofillPopupViewGtk::~AutofillPopupViewGtk() { 60 AutofillPopupViewGtk::~AutofillPopupViewGtk() {
61 g_object_unref(layout_);
27 gtk_widget_destroy(window_); 62 gtk_widget_destroy(window_);
28 } 63 }
29 64
30 void AutofillPopupViewGtk::Hide() { 65 void AutofillPopupViewGtk::Hide() {
31 gtk_widget_hide(window_); 66 gtk_widget_hide(window_);
32 } 67 }
33 68
34 // TODO(csharp): Actually show the values. 69 void AutofillPopupViewGtk::ShowInternal() {
35 void AutofillPopupViewGtk::Show(const std::vector<string16>& autofill_values,
36 const std::vector<string16>& autofill_labels,
37 const std::vector<string16>& autofill_icons,
38 const std::vector<int>& autofill_unique_ids,
39 int separator_index) {
40 gint origin_x, origin_y; 70 gint origin_x, origin_y;
41 gdk_window_get_origin(gtk_widget_get_window(parent_), &origin_x, &origin_y); 71 gdk_window_get_origin(gtk_widget_get_window(parent_), &origin_x, &origin_y);
42 72
73 // Move the popup to appear right below the text field it is using.
43 gtk_window_move(GTK_WINDOW(window_), 74 gtk_window_move(GTK_WINDOW(window_),
44 origin_x + element_bounds().x(), 75 origin_x + element_bounds().x(),
45 origin_y + element_bounds().y() + element_bounds().height()); 76 origin_y + element_bounds().y() + element_bounds().height());
46 77
78 // Find out the maximum bounds required by the popup.
79 // TODO(csharp): Once the icon is also displayed it will affect the required
80 // size so it will need to be include in the calculation.
Ilya Sherman 2012/01/20 07:26:47 nit: "include" -> "included"
csharp 2012/01/20 16:20:44 Done.
81 int popup_width = element_bounds().width();
82 DCHECK_EQ(autofill_values().size(), autofill_labels().size());
83 for (size_t i = 0; i < autofill_values().size(); ++i) {
84 popup_width = std::max(popup_width,
85 font_.GetStringWidth(autofill_values()[i]) +
86 kMiddlePadding +
87 font_.GetStringWidth(autofill_labels()[i]));
88 }
89
47 gtk_widget_set_size_request( 90 gtk_widget_set_size_request(
48 window_, 91 window_,
49 element_bounds().width(), 92 popup_width,
50 element_bounds().height() * autofill_values.size()); 93 row_height_ * autofill_values().size());
51 94
52 gtk_widget_show(window_); 95 gtk_widget_show(window_);
53 96
54 GtkWidget* toplevel = gtk_widget_get_toplevel(parent_); 97 GtkWidget* toplevel = gtk_widget_get_toplevel(parent_);
55 CHECK(gtk_widget_is_toplevel(toplevel)); 98 CHECK(gtk_widget_is_toplevel(toplevel));
56 ui::StackPopupWindow(window_, toplevel); 99 ui::StackPopupWindow(window_, toplevel);
57 } 100 }
58 101
59 gboolean AutofillPopupViewGtk::HandleExpose(GtkWidget* widget, 102 gboolean AutofillPopupViewGtk::HandleExpose(GtkWidget* widget,
60 GdkEventExpose* event) { 103 GdkEventExpose* event) {
104 gfx::Rect window_rect = GetWindowRect(event->window);
105 gfx::Rect damage_rect = gfx::Rect(event->area);
106
107 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(gtk_widget_get_window(widget)));
108 gdk_cairo_rectangle(cr, &event->area);
109 cairo_clip(cr);
110
111 // This assert is kinda ugly, but it would be more currently unneeded work
112 // to support painting a border that isn't 1 pixel thick. There is no point
113 // in writing that code now, and explode if that day ever comes.
114 COMPILE_ASSERT(kBorderThickness == 1, border_1px_implied);
115 // Draw the 1px border around the entire window.
116 gdk_cairo_set_source_color(cr, &kBorderColor);
117 cairo_rectangle(cr, 0, 0, window_rect.width(), window_rect.height());
118 cairo_stroke(cr);
119
120 SetupLayout(window_rect, kTextColor);
121
122 int actual_content_width, actual_content_height;
123 pango_layout_get_size(layout_, &actual_content_width, &actual_content_height);
124 actual_content_width /= PANGO_SCALE;
125 actual_content_height /= PANGO_SCALE;
126
127 for (size_t i = 0; i < autofill_values().size(); ++i) {
128 gfx::Rect line_rect = GetRectForRow(i, window_rect.width(), row_height_);
129 // Only repaint and layout damaged lines.
130 if (!line_rect.Intersects(damage_rect))
131 continue;
132
133 if (separator_index() == static_cast<int>(i)) {
134 int line_y = i * row_height_;
135
136 cairo_save(cr);
137 cairo_move_to(cr, 0, line_y);
138 cairo_line_to(cr, window_rect.width(), line_y);
139 cairo_stroke(cr);
140 cairo_restore(cr);
141 }
142
143 // Center the text within the line.
144 int content_y = std::max(
145 line_rect.y(),
146 line_rect.y() + ((row_height_ - actual_content_height) / 2));
147
148 // Draw the autofill value.
Ilya Sherman 2012/01/20 07:26:47 nit: "autofill" -> "Autofill" (or just omit "Autof
csharp 2012/01/20 16:20:44 Done.
149 gtk_util::SetLayoutText(layout_, autofill_values()[i]);
150
151 cairo_save(cr);
152 cairo_move_to(cr, 0, content_y);
153 pango_cairo_show_layout(cr, layout_);
154 cairo_restore(cr);
155
156 // Draw the autofill label.
Ilya Sherman 2012/01/20 07:26:47 nit: Ditto
csharp 2012/01/20 16:20:44 Done.
157 int x_align_left = window_rect.width() -
158 font_.GetStringWidth(autofill_labels()[i]);
159 gtk_util::SetLayoutText(layout_, autofill_labels()[i]);
160
161 cairo_save(cr);
162 cairo_move_to(cr, x_align_left, line_rect.y());
163 pango_cairo_show_layout(cr, layout_);
164 cairo_restore(cr);
165 }
166
167 cairo_destroy(cr);
168
61 return TRUE; 169 return TRUE;
62 } 170 }
171
172 void AutofillPopupViewGtk::SetupLayout(const gfx::Rect& window_rect,
173 const GdkColor& text_color) {
174 int allocated_content_width = window_rect.width();
175 pango_layout_set_width(layout_, allocated_content_width * PANGO_SCALE);
176 pango_layout_set_height(layout_, row_height_ * PANGO_SCALE);
177
178 PangoAttrList* attrs = pango_attr_list_new();
179
180 PangoAttribute* fg_attr = pango_attr_foreground_new(text_color.red,
181 text_color.green,
182 text_color.blue);
183 pango_attr_list_insert(attrs, fg_attr); // Ownership taken.
184
185
186 pango_layout_set_attributes(layout_, attrs); // Ref taken.
187 pango_attr_list_unref(attrs);
188 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698