1 // Copyright (c) 2011 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_BOOKMARKS_BOOKMARK_MENU_CONTROLLER_GTK_H_ 6 #define CHROME_BROWSER_UI_GTK_BOOKMARKS_BOOKMARK_MENU_CONTROLLER_GTK_H_ 7 8 #include <map> 9 #include <vector> 10 11 #include "base/compiler_specific.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "chrome/browser/bookmarks/base_bookmark_model_observer.h" 14 #include "chrome/browser/ui/bookmarks/bookmark_context_menu_controller.h" 15 #include "ui/base/glib/glib_integers.h" 16 #include "ui/base/gtk/gtk_signal.h" 17 #include "ui/base/gtk/gtk_signal_registrar.h" 18 #include "ui/base/gtk/owned_widget_gtk.h" 19 #include "ui/base/window_open_disposition.h" 20 21 class Browser; 22 class BookmarkModel; 23 class BookmarkNode; 24 class MenuGtk; 25 26 namespace content { 27 class PageNavigator; 28 } 29 30 typedef struct _GdkDragContext GdkDragContext; 31 typedef struct _GdkEventButton GdkEventButton; 32 typedef struct _GtkSelectionData GtkSelectionData; 33 typedef struct _GtkWidget GtkWidget; 34 35 class BookmarkMenuController : public BaseBookmarkModelObserver, 36 public BookmarkContextMenuControllerDelegate { 37 public: 38 // Creates a BookmarkMenuController showing the children of |node| starting 39 // at index |start_child_index|. 40 BookmarkMenuController(Browser* browser, 41 content::PageNavigator* page_navigator, 42 GtkWindow* window, 43 const BookmarkNode* node, 44 int start_child_index); 45 virtual ~BookmarkMenuController(); 46 47 GtkWidget* widget() { return menu_; } 48 49 // Pops up the menu. |widget| must be a GtkChromeButton. 50 void Popup(GtkWidget* widget, gint button_type, guint32 timestamp); 51 52 // Overridden from BaseBookmarkModelObserver: 53 virtual void BookmarkModelChanged() OVERRIDE; 54 virtual void BookmarkNodeFaviconChanged(BookmarkModel* model, 55 const BookmarkNode* node) OVERRIDE; 56 57 // Overridden from BookmarkContextMenuController::Delegate: 58 virtual void WillExecuteCommand( 59 int command_id, 60 const std::vector<const BookmarkNode*>& bookmarks) OVERRIDE; 61 virtual void CloseMenu() OVERRIDE; 62 63 private: 64 // Recursively change the bookmark hierarchy rooted in |parent| into a set of 65 // gtk menus rooted in |menu|. 66 void BuildMenu(const BookmarkNode* parent, 67 int start_child_index, 68 GtkWidget* menu); 69 70 // Calls the page navigator to navigate to the node represented by 71 // |menu_item|. 72 void NavigateToMenuItem(GtkWidget* menu_item, 73 WindowOpenDisposition disposition); 74 75 // Button press and release events for a GtkMenu. 76 CHROMEGTK_CALLBACK_1(BookmarkMenuController, gboolean, 77 OnMenuButtonPressedOrReleased, GdkEventButton*); 78 79 // Button release event for a GtkMenuItem. 80 CHROMEGTK_CALLBACK_1(BookmarkMenuController, gboolean, OnButtonReleased, 81 GdkEventButton*); 82 83 // We connect this handler to the button-press-event signal for folder nodes. 84 // It suppresses the normal behavior (popping up the submenu) to allow these 85 // nodes to be draggable. The submenu is instead popped up on a 86 // button-release-event. 87 CHROMEGTK_CALLBACK_1(BookmarkMenuController, gboolean, OnFolderButtonPressed, 88 GdkEventButton*); 89 90 // We have to stop drawing |triggering_widget_| as active when the menu 91 // closes. 92 CHROMEGTK_CALLBACK_0(BookmarkMenuController, void, OnMenuHidden) 93 94 // We respond to the activate signal because things other than mouse button 95 // events can trigger it. 96 CHROMEGTK_CALLBACK_0(BookmarkMenuController, void, OnMenuItemActivated); 97 98 // The individual GtkMenuItems in the BookmarkMenu are all drag sources. 99 CHROMEGTK_CALLBACK_1(BookmarkMenuController, void, OnMenuItemDragBegin, 100 GdkDragContext*); 101 CHROMEGTK_CALLBACK_1(BookmarkMenuController, void, OnMenuItemDragEnd, 102 GdkDragContext*); 103 CHROMEGTK_CALLBACK_4(BookmarkMenuController, void, OnMenuItemDragGet, 104 GdkDragContext*, GtkSelectionData*, guint, guint); 105 106 Browser* browser_; 107 content::PageNavigator* page_navigator_; 108 109 // Parent window of this menu. 110 GtkWindow* parent_window_; 111 112 // The bookmark model. 113 BookmarkModel* model_; 114 115 // The node we're showing the contents of. 116 const BookmarkNode* node_; 117 118 // Our bookmark menus. We don't use the MenuGtk class because we have to do 119 // all sorts of weird non-standard things with this menu, like: 120 // - The menu is a drag target 121 // - The menu items have context menus. 122 GtkWidget* menu_; 123 124 // The visual representation that follows the cursor during drags. 125 GtkWidget* drag_icon_; 126 127 // Whether we should ignore the next button release event (because we were 128 // dragging). 129 bool ignore_button_release_; 130 131 // The widget we are showing for (i.e. the bookmark bar folder button). 132 GtkWidget* triggering_widget_; 133 134 // Mapping from node to GtkMenuItem menu id. This only contains entries for 135 // nodes of type URL. 136 std::map<const BookmarkNode*, GtkWidget*> node_to_menu_widget_map_; 137 138 // The controller and view for the right click context menu. 139 scoped_ptr<BookmarkContextMenuController> context_menu_controller_; 140 scoped_ptr<MenuGtk> context_menu_; 141 142 ui::GtkSignalRegistrar signals_; 143 144 DISALLOW_COPY_AND_ASSIGN(BookmarkMenuController); 145 }; 146 147 #endif // CHROME_BROWSER_UI_GTK_BOOKMARKS_BOOKMARK_MENU_CONTROLLER_GTK_H_ 148