~ubuntu-branches/ubuntu/precise/xfce4-panel/precise

« back to all changes in this revision

Viewing changes to libxfce4panel/xfce-arrow-button.c

  • Committer: Bazaar Package Importer
  • Author(s): Lionel Le Folgoc
  • Date: 2010-12-04 15:45:53 UTC
  • mto: (4.1.3 experimental)
  • mto: This revision was merged to the branch mainline in revision 50.
  • Revision ID: james.westby@ubuntu.com-20101204154553-f452gq02eiksf09f
Tags: upstream-4.7.5
ImportĀ upstreamĀ versionĀ 4.7.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id$
2
 
 *
3
 
 * Copyright (c) 2004-2007 Jasper Huijsmans <jasper@xfce.org>
 
1
/*
 
2
 * Copyright (C) 2006-2007 Jasper Huijsmans <jasper@xfce.org>
 
3
 * Copyright (C) 2008-2009 Nick Schermer <nick@xfce.org>
4
4
 *
5
5
 * This library is free software; you can redistribute it and/or
6
 
 * modify it under the terms of the GNU Library General Public
 
6
 * modify it under the terms of the GNU Lesser General Public
7
7
 * License as published by the Free Software Foundation; either
8
 
 * version 2 of the License, or (at your option) any later version.
 
8
 * version 2.1 of the License, or (at your option) any later version.
9
9
 *
10
10
 * This library is distributed in the hope that it will be useful,
11
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 
 * Library General Public License for more details.
 
13
 * Lesser General Public License for more details.
14
14
 *
15
 
 * You should have received a copy of the GNU Library General Public
16
 
 * License along with this library; if not, write to the
17
 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
 
 * Boston, MA 02111-1307, USA.
 
15
 * You should have received a copy of the GNU Lesser General Public
 
16
 * License along with this library; if not, write to the Free Software
 
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
18
 */
20
19
 
21
20
#ifdef HAVE_CONFIG_H
30
29
#endif
31
30
 
32
31
#include <gtk/gtk.h>
33
 
#include <libxfce4panel/libxfce4panel-marshal.h>
 
32
 
 
33
#include <common/panel-private.h>
34
34
#include <libxfce4panel/xfce-panel-macros.h>
35
 
#include <libxfce4panel/libxfce4panel-enum-types.h>
36
35
#include <libxfce4panel/xfce-arrow-button.h>
37
36
#include <libxfce4panel/libxfce4panel-alias.h>
38
37
 
39
 
#define ARROW_WIDTH          8
40
 
#define ARROW_PADDING        2
41
 
#define DEFAULT_ARROW_TYPE   GTK_ARROW_UP
42
 
 
43
 
 
44
 
#ifndef _
45
 
#define _(x) (x)
46
 
#endif
47
 
 
48
 
enum
49
 
{
50
 
    ARROW_TYPE_CHANGED,
51
 
    LAST_SIGNAL
52
 
};
53
 
 
54
 
enum
55
 
{
56
 
    PROP_0,
57
 
    PROP_ARROW_TYPE
58
 
};
59
 
 
60
 
static void   xfce_arrow_button_class_init    (XfceArrowButtonClass  *klass);
61
 
static void   xfce_arrow_button_init          (XfceArrowButton       *button);
62
 
static void   xfce_arrow_button_set_property  (GObject               *object,
63
 
                                               guint                  prop_id,
64
 
                                               const GValue          *value,
65
 
                                               GParamSpec            *pspec);
66
 
static void   xfce_arrow_button_get_property  (GObject               *object,
67
 
                                               guint                  prop_id,
68
 
                                               GValue                *value,
69
 
                                               GParamSpec            *pspec);
70
 
static gint   xfce_arrow_button_expose        (GtkWidget             *widget,
71
 
                                               GdkEventExpose        *event);
72
 
static void   xfce_arrow_button_size_request  (GtkWidget             *widget,
73
 
                                               GtkRequisition        *requisition);
74
 
static void   xfce_arrow_button_add           (GtkContainer          *container,
75
 
                                               GtkWidget             *child);
76
 
static GType  xfce_arrow_button_child_type    (GtkContainer          *container);
77
 
 
78
 
 
79
 
 
80
 
