~ubuntu-branches/debian/sid/xfce4-indicator-plugin/sid

« back to all changes in this revision

Viewing changes to panel-plugin/indicator-box.c

  • Committer: Package Import Robot
  • Author(s): Evgeni Golov, Yves-Alexis Perez
  • Date: 2012-05-05 15:54:41 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20120505155441-720vom0wcnhtcg0z
Tags: 0.5.0-1
[ Yves-Alexis Perez ]
* New upstream release.
* debian/rules:
  - build with --parallel.
* debian/control:
  - update debhelper build-dep to 9.
  - add build-dep on exo and xfconf.
  - update standards version to 3.9.3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  Copyright (c) 2012 Andrzej <ndrwrdck@gmail.com>
 
2
 *
 
3
 *  This program is free software; you can redistribute it and/or modify
 
4
 *  it under the terms of the GNU General Public License as published by
 
5
 *  the Free Software Foundation; either version 2 of the License, or
 
6
 *  (at your option) any later version.
 
7
 *
 
8
 *  This program is distributed in the hope that it will be useful,
 
9
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 *  GNU Library General Public License for more details.
 
12
 *
 
13
 *  You should have received a copy of the GNU General Public License
 
14
 *  along with this program; if not, write to the Free Software
 
15
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
16
 */
 
17
 
 
18
#include <glib.h>
 
19
#include <gtk/gtk.h>
 
20
#include <exo/exo.h>
 
21
#include <libxfce4panel/libxfce4panel.h>
 
22
#include <libindicator/indicator-object.h>
 
23
 
 
24
#include "indicator-box.h"
 
25
#include "indicator-button.h"
 
26
 
 
27
static void                 xfce_indicator_box_finalize       (GObject          *object);
 
28
static void                 xfce_indicator_box_get_property   (GObject          *object,
 
29
                                                               guint             prop_id,
 
30
                                                               GValue           *value,
 
31
                                                               GParamSpec       *pspec);
 
32
static void                 xfce_indicator_box_set_property   (GObject          *object,
 
33
                                                               guint             prop_id,
 
34
                                                               const GValue     *value,
 
35
                                                               GParamSpec       *pspec);
 
36
static void                 xfce_indicator_box_add            (GtkContainer     *container,
 
37
                                                               GtkWidget        *child);
 
38
static void                 xfce_indicator_box_remove         (GtkContainer     *container,
 
39
                                                               GtkWidget        *child);
 
40
static void                 xfce_indicator_box_forall         (GtkContainer     *container,
 
41
                                                               gboolean          include_internals,
 
42
                                                               GtkCallback       callback,
 
43
                                                               gpointer          callback_data);
 
44
static GType                xfce_indicator_box_child_type     (GtkContainer     *container);
 
45
static void                 xfce_indicator_box_size_request   (GtkWidget        *widget,
 
46
                                                               GtkRequisition   *requisition);
 
47
static void                 xfce_indicator_box_size_allocate  (GtkWidget        *widget,
 
48
                                                               GtkAllocation    *allocation);
 
49
static gint                 xfce_indicator_box_get_row_size   (XfceIndicatorBox *box);
 
50
 
 
51
 
 
52
enum
 
53
{
 
54
  PROP_0,
 
55
  PROP_ICON_SIZE_MAX
 
56
};
 
57
 
 
58
G_DEFINE_TYPE (XfceIndicatorBox, xfce_indicator_box, GTK_TYPE_CONTAINER)
 
59
 
 
60
static void
 
61
xfce_indicator_box_class_init (XfceIndicatorBoxClass *klass)
 
