// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_GTK_BOOKMARK_MENU_CONTROLLER_GTK_H_ #define CHROME_BROWSER_GTK_BOOKMARK_MENU_CONTROLLER_GTK_H_ #pragma once #include #include "app/gtk_integers.h" #include "app/gtk_signal.h" #include "app/gtk_signal_registrar.h" #include "base/scoped_ptr.h" #include "chrome/browser/bookmarks/base_bookmark_model_observer.h" #include "chrome/browser/bookmarks/bookmark_context_menu_controller.h" #include "chrome/browser/gtk/owned_widget_gtk.h" #include "webkit/glue/window_open_disposition.h" class Browser; class Profile; class Profiler; class PageNavigator; class BookmarkModel; class BookmarkNode; class MenuGtk; typedef struct _GdkDragContext GdkDragContext; typedef struct _GdkEventButton GdkEventButton; typedef struct _GtkSelectionData GtkSelectionData; typedef struct _GtkWidget GtkWidget; class BookmarkMenuController : public BaseBookmarkModelObserver, public BookmarkContextMenuControllerDelegate { public: // Creates a BookmarkMenuController showing the children of |node| starting // at index |start_child_index|. BookmarkMenuController(Browser* browser, Profile* profile, PageNavigator* page_navigator, GtkWindow* window, const BookmarkNode* node, int start_child_index); virtual ~BookmarkMenuController(); GtkWidget* widget() { return menu_; } // Pops up the menu. |widget| must be a GtkChromeButton. void Popup(GtkWidget* widget, gint button_type, guint32 timestamp); // Overridden from BaseBookmarkModelObserver: virtual void BookmarkModelChanged(); virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, const BookmarkNode* node); // Overridden from BookmarkContextMenuController::Delegate: virtual void WillExecuteCommand(); virtual void CloseMenu(); private: // Recursively change the bookmark hierarchy rooted in |parent| into a set of // gtk menus rooted in |menu|. void BuildMenu(const BookmarkNode* parent, int start_child_index, GtkWidget* menu); // Calls the page navigator to navigate to the node represented by // |menu_item|. void NavigateToMenuItem(GtkWidget* menu_item, WindowOpenDisposition disposition); // Button press and release events for a GtkMenu. CHROMEGTK_CALLBACK_1(BookmarkMenuController, gboolean, OnMenuButtonPressedOrReleased, GdkEventButton*); // Button release event for a GtkMenuItem. CHROMEGTK_CALLBACK_1(BookmarkMenuController, gboolean, OnButtonReleased, GdkEventButton*); // We connect this handler to the button-press-event signal for folder nodes. // It suppresses the normal behavior (popping up the submenu) to allow these // nodes to be draggable. The submenu is instead popped up on a // button-release-event. CHROMEGTK_CALLBACK_1(BookmarkMenuController, gboolean, OnFolderButtonPressed, GdkEventButton*); // We have to stop drawing |triggering_widget_| as active when the menu // closes. CHROMEGTK_CALLBACK_0(BookmarkMenuController, void, OnMenuHidden) // We respond to the activate signal because things other than mouse button // events can trigger it. CHROMEGTK_CALLBACK_0(BookmarkMenuController, void, OnMenuItemActivated); // The individual GtkMenuItems in the BookmarkMenu are all drag sources. CHROMEGTK_CALLBACK_1(BookmarkMenuController, void, OnMenuItemDragBegin, GdkDragContext*); CHROMEGTK_CALLBACK_1(BookmarkMenuController, void, OnMenuItemDragEnd, GdkDragContext*); CHROMEGTK_CALLBACK_4(BookmarkMenuController, void, OnMenuItemDragGet, GdkDragContext*, GtkSelectionData*, guint, guint); Browser* browser_; Profile* profile_; PageNavigator* page_navigator_; // Parent window of this menu. GtkWindow* parent_window_; // The bookmark model. BookmarkModel* model_; // The node we're showing the contents of. const BookmarkNode* node_; // Our bookmark menus. We don't use the MenuGtk class because we have to do // all sorts of weird non-standard things with this menu, like: // - The menu is a drag target // - The menu items have context menus. GtkWidget* menu_; // The visual representation that follows the cursor during drags. GtkWidget* drag_icon_; // Whether we should ignore the next button release event (because we were // dragging). bool ignore_button_release_; // The widget we are showing for (i.e. the bookmark bar folder button). GtkWidget* triggering_widget_; // Mapping from node to GtkMenuItem menu id. This only contains entries for // nodes of type URL. std::map node_to_menu_widget_map_; // The controller and view for the right click context menu. scoped_ptr context_menu_controller_; scoped_ptr context_menu_; GtkSignalRegistrar signals_; DISALLOW_COPY_AND_ASSIGN(BookmarkMenuController); }; #endif // CHROME_BROWSER_GTK_BOOKMARK_MENU_CONTROLLER_GTK_H_