/* global vars */
81
 
static GtkToggleButtonClass *parent_class = NULL;
82
 
static guint                 arrow_button_signals[LAST_SIGNAL] = { 0 };
83
 
 
84
 
 
85
 
 
86
 
GType
87
 
xfce_arrow_button_get_type (void)
88
 
{
89
 
    static GtkType type = G_TYPE_INVALID;
90
 
 
91
 
    if (G_UNLIKELY (type == G_TYPE_INVALID))
92
 
    {
93
 
        type = _panel_g_type_register_simple (GTK_TYPE_TOGGLE_BUTTON,
94
 
                                              "XfceArrowButton",
95
 
                                              sizeof (XfceArrowButtonClass),
96
 
                                              xfce_arrow_button_class_init,
97
 
                                              sizeof (XfceArrowButton),
98
 
                                              xfce_arrow_button_init);
99
 
    }
100
 
 
101
 
    return type;
102
 
}
 
38
 
 
39
 
 
40
/**
 
41
 * SECTION: xfce-arrow-button
 
42
 * @title: XfceArrowButton
 
43
 * @short_description: Toggle button with arrow
 
44
 * @include: libxfce4panel/libxfce4panel.h
 
45
 *
 
46
 * Toggle button with (optional) arrow. The arrow direction will be
 
47
 * inverted when the button is toggled.
 
48
 * Since 4.8 it is also possible to make the button blink and pack additional
 
49
 * widgets in the button, using gtk_container_add().
 
50
 **/
 
51
 
 
52
 
 
53
 
 
54
#define ARROW_WIDTH        (8)
 
55
#define MAX_BLINKING_COUNT (16)
 
56
 
 
57
enum
 
58
{
 
59
  ARROW_TYPE_CHANGED,
 
60
  LAST_SIGNAL
 
61
};
 
62
 
 
63
enum
 
64
{
 
65
  PROP_0,
 
66
  PROP_ARROW_TYPE
 
67
};
 
68
 
 
69
static void     xfce_arrow_button_set_property  (GObject               *object,
 
70
                                                 guint                  prop_id,
 
71
                                                 const GValue          *value,
 
72
                                                 GParamSpec            *pspec);
 
73
static void     xfce_arrow_button_get_property  (GObject               *object,
 
74
                                                 guint                  prop_id,
 
75
                                                 GValue                *value,
 
76
                                                 GParamSpec            *pspec);
 
77
static void     xfce_arrow_button_finalize      (GObject               *object);
 
78
static gboolean xfce_arrow_button_expose_event  (GtkWidget             *widget,
 
79
                                                 GdkEventExpose        *event);
 
80
static void     xfce_arrow_button_size_request  (GtkWidget             *widget,
 
81
                                                 GtkRequisition        *requisition);
 
82
static void     xfce_arrow_button_size_allocate (GtkWidget             *widget,
 
83
                                                 GtkAllocation         *allocation);
 
84
 
 
85
 
 
86
 
 
87
struct _XfceArrowButtonPrivate
 
88
{
 
89
  /* arrow type of the button */
 
90
  GtkArrowType   arrow_type;
 
91
 
 
92
  /* blinking timeout id */
 
93
  guint          blinking_timeout_id;
 
94
 
 
95
  /* counter to make the blinking stop when
 
96
   * MAX_BLINKING_COUNT is reached */
 
97
  guint          blinking_counter;
 
98
 
 
99
  /* button relief when the blinking starts */
 
100
  GtkReliefStyle last_relief;
 
101
};
 
102
 
 
103
 
 
104
 
 
105
static guint arrow_button_signals[LAST_SIGNAL];
 
106
 
 
107
 
 
108
 
 
109
G_DEFINE_TYPE (XfceArrowButton, xfce_arrow_button, GTK_TYPE_TOGGLE_BUTTON)
103
110
 
104
111
 
105
112
 
