• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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