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

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: 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
« no previous file with comments | « chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.h ('k') | chrome/chrome_browser.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 "base/logging.h" 7 #include "base/logging.h"
8 #include "base/utf_string_conversions.h"
9 #include "ui/gfx/rect.h"
10 #include "ui/gfx/native_widget_types.h"
11 #include "ui/base/gtk/gtk_hig_constants.h"
8 #include "ui/base/gtk/gtk_windowing.h" 12 #include "ui/base/gtk/gtk_windowing.h"
13 #include "ui/gfx/font.h"
14
15 namespace {
16 const GdkColor kTextColor = GDK_COLOR_RGB(0x00, 0x00, 0x00);
17 const int kMiddlePadding = 10;
18
19 gfx::Rect GetWindowRect(GdkWindow* window) {
20 gint width, height;
21 gdk_drawable_get_size(GDK_DRAWABLE(window), &width, &height);
22 return gfx::Rect(width, height);
23 }
24
25 gfx::Rect GetRectForLine(size_t line, int width, int height) {
26 return gfx::Rect(0, (line * height), width, height);
27 }
28
29 void SetTextToDraw(PangoLayout* layout,
30 const string16& text) {
31 // Pango is really easy to overflow and send into a computational death
32 // spiral that can corrupt the screen. Assume that we'll never have more than
33 // 2000 characters, which should be a safe assumption until we all get robot
34 // eyes. http://crbug.com/66576
35 std::string text_utf8 = UTF16ToUTF8(text);
36 if (text_utf8.length() > 2000)
37 text_utf8 = text_utf8.substr(0, 2000);
38
39 pango_layout_set_text(layout, text_utf8.data(), text_utf8.length());
40 }
41
42 } // namespace
9 43
10 AutofillPopupViewGtk::AutofillPopupViewGtk(content::WebContents* web_contents, 44 AutofillPopupViewGtk::AutofillPopupViewGtk(content::WebContents* web_contents,
11 GtkWidget* parent) 45 GtkWidget* parent)
12 : AutofillPopupView(web_contents), 46 : AutofillPopupView(web_contents),
13 parent_(parent), 47 parent_(parent),
14 window_(gtk_window_new(GTK_WINDOW_POPUP)) { 48 window_(gtk_window_new(GTK_WINDOW_POPUP)) {
15 CHECK(parent != NULL); 49 CHECK(parent != NULL);
16 gtk_window_set_resizable(GTK_WINDOW(window_), FALSE); 50 gtk_window_set_resizable(GTK_WINDOW(window_), FALSE);
17 gtk_widget_set_app_paintable(window_, TRUE); 51 gtk_widget_set_app_paintable(window_, TRUE);
18 gtk_widget_set_double_buffered(window_, TRUE); 52 gtk_widget_set_double_buffered(window_, TRUE);
19 53
20 // Setup the window to ensure it recieves the expose event. 54 // Setup the window to ensure it recieves the expose event.
21 gtk_widget_add_events(window_, GDK_EXPOSURE_MASK); 55 gtk_widget_add_events(window_, GDK_EXPOSURE_MASK);
22 g_signal_connect(window_, "expose-event", 56 g_signal_connect(window_, "expose-event",
23 G_CALLBACK(HandleExposeThunk), this); 57 G_CALLBACK(HandleExposeThunk), this);
58
59 // Cache the layout so we don't have to create it for every expose.
60 layout_ = gtk_widget_create_pango_layout(window_, NULL);
61
62 row_height_ = font_.GetHeight();
24 } 63 }
25 64
26 AutofillPopupViewGtk::~AutofillPopupViewGtk() { 65 AutofillPopupViewGtk::~AutofillPopupViewGtk() {
66 g_object_unref(layout_);
27 gtk_widget_destroy(window_); 67 gtk_widget_destroy(window_);
28 } 68 }
29 69
30 void AutofillPopupViewGtk::Hide() { 70 void AutofillPopupViewGtk::Hide() {
31 gtk_widget_hide(window_); 71 gtk_widget_hide(window_);
32 } 72 }
33 73
34 // TODO(csharp): Actually show the values. 74 void AutofillPopupViewGtk::ShowInternal(
35 void AutofillPopupViewGtk::Show(const std::vector<string16>& autofill_values, 75 const std::vector<string16>& autofill_values,
36 const std::vector<string16>& autofill_labels, 76 const std::vector<string16>& autofill_labels,
37 const std::vector<string16>& autofill_icons, 77 const std::vector<string16>& autofill_icons) {
38 const std::vector<int>& autofill_unique_ids,
39 int separator_index) {
40 gint origin_x, origin_y; 78 gint origin_x, origin_y;
41 gdk_window_get_origin(gtk_widget_get_window(parent_), &origin_x, &origin_y); 79 gdk_window_get_origin(gtk_widget_get_window(parent_), &origin_x, &origin_y);
42 80
81 // Move the popup to appear right below the text field it is using.
43 gtk_window_move(GTK_WINDOW(window_), 82 gtk_window_move(GTK_WINDOW(window_),
44 origin_x + element_bounds().x(), 83 origin_x + element_bounds().x(),
45 origin_y + element_bounds().y() + element_bounds().height()); 84 origin_y + element_bounds().y() + element_bounds().height());
46 85
86 // Find out the maximum bounds required by the popup.
87 // TODO(csharp): Once the icon is also displayed it will affect the required
88 // size so it will need to be include in the calculation.
89 int popup_required_width = element_bounds().width();
90 CHECK_EQ(autofill_values.size(), autofill_labels.size());
91 for (size_t i = 0; i < autofill_values.size(); ++i) {
92 popup_required_width = std::max(popup_required_width,
93 font_.GetStringWidth(autofill_values[i]) +
94 kMiddlePadding +
95 font_.GetStringWidth(autofill_labels[i]));
96 }
97
47 gtk_widget_set_size_request( 98 gtk_widget_set_size_request(
48 window_, 99 window_,
49 element_bounds().width(), 100 popup_required_width,
50 element_bounds().height() * autofill_values.size()); 101 row_height_ * autofill_values.size());
51 102
52 gtk_widget_show(window_); 103 gtk_widget_show(window_);
53 104
54 GtkWidget* toplevel = gtk_widget_get_toplevel(parent_); 105 GtkWidget* toplevel = gtk_widget_get_toplevel(parent_);
55 CHECK(gtk_widget_is_toplevel(toplevel)); 106 CHECK(gtk_widget_is_toplevel(toplevel));
56 ui::StackPopupWindow(window_, toplevel); 107 ui::StackPopupWindow(window_, toplevel);
57 } 108 }
58 109
59 gboolean AutofillPopupViewGtk::HandleExpose(GtkWidget* widget, 110 gboolean AutofillPopupViewGtk::HandleExpose(GtkWidget* widget,
60 GdkEventExpose* event) { 111 GdkEventExpose* event) {
112 gfx::Rect window_rect = GetWindowRect(event->window);
113 gfx::Rect damage_rect = gfx::Rect(event->area);
114
115 GdkDrawable* drawable = GDK_DRAWABLE(event->window);
116 GdkGC* gc = gdk_gc_new(drawable);
Elliot Glaysher 2012/01/11 19:01:47 Please don't use GdkGC or other deprecated stuff.
csharp 2012/01/11 22:40:04 Sorry about that, I grab the code in early Decembe
117
118 SetupLayout(window_rect, &kTextColor);
119
120 for (size_t i = 0; i < autofill_values().size(); ++i) {
121 gfx::Rect line_rect = GetRectForLine(i, window_rect.width(), row_height_);
122 // Only repaint and layout damaged lines.
123 if (!line_rect.Intersects(damage_rect))
124 continue;
125
126 if (separator_index() == static_cast<int>(i)) {
127 int line_y = i * row_height_;
128 gdk_draw_line(drawable, gc, 0, line_y, window_rect.width(), line_y);
129 }
130
131 // Draw the autofill value.
132 SetTextToDraw(layout_, autofill_values()[i]);
133 gdk_draw_layout(drawable, gc, 0, line_rect.y(), layout_);
134
135 // Draw the autofill label.
136 int x_align_left = window_rect.width()
137 - font_.GetStringWidth(autofill_labels()[i]);
138 SetTextToDraw(layout_, autofill_labels()[i]);
139 gdk_draw_layout(drawable, gc, x_align_left, line_rect.y(), layout_);
140 }
141
142 g_object_unref(gc);
143
61 return TRUE; 144 return TRUE;
62 } 145 }
146
147 void AutofillPopupViewGtk::SetupLayout(const gfx::Rect& window_rect,
148 const GdkColor* text_color) {
149 int allocated_content_width = window_rect.width();
150 pango_layout_set_width(layout_, allocated_content_width * PANGO_SCALE);
151 pango_layout_set_height(layout_, row_height_ * PANGO_SCALE);
152
153 PangoAttrList* attrs = pango_attr_list_new();
154
155 PangoAttribute* fg_attr = pango_attr_foreground_new(text_color->red,
156 text_color->green,
157 text_color->blue);
158 pango_attr_list_insert(attrs, fg_attr); // Ownership taken.
159
160
161 pango_layout_set_attributes(layout_, attrs); // Ref taken.
162 pango_attr_list_unref(attrs);
163 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698