106
113
static void
107
114
xfce_arrow_button_class_init (XfceArrowButtonClass * klass)
108
115
{
109
 
    GObjectClass      *gobject_class;
110
 
    GtkWidgetClass    *widget_class;
111
 
    GtkContainerClass *container_class;
112
 
 
113
 
    parent_class = g_type_class_peek_parent (klass);
114
 
 
115
 
    gobject_class = G_OBJECT_CLASS (klass);
116
 
    gobject_class->get_property = xfce_arrow_button_get_property;
117
 
    gobject_class->set_property = xfce_arrow_button_set_property;
118
 
 
119
 
    widget_class = GTK_WIDGET_CLASS (klass);
120
 
    widget_class->expose_event  = xfce_arrow_button_expose;
121
 
    widget_class->size_request  = xfce_arrow_button_size_request;
122
 
 
123
 
    container_class = GTK_CONTAINER_CLASS (klass);
124
 
    container_class->add        = xfce_arrow_button_add;
125
 
    container_class->child_type = xfce_arrow_button_child_type;
126
 
 
127
 
    /* signals */
128
 
 
129
 
    /**
130
 
    * XfceArrowButton::arrow-type-changed
131
 
    * @button: the object which emitted the signal
132
 
    * @type: the new #GtkArrowType of the button
133
 
    *
134
 
    * Emitted when the arrow direction of the menu button changes.
135
 
    * This value also determines the direction of the popup menu.
136
 
    **/
137
 
    arrow_button_signals[ARROW_TYPE_CHANGED] =
138
 
        g_signal_new (I_("arrow-type-changed"),
139
 
                      G_OBJECT_CLASS_TYPE (klass),
140
 
                      G_SIGNAL_RUN_FIRST,
141
 
                      G_STRUCT_OFFSET (XfceArrowButtonClass, arrow_type_changed),
142
 
                      NULL, NULL,
143
 
                      g_cclosure_marshal_VOID__ENUM,
144
 
                      G_TYPE_NONE, 1, GTK_TYPE_ARROW_TYPE);
145
 
 
146
 
    /* properties */
147
 
 
148
 
    /**
149
 
     * XfceArrowButton:arrow-type
150
 
     *
151
 
     * The arrow type of the button. This value also determines the direction
152
 
     * of the popup menu.
153
 
     **/
154
 
    g_object_class_install_property (gobject_class,
155
 
                                     PROP_ARROW_TYPE,
156
 
                                     g_param_spec_enum ("arrow-type",
157
 
                                                        "Arrow type",
158
 
                                                        "The arrow type of the menu button",
159
 
                                                        GTK_TYPE_ARROW_TYPE,
160
 
                                                        GTK_ARROW_UP,
161
 
                                                        PANEL_PARAM_READWRITE));
 
116
  GObjectClass   *gobject_class;
 
117
  GtkWidgetClass *gtkwidget_class;
 
118
 
 
119
  g_type_class_add_private (klass, sizeof (XfceArrowButtonPrivate));
 
120
 
 
121
  gobject_class = G_OBJECT_CLASS (klass);
 
122
  gobject_class->get_property = xfce_arrow_button_get_property;
 
123
  gobject_class->set_property = xfce_arrow_button_set_property;
 
124
  gobject_class->finalize = xfce_arrow_button_finalize;
 
125
 
 
126
  gtkwidget_class = GTK_WIDGET_CLASS (klass);
 
127
  gtkwidget_class->expose_event = xfce_arrow_button_expose_event;
 
128
  gtkwidget_class->size_request = xfce_arrow_button_size_request;
 
129
  gtkwidget_class->size_allocate = xfce_arrow_button_size_allocate;
 
130
 
 
131
  /**
 
132
   * XfceArrowButton::arrow-type-changed
 
133
   * @button: the object which emitted the signal
 
134
   * @type: the new #GtkArrowType of the button
 
135
   *
 
136
   * Emitted when the arrow direction of the menu button changes.
 
137
   * This value also determines the direction of the popup menu.
 
138
   **/
 
139
  arrow_button_signals[ARROW_TYPE_CHANGED] =
 
140
      g_signal_new (g_intern_static_string ("arrow-type-changed"),
 
141
                    G_OBJECT_CLASS_TYPE (klass),
 
142
                    G_SIGNAL_RUN_LAST,
 
143
                    G_STRUCT_OFFSET (XfceArrowButtonClass, arrow_type_changed),
 
144
                    NULL, NULL,
 
145
                    g_cclosure_marshal_VOID__ENUM,
 
146
                    G_TYPE_NONE, 1, GTK_TYPE_ARROW_TYPE);
 
147
 
 
148
  /**
 
149
   * XfceArrowButton:arrow-type
 
150
   *
 
151
   * The arrow type of the button. This value also determines the direction
 
152
   * of the popup menu.
 
153
   **/
 
154
  g_object_class_install_property (gobject_class,
 
155
                                   PROP_ARROW_TYPE,
 
156
                                   g_param_spec_enum ("arrow-type",
 
157
                                                      "Arrow type",
 
158
                                                      "The arrow type of the menu button",
 
159
                                                      GTK_TYPE_ARROW_TYPE,
 
160
                                                      GTK_ARROW_UP,
 
161
                                                      G_PARAM_READWRITE
 
162
                                                      | G_PARAM_STATIC_STRINGS));
162
163
}
163
164
 
