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

Revision 17152, 12.1 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: sliding widget
2 * (C) 1999 the Free Software Foundation
3 *
4 * Authors:  Jacob Berkman
5 *           George Lebl
6 */
7
8#include "config.h"
9
10#include "sliding-widget.h"
11#include "panel_config_global.h"
12#include "foobar-widget.h"
13#include "panel-util.h"
14#include "multiscreen-stuff.h"
15
16extern GlobalConfig global_config;
17extern int pw_minimized_size;
18
19static void sliding_pos_class_init (SlidingPosClass *klass);
20static void sliding_pos_init (SlidingPos *pos);
21
22static void sliding_pos_set_pos (BasePWidget *basep,
23                                 int x, int y,
24                                 int w, int h,
25                                 gboolean force);
26static void sliding_pos_get_pos (BasePWidget *basep,
27                                 int *x, int *y,
28                                 int w, int h);
29
30static BorderPosClass *parent_class;
31
32GtkType
33sliding_pos_get_type (void)
34{
35        static GtkType sliding_pos_type = 0;
36
37        if (sliding_pos_type == 0) {
38                GtkTypeInfo sliding_pos_info = {
39                        "SlidingPos",
40                        sizeof (SlidingPos),
41                        sizeof (SlidingPosClass),
42                        (GtkClassInitFunc) sliding_pos_class_init,
43                        (GtkObjectInitFunc) sliding_pos_init,
44                        NULL,
45                        NULL,
46                        NULL
47                };
48
49                sliding_pos_type = gtk_type_unique (TYPE_BORDER_POS,
50                                                    &sliding_pos_info);
51        }
52                               
53        return sliding_pos_type;
54}
55
56enum {
57        ANCHOR_CHANGE_SIGNAL,
58        OFFSET_CHANGE_SIGNAL,
59        LAST_SIGNAL
60};
61
62static guint sliding_pos_signals[LAST_SIGNAL] = { 0, 0 };
63
64static void
65sliding_pos_class_init (SlidingPosClass *klass)
66{
67        BasePPosClass *pos_class = BASEP_POS_CLASS(klass);
68        GtkObjectClass *object_class = GTK_OBJECT_CLASS(klass);
69        parent_class = gtk_type_class(TYPE_BORDER_POS);
70
71        sliding_pos_signals[ANCHOR_CHANGE_SIGNAL] =
72                gtk_signal_new("anchor_change",
73                               GTK_RUN_LAST,
74                               object_class->type,
75                               GTK_SIGNAL_OFFSET(SlidingPosClass,
76                                                 anchor_change),
77                               gtk_marshal_NONE__ENUM,
78                               GTK_TYPE_NONE,
79                               1, GTK_TYPE_ENUM);
80
81        sliding_pos_signals[OFFSET_CHANGE_SIGNAL] =
82                gtk_signal_new("offset_change",
83                               GTK_RUN_LAST,
84                               object_class->type,
85                               GTK_SIGNAL_OFFSET(SlidingPosClass,
86                                                 offset_change),
87                               gtk_marshal_NONE__INT,
88                               GTK_TYPE_NONE,
89                               2, GTK_TYPE_INT,
90                               GTK_TYPE_INT);
91
92        gtk_object_class_add_signals (object_class,
93                                      sliding_pos_signals,
94                                      LAST_SIGNAL);
95       
96        pos_class->set_pos = sliding_pos_set_pos;
97        pos_class->get_pos = sliding_pos_get_pos;
98}
99
100static void
101sliding_pos_init (SlidingPos *pos) { }
102
103static void
104sliding_pos_set_pos (BasePWidget *basep,
105                     int x, int y,
106                     int w, int h,
107                     gboolean force)
108{
109        int minx, miny, maxx, maxy, offset_x, offset_y;
110        SlidingPos *pos = SLIDING_POS(basep->pos);
111        BorderEdge newedge = BORDER_POS(basep->pos)->edge;
112        SlidingAnchor newanchor = pos->anchor;
113        gint16 newoffset = pos->offset;
114        gboolean check_pos = TRUE;
115        int innerx, innery;
116        int screen_width, screen_height;
117
118        gdk_window_get_geometry (GTK_WIDGET(basep)->window, &minx, &miny,
119                                 &maxx, &maxy, NULL);
120        gdk_window_get_origin (GTK_WIDGET(basep)->window, &minx, &miny);
121        maxx += minx;
122        maxy += miny;
123
124        /* FIXME: how does screenchanging interact with depending on
125         * the above positions of the actual X windows stuff */
126       
127        innerx = x - multiscreen_x (basep->screen);
128        innery = y - multiscreen_y (basep->screen);
129        screen_width = multiscreen_width (basep->screen);
130        screen_height = multiscreen_height (basep->screen);
131
132        /*if in the inner 1/3rd, don't change to avoid fast flickery
133          movement*/
134        if (innerx > (screen_width / 3) &&
135            innerx < (2*screen_width / 3) &&
136            innery > (screen_height / 3) &&
137            innery < (2*screen_height / 3))
138                return;
139
140        /* don't switch the position if we are along the edge.
141           do this so that it won't flip-flop orientations in
142           the corners */
143        switch (BORDER_POS (pos)->edge) {
144        case BORDER_TOP:
145                check_pos = (y > maxy);
146                break;
147        case BORDER_BOTTOM:
148                check_pos = (y < miny);
149                break;
150        case BORDER_LEFT:
151                check_pos = (x > maxx);
152                break;
153        case BORDER_RIGHT:
154                check_pos = (x < minx);
155                break;
156        }
157
158        if (check_pos) {
159                if (innerx * screen_height > innery * screen_width ) {
160                        if(screen_height * (screen_width - innerx) >
161                           innery * screen_width)
162                                newedge = BORDER_TOP;
163                        else
164                                newedge = BORDER_RIGHT;
165                } else {
166                        if(screen_height * (screen_width - innerx) >
167                           innery * screen_width)
168                                newedge = BORDER_LEFT;
169                        else
170                                newedge = BORDER_BOTTOM;
171                }
172
173                /* we need to do this since the sizes might have changed
174                   (orientation changes and what not) */
175                if(newedge != BORDER_POS(basep->pos)->edge) {
176                        PanelOrientation old_orient;
177                        old_orient = PANEL_WIDGET (basep->panel)->orient;
178
179                        border_widget_change_edge (BORDER_WIDGET(basep),
180                                                   newedge);
181                        basep_widget_get_size (basep, &w, &h);
182
183                        /* if change of orient, swap offsets */
184                        if (old_orient != PANEL_WIDGET (basep->panel)->orient) {
185                                int tmp = basep->offset_x;
186                                basep->offset_x = basep->offset_y;
187                                basep->offset_y = tmp;
188                        }
189                }
190        }
191
192        offset_x = basep->offset_x;
193        if (offset_x > w)
194                offset_x = 0.99 * w; /* not completely on the edge */
195        offset_y = basep->offset_y;
196        if (offset_y > h)
197                offset_y = 0.99 * h; /* not completely on the edge */
198
199        g_assert (newedge == BORDER_POS (pos)->edge);
200        g_assert (newanchor == pos->anchor);
201
202        switch (PANEL_WIDGET (basep->panel)->orient) {
203        case PANEL_HORIZONTAL:
204                newanchor =  (innerx < 0.1 * screen_width)
205                        ? SLIDING_ANCHOR_LEFT
206                        : ( (innerx > 0.9 * screen_width)
207                            ? SLIDING_ANCHOR_RIGHT
208                            : newanchor);
209                if (newanchor == SLIDING_ANCHOR_LEFT) {
210                        newoffset = innerx - offset_x;
211                        if (basep->state == BASEP_HIDDEN_RIGHT)
212                                newoffset -= w - get_requisition_width (basep->hidebutton_e);
213                } else {
214                        newoffset = screen_width -
215                                (innerx - offset_x) - w;
216                        if (basep->state == BASEP_HIDDEN_LEFT)
217                                newoffset -= w - get_requisition_width (basep->hidebutton_w);
218                }
219                newoffset = CLAMP (newoffset, 0, screen_width - w);
220                break;
221        case PANEL_VERTICAL:
222                newanchor =  (innery < 0.1 * screen_height)
223                        ? SLIDING_ANCHOR_LEFT
224                        : ( (innery > 0.9 * screen_height)
225                            ? SLIDING_ANCHOR_RIGHT
226                            : newanchor);
227                if (newanchor == SLIDING_ANCHOR_LEFT) {
228                        newoffset = innery - offset_y;
229                        if (basep->state == BASEP_HIDDEN_RIGHT)
230                                newoffset -= h - get_requisition_height (basep->hidebutton_s);
231                } else {
232                        newoffset = screen_height -
233                                (innery - offset_y) - h;
234                        if (basep->state == BASEP_HIDDEN_LEFT)
235                                newoffset -= h - get_requisition_height (basep->hidebutton_n);
236                }
237                newoffset = CLAMP (newoffset, 0, screen_height - h);
238                break;
239        }
240
241        if (newanchor != pos->anchor)
242                sliding_widget_change_anchor (SLIDING_WIDGET (basep),
243                                              newanchor);
244
245        if (newoffset != pos->offset)
246                sliding_widget_change_offset (SLIDING_WIDGET (basep),
247                                              newoffset);
248}
249
250static void
251sliding_pos_get_pos (BasePWidget *basep, int *x, int *y,
252                     int w, int h)
253{
254        SlidingPos *pos = SLIDING_POS (basep->pos);
255        *x = *y = 0;
256
257        switch (BORDER_POS (basep->pos)->edge) {
258        case BORDER_BOTTOM:
259                *y = multiscreen_height (basep->screen) - h - foobar_widget_get_height (basep->screen);
260                /* fall through */
261        case BORDER_TOP:
262                (*y) += foobar_widget_get_height (basep->screen);
263                *x = (pos->anchor == SLIDING_ANCHOR_LEFT)
264                        ? pos->offset
265                        : multiscreen_width (basep->screen) - pos->offset - w;
266                break;
267        case BORDER_RIGHT:
268                *x = multiscreen_width (basep->screen) - w;
269                /* fall through */
270        case BORDER_LEFT:
271                *y = (pos->anchor == SLIDING_ANCHOR_LEFT)
272                        ? pos->offset
273                        : multiscreen_height (basep->screen) - pos->offset - h;
274                *y = MAX (*y, foobar_widget_get_height (basep->screen));
275                break;
276        }
277
278        *x += multiscreen_x (basep->screen);
279        *y += multiscreen_y (basep->screen);
280}
281
282GtkWidget *
283sliding_widget_new (int screen,
284                    SlidingAnchor anchor,
285                    gint16 offset,
286                    BorderEdge edge,
287                    BasePMode mode,
288                    BasePState state,
289                    BasePLevel level,
290                    gboolean avoid_on_maximize,
291                    int sz,
292                    gboolean hidebuttons_enabled,
293                    gboolean hidebutton_pixmaps_enabled,
294                    PanelBackType back_type,
295                    char *back_pixmap,
296                    gboolean fit_pixmap_bg,
297                    gboolean strech_pixmap_bg,
298                    gboolean rotate_pixmap_bg,
299                    GdkColor *back_color)
300{
301        SlidingWidget *sliding = gtk_type_new (TYPE_SLIDING_WIDGET);
302        SlidingPos *pos = gtk_type_new (TYPE_SLIDING_POS);
303
304        pos->anchor = anchor;
305        pos->offset = offset;
306       
307        BASEP_WIDGET (sliding)->pos = BASEP_POS (pos);
308
309        border_widget_construct (BORDER_WIDGET (sliding),
310                                 screen,
311                                 edge,
312                                 TRUE,
313                                 FALSE,
314                                 sz,
315                                 mode,
316                                 state,
317                                 level,
318                                 avoid_on_maximize,
319                                 hidebuttons_enabled,
320                                 hidebutton_pixmaps_enabled,
321                                 back_type,
322                                 back_pixmap,
323                                 fit_pixmap_bg, strech_pixmap_bg,
324                                 rotate_pixmap_bg,
325                                 back_color);
326
327        return GTK_WIDGET (sliding);
328}
329
330void
331sliding_widget_change_params (SlidingWidget *sliding,
332                              int screen,
333                              SlidingAnchor anchor,
334                              gint16 offset,
335                              BorderEdge edge,
336                              int sz,
337                              BasePMode mode,
338                              BasePState state,
339                              BasePLevel level,
340                              gboolean avoid_on_maximize,
341                              gboolean hidebuttons_enabled,
342                              gboolean hidebutton_pixmaps_enabled,
343                              PanelBackType back_type,
344                              char *pixmap_name,
345                              gboolean fit_pixmap_bg,
346                              gboolean strech_pixmap_bg,
347                              gboolean rotate_pixmap_bg,
348                              GdkColor *back_color)
349{
350        SlidingPos *pos = SLIDING_POS (BASEP_WIDGET (sliding)->pos);
351
352        if (anchor != pos->anchor) {
353                pos->anchor = anchor;
354                gtk_signal_emit (GTK_OBJECT (pos),
355                                 sliding_pos_signals[ANCHOR_CHANGE_SIGNAL],
356                                 anchor);
357               
358        }
359
360        if (offset != pos->offset) {
361                pos->offset = offset;
362                gtk_signal_emit (GTK_OBJECT (pos),
363                                 sliding_pos_signals[OFFSET_CHANGE_SIGNAL],
364                                 offset);
365        }
366
367        border_widget_change_params (BORDER_WIDGET (sliding),
368                                     screen,
369                                     edge,
370                                     sz,
371                                     mode,
372                                     state,
373                                     level,
374                                     avoid_on_maximize,
375                                     hidebuttons_enabled,
376                                     hidebutton_pixmaps_enabled,
377                                     back_type,
378                                     pixmap_name,
379                                     fit_pixmap_bg,
380                                     strech_pixmap_bg,
381                                     rotate_pixmap_bg,
382                                     back_color);
383}
384
385void
386sliding_widget_change_offset (SlidingWidget *sliding, gint16 offset)
387{
388        BasePWidget *basep = BASEP_WIDGET (sliding);
389        PanelWidget *panel = PANEL_WIDGET (basep->panel);
390        SlidingPos *pos = SLIDING_POS (basep->pos);
391
392        if (offset == pos->offset)
393                return;
394
395        sliding_widget_change_params (sliding,
396                                      basep->screen,
397                                      pos->anchor,
398                                      offset,
399                                      BORDER_POS (pos)->edge,
400                                      panel->sz,
401                                      basep->mode,
402                                      basep->state,
403                                      basep->level,
404                                      basep->avoid_on_maximize,
405                                      basep->hidebuttons_enabled,
406                                      basep->hidebutton_pixmaps_enabled,
407                                      panel->back_type,
408                                      panel->back_pixmap,
409                                      panel->fit_pixmap_bg,
410                                      panel->strech_pixmap_bg,
411                                      panel->rotate_pixmap_bg,
412                                      &panel->back_color);
413}
414
415void
416sliding_widget_change_anchor (SlidingWidget *sliding, SlidingAnchor anchor)
417{
418        BasePWidget *basep = BASEP_WIDGET (sliding);
419        PanelWidget *panel = PANEL_WIDGET (basep->panel);
420        SlidingPos *pos = SLIDING_POS (basep->pos);
421
422        if (anchor == pos->anchor)
423                return;
424
425        sliding_widget_change_params (sliding,
426                                      basep->screen,
427                                      anchor,
428                                      pos->offset,
429                                      BORDER_POS (pos)->edge,
430                                      panel->sz,
431                                      basep->mode,
432                                      basep->state,
433                                      basep->level,
434                                      basep->avoid_on_maximize,
435                                      basep->hidebuttons_enabled,
436                                      basep->hidebutton_pixmaps_enabled,
437                                      panel->back_type,
438                                      panel->back_pixmap,
439                                      panel->fit_pixmap_bg,
440                                      panel->strech_pixmap_bg,
441                                      panel->rotate_pixmap_bg,
442                                      &panel->back_color);
443}
444
445void
446sliding_widget_change_anchor_offset_edge (SlidingWidget *sliding,
447                                          SlidingAnchor anchor,
448                                          gint16 offset,
449                                          BorderEdge edge)
450{
451        BasePWidget *basep = BASEP_WIDGET (sliding);
452        PanelWidget *panel = PANEL_WIDGET (basep->panel);
453
454        sliding_widget_change_params (sliding,
455                                      basep->screen,
456                                      anchor,
457                                      offset,
458                                      edge,
459                                      panel->sz,
460                                      basep->mode,
461                                      basep->state,
462                                      basep->level,
463                                      basep->avoid_on_maximize,
464                                      basep->hidebuttons_enabled,
465                                      basep->hidebutton_pixmaps_enabled,
466                                      panel->back_type,
467                                      panel->back_pixmap,
468                                      panel->fit_pixmap_bg,
469                                      panel->strech_pixmap_bg,
470                                      panel->rotate_pixmap_bg,
471                                      &panel->back_color);
472}
Note: See TracBrowser for help on using the repository browser.