62
{
 
63
  GObjectClass      *gobject_class;
 
64
  GtkWidgetClass    *gtkwidget_class;
 
65
  GtkContainerClass *gtkcontainer_class;
 
66
 
 
67
  gobject_class = G_OBJECT_CLASS (klass);
 
68
  gobject_class->finalize = xfce_indicator_box_finalize;
 
69
  gobject_class->get_property = xfce_indicator_box_get_property;
 
70
  gobject_class->set_property = xfce_indicator_box_set_property;
 
71
 
 
72
  gtkwidget_class = GTK_WIDGET_CLASS (klass);
 
73
  gtkwidget_class->size_request = xfce_indicator_box_size_request;
 
74
  gtkwidget_class->size_allocate = xfce_indicator_box_size_allocate;
 
75
 
 
76
  gtkcontainer_class = GTK_CONTAINER_CLASS (klass);
 
77
  gtkcontainer_class->add = xfce_indicator_box_add;
 
78
  gtkcontainer_class->remove = xfce_indicator_box_remove;
 
79
  gtkcontainer_class->forall = xfce_indicator_box_forall;
 
80
  gtkcontainer_class->child_type = xfce_indicator_box_child_type;
 
81
 
 
82
  g_object_class_install_property (gobject_class,
 
83
                                   PROP_ICON_SIZE_MAX,
 
84
                                   g_param_spec_uint ("icon-size-max",
 
85
                                                      NULL, NULL,
 
86
                                                      1,
 
87
                                                      128,
 
88
                                                      24,
 
89
                                                      EXO_PARAM_READWRITE));
 
90
}
 
91
 
 
92
 
 
93
 
 
94
static void
 
95
xfce_indicator_box_init (XfceIndicatorBox *box)
 
96
{
 
97
  GTK_WIDGET_SET_FLAGS (box, GTK_NO_WINDOW);
 
98
 
 
99
  gtk_widget_set_can_focus(GTK_WIDGET(box), TRUE);
 
100
  gtk_container_set_border_width(GTK_CONTAINER(box), 0);
 
101
 
 
102
  box->children = NULL;
 
103
 
 
104
  box->nrows = 1;
 
105
  box->icon_size_max = 24;
 
106
  box->panel_size = 16;
 
107
  box->panel_orientation = GTK_ORIENTATION_HORIZONTAL;
 
108
  box->orientation = GTK_ORIENTATION_HORIZONTAL;
 
109
}
 
110
 
 
111
 
 
112
 
 
113
static void
 
114
xfce_indicator_box_finalize (GObject *object)
 
115
{
 
116
  XfceIndicatorBox *box = XFCE_INDICATOR_BOX (object);
 
117
 
 
118
  if (box->children != NULL)
 
119
    {
 
120
      g_slist_free (box->children);
 
121
      g_debug ("Not all icons have been removed from the indicator icon box.");
 
122
    }
 
123
 
 
124
  G_OBJECT_CLASS (xfce_indicator_box_parent_class)->finalize (object);
 
125
}
 
126
 
 
127
 
 
128
 
 
129
static void
 
130
xfce_indicator_box_get_property (GObject    *object,
 
131
                                 guint       prop_id,
 
132
                                 GValue     *value,
 
133
                                 GParamSpec *pspec)
 
134
{
 
135
  XfceIndicatorBox *box = XFCE_INDICATOR_BOX (object);
 
136
  GPtrArray        *array;
 
137
 
 
138
  switch (prop_id)
 
139
    {
 
140
    case PROP_ICON_SIZE_MAX:
 
141
      g_value_set_uint (value, box->icon_size_max);
 
142
      break;
 
143
 
 
144
    default:
 
145
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
146
      break;
 
147
    }
 
148
}
 
149
 
 
150
 
 
151
 
 
152
static void
 
153
xfce_indicator_box_set_property (GObject      *object,
 
154
                                 guint         prop_id,
 
155
                                 const GValue *value,
 
156
                                 GParamSpec   *pspec)
 
157
{
 
158
  XfceIndicatorBox     *box = XFCE_INDICATOR_BOX (object);
 
159
  gint                  val;
 
160
  gint                  size;
 
161
  XfceIndicatorButton  *child;
 
162
  GSList               *li;
 
163
 
 
164
  switch (prop_id)
 
165
    {
 
166
    case PROP_ICON_SIZE_MAX:
 
167
      val = g_value_get_uint (value);
 
168
      if (box->icon_size_max != val)
 
169
        {
 
170
          box->icon_size_max = val;
 
171
          size = xfce_indicator_box_get_row_size (box);
 
172
          for (li = box->children; li != NULL; li = li->next)
 
173
            {
 
174
              child = XFCE_INDICATOR_BUTTON (li->data);
 
175
              g_return_if_fail (XFCE_IS_INDICATOR_BUTTON (child));
 
176
              xfce_indicator_button_set_size (child, box->panel_size, size);
 
177
            }
 
178
          gtk_widget_queue_resize (GTK_WIDGET (box));
 
179
        }
 
180
      break;
 
181
 
 
182
    default:
 
183
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
184
      break;
 
185
    }
 
186
}
 