164
165
 
165
166
 
166
167
static void
167
 
xfce_arrow_button_init (XfceArrowButton * arrow_button)
 
168
xfce_arrow_button_init (XfceArrowButton *button)
168
169
{
169
 
    GTK_WIDGET_SET_FLAGS (GTK_WIDGET (arrow_button), GTK_NO_WINDOW);
170
 
 
171
 
    arrow_button->arrow_type = DEFAULT_ARROW_TYPE;
 
170
  button->priv = G_TYPE_INSTANCE_GET_PRIVATE (button, XFCE_TYPE_ARROW_BUTTON, XfceArrowButtonPrivate);
 
171
 
 
172
  /* initialize button values */
 
173
  button->priv->arrow_type = GTK_ARROW_UP;
 
174
  button->priv->blinking_timeout_id = 0;
 
175
  button->priv->blinking_counter = 0;
 
176
  button->priv->last_relief = GTK_RELIEF_NORMAL;
 
177
 
 
178
  /* set some widget properties */
 
179
  GTK_WIDGET_SET_FLAGS (GTK_WIDGET (button), GTK_NO_WINDOW);
 
180
  GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_DEFAULT | GTK_CAN_FOCUS);
 
181
  gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
172
182
}
173
183
 
174
184
 
179
189
                                const GValue *value,
180
190
                                GParamSpec   *pspec)
181
191
{
182
 
    XfceArrowButton *button = XFCE_ARROW_BUTTON (object);
 
192
  XfceArrowButton *button = XFCE_ARROW_BUTTON (object);
183
193
 
184
 
    switch (prop_id)
 
194
  switch (prop_id)
185
195
    {
186
 
        case PROP_ARROW_TYPE:
187
 
            xfce_arrow_button_set_arrow_type (button, g_value_get_enum (value));
188
 
            break;
189
 
        default:
190
 
            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
191
 
            break;
 
196
    case PROP_ARROW_TYPE:
 
197
      xfce_arrow_button_set_arrow_type (button, g_value_get_enum (value));
 
198
      break;
 
199
 
 
200
    default:
 
201
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
202
      break;
192
203
    }
193
204
}
194
205
 
200
211
                                GValue     *value,
201
212
                                GParamSpec *pspec)
202
213
{
203
 
    XfceArrowButton *button = XFCE_ARROW_BUTTON (object);
204
 
 
205
 
    switch (prop_id)
206
 
    {
207
 
        case PROP_ARROW_TYPE:
208
 
            g_value_set_enum (value, button->arrow_type);
209
 
            break;
210
 
        default:
211
 
            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
212
 
            break;
213
 
    }
214
 
}
215
 
 
216
 
 
217
 
 
218
 
static gint
219
 
xfce_arrow_button_expose (GtkWidget      *widget,
220
 
                          GdkEventExpose *event)
221
 
