libyui-gtk  2.44.9
YGMenuButton.cc
1 /********************************************************************
2  * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
3  ********************************************************************/
4 
5 #define YUILogComponent "gtk"
6 #include <yui/Libyui_config.h>
7 #include "YGUI.h"
8 #include "YGUtils.h"
9 #include "YGWidget.h"
10 #include "YMenuButton.h"
11 #include "ygtkmenubutton.h"
12 
13 static void selected_item_cb (GtkMenuItem *menuitem, YItem *item)
14 {
15  // HACK: gtk_menu_get_active() doesn't work properly
16  GtkWidget *menu = gtk_widget_get_ancestor (GTK_WIDGET (menuitem), GTK_TYPE_MENU);
17  g_object_set_data (G_OBJECT (menu), "active", menuitem);
18 
19  YGUI::ui()->sendEvent (new YMenuEvent (item));
20 }
21 
22 static void doCreateMenu (GtkWidget *parent, YItemIterator begin, YItemIterator end)
23 {
24  for (YItemIterator it = begin; it != end; it++) {
25  GtkWidget *entry;
26  std::string str = YGUtils::mapKBAccel ((*it)->label());
27 
28  entry = gtk_menu_item_new_with_mnemonic (str.c_str());
29 
30  gtk_menu_shell_append (GTK_MENU_SHELL (parent), entry);
31 
32  if ((*it)->hasChildren()) {
33  GtkWidget *submenu = gtk_menu_new();
34  doCreateMenu (submenu, (*it)->childrenBegin(), (*it)->childrenEnd());
35  gtk_menu_item_set_submenu (GTK_MENU_ITEM (entry), submenu);
36  }
37  else
38  g_signal_connect (G_OBJECT (entry), "activate",
39  G_CALLBACK (selected_item_cb), *it);
40  }
41 }
42 
43 class YGMenuButton : public YMenuButton, public YGWidget
44 {
45 public:
46  YGMenuButton (YWidget *parent, const std::string &label)
47  : YMenuButton (NULL, label),
48  YGWidget (this, parent, YGTK_TYPE_MENU_BUTTON, NULL)
49  { setLabel (label); }
50 
51  // YMenuButton
52  virtual void setLabel (const std::string &label)
53  {
54  std::string str = YGUtils::mapKBAccel (label.c_str());
55  ygtk_menu_button_set_label (YGTK_MENU_BUTTON (getWidget()), str.c_str());
56  YMenuButton::setLabel (label);
57  }
58 
59  virtual void rebuildMenuTree()
60  {
61  GtkWidget *menu = gtk_menu_new();
62  doCreateMenu (menu, itemsBegin(), itemsEnd());
63  gtk_widget_show_all (menu);
64  ygtk_menu_button_set_popup (YGTK_MENU_BUTTON (getWidget()), menu);
65  }
66 
67  YGWIDGET_IMPL_COMMON (YMenuButton)
68 };
69 
70 YMenuButton *YGWidgetFactory::createMenuButton (YWidget *parent, const std::string &label)
71 { return new YGMenuButton (parent, label); }
72 
73 #include <YContextMenu.h>
74 
75 class YGContextMenu : public YContextMenu, public YGWidget
76 {
77  int m_deactivateTimeout;
78 
79 public:
81  : YContextMenu(),
82  YGWidget (this, NULL, GTK_TYPE_MENU, NULL)
83  {
84  // "cancel" signal doesnt seem to work properly
85  m_deactivateTimeout = 0;
86  connect (getWidget(), "deactivate", G_CALLBACK (deactivate_cb), this);
87  }
88 
89  // YContextMenu
90  virtual void rebuildMenuTree()
91  {
92  GtkWidget *menu = getWidget();
93  doCreateMenu (menu, itemsBegin(), itemsEnd());
94  gtk_widget_show_all (menu);
95 
96  // gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 3, gtk_get_current_event_time());
97  gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
98  }
99 
100  // callbacks
101  static void deactivate_cb (GtkMenuShell *menu, YGContextMenu *pThis)
102  { // ugly: we need to make sure a selection was made before this callback called
103  // we'll use a timeout because deactivate seems to be called more than once
104  if(pThis->m_deactivateTimeout == 0)
105  pThis->m_deactivateTimeout = g_timeout_add_full (G_PRIORITY_LOW, 50, cancel_cb, pThis, NULL);
106  //g_idle_add_full (G_PRIORITY_LOW, cancel_cb, pThis, NULL);
107  }
108 
109  static gboolean cancel_cb (gpointer data)
110  {
111  YGContextMenu *pThis = (YGContextMenu *) data;
112  if (!g_object_get_data (G_OBJECT (pThis->getWidget()), "active"))
113  YGUI::ui()->sendEvent (new YCancelEvent());
114  delete pThis;
115  return FALSE;
116  }
117 
118  YGWIDGET_IMPL_COMMON (YContextMenu)
119 };
120 
121 bool YGApplication::openContextMenu (const YItemCollection &itemCollection)
122 {
123  YGContextMenu *menu = new YGContextMenu();
124  menu->addItems (itemCollection);
125  return true;
126 }
127 
YGContextMenu
Definition: YGMenuButton.cc:75
YGMenuButton
Definition: YGMenuButton.cc:43
YGWidget
Definition: YGWidget.h:13