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 93a347e551124cc2ecce1637279d72ac71a0fe0d..8103781cc793900b8cb7591cb6918ee4bddb1f3f 100644 |
--- a/chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.cc |
+++ b/chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.cc |
@@ -6,6 +6,7 @@ |
#include "base/logging.h" |
#include "base/utf_string_conversions.h" |
+#include "chrome/browser/autofill/autofill_external_delegate.h" |
#include "chrome/browser/ui/gtk/gtk_util.h" |
#include "ui/base/gtk/gtk_compat.h" |
#include "ui/base/gtk/gtk_hig_constants.h" |
@@ -15,6 +16,7 @@ |
namespace { |
const GdkColor kBorderColor = GDK_COLOR_RGB(0xc7, 0xca, 0xce); |
+const GdkColor kHoveredBackgroundColor = GDK_COLOR_RGB(0x0CD, 0xCD, 0xCD); |
const GdkColor kTextColor = GDK_COLOR_RGB(0x00, 0x00, 0x00); |
// The amount of minimum padding between the Autofill value and label in pixels. |
@@ -35,9 +37,11 @@ gfx::Rect GetRectForRow(size_t index, int width, int height) { |
} // namespace |
-AutofillPopupViewGtk::AutofillPopupViewGtk(content::WebContents* web_contents, |
- GtkWidget* parent) |
- : AutofillPopupView(web_contents), |
+AutofillPopupViewGtk::AutofillPopupViewGtk( |
+ content::WebContents* web_contents, |
+ AutofillExternalDelegate* external_delegate, |
+ GtkWidget* parent) |
+ : AutofillPopupView(web_contents, external_delegate), |
parent_(parent), |
window_(gtk_window_new(GTK_WINDOW_POPUP)) { |
CHECK(parent != NULL); |
@@ -45,11 +49,19 @@ AutofillPopupViewGtk::AutofillPopupViewGtk(content::WebContents* web_contents, |
gtk_widget_set_app_paintable(window_, TRUE); |
gtk_widget_set_double_buffered(window_, TRUE); |
- // Setup the window to ensure it recieves the expose event. |
- gtk_widget_add_events(window_, GDK_EXPOSURE_MASK); |
+ // Setup the window to ensure it receives the expose event. |
+ gtk_widget_add_events(window_, GDK_BUTTON_MOTION_MASK | |
+ GDK_BUTTON_RELEASE_MASK | |
+ GDK_EXPOSURE_MASK | |
+ GDK_POINTER_MOTION_MASK); |
g_signal_connect(window_, "expose-event", |
G_CALLBACK(HandleExposeThunk), this); |
+ g_signal_connect(window_, "motion-notify-event", |
+ G_CALLBACK(HandleMotionThunk), this); |
+ g_signal_connect(window_, "button-release-event", |
+ G_CALLBACK(HandleButtonReleaseThunk), this); |
+ |
// Cache the layout so we don't have to create it for every expose. |
layout_ = gtk_widget_create_pango_layout(window_, NULL); |
@@ -61,19 +73,7 @@ AutofillPopupViewGtk::~AutofillPopupViewGtk() { |
gtk_widget_destroy(window_); |
} |
-void AutofillPopupViewGtk::Hide() { |
- gtk_widget_hide(window_); |
-} |
- |
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 included in the calculation. |
@@ -86,6 +86,18 @@ void AutofillPopupViewGtk::ShowInternal() { |
font_.GetStringWidth(autofill_labels()[i])); |
} |
+ 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. |
+ bounds_.SetRect( |
+ origin_x + element_bounds().x(), |
+ origin_y + element_bounds().y() + element_bounds().height(), |
+ popup_width, |
+ row_height_ * autofill_values().size()); |
+ |
+ gtk_window_move(GTK_WINDOW(window_), bounds_.x(), bounds_.y()); |
+ |
gtk_widget_set_size_request( |
window_, |
popup_width, |
@@ -98,6 +110,29 @@ void AutofillPopupViewGtk::ShowInternal() { |
ui::StackPopupWindow(window_, toplevel); |
} |
+void AutofillPopupViewGtk::HideInternal() { |
+ gtk_widget_hide(window_); |
+} |
+ |
+void AutofillPopupViewGtk::InvalidateRow(size_t row) { |
+ GdkRectangle row_rect = GetRectForRow( |
+ row, bounds_.width(), row_height_).ToGdkRectangle(); |
+ gdk_window_invalidate_rect(window_->window, &row_rect, FALSE); |
+} |
+ |
+gboolean AutofillPopupViewGtk::HandleButtonRelease(GtkWidget* widget, |
Ilya Sherman
2012/02/04 04:10:52
nit: Is there a GTK-specific reason why this funct
csharp
2012/02/07 22:30:58
I've changed it to ignore other clicks. I noticed
Ilya Sherman
2012/02/07 23:35:55
I think the new UI should behave like a system-nat
Elliot Glaysher
2012/02/07 23:44:09
Yes. The return value specifies whether other sign
|
+ GdkEventButton* event) { |
+ size_t line = LineFromY(event->y); |
Ilya Sherman
2012/02/04 04:10:52
nit: DCHECK_LT(line, autofill_values.size());
Ilya Sherman
2012/02/04 04:10:52
nit: Any reason not to move this work into the bod
csharp
2012/02/07 22:30:58
Done.
|
+ |
+ if (event->button == 1) // Left click. |
Ilya Sherman
2012/02/04 04:10:52
nit: Since the body wraps to multiple lines, pleas
csharp
2012/02/07 22:30:58
Done.
|
+ external_delegate()->didAcceptAutofillSuggestions( |
+ autofill_values()[line], |
+ autofill_unique_ids()[line], |
+ line); |
+ |
+ return TRUE; |
+} |
+ |
gboolean AutofillPopupViewGtk::HandleExpose(GtkWidget* widget, |
GdkEventExpose* event) { |
gfx::Rect window_rect = GetWindowRect(event->window); |
@@ -139,6 +174,13 @@ gboolean AutofillPopupViewGtk::HandleExpose(GtkWidget* widget, |
cairo_restore(cr); |
} |
+ if (selected_line() == static_cast<int>(i)) { |
+ gdk_cairo_set_source_color(cr, &kHoveredBackgroundColor); |
+ cairo_rectangle(cr, line_rect.x(), line_rect.y(), |
+ line_rect.width(), line_rect.height()); |
+ cairo_fill(cr); |
+ } |
+ |
// Center the text within the line. |
int content_y = std::max( |
line_rect.y(), |
@@ -168,6 +210,15 @@ gboolean AutofillPopupViewGtk::HandleExpose(GtkWidget* widget, |
return TRUE; |
} |
+gboolean AutofillPopupViewGtk::HandleMotion(GtkWidget* widget, |
+ GdkEventMotion* event) { |
+ int line = LineFromY(event->y); |
+ |
+ SetSelectedLine(line); |
+ |
+ return TRUE; |
+} |
+ |
void AutofillPopupViewGtk::SetupLayout(const gfx::Rect& window_rect, |
const GdkColor& text_color) { |
int allocated_content_width = window_rect.width(); |
@@ -185,3 +236,7 @@ void AutofillPopupViewGtk::SetupLayout(const gfx::Rect& window_rect, |
pango_layout_set_attributes(layout_, attrs); // Ref taken. |
pango_attr_list_unref(attrs); |
} |
+ |
+int AutofillPopupViewGtk::LineFromY(int y) { |
+ return y / row_height_; |
+} |