{
222
 
    gint x, y, w;
223
 
 
224
 
    if (G_LIKELY (GTK_WIDGET_DRAWABLE (widget)))
225
 
    {
226
 
        w = MIN (widget->allocation.height - 2 * widget->style->ythickness,
227
 
                 widget->allocation.width  - 2 * widget->style->xthickness);
228
 
        w = MIN (w, ARROW_WIDTH);
229
 
 
230
 
        x = widget->allocation.x + (widget->allocation.width - w) / 2;
231
 
        y = widget->allocation.y + (widget->allocation.height - w) / 2;
232
 
 
233
 
        GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
234
 
 
235
 
        gtk_paint_arrow (widget->style, widget->window,
236
 
                         GTK_WIDGET_STATE (widget), GTK_SHADOW_NONE,
237
 
                         &(event->area), widget, "xfce_arrow_button",
238
 
                         XFCE_ARROW_BUTTON (widget)->arrow_type, FALSE,
239
 
                         x, y, w, w);
240
 
    }
241
 
 
242
 
    return TRUE;
 
214
  XfceArrowButton *button = XFCE_ARROW_BUTTON (object);
 
215
 
 
216
  switch (prop_id)
 
217
    {
 
218
    case PROP_ARROW_TYPE:
 
219
      g_value_set_enum (value, xfce_arrow_button_get_arrow_type (button));
 
220
      break;
 
221
 
 
222
    default:
 
223
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
224
      break;
 
225
    }
 
226
}
 
227
 
 
228
 
 
229
 
 
230
static void
 
231
xfce_arrow_button_finalize (GObject *object)
 
232
{
 
233
  XfceArrowButton *button = XFCE_ARROW_BUTTON (object);
 
234
 
 
235
  if (button->priv->blinking_timeout_id != 0)
 
236
    g_source_remove (button->priv->blinking_timeout_id);
 
237
 
 
238
  (*G_OBJECT_CLASS (xfce_arrow_button_parent_class)->finalize) (object);
 
239
}
 
240
 
 
241
 
 
242
 
 
243
static gboolean
 
244
xfce_arrow_button_expose_event (GtkWidget      *widget,
 
245
                                GdkEventExpose *event)
 
246
{
 
247
  XfceArrowButton *button = XFCE_ARROW_BUTTON (widget);
 
248
  GtkWidget       *child;
 
249
  gint             x, y, width;
 
250
 
 
251
  /* draw the button */
 
252
  (*GTK_WIDGET_CLASS (xfce_arrow_button_parent_class)->expose_event) (widget, event);
 
253
 
 
254
  if (button->priv->arrow_type != GTK_ARROW_NONE
 
255
      && GTK_WIDGET_DRAWABLE (widget))
 
256
    {
 
257
      child = gtk_bin_get_child (GTK_BIN (widget));
 
258
      if (child != NULL && GTK_WIDGET_VISIBLE (child))
 
259
        {
 
260
          if (button->priv->arrow_type == GTK_ARROW_UP
 
261
              || button->priv->arrow_type == GTK_ARROW_DOWN)
 
262
            {
 
263
              width = ARROW_WIDTH;
 
264
              x = widget->allocation.x + widget->style->xthickness;
 
265
              y = widget->allocation.y + (widget->allocation.height - width) / 2;
 
266
            }
 
267
          else
 
268
            {
 
269
              width = ARROW_WIDTH;
 
270
              x = widget->allocation.x + (widget->allocation.width - width) / 2;
 
271
              y = widget->allocation.y + widget->style->ythickness;
 
272
            }
 
273
        }
 
274
      else
 
275
        {
 
276
          width = MIN (widget->allocation.height - 2 * widget->style->ythickness,
 
277
                       widget->allocation.width  - 2 * widget->style->xthickness);
 
278
          width = CLAMP (width, 1, ARROW_WIDTH);
 
279
 
 
280
          x = widget->allocation.x + (widget->allocation.width - width) / 2;
 
281
          y = widget->allocation.y + (widget->allocation.height - width) / 2;
 
282
        }
 
283
 
 
284
      gtk_paint_arrow (widget->style, widget->window,
 
285
                       GTK_WIDGET_STATE (widget), GTK_SHADOW_NONE,
 
286
                       &(event->area), widget, "xfce_arrow_button",
 
287
                       button->priv->arrow_type, FALSE,
 
288
                       x, y, width, width);
 
289
    }
 
290
 
 
291
  return TRUE;
243
292
}
244
293
 
245
294
 
