summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcsharp@chromium.org <csharp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-15 14:55:33 +0000
committercsharp@chromium.org <csharp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-15 14:55:33 +0000
commit723be5d0ebfe0e1b3c0974f6b61078701c5c14c3 (patch)
tree311ac9f92afb893493739ad3678249d579e9a9e1
parent6c45ea836ab965ca5993128af9e8e71b86527d27 (diff)
downloadchromium_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.cc1
-rw-r--r--chrome/browser/autofill/autofill_external_delegate.h5
-rw-r--r--chrome/browser/autofill/autofill_external_delegate_gtk.cc2
-rw-r--r--chrome/browser/autofill/autofill_popup_view.cc27
-rw-r--r--chrome/browser/autofill/autofill_popup_view.h4
-rw-r--r--chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.cc75
-rw-r--r--chrome/browser/ui/gtk/autofill/autofill_popup_view_gtk.h8
-rw-r--r--chrome/browser/ui/gtk/gtk_util.cc12
-rw-r--r--chrome/browser/ui/gtk/gtk_util.h11
-rw-r--r--chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.cc26
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);
}
}