187
 
 
188
 
 
189
 
 
190
void
 
191
xfce_indicator_box_set_orientation (XfceIndicatorBox *box,
 
192
                                    GtkOrientation    panel_orientation,
 
193
                                    GtkOrientation    orientation)
 
194
{
 
195
  gboolean              needs_update = FALSE;
 
196
  XfceIndicatorButton  *child;
 
197
  GSList               *li;
 
198
 
 
199
  g_return_if_fail (XFCE_IS_INDICATOR_BOX (box));
 
200
 
 
201
  if (box->orientation != orientation)
 
202
    {
 
203
      box->orientation = orientation;
 
204
      needs_update = TRUE;
 
205
    }
 
206
 
 
207
  if (box->panel_orientation != panel_orientation)
 
208
    {
 
209
      box->panel_orientation = panel_orientation;
 
210
      needs_update = TRUE;
 
211
    }
 
212
 
 
213
  if (needs_update)
 
214
    {
 
215
      for (li = box->children; li != NULL; li = li->next)
 
216
        {
 
217
          child = XFCE_INDICATOR_BUTTON (li->data);
 
218
          g_return_if_fail (XFCE_IS_INDICATOR_BUTTON (child));
 
219
          xfce_indicator_button_set_orientation (child, panel_orientation, orientation);
 
220
        }
 
221
      gtk_widget_queue_resize (GTK_WIDGET (box));
 
222
    }
 
223
}
 
224
 
 
225
 
 
226
 
 
227
void
 
228
xfce_indicator_box_set_size (XfceIndicatorBox *box,
 
229
                             gint              panel_size,
 
230
                             gint              nrows)
 
231
{
 
232
  gboolean              needs_update = FALSE;
 
233
  XfceIndicatorButton  *child;
 
234
  GSList               *li;
 
235
  gint                  size;
 
236
 
 
237
  g_return_if_fail (XFCE_IS_INDICATOR_BOX (box));
 
238
 
 
239
  if (box->nrows != nrows)
 
240
    {
 
241
      box->nrows = nrows;
 
242
      needs_update = TRUE;
 
243
    }
 
244
 
 
245
  if (box->panel_size != panel_size)
 
246
    {
 
247
      box->panel_size = panel_size;
 
248
      needs_update = TRUE;
 
249
    }
 
250
 
 
251
  if (needs_update)
 
252
    {
 
253
      size = xfce_indicator_box_get_row_size (box);
 
254
      for (li = box->children; li != NULL; li = li->next)
 
255
        {
 
256
          child = XFCE_INDICATOR_BUTTON (li->data);
 
257
          g_return_if_fail (XFCE_IS_INDICATOR_BUTTON (child));
 
258
          xfce_indicator_button_set_size (child, panel_size, size);
 
259
        }
 
260
      gtk_widget_queue_resize (GTK_WIDGET (box));
 
261
    }
 
262
}
 
263
 
 
264
 
 
265
 
 
266
GtkWidget *
 
267
xfce_indicator_box_new ()
 
268
{
 
269
  XfceIndicatorBox *box = g_object_new (XFCE_TYPE_INDICATOR_BOX, NULL);
 
270
  return GTK_WIDGET (box);
 
271
}
 
272
 
 
273
 
 
274
 
 
275
static void
 
276
xfce_indicator_box_add (GtkContainer *container,
 
277
                        GtkWidget    *child)
 
278
{
 
279
  XfceIndicatorBox    *box = XFCE_INDICATOR_BOX (container);
 
280
  XfceIndicatorButton *button = XFCE_INDICATOR_BUTTON (child);
 
281
  gint                 size;
 
282
 
 
283
  g_return_if_fail (XFCE_IS_INDICATOR_BOX (box));
 
284
  g_return_if_fail (GTK_IS_WIDGET (child));
 
285
  g_return_if_fail (child->parent == NULL);
 
286
 
 
287
  box->children = g_slist_append (box->children, child);
 
288
 
 
289
  gtk_widget_set_parent (child, GTK_WIDGET (box));
 
290
  xfce_indicator_button_set_orientation (button, box->panel_orientation, box->orientation);
 
291
  size = xfce_indicator_box_get_row_size (box);
 
292
  xfce_indicator_button_set_size (button, box->panel_size, size);
 
293
 
 
294
  gtk_widget_queue_resize (GTK_WIDGET (container));
 
295
}
 
