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

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

Issue 11636040: AutofillPopupController clarifications + simplifications. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ilya review Created 8 years 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 "chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.h" 5 #include "chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.h"
6 6
7 #include <gdk/gdkkeysyms.h> 7 #include <gdk/gdkkeysyms.h>
8 8
9 #include "base/i18n/rtl.h" 9 #include "base/i18n/rtl.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 12 matching lines...) Expand all
23 #include "ui/gfx/rect.h" 23 #include "ui/gfx/rect.h"
24 24
25 using WebKit::WebAutofillClient; 25 using WebKit::WebAutofillClient;
26 26
27 namespace { 27 namespace {
28 const GdkColor kBorderColor = GDK_COLOR_RGB(0xc7, 0xca, 0xce); 28 const GdkColor kBorderColor = GDK_COLOR_RGB(0xc7, 0xca, 0xce);
29 const GdkColor kHoveredBackgroundColor = GDK_COLOR_RGB(0xcd, 0xcd, 0xcd); 29 const GdkColor kHoveredBackgroundColor = GDK_COLOR_RGB(0xcd, 0xcd, 0xcd);
30 const GdkColor kValueTextColor = GDK_COLOR_RGB(0x00, 0x00, 0x00); 30 const GdkColor kValueTextColor = GDK_COLOR_RGB(0x00, 0x00, 0x00);
31 const GdkColor kLabelTextColor = GDK_COLOR_RGB(0x7f, 0x7f, 0x7f); 31 const GdkColor kLabelTextColor = GDK_COLOR_RGB(0x7f, 0x7f, 0x7f);
32 32
33 gfx::Rect GetWindowRect(GdkWindow* window) {
34 return gfx::Rect(gdk_window_get_width(window),
35 gdk_window_get_height(window));
36 }
37
38 } // namespace 33 } // namespace
39 34
40 AutofillPopupViewGtk::AutofillPopupViewGtk( 35 AutofillPopupViewGtk::AutofillPopupViewGtk(
41 AutofillPopupController* controller) 36 AutofillPopupController* controller)
42 : controller_(controller), 37 : controller_(controller),
43 window_(gtk_window_new(GTK_WINDOW_POPUP)) { 38 window_(gtk_window_new(GTK_WINDOW_POPUP)) {
44 gtk_window_set_resizable(GTK_WINDOW(window_), FALSE); 39 gtk_window_set_resizable(GTK_WINDOW(window_), FALSE);
45 gtk_widget_set_app_paintable(window_, TRUE); 40 gtk_widget_set_app_paintable(window_, TRUE);
46 gtk_widget_set_double_buffered(window_, TRUE); 41 gtk_widget_set_double_buffered(window_, TRUE);
47 42
(...skipping 30 matching lines...) Expand all
78 UpdateBoundsAndRedrawPopup(); 73 UpdateBoundsAndRedrawPopup();
79 74
80 gtk_widget_show(window_); 75 gtk_widget_show(window_);
81 76
82 GtkWidget* parent_window = 77 GtkWidget* parent_window =
83 gtk_widget_get_toplevel(controller_->container_view()); 78 gtk_widget_get_toplevel(controller_->container_view());
84 ui::StackPopupWindow(window_, parent_window); 79 ui::StackPopupWindow(window_, parent_window);
85 } 80 }
86 81
87 void AutofillPopupViewGtk::InvalidateRow(size_t row) { 82 void AutofillPopupViewGtk::InvalidateRow(size_t row) {
88 GdkRectangle row_rect = controller_->GetRectForRow( 83 GdkRectangle row_rect = controller_->GetRowBounds(row).ToGdkRectangle();
89 row,
90 controller_->popup_bounds().width()).ToGdkRectangle();
91 GdkWindow* gdk_window = gtk_widget_get_window(window_); 84 GdkWindow* gdk_window = gtk_widget_get_window(window_);
92 gdk_window_invalidate_rect(gdk_window, &row_rect, FALSE); 85 gdk_window_invalidate_rect(gdk_window, &row_rect, FALSE);
93 } 86 }
94 87
95 void AutofillPopupViewGtk::UpdateBoundsAndRedrawPopup() { 88 void AutofillPopupViewGtk::UpdateBoundsAndRedrawPopup() {
96 gtk_widget_set_size_request(window_, 89 gtk_widget_set_size_request(window_,
97 controller_->popup_bounds().width(), 90 controller_->popup_bounds().width(),
98 controller_->popup_bounds().height()); 91 controller_->popup_bounds().height());
99 gtk_window_move(GTK_WINDOW(window_), 92 gtk_window_move(GTK_WINDOW(window_),
100 controller_->popup_bounds().x(), 93 controller_->popup_bounds().x(),
101 controller_->popup_bounds().y()); 94 controller_->popup_bounds().y());
102 95
103 GdkWindow* gdk_window = gtk_widget_get_window(window_); 96 GdkWindow* gdk_window = gtk_widget_get_window(window_);
104 GdkRectangle popup_rect = controller_->popup_bounds().ToGdkRectangle(); 97 GdkRectangle popup_rect = controller_->popup_bounds().ToGdkRectangle();
105 if (gdk_window != NULL) 98 if (gdk_window != NULL)
106 gdk_window_invalidate_rect(gdk_window, &popup_rect, FALSE); 99 gdk_window_invalidate_rect(gdk_window, &popup_rect, FALSE);
107 } 100 }
108 101
109 gboolean AutofillPopupViewGtk::HandleButtonRelease(GtkWidget* widget, 102 gboolean AutofillPopupViewGtk::HandleButtonRelease(GtkWidget* widget,
110 GdkEventButton* event) { 103 GdkEventButton* event) {
111 // We only care about the left click. 104 // We only care about the left click.
112 if (event->button != 1) 105 if (event->button != 1)
113 return FALSE; 106 return FALSE;
114 107
115 controller_->AcceptSelectedPosition(event->x, event->y); 108 controller_->MouseClicked(event->x, event->y);
116 return TRUE; 109 return TRUE;
117 } 110 }
118 111
119 gboolean AutofillPopupViewGtk::HandleExpose(GtkWidget* widget, 112 gboolean AutofillPopupViewGtk::HandleExpose(GtkWidget* widget,
120 GdkEventExpose* event) { 113 GdkEventExpose* event) {
121 gfx::Rect window_rect = GetWindowRect(event->window);
122 gfx::Rect damage_rect = gfx::Rect(event->area);
123
124 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(gtk_widget_get_window(widget))); 114 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(gtk_widget_get_window(widget)));
125 gdk_cairo_rectangle(cr, &event->area); 115 gdk_cairo_rectangle(cr, &event->area);
126 cairo_clip(cr); 116 cairo_clip(cr);
127 117
128 // This assert is kinda ugly, but it would be more currently unneeded work 118 // This assert is kinda ugly, but it would be more currently unneeded work
129 // to support painting a border that isn't 1 pixel thick. There is no point 119 // to support painting a border that isn't 1 pixel thick. There is no point
130 // in writing that code now, and explode if that day ever comes. 120 // in writing that code now, and explode if that day ever comes.
131 DCHECK_EQ(1, kBorderThickness); 121 DCHECK_EQ(1, kBorderThickness);
132 // Draw the 1px border around the entire window. 122 // Draw the 1px border around the entire window.
133 gdk_cairo_set_source_color(cr, &kBorderColor); 123 gdk_cairo_set_source_color(cr, &kBorderColor);
134 cairo_rectangle(cr, 0, 0, window_rect.width(), window_rect.height()); 124 gdk_cairo_rectangle(cr, &widget->allocation);
135 cairo_stroke(cr); 125 cairo_stroke(cr);
126 SetUpLayout();
136 127
137 SetupLayout(window_rect); 128 gfx::Rect damage_rect(event->area);
138 129
139 for (size_t i = 0; i < controller_->autofill_values().size(); ++i) { 130 for (size_t i = 0; i < controller_->labels().size(); ++i) {
140 gfx::Rect line_rect = controller_->GetRectForRow(i, window_rect.width()); 131 gfx::Rect line_rect = controller_->GetRowBounds(i);
141 // Only repaint and layout damaged lines. 132 // Only repaint and layout damaged lines.
142 if (!line_rect.Intersects(damage_rect)) 133 if (!line_rect.Intersects(damage_rect))
143 continue; 134 continue;
144 135
145 if (controller_->autofill_unique_ids()[i] == 136 if (controller_->identifiers()[i] ==
146 WebAutofillClient::MenuItemIDSeparator) { 137 WebAutofillClient::MenuItemIDSeparator) {
147 DrawSeparator(cr, line_rect); 138 DrawSeparator(cr, line_rect);
148 } else { 139 } else {
149 DrawAutofillEntry(cr, i, line_rect); 140 DrawAutofillEntry(cr, i, line_rect);
150 } 141 }
151 } 142 }
152 143
153 cairo_destroy(cr); 144 cairo_destroy(cr);
154 145
155 return TRUE; 146 return TRUE;
156 } 147 }
157 148
158 gboolean AutofillPopupViewGtk::HandleLeave(GtkWidget* widget, 149 gboolean AutofillPopupViewGtk::HandleLeave(GtkWidget* widget,
159 GdkEventCrossing* event) { 150 GdkEventCrossing* event) {
160 controller_->ClearSelectedLine(); 151 controller_->MouseExitedPopup();
161 152
162 return FALSE; 153 return FALSE;
163 } 154 }
164 155
165 gboolean AutofillPopupViewGtk::HandleMotion(GtkWidget* widget, 156 gboolean AutofillPopupViewGtk::HandleMotion(GtkWidget* widget,
166 GdkEventMotion* event) { 157 GdkEventMotion* event) {
167 controller_->SetSelectedPosition(event->x, event->y); 158 controller_->MouseHovered(event->x, event->y);
168 159
169 return TRUE; 160 return TRUE;
170 } 161 }
171 162
172 void AutofillPopupViewGtk::SetupLayout(const gfx::Rect& window_rect) { 163 void AutofillPopupViewGtk::SetupLayout() {
173 pango_layout_set_width(layout_, window_rect.width() * PANGO_SCALE); 164 pango_layout_set_width(layout_, window_->allocation.width * PANGO_SCALE);
174 pango_layout_set_height(layout_, window_rect.height() * PANGO_SCALE); 165 pango_layout_set_height(layout_, window_->allocation.height * PANGO_SCALE);
175 } 166 }
176 167
177 void AutofillPopupViewGtk::SetLayoutText(const string16& text, 168 void AutofillPopupViewGtk::SetLayoutText(const string16& text,
178 const gfx::Font& font, 169 const gfx::Font& font,
179 const GdkColor text_color) { 170 const GdkColor text_color) {
180 PangoAttrList* attrs = pango_attr_list_new(); 171 PangoAttrList* attrs = pango_attr_list_new();
181 172
182 PangoAttribute* fg_attr = pango_attr_foreground_new(text_color.red, 173 PangoAttribute* fg_attr = pango_attr_foreground_new(text_color.red,
183 text_color.green, 174 text_color.green,
184 text_color.blue); 175 text_color.blue);
(...skipping 29 matching lines...) Expand all
214 size_t index, 205 size_t index,
215 const gfx::Rect& entry_rect) { 206 const gfx::Rect& entry_rect) {
216 if (controller_->selected_line() == static_cast<int>(index)) { 207 if (controller_->selected_line() == static_cast<int>(index)) {
217 gdk_cairo_set_source_color(cairo_context, &kHoveredBackgroundColor); 208 gdk_cairo_set_source_color(cairo_context, &kHoveredBackgroundColor);
218 cairo_rectangle(cairo_context, entry_rect.x(), entry_rect.y(), 209 cairo_rectangle(cairo_context, entry_rect.x(), entry_rect.y(),
219 entry_rect.width(), entry_rect.height()); 210 entry_rect.width(), entry_rect.height());
220 cairo_fill(cairo_context); 211 cairo_fill(cairo_context);
221 } 212 }
222 213
223 // Draw the value. 214 // Draw the value.
224 SetLayoutText(controller_->autofill_values()[index], 215 SetLayoutText(controller_->labels()[index],
225 controller_->value_font(), 216 controller_->label_font(),
226 kValueTextColor); 217 kValueTextColor);
227 int value_text_width = controller_->value_font().GetStringWidth( 218 int value_text_width =
228 controller_->autofill_values()[index]); 219 controller_->label_font().GetStringWidth(controller_->labels()[index]);
229 220
230 // Center the text within the line. 221 // Center the text within the line.
231 int row_height = controller_->GetRowHeightFromId( 222 int row_height = controller_->GetRowBounds(index).height();
232 controller_->autofill_unique_ids()[index]);
233 int value_content_y = std::max( 223 int value_content_y = std::max(
234 entry_rect.y(), 224 entry_rect.y(),
235 entry_rect.y() + 225 entry_rect.y() +
236 (row_height - controller_->value_font().GetHeight()) / 2); 226 (row_height - controller_->label_font().GetHeight()) / 2);
237 227
238 bool is_rtl = base::i18n::IsRTL(); 228 bool is_rtl = base::i18n::IsRTL();
239 int value_content_x = is_rtl ? 229 int value_content_x = is_rtl ?
240 entry_rect.width() - value_text_width - kEndPadding : kEndPadding; 230 entry_rect.width() - value_text_width - kEndPadding : kEndPadding;
241 231
242 cairo_save(cairo_context); 232 cairo_save(cairo_context);
243 cairo_move_to(cairo_context, value_content_x, value_content_y); 233 cairo_move_to(cairo_context, value_content_x, value_content_y);
244 pango_cairo_show_layout(cairo_context, layout_); 234 pango_cairo_show_layout(cairo_context, layout_);
245 cairo_restore(cairo_context); 235 cairo_restore(cairo_context);
246 236
247 // Use this to figure out where all the other Autofill items should be placed. 237 // Use this to figure out where all the other Autofill items should be placed.
248 int x_align_left = is_rtl ? kEndPadding : entry_rect.width() - kEndPadding; 238 int x_align_left = is_rtl ? kEndPadding : entry_rect.width() - kEndPadding;
249 239
250 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 240 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
251 241
252 // Draw the delete icon, if one is needed. 242 // Draw the delete icon, if one is needed.
253 if (controller_->CanDelete(controller_->autofill_unique_ids()[index])) { 243 if (controller_->CanDelete(index)) {
254 x_align_left += is_rtl ? 0 : -kDeleteIconWidth; 244 x_align_left += is_rtl ? 0 : -kDeleteIconWidth;
255 245
256 gfx::Image delete_icon; 246 gfx::Image delete_icon;
257 if (static_cast<int>(index) == controller_->selected_line() && 247 if (static_cast<int>(index) == controller_->selected_line() &&
258 controller_->delete_icon_hovered()) { 248 controller_->delete_icon_hovered()) {
259 delete_icon = rb.GetImageNamed(IDR_CLOSE_BAR_H); 249 delete_icon = rb.GetImageNamed(IDR_CLOSE_BAR_H);
260 } else { 250 } else {
261 delete_icon = rb.GetImageNamed(IDR_CLOSE_BAR); 251 delete_icon = rb.GetImageNamed(IDR_CLOSE_BAR);
262 } 252 }
263 253
264 // TODO(csharp): Create a custom resource for the delete icon. 254 // TODO(csharp): Create a custom resource for the delete icon.
265 // http://crbug.com/131801 255 // http://crbug.com/131801
266 cairo_save(cairo_context); 256 cairo_save(cairo_context);
267 gtk_util::DrawFullImage( 257 gtk_util::DrawFullImage(
268 cairo_context, 258 cairo_context,
269 window_, 259 window_,
270 delete_icon, 260 delete_icon,
271 x_align_left, 261 x_align_left,
272 entry_rect.y() + 262 entry_rect.y() +
273 ((row_height - kDeleteIconHeight) / 2)); 263 ((row_height - kDeleteIconHeight) / 2));
274 cairo_restore(cairo_context); 264 cairo_restore(cairo_context);
275 cairo_save(cairo_context); 265 cairo_save(cairo_context);
276 266
277 x_align_left += is_rtl ? kDeleteIconWidth + kIconPadding : -kIconPadding; 267 x_align_left += is_rtl ? kDeleteIconWidth + kIconPadding : -kIconPadding;
278 } 268 }
279 269
280 // Draw the Autofill icon, if one exists 270 // Draw the Autofill icon, if one exists
281 if (!controller_->autofill_icons()[index].empty()) { 271 if (!controller_->icons()[index].empty()) {
282 int icon = 272 int icon = controller_->GetIconResourceID(controller_->icons()[index]);
283 controller_->GetIconResourceID(controller_->autofill_icons()[index]);
284 DCHECK_NE(-1, icon); 273 DCHECK_NE(-1, icon);
285 int icon_y = entry_rect.y() + (row_height - kAutofillIconHeight) / 2; 274 int icon_y = entry_rect.y() + (row_height - kAutofillIconHeight) / 2;
286 275
287 x_align_left += is_rtl ? 0 : -kAutofillIconWidth; 276 x_align_left += is_rtl ? 0 : -kAutofillIconWidth;
288 277
289 cairo_save(cairo_context); 278 cairo_save(cairo_context);
290 gtk_util::DrawFullImage(cairo_context, 279 gtk_util::DrawFullImage(cairo_context,
291 window_, 280 window_,
292 rb.GetImageNamed(icon), 281 rb.GetImageNamed(icon),
293 x_align_left, 282 x_align_left,
294 icon_y); 283 icon_y);
295 cairo_restore(cairo_context); 284 cairo_restore(cairo_context);
296 285
297 x_align_left += is_rtl ? kAutofillIconWidth + kIconPadding : -kIconPadding; 286 x_align_left += is_rtl ? kAutofillIconWidth + kIconPadding : -kIconPadding;
298 } 287 }
299 288
300 // Draw the label text. 289 // Draw the label text.
301 SetLayoutText(controller_->autofill_labels()[index], 290 SetLayoutText(controller_->sub_labels()[index],
302 controller_->label_font(), 291 controller_->sub_label_font(),
303 kLabelTextColor); 292 kLabelTextColor);
304 if (!is_rtl) { 293 if (!is_rtl) {
305 x_align_left -= controller_->label_font().GetStringWidth( 294 x_align_left -= controller_->sub_label_font().GetStringWidth(
306 controller_->autofill_labels()[index]); 295 controller_->sub_labels()[index]);
307 } 296 }
308 297
309 // Center the text within the line. 298 // Center the text within the line.
310 int label_content_y = std::max( 299 int label_content_y = std::max(
311 entry_rect.y(), 300 entry_rect.y(),
312 entry_rect.y() + 301 entry_rect.y() +
313 (row_height - controller_->label_font().GetHeight()) / 2); 302 (row_height - controller_->sub_label_font().GetHeight()) / 2);
314 303
315 cairo_save(cairo_context); 304 cairo_save(cairo_context);
316 cairo_move_to(cairo_context, x_align_left, label_content_y); 305 cairo_move_to(cairo_context, x_align_left, label_content_y);
317 pango_cairo_show_layout(cairo_context, layout_); 306 pango_cairo_show_layout(cairo_context, layout_);
318 cairo_restore(cairo_context); 307 cairo_restore(cairo_context);
319 } 308 }
320 309
321 void AutofillPopupViewGtk::SetInitialBounds() { 310 void AutofillPopupViewGtk::SetInitialBounds() {
322 GdkScreen* screen = 311 GdkScreen* screen =
323 gtk_widget_get_screen(GTK_WIDGET(controller_->container_view())); 312 gtk_widget_get_screen(GTK_WIDGET(controller_->container_view()));
(...skipping 22 matching lines...) Expand all
346 x + controller_->element_bounds().x(), 335 x + controller_->element_bounds().x(),
347 top_of_popup, 336 top_of_popup,
348 controller_->GetPopupRequiredWidth(), 337 controller_->GetPopupRequiredWidth(),
349 popup_height)); 338 popup_height));
350 } 339 }
351 340
352 AutofillPopupView* AutofillPopupView::Create( 341 AutofillPopupView* AutofillPopupView::Create(
353 AutofillPopupController* controller) { 342 AutofillPopupController* controller) {
354 return new AutofillPopupViewGtk(controller); 343 return new AutofillPopupViewGtk(controller);
355 } 344 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698