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