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

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