diff options
author | csharp@chromium.org <csharp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-15 14:55:33 +0000 |
---|---|---|
committer | csharp@chromium.org <csharp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-15 14:55:33 +0000 |
commit | 723be5d0ebfe0e1b3c0974f6b61078701c5c14c3 (patch) | |
tree | 311ac9f92afb893493739ad3678249d579e9a9e1 | |
parent | 6c45ea836ab965ca5993128af9e8e71b86527d27 (diff) | |
download | chromium_src-723be5d0ebfe0e1b3c0974f6b61078701c5c14c3.zip chromium_src-723be5d0ebfe0e1b3c0974f6b61078701c5c14c3.tar.gz chromium_src-723be5d0ebfe0e1b3c0974f6b61078701c5c14c3.tar.bz2 |
Add Icon Support for New Autofill Gtk UI
Show credit card icons for the new Autofill Gtk popup.
BUG=51644
TEST=
Review URL: https://chromiumcodereview.appspot.com/10396003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@137126 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/autofill/autofill_external_delegate.cc | 1 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_external_delegate.h | 5 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_external_delegate_gtk.cc | 2 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_popup_view.cc | 27 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_popup_view.h | 4 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.cc | 75 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.h | 8 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/gtk_util.cc | 12 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/gtk_util.h | 11 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.cc | 26 |
10 files changed, 129 insertions, 42 deletions
diff --git a/chrome/browser/autofill/autofill_external_delegate.cc b/chrome/browser/autofill/autofill_external_delegate.cc index 3420018..a675a29 100644 --- a/chrome/browser/autofill/autofill_external_delegate.cc +++ b/chrome/browser/autofill/autofill_external_delegate.cc @@ -6,7 +6,6 @@ #include "chrome/browser/autocomplete_history_manager.h" #include "chrome/browser/autofill/autofill_external_delegate.h" #include "chrome/browser/autofill/autofill_manager.h" -#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/common/autofill_messages.h" #include "chrome/common/chrome_constants.h" #include "content/public/browser/render_view_host.h" diff --git a/chrome/browser/autofill/autofill_external_delegate.h b/chrome/browser/autofill/autofill_external_delegate.h index 803485d8..652f9ee 100644 --- a/chrome/browser/autofill/autofill_external_delegate.h +++ b/chrome/browser/autofill/autofill_external_delegate.h @@ -11,12 +11,12 @@ #include "base/compiler_specific.h" #include "base/string16.h" #include "chrome/browser/autofill/password_autofill_manager.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "webkit/forms/form_data.h" #include "webkit/forms/form_field.h" #include "webkit/forms/password_form_dom_manager.h" class AutofillManager; -class TabContentsWrapper; namespace gfx { class Rect; @@ -125,6 +125,9 @@ class AutofillExternalDelegate { // Set the bounds of the Autofill element being worked with. virtual void SetBounds(const gfx::Rect& bounds) = 0; + // Return the profile that this autofill delegate is currently working with. + Profile* profile() { return tab_contents_wrapper_->profile(); } + private: // Fills the form with the Autofill data corresponding to |unique_id|. // If |is_preview| is true then this is just a preview to show the user what diff --git a/chrome/browser/autofill/autofill_external_delegate_gtk.cc b/chrome/browser/autofill/autofill_external_delegate_gtk.cc index 89d2107..bbb3f00 100644 --- a/chrome/browser/autofill/autofill_external_delegate_gtk.cc +++ b/chrome/browser/autofill/autofill_external_delegate_gtk.cc @@ -5,6 +5,7 @@ #include "chrome/browser/autofill/autofill_external_delegate_gtk.h" #include "chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.h" +#include "chrome/browser/ui/gtk/gtk_theme_service.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_view.h" @@ -69,6 +70,7 @@ void AutofillExternalDelegateGtk::CreateViewIfNeeded() { return; view_.reset(new AutofillPopupViewGtk(web_contents_, + GtkThemeService::GetFrom(profile()), this, tab_native_view_)); diff --git a/chrome/browser/autofill/autofill_popup_view.cc b/chrome/browser/autofill/autofill_popup_view.cc index 7f3d5ea..0a146f5 100644 --- a/chrome/browser/autofill/autofill_popup_view.cc +++ b/chrome/browser/autofill/autofill_popup_view.cc @@ -5,12 +5,14 @@ #include "chrome/browser/autofill/autofill_popup_view.h" #include "base/logging.h" +#include "base/utf_string_conversions.h" #include "chrome/browser/autofill/autofill_external_delegate.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" #include "content/public/browser/notification_types.h" +#include "grit/webkit_resources.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebAutofillClient.h" using WebKit::WebAutofillClient; @@ -20,6 +22,22 @@ namespace { // Used to indicate that no line is currently selected by the user. const int kNoSelection = -1; +struct DataResource { + const char* name; + int id; +}; + +const DataResource kDataResources[] = { + { "americanExpressCC", IDR_AUTOFILL_CC_AMEX }, + { "dinersCC", IDR_AUTOFILL_CC_DINERS }, + { "discoverCC", IDR_AUTOFILL_CC_DISCOVER }, + { "genericCC", IDR_AUTOFILL_CC_GENERIC }, + { "jcbCC", IDR_AUTOFILL_CC_JCB }, + { "masterCardCC", IDR_AUTOFILL_CC_MASTERCARD }, + { "soloCC", IDR_AUTOFILL_CC_SOLO }, + { "visaCC", IDR_AUTOFILL_CC_VISA }, +}; + } // end namespace AutofillPopupView::AutofillPopupView( @@ -151,6 +169,15 @@ bool AutofillPopupView::IsSeparatorIndex(int index) { autofill_unique_ids_[index] < 0); } +int AutofillPopupView::GetIconResourceID(const string16& resource_name) { + for (size_t i = 0; i < arraysize(kDataResources); ++i) { + if (resource_name == ASCIIToUTF16(kDataResources[i].name)) + return kDataResources[i].id; + } + + return -1; +} + bool AutofillPopupView::CanDelete(int id) { return id > 0 || id == WebAutofillClient::MenuItemIDAutocompleteEntry || diff --git a/chrome/browser/autofill/autofill_popup_view.h b/chrome/browser/autofill/autofill_popup_view.h index 7d1771d..4fac024 100644 --- a/chrome/browser/autofill/autofill_popup_view.h +++ b/chrome/browser/autofill/autofill_popup_view.h @@ -92,6 +92,10 @@ class AutofillPopupView : public content::NotificationObserver { // have a separator above it. bool IsSeparatorIndex(int index); + // Get the resource value for the given resource, returning -1 if the + // resource isn't recognized. + int GetIconResourceID(const string16& resource_name); + private: // Returns true if the given id refers to an element that can be deleted. bool CanDelete(int id); 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 017bef0..c9192fc 100644 --- a/chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.cc +++ b/chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.cc @@ -10,6 +10,7 @@ #include "base/utf_string_conversions.h" #include "chrome/browser/autofill/autofill_external_delegate.h" #include "chrome/browser/ui/gtk/gtk_util.h" +#include "chrome/browser/ui/gtk/gtk_theme_service.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "ui/base/gtk/gtk_compat.h" @@ -23,31 +24,45 @@ 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 vertical height of each row in pixels. +const int kRowHeight = 24; + // The amount of minimum padding between the Autofill value and label in pixels. const int kMiddlePadding = 10; +// The amount of padding between the label and icon or edge and icon in pixels. +const int kIconPadding = 5; + // We have a 1 pixel border around the entire results popup. const int kBorderThickness = 1; +// Width of the icons in pixels. +const int kIconWidth = 25; + +// Height of the icons in pixels. +const int kIconHeight = 16; + 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); +gfx::Rect GetRectForRow(size_t index, int width) { + return gfx::Rect(0, (index * kRowHeight), width, kRowHeight); } } // namespace AutofillPopupViewGtk::AutofillPopupViewGtk( content::WebContents* web_contents, + GtkThemeService* theme_service, AutofillExternalDelegate* external_delegate, GtkWidget* parent) : AutofillPopupView(web_contents, external_delegate), parent_(parent), window_(gtk_window_new(GTK_WINDOW_POPUP)), + theme_service_(theme_service), render_view_host_(web_contents->GetRenderViewHost()) { CHECK(parent != NULL); gtk_window_set_resizable(GTK_WINDOW(window_), FALSE); @@ -69,8 +84,6 @@ AutofillPopupViewGtk::AutofillPopupViewGtk( // 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() { @@ -100,8 +113,7 @@ void AutofillPopupViewGtk::HideInternal() { } void AutofillPopupViewGtk::InvalidateRow(size_t row) { - GdkRectangle row_rect = GetRectForRow( - row, bounds_.width(), row_height_).ToGdkRectangle(); + GdkRectangle row_rect = GetRectForRow(row, bounds_.width()).ToGdkRectangle(); GdkWindow* gdk_window = gtk_widget_get_window(window_); gdk_window_invalidate_rect(gdk_window, &row_rect, FALSE); } @@ -110,7 +122,7 @@ void AutofillPopupViewGtk::ResizePopup() { gtk_widget_set_size_request( window_, GetPopupRequiredWidth(), - row_height_ * autofill_values().size()); + kRowHeight * autofill_values().size()); } gboolean AutofillPopupViewGtk::HandleButtonRelease(GtkWidget* widget, @@ -152,13 +164,13 @@ gboolean AutofillPopupViewGtk::HandleExpose(GtkWidget* widget, 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_); + gfx::Rect line_rect = GetRectForRow(i, window_rect.width()); // Only repaint and layout damaged lines. if (!line_rect.Intersects(damage_rect)) continue; if (IsSeparatorIndex(i)) { - int line_y = i * row_height_; + int line_y = i * kRowHeight; cairo_save(cr); cairo_move_to(cr, 0, line_y); @@ -177,7 +189,7 @@ gboolean AutofillPopupViewGtk::HandleExpose(GtkWidget* widget, // Center the text within the line. int content_y = std::max( line_rect.y(), - line_rect.y() + ((row_height_ - actual_content_height) / 2)); + line_rect.y() + ((kRowHeight - actual_content_height) / 2)); // Draw the value. gtk_util::SetLayoutText(layout_, autofill_values()[i]); @@ -190,12 +202,32 @@ gboolean AutofillPopupViewGtk::HandleExpose(GtkWidget* widget, // Draw the label. int x_align_left = window_rect.width() - font_.GetStringWidth(autofill_labels()[i]); + + if (!autofill_icons()[i].empty()) + x_align_left -= 2 * kIconPadding + kIconWidth; + gtk_util::SetLayoutText(layout_, autofill_labels()[i]); cairo_save(cr); - cairo_move_to(cr, x_align_left, line_rect.y()); + cairo_move_to(cr, x_align_left, content_y); pango_cairo_show_layout(cr, layout_); cairo_restore(cr); + + // Draw the icon, if one exists + if (!autofill_icons()[i].empty()) { + int icon = GetIconResourceID(autofill_icons()[i]); + DCHECK_NE(-1, icon); + int icon_y = line_rect.y() + ((kRowHeight - kIconHeight) / 2); + + cairo_save(cr); + gtk_util::DrawFullImage(cr, + window_, + theme_service_->GetImageNamed(icon), + window_rect.width() - + (kIconPadding + kIconWidth), + icon_y); + cairo_restore(cr); + } } cairo_destroy(cr); @@ -247,7 +279,7 @@ 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); + pango_layout_set_height(layout_, kRowHeight * PANGO_SCALE); PangoAttrList* attrs = pango_attr_list_new(); @@ -270,7 +302,7 @@ void AutofillPopupViewGtk::SetBounds() { int bottom_of_field = origin_y + element_bounds().y() + element_bounds().height(); - int popup_size = row_height_ * autofill_values().size(); + int popup_size = kRowHeight * autofill_values().size(); // Find the correct top position of the popup so that is doesn't go off // the screen. @@ -291,20 +323,23 @@ void AutofillPopupViewGtk::SetBounds() { } int AutofillPopupViewGtk::GetPopupRequiredWidth() { - // TODO(csharp): Once the icon is also displayed it will affect the required - // size so it will need to be included in the calculation. 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])); + int row_size = font_.GetStringWidth(autofill_values()[i]) + + kMiddlePadding + + font_.GetStringWidth(autofill_labels()[i]); + + // Add the icon size if required. + if (!autofill_icons()[i].empty()) + row_size += kIconWidth + 2 * kIconPadding; + + popup_width = std::max(popup_width, row_size); } return popup_width; } int AutofillPopupViewGtk::LineFromY(int y) { - return y / row_height_; + return y / kRowHeight; } diff --git a/chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.h b/chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.h index 2d0997f..4c13983 100644 --- a/chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.h +++ b/chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.h @@ -14,6 +14,9 @@ #include "ui/base/gtk/gtk_signal.h" #include "ui/gfx/font.h" +class GtkThemeService; +class Profile; + namespace content { class RenderViewHost; } @@ -33,6 +36,7 @@ class AutofillPopupViewGtk : public AutofillPopupView, public KeyboardListener { public: AutofillPopupViewGtk(content::WebContents* web_contents, + GtkThemeService* theme_service, AutofillExternalDelegate* external_delegate, GtkWidget* parent); virtual ~AutofillPopupViewGtk(); @@ -71,9 +75,7 @@ class AutofillPopupViewGtk : public AutofillPopupView, GtkWidget* window_; // Strong reference. PangoLayout* layout_; // Strong reference gfx::Font font_; - - // The height of each individual Autofill popup row. - int row_height_; + GtkThemeService* theme_service_; // The size of the popup. gfx::Rect bounds_; diff --git a/chrome/browser/ui/gtk/gtk_util.cc b/chrome/browser/ui/gtk/gtk_util.cc index b26399a..826c3e3b 100644 --- a/chrome/browser/ui/gtk/gtk_util.cc +++ b/chrome/browser/ui/gtk/gtk_util.cc @@ -879,6 +879,18 @@ void DrawThemedToolbarBackground(GtkWidget* widget, cairo_fill(cr); } +void DrawFullImage(cairo_t* cr, + GtkWidget* widget, + const gfx::Image* image, + gint dest_x, + gint dest_y) { + gfx::CairoCachedSurface* surface = image->ToCairo(); + surface->SetSource(cr, widget, dest_x, dest_y); + cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); + cairo_rectangle(cr, dest_x, dest_y, surface->Width(), surface->Height()); + cairo_fill(cr); +} + GdkColor AverageColors(GdkColor color_one, GdkColor color_two) { GdkColor average_color; average_color.pixel = 0; diff --git a/chrome/browser/ui/gtk/gtk_util.h b/chrome/browser/ui/gtk/gtk_util.h index 317c5c29..c37d990 100644 --- a/chrome/browser/ui/gtk/gtk_util.h +++ b/chrome/browser/ui/gtk/gtk_util.h @@ -29,6 +29,10 @@ namespace content { struct RendererPreferences; } +namespace gfx { +class Image; +} + namespace event_utils { // Translates GdkEvent state into what kind of disposition they represent. @@ -223,6 +227,13 @@ void DrawThemedToolbarBackground(GtkWidget* widget, const gfx::Point& tabstrip_origin, GtkThemeService* provider); +// Draw an entire pixbuf without dithering. +void DrawFullImage(cairo_t* cr, + GtkWidget* widget, + const gfx::Image* image, + gint dest_x, + gint dest_y); + // Returns the two colors averaged together. GdkColor AverageColors(GdkColor color_one, GdkColor color_two); diff --git a/chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.cc b/chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.cc index 0c5a187..da99670 100644 --- a/chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.cc +++ b/chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.cc @@ -107,16 +107,6 @@ gfx::Rect GetRectForLine(size_t line, int width) { kHeightPerResult); } -// Helper for drawing an entire pixbuf without dithering. -void DrawFullImage(cairo_t* cr, GtkWidget* widget, const gfx::Image* image, - gint dest_x, gint dest_y) { - gfx::CairoCachedSurface* surface = image->ToCairo(); - surface->SetSource(cr, widget, dest_x, dest_y); - cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); - cairo_rectangle(cr, dest_x, dest_y, surface->Width(), surface->Height()); - cairo_fill(cr); -} - // TODO(deanm): Find some better home for this, and make it more efficient. size_t GetUTF8Offset(const string16& text, size_t text_offset) { return UTF16ToUTF8(text.substr(0, text_offset)).length(); @@ -662,9 +652,10 @@ gboolean OmniboxPopupViewGtk::HandleExpose(GtkWidget* widget, int icon_start_x = ltr ? kIconLeftPadding : (line_rect.width() - kIconLeftPadding - kIconWidth); // Draw the icon for this result. - DrawFullImage(cr, widget, - IconForMatch(*match, is_selected, is_selected_keyword), - icon_start_x, line_rect.y() + kIconTopPadding); + gtk_util::DrawFullImage(cr, widget, + IconForMatch(*match, is_selected, + is_selected_keyword), + icon_start_x, line_rect.y() + kIconTopPadding); // Draw the results text vertically centered in the results space. // First draw the contents / url, but don't let it take up the whole width @@ -738,10 +729,11 @@ gboolean OmniboxPopupViewGtk::HandleExpose(GtkWidget* widget, icon_start_x = ltr ? (line_rect.width() - kIconLeftPadding - kIconWidth) : kIconLeftPadding; // Draw the icon for this result. - DrawFullImage(cr, widget, - theme_service_->GetImageNamed( - is_selected ? IDR_OMNIBOX_TTS_DARK : IDR_OMNIBOX_TTS), - icon_start_x, line_rect.y() + kIconTopPadding); + gtk_util::DrawFullImage(cr, widget, + theme_service_->GetImageNamed( + is_selected ? IDR_OMNIBOX_TTS_DARK : + IDR_OMNIBOX_TTS), + icon_start_x, line_rect.y() + kIconTopPadding); } } |