248
297
xfce_arrow_button_size_request (GtkWidget      *widget,
249
298
                                GtkRequisition *requisition)
250
299
{
251
 
    gint size = ARROW_WIDTH + ARROW_PADDING +
252
 
                2 * MAX (widget->style->xthickness, widget->style->ythickness);
253
 
 
254
 
    requisition->width = requisition->height = size;
255
 
}
256
 
 
257
 
 
258
 
 
259
 
static void
260
 
xfce_arrow_button_add (GtkContainer *container,
261
 
                       GtkWidget    *child)
262
 
{
263
 
    g_warning ("XfceArrowButton cannot contain any children");
264
 
}
265
 
 
266
 
 
267
 
 
268
 
static GType
269
 
xfce_arrow_button_child_type (GtkContainer *container)
270
 
{
271
 
    return GTK_TYPE_NONE;
272
 
}
273
 
 
274
 
 
275
 
 
276
 
/* public interface */
 
300
  XfceArrowButton *button = XFCE_ARROW_BUTTON (widget);
 
301
  GtkWidget *child;
 
302
 
 
303
  child = gtk_bin_get_child (GTK_BIN (widget));
 
304
  if (child != NULL && GTK_WIDGET_VISIBLE (child))
 
305
    {
 
306
      /* use gtk for the widget size */
 
307
      (*GTK_WIDGET_CLASS (xfce_arrow_button_parent_class)->size_request) (widget, requisition);
 
308
 
 
309
      /* reserve space for the arrow */
 
310
      switch (button->priv->arrow_type)
 
311
        {
 
312
        case GTK_ARROW_UP:
 
313
        case GTK_ARROW_DOWN:
 
314
          requisition->width += ARROW_WIDTH;
 
315
          break;
 
316
 
 
317
        case GTK_ARROW_LEFT:
 
318
        case GTK_ARROW_RIGHT:
 
319
          requisition->height += ARROW_WIDTH;
 
320
          break;
 
321
 
 
322
        default:
 
323
          break;
 
324
        }
 
325
    }
 
326
  else if (button->priv->arrow_type != GTK_ARROW_NONE)
 
327
    {
 
328
      requisition->height = ARROW_WIDTH + 2 * widget->style->xthickness;
 
329
      requisition->width = ARROW_WIDTH + 2 * widget->style->ythickness;
 
330
    }
 
331
}
 
332
 
 
333
 
 
334
 
 
335
static void
 
336
xfce_arrow_button_size_allocate (GtkWidget     *widget,
 
337
                                 GtkAllocation *allocation)
 
338
{
 
339
  XfceArrowButton *button = XFCE_ARROW_BUTTON (widget);
 
340
  GtkWidget       *child;
 
341
  GtkAllocation    child_allocation;
 
342
 
 
343
  /* allocate the button */
 
344
  (*GTK_WIDGET_CLASS (xfce_arrow_button_parent_class)->size_allocate) (widget, allocation);
 
345
 
 
346
  if (button->priv->arrow_type != GTK_ARROW_NONE)
 
347
    {
 
348
      child = gtk_bin_get_child (GTK_BIN (widget));
 
349
      if (child != NULL && GTK_WIDGET_VISIBLE (child))
 
350
        {
 
351
          /* copy the child allocation */
 
352
          child_allocation = child->allocation;
 
353
 
 
354
          /* update the allocation to make space for the arrow */
 
355
          switch (button->priv->arrow_type)
 
356
            {
 
357
            case GTK_ARROW_LEFT:
 
358
            case GTK_ARROW_RIGHT:
 
359
              child_allocation.height -= ARROW_WIDTH;
 
360
              child_allocation.y += ARROW_WIDTH;
 
361
              break;
 
362
 
 
363
            default:
 
364
              child_allocation.width -= ARROW_WIDTH;
 
365
              child_allocation.x += ARROW_WIDTH;
 
366
              break;
 
367
            }
 
368
 
 
369
          /* set the child allocation again */
 
370
          gtk_widget_size_allocate (child, &child_allocation);
 
371
        }
 
372
    }
 
373
}
 
374
 
 
375
 
 
376
 
 
377
static gboolean
 
