Home | History | Annotate | Download | only in bookmarks
      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 
     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