296
 
 
297
 
 
298
 
 
299
static void
 
300
xfce_indicator_box_remove (GtkContainer *container,
 
301
                           GtkWidget    *child)
 
302
{
 
303
  XfceIndicatorBox *box = XFCE_INDICATOR_BOX (container);
 
304
  GSList           *li;
 
305
 
 
306
  /* search the child */
 
307
  li = g_slist_find (box->children, child);
 
308
  if (G_LIKELY (li != NULL))
 
309
    {
 
310
      g_assert (GTK_WIDGET (li->data) == child);
 
311
 
 
312
      /* unparent widget */
 
313
      box->children = g_slist_remove_link (box->children, li);
 
314
      gtk_widget_unparent (child);
 
315
 
 
316
      /* resize, so we update has-hidden */
 
317
      gtk_widget_queue_resize (GTK_WIDGET (container));
 
318
    }
 
319
}
 
320
 
 
321
 
 
322
 
 
323
static void
 
324
xfce_indicator_box_forall (GtkContainer *container,
 
325
                           gboolean      include_internals,
 
326
                           GtkCallback   callback,
 
327
                           gpointer      callback_data)
 
328
{
 
329
  XfceIndicatorBox *box = XFCE_INDICATOR_BOX (container);
 
330
  GSList           *li, *lnext;
 
331
 
 
332
  /* run callback for all children */
 
333
  for (li = box->children; li != NULL; li = lnext)
 
334
    {
 
335
      lnext = li->next;
 
336
      (*callback) (GTK_WIDGET (li->data), callback_data);
 
337
    }
 
338
}
 
339
 
 
340
 
 
341
 
 
342
static GType
 
343
xfce_indicator_box_child_type (GtkContainer *container)
 
344
{
 
345
  return GTK_TYPE_WIDGET;
 
346
}
 
347
 
 
348
 
 
349
 
 
350
static void
 
351
xfce_indicator_box_size_request (GtkWidget      *widget,
 
352
                                 GtkRequisition *requisition)
 
353
{
 
354
  XfceIndicatorBox *box = XFCE_INDICATOR_BOX (widget);
 
355
  GtkWidget        *child;
 
356
  GtkRequisition    child_req;
 
357
  GSList           *li;
 
358
  gint              panel_size;
 
359
  gint              length;
 
360
  gint              row;
 
361
  gint              nrows;
 
362
  gint              x;
 
363
  gboolean          has_label;
 
364
 
 
365
  panel_size = box->panel_size;
 
366
  row = 0;
 
367
  length = 0;
 
368
  x = 0;
 
369
  //nrows = MAX (box->nrows,
 
370
  //             box->panel_size / xfce_indicator_box_get_row_size (box));
 
371
  nrows = box->panel_size / xfce_indicator_box_get_row_size (box);
 
372
 
 
373
  for (li = box->children; li != NULL; li = li->next)
 
374
    {
 
375
      child = GTK_WIDGET (li->data);
 
376
      g_return_if_fail (XFCE_IS_INDICATOR_BUTTON (child));
 
377
 
 
378
      gtk_widget_size_request (child, &child_req);
 
379
      has_label = (xfce_indicator_button_get_label (XFCE_INDICATOR_BUTTON (child)) != NULL);
 
380
 
 
381
      /* wrap rows if column is overflowing or a label is encountered */
 
382
      if (row > 0 && (has_label || row >= nrows))
 
383
        {
 
384
          x += length;
 
385
          row = 0;
 
386
          length = 0;
 
387
        }
 
388
 
 
389
      length =
 
390
        MAX (length, (box->panel_orientation == GTK_ORIENTATION_HORIZONTAL) ? child_req.width :child_req.height);
 
391
 
 
392
      if (has_label || row >= nrows)
 
393
        {
 
394
          x += length;
 
395
          row = 0;
 
396
          length = 0;
 
397
        }
 
398
      else
 
399
        {
 
400
          row += 1;
 
401
        }
 
402
    }
 
403
 
 
404
  x += length;
 
405
 
 
406
  if (box->panel_orientation == GTK_ORIENTATION_HORIZONTAL)
 
407
    {
 
408
      requisition->width = x;
 
409
      requisition->height = panel_size;
 
410
    }
 
411
  else
 
412
    {
 
413
      requisition->width = panel_size;
 
414
      requisition->height = x;
 
415
    }
 
416
  /* g_debug ("indicator-box size request: w=%d h=%d", requisition->width, requisition->height); */
 
417
}
 