378
xfce_arrow_button_blinking_timeout (gpointer user_data)
 
379
{
 
380
  XfceArrowButton *button = XFCE_ARROW_BUTTON (user_data);
 
381
  GtkStyle        *style;
 
382
  GtkRcStyle      *rc;
 
383
 
 
384
  rc = gtk_widget_get_modifier_style (GTK_WIDGET (button));
 
385
  if(PANEL_HAS_FLAG (rc->color_flags[GTK_STATE_NORMAL], GTK_RC_BG)
 
386
     || button->priv->blinking_timeout_id == 0)
 
387
    {
 
388
      gtk_button_set_relief (GTK_BUTTON (button), button->priv->last_relief);
 
389
      PANEL_UNSET_FLAG (rc->color_flags[GTK_STATE_NORMAL], GTK_RC_BG);
 
390
      gtk_widget_modify_style (GTK_WIDGET (button), rc);
 
391
    }
 
392
  else
 
393
    {
 
394
      gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NORMAL);
 
395
      PANEL_SET_FLAG (rc->color_flags[GTK_STATE_NORMAL], GTK_RC_BG);
 
396
      style = gtk_widget_get_style (GTK_WIDGET (button));
 
397
      rc->bg[GTK_STATE_NORMAL] = style->bg[GTK_STATE_SELECTED];
 
398
      gtk_widget_modify_style(GTK_WIDGET (button), rc);
 
399
    }
 
400
 
 
401
  return (button->priv->blinking_counter++ < MAX_BLINKING_COUNT);
 
402
}
 
403
 
 
404
 
 
405
 
 
406
static void
 
407
xfce_arrow_button_blinking_timeout_destroyed (gpointer user_data)
 
408
{
 
409
  XfceArrowButton *button = XFCE_ARROW_BUTTON (user_data);
 
410
 
 
411
  button->priv->blinking_timeout_id = 0;
 
412
  button->priv->blinking_counter = 0;
 
413
}
 
414
 
 
415
 
277
416
 
278
417
/**
279
418
 * xfce_arrow_button_new:
280
 
 * @type : #GtkArrowType for the arrow button
 
419
 * @arrow_type : #GtkArrowType for the arrow button
281
420
 *
282
421
 * Creates a new #XfceArrowButton widget.
283
422
 *
284
423
 * Returns: The newly created #XfceArrowButton widget.
285
424
 **/
286
425
GtkWidget *
287
 
xfce_arrow_button_new (GtkArrowType type)
288
 
{
289
 
    return g_object_new (XFCE_TYPE_ARROW_BUTTON, "arrow-type", type, NULL);
290
 
}
291
 
 
292
 
 
293
 
 
294
 
/**
295
 
 * xfce_arrow_button_set_arrow_type:
296
 
 * @button : a #XfceArrowButton
297
 
 * @type   : a valid  #GtkArrowType
298
 
 *
299
 
 * Sets the arrow type for @button.
300
 
 **/
301
 
void
302
 
xfce_arrow_button_set_arrow_type (XfceArrowButton *button,
303
 
                                  GtkArrowType     type)
304
 
