~ubuntu-branches/ubuntu/trusty/xfce4-panel/trusty-proposed

« back to all changes in this revision

Viewing changes to panel/groups.c

  • Committer: Bazaar Package Importer
  • Author(s): Simon Huggins
  • Date: 2004-06-08 10:44:21 UTC
  • Revision ID: james.westby@ubuntu.com-20040608104421-b0b77kis8o0uoi6q
Tags: upstream-4.0.5
ImportĀ upstreamĀ versionĀ 4.0.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  xfce4
 
2
 *  
 
3
 *  Copyright (C) 2002 Jasper Huijsmans (huysmans@users.sourceforge.net)
 
4
 *
 
5
 *  This program is free software; you can redistribute it and/or modify
 
6
 *  it under the terms of the GNU General Public License as published by
 
7
 *  the Free Software Foundation; either version 2 of the License, or
 
8
 *  (at your option) any later version.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
18
*/
 
19
 
 
20
/*  Groups
 
21
 *  ------
 
22
 *  The panel consist of a collection of panel groups. A panel group defines 
 
23
 *  several containers to pack widgets into and to allow easy rearragement of 
 
24
 *  these widgets.
 
25
 *  
 
26
 *  Two widgets are packed into a panel group: a panel control and a popup 
 
27
 *  button. 
 
28
*/
 
29
 
 
30
#ifdef HAVE_CONFIG_H
 
31
#include <config.h>
 
32
#endif
 
33
 
 
34
#include <libxfce4util/i18n.h>
 
35
#include <libxfce4util/debug.h>
 
36
 
 
37
#include "xfce.h"
 
38
#include "groups.h"
 
39
#include "popup.h"
 
40
 
 
41
static GSList *group_list = NULL;
 
42
static GSList *removed_list = NULL;
 
43
static GtkArrowType popup_arrow_type = GTK_ARROW_UP;
 
44
 
 
45
static GtkBox *groupbox;
 
46
 
 
47
/*  Panel group
 
48
 *  -----------
 
49
*/
 
50
typedef struct _PanelGroup PanelGroup;
 
51
 
 
52
struct _PanelGroup
 
53
{
 
54
    int index;
 
55
 
 
56
    GtkWidget *base;            /* container to pack into panel */
 
57
    GtkWidget *box;             /* hbox or vbox */
 
58
 
 
59
    PanelPopup *popup;
 
60
    Control *control;
 
61
};
 
62
 
 
63
static void
 
64
panel_group_arrange (PanelGroup * pg)
 
65
{
 
66
    int position = settings.popup_position;
 
67
 
 
68
    if (pg->box)
 
69
    {
 
70
        if (pg->popup)
 
71
            panel_popup_unpack (pg->popup);
 
72
        if (pg->control)
 
73
            control_unpack (pg->control);
 
74
 
 
75
        gtk_widget_destroy (pg->box);
 
76
    }
 
77
 
 
78
    if (position == TOP || position == BOTTOM)
 
79
        pg->box = gtk_vbox_new (FALSE, 0);
 
80
    else
 
81
        pg->box = gtk_hbox_new (FALSE, 0);
 
82
 
 
83
    gtk_widget_show (pg->box);
 
84
    gtk_container_add (GTK_CONTAINER (pg->base), pg->box);
 
85
 
 
86
    if (position == RIGHT || position == BOTTOM)
 
87
    {
 
88
        if (pg->control)
 
89
            control_pack (pg->control, GTK_BOX (pg->box));
 
90
        if (pg->popup)
 
91
            panel_popup_pack (pg->popup, GTK_BOX (pg->box));
 
92
    }
 
93
    else
 
94
    {
 
95
        if (pg->popup)
 
96
            panel_popup_pack (pg->popup, GTK_BOX (pg->box));
 
97
        if (pg->control)
 
98
            control_pack (pg->control, GTK_BOX (pg->box));
 
99
    }
 
100
}
 
101
 
 
102
PanelGroup *
 
103
create_panel_group (int index)
 
104
{
 
105
    PanelGroup *pg = g_new (PanelGroup, 1);
 
106
 
 
107
    pg->index = index;
 
108
 
 
109
    pg->base = gtk_alignment_new (0, 0, 1, 1);
 
110
    gtk_widget_show (pg->base);
 
111
 
 
112
    /* protect against destruction when unpacking */
 
113
    g_object_ref (pg->base);
 
114
    gtk_object_sink (GTK_OBJECT (pg->base));
 
115
 
 
116
    pg->box = NULL;
 
117
    pg->popup = NULL;
 
118
    pg->control = NULL;
 
119
 
 
120
    return pg;
 
121
}
 
