diff options
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/gtk/bookmark_bar_gtk.cc | 83 | ||||
-rw-r--r-- | chrome/browser/gtk/bookmark_bar_gtk.h | 21 |
2 files changed, 101 insertions, 3 deletions
diff --git a/chrome/browser/gtk/bookmark_bar_gtk.cc b/chrome/browser/gtk/bookmark_bar_gtk.cc index d2dc5eb..45cd4e0 100644 --- a/chrome/browser/gtk/bookmark_bar_gtk.cc +++ b/chrome/browser/gtk/bookmark_bar_gtk.cc @@ -184,11 +184,21 @@ void BookmarkBarGtk::Init(Profile* profile) { SetToolBarStyle(); gtk_widget_set_name(bookmark_toolbar_.get(), "chrome-bookmark-toolbar"); gtk_widget_set_app_paintable(bookmark_toolbar_.get(), TRUE); - g_signal_connect(G_OBJECT(bookmark_toolbar_.get()), "expose-event", + g_signal_connect(bookmark_toolbar_.get(), "expose-event", G_CALLBACK(&OnToolbarExpose), this); + g_signal_connect(bookmark_toolbar_.get(), "size-allocate", + G_CALLBACK(&OnToolbarSizeAllocate), this); gtk_box_pack_start(GTK_BOX(bookmark_hbox_), bookmark_toolbar_.get(), TRUE, TRUE, 0); + overflow_button_ = theme_provider_->BuildChromeButton(); + g_object_set_data(G_OBJECT(overflow_button_), "left-align-popup", + reinterpret_cast<void*>(true)); + SetOverflowButtonAppearance(); + ConnectFolderButtonEvents(overflow_button_); + gtk_box_pack_start(GTK_BOX(bookmark_hbox_), overflow_button_, + FALSE, FALSE, 0); + gtk_drag_dest_set(bookmark_toolbar_.get(), GTK_DEST_DEFAULT_DROP, NULL, 0, kDragAction); GtkDndUtil::SetDestTargetList(bookmark_toolbar_.get(), kDestTargetList); @@ -304,6 +314,7 @@ void BookmarkBarGtk::BookmarkNodeAdded(BookmarkModel* model, item, index); SetInstructionState(); + SetChevronState(); } void BookmarkBarGtk::BookmarkNodeRemoved(BookmarkModel* model, @@ -322,6 +333,7 @@ void BookmarkBarGtk::BookmarkNodeRemoved(BookmarkModel* model, to_remove); SetInstructionState(); + SetChevronState(); } void BookmarkBarGtk::BookmarkNodeChanged(BookmarkModel* model, @@ -337,6 +349,7 @@ void BookmarkBarGtk::BookmarkNodeChanged(BookmarkModel* model, GTK_TOOLBAR(bookmark_toolbar_.get()), index); GtkWidget* button = gtk_bin_get_child(GTK_BIN(item)); bookmark_utils::ConfigureButtonForNode(node, model, button, theme_provider_); + SetChevronState(); } void BookmarkBarGtk::BookmarkNodeFavIconLoaded(BookmarkModel* model, @@ -368,6 +381,7 @@ void BookmarkBarGtk::CreateAllBookmarkButtons() { model_, other_bookmarks_button_, theme_provider_); SetInstructionState(); + SetChevronState(); } void BookmarkBarGtk::SetInstructionState() { @@ -379,6 +393,19 @@ void BookmarkBarGtk::SetInstructionState() { } } +void BookmarkBarGtk::SetChevronState() { + int extra_space = 0; + + if (GTK_WIDGET_VISIBLE(overflow_button_)) + extra_space = overflow_button_->allocation.width; + + int overflow_idx = GetFirstHiddenBookmark(extra_space); + if (overflow_idx == -1) + gtk_widget_hide(overflow_button_); + else + gtk_widget_show_all(overflow_button_); +} + void BookmarkBarGtk::RemoveAllBookmarkButtons() { gtk_util::RemoveAllChildren(bookmark_toolbar_.get()); } @@ -391,6 +418,43 @@ int BookmarkBarGtk::GetBookmarkButtonCount() { return count; } +void BookmarkBarGtk::SetOverflowButtonAppearance() { + GtkWidget* former_child = gtk_bin_get_child(GTK_BIN(overflow_button_)); + if (former_child) + gtk_widget_destroy(former_child); + + GtkWidget* new_child = theme_provider_->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(overflow_button_), new_child); + SetChevronState(); +} + +int BookmarkBarGtk::GetFirstHiddenBookmark(int extra_space) { + int rv = 0; + bool overflow = false; + GList* toolbar_items = + gtk_container_get_children(GTK_CONTAINER(bookmark_toolbar_.get())); + for (GList* iter = toolbar_items; iter; iter = g_list_next(iter)) { + GtkWidget* tool_item = reinterpret_cast<GtkWidget*>(iter->data); + if (tool_item->allocation.x + tool_item->allocation.width > + bookmark_toolbar_.get()->allocation.width + extra_space) { + overflow = true; + break; + } + rv++; + } + + g_list_free(toolbar_items); + + if (!overflow) + return -1; + + return rv; +} + bool BookmarkBarGtk::IsAlwaysShown() { return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); } @@ -430,6 +494,8 @@ void BookmarkBarGtk::Observe(NotificationType type, // themes, we want to let the background show through the toolbar. gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box_.get()), theme_provider_->UseGtkTheme()); + + SetOverflowButtonAppearance(); } } @@ -504,7 +570,7 @@ const BookmarkNode* BookmarkBarGtk::GetNodeForToolButton(GtkWidget* widget) { // First check to see if |button| is special cased. if (widget == other_bookmarks_button_) return model_->other_node(); - else if (widget == event_box_.get()) + else if (widget == event_box_.get() || widget == overflow_button_) return model_->GetBookmarkBarNode(); // Search the contents of |bookmark_toolbar_| for the corresponding widget @@ -651,12 +717,16 @@ void BookmarkBarGtk::OnFolderClicked(GtkWidget* sender, DCHECK(node); DCHECK(bar->page_navigator_); + int start_child_idx = 0; + if (sender == bar->overflow_button_) + start_child_idx = bar->GetFirstHiddenBookmark(0); + bar->current_menu_.reset( new BookmarkMenuController(bar->browser_, bar->profile_, bar->page_navigator_, GTK_WINDOW(gtk_widget_get_toplevel(sender)), node, - 0, + start_child_idx, false)); GdkEventButton* event = reinterpret_cast<GdkEventButton*>(gtk_get_current_event()); @@ -740,6 +810,13 @@ void BookmarkBarGtk::OnToolbarDragLeave(GtkToolbar* toolbar, } // static +void BookmarkBarGtk::OnToolbarSizeAllocate(GtkWidget* widget, + GtkAllocation* allocation, + BookmarkBarGtk* bar) { + bar->SetChevronState(); +} + +// static void BookmarkBarGtk::OnDragReceived(GtkWidget* widget, GdkDragContext* context, gint x, gint y, diff --git a/chrome/browser/gtk/bookmark_bar_gtk.h b/chrome/browser/gtk/bookmark_bar_gtk.h index 0f44bf6..afc7e8a 100644 --- a/chrome/browser/gtk/bookmark_bar_gtk.h +++ b/chrome/browser/gtk/bookmark_bar_gtk.h @@ -84,6 +84,9 @@ class BookmarkBarGtk : public AnimationDelegate, // any bookmarks in the bookmark bar node. void SetInstructionState(); + // Sets the visibility of the overflow chevron. + void SetChevronState(); + // Helper function which destroys all the bookmark buttons in the GtkToolbar. void RemoveAllBookmarkButtons(); @@ -92,6 +95,17 @@ class BookmarkBarGtk : public AnimationDelegate, // bookmark bar model has. int GetBookmarkButtonCount(); + // Set the appearance of the overflow button appropriately (either chromium + // style or GTK style). + void SetOverflowButtonAppearance(); + + // Returns the index of the first bookmark that is not visible on the bar. + // Returns -1 if they are all visible. + // |extra_space| is how much extra space to give the toolbar during the + // calculation (for the purposes of determining if ditching the chevron + // would be a good idea). + int GetFirstHiddenBookmark(int extra_space); + // Overridden from BookmarkModelObserver: // Invoked when the bookmark model has finished loading. Creates a button @@ -173,6 +187,9 @@ class BookmarkBarGtk : public AnimationDelegate, GdkDragContext* context, guint time, BookmarkBarGtk* bar); + static void OnToolbarSizeAllocate(GtkWidget* widget, + GtkAllocation* allocation, + BookmarkBarGtk* bar); // Used for both folder buttons and the toolbar. static void OnDragReceived(GtkWidget* widget, @@ -215,6 +232,10 @@ class BookmarkBarGtk : public AnimationDelegate, // GtkToolbar which contains all the bookmark buttons. OwnedWidgetGtk bookmark_toolbar_; + // The button that shows extra bookmarks that don't fit on the bookmark + // bar. + GtkWidget* overflow_button_; + // The other bookmarks button. GtkWidget* other_bookmarks_button_; |