15
15
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
* This file implements an indicator button class corresponding to
22
* a single indicator object entry.
19
29
#include <gtk/gtk.h>
20
30
#include <libxfce4panel/libxfce4panel.h>
21
31
#include <libindicator/indicator-object.h>
23
33
#include "indicator-button.h"
25
static void xfce_indicator_button_finalize (GObject *object);
34
#include "indicator-button-box.h"
37
#include <libindicator/indicator-object.h>
42
//#ifndef INDICATOR_OBJECT_SIGNAL_ENTRY_SCROLLED
43
//#define INDICATOR_OBJECT_SIGNAL_ENTRY_SCROLLED "scroll-entry"
46
static void xfce_indicator_button_finalize (GObject *object);
47
static gboolean xfce_indicator_button_button_press (GtkWidget *widget,
48
GdkEventButton *event);
49
static gboolean xfce_indicator_button_button_release (GtkWidget *widget,
50
GdkEventButton *event);
51
static gboolean xfce_indicator_button_scroll_event (GtkWidget *widget,
52
GdkEventScroll *event);
53
static void xfce_indicator_button_menu_deactivate (XfceIndicatorButton *button,
55
static void xfce_indicator_button_get_preferred_width (GtkWidget *widget,
58
static void xfce_indicator_button_get_preferred_height (GtkWidget *widget,
60
gint *natural_height);
63
struct _XfceIndicatorButton
65
GtkToggleButton __parent__;
69
IndicatorObjectEntry *entry;
71
XfcePanelPlugin *plugin;
72
IndicatorConfig *config;
78
struct _XfceIndicatorButtonClass
80
GtkToggleButtonClass __parent__;
28
86
G_DEFINE_TYPE (XfceIndicatorButton, xfce_indicator_button, GTK_TYPE_TOGGLE_BUTTON)
42
108
xfce_indicator_button_init (XfceIndicatorButton *button)
44
GtkWidget *outer_container;
46
GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (button), GTK_CAN_DEFAULT | GTK_CAN_FOCUS);
110
//GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (button), GTK_CAN_DEFAULT | GTK_CAN_FOCUS);
111
gtk_widget_set_can_focus(GTK_WIDGET(button), FALSE);
112
gtk_widget_set_can_default (GTK_WIDGET (button), FALSE);
47
113
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
48
114
gtk_button_set_use_underline (GTK_BUTTON (button),TRUE);
49
115
gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
50
116
gtk_widget_set_name (GTK_WIDGET (button), "indicator-button");
118
gtk_widget_add_events (GTK_WIDGET (button), GDK_SCROLL_MASK);
52
120
button->io = NULL;
53
121
button->entry = NULL;
122
button->plugin = NULL;
123
button->config = NULL;
54
124
button->menu = NULL;
57
button->orig_icon = NULL;
59
button->orig_icon_handler = 0;
62
button->panel_size = 0;
63
button->icon_size = 24;
64
button->panel_orientation = GTK_ORIENTATION_HORIZONTAL;
65
button->orientation = GTK_ORIENTATION_HORIZONTAL;
67
outer_container = gtk_table_new (1, 1, FALSE);
68
gtk_container_add (GTK_CONTAINER (button), outer_container);
69
gtk_widget_show (outer_container);
71
button->box = xfce_hvbox_new (button->orientation, FALSE, 1);
72
gtk_table_attach (GTK_TABLE (outer_container), button->box,
74
GTK_EXPAND | GTK_SHRINK, GTK_EXPAND | GTK_SHRINK, 0, 0);
75
gtk_widget_show (button->box);
126
button->align_box = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
127
gtk_container_add (GTK_CONTAINER (button), button->align_box);
128
gtk_widget_show (button->align_box);
105
xfce_indicator_button_update_layout (XfceIndicatorButton *button)
107
GtkRequisition label_size;
109
g_return_if_fail (XFCE_IS_INDICATOR_BUTTON (button));
111
if (button->icon != NULL && button->size != 0)
113
if (button->label != NULL &&
114
button->panel_orientation == GTK_ORIENTATION_VERTICAL &&
115
button->orientation == GTK_ORIENTATION_HORIZONTAL)
117
gtk_widget_size_request (button->label, &label_size);
119
/* put icon above the label if number of rows > 1 (they look better)
120
or if they don't fit when arranged horizontally */
121
if (button->panel_size != button->size ||
122
label_size.width > button->panel_size - button->size)
123
gtk_orientable_set_orientation (GTK_ORIENTABLE (button->box), GTK_ORIENTATION_VERTICAL);
125
gtk_orientable_set_orientation (GTK_ORIENTABLE (button->box), GTK_ORIENTATION_HORIZONTAL);
128
xfce_panel_image_set_size (XFCE_PANEL_IMAGE (button->icon), button->icon_size);
135
xfce_indicator_button_update_icon (XfceIndicatorButton *button)
137
GdkPixbuf *pixbuf_s, *pixbuf_d;
141
g_return_if_fail (GTK_IS_IMAGE (button->orig_icon));
142
g_return_if_fail (XFCE_IS_PANEL_IMAGE (button->icon));
144
size = button->icon_size;
146
/* Copied from xfce_panel_image.c, try to snap to icon sizes, which minimize smoothing */
148
if (size > 16 && size < 22)
150
else if (size > 22 && size < 24)
152
else if (size > 24 && size < 32)
156
pixbuf_s = gtk_image_get_pixbuf (GTK_IMAGE (button->orig_icon));
158
if (pixbuf_s != NULL)
160
aspect = (gdouble) gdk_pixbuf_get_width (pixbuf_s) /
161
(gdouble) gdk_pixbuf_get_height (pixbuf_s);
163
pixbuf_d = gdk_pixbuf_scale_simple
164
(pixbuf_s, size, (gint) (size / aspect),
165
GDK_INTERP_BILINEAR);
167
pixbuf_d = gdk_pixbuf_scale_simple
168
(pixbuf_s, (gint) (size * aspect), size,
169
GDK_INTERP_BILINEAR);
170
xfce_panel_image_set_from_pixbuf (XFCE_PANEL_IMAGE (button->icon), pixbuf_d);
174
xfce_panel_image_set_from_source (XFCE_PANEL_IMAGE (button->icon), "image-missing");
177
xfce_panel_image_set_size (XFCE_PANEL_IMAGE (button->icon), button->icon_size);
183
154
xfce_indicator_button_set_label (XfceIndicatorButton *button,
224
167
xfce_indicator_button_set_image (XfceIndicatorButton *button,
229
170
g_return_if_fail (XFCE_IS_INDICATOR_BUTTON (button));
230
171
g_return_if_fail (GTK_IS_IMAGE (image));
232
g_debug ("indicator-button set image, image=%x\n", (uint) image);
234
if (button->orig_icon != GTK_WIDGET (image))
236
if (button->orig_icon != NULL)
238
g_signal_handler_disconnect
239
(G_OBJECT (button->orig_icon), button->orig_icon_handler);
240
g_object_unref (G_OBJECT (button->orig_icon));
243
if (button->icon != NULL)
245
gtk_container_remove (GTK_CONTAINER (button->box), button->icon);
246
g_object_unref (G_OBJECT (button->icon));
249
button->orig_icon = GTK_WIDGET (image);
250
g_object_ref (G_OBJECT (button->orig_icon));
252
button->orig_icon_handler = g_signal_connect
253
(G_OBJECT (image), "notify::pixbuf", G_CALLBACK (on_pixbuf_changed), button);
256
button->icon = xfce_panel_image_new ();
257
xfce_indicator_button_update_icon (button);
259
gtk_box_pack_start (GTK_BOX (button->box), button->icon, TRUE, FALSE, 1);
260
gtk_widget_show (button->icon);
262
xfce_indicator_button_update_layout (button);
173
indicator_button_box_set_image (XFCE_INDICATOR_BUTTON_BOX (button->box), image);
338
xfce_indicator_button_set_orientation (XfceIndicatorButton *button,
339
GtkOrientation panel_orientation,
340
GtkOrientation orientation)
342
gboolean needs_update = FALSE;
344
g_return_if_fail (XFCE_IS_INDICATOR_BUTTON (button));
346
if (button->orientation != orientation)
348
button->orientation = orientation;
350
if (button->label != NULL)
351
gtk_label_set_angle (GTK_LABEL (button->label),
352
(orientation == GTK_ORIENTATION_VERTICAL) ? -90 : 0);
356
if (button->panel_orientation != panel_orientation)
358
button->panel_orientation = panel_orientation;
364
gtk_orientable_set_orientation (GTK_ORIENTABLE (button->box), orientation);
365
xfce_indicator_button_update_layout (button);
372
xfce_indicator_button_set_size (XfceIndicatorButton *button,
376
gboolean needs_update = FALSE;
377
gint border_thickness;
381
g_return_if_fail (XFCE_IS_INDICATOR_BUTTON (button));
383
if (button->size != size)
389
if (button->panel_size != panel_size)
391
button->panel_size = panel_size;
397
style = gtk_widget_get_style (GTK_WIDGET (button));
398
border_thickness = 2 * MAX (style->xthickness, style->ythickness) + 2;
399
button->icon_size = button->size - border_thickness;
401
if (button->orig_icon != NULL)
403
xfce_indicator_button_update_icon (button);
404
xfce_indicator_button_update_layout (button);
256
xfce_indicator_button_is_small (XfceIndicatorButton *button)
258
g_return_val_if_fail (XFCE_IS_INDICATOR_BUTTON (button), FALSE);
260
return indicator_button_box_is_small (XFCE_INDICATOR_BUTTON_BOX (button->box));
267
xfce_indicator_button_get_button_border (XfceIndicatorButton *button)
269
GtkStyleContext *ctx;
270
GtkBorder padding, border;
272
g_return_val_if_fail (XFCE_IS_INDICATOR_BUTTON (button), 0);
274
ctx = gtk_widget_get_style_context (GTK_WIDGET (button));
275
gtk_style_context_get_padding (ctx, gtk_widget_get_state_flags (GTK_WIDGET (button)), &padding);
276
gtk_style_context_get_border (ctx, gtk_widget_get_state_flags (GTK_WIDGET (button)), &border);
278
return MAX (padding.left+padding.right+border.left+border.right,
279
padding.top+padding.bottom+border.top+border.bottom);
412
xfce_indicator_button_new (IndicatorObject *io,
413
IndicatorObjectEntry *entry)
284
xfce_indicator_button_new (IndicatorObject *io,
285
const gchar *io_name,
286
IndicatorObjectEntry *entry,
287
XfcePanelPlugin *plugin,
288
IndicatorConfig *config)
415
290
XfceIndicatorButton *button = g_object_new (XFCE_TYPE_INDICATOR_BUTTON, NULL);
291
g_return_val_if_fail (XFCE_IS_INDICATOR_CONFIG (config), NULL);
292
g_return_val_if_fail (XFCE_IS_PANEL_PLUGIN (plugin), NULL);
295
button->io_name = io_name;
417
296
button->entry = entry;
297
button->plugin = plugin;
298
button->config = config;
300
button->box = indicator_button_box_new (button->config);
301
//gtk_container_add (GTK_CONTAINER (button), button->box);
302
gtk_container_add (GTK_CONTAINER (button->align_box), button->box);
303
gtk_widget_show (button->box);
418
305
if (button->io != NULL)
419
306
g_object_ref (G_OBJECT (button->io));
420
307
/* IndicatorObjectEntry is not GObject */
421
308
/* g_object_ref (G_OBJECT (button->entry)); */
422
310
return GTK_WIDGET (button);
316
xfce_indicator_button_disconnect_signals (XfceIndicatorButton *button)
318
g_return_if_fail (XFCE_IS_INDICATOR_BUTTON (button));
320
if (button->menu != 0)
322
gtk_menu_popdown (button->menu);
328
xfce_indicator_button_button_press (GtkWidget *widget,
329
GdkEventButton *event)
331
XfceIndicatorButton *button = XFCE_INDICATOR_BUTTON (widget);
333
if(event->button == 1 && button->menu != NULL) /* left click only */
335
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),TRUE);
336
gtk_menu_reposition (GTK_MENU (button->menu));
337
gtk_menu_popup (button->menu, NULL, NULL,
338
xfce_panel_plugin_position_menu, button->plugin,
339
event->button, event->time);
348
xfce_indicator_button_button_release (GtkWidget *widget,
349
GdkEventButton *event)
351
XfceIndicatorButton *button = XFCE_INDICATOR_BUTTON (widget);
353
if(event->button == 2) /* middle button */
355
g_signal_emit_by_name(button->io, INDICATOR_OBJECT_SIGNAL_SECONDARY_ACTIVATE,
356
button->entry, event->time);
365
xfce_indicator_button_scroll_event (GtkWidget *widget, GdkEventScroll *event)
367
XfceIndicatorButton *button = XFCE_INDICATOR_BUTTON (widget);
369
g_signal_emit_by_name (button->io, INDICATOR_OBJECT_SIGNAL_ENTRY_SCROLLED,
370
button->entry, 1, event->direction);
377
xfce_indicator_button_menu_deactivate (XfceIndicatorButton *button,
380
g_return_if_fail (XFCE_IS_INDICATOR_BUTTON (button));
381
g_return_if_fail (GTK_IS_MENU (menu));
383
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
389
/* When can_focus is true, GtkButton allocates larger size than requested *
390
* and causes the panel image to grow indefinitely. *
391
* This workaround compensates for this difference. *
392
* Details in https://bugzilla.gnome.org/show_bug.cgi?id=698030 *
395
xfce_indicator_button_padding_correction (GtkWidget *widget)
397
GtkStyleContext *context;
402
if (!gtk_widget_get_can_focus (widget))
404
context = gtk_widget_get_style_context (widget);
405
gtk_style_context_get_style (context,
406
"focus-line-width", &focus_width,
407
"focus-padding", &focus_pad,
409
correction = (focus_width + focus_pad) * 2;
421
xfce_indicator_button_get_preferred_width (GtkWidget *widget,
427
g_return_if_fail (XFCE_IS_INDICATOR_BUTTON (widget));
429
(*GTK_WIDGET_CLASS (xfce_indicator_button_parent_class)->get_preferred_width) (widget, minimum_width, natural_width);
431
correction = xfce_indicator_button_padding_correction (widget);
433
if (minimum_width != NULL)
434
*minimum_width = MAX (1, *minimum_width - correction);
436
if (natural_width != NULL)
437
*natural_width = MAX (1, *natural_width - correction);
443
xfce_indicator_button_get_preferred_height (GtkWidget *widget,
444
gint *minimum_height,
445
gint *natural_height)
449
g_return_if_fail (XFCE_IS_INDICATOR_BUTTON (widget));
451
(*GTK_WIDGET_CLASS (xfce_indicator_button_parent_class)->get_preferred_height) (widget, minimum_height, natural_height);
453
correction = xfce_indicator_button_padding_correction (widget);
455
if (minimum_height != NULL)
456
*minimum_height = MAX (1, *minimum_height - correction);
458
if (natural_height != NULL)
459
*natural_height = MAX (1, *natural_height - correction);