122
 
 
123
static void
 
124
panel_group_free (PanelGroup * pg)
 
125
{
 
126
    panel_popup_free (pg->popup);
 
127
    control_free (pg->control);
 
128
 
 
129
    g_object_unref (pg->base);
 
130
    g_free (pg);
 
131
}
 
132
 
 
133
static void
 
134
panel_group_pack (PanelGroup * pg, GtkBox * hbox)
 
135
{
 
136
    gtk_box_pack_start (hbox, pg->base, TRUE, TRUE, 0);
 
137
}
 
138
 
 
139
static void
 
140
panel_group_unpack (PanelGroup * pg)
 
141
{
 
142
    gtk_container_remove (GTK_CONTAINER (pg->base->parent), pg->base);
 
143
}
 
144
 
 
145
/*  Groups
 
146
 *  ------
 
147
 *  Mainly housekeeping for the global list of panel groups
 
148
*/
 
149
void
 
150
groups_init (GtkBox * box)
 
151
{
 
152
    groupbox = box;
 
153
 
 
154
    /* we need this later on, so we may just as well initialize it here */
 
155
    control_class_list_init ();
 
156
}
 
157
 
 
158
void
 
159
groups_cleanup (void)
 
160
{
 
161
    GSList *li;
 
162
    PanelGroup *group;
 
163
 
 
164
    for (li = group_list; li; li = li->next)
 
165
    {
 
166
        group = li->data;
 
167
 
 
168
        panel_group_free (group);
 
169
    }
 
170
 
 
171
    control_class_list_cleanup ();
 
172
 
 
173
    g_slist_free (group_list);
 
174
    g_slist_free (removed_list);
 
175
    group_list = NULL;
 
176
    removed_list = NULL;
 
177
}
 
178
 
 
179
void
 
180
old_groups_set_from_xml (int side, xmlNodePtr node)
 
181
{
 
182
    static int last_group = 0;
 
183
    xmlNodePtr child;
 
184
    int i;
 
185
    GSList *li;
 
186
    PanelGroup *group;
 
187
 
 
188
    if (side == LEFT)
 
189
        last_group = 0;
 
190
 
 
191
    li = g_slist_nth (group_list, last_group);
 
192
 
 
193
    /* children are "Group" nodes */
 
194
    if (node)
 
195
        node = node->children;
 
196
 
 
197
    for (i = last_group; /*i < settings.num_groups ||*/ li || node; i++)
 
198
    {
 
199
        gboolean control_created = FALSE;
 
200
 
 
201
        if (side == LEFT && !node)
 
202
            break;
 
203
 
 
204
        if (li)
 
205
        {
 
206
            group = li->data;
 
207
        }
 
208
        else
 
209
        {
 
210
            group = create_panel_group (i);
 
211
            panel_group_pack (group, groupbox);
 
212
            group_list = g_slist_append (group_list, group);
 
213
 
 
214
            group->popup = create_panel_popup ();
 
215
 
 
216
            group->control = control_new (i);
 
217
 
 
218
            panel_group_arrange (group);
 
219
        }
 
220
 
 
221
        if (node)
 
222
        {
 
223
            for (child = node->children; child; child = child->next)
 
224
            {
 
225
                /* create popup items and panel control */
 
226
                if (xmlStrEqual (child->name, (const xmlChar *) "Popup"))
 
227
                {
 
228
                    panel_popup_set_from_xml (group->popup, child);
 
229
                }
 
230
                else if (xmlStrEqual
 
231
                         (child->name, (const xmlChar *) "Control"))
 
232
                {
 
233
                    control_set_from_xml (group->control, child);
 
234
                    control_created = TRUE;
 
235
                }
 
236
            }
 
237
        }
 
238
 
 
239
        if (!control_created)
 
240
            control_set_from_xml (group->control, NULL);
 
241
 
 
242
        if (node)
 
243
            node = node->next;
 
244
 
 
245
        if (li)
 
246
            li = li->next;
 
247
 
 
248
        last_group++;
 
249
    }
 
250
}
 