418
 
 
419
 
 
420
 
 
421
static void
 
422
xfce_indicator_box_size_allocate (GtkWidget     *widget,
 
423
                                  GtkAllocation *allocation)
 
424
{
 
425
  XfceIndicatorBox *box = XFCE_INDICATOR_BOX (widget);
 
426
  GtkWidget        *child;
 
427
  GtkAllocation     child_alloc;
 
428
  GtkRequisition    child_req;
 
429
  gint              panel_size, size;
 
430
  gint              x, y;
 
431
  gint              x0, y0;
 
432
  GSList           *li;
 
433
  gint              length, width;
 
434
  gint              row;
 
435
  gint              nrows;
 
436
  gboolean          has_label;
 
437
 
 
438
  row = 0;
 
439
  length = 0;
 
440
  width = 0;
 
441
  x = y = 0;
 
442
  x0 = allocation->x;
 
443
  y0 = allocation->y;
 
444
 
 
445
  //nrows = MAX (box->nrows, box->panel_size / box->icon_size_max);
 
446
  nrows = box->panel_size / xfce_indicator_box_get_row_size (box);
 
447
  panel_size = box->panel_size;
 
448
  size = panel_size / nrows;
 
449
 
 
450
  for (li = box->children; li != NULL; li = li->next)
 
451
    {
 
452
      child = GTK_WIDGET (li->data);
 
453
      g_return_if_fail (XFCE_IS_INDICATOR_BUTTON (child));
 
454
 
 
455
      gtk_widget_get_child_requisition (child, &child_req);
 
456
 
 
457
      has_label = (xfce_indicator_button_get_label (XFCE_INDICATOR_BUTTON (child)) != NULL);
 
458
 
 
459
      /* wrap rows if column is overflowing or a label is encountered */
 
460
      if (row > 0 && (has_label || row >= nrows))
 
461
        {
 
462
          x += length;
 
463
          y = 0;
 
464
          row = 0;
 
465
          length = 0;
 
466
        }
 
467
 
 
468
      width = (has_label) ? panel_size : size;
 
469
      length = MAX (length,
 
470
                    (box->panel_orientation == GTK_ORIENTATION_HORIZONTAL) ? child_req.width :child_req.height);
 
471
 
 
472
      if (box->panel_orientation == GTK_ORIENTATION_HORIZONTAL)
 
473
        {
 
474
          child_alloc.x = x0 + x;
 
475
          child_alloc.y = y0 + y;
 
476
          child_alloc.width = length;
 
477
          child_alloc.height = width;
 
478
        }
 
479
      else
 
480
        {
 
481
          child_alloc.x = x0 + y;
 
482
          child_alloc.y = y0 + x;
 
483
          child_alloc.width = width;
 
484
          child_alloc.height = length;
 
485
        }
 
486
 
 
487
      /* g_debug ("indicator-box size allocate: x=%d y=%d w=%d h=%d", */
 
488
      /*          child_alloc.x, child_alloc.y, child_alloc.width, child_alloc.height); */
 
489
 
 
490
      gtk_widget_size_allocate (child, &child_alloc);
 
491
 
 
492
      if (has_label || row >= nrows)
 
493
        {
 
494
          x += length;
 
495
          y = 0;
 
496
          row = 0;
 
497
          length = 0;
 
498
        }
 
499
      else
 
500
        {
 
501
          row += 1;
 
502
          y += size;
 
503
        }
 
504
    }
 
505
}
 
506
 
 
507
 
 
508
 
 
509
static gint
 
510
xfce_indicator_box_get_row_size (XfceIndicatorBox *box)
 
511
{
 
512
  gint                 border_thickness;
 
513
  GtkStyle            *style;
 
514
 
 
515
  g_return_val_if_fail (XFCE_IS_INDICATOR_BOX (box), 24);
 
516
 
 
517
  style = gtk_widget_get_style (GTK_WIDGET (box));
 
518
  border_thickness = 2 * MAX (style->xthickness, style->ythickness) + 2;
 
519
 
 
520
  return MIN (box->panel_size / box->nrows, box->icon_size_max + border_thickness);
 
521
}