172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This class replicates some menubar behaviors that are tricky to get right.
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// It is used to create a more native feel for the bookmark bar.
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#ifndef CHROME_BROWSER_UI_GTK_MENU_BAR_HELPER_H_
972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#define CHROME_BROWSER_UI_GTK_MENU_BAR_HELPER_H_
103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <gtk/gtk.h>
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/gtk/gtk_signal.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsennamespace ui {
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass GtkSignalRegistrar;
2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MenuBarHelper {
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  class Delegate {
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   public:
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual ~Delegate() {}
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Called when a the menu for a button ought to be triggered.
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void PopupForButton(GtkWidget* button) = 0;
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void PopupForButtonNextTo(GtkWidget* button,
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      GtkMenuDirectionType dir) = 0;
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |delegate| cannot be null.
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit MenuBarHelper(Delegate* delegate);
373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual ~MenuBarHelper();
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Must be called whenever a button's menu starts showing. It triggers the
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // MenuBarHelper to start listening for certain events.
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void MenuStartedShowing(GtkWidget* button, GtkWidget* menu);
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add |button| to the set of buttons we care about.
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Add(GtkWidget* button);
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Remove |button| from the set of buttons we care about.
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Remove(GtkWidget* button);
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Clear all buttons from the set.
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Clear();
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
53201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  CHROMEGTK_CALLBACK_0(MenuBarHelper, void, OnMenuHiddenOrDestroyed);
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHROMEGTK_CALLBACK_1(MenuBarHelper, gboolean, OnMenuMotionNotify,
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       GdkEventMotion*);
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHROMEGTK_CALLBACK_1(MenuBarHelper, void, OnMenuMoveCurrent,
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       GtkMenuDirectionType);
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The buttons for which we pop up menus. We do not own these, or even add
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // refs to them.
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<GtkWidget*> buttons_;
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The button that is currently showing a menu, or NULL.
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* button_showing_menu_;
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The highest level menu that is currently showing, or NULL.
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* showing_menu_;
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // All the submenus of |showing_menu_|. We connect to motion events on all
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // of them.
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<GtkWidget*> submenus_;
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Signal handlers that are attached only between the "show" and "hide" events
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // for the menu.
7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  scoped_ptr<ui::GtkSignalRegistrar> signal_handlers_;
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Delegate* delegate_;
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif  // CHROME_BROWSER_UI_GTK_MENU_BAR_HELPER_H_
81