Commit 23512f4b authored by estade@chromium.org's avatar estade@chromium.org

Give page/app menu native menu bar feel.

Allow keyboard and mouse navigation between the two while one is open.

BUG=none
TEST=the page and wrench menus feel like a native menubar

Review URL: http://codereview.chromium.org/155164

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20095 0039d316-1c4b-4281-b951-d872f2087c98
parent b45243c4
......@@ -154,6 +154,10 @@ void BrowserToolbarGtk::Init(Profile* profile,
l10n_util::GetStringUTF8(IDS_PAGEMENU_TOOLTIP),
&page_menu_button_);
page_menu_.reset(new MenuGtk(this, GetStandardPageMenu(), accel_group_));
g_signal_connect(page_menu_->widget(), "motion-notify-event",
G_CALLBACK(OnPageAppMenuMouseMotion), this);
g_signal_connect(page_menu_->widget(), "move-current",
G_CALLBACK(OnPageAppMenuMoveCurrent), this);
gtk_box_pack_start(GTK_BOX(menus_hbox_), page_menu, FALSE, FALSE, 0);
GtkWidget* chrome_menu = BuildToolbarMenuButton(IDR_MENU_CHROME,
......@@ -161,6 +165,10 @@ void BrowserToolbarGtk::Init(Profile* profile,
WideToUTF16(l10n_util::GetString(IDS_PRODUCT_NAME))),
&app_menu_button_);
app_menu_.reset(new MenuGtk(this, GetStandardAppMenu(), accel_group_));
g_signal_connect(app_menu_->widget(), "motion-notify-event",
G_CALLBACK(OnPageAppMenuMouseMotion), this);
g_signal_connect(app_menu_->widget(), "move-current",
G_CALLBACK(OnPageAppMenuMoveCurrent), this);
gtk_box_pack_start(GTK_BOX(menus_hbox_), chrome_menu, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(toolbar_), menus_hbox_, FALSE, FALSE, 0);
......@@ -377,6 +385,27 @@ void BrowserToolbarGtk::SetUpDragForHomeButton() {
G_CALLBACK(OnDragDataReceived), this);
}
void BrowserToolbarGtk::ChangeActiveMenu(GtkWidget* active_menu,
guint timestamp) {
MenuGtk* old_menu;
MenuGtk* new_menu;
GtkWidget* relevant_button;
if (active_menu == app_menu_->widget()) {
old_menu = app_menu_.get();
new_menu = page_menu_.get();
relevant_button = page_menu_button_.get();
} else {
old_menu = page_menu_.get();
new_menu = app_menu_.get();
relevant_button = app_menu_button_.get();
}
old_menu->Cancel();
gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(relevant_button),
GTK_STATE_ACTIVE);
new_menu->Popup(relevant_button, 0, timestamp);
}
// static
gboolean BrowserToolbarGtk::OnToolbarExpose(GtkWidget* widget,
GdkEventExpose* e,
......@@ -461,6 +490,40 @@ void BrowserToolbarGtk::OnDragDataReceived(GtkWidget* widget,
}
}
// static
gboolean BrowserToolbarGtk::OnPageAppMenuMouseMotion(GtkWidget* menu,
GdkEventMotion* event, BrowserToolbarGtk* toolbar) {
if (gtk_util::WidgetContainsCursor(menu == toolbar->app_menu_->widget() ?
toolbar->page_menu_button_.get() :
toolbar->app_menu_button_.get())) {
toolbar->ChangeActiveMenu(menu, event->time);
return TRUE;
}
return FALSE;
}
// static
void BrowserToolbarGtk::OnPageAppMenuMoveCurrent(GtkWidget* menu,
GtkMenuDirectionType dir, BrowserToolbarGtk* toolbar) {
GtkWidget* active_item = GTK_MENU_SHELL(menu)->active_menu_item;
switch (dir) {
case GTK_MENU_DIR_CHILD:
// The move is going to open a submenu; don't override default behavior.
if (active_item && gtk_menu_item_get_submenu(GTK_MENU_ITEM(active_item)))
break;
// Fall through.
case GTK_MENU_DIR_PARENT:
toolbar->ChangeActiveMenu(menu, gtk_get_current_event_time());
// This signal doesn't have a return value; we have to manually stop its
// propagation.
g_signal_stop_emission_by_name(menu, "move-current");
default:
break;
}
}
void BrowserToolbarGtk::InitNineBox() {
// TODO(estade): use |profile_|?
background_ninebox_.reset(new NineBox(
......
......@@ -109,6 +109,10 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
// Connect signals for dragging a url onto the home button.
void SetUpDragForHomeButton();
// Helper for the PageAppMenu event handlers. Pops down the currently active
// meun and pops up the other menu.
void ChangeActiveMenu(GtkWidget* active_menu, guint timestamp);
// Gtk callback for the "expose-event" signal.
static gboolean OnToolbarExpose(GtkWidget* widget, GdkEventExpose* e,
BrowserToolbarGtk* toolbar);
......@@ -133,6 +137,15 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
guint info, guint time,
BrowserToolbarGtk* toolbar);
// These event handlers are used to fake menu-bar behavior in the page and
// app menus.
static gboolean OnPageAppMenuMouseMotion(GtkWidget* widget,
GdkEventMotion* event,
BrowserToolbarGtk* toolbar);
static void OnPageAppMenuMoveCurrent(GtkWidget* widget,
GtkMenuDirectionType dir,
BrowserToolbarGtk* toolbar);
// Initialize the background NineBox.
void InitNineBox();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment