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

Revision 18631, 11.2 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18630, 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 "panel-marshal.h"
10#include "aligned-widget.h"
11#include "panel-config-global.h"
12#include "foobar-widget.h"
13#include "multiscreen-stuff.h"
14#include "panel-typebuiltins.h"
15
16static void aligned_pos_class_init (AlignedPosClass *klass);
17static void aligned_pos_instance_init (AlignedPos *pos);
18
19static void aligned_pos_set_pos (BasePWidget *basep,
20                                 int x, int y,
21                                 int w, int h,
22                                 gboolean force);
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 *aligned_pos_parent_class;
30
31GType
32aligned_pos_get_type (void)
33{
34        static GType object_type = 0;
35
36        if (object_type == 0) {
37                static const GTypeInfo object_info = {
38                    sizeof (AlignedPosClass),
39                    (GBaseInitFunc)         NULL,
40                    (GBaseFinalizeFunc)     NULL,
41                    (GClassInitFunc)        aligned_pos_class_init,
42                    NULL,                   /* class_finalize */
43                    NULL,                   /* class_data */
44                    sizeof (AlignedPos),
45                    0,                      /* n_preallocs */
46                    (GInstanceInitFunc)     aligned_pos_instance_init
47                };
48
49                object_type = g_type_register_static (BORDER_TYPE_POS, "AlignedPos", &object_info, 0);
50                aligned_pos_parent_class = g_type_class_ref (BORDER_TYPE_POS);
51        }
52                               
53        return object_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        GObjectClass *object_class = G_OBJECT_CLASS (klass);
67        BasePPosClass *pos_class = BASEP_POS_CLASS (klass);
68
69       
70        aligned_pos_signals[ALIGN_CHANGE_SIGNAL] =
71                g_signal_new ("align_change",
72                              G_TYPE_FROM_CLASS (object_class),
73                              G_SIGNAL_RUN_LAST,
74                              G_STRUCT_OFFSET (AlignedPosClass, align_change),
75                              NULL,
76                              NULL,
77                              g_cclosure_marshal_VOID__ENUM,
78                              G_TYPE_NONE,
79                              1,
80                              PANEL_TYPE_ALIGNMENT);
81
82        pos_class->set_pos = aligned_pos_set_pos;
83        pos_class->get_pos = aligned_pos_get_pos;
84        pos_class->north_clicked = pos_class->west_clicked =
85                aligned_pos_show_hide_left;
86        pos_class->south_clicked = pos_class->east_clicked =
87                aligned_pos_show_hide_right;
88}
89
90static void
91aligned_pos_instance_init (AlignedPos *pos) {
92        /* Does nothing */
93}
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, basep->monitor);
122        innery = y - multiscreen_y (basep->screen, basep->monitor);
123        screen_width = multiscreen_width (basep->screen, basep->monitor);
124        screen_height = multiscreen_height (basep->screen, basep->monitor);
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, basep->monitor) -
193                     foobar_widget_get_height (basep->screen, basep->monitor) - h;
194                /* fall thru */
195        case BORDER_TOP:
196                *y += foobar_widget_get_height (basep->screen, basep->monitor);
197                switch (ALIGNED_POS (basep->pos)->align) {
198                case ALIGNED_LEFT:
199                        break;
200                case ALIGNED_CENTER:
201                        *x = (multiscreen_width (basep->screen, basep->monitor) - w) / 2;
202                        break;
203                case ALIGNED_RIGHT:
204                        *x = multiscreen_width (basep->screen, basep->monitor) - w;
205                        break;
206                }
207                break;
208        case BORDER_RIGHT:
209                *x = multiscreen_width (basep->screen, basep->monitor) - w;
210                basep_border_get (basep, BORDER_TOP, NULL, NULL, &a);
211                basep_border_get (basep, BORDER_BOTTOM, NULL, NULL, &b);
212                switch (ALIGNED_POS (basep->pos)->align) {
213                case ALIGNED_LEFT:
214                        *y = foobar_widget_get_height (basep->screen, basep->monitor) + a;
215                        break;
216                case ALIGNED_CENTER:
217                        *y = (multiscreen_height (basep->screen, basep->monitor) - h) / 2;
218                        break;
219                case ALIGNED_RIGHT:
220                        *y = multiscreen_height (basep->screen, basep->monitor) - h - b;
221                        break;
222                }
223                break;
224        case BORDER_LEFT:
225                basep_border_get (basep, BORDER_TOP, &a, NULL, NULL);
226                basep_border_get (basep, BORDER_BOTTOM, &b, NULL, NULL);
227                switch (ALIGNED_POS (basep->pos)->align) {
228                case ALIGNED_LEFT:
229                        *y = foobar_widget_get_height (basep->screen, basep->monitor) + a;
230                        break;
231                case ALIGNED_CENTER:
232                        *y = (multiscreen_height (basep->screen, basep->monitor) - h) / 2;
233                        break;
234                case ALIGNED_RIGHT:
235                        *y = multiscreen_height (basep->screen, basep->monitor) - h - b;
236                        break;
237                }
238                break;
239        }
240
241        *x += multiscreen_x (basep->screen, basep->monitor);
242        *y += multiscreen_y (basep->screen, basep->monitor);
243
244        basep_border_queue_recalc (basep->screen, basep->monitor);
245}
246
247static void
248aligned_pos_show_hide_left (BasePWidget *basep)
249{
250        switch (basep->state) {
251        case BASEP_SHOWN:
252                if (ALIGNED_POS (basep->pos)->align == ALIGNED_RIGHT)
253                        aligned_widget_change_align (ALIGNED_WIDGET (basep),
254                                                     ALIGNED_LEFT);
255                else
256                        basep_widget_explicit_hide (basep, BASEP_HIDDEN_LEFT);
257                break;
258        case BASEP_HIDDEN_RIGHT:
259                basep_widget_explicit_show (basep);
260                break;
261        default:
262                break;
263        }
264}
265
266
267static void
268aligned_pos_show_hide_right (BasePWidget *basep)
269{
270        switch (basep->state) {
271        case BASEP_SHOWN:
272                if (ALIGNED_POS (basep->pos)->align == ALIGNED_LEFT)
273                        aligned_widget_change_align (ALIGNED_WIDGET (basep),
274                                                     ALIGNED_RIGHT);
275                else
276                        basep_widget_explicit_hide (basep, BASEP_HIDDEN_RIGHT);
277                break;
278        case BASEP_HIDDEN_LEFT:
279                basep_widget_explicit_show (basep);
280                break;
281        default:
282                break;
283        }
284}
285
286void
287aligned_widget_change_params (AlignedWidget *aligned,
288                              int screen,
289                              int monitor,
290                              AlignedAlignment align,
291                              BorderEdge edge,
292                              int sz,
293                              BasePMode mode,
294                              BasePState state,
295                              gboolean hidebuttons_enabled,
296                              gboolean hidebutton_pixmaps_enabled,
297                              PanelBackgroundType back_type,
298                              char *pixmap_name,
299                              gboolean fit_pixmap_bg,
300                              gboolean stretch_pixmap_bg,
301                              gboolean rotate_pixmap_bg,
302                              PanelColor *back_color)
303{
304        AlignedPos *pos = ALIGNED_POS (BASEP_WIDGET (aligned)->pos);
305
306        if (pos->align != align) {
307                pos->align = align;
308                g_signal_emit (G_OBJECT (pos),
309                               aligned_pos_signals[ALIGN_CHANGE_SIGNAL],
310                               0, align);
311        }
312
313        border_widget_change_params (BORDER_WIDGET (aligned),
314                                     screen,
315                                     monitor,
316                                     edge,
317                                     sz,
318                                     mode,
319                                     state,
320                                     hidebuttons_enabled,
321                                     hidebutton_pixmaps_enabled,
322                                     back_type,
323                                     pixmap_name,
324                                     fit_pixmap_bg,
325                                     stretch_pixmap_bg,
326                                     rotate_pixmap_bg,
327                                     back_color);
328}
329
330
331void
332aligned_widget_change_align (AlignedWidget *aligned,
333                             AlignedAlignment align)
334{
335        BasePWidget *basep = BASEP_WIDGET (aligned);
336        PanelWidget *panel = PANEL_WIDGET (basep->panel);
337        AlignedPos *pos = ALIGNED_POS (basep->pos);
338
339        if (pos->align == align)
340                return;
341
342        aligned_widget_change_params (aligned,
343                                      basep->screen,
344                                      basep->monitor,
345                                      align,
346                                      BORDER_POS (pos)->edge,
347                                      panel->sz, basep->mode,
348                                      basep->state,
349                                      basep->hidebuttons_enabled,
350                                      basep->hidebutton_pixmaps_enabled,
351                                      panel->background.type,
352                                      panel->background.image,
353                                      panel->background.fit_image,
354                                      panel->background.stretch_image,
355                                      panel->background.rotate_image,
356                                      &panel->background.color);
357}
358
359void
360aligned_widget_change_align_edge (AlignedWidget *aligned,
361                                  AlignedAlignment align,
362                                  BorderEdge edge)
363{
364        BasePWidget *basep = BASEP_WIDGET (aligned);
365        PanelWidget *panel = PANEL_WIDGET (basep->panel);
366
367        aligned_widget_change_params (aligned,
368                                      basep->screen,
369                                      basep->monitor,
370                                      align,
371                                      edge,
372                                      panel->sz,
373                                      basep->mode,
374                                      basep->state,
375                                      basep->hidebuttons_enabled,
376                                      basep->hidebutton_pixmaps_enabled,
377                                      panel->background.type,
378                                      panel->background.image,
379                                      panel->background.fit_image,
380                                      panel->background.stretch_image,
381                                      panel->background.rotate_image,
382                                      &panel->background.color);
383}
384                                 
385GtkWidget *
386aligned_widget_new (const char *panel_id,
387                    int screen,
388                    int monitor,
389                    AlignedAlignment align,
390                    BorderEdge edge,
391                    BasePMode mode,
392                    BasePState state,
393                    int sz,
394                    gboolean hidebuttons_enabled,
395                    gboolean hidebutton_pixmaps_enabled,
396                    PanelBackgroundType back_type,
397                    const char *back_pixmap,
398                    gboolean fit_pixmap_bg,
399                    gboolean stretch_pixmap_bg,
400                    gboolean rotate_pixmap_bg,
401                    PanelColor *back_color)
402{
403        AlignedWidget *aligned;
404        AlignedPos    *pos;
405
406        aligned = g_object_new (ALIGNED_TYPE_WIDGET, NULL);
407        pos = g_object_new (ALIGNED_TYPE_POS, NULL);
408        pos->align = align;
409
410        BASEP_WIDGET (aligned)->pos = BASEP_POS (pos);
411
412        border_widget_construct (panel_id,
413                                 BORDER_WIDGET (aligned),
414                                 screen,
415                                 monitor,
416                                 edge,
417                                 TRUE,
418                                 FALSE,
419                                 sz,
420                                 mode,
421                                 state,
422                                 hidebuttons_enabled,
423                                 hidebutton_pixmaps_enabled,
424                                 back_type,
425                                 back_pixmap,
426                                 fit_pixmap_bg,
427                                 stretch_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.