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

Revision 17152, 13.9 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: floating widget
2 * (C) 1999 the Free Software Foundation
3 *
4 * Authors:  Jacob Berkman
5 *           George Lebl
6 *
7 */
8
9#include "config.h"
10
11#include "floating-widget.h"
12#include "border-widget.h"
13#include "panel_config_global.h"
14#include "foobar-widget.h"
15#include "panel-util.h"
16#include "multiscreen-stuff.h"
17
18extern GlobalConfig global_config;
19extern int pw_minimized_size;
20
21static void floating_pos_class_init (FloatingPosClass *klass);
22static void floating_pos_init (FloatingPos *pos);
23
24static void floating_pos_set_hidebuttons (BasePWidget *basep);
25static PanelOrientType floating_pos_get_applet_orient (BasePWidget *basep);
26
27static PanelOrientType floating_pos_get_hide_orient (BasePWidget *basep);
28static void floating_pos_get_hide_pos (BasePWidget *basep,
29                                     PanelOrientType hide_orient,
30                                     int *x, int *y,
31                                     int w, int h);
32
33static void floating_pos_get_pos(BasePWidget *basep,
34                                 int *x, int *y,
35                                 int w, int h);
36
37static void floating_pos_set_pos (BasePWidget *basep,
38                                  int x, int y,
39                                  int w, int h,
40                                  gboolean force);
41
42static void floating_pos_get_hide_size (BasePWidget *basep,
43                                        PanelOrientType hide_orient,
44                                        int *x, int *y);
45
46static void floating_pos_get_menu_pos (BasePWidget *basep,
47                                       GtkWidget *widget,
48                                       GtkRequisition *mreq,
49                                       int *x, int *y,
50                                       int wx, int wy,
51                                       int ww, int wh);
52
53static void floating_pos_pre_convert_hook (BasePWidget *basep);
54
55static void floating_pos_show_hide_left (BasePWidget *basep);
56static void floating_pos_show_hide_right (BasePWidget *basep);
57
58static BasePPosClass *parent_class;
59
60GtkType
61floating_pos_get_type (void)
62{
63        static GtkType floating_pos_type = 0;
64
65        if (floating_pos_type == 0) {
66                GtkTypeInfo floating_pos_info = {
67                        "FloatingPos",
68                        sizeof (FloatingPos),
69                        sizeof (FloatingPosClass),
70                        (GtkClassInitFunc) floating_pos_class_init,
71                        (GtkObjectInitFunc) floating_pos_init,
72                        NULL,
73                        NULL,
74                        NULL
75                };
76
77                floating_pos_type = gtk_type_unique (TYPE_BASEP_POS,
78                                                     &floating_pos_info);
79        }
80
81        return floating_pos_type;
82}
83
84enum {
85        COORDS_CHANGE_SIGNAL,
86        LAST_SIGNAL
87};
88static guint floating_pos_signals[LAST_SIGNAL] = { 0 };
89
90static void
91floating_pos_class_init (FloatingPosClass *klass)
92{
93        GtkObjectClass *object_class = GTK_OBJECT_CLASS(klass);
94        BasePPosClass *pos_class = BASEP_POS_CLASS(klass);
95
96        parent_class = gtk_type_class(TYPE_BASEP_POS);
97
98        floating_pos_signals[COORDS_CHANGE_SIGNAL] =
99                gtk_signal_new ("floating_coords_change",
100                                GTK_RUN_LAST,
101                                object_class->type,
102                                GTK_SIGNAL_OFFSET (FloatingPosClass,
103                                                   coords_change),
104                                gtk_marshal_NONE__INT_INT,
105                                GTK_TYPE_NONE,
106                                2, GTK_TYPE_INT, GTK_TYPE_INT);
107       
108        gtk_object_class_add_signals (object_class,
109                                      floating_pos_signals,
110                                      LAST_SIGNAL);
111       
112        /* fill out the virtual funcs */
113        pos_class->set_hidebuttons = floating_pos_set_hidebuttons;
114        pos_class->get_applet_orient = floating_pos_get_applet_orient;
115        pos_class->get_hide_orient = floating_pos_get_hide_orient;
116        pos_class->get_hide_pos = floating_pos_get_hide_pos;
117        pos_class->get_hide_size = floating_pos_get_hide_size;
118        pos_class->get_pos = floating_pos_get_pos;
119        pos_class->set_pos = floating_pos_set_pos;
120        pos_class->get_menu_pos = floating_pos_get_menu_pos;
121        pos_class->pre_convert_hook = floating_pos_pre_convert_hook;
122        pos_class->north_clicked = pos_class->west_clicked =
123                floating_pos_show_hide_left;
124        pos_class->south_clicked = pos_class->east_clicked =
125                floating_pos_show_hide_right;
126}
127
128static void
129floating_pos_init (FloatingPos *pos) { }
130
131static void
132floating_pos_set_hidebuttons (BasePWidget *basep)
133{
134        if (PANEL_WIDGET(basep->panel)->orient == PANEL_HORIZONTAL) {
135                gtk_widget_hide(basep->hidebutton_n);
136                gtk_widget_show(basep->hidebutton_e);
137                gtk_widget_show(basep->hidebutton_w);
138                gtk_widget_hide(basep->hidebutton_s);
139        } else { /*vertical*/
140                gtk_widget_show(basep->hidebutton_n);
141                gtk_widget_hide(basep->hidebutton_e);
142                gtk_widget_hide(basep->hidebutton_w);
143                gtk_widget_show(basep->hidebutton_s);
144        }
145}
146
147static PanelOrientType
148floating_pos_get_applet_orient (BasePWidget *basep)
149{
150        PanelWidget *panel = PANEL_WIDGET (basep->panel);
151        if (panel->orient == PANEL_HORIZONTAL)
152                return (FLOATING_POS (basep->pos)->y -
153                        multiscreen_y (basep->screen) <
154                        multiscreen_height (basep->screen) / 2)
155                        ? ORIENT_DOWN : ORIENT_UP;
156        else
157                return (FLOATING_POS (basep->pos)->x -
158                        multiscreen_x (basep->screen) <
159                        multiscreen_width (basep->screen) /2)
160                        ? ORIENT_RIGHT : ORIENT_LEFT;
161}
162
163static PanelOrientType
164floating_pos_get_hide_orient (BasePWidget *basep)
165{
166        FloatingPos *pos = FLOATING_POS (basep->pos);
167        PanelWidget *panel = PANEL_WIDGET (basep->panel);
168
169        switch (basep->state) {
170        case BASEP_HIDDEN_LEFT:
171                return (panel->orient == PANEL_HORIZONTAL)
172                        ? ORIENT_LEFT : ORIENT_UP;
173        case BASEP_HIDDEN_RIGHT:
174                return (panel->orient == PANEL_HORIZONTAL)
175                        ? ORIENT_RIGHT : ORIENT_DOWN;
176        case BASEP_AUTO_HIDDEN:
177                if (panel->orient == PANEL_HORIZONTAL) {
178                        return ((pos->x >
179                                 (multiscreen_width (basep->screen) +
180                                  multiscreen_x (basep->screen) - pos->x -
181                                  basep->shown_alloc.width))
182                                ? ORIENT_RIGHT : ORIENT_LEFT);
183                } else {
184                        return ((pos->y >
185                                 (multiscreen_height (basep->screen) +
186                                  multiscreen_y (basep->screen) - pos->y -
187                                  basep->shown_alloc.height))
188                                ? ORIENT_DOWN : ORIENT_UP);
189                }
190        default:
191                g_warning ("not hidden");
192                return -1;
193        }
194}
195
196static void
197floating_pos_get_menu_pos (BasePWidget *basep,
198                           GtkWidget *widget,
199                           GtkRequisition *mreq,
200                           int *x, int *y,
201                           int wx, int wy,
202                           int ww, int wh)
203{       
204        PanelOrientType menu_orient = floating_pos_get_applet_orient (basep);
205       
206        switch (menu_orient) {
207        case ORIENT_DOWN:
208                *x += wx;
209                *y = wy + wh;
210                break;
211        case ORIENT_LEFT:
212                *x = wx - mreq->width;
213                *y += wy;
214                break;
215        default:
216        case ORIENT_UP:
217                *x += wx;
218                *y = wy - mreq->height;
219                break;
220        case ORIENT_RIGHT:
221                *x = wx + ww;
222                *y += wy;
223                break;
224        }
225}
226
227static int
228xclamp (int screen, int x, int w)
229{
230        return CLAMP (x, 0,
231                      multiscreen_width (screen) - w);
232}
233
234static int
235yclamp (int screen, int y, int h)
236{
237        return CLAMP (y, 0,
238                      multiscreen_height (screen) - h -
239                      foobar_widget_get_height (screen));
240}
241
242static void
243floating_pos_set_pos (BasePWidget *basep,
244                      int x, int y,
245                      int w, int h,
246                      gboolean force)
247{
248        FloatingPos *pos = FLOATING_POS(basep->pos);
249        gint16 newx, newy;
250
251        x -= basep->offset_x;
252        y -= basep->offset_y;
253
254        x -= multiscreen_x (basep->screen);
255        y -= multiscreen_y (basep->screen);
256
257        if (PANEL_WIDGET (basep->panel)->orient == PANEL_HORIZONTAL) {
258                switch (basep->state) {
259                case BASEP_SHOWN:
260                case BASEP_MOVING:
261                        break;
262                case BASEP_AUTO_HIDDEN:
263                case BASEP_HIDDEN_LEFT:
264                        w = get_requisition_width (basep->hidebutton_w);
265                        break;
266                case BASEP_HIDDEN_RIGHT:
267                        w = get_requisition_width (basep->hidebutton_e);
268                        break;
269                }
270        }
271
272        newx = xclamp (basep->screen, x, w);
273
274        if (PANEL_WIDGET (basep->panel)->orient == PANEL_VERTICAL) {
275                switch (basep->state) {
276                case BASEP_SHOWN:
277                case BASEP_MOVING:
278                        break;
279                case BASEP_AUTO_HIDDEN:
280                case BASEP_HIDDEN_LEFT:
281                        h = get_requisition_height (basep->hidebutton_n);
282                        break;
283                case BASEP_HIDDEN_RIGHT:
284                        h = get_requisition_height (basep->hidebutton_s);
285                        break;
286                }
287        }
288        newy = yclamp (basep->screen, y, h);
289
290        if (newy != pos->y || newx != pos->x) {
291                pos->x = newx;
292                pos->y = newy;
293                gtk_signal_emit (GTK_OBJECT (pos),
294                                 floating_pos_signals[COORDS_CHANGE_SIGNAL],
295                                 pos->x, pos->y);
296                gtk_widget_queue_resize (GTK_WIDGET (basep));
297        }
298}
299
300static void
301floating_pos_get_pos(BasePWidget *basep,
302                     int *x, int *y,
303                     int w, int h)
304{
305        *x = xclamp (basep->screen, FLOATING_POS (basep->pos)->x, w);
306        *y = yclamp (basep->screen, FLOATING_POS (basep->pos)->y, h);
307        *x += multiscreen_x (basep->screen);
308        *y += multiscreen_y (basep->screen);
309}
310
311static void
312floating_pos_get_hide_size (BasePWidget *basep,
313                            PanelOrientType hide_orient,
314                            int *w, int *h)
315{
316        if (basep->state == BASEP_AUTO_HIDDEN &&
317            ! basep->hidebuttons_enabled) {
318                switch (hide_orient) {
319                case ORIENT_UP:
320                case ORIENT_DOWN:
321                        *h = pw_minimized_size;
322                        break;
323                case ORIENT_LEFT:
324                case ORIENT_RIGHT:
325                        *w = pw_minimized_size;
326                        break;
327                }
328        } else {
329                switch (hide_orient) {
330                case ORIENT_UP:
331                        *h = get_requisition_height (basep->hidebutton_n);
332                        break;
333                case ORIENT_RIGHT:
334                        *w = get_requisition_width (basep->hidebutton_w);
335                        break;
336                case ORIENT_DOWN:
337                        *h = get_requisition_height (basep->hidebutton_s);
338                        break;
339                case ORIENT_LEFT:
340                        *w = get_requisition_width (basep->hidebutton_e);
341                        break;
342                }
343        }
344        /* minimum of 3x3 pixels, as 1x1 is impossible to hit in case
345         * something goes wrong */
346        *w = MAX (*w, 3);
347        *h = MAX (*h, 3);
348}
349
350static void
351floating_pos_get_hide_pos (BasePWidget *basep,
352                           PanelOrientType hide_orient,
353                           int *x, int *y,
354                           int w, int h)
355{
356        switch (hide_orient) {
357        case ORIENT_UP:
358        case ORIENT_LEFT:
359                break;
360        case ORIENT_RIGHT:
361                *x += w - ((basep->state == BASEP_AUTO_HIDDEN &&
362                            ! basep->hidebuttons_enabled)
363                           ? pw_minimized_size
364                           : get_requisition_width (basep->hidebutton_w));
365                break;
366        case ORIENT_DOWN:
367                *y += h - ((basep->state == BASEP_AUTO_HIDDEN &&
368                            ! basep->hidebuttons_enabled)
369                           ? pw_minimized_size
370                           : get_requisition_height (basep->hidebutton_s));
371                break;
372        }
373}
374
375static void
376floating_pos_show_hide_left (BasePWidget *basep)
377{
378        switch (basep->state) {
379        case BASEP_SHOWN:
380                basep_widget_explicit_hide (basep, BASEP_HIDDEN_LEFT);
381                break;
382        case BASEP_HIDDEN_RIGHT:
383                basep_widget_explicit_show (basep);
384                break;
385        default:
386                break;
387        }
388}
389
390static void
391floating_pos_show_hide_right (BasePWidget *basep)
392{
393        switch (basep->state) {
394        case BASEP_SHOWN:
395                basep_widget_explicit_hide (basep, BASEP_HIDDEN_RIGHT);
396                break;
397        case BASEP_HIDDEN_LEFT:
398                basep_widget_explicit_show (basep);
399                break;
400        default:
401                break;
402        }
403}
404
405static void
406floating_pos_pre_convert_hook (BasePWidget *basep)
407{
408        basep->keep_in_screen = TRUE;
409        PANEL_WIDGET (basep->panel)->packed = TRUE;
410}
411
412void
413floating_widget_change_params (FloatingWidget *floating,
414                               int screen,
415                               gint16 x,
416                               gint16 y,
417                               PanelOrientation orient,
418                               BasePMode mode,
419                               BasePState state,
420                               BasePLevel level,
421                               gboolean avoid_on_maximize,
422                               int sz,
423                               gboolean hidebuttons_enabled,
424                               gboolean hidebutton_pixmap_enabled,
425                               PanelBackType back_type,
426                               char *back_pixmap,
427                               gboolean fit_pixmap_bg,
428                               gboolean strech_pixmap_bg,
429                               gboolean rotate_pixmap_bg,
430                               GdkColor *back_color)
431{
432        BasePWidget *basep = BASEP_WIDGET (floating);
433        FloatingPos *pos = FLOATING_POS (basep->pos);
434
435        if (PANEL_WIDGET (basep->panel)->orient != orient)
436                BASEP_WIDGET (floating)->request_cube = TRUE;
437
438        x = xclamp (basep->screen, x, basep->shown_alloc.width);
439        y = yclamp (basep->screen, y, basep->shown_alloc.height);
440
441        if (y != pos->y || x != pos->x) {
442                pos->x = x;
443                pos->y = y;
444                gtk_signal_emit (GTK_OBJECT (pos),
445                                 floating_pos_signals[COORDS_CHANGE_SIGNAL],
446                                 x, y);
447        }
448
449        basep_widget_change_params (basep,
450                                    screen,
451                                    orient,
452                                    sz,
453                                    mode,
454                                    state,
455                                    level,
456                                    avoid_on_maximize,
457                                    hidebuttons_enabled,
458                                    hidebutton_pixmap_enabled,
459                                    back_type,
460                                    back_pixmap,
461                                    fit_pixmap_bg,
462                                    strech_pixmap_bg,
463                                    rotate_pixmap_bg,
464                                    back_color);
465                                   
466}
467
468void
469floating_widget_change_orient (FloatingWidget *floating,
470                               PanelOrientation orient)
471{
472        FloatingPos *pos = FLOATING_POS (floating->pos);
473        if (PANEL_WIDGET (BASEP_WIDGET (floating)->panel)->orient != orient) {
474                BasePWidget *basep = BASEP_WIDGET (floating);
475                PanelWidget *panel = PANEL_WIDGET (basep->panel);
476                floating_widget_change_params (floating,
477                                               basep->screen,
478                                               pos->x,
479                                               pos->y,
480                                               orient,
481                                               basep->mode,
482                                               basep->state,
483                                               basep->level,
484                                               basep->avoid_on_maximize,
485                                               panel->sz,
486                                               basep->hidebuttons_enabled,
487                                               basep->hidebutton_pixmaps_enabled,
488                                               panel->back_type,
489                                               panel->back_pixmap,
490                                               panel->fit_pixmap_bg,
491                                               panel->strech_pixmap_bg,
492                                               panel->rotate_pixmap_bg,
493                                               &panel->back_color);
494        }
495}
496
497void
498floating_widget_change_coords (FloatingWidget *floating,
499                               gint16 x, gint16 y)
500{
501        FloatingPos *pos = FLOATING_POS (floating->pos);
502        if (pos->x != x || pos->y != y) {
503                BasePWidget *basep = BASEP_WIDGET (floating);
504                PanelWidget *panel = PANEL_WIDGET (basep->panel);
505                floating_widget_change_params (floating,
506                                               basep->screen,
507                                               x,
508                                               y,
509                                               panel->orient,
510                                               basep->mode,
511                                               basep->state,
512                                               basep->level,
513                                               basep->avoid_on_maximize,
514                                               panel->sz,
515                                               basep->hidebuttons_enabled,
516                                               basep->hidebutton_pixmaps_enabled,
517                                               panel->back_type,
518                                               panel->back_pixmap,
519                                               panel->fit_pixmap_bg,
520                                               panel->strech_pixmap_bg,
521                                               panel->rotate_pixmap_bg,
522                                               &panel->back_color);
523        }
524}
525
526GtkWidget *
527floating_widget_new (int screen,
528                     gint16 x,
529                     gint16 y,
530                     PanelOrientation orient,
531                     BasePMode mode,
532                     BasePState state,
533                     BasePLevel level,
534                     gboolean avoid_on_maximize,
535                     int sz,
536                     gboolean hidebuttons_enabled,
537                     gboolean hidebutton_pixmap_enabled,
538                     PanelBackType back_type,
539                     char *back_pixmap,
540                     gboolean fit_pixmap_bg,
541                     gboolean strech_pixmap_bg,
542                     gboolean rotate_pixmap_bg,
543                     GdkColor *back_color)
544{
545        FloatingWidget *floating;
546        FloatingPos *pos;
547
548        floating = gtk_type_new (TYPE_FLOATING_WIDGET);
549        floating->pos = gtk_type_new (TYPE_FLOATING_POS);
550        pos = FLOATING_POS (floating->pos);
551
552        pos->x = x;
553        pos->y = y;
554
555        basep_widget_construct (BASEP_WIDGET (floating),
556                                TRUE, FALSE,
557                                screen,
558                                orient,
559                                sz,
560                                mode,
561                                state,
562                                level,
563                                avoid_on_maximize,
564                                hidebuttons_enabled,
565                                hidebutton_pixmap_enabled,
566                                back_type,
567                                back_pixmap,
568                                fit_pixmap_bg,
569                                strech_pixmap_bg,
570                                rotate_pixmap_bg,
571                                back_color);
572
573        return GTK_WIDGET (floating);
574}
Note: See TracBrowser for help on using the repository browser.