251
 
 
252
void
 
253
groups_set_from_xml (xmlNodePtr node)
 
254
{
 
255
    xmlNodePtr child;
 
256
    int i;
 
257
    GSList *li;
 
258
    PanelGroup *group;
 
259
 
 
260
    li = group_list;
 
261
 
 
262
    /* children are "Group" nodes */
 
263
    if (node)
 
264
        node = node->children;
 
265
 
 
266
    DBG("expected number of panel items: %d", settings.num_groups);
 
267
    
 
268
    for (i = 0; /* i < settings.num_groups || */ li || node; i++)
 
269
    {
 
270
        gboolean control_created = FALSE;
 
271
 
 
272
        if (li)
 
273
        {
 
274
            group = li->data;
 
275
        }
 
276
        else
 
277
        {
 
278
            group = create_panel_group (i);
 
279
            panel_group_pack (group, groupbox);
 
280
            group_list = g_slist_append (group_list, group);
 
281
 
 
282
            group->popup = create_panel_popup ();
 
283
 
 
284
            group->control = control_new (i);
 
285
 
 
286
            panel_group_arrange (group);
 
287
        }
 
288
 
 
289
        if (node)
 
290
        {
 
291
            for (child = node->children; child; child = child->next)
 
292
            {
 
293
                /* create popup items and panel control */
 
294
                if (xmlStrEqual (child->name, (const xmlChar *) "Popup"))
 
295
                {
 
296
                    panel_popup_set_from_xml (group->popup, child);
 
297
                }
 
298
                else if (xmlStrEqual
 
299
                         (child->name, (const xmlChar *) "Control"))
 
300
                {
 
301
                    control_set_from_xml (group->control, child);
 
302
                    control_created = TRUE;
 
303
                }
 
304
            }
 
305
        }
 
306
 
 
307
        if (!control_created)
 
308
            control_set_from_xml (group->control, NULL);
 
309
 
 
310
        if (node)
 
311
            node = node->next;
 
312
 
 
313
        if (li)
 
314
            li = li->next;
 
315
    }
 
316
 
 
317
    settings.num_groups = g_slist_length (group_list);
 
318
    
 
319
    DBG("actual number of panel items: %d", settings.num_groups);
 
320
}
 
321
 
 
322
void
 
323
groups_write_xml (xmlNodePtr root)
 
324
{
 
325
    xmlNodePtr node, child;
 
326
    GSList *li;
 
327
    PanelGroup *group;
 
328
 
 
329
    node = xmlNewTextChild (root, NULL, "Groups", NULL);
 
330
 
 
331
    for (li = group_list; li; li = li->next)
 
332
    {
 
333
        group = li->data;
 
334
 
 
335
        child = xmlNewTextChild (node, NULL, "Group", NULL);
 
336
 
 
337
        panel_popup_write_xml (group->popup, child);
 
338
        control_write_xml (group->control, child);
 
339
    }
 
340
}
 
341
 
 
342
void
 
343
groups_pack (GtkBox * box)
 
344
{
 
345
    GSList *li;
 
346
    PanelGroup *group;
 
347
 
 
348
    groupbox = box;
 
349
 
 
350
    for (li = group_list; li; li = li->next)
 
351
    {
 
352
        group = li->data;
 
353
 
 
354
        panel_group_pack (group, box);
 
355
        panel_group_arrange (group);
 
356
    }
 
357
}
 
358
 
 
359
void
 
360
groups_unpack (void)
 
361
{
 
362
    GSList *li;
 
363
    PanelGroup *group;
 
364
 
 
365
    for (li = group_list; li; li = li->next)
 
366
    {
 
367
        group = li->data;
 
368
 
 
369
        panel_group_unpack (group);
 
370
    }
 
371
}
 
372
 
 
373
void
 
374
groups_register_control (Control * control)
 
375
{
 
376
    PanelGroup *group;
 
377
 
 
378
    group = g_slist_nth (group_list, control->index)->data;
 
379
 
 
380
    group->control = control;
 
381
 
 
382
    if (!control->with_popup)
 
383
        groups_show_popup (control->index, FALSE);
 
384
    else
 
385
        groups_show_popup (control->index, TRUE);
 
386
 
 
387
    panel_group_arrange (group);
 
388
}
 
389
 
 
390
static PanelGroup *
 
391
groups_get_nth (int n)
 
