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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.cc
diff --git a/chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.cc b/chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.cc
index 5df1bdcef9f1bea5ddab2ef80c96dbcaeed4318b..a6e12d758f491abb5f869dbd5695b15835c4a03d 100644
--- a/chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.cc
+++ b/chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.cc
@@ -5,7 +5,36 @@
#include "autofill_popup_view_gtk.h"
#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/ui/gtk/gtk_util.h"
+#include "ui/gfx/rect.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/base/gtk/gtk_compat.h"
+#include "ui/base/gtk/gtk_hig_constants.h"
#include "ui/base/gtk/gtk_windowing.h"
+#include "ui/gfx/font.h"
+
+namespace {
+const GdkColor kBorderColor = GDK_COLOR_RGB(0xc7, 0xca, 0xce);
+const GdkColor kTextColor = GDK_COLOR_RGB(0x00, 0x00, 0x00);
+
+// 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.
+const int kMiddlePadding = 10;
+
+// We have a 1 pixel border around the entire results popup.
+const int kBorderThickness = 1;
+
+gfx::Rect GetWindowRect(GdkWindow* window) {
+ return gfx::Rect(gdk_window_get_width(window),
+ gdk_window_get_height(window));
+}
+
+// Returns the rectangle containing the item at position |index| in the popup.
+gfx::Rect GetRectForRow(size_t index, int width, int height) {
+ return gfx::Rect(0, (index * height), width, height);
+}
+
+} // namespace
AutofillPopupViewGtk::AutofillPopupViewGtk(content::WebContents* web_contents,
GtkWidget* parent)
@@ -21,9 +50,15 @@ AutofillPopupViewGtk::AutofillPopupViewGtk(content::WebContents* web_contents,
gtk_widget_add_events(window_, GDK_EXPOSURE_MASK);
g_signal_connect(window_, "expose-event",
G_CALLBACK(HandleExposeThunk), this);
+
+ // Cache the layout so we don't have to create it for every expose.
+ layout_ = gtk_widget_create_pango_layout(window_, NULL);
+
+ row_height_ = font_.GetHeight();
}
AutofillPopupViewGtk::~AutofillPopupViewGtk() {
+ g_object_unref(layout_);
gtk_widget_destroy(window_);
}
@@ -31,23 +66,31 @@ void AutofillPopupViewGtk::Hide() {
gtk_widget_hide(window_);
}
-// TODO(csharp): Actually show the values.
-void AutofillPopupViewGtk::Show(const std::vector<string16>& autofill_values,
- const std::vector<string16>& autofill_labels,
- const std::vector<string16>& autofill_icons,
- const std::vector<int>& autofill_unique_ids,
- int separator_index) {
+void AutofillPopupViewGtk::ShowInternal() {
gint origin_x, origin_y;
gdk_window_get_origin(gtk_widget_get_window(parent_), &origin_x, &origin_y);
+ // Move the popup to appear right below the text field it is using.
gtk_window_move(GTK_WINDOW(window_),
origin_x + element_bounds().x(),
origin_y + element_bounds().y() + element_bounds().height());
+ // Find out the maximum bounds required by the popup.
+ // TODO(csharp): Once the icon is also displayed it will affect the required
+ // 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.
+ int popup_width = element_bounds().width();
+ DCHECK_EQ(autofill_values().size(), autofill_labels().size());
+ for (size_t i = 0; i < autofill_values().size(); ++i) {
+ popup_width = std::max(popup_width,
+ font_.GetStringWidth(autofill_values()[i]) +
+ kMiddlePadding +
+ font_.GetStringWidth(autofill_labels()[i]));
+ }
+
gtk_widget_set_size_request(
window_,
- element_bounds().width(),
- element_bounds().height() * autofill_values.size());
+ popup_width,
+ row_height_ * autofill_values().size());
gtk_widget_show(window_);
@@ -58,5 +101,88 @@ void AutofillPopupViewGtk::Show(const std::vector<string16>& autofill_values,
gboolean AutofillPopupViewGtk::HandleExpose(GtkWidget* widget,
GdkEventExpose* event) {
+ gfx::Rect window_rect = GetWindowRect(event->window);
+ gfx::Rect damage_rect = gfx::Rect(event->area);
+
+ cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(gtk_widget_get_window(widget)));
+ gdk_cairo_rectangle(cr, &event->area);
+ cairo_clip(cr);
+
+ // This assert is kinda ugly, but it would be more currently unneeded work
+ // to support painting a border that isn't 1 pixel thick. There is no point
+ // in writing that code now, and explode if that day ever comes.
+ COMPILE_ASSERT(kBorderThickness == 1, border_1px_implied);
+ // Draw the 1px border around the entire window.
+ gdk_cairo_set_source_color(cr, &kBorderColor);
+ cairo_rectangle(cr, 0, 0, window_rect.width(), window_rect.height());
+ cairo_stroke(cr);
+
+ SetupLayout(window_rect, kTextColor);
+
+ int actual_content_width, actual_content_height;
+ pango_layout_get_size(layout_, &actual_content_width, &actual_content_height);
+ actual_content_width /= PANGO_SCALE;
+ actual_content_height /= PANGO_SCALE;
+
+ for (size_t i = 0; i < autofill_values().size(); ++i) {
+ gfx::Rect line_rect = GetRectForRow(i, window_rect.width(), row_height_);
+ // Only repaint and layout damaged lines.
+ if (!line_rect.Intersects(damage_rect))
+ continue;
+
+ if (separator_index() == static_cast<int>(i)) {
+ int line_y = i * row_height_;
+
+ cairo_save(cr);
+ cairo_move_to(cr, 0, line_y);
+ cairo_line_to(cr, window_rect.width(), line_y);
+ cairo_stroke(cr);
+ cairo_restore(cr);
+ }
+
+ // Center the text within the line.
+ int content_y = std::max(
+ line_rect.y(),
+ line_rect.y() + ((row_height_ - actual_content_height) / 2));
+
+ // 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.
+ gtk_util::SetLayoutText(layout_, autofill_values()[i]);
+
+ cairo_save(cr);
+ cairo_move_to(cr, 0, content_y);
+ pango_cairo_show_layout(cr, layout_);
+ cairo_restore(cr);
+
+ // Draw the autofill label.
Ilya Sherman 2012/01/20 07:26:47 nit: Ditto
csharp 2012/01/20 16:20:44 Done.
+ int x_align_left = window_rect.width() -
+ font_.GetStringWidth(autofill_labels()[i]);
+ gtk_util::SetLayoutText(layout_, autofill_labels()[i]);
+
+ cairo_save(cr);
+ cairo_move_to(cr, x_align_left, line_rect.y());
+ pango_cairo_show_layout(cr, layout_);
+ cairo_restore(cr);
+ }
+
+ cairo_destroy(cr);
+
return TRUE;
}
+
+void AutofillPopupViewGtk::SetupLayout(const gfx::Rect& window_rect,
+ const GdkColor& text_color) {
+ int allocated_content_width = window_rect.width();
+ pango_layout_set_width(layout_, allocated_content_width * PANGO_SCALE);
+ pango_layout_set_height(layout_, row_height_ * PANGO_SCALE);
+
+ PangoAttrList* attrs = pango_attr_list_new();
+
+ PangoAttribute* fg_attr = pango_attr_foreground_new(text_color.red,
+ text_color.green,
+ text_color.blue);
+ pango_attr_list_insert(attrs, fg_attr); // Ownership taken.
+
+
+ pango_layout_set_attributes(layout_, attrs); // Ref taken.
+ pango_attr_list_unref(attrs);
+}

Powered by Google App Engine
This is Rietveld 408576698