OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef CHROME_BROWSER_UI_GTK_BOOKMARK_BAR_GTK_H_ |
| 6 #define CHROME_BROWSER_UI_GTK_BOOKMARK_BAR_GTK_H_ |
| 7 #pragma once |
| 8 |
| 9 #include <gtk/gtk.h> |
| 10 |
| 11 #include <vector> |
| 12 |
| 13 #include "app/gtk_signal.h" |
| 14 #include "base/gtest_prod_util.h" |
| 15 #include "base/scoped_ptr.h" |
| 16 #include "chrome/browser/bookmarks/bookmark_context_menu_controller.h" |
| 17 #include "chrome/browser/bookmarks/bookmark_model_observer.h" |
| 18 #include "chrome/browser/gtk/bookmark_bar_instructions_gtk.h" |
| 19 #include "chrome/browser/gtk/menu_bar_helper.h" |
| 20 #include "chrome/browser/gtk/owned_widget_gtk.h" |
| 21 #include "chrome/browser/gtk/view_id_util.h" |
| 22 #include "chrome/browser/sync/profile_sync_service.h" |
| 23 #include "chrome/common/notification_observer.h" |
| 24 #include "chrome/common/notification_registrar.h" |
| 25 #include "gfx/point.h" |
| 26 #include "gfx/size.h" |
| 27 #include "ui/base/animation/animation_delegate.h" |
| 28 |
| 29 class BookmarkMenuController; |
| 30 class Browser; |
| 31 class BrowserWindowGtk; |
| 32 class CustomContainerButton; |
| 33 class GtkThemeProvider; |
| 34 class MenuGtk; |
| 35 class PageNavigator; |
| 36 class Profile; |
| 37 class TabstripOriginProvider; |
| 38 |
| 39 namespace ui { |
| 40 class SlideAnimation; |
| 41 } |
| 42 |
| 43 class BookmarkBarGtk : public ui::AnimationDelegate, |
| 44 public ProfileSyncServiceObserver, |
| 45 public BookmarkModelObserver, |
| 46 public MenuBarHelper::Delegate, |
| 47 public NotificationObserver, |
| 48 public BookmarkBarInstructionsGtk::Delegate, |
| 49 public BookmarkContextMenuControllerDelegate { |
| 50 public: |
| 51 BookmarkBarGtk(BrowserWindowGtk* window, |
| 52 Profile* profile, |
| 53 Browser* browser, |
| 54 TabstripOriginProvider* tabstrip_origin_provider); |
| 55 virtual ~BookmarkBarGtk(); |
| 56 |
| 57 // Resets the profile. This removes any buttons for the current profile and |
| 58 // recreates the models. |
| 59 void SetProfile(Profile* profile); |
| 60 |
| 61 // Returns the current profile. |
| 62 Profile* GetProfile() { return profile_; } |
| 63 |
| 64 // Returns the current browser. |
| 65 Browser* browser() const { return browser_; } |
| 66 |
| 67 // Returns the top level widget. |
| 68 GtkWidget* widget() const { return event_box_.get(); } |
| 69 |
| 70 // Sets the PageNavigator that is used when the user selects an entry on |
| 71 // the bookmark bar. |
| 72 void SetPageNavigator(PageNavigator* navigator); |
| 73 |
| 74 // Create the contents of the bookmark bar. |
| 75 void Init(Profile* profile); |
| 76 |
| 77 // Whether the current page is the New Tag Page (which requires different |
| 78 // rendering). |
| 79 bool OnNewTabPage(); |
| 80 |
| 81 // Change the visibility of the bookmarks bar. (Starts out hidden, per GTK's |
| 82 // default behaviour). There are three visiblity states: |
| 83 // |
| 84 // Showing - bookmark bar is fully visible. |
| 85 // Hidden - bookmark bar is hidden except for a few pixels that give |
| 86 // extra padding to the bottom of the toolbar. Buttons are not |
| 87 // clickable. |
| 88 // Fullscreen - bookmark bar is fully hidden. |
| 89 void Show(bool animate); |
| 90 void Hide(bool animate); |
| 91 void EnterFullscreen(); |
| 92 |
| 93 // Get the current height of the bookmark bar. |
| 94 int GetHeight(); |
| 95 |
| 96 // Returns true if the bookmark bar is showing an animation. |
| 97 bool IsAnimating(); |
| 98 |
| 99 // Returns true if the bookmarks bar preference is set to 'always show'. |
| 100 bool IsAlwaysShown(); |
| 101 |
| 102 // ui::AnimationDelegate implementation -------------------------------------- |
| 103 virtual void AnimationProgressed(const ui::Animation* animation); |
| 104 virtual void AnimationEnded(const ui::Animation* animation); |
| 105 |
| 106 // MenuBarHelper::Delegate implementation ------------------------------------ |
| 107 virtual void PopupForButton(GtkWidget* button); |
| 108 virtual void PopupForButtonNextTo(GtkWidget* button, |
| 109 GtkMenuDirectionType dir); |
| 110 |
| 111 // The NTP needs to have access to this. |
| 112 static const int kBookmarkBarNTPHeight; |
| 113 |
| 114 // BookmarkContextMenuController::Delegate implementation -------------------- |
| 115 virtual void CloseMenu(); |
| 116 |
| 117 private: |
| 118 FRIEND_TEST_ALL_PREFIXES(BookmarkBarGtkUnittest, DisplaysHelpMessageOnEmpty); |
| 119 FRIEND_TEST_ALL_PREFIXES(BookmarkBarGtkUnittest, |
| 120 HidesHelpMessageWithBookmark); |
| 121 FRIEND_TEST_ALL_PREFIXES(BookmarkBarGtkUnittest, BuildsButtons); |
| 122 |
| 123 // Helper function which generates GtkToolItems for |bookmark_toolbar_|. |
| 124 void CreateAllBookmarkButtons(); |
| 125 |
| 126 // Sets the visibility of the instructional text based on whether there are |
| 127 // any bookmarks in the bookmark bar node. |
| 128 void SetInstructionState(); |
| 129 |
| 130 // Sets the visibility of the overflow chevron. |
| 131 void SetChevronState(); |
| 132 |
| 133 // Helper function which destroys all the bookmark buttons in the GtkToolbar. |
| 134 void RemoveAllBookmarkButtons(); |
| 135 |
| 136 // Returns the number of buttons corresponding to starred urls/groups. This |
| 137 // is equivalent to the number of children the bookmark bar node from the |
| 138 // bookmark bar model has. |
| 139 int GetBookmarkButtonCount(); |
| 140 |
| 141 // Set the appearance of the overflow button appropriately (either chromium |
| 142 // style or GTK style). |
| 143 void SetOverflowButtonAppearance(); |
| 144 |
| 145 // Returns the index of the first bookmark that is not visible on the bar. |
| 146 // Returns -1 if they are all visible. |
| 147 // |extra_space| is how much extra space to give the toolbar during the |
| 148 // calculation (for the purposes of determining if ditching the chevron |
| 149 // would be a good idea). |
| 150 // If non-NULL, |showing_folders| will be packed with all the folders that are |
| 151 // showing on the bar. |
| 152 int GetFirstHiddenBookmark(int extra_space, |
| 153 std::vector<GtkWidget*>* showing_folders); |
| 154 |
| 155 // Returns true if the bookmark bar should be floating on the page (for |
| 156 // NTP). |
| 157 bool ShouldBeFloating(); |
| 158 // Update the floating state (either enable or disable it, or do nothing). |
| 159 void UpdateFloatingState(); |
| 160 |
| 161 // Turns on or off the app_paintable flag on |event_box_|, depending on our |
| 162 // state. |
| 163 void UpdateEventBoxPaintability(); |
| 164 |
| 165 // Queue a paint on the event box. |
| 166 void PaintEventBox(); |
| 167 |
| 168 // Finds the size of the current tab contents, if it exists and sets |size| |
| 169 // to the correct value. Returns false if there isn't a TabContents, a |
| 170 // condition that can happen during testing. |
| 171 bool GetTabContentsSize(gfx::Size* size); |
| 172 |
| 173 // Makes the appropriate widget on the bookmark bar stop throbbing |
| 174 // (a folder, the overflow chevron, or nothing). |
| 175 void StartThrobbing(const BookmarkNode* node); |
| 176 |
| 177 // Set |throbbing_widget_| to |widget|. Also makes sure that |
| 178 // |throbbing_widget_| doesn't become stale. |
| 179 void SetThrobbingWidget(GtkWidget* widget); |
| 180 |
| 181 // An item has been dragged over the toolbar, update the drag context |
| 182 // and toolbar UI appropriately. |
| 183 gboolean ItemDraggedOverToolbar( |
| 184 GdkDragContext* context, int index, guint time); |
| 185 |
| 186 // When dragging in the middle of a folder, assume the user wants to drop |
| 187 // on the folder. Towards the edges, assume the user wants to drop on the |
| 188 // toolbar. This makes it possible to drop between two folders. This function |
| 189 // returns the index on the toolbar the drag should target, or -1 if the |
| 190 // drag should hit the folder. |
| 191 int GetToolbarIndexForDragOverFolder(GtkWidget* button, gint x); |
| 192 |
| 193 void ClearToolbarDropHighlighting(); |
| 194 |
| 195 // Overridden from BookmarkModelObserver: |
| 196 |
| 197 // Invoked when the bookmark model has finished loading. Creates a button |
| 198 // for each of the children of the root node from the model. |
| 199 virtual void Loaded(BookmarkModel* model); |
| 200 |
| 201 // Invoked when the model is being deleted. |
| 202 virtual void BookmarkModelBeingDeleted(BookmarkModel* model); |
| 203 |
| 204 // Invoked when a node has moved. |
| 205 virtual void BookmarkNodeMoved(BookmarkModel* model, |
| 206 const BookmarkNode* old_parent, |
| 207 int old_index, |
| 208 const BookmarkNode* new_parent, |
| 209 int new_index); |
| 210 virtual void BookmarkNodeAdded(BookmarkModel* model, |
| 211 const BookmarkNode* parent, |
| 212 int index); |
| 213 virtual void BookmarkNodeRemoved(BookmarkModel* model, |
| 214 const BookmarkNode* parent, |
| 215 int old_index, |
| 216 const BookmarkNode* node); |
| 217 virtual void BookmarkNodeChanged(BookmarkModel* model, |
| 218 const BookmarkNode* node); |
| 219 // Invoked when a favicon has finished loading. |
| 220 virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, |
| 221 const BookmarkNode* node); |
| 222 virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, |
| 223 const BookmarkNode* node); |
| 224 |
| 225 // Overridden from NotificationObserver: |
| 226 virtual void Observe(NotificationType type, |
| 227 const NotificationSource& source, |
| 228 const NotificationDetails& details); |
| 229 |
| 230 GtkWidget* CreateBookmarkButton(const BookmarkNode* node); |
| 231 GtkToolItem* CreateBookmarkToolItem(const BookmarkNode* node); |
| 232 |
| 233 void ConnectFolderButtonEvents(GtkWidget* widget, bool is_tool_item); |
| 234 |
| 235 // Finds the BookmarkNode from the model associated with |button|. |
| 236 const BookmarkNode* GetNodeForToolButton(GtkWidget* button); |
| 237 |
| 238 // Creates and displays a popup menu for BookmarkNode |node|. |
| 239 void PopupMenuForNode(GtkWidget* sender, const BookmarkNode* node, |
| 240 GdkEventButton* event); |
| 241 |
| 242 // GtkButton callbacks. |
| 243 CHROMEGTK_CALLBACK_1(BookmarkBarGtk, gboolean, OnButtonPressed, |
| 244 GdkEventButton*); |
| 245 CHROMEGTK_CALLBACK_1(BookmarkBarGtk, gboolean, OnSyncErrorButtonPressed, |
| 246 GdkEventButton*); |
| 247 CHROMEGTK_CALLBACK_0(BookmarkBarGtk, void, OnClicked); |
| 248 CHROMEGTK_CALLBACK_1(BookmarkBarGtk, void, OnButtonDragBegin, |
| 249 GdkDragContext*); |
| 250 CHROMEGTK_CALLBACK_1(BookmarkBarGtk, void, OnButtonDragEnd, GdkDragContext*); |
| 251 CHROMEGTK_CALLBACK_4(BookmarkBarGtk, void, OnButtonDragGet, |
| 252 GdkDragContext*, GtkSelectionData*, guint, guint); |
| 253 |
| 254 // GtkButton callbacks for folder buttons. |
| 255 CHROMEGTK_CALLBACK_0(BookmarkBarGtk, void, OnFolderClicked); |
| 256 |
| 257 // GtkToolbar callbacks. |
| 258 CHROMEGTK_CALLBACK_4(BookmarkBarGtk, gboolean, OnToolbarDragMotion, |
| 259 GdkDragContext*, gint, gint, guint); |
| 260 CHROMEGTK_CALLBACK_1(BookmarkBarGtk, void, OnToolbarSizeAllocate, |
| 261 GtkAllocation*); |
| 262 |
| 263 // Used for both folder buttons and the toolbar. |
| 264 CHROMEGTK_CALLBACK_6(BookmarkBarGtk, void, OnDragReceived, |
| 265 GdkDragContext*, gint, gint, GtkSelectionData*, |
| 266 guint, guint); |
| 267 CHROMEGTK_CALLBACK_2(BookmarkBarGtk, void, OnDragLeave, |
| 268 GdkDragContext*, guint); |
| 269 |
| 270 // Used for folder buttons. |
| 271 CHROMEGTK_CALLBACK_4(BookmarkBarGtk, gboolean, OnFolderDragMotion, |
| 272 GdkDragContext*, gint, gint, guint); |
| 273 |
| 274 // GtkEventBox callbacks. |
| 275 CHROMEGTK_CALLBACK_1(BookmarkBarGtk, gboolean, OnEventBoxExpose, |
| 276 GdkEventExpose*); |
| 277 CHROMEGTK_CALLBACK_0(BookmarkBarGtk, void, OnEventBoxDestroy); |
| 278 |
| 279 // Callbacks on our parent widget. |
| 280 CHROMEGTK_CALLBACK_1(BookmarkBarGtk, void, OnParentSizeAllocate, |
| 281 GtkAllocation*); |
| 282 |
| 283 // |throbbing_widget_| callback. |
| 284 CHROMEGTK_CALLBACK_0(BookmarkBarGtk, void, OnThrobbingWidgetDestroy); |
| 285 |
| 286 // ProfileSyncServiceObserver method. |
| 287 virtual void OnStateChanged(); |
| 288 |
| 289 // Overriden from BookmarkBarInstructionsGtk::Delegate. |
| 290 virtual void ShowImportDialog(); |
| 291 |
| 292 Profile* profile_; |
| 293 |
| 294 // Used for opening urls. |
| 295 PageNavigator* page_navigator_; |
| 296 |
| 297 Browser* browser_; |
| 298 BrowserWindowGtk* window_; |
| 299 |
| 300 // Provides us with the offset into the background theme image. |
| 301 TabstripOriginProvider* tabstrip_origin_provider_; |
| 302 |
| 303 // Model providing details as to the starred entries/groups that should be |
| 304 // shown. This is owned by the Profile. |
| 305 BookmarkModel* model_; |
| 306 |
| 307 // Contains |bookmark_hbox_|. Event box exists to prevent leakage of |
| 308 // background color from the toplevel application window's GDK window. |
| 309 OwnedWidgetGtk event_box_; |
| 310 |
| 311 // Used to float the bookmark bar when on the NTP. |
| 312 GtkWidget* ntp_padding_box_; |
| 313 |
| 314 // Used to paint the background of the bookmark bar when in floating mode. |
| 315 GtkWidget* paint_box_; |
| 316 |
| 317 // Used to position all children. |
| 318 GtkWidget* bookmark_hbox_; |
| 319 |
| 320 // Alignment widget that is visible if there are no bookmarks on |
| 321 // the bookmar bar. |
| 322 GtkWidget* instructions_; |
| 323 |
| 324 // BookmarkBarInstructionsGtk that holds the label and the link for importing |
| 325 // bookmarks when there are no bookmarks on the bookmark bar. |
| 326 scoped_ptr<BookmarkBarInstructionsGtk> instructions_gtk_; |
| 327 |
| 328 // GtkToolbar which contains all the bookmark buttons. |
| 329 OwnedWidgetGtk bookmark_toolbar_; |
| 330 |
| 331 // The button that shows extra bookmarks that don't fit on the bookmark |
| 332 // bar. |
| 333 GtkWidget* overflow_button_; |
| 334 |
| 335 // The other bookmarks button. |
| 336 GtkWidget* other_bookmarks_button_; |
| 337 |
| 338 // The sync error button. |
| 339 GtkWidget* sync_error_button_; |
| 340 |
| 341 // A pointer to the ProfileSyncService instance if one exists. |
| 342 ProfileSyncService* sync_service_; |
| 343 |
| 344 // The BookmarkNode from the model being dragged. NULL when we aren't |
| 345 // dragging. |
| 346 const BookmarkNode* dragged_node_; |
| 347 |
| 348 // The visual representation that follows the cursor during drags. |
| 349 GtkWidget* drag_icon_; |
| 350 |
| 351 // We create a GtkToolbarItem from |dragged_node_| ;or display. |
| 352 GtkToolItem* toolbar_drop_item_; |
| 353 |
| 354 // Theme provider for building buttons. |
| 355 GtkThemeProvider* theme_provider_; |
| 356 |
| 357 // Whether we should show the instructional text in the bookmark bar. |
| 358 bool show_instructions_; |
| 359 |
| 360 MenuBarHelper menu_bar_helper_; |
| 361 |
| 362 // The last displayed right click menu, or NULL if no menus have been |
| 363 // displayed yet. |
| 364 // The controller. |
| 365 scoped_ptr<BookmarkContextMenuController> current_context_menu_controller_; |
| 366 // The view. |
| 367 scoped_ptr<MenuGtk> current_context_menu_; |
| 368 |
| 369 // The last displayed left click menu, or NULL if no menus have been |
| 370 // displayed yet. |
| 371 scoped_ptr<BookmarkMenuController> current_menu_; |
| 372 |
| 373 scoped_ptr<ui::SlideAnimation> slide_animation_; |
| 374 |
| 375 // Whether we are currently configured as floating (detached from the |
| 376 // toolbar). This reflects our actual state, and can be out of sync with |
| 377 // what ShouldShowFloating() returns. |
| 378 bool floating_; |
| 379 |
| 380 // Used to optimize out |bookmark_toolbar_| size-allocate events we don't |
| 381 // need to respond to. |
| 382 int last_allocation_width_; |
| 383 |
| 384 NotificationRegistrar registrar_; |
| 385 |
| 386 // The size of the tab contents last time we forced a paint. We keep track |
| 387 // of this so we don't force too many paints. |
| 388 gfx::Size last_tab_contents_size_; |
| 389 |
| 390 // The last coordinates recorded by OnButtonPress; used to line up the |
| 391 // drag icon during bookmark drags. |
| 392 gfx::Point last_pressed_coordinates_; |
| 393 |
| 394 // The currently throbbing widget. This is NULL if no widget is throbbing. |
| 395 // We track it because we only want to allow one widget to throb at a time. |
| 396 GtkWidget* throbbing_widget_; |
| 397 |
| 398 ScopedRunnableMethodFactory<BookmarkBarGtk> method_factory_; |
| 399 }; |
| 400 |
| 401 #endif // CHROME_BROWSER_UI_GTK_BOOKMARK_BAR_GTK_H_ |
OLD | NEW |