diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-11 19:32:10 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-11 19:32:10 +0000 |
commit | cbc9ed60c4959214cbbcff09035534e29eaed0db (patch) | |
tree | 327956baa5e08edbd4c576cebf860d849740e329 /chrome | |
parent | 25396dab596e7e47262a8a9569c7570d72b1a5ea (diff) | |
download | chromium_src-cbc9ed60c4959214cbbcff09035534e29eaed0db.zip chromium_src-cbc9ed60c4959214cbbcff09035534e29eaed0db.tar.gz chromium_src-cbc9ed60c4959214cbbcff09035534e29eaed0db.tar.bz2 |
GTK: make browser actions container resizable.
TODO: persist the size of the browser actions container to the profile.
TODO: implement the overflow menu.
BUG=32101
TEST=manual
Review URL: http://codereview.chromium.org/800003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41305 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/extensions/extension_toolbar_model.h | 3 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_actions_toolbar_gtk.cc | 155 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_actions_toolbar_gtk.h | 69 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_gtk.cc | 4 | ||||
-rw-r--r-- | chrome/browser/gtk/gtk_chrome_shrinkable_hbox.cc | 14 | ||||
-rw-r--r-- | chrome/browser/gtk/gtk_chrome_shrinkable_hbox.h | 3 | ||||
-rw-r--r-- | chrome/browser/gtk/overflow_button.cc | 44 | ||||
-rw-r--r-- | chrome/browser/gtk/overflow_button.h | 37 | ||||
-rwxr-xr-x | chrome/chrome_browser.gypi | 2 |
9 files changed, 271 insertions, 60 deletions
diff --git a/chrome/browser/extensions/extension_toolbar_model.h b/chrome/browser/extensions/extension_toolbar_model.h index a4c7855..d930c86 100644 --- a/chrome/browser/extensions/extension_toolbar_model.h +++ b/chrome/browser/extensions/extension_toolbar_model.h @@ -37,6 +37,9 @@ class ExtensionToolbarModel : public NotificationObserver { void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); void MoveBrowserAction(Extension* extension, int index); + // TODO(estade): implement these. + void SetVisibleIconCount(int count) {} + int GetVisibleIconCount() { return -1; } size_t size() const { return toolitems_.size(); diff --git a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc index 78da006..a20a4921 100644 --- a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc +++ b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -13,11 +13,14 @@ #include "chrome/browser/extensions/extension_browser_event_router.h" #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/extensions/image_loading_tracker.h" +#include "chrome/browser/gtk/cairo_cached_surface.h" #include "chrome/browser/gtk/extension_popup_gtk.h" #include "chrome/browser/gtk/gtk_chrome_button.h" +#include "chrome/browser/gtk/gtk_chrome_shrinkable_hbox.h" #include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/browser/gtk/gtk_util.h" #include "chrome/browser/gtk/menu_gtk.h" +#include "chrome/browser/gtk/view_id_util.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/extensions/extension.h" @@ -26,6 +29,7 @@ #include "chrome/common/notification_service.h" #include "chrome/common/notification_source.h" #include "chrome/common/notification_type.h" +#include "grit/app_resources.h" namespace { @@ -48,6 +52,43 @@ GtkTargetEntry GetDragTargetEntry() { return drag_target; } +// The minimum width in pixels of the button hbox if |icon_count| icons are +// showing. +gint WidthForIconCount(gint icon_count) { + return (kButtonSize + kButtonPadding) * icon_count - kButtonPadding; +} + +// These three signal handlers are used to give the gripper the resize +// cursor. Since it doesn't have its own window, we have to set the cursor +// whenever the pointer moves into the button or leaves the button, and be +// sure to leave it on when the user is dragging. +gboolean OnGripperEnterNotify(GtkWidget* gripper, + GdkEventCrossing* event, + gpointer unused) { + gdk_window_set_cursor(gripper->window, + gtk_util::GetCursor(GDK_SB_H_DOUBLE_ARROW)); + return FALSE; +} + +gboolean OnGripperLeaveNotify(GtkWidget* gripper, + GdkEventCrossing* event, + gpointer unused) { + if (!(event->state & GDK_BUTTON1_MASK)) + gdk_window_set_cursor(gripper->window, NULL); + return FALSE; +} + +gboolean OnGripperButtonRelease(GtkWidget* gripper, + GdkEventButton* event, + gpointer unused) { + gfx::Rect gripper_rect(0, 0, + gripper->allocation.width, gripper->allocation.height); + gfx::Point release_point(event->x, event->y); + if (!gripper_rect.Contains(release_point)) + gdk_window_set_cursor(gripper->window, NULL); + return FALSE; +} + } // namespace class BrowserActionButton : public NotificationObserver, @@ -254,8 +295,11 @@ class BrowserActionButton : public NotificationObserver, BrowserActionsToolbarGtk::BrowserActionsToolbarGtk(Browser* browser) : browser_(browser), profile_(browser->profile()), + theme_provider_(GtkThemeProvider::GetFrom(browser->profile())), model_(NULL), - hbox_(gtk_hbox_new(FALSE, kButtonPadding)), + hbox_(gtk_hbox_new(FALSE, 0)), + button_hbox_(gtk_chrome_shrinkable_hbox_new(TRUE, FALSE, kButtonPadding)), + overflow_button_(browser->profile()), drag_button_(NULL), drop_index_(-1), method_factory_(this) { @@ -264,6 +308,25 @@ BrowserActionsToolbarGtk::BrowserActionsToolbarGtk(Browser* browser) if (!extension_service) return; + GtkWidget* gripper = gtk_button_new(); + GTK_WIDGET_UNSET_FLAGS(gripper, GTK_CAN_FOCUS); + gtk_widget_add_events(gripper, GDK_POINTER_MOTION_MASK); + g_signal_connect(gripper, "motion-notify-event", + G_CALLBACK(OnGripperMotionNotifyThunk), this); + g_signal_connect(gripper, "expose-event", + G_CALLBACK(OnGripperExposeThunk), this); + g_signal_connect(gripper, "enter-notify-event", + G_CALLBACK(OnGripperEnterNotify), NULL); + g_signal_connect(gripper, "leave-notify-event", + G_CALLBACK(OnGripperLeaveNotify), NULL); + g_signal_connect(gripper, "button-release-event", + G_CALLBACK(OnGripperButtonRelease), NULL); + + gtk_box_pack_start(GTK_BOX(hbox_.get()), gripper, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox_.get()), button_hbox_, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(hbox_.get()), overflow_button_.widget(), + FALSE, FALSE, 0); + model_ = extension_service->toolbar_model(); model_->AddObserver(this); SetupDrags(); @@ -273,6 +336,12 @@ BrowserActionsToolbarGtk::BrowserActionsToolbarGtk(Browser* browser) // until we are added to a toplevel window to do so. g_signal_connect(widget(), "hierarchy-changed", G_CALLBACK(OnHierarchyChangedThunk), this); + + int showing_actions = model_->GetVisibleIconCount(); + if (showing_actions >= 0) + SetButtonHBoxWidth(WidthForIconCount(showing_actions)); + + ViewIDUtil::SetID(button_hbox_, VIEW_ID_BROWSER_ACTION_TOOLBAR); } BrowserActionsToolbarGtk::~BrowserActionsToolbarGtk() { @@ -304,10 +373,10 @@ void BrowserActionsToolbarGtk::Update() { void BrowserActionsToolbarGtk::SetupDrags() { GtkTargetEntry drag_target = GetDragTargetEntry(); - gtk_drag_dest_set(widget(), GTK_DEST_DEFAULT_DROP, &drag_target, 1, + gtk_drag_dest_set(button_hbox_, GTK_DEST_DEFAULT_DROP, &drag_target, 1, GDK_ACTION_MOVE); - g_signal_connect(widget(), "drag-motion", + g_signal_connect(button_hbox_, "drag-motion", G_CALLBACK(OnDragMotionThunk), this); } @@ -332,8 +401,9 @@ void BrowserActionsToolbarGtk::CreateButtonForExtension(Extension* extension, RemoveButtonForExtension(extension); linked_ptr<BrowserActionButton> button( new BrowserActionButton(this, extension)); - gtk_box_pack_start(GTK_BOX(hbox_.get()), button->widget(), FALSE, FALSE, 0); - gtk_box_reorder_child(GTK_BOX(hbox_.get()), button->widget(), index); + gtk_chrome_shrinkable_hbox_pack_start( + GTK_CHROME_SHRINKABLE_HBOX(button_hbox_), button->widget(), 0); + gtk_box_reorder_child(GTK_BOX(button_hbox_), button->widget(), index); gtk_widget_show(button->widget()); extension_button_map_[extension->id()] = button; @@ -392,7 +462,7 @@ void BrowserActionsToolbarGtk::BrowserActionAdded(Extension* extension, void BrowserActionsToolbarGtk::BrowserActionRemoved(Extension* extension) { if (drag_button_ != NULL) { // Break the current drag. - gtk_grab_remove(widget()); + gtk_grab_remove(button_hbox_); } RemoveButtonForExtension(extension); @@ -414,7 +484,7 @@ void BrowserActionsToolbarGtk::BrowserActionMoved(Extension* extension, if (profile_->IsOffTheRecord()) index = model_->OriginalIndexToIncognito(index); - gtk_box_reorder_child(GTK_BOX(hbox_.get()), button->widget(), index); + gtk_box_reorder_child(GTK_BOX(button_hbox_), button->widget(), index); } void BrowserActionsToolbarGtk::DragStarted(BrowserActionButton* button, @@ -428,6 +498,34 @@ void BrowserActionsToolbarGtk::DragStarted(BrowserActionButton* button, drag_button_ = button; } +void BrowserActionsToolbarGtk::SetButtonHBoxWidth(int new_width) { + gint max_width = WidthForIconCount(model_->size()); + new_width = std::min(max_width, new_width); + new_width = std::max(new_width, 0); + gtk_widget_set_size_request(button_hbox_, new_width, -1); + + int showing_icon_count = + gtk_chrome_shrinkable_hbox_get_visible_child_count( + GTK_CHROME_SHRINKABLE_HBOX(button_hbox_)); + + model_->SetVisibleIconCount(showing_icon_count); + if (model_->size() > static_cast<size_t>(showing_icon_count)) { + if (!GTK_WIDGET_VISIBLE(overflow_button_.widget())) { + // When the overflow chevron shows for the first time, take that + // much space away from |button_hbox_| to make the drag look smoother. + GtkRequisition req; + gtk_widget_size_request(overflow_button_.widget(), &req); + new_width -= req.width; + new_width = std::max(new_width, 0); + gtk_widget_set_size_request(button_hbox_, new_width, -1); + + gtk_widget_show(overflow_button_.widget()); + } + } else { + gtk_widget_hide(overflow_button_.widget()); + } +} + gboolean BrowserActionsToolbarGtk::OnDragMotion(GtkWidget* widget, GdkDragContext* drag_context, gint x, gint y, guint time) { @@ -442,7 +540,7 @@ gboolean BrowserActionsToolbarGtk::OnDragMotion(GtkWidget* widget, // We will go ahead and reorder the child in order to provide visual feedback // to the user. We don't inform the model that it has moved until the drag // ends. - gtk_box_reorder_child(GTK_BOX(hbox_.get()), drag_button_->widget(), + gtk_box_reorder_child(GTK_BOX(button_hbox_), drag_button_->widget(), drop_index_); gdk_drag_status(drag_context, GDK_ACTION_MOVE, time); @@ -468,18 +566,51 @@ gboolean BrowserActionsToolbarGtk::OnDragFailed(GtkWidget* widget, return TRUE; } -void BrowserActionsToolbarGtk::OnHierarchyChanged() { - GtkWidget* toplevel = gtk_widget_get_toplevel(widget()); +void BrowserActionsToolbarGtk::OnHierarchyChanged(GtkWidget* widget, + GtkWidget* previous_toplevel) { + GtkWidget* toplevel = gtk_widget_get_toplevel(widget); if (!GTK_WIDGET_TOPLEVEL(toplevel)) return; g_signal_connect(toplevel, "set-focus", G_CALLBACK(OnSetFocusThunk), this); } -void BrowserActionsToolbarGtk::OnSetFocus() { +void BrowserActionsToolbarGtk::OnSetFocus(GtkWidget* widget, + GtkWidget* focus_widget) { // The focus of the parent window has changed. Close the popup. Delay the hide // because it will destroy the RenderViewHost, which may still be on the // call stack. + if (!ExtensionPopupGtk::get_current_extension_popup()) + return; MessageLoop::current()->PostTask(FROM_HERE, method_factory_.NewRunnableMethod(&BrowserActionsToolbarGtk::HidePopup)); } + +gboolean BrowserActionsToolbarGtk::OnGripperMotionNotify( + GtkWidget* widget, GdkEventMotion* event) { + if (!(event->state & GDK_BUTTON1_MASK)) + return FALSE; + + gint new_width = button_hbox_->allocation.width - + (event->x - widget->allocation.width); + SetButtonHBoxWidth(new_width); + + return FALSE; +} + +gboolean BrowserActionsToolbarGtk::OnGripperExpose(GtkWidget* gripper, + GdkEventExpose* expose) { + cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(expose->window)); + + CairoCachedSurface* surface = theme_provider_->GetSurfaceNamed( + IDR_RESIZE_GRIPPER, gripper); + gfx::Point center = gfx::Rect(gripper->allocation).CenterPoint(); + center.Offset(-surface->Width() / 2, -surface->Height() / 2); + surface->SetSource(cr, center.x(), center.y()); + gdk_cairo_rectangle(cr, &expose->area); + cairo_fill(cr); + + cairo_destroy(cr); + + return TRUE; +} diff --git a/chrome/browser/gtk/browser_actions_toolbar_gtk.h b/chrome/browser/gtk/browser_actions_toolbar_gtk.h index 024e81b..2e03897 100644 --- a/chrome/browser/gtk/browser_actions_toolbar_gtk.h +++ b/chrome/browser/gtk/browser_actions_toolbar_gtk.h @@ -13,13 +13,16 @@ #include "base/linked_ptr.h" #include "base/task.h" #include "chrome/browser/extensions/extension_toolbar_model.h" +#include "chrome/browser/gtk/overflow_button.h" #include "chrome/common/notification_observer.h" #include "chrome/common/notification_registrar.h" #include "chrome/common/owned_widget_gtk.h" +#include "chrome/common/gtk_signal.h" class Browser; class BrowserActionButton; class Extension; +class GtkThemeProvider; class Profile; typedef struct _GtkWidget GtkWidget; @@ -27,7 +30,7 @@ typedef struct _GtkWidget GtkWidget; class BrowserActionsToolbarGtk : public ExtensionToolbarModel::Observer { public: explicit BrowserActionsToolbarGtk(Browser* browser); - ~BrowserActionsToolbarGtk(); + virtual ~BrowserActionsToolbarGtk(); GtkWidget* widget() { return hbox_.get(); } @@ -83,55 +86,39 @@ class BrowserActionsToolbarGtk : public ExtensionToolbarModel::Observer { // Called by the BrowserActionButton in response to drag-begin. void DragStarted(BrowserActionButton* button, GdkDragContext* drag_context); - static gboolean OnDragMotionThunk(GtkWidget* widget, - GdkDragContext* drag_context, - gint x, gint y, guint time, - BrowserActionsToolbarGtk* toolbar) { - return toolbar->OnDragMotion(widget, drag_context, x, y, time); - } - gboolean OnDragMotion(GtkWidget* widget, - GdkDragContext* drag_context, - gint x, gint y, guint time); - - static void OnDragEndThunk(GtkWidget* button, - GdkDragContext* drag_context, - BrowserActionsToolbarGtk* toolbar) { - toolbar->OnDragEnd(button, drag_context); - } - void OnDragEnd(GtkWidget* button, GdkDragContext* drag_context); - - static gboolean OnDragFailedThunk(GtkWidget* widget, - GdkDragContext* drag_context, - GtkDragResult result, - BrowserActionsToolbarGtk* toolbar) { - return toolbar->OnDragFailed(widget, drag_context, result); - } - gboolean OnDragFailed(GtkWidget* widget, - GdkDragContext* drag_context, - GtkDragResult result); - - static void OnHierarchyChangedThunk(GtkWidget* widget, - GtkWidget* previous_toplevel, - BrowserActionsToolbarGtk* toolbar) { - toolbar->OnHierarchyChanged(); - } - void OnHierarchyChanged(); - - static void OnSetFocusThunk(GtkWindow* window, - GtkWidget* widget, - BrowserActionsToolbarGtk* toolbar) { - toolbar->OnSetFocus(); - } - void OnSetFocus(); + // Sets the width of the button area of the toolbar to |new_width|, clamping + // it to appropriate values and updating the model. + void SetButtonHBoxWidth(int new_width); + + CHROMEGTK_CALLBACK_4(BrowserActionsToolbarGtk, gboolean, OnDragMotion, + GdkDragContext*, gint, gint, guint); + CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, void, OnDragEnd, + GdkDragContext*); + CHROMEGTK_CALLBACK_2(BrowserActionsToolbarGtk, gboolean, OnDragFailed, + GdkDragContext*, GtkDragResult); + CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, void, OnHierarchyChanged, + GtkWidget*); + CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, void, OnSetFocus, GtkWidget*); + CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean, + OnGripperMotionNotify, GdkEventMotion*); + CHROMEGTK_CALLBACK_1(BrowserActionsToolbarGtk, gboolean, OnGripperExpose, + GdkEventExpose*); Browser* browser_; Profile* profile_; + GtkThemeProvider* theme_provider_; ExtensionToolbarModel* model_; + // Contains the drag gripper, browser action buttons, and overflow chevron. OwnedWidgetGtk hbox_; + // Contains the browser action buttons. + GtkWidget* button_hbox_; + + OverflowButton overflow_button_; + // The button that is currently being dragged, or NULL. BrowserActionButton* drag_button_; diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc index 8650770..7eed210 100644 --- a/chrome/browser/gtk/browser_toolbar_gtk.cc +++ b/chrome/browser/gtk/browser_toolbar_gtk.cc @@ -264,10 +264,6 @@ void BrowserToolbarGtk::SetViewIDs() { ViewIDUtil::SetID(go_->widget(), VIEW_ID_GO_BUTTON); ViewIDUtil::SetID(page_menu_button_.get(), VIEW_ID_PAGE_MENU); ViewIDUtil::SetID(app_menu_button_.get(), VIEW_ID_APP_MENU); - if (actions_toolbar_.get()) { - ViewIDUtil::SetID(actions_toolbar_->widget(), - VIEW_ID_BROWSER_ACTION_TOOLBAR); - } } void BrowserToolbarGtk::Show() { diff --git a/chrome/browser/gtk/gtk_chrome_shrinkable_hbox.cc b/chrome/browser/gtk/gtk_chrome_shrinkable_hbox.cc index b147f5f..0dccb7d 100644 --- a/chrome/browser/gtk/gtk_chrome_shrinkable_hbox.cc +++ b/chrome/browser/gtk/gtk_chrome_shrinkable_hbox.cc @@ -170,9 +170,9 @@ static void gtk_chrome_shrinkable_hbox_size_allocate( (GTK_WIDGET_CLASS(gtk_chrome_shrinkable_hbox_parent_class)->size_allocate) (widget, allocation); - int visible_children_count = 0; - gtk_container_foreach(GTK_CONTAINER(widget), CountVisibleChildren, - &visible_children_count); + gint visible_children_count = + gtk_chrome_shrinkable_hbox_get_visible_child_count( + GTK_CHROME_SHRINKABLE_HBOX(widget)); if (visible_children_count == 0) return; @@ -238,4 +238,12 @@ void gtk_chrome_shrinkable_hbox_pack_end(GtkChromeShrinkableHBox* box, gtk_box_pack_end(GTK_BOX(box), child, FALSE, FALSE, 0); } +gint gtk_chrome_shrinkable_hbox_get_visible_child_count( + GtkChromeShrinkableHBox* box) { + gint visible_children_count = 0; + gtk_container_foreach(GTK_CONTAINER(box), CountVisibleChildren, + &visible_children_count); + return visible_children_count; +} + G_END_DECLS diff --git a/chrome/browser/gtk/gtk_chrome_shrinkable_hbox.h b/chrome/browser/gtk/gtk_chrome_shrinkable_hbox.h index 75f9ed2..02be55d 100644 --- a/chrome/browser/gtk/gtk_chrome_shrinkable_hbox.h +++ b/chrome/browser/gtk/gtk_chrome_shrinkable_hbox.h @@ -75,6 +75,9 @@ void gtk_chrome_shrinkable_hbox_pack_end(GtkChromeShrinkableHBox* box, GtkWidget* child, guint padding); +gint gtk_chrome_shrinkable_hbox_get_visible_child_count( + GtkChromeShrinkableHBox* box); + G_END_DECLS #endif // CHROME_BROWSER_GTK_GTK_CHROME_SHRINKABLE_HBOX_H_ diff --git a/chrome/browser/gtk/overflow_button.cc b/chrome/browser/gtk/overflow_button.cc new file mode 100644 index 0000000..bd1e216 --- /dev/null +++ b/chrome/browser/gtk/overflow_button.cc @@ -0,0 +1,44 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/gtk/overflow_button.h" + +#include <gtk/gtk.h> + +#include "app/resource_bundle.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/gtk/gtk_theme_provider.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_type.h" +#include "grit/theme_resources.h" + +OverflowButton::OverflowButton(Profile* profile) : profile_(profile) { + widget_.Own(GtkThemeProvider::GetFrom(profile)->BuildChromeButton()); + gtk_widget_set_no_show_all(widget_.get(), TRUE); + + registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, + NotificationService::AllSources()); + GtkThemeProvider::GetFrom(profile)->InitThemesFor(this); +} + +OverflowButton::~OverflowButton() { + widget_.Destroy(); +} + +void OverflowButton::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + GtkWidget* former_child = gtk_bin_get_child(GTK_BIN(widget())); + if (former_child) + gtk_widget_destroy(former_child); + + GtkWidget* new_child = + GtkThemeProvider::GetFrom(profile_)->UseGtkTheme() ? + gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE) : + gtk_image_new_from_pixbuf(ResourceBundle::GetSharedInstance(). + GetRTLEnabledPixbufNamed(IDR_BOOKMARK_BAR_CHEVRONS)); + + gtk_container_add(GTK_CONTAINER(widget()), new_child); + gtk_widget_show(new_child); +} diff --git a/chrome/browser/gtk/overflow_button.h b/chrome/browser/gtk/overflow_button.h new file mode 100644 index 0000000..5362e6b --- /dev/null +++ b/chrome/browser/gtk/overflow_button.h @@ -0,0 +1,37 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GTK_OVERFLOW_BUTTON_H_ +#define CHROME_BROWSER_GTK_OVERFLOW_BUTTON_H_ + +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" +#include "chrome/common/owned_widget_gtk.h" + +typedef struct _GtkWidget GtkWidget; +class Profile; + +// An overflow chevron button. The button itself is a plain gtk_chrome_button, +// and this class handles theming it. +class OverflowButton : public NotificationObserver { + public: + explicit OverflowButton(Profile* profile); + virtual ~OverflowButton(); + + GtkWidget* widget() { return widget_.get(); } + + private: + // NotificationObserver implementation. + void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + OwnedWidgetGtk widget_; + + Profile* profile_; + + NotificationRegistrar registrar_; +}; + +#endif // CHROME_BROWSER_GTK_OVERFLOW_BUTTON_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index ddf754b..08441c5 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1194,6 +1194,8 @@ 'browser/gtk/notifications/balloon_view_host_gtk.h', 'browser/gtk/notifications/notification_options_menu_model.cc', 'browser/gtk/notifications/notification_options_menu_model.h', + 'browser/gtk/overflow_button.cc', + 'browser/gtk/overflow_button.h', 'browser/gtk/options/advanced_contents_gtk.cc', 'browser/gtk/options/advanced_contents_gtk.h', 'browser/gtk/options/advanced_page_gtk.cc', |