392
{
 
393
    PanelGroup *group;
 
394
    GSList *li;
 
395
    int index, len;
 
396
 
 
397
    len = g_slist_length (group_list);
 
398
 
 
399
    if (n < 0)
 
400
        index = 0;
 
401
    else if (n >= len)
 
402
        index = len - 1;
 
403
    else
 
404
        index = n;
 
405
 
 
406
    li = g_slist_nth (group_list, index);
 
407
 
 
408
    group = li->data;
 
409
 
 
410
    return group;
 
411
}
 
412
 
 
413
Control *
 
414
groups_get_control (int index)
 
415
{
 
416
    PanelGroup *group;
 
417
 
 
418
    group = groups_get_nth (index);
 
419
    return group->control;
 
420
}
 
421
 
 
422
PanelPopup *
 
423
groups_get_popup (int index)
 
424
{
 
425
    PanelGroup *group;
 
426
 
 
427
    group = groups_get_nth (index);
 
428
    return group->popup;
 
429
}
 
430
 
 
431
void
 
432
groups_move (int from, int to)
 
433
{
 
434
    int i;
 
435
    GSList *li;
 
436
    PanelGroup *group;
 
437
 
 
438
    if (from < 0 || from >= g_slist_length (group_list))
 
439
        return;
 
440
 
 
441
    li = g_slist_nth (group_list, from);
 
442
    group = li->data;
 
443
 
 
444
    gtk_box_reorder_child (groupbox, group->base, to);
 
445
 
 
446
    group_list = g_slist_delete_link (group_list, li);
 
447
    group_list = g_slist_insert (group_list, group, to);
 
448
 
 
449
    for (i = 0, li = group_list; li; i++, li = li->next)
 
450
    {
 
451
        group = li->data;
 
452
 
 
453
        group->index = group->control->index = i;
 
454
    }
 
455
}
 
456
 
 
457
void
 
458
groups_remove (int index)
 
459
{
 
460
    int i;
 
461
    GSList *li;
 
462
    PanelGroup *group;
 
463
 
 
464
    li = g_slist_nth (group_list, index);
 
465
    group = li->data;
 
466
 
 
467
    panel_group_unpack (group);
 
468
 
 
469
    group_list = g_slist_delete_link (group_list, li);
 
470
 
 
471
    panel_group_free (group);
 
472
 
 
473
    settings.num_groups--;
 
474
 
 
475
    for (i = 0, li = group_list; li; i++, li = li->next)
 
476
    {
 
477
        group = li->data;
 
478
 
 
479
        group->index = group->control->index = i;
 
480
    }
 
481
}
 
482
 
 
483
void
 
484
groups_show_popup (int index, gboolean show)
 
485
{
 
486
    GSList *li;
 
487
    PanelGroup *group;
 
488
 
 
489
    li = g_slist_nth (group_list, index);
 
490
    group = li->data;
 
491
 
 
492
    if (show)
 
493
        gtk_widget_show (group->popup->button);
 
494
    else
 
495
        gtk_widget_hide (group->popup->button);
 
496
}
 
497
 
 
498
/* settings */
 
499
void
 
500
groups_set_orientation (int orientation)
 
501
{
 
502
    GSList *li;
 
503
    PanelGroup *group;
 
504
 
 
505
    for (li = group_list; li; li = li->next)
 
506
    {
 
507
        group = li->data;
 
508
 
 
509
        control_set_orientation (group->control, orientation);
 
510
    }
 
511
}
 
512
 
 
513
void
 
514
groups_set_layer (int layer)
 
515
{
 
516
    GSList *li;
 
517
    PanelGroup *group;
 
518
 
 
519
    for (li = group_list; li; li = li->next)
 
520
    {
 
521
        group = li->data;
 
522
 
 
523
        panel_popup_set_layer (group->popup, layer);
 
524
    }
 
525
}
 
526
 
 
527
void
 
528
groups_set_size (int size)
 
529
{
 
530
    GSList *li;
 
531
    PanelGroup *group;
 
532
 
 
533
    for (li = group_list; li; li = li->next)
 
534
    {
 
535
        group = li->data;
 
536
 
 
537
        panel_popup_set_size (group->popup, size);
 
538
        control_set_size (group->control, size);
 
539
    }
 
540
}
 
541
 
 
542
void
 
543
groups_set_popup_position (int position)
 
