source: trunk/third/gnome-core/panel/drawer-widget.c @ 17152

Revision 17152, 12.3 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r17151, which included commits to RCS files with non-trunk default branches.
Line 
1/* Gnome panel: drawer widget
2 * (C) 1999 the Free Software Foundation
3 *
4 * Authors:  Jacob Berkman
5 *           George Lebl
6 *
7 */
8
9#include "config.h"
10#include "drawer-widget.h"
11#include "border-widget.h"
12#include "floating-widget.h"
13#include "panel_config_global.h"
14
15#include "multiscreen-stuff.h"
16
17extern GlobalConfig global_config;
18extern int pw_minimized_size;
19
20static void drawer_pos_class_init (DrawerPosClass *klass);
21static void drawer_pos_init (DrawerPos *pos);
22
23static void drawer_pos_set_hidebuttons (BasePWidget *basep);
24static PanelOrientType drawer_pos_get_applet_orient (BasePWidget *basep);
25
26static PanelOrientType drawer_pos_get_hide_orient (BasePWidget *basep);
27static void drawer_pos_get_hide_pos (BasePWidget *basep,
28                                     PanelOrientType hide_orient,
29                                     int *x, int *y,
30                                     int w, int h);
31static void drawer_pos_get_hide_size (BasePWidget *basep,
32                                      PanelOrientType hide_orient,
33                                      int *w, int *h);
34
35static void drawer_pos_get_pos(BasePWidget *basep,
36                               int *x, int *y,
37                               int width, int height);
38
39static void drawer_pos_get_menu_pos (BasePWidget *basep,
40                                     GtkWidget *widget,
41                                     GtkRequisition *mreq,
42                                     int *x, int *y,
43                                     int wx, int wy,
44                                     int ww, int wh);
45
46static void drawer_pos_hidebutton_click (BasePWidget *basep);
47
48static void drawer_pos_pre_convert_hook (BasePWidget *basep);
49
50static BasePPosClass *parent_class;
51
52GtkType
53drawer_pos_get_type (void)
54{
55        static GtkType drawer_pos_type = 0;
56
57        if (drawer_pos_type == 0) {
58                GtkTypeInfo drawer_pos_info = {
59                        "DrawerPos",
60                        sizeof (DrawerPos),
61                        sizeof (DrawerPosClass),
62                        (GtkClassInitFunc) drawer_pos_class_init,
63                        (GtkObjectInitFunc) drawer_pos_init,
64                        NULL,
65                        NULL,
66                        NULL
67                };
68
69                drawer_pos_type = gtk_type_unique (TYPE_BASEP_POS,
70                                                   &drawer_pos_info);
71        }
72
73        return drawer_pos_type;
74}
75
76static void
77drawer_pos_class_init (DrawerPosClass *klass)
78{
79        /*GtkObjectClass *object_class = GTK_OBJECT_CLASS(klass);*/
80        BasePPosClass *pos_class = BASEP_POS_CLASS(klass);
81
82        parent_class = gtk_type_class(TYPE_BASEP_POS);
83
84        /* fill out the virtual funcs */
85        pos_class->set_hidebuttons = drawer_pos_set_hidebuttons;
86        pos_class->get_applet_orient = drawer_pos_get_applet_orient;
87        pos_class->get_size = NULL; /* the default is ok */
88        pos_class->get_hide_orient = drawer_pos_get_hide_orient;
89        pos_class->get_hide_pos = drawer_pos_get_hide_pos;
90        pos_class->get_hide_size = drawer_pos_get_hide_size;
91        pos_class->get_pos = drawer_pos_get_pos;
92        pos_class->get_menu_pos = drawer_pos_get_menu_pos;
93
94        pos_class->north_clicked =
95                pos_class->west_clicked =
96                pos_class->south_clicked =
97                pos_class->east_clicked =
98                drawer_pos_hidebutton_click;
99        pos_class->pre_convert_hook = drawer_pos_pre_convert_hook;
100}
101
102static void
103drawer_pos_init (DrawerPos *pos) { }
104
105static void
106drawer_pos_set_hidebuttons (BasePWidget *basep)
107{
108        switch(DRAWER_POS(basep->pos)->orient) {
109        case ORIENT_UP:
110                gtk_widget_show(basep->hidebutton_n);
111                gtk_widget_hide(basep->hidebutton_e);
112                gtk_widget_hide(basep->hidebutton_w);
113                gtk_widget_hide(basep->hidebutton_s);
114                break;
115        case ORIENT_DOWN:
116                gtk_widget_hide(basep->hidebutton_n);
117                gtk_widget_hide(basep->hidebutton_e);
118                gtk_widget_hide(basep->hidebutton_w);
119                gtk_widget_show(basep->hidebutton_s);
120                break;
121        case ORIENT_LEFT:
122                gtk_widget_hide(basep->hidebutton_n);
123                gtk_widget_hide(basep->hidebutton_e);
124                gtk_widget_show(basep->hidebutton_w);
125                gtk_widget_hide(basep->hidebutton_s);
126                break;
127        case ORIENT_RIGHT:
128                gtk_widget_hide(basep->hidebutton_n);
129                gtk_widget_show(basep->hidebutton_e);
130                gtk_widget_hide(basep->hidebutton_w);
131                gtk_widget_hide(basep->hidebutton_s);
132                break;
133        }
134}
135
136static PanelOrientType
137drawer_pos_get_applet_orient (BasePWidget *basep)
138{
139        PanelWidget *panel = PANEL_WIDGET (basep->panel);
140        PanelOrientation porient = panel->orient;
141        int x,y;
142
143        x = GTK_WIDGET(basep)->allocation.x;
144        y = GTK_WIDGET(basep)->allocation.y;
145
146        if(porient == PANEL_VERTICAL) {
147                if (x > (multiscreen_width (basep->screen)/2 +
148                         multiscreen_x (basep->screen)))
149                        return ORIENT_LEFT;
150                else
151                        return ORIENT_RIGHT;
152        } else {
153                if (y > (multiscreen_height (basep->screen)/2 +
154                         multiscreen_y (basep->screen)))
155                        return ORIENT_UP;
156                else
157                        return ORIENT_DOWN;
158        }
159}
160
161static PanelOrientType
162drawer_pos_get_hide_orient (BasePWidget *basep)
163{
164        DrawerPos *pos = DRAWER_POS (basep->pos);
165        PanelWidget *panel = PANEL_WIDGET (basep->panel);
166
167        switch (basep->state) {
168        case BASEP_AUTO_HIDDEN:
169                switch (pos->orient) {
170                case ORIENT_UP: return ORIENT_DOWN;
171                case ORIENT_RIGHT: return ORIENT_LEFT;
172                case ORIENT_DOWN: return ORIENT_UP;
173                case ORIENT_LEFT: return ORIENT_RIGHT;
174                }
175                g_assert_not_reached ();
176                break;
177        case BASEP_HIDDEN_LEFT:
178                return (panel->orient == PANEL_HORIZONTAL)
179                        ? ORIENT_LEFT : ORIENT_UP;
180        case BASEP_HIDDEN_RIGHT:
181                return (panel->orient == PANEL_HORIZONTAL)
182                        ? ORIENT_RIGHT : ORIENT_DOWN;
183        default:
184                g_assert_not_reached ();
185                break;
186        }
187        g_assert_not_reached ();
188        return -1;
189}
190       
191void
192drawer_widget_open_drawer (DrawerWidget *drawer, GtkWidget *parentp)
193{
194        if (IS_BASEP_WIDGET (parentp))
195                BASEP_WIDGET (parentp)->drawers_open++;
196        basep_widget_explicit_show (BASEP_WIDGET (drawer));
197}
198
199void
200drawer_widget_close_drawer (DrawerWidget *drawer, GtkWidget *parentp)
201{
202        BasePWidget *basep = BASEP_WIDGET (drawer);
203
204        if(GTK_WIDGET(parentp)->window)
205                gdk_window_raise(GTK_WIDGET(parentp)->window);
206
207        switch (DRAWER_POS (basep->pos)->orient) {
208        case ORIENT_UP:
209        case ORIENT_LEFT:
210                basep_widget_explicit_hide (basep, BASEP_HIDDEN_RIGHT);
211                break;
212        case ORIENT_RIGHT:
213        case ORIENT_DOWN:
214                basep_widget_explicit_hide (basep, BASEP_HIDDEN_LEFT);
215                break;
216        }
217
218        if (IS_BASEP_WIDGET (parentp))
219                BASEP_WIDGET (parentp)->drawers_open--;
220}
221
222static void
223drawer_pos_hidebutton_click (BasePWidget *basep)
224{
225        Drawer *drawer = gtk_object_get_data (GTK_OBJECT (basep),
226                                              DRAWER_PANEL_KEY);
227        PanelWidget *panel = PANEL_WIDGET (drawer->button->parent);
228        GtkWidget *parent = panel->panel_parent;
229
230        drawer_widget_close_drawer (DRAWER_WIDGET (basep), parent);
231}
232
233static void
234drawer_pos_get_menu_pos (BasePWidget *basep,
235                         GtkWidget *widget,
236                         GtkRequisition *mreq,
237                         int *x, int *y,
238                         int wx, int wy,
239                         int ww, int wh)
240{       
241        PanelWidget *panel =
242                PANEL_WIDGET(basep->panel);
243
244        if(panel->orient==PANEL_VERTICAL) {
245                *x = wx + ww;
246                *y += wy;
247        } else {
248                *x += wx;
249                *y = wy - mreq->height;
250        }
251}
252
253static void
254drawer_pos_get_pos(BasePWidget *basep,
255                   int *x, int *y,
256                   int width, int height)
257{
258        PanelWidget *panel = PANEL_WIDGET(basep->panel);
259        DrawerPos *pos = DRAWER_POS (basep->pos);
260
261        /* we are shown but we are hidden, life is full of ironies */
262        if (pos->temp_hidden) {
263                *x = -width - 1;
264                *y = -height - 1;
265                return;
266        }
267
268        if (panel->master_widget &&
269            GTK_WIDGET_REALIZED (panel->master_widget) &&
270            /*"allocated" data will be set on each allocation, until then,
271              don't show the actual panel*/
272            gtk_object_get_data(GTK_OBJECT(panel->master_widget),"allocated")) {
273                int bx, by, bw, bh;
274                int px, py, pw, ph;
275                GtkWidget *ppanel; /*parent panel*/
276               
277                /*get the parent of the applet*/
278                /*note we know these are not NO_WINDOW widgets, so
279                  we don't need to check*/
280                ppanel = panel->master_widget->parent;
281                bx = panel->master_widget->allocation.x +
282                        ppanel->allocation.x;
283                by = panel->master_widget->allocation.y +
284                        ppanel->allocation.y;
285                /*go the the toplevel panel widget*/
286                while(ppanel->parent) {
287                        ppanel = ppanel->parent;
288                        if(!GTK_WIDGET_NO_WINDOW(ppanel)) {
289                                bx += ppanel->allocation.x;
290                                by += ppanel->allocation.y;
291                        }
292                }
293
294                bw = panel->master_widget->allocation.width;
295                bh = panel->master_widget->allocation.height;
296                px = ppanel->allocation.x;
297                py = ppanel->allocation.y;
298                pw = ppanel->allocation.width;
299                ph = ppanel->allocation.height;
300
301                switch(pos->orient) {
302                case ORIENT_UP:
303                        *x = bx+(bw-width)/2;
304                        *y = py - height;
305                        break;
306                case ORIENT_DOWN:
307                        *x = bx+(bw-width)/2;
308                        *y = py + ph;
309                        break;
310                case ORIENT_LEFT:
311                        *x = px - width;
312                        *y = by+(bh-height)/2;
313                        break;
314                case ORIENT_RIGHT:
315                        *x = px + pw;
316                        *y = by+(bh-height)/2;
317                        break;
318                }
319        }
320}
321
322static void
323drawer_pos_get_hide_pos (BasePWidget *basep,
324                         PanelOrientType hide_orient,
325                         int *x, int *y,
326                         int w, int h)
327{
328        if (basep->state != BASEP_SHOWN ||
329            DRAWER_POS (basep->pos)->temp_hidden) {
330                *x = -ABS(*x) - 1;
331                *y = -ABS(*y) - 1;
332        }
333}
334
335static void
336drawer_pos_get_hide_size (BasePWidget *basep,
337                          PanelOrientType hide_orient,
338                          int *w, int *h)
339{
340        switch (hide_orient) {
341        case ORIENT_UP:
342        case ORIENT_DOWN:
343                *h = 1;
344                break;
345        case ORIENT_RIGHT:
346        case ORIENT_LEFT:
347                *w = 1;
348                break;
349        }
350}
351
352
353static void
354drawer_pos_pre_convert_hook (BasePWidget *basep)
355{
356        basep->keep_in_screen = FALSE;
357        PANEL_WIDGET (basep->panel)->packed = TRUE;
358}
359
360void
361drawer_widget_change_params (DrawerWidget *drawer,
362                             PanelOrientType orient,
363                             BasePMode mode,
364                             BasePState state,
365                             BasePLevel level,
366                             gboolean avoid_on_maximize,
367                             int sz,
368                             gboolean hidebuttons_enabled,
369                             gboolean hidebutton_pixmap_enabled,
370                             PanelBackType back_type,
371                             char *back_pixmap,
372                             gboolean fit_pixmap_bg,
373                             gboolean strech_pixmap_bg,
374                             gboolean rotate_pixmap_bg,
375                             GdkColor *back_color)
376{
377        PanelOrientation porient;
378        DrawerPos *pos = DRAWER_POS (BASEP_WIDGET (drawer)->pos);
379
380        switch (orient) {
381        case ORIENT_UP:
382        case ORIENT_DOWN:
383                porient = PANEL_VERTICAL;
384                break;
385        case ORIENT_LEFT:
386        case ORIENT_RIGHT:
387        default:
388                porient = PANEL_HORIZONTAL;
389                break;
390        }
391
392        if (PANEL_WIDGET (BASEP_WIDGET (drawer)->panel)->orient != porient)
393                BASEP_WIDGET (drawer)->request_cube = TRUE;
394
395        if (state != BASEP_WIDGET (drawer)->state ||
396            pos->orient != orient) {
397                if (state == BASEP_HIDDEN_LEFT &&
398                    (orient == ORIENT_LEFT ||
399                     orient == ORIENT_UP))
400                        state = BASEP_HIDDEN_RIGHT;
401                else if (state == BASEP_HIDDEN_RIGHT &&
402                         (orient == ORIENT_RIGHT ||
403                          orient == ORIENT_DOWN))
404                         state = BASEP_HIDDEN_LEFT;
405        }
406
407        if (pos->orient != orient) {
408                pos->orient = orient;
409#if 0
410                gtk_signal_emit (GTK_OBJECT (drawer),
411                                 drawer_pos_signals[ORIENT_CHANGE_SIGNAL],
412                                 orient);
413#endif
414        }
415
416        basep_widget_change_params (BASEP_WIDGET (drawer),
417                                    0 /*FIXME */,
418                                    porient,
419                                    sz,
420                                    mode,
421                                    state,
422                                    level,
423                                    avoid_on_maximize,
424                                    hidebuttons_enabled,
425                                    hidebutton_pixmap_enabled,
426                                    back_type,
427                                    back_pixmap,
428                                    fit_pixmap_bg,
429                                    strech_pixmap_bg,
430                                    rotate_pixmap_bg,
431                                    back_color);
432                                   
433}
434
435void
436drawer_widget_change_orient (DrawerWidget *drawer,
437                             PanelOrientType orient)
438{
439        DrawerPos *pos = DRAWER_POS (drawer->pos);
440        if (pos->orient != orient) {
441                BasePWidget *basep = BASEP_WIDGET (drawer);
442                PanelWidget *panel = PANEL_WIDGET (basep->panel);
443                drawer_widget_change_params (drawer,
444                                             orient,
445                                             basep->mode,
446                                             basep->state,
447                                             basep->level,
448                                             basep->avoid_on_maximize,
449                                             panel->sz,
450                                             basep->hidebuttons_enabled,
451                                             basep->hidebutton_pixmaps_enabled,
452                                             panel->back_type,
453                                             panel->back_pixmap,
454                                             panel->fit_pixmap_bg,
455                                             panel->strech_pixmap_bg,
456                                             panel->rotate_pixmap_bg,
457                                             &panel->back_color);
458        }
459}
460
461GtkWidget *
462drawer_widget_new (PanelOrientType orient,
463                   BasePMode mode,
464                   BasePState state,
465                   BasePLevel level,
466                   gboolean avoid_on_maximize,
467                   int sz,
468                   gboolean hidebuttons_enabled,
469                   gboolean hidebutton_pixmap_enabled,
470                   PanelBackType back_type,
471                   char *back_pixmap,
472                   gboolean fit_pixmap_bg,
473                   gboolean strech_pixmap_bg,
474                   gboolean rotate_pixmap_bg,
475                   GdkColor *back_color)
476{
477        DrawerWidget *drawer;
478        DrawerPos *pos;
479        PanelOrientation porient;
480
481        drawer = gtk_type_new (TYPE_DRAWER_WIDGET);
482        drawer->pos = gtk_type_new (TYPE_DRAWER_POS);
483        pos = DRAWER_POS (drawer->pos);
484        pos->orient = orient;
485
486        switch (orient) {
487        case ORIENT_UP:
488        case ORIENT_DOWN:
489                porient = PANEL_VERTICAL;
490                break;
491        default:
492                porient = PANEL_HORIZONTAL;
493                break;
494        }
495
496        basep_widget_construct (BASEP_WIDGET (drawer),
497                                TRUE, TRUE,
498                                0 /*FIXME */,
499                                porient,
500                                sz, mode, state,
501                                level,
502                                avoid_on_maximize,
503                                hidebuttons_enabled,
504                                hidebutton_pixmap_enabled,
505                                back_type,
506                                back_pixmap,
507                                fit_pixmap_bg,
508                                strech_pixmap_bg,
509                                rotate_pixmap_bg,
510                                back_color);
511
512        return GTK_WIDGET (drawer);
513}
514
515#if 0
516void
517drawer_widget_restore_state(DrawerWidget *drawer)
518{
519        DRAWER_POS (BASEP_WIDGET (drawer)->pos)->temp_hidden = FALSE;
520        gtk_widget_queue_resize(GTK_WIDGET(drawer));
521        gtk_widget_show(GTK_WIDGET(drawer));
522}
523#endif
Note: See TracBrowser for help on using the repository browser.