summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-30 22:16:33 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-30 22:16:33 +0000
commit6dce30b06f8f099a7e2a753126dab23f0c02c874 (patch)
tree7a42079c12f906ceaaa54606b2ad209944409869
parent00d272fd44bc771e0d35de57a0deae6f8fc78296 (diff)
downloadchromium_src-6dce30b06f8f099a7e2a753126dab23f0c02c874.zip
chromium_src-6dce30b06f8f099a7e2a753126dab23f0c02c874.tar.gz
chromium_src-6dce30b06f8f099a7e2a753126dab23f0c02c874.tar.bz2
GTK: Implement popup favicon menu.
BUG=18181 Review URL: http://codereview.chromium.org/244029 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27666 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/gtk/browser_titlebar.cc148
-rw-r--r--chrome/browser/gtk/browser_titlebar.h10
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.cc30
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.h1
-rw-r--r--chrome/browser/gtk/standard_menus.cc27
-rw-r--r--chrome/browser/gtk/standard_menus.h7
6 files changed, 154 insertions, 69 deletions
diff --git a/chrome/browser/gtk/browser_titlebar.cc b/chrome/browser/gtk/browser_titlebar.cc
index 705b4f1..a78954d 100644
--- a/chrome/browser/gtk/browser_titlebar.cc
+++ b/chrome/browser/gtk/browser_titlebar.cc
@@ -16,6 +16,7 @@
#include "base/gfx/gtk_util.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/browser.h"
+#include "chrome/browser/encoding_menu_controller.h"
#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/gtk/custom_button.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
@@ -121,6 +122,59 @@ GdkColor PickLuminosityContrastingColor(const GdkColor* base,
return *one;
}
+MenuCreateMaterial g_favicon_menu[] = {
+ { MENU_NORMAL, IDC_BACK, IDS_CONTENT_CONTEXT_BACK, 0, NULL,
+ GDK_Left, GDK_MOD1_MASK, true },
+ { MENU_NORMAL, IDC_FORWARD, IDS_CONTENT_CONTEXT_FORWARD, 0, NULL,
+ GDK_Right, GDK_MOD1_MASK, true },
+ { MENU_NORMAL, IDC_RELOAD, IDS_APP_MENU_RELOAD, 0, NULL,
+ GDK_R, GDK_CONTROL_MASK, true },
+ { MENU_SEPARATOR },
+ { MENU_NORMAL, IDC_RESTORE_TAB, IDS_APP_MENU_RELOAD, 0, NULL,
+ GDK_T, GDK_CONTROL_MASK | GDK_SHIFT_MASK, true },
+ { MENU_NORMAL, IDC_DUPLICATE_TAB, IDS_APP_MENU_DUPLICATE_APP_WINDOW },
+ { MENU_NORMAL, IDC_COPY_URL, IDS_APP_MENU_COPY_URL },
+ { MENU_NORMAL, IDC_SHOW_AS_TAB, IDS_SHOW_AS_TAB },
+ { MENU_NORMAL, IDC_NEW_TAB, IDS_APP_MENU_NEW_WEB_PAGE, 0, NULL,
+ GDK_T, GDK_CONTROL_MASK },
+};
+
+const MenuCreateMaterial* GetFaviconMenu(Profile* profile,
+ MenuGtk::Delegate* delegate) {
+ static bool favicon_menu_built = false;
+ static MenuCreateMaterial* favicon_menu;
+ if (!favicon_menu_built) {
+ const MenuCreateMaterial* standard_page =
+ GetStandardPageMenu(profile, delegate);
+ int standard_page_menu_length = 1;
+ // Don't include the Create App Shortcut menu item.
+ int start_offset = 0;
+ for (int i = 0; standard_page[i].type != MENU_END; ++i) {
+ if (standard_page[i].id == IDC_CREATE_SHORTCUTS) {
+ // Pass the separator as well.
+ start_offset = i + 2;
+ ++i;
+ continue;
+ } else if (start_offset == 0) {
+ // The Create App Shortcut menu item is the first menu item, and if that
+ // ever changes we'll probably have to re-evaluate this code.
+ NOTREACHED();
+ continue;
+ }
+
+ standard_page_menu_length++;
+ }
+ favicon_menu = new MenuCreateMaterial[arraysize(g_favicon_menu) +
+ standard_page_menu_length];
+ memcpy(favicon_menu, g_favicon_menu,
+ arraysize(g_favicon_menu) * sizeof(MenuCreateMaterial));
+ memcpy(favicon_menu + arraysize(g_favicon_menu),
+ standard_page + start_offset,
+ (standard_page_menu_length) * sizeof(MenuCreateMaterial));
+ }
+ return favicon_menu;
+}
+
} // namespace
BrowserTitlebar::BrowserTitlebar(BrowserWindowGtk* browser_window,
@@ -209,14 +263,20 @@ void BrowserTitlebar::Init() {
gtk_box_pack_start(GTK_BOX(app_mode_hbox),
browser_window_->tabstrip()->widget(), FALSE, FALSE, 0);
+ GtkWidget* favicon_event_box = gtk_event_box_new();
+ gtk_event_box_set_visible_window(GTK_EVENT_BOX(favicon_event_box), FALSE);
+ g_signal_connect(favicon_event_box, "button-press-event",
+ G_CALLBACK(OnButtonPressed), this);
+ gtk_box_pack_start(GTK_BOX(app_mode_hbox), favicon_event_box, FALSE,
+ FALSE, 0);
// We use the app logo as a placeholder image so the title doesn't jump
// around.
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- // TODO(tc): Add a left click menu to this icon.
app_mode_favicon_ = gtk_image_new_from_pixbuf(
rb.GetRTLEnabledPixbufNamed(IDR_PRODUCT_LOGO_16));
- gtk_box_pack_start(GTK_BOX(app_mode_hbox), app_mode_favicon_, FALSE,
- FALSE, 0);
+ g_object_set_data(G_OBJECT(app_mode_favicon_), "left-align-popup",
+ reinterpret_cast<void*>(true));
+ gtk_container_add(GTK_CONTAINER(favicon_event_box), app_mode_favicon_);
app_mode_title_ = gtk_label_new(NULL);
gtk_label_set_ellipsize(GTK_LABEL(app_mode_title_), PANGO_ELLIPSIZE_END);
@@ -434,6 +494,15 @@ void BrowserTitlebar::UpdateTextColor() {
}
}
+void BrowserTitlebar::ShowFaviconMenu(GdkEventButton* event) {
+ if (!favicon_menu_.get()) {
+ favicon_menu_.reset(new MenuGtk(this,
+ GetFaviconMenu(browser_window_->browser()->profile(), this), NULL));
+ }
+
+ favicon_menu_->Popup(app_mode_favicon_, reinterpret_cast<GdkEvent*>(event));
+}
+
// static
gboolean BrowserTitlebar::OnWindowStateChanged(GtkWindow* window,
GdkEventWindowState* event, BrowserTitlebar* titlebar) {
@@ -480,6 +549,17 @@ void BrowserTitlebar::OnButtonClicked(GtkWidget* button,
}
}
+// static
+gboolean BrowserTitlebar::OnButtonPressed(GtkWidget* widget,
+ GdkEventButton* event,
+ BrowserTitlebar* titlebar) {
+ if (event->button != 1)
+ return FALSE;
+
+ titlebar->ShowFaviconMenu(event);
+ return TRUE;
+}
+
void BrowserTitlebar::ShowContextMenu() {
if (!context_menu_.get()) {
static const MenuCreateMaterial context_menu_blueprint[] = {
@@ -505,48 +585,44 @@ void BrowserTitlebar::ShowContextMenu() {
}
bool BrowserTitlebar::IsCommandEnabled(int command_id) const {
- switch (command_id) {
- case IDC_NEW_TAB:
- case kShowWindowDecorationsCommand:
- return true;
+ if (command_id == kShowWindowDecorationsCommand)
+ return true;
- case IDC_RESTORE_TAB:
- return browser_window_->browser()->CanRestoreTab();
+ return browser_window_->browser()->command_updater()->
+ IsCommandEnabled(command_id);
+}
- case IDC_TASK_MANAGER:
- return true;
+bool BrowserTitlebar::IsItemChecked(int command_id) const {
+ if (command_id == kShowWindowDecorationsCommand) {
+ PrefService* prefs = browser_window_->browser()->profile()->GetPrefs();
+ return !prefs->GetBoolean(prefs::kUseCustomChromeFrame);
+ }
- default:
- NOTREACHED();
+ EncodingMenuController controller;
+ if (controller.DoesCommandBelongToEncodingMenu(command_id)) {
+ TabContents* tab_contents =
+ browser_window_->browser()->GetSelectedTabContents();
+ if (tab_contents) {
+ return controller.IsItemChecked(browser_window_->browser()->profile(),
+ tab_contents->encoding(),
+ command_id);
+ }
+ return false;
}
- return false;
-}
-bool BrowserTitlebar::IsItemChecked(int command_id) const {
- DCHECK(command_id == kShowWindowDecorationsCommand);
- PrefService* prefs = browser_window_->browser()->profile()->GetPrefs();
- return !prefs->GetBoolean(prefs::kUseCustomChromeFrame);
+ NOTREACHED();
+ return false;
}
void BrowserTitlebar::ExecuteCommand(int command_id) {
- switch (command_id) {
- case IDC_NEW_TAB:
- case IDC_RESTORE_TAB:
- case IDC_TASK_MANAGER:
- browser_window_->browser()->ExecuteCommand(command_id);
- break;
-
- case kShowWindowDecorationsCommand:
- {
- PrefService* prefs = browser_window_->browser()->profile()->GetPrefs();
- prefs->SetBoolean(prefs::kUseCustomChromeFrame,
- !prefs->GetBoolean(prefs::kUseCustomChromeFrame));
- break;
- }
-
- default:
- NOTREACHED();
+ if (command_id == kShowWindowDecorationsCommand) {
+ PrefService* prefs = browser_window_->browser()->profile()->GetPrefs();
+ prefs->SetBoolean(prefs::kUseCustomChromeFrame,
+ !prefs->GetBoolean(prefs::kUseCustomChromeFrame));
+ return;
}
+
+ browser_window_->browser()->ExecuteCommand(command_id);
}
void BrowserTitlebar::Observe(NotificationType type,
diff --git a/chrome/browser/gtk/browser_titlebar.h b/chrome/browser/gtk/browser_titlebar.h
index 84d9236..a9ace55 100644
--- a/chrome/browser/gtk/browser_titlebar.h
+++ b/chrome/browser/gtk/browser_titlebar.h
@@ -95,6 +95,9 @@ class BrowserTitlebar : public MenuGtk::Delegate,
// change in the window.
void UpdateTextColor();
+ // Show the menu that the user gets from left-clicking the favicon.
+ void ShowFaviconMenu(GdkEventButton* event);
+
// Callback for changes to window state. This includes
// maximizing/restoring/minimizing the window.
static gboolean OnWindowStateChanged(GtkWindow* window,
@@ -108,6 +111,10 @@ class BrowserTitlebar : public MenuGtk::Delegate,
// Callback for min/max/close buttons.
static void OnButtonClicked(GtkWidget* button, BrowserTitlebar* window);
+ // Callback for favicon.
+ static gboolean OnButtonPressed(GtkWidget* widget, GdkEventButton* event,
+ BrowserTitlebar* titlebar);
+
// -- Context Menu -----------------------------------------------------------
// MenuGtk::Delegate implementation:
@@ -166,6 +173,9 @@ class BrowserTitlebar : public MenuGtk::Delegate,
// The context menu.
scoped_ptr<MenuGtk> context_menu_;
+ // The favicon menu.
+ scoped_ptr<MenuGtk> favicon_menu_;
+
// The throbber used when the window is in app mode or popup window mode.
Throbber throbber_;
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc
index 0a0aad3..ce1984e 100644
--- a/chrome/browser/gtk/browser_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_toolbar_gtk.cc
@@ -103,33 +103,6 @@ BrowserToolbarGtk::~BrowserToolbarGtk() {
g_object_unref(accel_group_);
}
-// Construct an "encodings" menu based on profile settings.
-static MenuGtk* BuildEncodingsMenu(Profile* profile,
- MenuGtk::Delegate* delegate) {
- EncodingMenuController controller;
- EncodingMenuController::EncodingMenuItemList items;
- controller.GetEncodingMenuItems(profile, &items);
-
- MenuGtk* menu = new MenuGtk(delegate, false);
- GSList* radio_group = NULL;
- for (EncodingMenuController::EncodingMenuItemList::const_iterator i =
- items.begin();
- i != items.end(); ++i) {
- if (i == items.begin()) {
- menu->AppendCheckMenuItemWithLabel(i->first, UTF16ToUTF8(i->second));
- } else if (i->first == 0) {
- menu->AppendSeparator();
- } else {
- GtkWidget* item =
- gtk_radio_menu_item_new_with_label(radio_group,
- UTF16ToUTF8(i->second).c_str());
- radio_group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item));
- menu->AppendMenuItem(i->first, item);
- }
- }
- return menu;
-}
-
void BrowserToolbarGtk::Init(Profile* profile,
GtkWindow* top_level_window) {
// Make sure to tell the location bar the profile before calling its Init.
@@ -222,8 +195,7 @@ void BrowserToolbarGtk::Init(Profile* profile,
theme_provider_->GetRTLEnabledPixbufNamed(IDR_MENU_PAGE));
gtk_container_add(GTK_CONTAINER(page_menu), page_menu_image_);
- encodings_menu_.reset(BuildEncodingsMenu(profile, this));
- page_menu_.reset(new MenuGtk(this, GetStandardPageMenu(encodings_menu_.get()),
+ page_menu_.reset(new MenuGtk(this, GetStandardPageMenu(profile_, this),
accel_group_));
gtk_box_pack_start(GTK_BOX(menus_hbox_), page_menu, FALSE, FALSE, 0);
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.h b/chrome/browser/gtk/browser_toolbar_gtk.h
index 74b2a48..b2f0590 100644
--- a/chrome/browser/gtk/browser_toolbar_gtk.h
+++ b/chrome/browser/gtk/browser_toolbar_gtk.h
@@ -189,7 +189,6 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
scoped_ptr<MenuGtk> page_menu_;
scoped_ptr<MenuGtk> app_menu_;
- scoped_ptr<MenuGtk> encodings_menu_;
Browser* browser_;
BrowserWindowGtk* window_;
diff --git a/chrome/browser/gtk/standard_menus.cc b/chrome/browser/gtk/standard_menus.cc
index 64e4309..c798fbbb 100644
--- a/chrome/browser/gtk/standard_menus.cc
+++ b/chrome/browser/gtk/standard_menus.cc
@@ -12,6 +12,7 @@
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/encoding_menu_controller.h"
+#include "chrome/browser/profile.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
@@ -107,7 +108,31 @@ struct MenuCreateMaterial standard_app_menu_materials[] = {
} // namespace
-const MenuCreateMaterial* GetStandardPageMenu(MenuGtk* encodings_menu) {
+const MenuCreateMaterial* GetStandardPageMenu(Profile* profile,
+ MenuGtk::Delegate* delegate) {
+ EncodingMenuController controller;
+ EncodingMenuController::EncodingMenuItemList items;
+ controller.GetEncodingMenuItems(profile, &items);
+
+ MenuGtk* encodings_menu = new MenuGtk(delegate, false);
+ GSList* radio_group = NULL;
+ for (EncodingMenuController::EncodingMenuItemList::const_iterator i =
+ items.begin();
+ i != items.end(); ++i) {
+ if (i == items.begin()) {
+ encodings_menu->AppendCheckMenuItemWithLabel(i->first,
+ UTF16ToUTF8(i->second));
+ } else if (i->first == 0) {
+ encodings_menu->AppendSeparator();
+ } else {
+ GtkWidget* item =
+ gtk_radio_menu_item_new_with_label(radio_group,
+ UTF16ToUTF8(i->second).c_str());
+ radio_group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item));
+ encodings_menu->AppendMenuItem(i->first, item);
+ }
+ }
+
// Find the encoding menu and attach this menu.
for (MenuCreateMaterial* entry = standard_page_menu_materials;
entry->type != MENU_END; ++entry) {
diff --git a/chrome/browser/gtk/standard_menus.h b/chrome/browser/gtk/standard_menus.h
index c9298c3..15c3734 100644
--- a/chrome/browser/gtk/standard_menus.h
+++ b/chrome/browser/gtk/standard_menus.h
@@ -5,8 +5,9 @@
#ifndef CHROME_BROWSER_GTK_STANDARD_MENUS_H_
#define CHROME_BROWSER_GTK_STANDARD_MENUS_H_
+#include "chrome/browser/gtk/menu_gtk.h"
+
class Menu;
-class MenuGtk;
class Profile;
enum MenuItemType {
@@ -54,7 +55,9 @@ struct MenuCreateMaterial {
};
// Returns the menu construction data structure for the page menu.
-const MenuCreateMaterial* GetStandardPageMenu(MenuGtk* encodings_menu);
+// The parameters are used to construct the encodings menu.
+const MenuCreateMaterial* GetStandardPageMenu(Profile* profile,
+ MenuGtk::Delegate* delegate);
// Returns the menu construction data structure for the app menu.
const MenuCreateMaterial* GetStandardAppMenu();