source: trunk/third/gnome-core/panel/aligned-widget.c @ 16298

Revision 16298, 10.3 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r16297, which included commits to RCS files with non-trunk default branches.
Line 
1/* Gnome panel: aligned (corner) widget
2 * (C) 1999 the Free Software Foundation
3 *
4 * Authores:  Jacob Berkman
5 *            George Lebl
6 */
7
8#include "config.h"
9#include "aligned-widget.h"
10#include "panel_config_global.h"
11#include "foobar-widget.h"
12#include "multiscreen-stuff.h"
13
14extern GlobalConfig global_config;
15extern int pw_minimized_size;
16
17static void aligned_pos_class_init (AlignedPosClass *klass);
18static void aligned_pos_init (AlignedPos *pos);
19
20static void aligned_pos_set_pos (BasePWidget *basep,
21                                 int x, int y,
22                                 int w, int h);
23static void aligned_pos_get_pos (BasePWidget *basep,
24                                 int *x, int *y,
25                                 int w, int h);
26
27static void aligned_pos_show_hide_left (BasePWidget *basep);
28static void aligned_pos_show_hide_right (BasePWidget *basep);
29static BorderPosClass *parent_class;
30
31GtkType
32aligned_pos_get_type (void)
33{
34        static GtkType aligned_pos_type = 0;
35
36        if (aligned_pos_type == 0) {
37                GtkTypeInfo aligned_pos_info = {
38                        "AlignedPos",
39                        sizeof (AlignedPos),
40                        sizeof (AlignedPosClass),
41                        (GtkClassInitFunc) aligned_pos_class_init,
42                        (GtkObjectInitFunc) aligned_pos_init,
43                        NULL,
44                        NULL,
45                        NULL
46                };
47
48                aligned_pos_type = gtk_type_unique (TYPE_BORDER_POS,
49                                                    &aligned_pos_info);
50        }
51                               
52        return aligned_pos_type;
53}
54
55enum {
56        ALIGN_CHANGE_SIGNAL,
57        LAST_SIGNAL
58};
59
60static guint aligned_pos_signals[LAST_SIGNAL] = { 0 };
61
62static void
63aligned_pos_class_init (AlignedPosClass *klass)
64{
65        BasePPosClass *pos_class = BASEP_POS_CLASS(klass);
66        GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
67        parent_class = gtk_type_class(TYPE_BORDER_POS);
68       
69        aligned_pos_signals[ALIGN_CHANGE_SIGNAL] =
70                gtk_signal_new ("align_change",
71                                GTK_RUN_LAST,
72                                object_class->type,
73                                GTK_SIGNAL_OFFSET (AlignedPosClass,
74                                                   align_change),
75                                gtk_marshal_NONE__ENUM,
76                                GTK_TYPE_NONE,
77                                1, GTK_TYPE_ENUM);
78
79        gtk_object_class_add_signals (object_class,
80                                      aligned_pos_signals,
81                                      LAST_SIGNAL);
82
83        pos_class->set_pos = aligned_pos_set_pos;
84        pos_class->get_pos = aligned_pos_get_pos;
85        pos_class->north_clicked = pos_class->west_clicked =
86                aligned_pos_show_hide_left;
87        pos_class->south_clicked = pos_class->east_clicked =
88                aligned_pos_show_hide_right;
89}
90
91static void
92aligned_pos_init (AlignedPos *pos) { }
93
94static void
95aligned_pos_set_pos (BasePWidget *basep,
96                     int x, int y,
97                     int w, int h)
98{
99        int minx, miny, maxx, maxy;
100        int innerx, innery;
101        int screen_width, screen_height;
102
103        BorderEdge newpos = BORDER_POS(basep->pos)->edge;
104        AlignedAlignment newalign = ALIGNED_POS(basep->pos)->align;
105
106        gdk_window_get_geometry (GTK_WIDGET(basep)->window,
107                                 &minx, &miny, &maxx, &maxy, NULL);
108        gdk_window_get_origin (GTK_WIDGET(basep)->window, &minx, &miny);
109        maxx += minx;
110        maxy += miny;
111        if (x >= minx &&
112            x <= maxx &&
113            y >= miny &&
114            y <= maxy)
115                return;
116
117        /* FIXME: screenchanging stuff */
118       
119        innerx = x - multiscreen_x (basep->screen);
120        innery = y - multiscreen_y (basep->screen);
121        screen_width = multiscreen_width (basep->screen);
122        screen_height = multiscreen_height (basep->screen);
123
124        /*if in the inner 1/3rd, don't change to avoid fast flickery
125          movement*/
126        if ( innerx > (screen_width / 3) &&
127             innerx < (2*screen_width / 3) &&
128             innery > (screen_height / 3) &&
129             innery < (2*screen_height / 3))
130                return;
131
132        if (innerx * screen_height > innery * screen_width ) {
133                if (screen_height * (screen_width-innerx) >
134                    innery * screen_width ) {
135                        newpos = BORDER_TOP;
136                        if (innerx < screen_width/3)
137                                newalign = ALIGNED_LEFT;
138                        else if (innerx < 2*screen_width/3)
139                                newalign = ALIGNED_CENTER;
140                        else
141                                newalign = ALIGNED_RIGHT;
142                } else {
143                        newpos = BORDER_RIGHT;
144                        if (innery < screen_height/3)
145                                newalign = ALIGNED_LEFT;
146                        else if (innery < 2*screen_height/3)
147                                newalign = ALIGNED_CENTER;
148                        else
149                                newalign = ALIGNED_RIGHT;
150                }
151        } else {
152                if (screen_height * (screen_width-innerx) >
153                    innery * screen_width ) {
154                        newpos = BORDER_LEFT;
155                        if (innery < screen_height/3)
156                                newalign = ALIGNED_LEFT;
157                        else if (innery < 2*screen_height/3)
158                                newalign = ALIGNED_CENTER;
159                        else
160                                newalign = ALIGNED_RIGHT;
161                } else {
162                        newpos = BORDER_BOTTOM;
163                        if (innerx < screen_width/3)
164                                newalign = ALIGNED_LEFT;
165                        else if (innerx < 2*screen_width/3)
166                                newalign = ALIGNED_CENTER;
167                        else
168                                newalign = ALIGNED_RIGHT;
169                }
170        }
171
172        if(newalign != ALIGNED_POS(basep->pos)->align)
173                aligned_widget_change_align (ALIGNED_WIDGET(basep), newalign);
174       
175        if(newpos != BORDER_POS(basep->pos)->edge)
176                border_widget_change_edge (BORDER_WIDGET(basep), newpos);
177
178}
179
180static void
181aligned_pos_get_pos (BasePWidget *basep, int *x, int *y,
182                     int w, int h)
183{
184        int a, b;
185        BorderEdge edge = BORDER_POS(basep->pos)->edge;
186
187        *x = *y = 0;
188        switch (edge) {
189        case BORDER_BOTTOM:
190                *y = multiscreen_height(basep->screen) - h - foobar_widget_get_height (basep->screen);
191                /* fall thru */
192        case BORDER_TOP:
193                *y += foobar_widget_get_height (basep->screen);
194                switch (ALIGNED_POS(basep->pos)->align) {
195                case ALIGNED_LEFT:
196                        break;
197                case ALIGNED_CENTER:
198                        *x = (multiscreen_width(basep->screen) - w) / 2;
199                        break;
200                case ALIGNED_RIGHT:
201                        *x = multiscreen_width(basep->screen) - w;
202                        break;
203                }
204                break;
205        case BORDER_RIGHT:
206                *x = multiscreen_width(basep->screen) - w;
207                basep_border_get (BORDER_TOP, NULL, NULL, &a);
208                basep_border_get (BORDER_BOTTOM, NULL, NULL, &b);
209                switch (ALIGNED_POS(basep->pos)->align) {
210                case ALIGNED_LEFT:
211                        *y = foobar_widget_get_height (basep->screen) + a;
212                        break;
213                case ALIGNED_CENTER:
214                        *y = (multiscreen_height(basep->screen) - h) / 2;
215                        break;
216                case ALIGNED_RIGHT:
217                        *y = multiscreen_height(basep->screen) - h - b;
218                        break;
219                }
220                break;
221        case BORDER_LEFT:
222                basep_border_get (BORDER_TOP, &a, NULL, NULL);
223                basep_border_get (BORDER_BOTTOM, &b, NULL, NULL);
224                switch (ALIGNED_POS(basep->pos)->align) {
225                case ALIGNED_LEFT:
226                        *y = foobar_widget_get_height (basep->screen) + a;
227                        break;
228                case ALIGNED_CENTER:
229                        *y = (multiscreen_height(basep->screen) - h) / 2;
230                        break;
231                case ALIGNED_RIGHT:
232                        *y = multiscreen_height(basep->screen) - h - b;
233                        break;
234                }
235                break;
236        }
237
238        *x += multiscreen_x (basep->screen);
239        *y += multiscreen_y (basep->screen);
240
241        basep_border_queue_recalc ();
242}
243
244static void
245aligned_pos_show_hide_left (BasePWidget *basep)
246{
247        switch (basep->state) {
248        case BASEP_SHOWN:
249                if (ALIGNED_POS (basep->pos)->align == ALIGNED_RIGHT)
250                        aligned_widget_change_align (ALIGNED_WIDGET (basep),
251                                                     ALIGNED_LEFT);
252                else
253                        basep_widget_explicit_hide (basep, BASEP_HIDDEN_LEFT);
254                break;
255        case BASEP_HIDDEN_RIGHT:
256                basep_widget_explicit_show (basep);
257                break;
258        default:
259                break;
260        }
261}
262
263
264static void
265aligned_pos_show_hide_right (BasePWidget *basep)
266{
267        switch (basep->state) {
268        case BASEP_SHOWN:
269                if (ALIGNED_POS (basep->pos)->align == ALIGNED_LEFT)
270                        aligned_widget_change_align (ALIGNED_WIDGET (basep),
271                                                     ALIGNED_RIGHT);
272                else
273                        basep_widget_explicit_hide (basep, BASEP_HIDDEN_RIGHT);
274                break;
275        case BASEP_HIDDEN_LEFT:
276                basep_widget_explicit_show (basep);
277                break;
278        default:
279                break;
280        }
281}
282
283void
284aligned_widget_change_params (AlignedWidget *aligned,
285                              AlignedAlignment align,
286                              BorderEdge edge,
287                              int sz,
288                              BasePMode mode,
289                              BasePState state,
290                              BasePLevel level,
291                              gboolean avoid_on_maximize,
292                              gboolean hidebuttons_enabled,
293                              gboolean hidebutton_pixmaps_enabled,
294                              PanelBackType back_type,
295                              char *pixmap_name,
296                              gboolean fit_pixmap_bg,
297                              gboolean strech_pixmap_bg,
298                              gboolean rotate_pixmap_bg,
299                              GdkColor *back_color)
300{
301        AlignedPos *pos = ALIGNED_POS (BASEP_WIDGET (aligned)->pos);
302
303        if (pos->align != align) {
304                pos->align = align;
305                gtk_signal_emit (GTK_OBJECT (pos),
306                                 aligned_pos_signals[ALIGN_CHANGE_SIGNAL],
307                                 align);
308        }
309
310        border_widget_change_params (BORDER_WIDGET (aligned),
311                                     edge, sz, mode, state,
312                                     level, avoid_on_maximize,
313                                     hidebuttons_enabled,
314                                     hidebutton_pixmaps_enabled,
315                                     back_type, pixmap_name,
316                                     fit_pixmap_bg, strech_pixmap_bg,
317                                     rotate_pixmap_bg,
318                                     back_color);
319}
320
321
322void
323aligned_widget_change_align (AlignedWidget *aligned,
324                             AlignedAlignment align)
325{
326        BasePWidget *basep = BASEP_WIDGET (aligned);
327        PanelWidget *panel = PANEL_WIDGET (basep->panel);
328        AlignedPos *pos = ALIGNED_POS (basep->pos);
329
330        if (pos->align == align)
331                return;
332
333        aligned_widget_change_params (aligned, align,
334                                      BORDER_POS (pos)->edge,
335                                      panel->sz, basep->mode,
336                                      basep->state,
337                                      basep->level,
338                                      basep->avoid_on_maximize,
339                                      basep->hidebuttons_enabled,
340                                      basep->hidebutton_pixmaps_enabled,
341                                      panel->back_type,
342                                      panel->back_pixmap,
343                                      panel->fit_pixmap_bg,
344                                      panel->strech_pixmap_bg,
345                                      panel->rotate_pixmap_bg,
346                                      &panel->back_color);
347}
348
349void
350aligned_widget_change_align_edge (AlignedWidget *aligned,
351                                  AlignedAlignment align,
352                                  BorderEdge edge)
353{
354        BasePWidget *basep = BASEP_WIDGET (aligned);
355        PanelWidget *panel = PANEL_WIDGET (basep->panel);
356
357        aligned_widget_change_params (aligned, align, edge,
358                                      panel->sz, basep->mode,
359                                      basep->state,
360                                      basep->level,
361                                      basep->avoid_on_maximize,
362                                      basep->hidebuttons_enabled,
363                                      basep->hidebutton_pixmaps_enabled,
364                                      panel->back_type,
365                                      panel->back_pixmap,
366                                      panel->fit_pixmap_bg,
367                                      panel->strech_pixmap_bg,
368                                      panel->rotate_pixmap_bg,
369                                      &panel->back_color);
370}
371                                 
372GtkWidget *
373aligned_widget_new (AlignedAlignment align,
374                    BorderEdge edge,
375                    BasePMode mode,
376                    BasePState state,
377                    BasePLevel level,
378                    gboolean avoid_on_maximize,
379                    int sz,
380                    gboolean hidebuttons_enabled,
381                    gboolean hidebutton_pixmaps_enabled,
382                    PanelBackType back_type,
383                    char *back_pixmap,
384                    gboolean fit_pixmap_bg,
385                    gboolean strech_pixmap_bg,
386                    gboolean rotate_pixmap_bg,
387                    GdkColor *back_color)
388{
389        AlignedWidget *aligned = gtk_type_new (TYPE_ALIGNED_WIDGET);
390        AlignedPos *pos = gtk_type_new (TYPE_ALIGNED_POS);
391        pos->align = align;
392
393        BASEP_WIDGET (aligned)->pos = BASEP_POS (pos);
394
395        border_widget_construct (BORDER_WIDGET (aligned),
396                                 edge,
397                                 TRUE, FALSE,
398                                 sz, mode, state,
399                                 level,
400                                 avoid_on_maximize,
401                                 hidebuttons_enabled,
402                                 hidebutton_pixmaps_enabled,
403                                 back_type, back_pixmap,
404                                 fit_pixmap_bg, strech_pixmap_bg,
405                                 rotate_pixmap_bg,
406                                 back_color);
407
408        return GTK_WIDGET (aligned);
409}
Note: See TracBrowser for help on using the repository browser.