Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
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 2012, Michael R. Fisher <mfisher31@gmail.com>
7
8  **Lumiera** is free software; you can redistribute it and/or modify it
9  under the terms of the GNU General Public License as published by the
10  Free Software Foundation; either version 2 of the License, or (at your
11  option) any later version. See the file COPYING for further details.
12
13* *****************************************************************/
14
15
22
23
24#define POPUP_SLUG "TheMenu"
25#define POPUP_PATH "/" POPUP_SLUG
26
27
28namespace stage {
29namespace widget{
30
31 namespace {
32 const int CAPTION_PADDING = 4;
33 const Gtk::ArrowType ARROW_TYPE = Gtk::ARROW_DOWN;
34 const Gtk::ShadowType SHADOW_TYPE = Gtk::SHADOW_NONE;
35 }
36
37
38
40 : ToggleButton()
41 , arrow_{ARROW_TYPE, SHADOW_TYPE}
42 , uimanager_{Gtk::UIManager::create()}
43 , actions_{Gtk::ActionGroup::create()}
44 {
46 }
47
48
49 MenuButton::MenuButton (Gtk::StockID const& stock_id)
50 : ToggleButton{}
51 , image_{stock_id, Gtk::ICON_SIZE_MENU}
52 , caption_{}
53 , arrow_{ARROW_TYPE, SHADOW_TYPE}
54 {
55 Gtk::StockItem stock_item;
56 REQUIRE (Gtk::StockItem::lookup (stock_id, stock_item));
57 caption_.set_text_with_mnemonic (stock_item.get_label());
58 hBox_.pack_start (image_);
60 }
61
62
63 MenuButton::MenuButton (cuString& label, bool mnemonic)
64 : ToggleButton()
65 , caption_(label, mnemonic)
66 , arrow_(ARROW_TYPE, SHADOW_TYPE)
67 {
69 }
70
71
72
73 Gtk::Widget*
75 {
76 //TODO: if (slug == "Menu") return &get_menu();
77 uString path (POPUP_PATH);
78 path.append("/");
79 return uimanager_->get_widget(path.append(slug));
80 }
81
82
83 Gtk::Menu&
85 {
86 uString path{"/"};
87 path.append (POPUP_SLUG);
88 auto* p_menu = dynamic_cast<Gtk::Menu*> (uimanager_->get_widget(path));
89 REQUIRE (p_menu);
90 return *p_menu;
91 }
92
93
94 void
96 sigc::slot<void>& callback, bool toggle)
97 {
98 if (not toggle)
99 actions_->add (Gtk::Action::create (slug, title,""), callback);
100 else
101 actions_->add (Gtk::ToggleAction::create (slug, title,"",false), callback);
102
104 uimanager_->add_ui (uimanager_->new_merge_id() // ID for the merged UI, see gtk_ui_manager_new_merge_id().
105 ,uString{"ui/"}.append(POPUP_SLUG) // schematic path in the UI
106 ,slug // name for the added UI element
107 ,slug // name for the action to be proxied
108 ,Gtk::UI_MANAGER_AUTO // type of the UI element to add
109 ,false // if the UI element is added before its siblings (otherwise added after them)
110 );
111
112 uimanager_->ensure_update();
113 }
114
115
116 void
118 sigc::slot<void>& callback, bool toggle)
119 {
120 uString uSlug{slug};
121 uString uTitle{_(title)};
122 append (uSlug, uTitle, callback, toggle);
123 }
124
125
126 void
128 {
129 uimanager_->add_ui_separator(
130 uimanager_->new_merge_id(),
131 uString{"ui/"}.append(POPUP_SLUG),
132 "Separator", Gtk::UI_MANAGER_SEPARATOR,
133 false);
134 }
135
136
137 void
139 {
140 get_menu().popup (sigc::mem_fun (this, &MenuButton::on_menu_position)
141 ,0 // The mouse button which was pressed to initiate the event
142 ,gtk_get_current_event_time()); // activate_time The time at which the activation event occurred.
143 this->set_active();
144 }
145
146
147 void
149 {
150 uimanager_ = Gtk::UIManager::create();
151 actions_ = Gtk::ActionGroup::create();
152 uimanager_->insert_action_group(actions_);
153
154 // Setup the UIManager with a popup menu
155 const guint rootId = uimanager_->new_merge_id();
156 uimanager_->add_ui (rootId
157 ,"ui"
160 ,Gtk::UI_MANAGER_POPUP
161 );
162 get_menu().signal_deactivate().connect(
163 sigc::mem_fun (this, &MenuButton::on_menu_deactivated));
164
165 arrow_.set (Gtk::ARROW_DOWN, Gtk::SHADOW_NONE);
166
167 hBox_.pack_start (caption_, Gtk::PACK_EXPAND_WIDGET, CAPTION_PADDING);
168 hBox_.pack_start (arrow_);
169
170 add (hBox_);
171 show_all();
172 }
173
174
175 void
177 {
178 this->popup();
179 }
180
181
182 void
184 {
185 this->set_active (false);
186 }
187
188
189 void
190 MenuButton::on_menu_position (int& x, int& y, bool& push_in)
191 {
192 Glib::RefPtr<Gdk::Window> window = get_window();
193 REQUIRE(window);
194
195 window->get_origin(x, y);
196 auto allocation = get_allocation();
197 x += allocation.get_x();
198 y += allocation.get_y() + allocation.get_height();
199
200 push_in = true;
201 }
202
203
204}}// stage::widget
void setupButton()
An internal method which sets up the button at create time.
Gtk::Label caption_
caption text label to show on the button.
MenuButton()
Create an empty button.
void on_menu_position(int &x, int &y, bool &push_in)
callback function used to determine the correct position for the popup menu.
void on_menu_deactivated()
An event handler for when the menu is closed.
Glib::RefPtr< Gtk::UIManager > uimanager_
Glib::RefPtr< Gtk::ActionGroup > actions_
Gtk::Arrow arrow_
arrow widget to be displayed to indicate a drop-down menu
Gtk::Widget * get(uString slug)
Get an object from the Menu.
void append(uString &slug, uString &title, sigc::slot< void > &callback, bool toggle=false)
Append a Menu Item to the Menu.
Gtk::HBox hBox_
holds the layout of an image, caption and arrow.
Gtk::Menu & get_menu()
Gets the menu which will be displayed when the button is clicked on.
Gtk::Image image_
can optionally display an icon.
void popup()
Pops up the menu.
void appendSeparator()
Append a Gtk::SeparatorMenuItem to the Menu.
void on_pressed()
An event handler for when the button is pressed.
const char * CStr
Definition error.hpp:42
#define _(String)
Definition gtk-base.hpp:68
#define POPUP_PATH
#define POPUP_SLUG
A button widget that displays a menu when clicked.
Lumiera GTK UI implementation root.
Definition guifacade.cpp:37
const uString cuString
Definition gtk-base.hpp:93
Glib::ustring uString
Definition gtk-base.hpp:92