{
305
 
    _panel_return_if_fail (XFCE_IS_ARROW_BUTTON (button));
306
 
 
307
 
    button->arrow_type = type;
308
 
 
309
 
    g_signal_emit (button, arrow_button_signals[ARROW_TYPE_CHANGED], 0, type);
310
 
 
311
 
    g_object_notify (G_OBJECT (button), "arrow_type");
312
 
 
313
 
    gtk_widget_queue_draw (GTK_WIDGET (button));
 
426
xfce_arrow_button_new (GtkArrowType arrow_type)
 
427
{
 
428
  return g_object_new (XFCE_TYPE_ARROW_BUTTON,
 
429
                       "arrow-type", arrow_type,
 
430
                       NULL);
314
431
}
315
432
 
316
433
 
326
443
GtkArrowType
327
444
xfce_arrow_button_get_arrow_type (XfceArrowButton *button)
328
445
{
329
 
    _panel_return_val_if_fail (XFCE_IS_ARROW_BUTTON (button), DEFAULT_ARROW_TYPE);
330
 
 
331
 
    return button->arrow_type;
 
446
  g_return_val_if_fail (XFCE_IS_ARROW_BUTTON (button), GTK_ARROW_UP);
 
447
  return button->priv->arrow_type;
 
448
}
 
449
 
 
450
 
 
451
 
 
452
/**
 
453
 * xfce_arrow_button_set_arrow_type:
 
454
 * @button     : a #XfceArrowButton
 
455
 * @arrow_type : a valid  #GtkArrowType
 
456
 *
 
457
 * Sets the arrow type for @button.
 
458
 **/
 
459
void
 
460
xfce_arrow_button_set_arrow_type (XfceArrowButton *button,
 
461
                                  GtkArrowType     arrow_type)
 
462
{
 
463
  g_return_if_fail (XFCE_IS_ARROW_BUTTON (button));
 
464
 
 
465
  if (G_LIKELY (button->priv->arrow_type != arrow_type))
 
466
    {
 
467
      /* store the new arrow type */
 
468
      button->priv->arrow_type = arrow_type;
 
469
 
 
470
      /* emit signal */
 
471
      g_signal_emit (G_OBJECT (button),
 
472
                     arrow_button_signals[ARROW_TYPE_CHANGED],
 
473
                     0, arrow_type);
 
474
 
 
475
      /* notify property change */
 
476
      g_object_notify (G_OBJECT (button), "arrow-type");
 
477
 
 
478
      /* redraw the arrow button */
 
479
      gtk_widget_queue_resize (GTK_WIDGET (button));
 
480
    }
 
481
}
 
482
 
 
483
 
 
484
 
 
485
/**
 
486
 * xfce_arrow_button_get_blinking:
 
487
 * @button : a #XfceArrowButton
 
488
 *
 
489
 * Whether the button is blinking. If the blink timeout is finished
 
490
 * and the button is still highlighted, this functions returns %FALSE.
 
491
 *
 
492
 * Returns: %TRUE when @button is blinking.
 
493
 *
 
494
 * Since: 4.8
 
495
 **/
 
496
gboolean
 
497
xfce_arrow_button_get_blinking (XfceArrowButton *button)
 
498
{
 
499
  g_return_val_if_fail (XFCE_IS_ARROW_BUTTON (button), FALSE);
 
500
  return !!(button->priv->blinking_timeout_id != 0);
 
501
}
 
502
 
 
503
 
 
504
 
 
505
/**
 
506
 * xfce_arrow_button_set_blinking:
 
507
 * @button   : a #XfceArrowButton
 
508
 * @blinking : %TRUE when the button should start blinking, %FALSE to
 
509
 *             stop the blinking.
 
510
 *
 
511
 * Make the button blink.
 
512
 *
 
513
 * Since: 4.8
 
514
 **/
 
515
void
 
516
xfce_arrow_button_set_blinking (XfceArrowButton *button,
 
517
                                gboolean         blinking)
 
518
{
 
519
  g_return_if_fail (XFCE_IS_ARROW_BUTTON (button));
 
520
 
 
521
  if (blinking)
 
522
    {
 
523
      /* store the relief of the button */
 
524
      button->priv->last_relief = gtk_button_get_relief (GTK_BUTTON (button));
 
525
 
 
526
      if (button->priv->blinking_timeout_id == 0)
 
527
        {
 
528
          /* start blinking timeout */
 
529
          button->priv->blinking_timeout_id =
 
530
              g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, 500,
 
531
                                  xfce_arrow_button_blinking_timeout, button,
 
532
                                  xfce_arrow_button_blinking_timeout_destroyed);
 
533
        }
 
534
    }
 
535
  else if (button->priv->blinking_timeout_id != 0)
 
536
    {
 
537
      /* stop the blinking timeout */
 
538
      g_source_remove (button->priv->blinking_timeout_id);
 
539
    }
 
540
 
 
541
  /* start with a blinking or make sure the button is normal */
 
542
  xfce_arrow_button_blinking_timeout (button);
332
543
}
333
544
 
334
545
 
335
546
 
336
547
#define __XFCE_ARROW_BUTTON_C__
337
548
#include <libxfce4panel/libxfce4panel-aliasdef.c>
338