43
41
PROP_USE_UNDERLINE,
50
47
static int signals[LAST_SIGNAL];
53
G_DEFINE_TYPE (GthMenuButton, gth_menu_button, GTK_TYPE_TOGGLE_BUTTON)
57
gth_menu_button_state_changed (GtkWidget *widget,
58
GtkStateType previous_state)
60
GthMenuButton *self = GTH_MENU_BUTTON (widget);
62
if (! gtk_widget_is_sensitive (widget) && (self->priv->menu != NULL))
63
gtk_menu_shell_deactivate (GTK_MENU_SHELL (self->priv->menu));
50
G_DEFINE_TYPE (GthMenuButton, gth_menu_button, GTK_TYPE_MENU_BUTTON)
129
/* Callback for the "deactivate" signal on the pop-up menu.
130
* This is used so that we unset the state of the toggle button
131
* when the pop-up menu disappears.
134
menu_deactivate_cb (GtkMenuShell *menu_shell,
137
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self), FALSE);
143
menu_position_func (GtkMenu *menu,
149
GtkWidget *widget = GTK_WIDGET (self);
150
GtkRequisition menu_req;
151
GtkTextDirection direction;
152
cairo_rectangle_int_t monitor;
155
GtkAllocation allocation;
157
gtk_widget_get_preferred_size (GTK_WIDGET (self->priv->menu), &menu_req, NULL);
159
direction = gtk_widget_get_direction (widget);
161
screen = gtk_widget_get_screen (GTK_WIDGET (menu));
162
monitor_num = gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (widget));
165
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
166
gtk_widget_get_allocation (widget, &allocation);
168
gdk_window_get_origin (gtk_widget_get_window (widget), x, y);
172
if (direction == GTK_TEXT_DIR_LTR)
173
*x += MAX (allocation.width - menu_req.width, 0);
174
else if (menu_req.width > allocation.width)
175
*x -= menu_req.width - allocation.width;
177
if ((*y + allocation.height + menu_req.height) <= monitor.y + monitor.height)
178
*y += allocation.height;
179
else if ((*y - menu_req.height) >= monitor.y)
180
*y -= menu_req.height;
181
else if (monitor.y + monitor.height - (*y + allocation.height) > *y)
182
*y += allocation.height;
184
*y -= menu_req.height;
191
popup_menu_under_button (GthMenuButton *self,
192
GdkEventButton *event)
194
g_signal_emit (self, signals[SHOW_MENU], 0);
196
if (self->priv->menu == NULL)
199
if (gtk_menu_get_attach_widget (self->priv->menu) != NULL)
200
gtk_menu_detach (self->priv->menu);
201
gtk_menu_popup (self->priv->menu, NULL, NULL,
202
(GtkMenuPositionFunc) menu_position_func,
204
event ? event->button : 0,
205
event ? event->time : gtk_get_current_event_time ());
210
toggle_button_toggled_cb (GtkToggleButton *togglebutton,
213
GthMenuButton *self = user_data;
214
gboolean toggle_active = gtk_toggle_button_get_active (togglebutton);
216
if (self->priv->menu == NULL)
219
if (self->priv->active != toggle_active) {
220
self->priv->active = toggle_active;
221
g_object_notify (G_OBJECT (self), "active");
223
if (self->priv->active && ! gtk_widget_get_visible (GTK_WIDGET (self->priv->menu))) {
224
/* we get here only when the menu is activated by a key
225
* press, so that we can select the first menu item */
226
popup_menu_under_button (self, NULL);
227
gtk_menu_shell_select_first (GTK_MENU_SHELL (self->priv->menu), FALSE);
236
110
toggle_button_press_event_cb (GtkWidget *widget,
237
111
GdkEventButton *event,
240
114
GthMenuButton *self = user_data;
242
if ((event->button == 1) && (self->priv->menu != NULL)) {
243
popup_menu_under_button (self, event);
244
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
116
if (event->button == 1)
117
g_signal_emit (self, signals[SHOW_MENU], 0);
254
124
gth_menu_button_class_init (GthMenuButtonClass *klass)
256
GObjectClass *object_class;
257
GtkWidgetClass *widget_class;
126
GObjectClass *object_class;
259
128
g_type_class_add_private (klass, sizeof (GthMenuButtonPrivate));
527
380
g_return_if_fail (GTH_IS_MENU_BUTTON (self));
528
381
g_return_if_fail (GTK_IS_MENU (menu) || menu == NULL);
530
if (self->priv->menu != GTK_MENU (menu)) {
531
if ((self->priv->menu != NULL) && gtk_widget_get_visible (GTK_WIDGET (self->priv->menu)))
532
gtk_menu_shell_deactivate (GTK_MENU_SHELL (self->priv->menu));
534
self->priv->menu = GTK_MENU (menu);
536
if (self->priv->menu != NULL) {
537
g_object_add_weak_pointer (G_OBJECT (self->priv->menu), (gpointer *) &self->priv->menu);
539
gtk_widget_set_sensitive (GTK_WIDGET (self), TRUE);
540
g_signal_connect (self->priv->menu,
542
G_CALLBACK (menu_deactivate_cb),
546
gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
549
g_object_notify (G_OBJECT (self), "menu");
383
g_object_set (self, "menu", menu, NULL);
554
388
gth_menu_button_get_menu (GthMenuButton *self)
556
392
g_return_val_if_fail (GTH_IS_MENU_BUTTON (self), NULL);
558
return GTK_WIDGET (self->priv->menu);
394
g_object_get (self, "menu", &menu, NULL);