Lumiera  0.pre.03
»edit your freedom«
menu-button.cpp
Go to the documentation of this file.
1 /*
2  MenuButton - button widget to invoke a menu
3 
4  Copyright (C)
5  2008, Joel Holdsworth <joel@airwebreathe.org.uk>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
14 
21 
22 
23 using namespace Gtk;
24 using namespace Glib;
25 using namespace sigc;
26 
27 
28 #define POPUP_SLUG "TheMenu"
29 #define POPUP_PATH "/" POPUP_SLUG
30 
31 namespace stage {
32 namespace widget {
33 
34  namespace {
35  const int CaptionPadding = 4;
36  const ArrowType arrowType = ARROW_DOWN;
37  const ShadowType shadowType = SHADOW_NONE;
38  }
39 
40 
41 
42  MenuButton::MenuButton()
43  : ToggleButton()
44  , arrow(arrowType, shadowType)
45  , uimanager(UIManager::create())
46  , actions(ActionGroup::create())
47  {
48  setupButton();
49  }
50 
51 
52  MenuButton::MenuButton (StockID const& stock_id)
53  : ToggleButton()
54  , image(stock_id, ICON_SIZE_MENU)
55  , caption()
56  , arrow(arrowType, shadowType)
57  {
58  StockItem stock_item;
59  REQUIRE (StockItem::lookup (stock_id, stock_item));
60  caption.set_text_with_mnemonic (stock_item.get_label());
61  hBox.pack_start (image);
62  setupButton();
63  }
64 
65 
66  MenuButton::MenuButton (cuString& label, bool mnemonic)
67  : ToggleButton()
68  , caption(label, mnemonic)
69  , arrow(arrowType, shadowType)
70  {
71  setupButton();
72  }
73 
74 
75 
76  Gtk::Widget*
77  MenuButton::get (uString slug)
78  {
79  //TODO: if (slug == "Menu") return &get_menu();
80  uString path (POPUP_PATH);
81  path.append("/");
82  return uimanager->get_widget(path.append(slug));
83  }
84 
85 
86  Menu&
88  {
89  uString path ("/");
90  path.append (POPUP_SLUG);
91  Menu* p_menu = dynamic_cast<Menu*>(
92  uimanager->get_widget(path));
93  REQUIRE (p_menu);
94  return *p_menu;
95  }
96 
97 
98  void
99  MenuButton::append (uString &slug, uString &title,
100  sigc::slot<void> &callback, bool toggle)
101  {
102  if (!toggle)
103  actions->add(Action::create(slug, title,""), callback);
104  else
105  actions->add(ToggleAction::create(slug, title,"",false), callback);
106 
107  uimanager->add_ui(uimanager->new_merge_id(),
108  ustring("ui/").append(POPUP_SLUG),
109  slug, slug, Gtk::UI_MANAGER_AUTO,
110  false);
111  uimanager->ensure_update();
112  }
113 
114 
115  void
116  MenuButton::append (const char *slug, const char* title,
117  sigc::slot<void>& callback, bool toggle)
118  {
119  uString uSlug (slug);
120  uString uTitle (_(title));
121  append (uSlug, uTitle, callback, toggle);
122  }
123 
124 
125  void
127  {
128  uimanager->add_ui_separator(
129  uimanager->new_merge_id(),
130  ustring("ui/").append(POPUP_SLUG),
131  "Separator", Gtk::UI_MANAGER_SEPARATOR,
132  false);
133  }
134 
135 
136  void
138  {
139  get_menu().popup(mem_fun(this, &MenuButton::on_menu_position),
140  0, gtk_get_current_event_time());
141  set_active();
142  }
143 
144 
145  void
147  {
148  uimanager = UIManager::create();
149  actions = ActionGroup::create();
150  uimanager->insert_action_group(actions);
151 
152  // Setup the UIManager with a popup menu
153  const guint rootId = uimanager->new_merge_id();
154  uimanager->add_ui(rootId, "ui",
155  POPUP_SLUG, POPUP_SLUG,
156  Gtk::UI_MANAGER_POPUP);
157 
158  get_menu().signal_deactivate().connect(mem_fun(
160 
161  arrow.set(ARROW_DOWN, SHADOW_NONE);
162 
163  hBox.pack_start(caption, PACK_EXPAND_WIDGET, CaptionPadding);
164  hBox.pack_start(arrow);
165 
166  add(hBox);
167  show_all();
168  }
169 
170 
171  void
173  {
174  popup();
175  }
176 
177 
178  void
180  {
181  set_active(false);
182  }
183 
184 
185  void
186  MenuButton::on_menu_position (int& x, int& y, bool& push_in)
187  {
188  Glib::RefPtr<Gdk::Window> window = get_window();
189  REQUIRE(window);
190 
191  window->get_origin(x, y);
192  const Allocation allocation = get_allocation();
193  x += allocation.get_x();
194  y += allocation.get_y() + allocation.get_height();
195 
196  push_in = true;
197  }
198 
199 
200 }}// stage::widget
void appendSeparator()
Append a Gtk::SeparatorMenuItem to the Menu.
Image image
The image that will optionally display an icon.
Label caption
caption text label to show on the button.
void on_menu_position(int &x, int &y, bool &push_in)
callback function used to determine the correct position for the popup menu.
Arrow arrow
The arrow widget that will be displayed to hint the user that this button is a drop-down.
Menu & get_menu()
Gets the menu which will be displayed when the button is clicked on.
Definition: menu-button.cpp:87
Lumiera GTK UI implementation root.
Definition: guifacade.cpp:37
void append(uString &slug, uString &title, sigc::slot< void > &callback, bool toggle=false)
Append a Menu Item to the Menu.
Definition: menu-button.cpp:99
void popup()
Pops up the menu.
Gtk::Widget * get(uString slug)
Get an object from the Menu.
Definition: menu-button.cpp:77
void setupButton()
An internal method which sets up the button at create time.
void on_pressed()
An event handler for when the button is pressed.
MenuButton()
Create an empty button.
Definition: menu-button.cpp:42
HBox hBox
hBox for the layout of an image, caption and arrow.
void on_menu_deactivated()
An event handler for when the menu is closed.