menu_bar_helper.h revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
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// This class replicates some menubar behaviors that are tricky to get right.
6// It is used to create a more native feel for the bookmark bar.
7
8#ifndef CHROME_BROWSER_UI_GTK_MENU_BAR_HELPER_H_
9#define CHROME_BROWSER_UI_GTK_MENU_BAR_HELPER_H_
10#pragma once
11
12#include <gtk/gtk.h>
13
14#include <vector>
15
16#include "base/scoped_ptr.h"
17#include "ui/base/gtk/gtk_signal.h"
18
19namespace ui {
20class GtkSignalRegistrar;
21}
22
23class MenuBarHelper {
24 public:
25  class Delegate {
26   public:
27    virtual ~Delegate() {}
28
29    // Called when a the menu for a button ought to be triggered.
30    virtual void PopupForButton(GtkWidget* button) = 0;
31    virtual void PopupForButtonNextTo(GtkWidget* button,
32                                      GtkMenuDirectionType dir) = 0;
33  };
34
35  // |delegate| cannot be null.
36  explicit MenuBarHelper(Delegate* delegate);
37  virtual ~MenuBarHelper();
38
39  // Must be called whenever a button's menu starts showing. It triggers the
40  // MenuBarHelper to start listening for certain events.
41  void MenuStartedShowing(GtkWidget* button, GtkWidget* menu);
42
43  // Add |button| to the set of buttons we care about.
44  void Add(GtkWidget* button);
45
46  // Remove |button| from the set of buttons we care about.
47  void Remove(GtkWidget* button);
48
49  // Clear all buttons from the set.
50  void Clear();
51
52 private:
53  CHROMEGTK_CALLBACK_0(MenuBarHelper, void, OnMenuHiddenOrDestroyed);
54  CHROMEGTK_CALLBACK_1(MenuBarHelper, gboolean, OnMenuMotionNotify,
55                       GdkEventMotion*);
56  CHROMEGTK_CALLBACK_1(MenuBarHelper, void, OnMenuMoveCurrent,
57                       GtkMenuDirectionType);
58
59  // The buttons for which we pop up menus. We do not own these, or even add
60  // refs to them.
61  std::vector<GtkWidget*> buttons_;
62
63  // The button that is currently showing a menu, or NULL.
64  GtkWidget* button_showing_menu_;
65
66  // The highest level menu that is currently showing, or NULL.
67  GtkWidget* showing_menu_;
68
69  // All the submenus of |showing_menu_|. We connect to motion events on all
70  // of them.
71  std::vector<GtkWidget*> submenus_;
72
73  // Signal handlers that are attached only between the "show" and "hide" events
74  // for the menu.
75  scoped_ptr<ui::GtkSignalRegistrar> signal_handlers_;
76
77  Delegate* delegate_;
78};
79
80#endif  // CHROME_BROWSER_UI_GTK_MENU_BAR_HELPER_H_
81