544
{
 
545
    GSList *li;
 
546
    PanelGroup *group;
 
547
 
 
548
    for (li = group_list; li; li = li->next)
 
549
    {
 
550
        group = li->data;
 
551
 
 
552
        panel_group_arrange (group);
 
553
        panel_popup_set_popup_position (group->popup, position);
 
554
    }
 
555
}
 
556
 
 
557
void
 
558
groups_set_theme (const char *theme)
 
559
{
 
560
    GSList *li;
 
561
    PanelGroup *group;
 
562
 
 
563
    for (li = group_list; li; li = li->next)
 
564
    {
 
565
        group = li->data;
 
566
 
 
567
        panel_popup_set_theme (group->popup, theme);
 
568
        control_set_theme (group->control, theme);
 
569
    }
 
570
}
 
571
 
 
572
void
 
573
groups_add_control (int id, const char *filename, int index)
 
574
{
 
575
    int len;
 
576
    PanelGroup *group = NULL;
 
577
 
 
578
    len = g_slist_length (group_list);
 
579
 
 
580
    if (index < 0 || index > len)
 
581
        index = len;
 
582
 
 
583
    group = create_panel_group (index);
 
584
    panel_group_pack (group, groupbox);
 
585
    group_list = g_slist_append (group_list, group);
 
586
 
 
587
    group->popup = create_panel_popup ();
 
588
 
 
589
    group->control = control_new (index);
 
590
    create_control (group->control, id, filename);
 
591
 
 
592
    panel_group_arrange (group);
 
593
 
 
594
    if (index >= 0 && index < len)
 
595
        groups_move (len, index);
 
596
 
 
597
    if (!group->control->with_popup)
 
598
        groups_show_popup (index, FALSE);
 
599
 
 
600
    settings.num_groups++;
 
601
}
 
602
 
 
603
void
 
604
groups_set_num_groups (int n)
 
605
{
 
606
    int i, len;
 
607
    GSList *li;
 
608
    PanelGroup *group = NULL;
 
609
 
 
610
    len = g_slist_length (group_list);
 
611
 
 
612
    /* nothing to do */
 
613
    if (n == len)
 
614
        return;
 
615
 
 
616
    /* add group(s) */
 
617
    if (n > len)
 
618
    {
 
619
        for (i = len; i < n; i++)
 
620
        {
 
621
            if (removed_list)
 
622
            {
 
623
                group = removed_list->data;
 
624
                removed_list =
 
625
                    g_slist_delete_link (removed_list, removed_list);
 
626
 
 
627
                panel_group_pack (group, groupbox);
 
628
                group_list = g_slist_append (group_list, group);
 
629
 
 
630
                panel_group_arrange (group);
 
631
                settings.num_groups++;
 
632
            }
 
633
            else
 
634
            {
 
635
                groups_add_control (ICON, NULL, i);
 
636
            }
 
637
 
 
638
            gtk_widget_show (group->base);
 
639
        }
 
640
 
 
641
        return;
 
642
    }
 
643
 
 
644
    /* removing group(s) */
 
645
    li = g_slist_nth (group_list, n);
 
646
 
 
647
    for (i = n; i < len; i++)
 
648
    {
 
649
        GSList *li2;
 
650
 
 
651
        group = li->data;
 
652
        panel_group_unpack (group);
 
653
 
 
654
        /* this sets the list to the next group */
 
655
        li2 = li;
 
656
        li = li->next;
 
657
 
 
658
        group_list = g_slist_remove_link (group_list, li2);
 
659
        removed_list = g_slist_prepend (removed_list, group);
 
660
        settings.num_groups--;
 
661
    }
 
662
}
 
663
 
 
664
/* arrow direction */
 
665
 
 
666
void
 
667
groups_set_arrow_direction (GtkArrowType type)
 
668
{
 
669
    GSList *li;
 
670
    PanelGroup *group;
 
671
 
 
672
    popup_arrow_type = type;
 
673
 
 
674
    for (li = group_list; li; li = li->next)
 
675
    {
 
676
        group = li->data;
 
677
 
 
678
        panel_popup_set_arrow_type (group->popup, type);
 
679
    }
 
680
}
 
681
 
 
682
GtkArrowType
 
683
groups_get_arrow_direction (void)
 
684
{
 
685
    return popup_arrow_type;
 
686
}
 
687