libyui-mga-gtk  1.1.0
YMGAGMenuBar.cc
1 /*
2  Copyright 2020 by Angelo Naselli <anaselli at linux dot it>
3 
4  This library is free software; you can redistribute it and/or modify
5  it under the terms of the GNU Lesser General Public License as
6  published by the Free Software Foundation; either version 2.1 of the
7  License, or (at your option) version 3.0 of the License. This library
8  is distributed in the hope that it will be useful, but WITHOUT ANY
9  WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
11  License for more details. You should have received a copy of the GNU
12  Lesser General Public License along with this library; if not, write
13  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
14  Floor, Boston, MA 02110-1301 USA
15 */
16 
17 
18 /*-/
19 
20  File: YMGAGMenuBar.cc
21 
22  Author: Angelo Naselli <anaselli@linux.it>
23 
24 /-*/
25 
26 #include <yui/gtk/YGi18n.h>
27 
28 #define YUILogComponent "mga-gtk-ui"
29 
30 #include <yui/YUILog.h>
31 #include <yui/gtk/YGUI.h>
32 #include <yui/gtk/YGUtils.h>
33 #include <yui/gtk/YGWidget.h>
34 #include <YSelectionWidget.h>
35 #include <yui/gtk/YGSelectionStore.h>
36 #include <yui/gtk/ygtktreeview.h>
37 #include <yui/gtk/ygtkratiobox.h>
38 #include <string.h>
39 #include <yui/mga/YMGAMenuItem.h>
40 #include <YTable.h>
41 
42 #include <yui/gtk/YGDialog.h>
43 #include <gdk/gdkkeysyms.h>
44 #include <gtk/gtkmenubar.h>
45 #include <gtk/gtk.h>
46 #include "YMGAGMenuBar.h"
47 #include <boost/filesystem.hpp>
48 
49 #define YGTK_VBOX_NEW(arg) gtk_box_new(GTK_ORIENTATION_VERTICAL,arg)
50 #define YGTK_HBOX_NEW(arg) gtk_box_new(GTK_ORIENTATION_HORIZONTAL,arg)
51 
52 typedef std::map<YItem*, GtkWidget*> MenuEntryMap;
53 typedef std::pair<YItem*, GtkWidget*> MenuEntryPair;
54 
55 typedef std::map<YItem*, gulong> MenuCBMap;
56 typedef std::pair<YItem*, gulong> MenuCBPair;
57 
58 
60 {
61  GtkWidget *menubar;
62 
63  MenuEntryMap menu_entry;
64  MenuCBMap menu_cb;
65 
66  std::vector<GtkWidget*> menu_widgets;
67 };
68 
69 YMGAGMenuBar::YMGAGMenuBar(YWidget* parent)
70  : YMGAMenuBar(NULL),
71  YGWidget(this, parent, gtk_menu_bar_get_type(), NULL),
72  d(new Private)
73 
74 {
75  YUI_CHECK_NEW ( d );
76  d->menubar = getWidget();
77 
78 
79  //gtk_misc_set_alignment (GTK_MISC (getWidget()), 0.0, 0.5);
80 }
81 
82 static void selected_menuitem(GtkMenuItem *, YItem *item)
83 {
84  YGUI::ui()->sendEvent (new YMenuEvent (item));
85 }
86 
87 void YMGAGMenuBar::doCreateMenu (GtkWidget *menu, YItemIterator begin, YItemIterator end)
88 {
89  for (YItemIterator it = begin; it != end; it++)
90  {
91  YMenuSeparator *separator = dynamic_cast<YMenuSeparator *>(*it);
92  if (separator)
93  {
94  GtkWidget *sep = gtk_separator_menu_item_new();
95  gtk_menu_shell_append(GTK_MENU_SHELL(menu), sep);
96  gtk_widget_show(sep);
97  }
98  else
99  {
100  GtkWidget *entry;
101  YItem * yitem = *it;
102  std::string action_name = YGUtils::mapKBAccel (yitem->label());
103  if (yitem->hasIconName())
104  {
105  GtkIconTheme * theme = gtk_icon_theme_get_default();
106  std::string ico = boost::filesystem::path(yitem->iconName()).stem().c_str();
107  GtkWidget *icon;
108  GtkWidget *box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
109  if (gtk_icon_theme_has_icon (theme, ico.c_str()))
110  {
111  icon = gtk_image_new_from_icon_name (ico.c_str(), GTK_ICON_SIZE_MENU);
112  }
113  else
114  {
115  icon = gtk_image_new_from_file(yitem->iconName().c_str());
116  }
117  GtkWidget *label = gtk_label_new (action_name.c_str());
118  entry = gtk_menu_item_new ();
119 
120  gtk_container_add (GTK_CONTAINER (box), icon);
121  gtk_container_add (GTK_CONTAINER (box), label);
122 
123  gtk_label_set_use_underline (GTK_LABEL (label), TRUE);
124  gtk_label_set_xalign (GTK_LABEL (label), 0.0);
125 
126  gtk_container_add (GTK_CONTAINER (entry), box);
127  }
128  else
129  {
130  entry = gtk_menu_item_new_with_mnemonic (action_name.c_str());
131  }
132  d->menu_entry.insert(MenuEntryPair(*it, entry));
133 
134 
135  YMGAMenuItem *menuItem = dynamic_cast<YMGAMenuItem *>(*it);
136  if (menuItem)
137  {
138  gtk_widget_set_sensitive(entry, menuItem->enabled() ? gtk_true() : gtk_false());
139 
140  yuiDebug() << menuItem->label() << " enabled: " << menuItem->enabled() << " hidden:" << menuItem->hidden() << std::endl;
141  }
142  if ((*it)->hasChildren()) {
143  GtkWidget *submenu = gtk_menu_new();
144 
145  gtk_menu_item_set_submenu(GTK_MENU_ITEM(entry), submenu);
146  gtk_menu_shell_append (GTK_MENU_SHELL (menu), entry);
147  gtk_widget_show_all(entry);
148 
149  doCreateMenu (submenu, (*it)->childrenBegin(), (*it)->childrenEnd());
150 
151  }
152  else
153  {
154  gtk_menu_shell_append (GTK_MENU_SHELL (menu), entry);
155  gtk_widget_show_all (entry);
156 
157  gulong id = g_signal_connect (G_OBJECT (entry), "activate",
158  G_CALLBACK (selected_menuitem), *it);
159 
160  d->menu_cb.insert(MenuCBPair(*it, id));
161  }
162  if (menuItem)
163  if (menuItem->hidden())
164  gtk_widget_hide(entry);
165  }
166  }
167 }
168 
169 
170 void YMGAGMenuBar::addItem(YItem* yitem)
171 {
172  YMenuItem * item = dynamic_cast<YMenuItem *> ( yitem );
173  YUI_CHECK_PTR ( item );
174  yuiDebug() << item->label() << std::endl;
175 
176  // TODO icon from item
177  GtkWidget *menu = gtk_menu_new();
178 
179 
180  std::string lbl = YGUtils::mapKBAccel (item->label());
181  GtkWidget *menu_entry = gtk_menu_item_new_with_mnemonic(lbl.c_str());
182 
183  d->menu_widgets.push_back(menu_entry);
184 
185  d->menu_entry.insert(MenuEntryPair(yitem, menu_entry));
186  gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_entry), menu);
187  gtk_widget_show(menu_entry);
188  gtk_menu_shell_append (GTK_MENU_SHELL (d->menubar), menu_entry);
189 
190  YMGAMenuItem *menuItem = dynamic_cast<YMGAMenuItem *>(yitem);
191  if (menuItem)
192  {
193  yuiDebug() << menuItem->label() << " enabled: " << menuItem->enabled() << " hidden:" << menuItem->hidden() << std::endl;
194  gtk_widget_set_sensitive(menu_entry, menuItem->enabled() ? gtk_true() : gtk_false());
195  }
196  if (item->hasChildren())
197  doCreateMenu(menu, item->childrenBegin(), item->childrenEnd());
198 
199  if (menuItem)
200  if (menuItem->hidden())
201  gtk_widget_hide(menu_entry);
202 
203 
204  YMGAMenuBar::addItem(yitem);
205 }
206 
207 void YMGAGMenuBar::enableItem(YItem* menu_item, bool enable)
208 {
209  YMGAMenuBar::enableItem(menu_item, enable);
210 
211  auto search = d->menu_entry.find( menu_item );
212  if (search != d->menu_entry.end())
213  {
214  GtkWidget * menu_entry = search->second;
215  gtk_widget_set_sensitive(menu_entry, enable ? gtk_true() : gtk_false());
216  }
217  else
218  {
219  yuiError() << menu_item->label() << " not found" << std::endl;
220  }
221 }
222 
223 void YMGAGMenuBar::hideItem(YItem* menu_item, bool invisible)
224 {
225  YMGAMenuBar::hideItem(menu_item, invisible);
226 
227  auto search = d->menu_entry.find( menu_item );
228  if (search != d->menu_entry.end())
229  {
230  GtkWidget * menu_entry = search->second;
231  gtk_widget_set_visible(menu_entry, invisible ? gtk_false() : gtk_true());
232 // if (!invisible)
233 // {
234 // int min_width = this->getMinSize (YD_HORIZ);
235 // int min_height = this->getMinSize (YD_VERT);
236 // ygtk_adj_size_set_min(YGTK_ADJ_SIZE(getLayout()), min_width + menu_item->label().size(), min_height);
237 //
238 // gtk_widget_queue_resize(getWidget());
239 // }
240 
241  }
242  else
243  {
244  yuiError() << menu_item->label() << " not found" << std::endl;
245  }
246 }
247 
249 {
250 
251  for (MenuCBMap::iterator it=d->menu_cb.begin(); it!=d->menu_cb.end(); ++it)
252  {
253  auto search = d->menu_entry.find( it->first );
254  if (search != d->menu_entry.end())
255  g_signal_handler_disconnect (search->second, it->second);
256  }
257 
258 
259  for (GtkWidget *m: d->menu_widgets)
260  {
261  gtk_widget_destroy(m);
262  }
263 
264 // for (MenuEntryMap::iterator it=d->menu_entry.begin(); it!=d->menu_entry.end(); ++it)
265 // {
266 // gtk_widget_destroy(it->second);
267 // }
268 
269  d->menu_widgets.clear();
270  d->menu_cb.clear();
271  d->menu_entry.clear();
272 
273  YSelectionWidget::deleteAllItems();
274 }
275 
276 
277 YMGAGMenuBar::~YMGAGMenuBar()
278 {
279  d->menu_cb.clear();
280  d->menu_entry.clear();
281 
282  delete d;
283 }
284 
285 
YMGAGMenuBar::deleteAllItems
virtual void deleteAllItems()
Delete all items.
Definition: YMGAGMenuBar.cc:248
YMGAGMenuBar::enableItem
virtual void enableItem(YItem *menu_item, bool enable=true)
Enable YMGAMenuItem (menu name or menu entry) to enable/disable it into menubar or menu.
Definition: YMGAGMenuBar.cc:207
YMGAGMenuBar::hideItem
virtual void hideItem(YItem *menu_item, bool invisible=true)
Hide YMGAMenuItem (menu name or menu entry) to hide/show it into menubar or menu.
Definition: YMGAGMenuBar.cc:223
YMGAGMenuBar::addItem
virtual void addItem(YItem *item)
Add an YMenuItem first item represents the menu name, other sub items menu entries.
Definition: YMGAGMenuBar.cc:170
YMGAGMenuBar::Private
Definition: YMGAGMenuBar.cc:60