]> Pileus Git - ~andy/gtk/blob - gtk/gtkmisc.c
1379b396949e22dc5c9eee15acfd0b270d93f4e0
[~andy/gtk] / gtk / gtkmisc.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include <config.h>
28 #include "gtkcontainer.h"
29 #include "gtkmisc.h"
30 #include "gtkintl.h"
31
32
33 enum {
34   PROP_0,
35   PROP_XALIGN,
36   PROP_YALIGN,
37   PROP_XPAD,
38   PROP_YPAD
39 };
40
41 static void gtk_misc_class_init   (GtkMiscClass *klass);
42 static void gtk_misc_init         (GtkMisc      *misc);
43 static void gtk_misc_realize      (GtkWidget    *widget);
44 static void gtk_misc_set_property (GObject         *object,
45                                    guint            prop_id,
46                                    const GValue    *value,
47                                    GParamSpec      *pspec);
48 static void gtk_misc_get_property (GObject         *object,
49                                    guint            prop_id,
50                                    GValue          *value,
51                                    GParamSpec      *pspec);
52
53
54 GType
55 gtk_misc_get_type (void)
56 {
57   static GType misc_type = 0;
58
59   if (!misc_type)
60     {
61       static const GTypeInfo misc_info =
62       {
63         sizeof (GtkMiscClass),
64         NULL,           /* base_init */
65         NULL,           /* base_finalize */
66         (GClassInitFunc) gtk_misc_class_init,
67         NULL,           /* class_finalize */
68         NULL,           /* class_data */
69         sizeof (GtkMisc),
70         0,              /* n_preallocs */
71         (GInstanceInitFunc) gtk_misc_init,
72         NULL,           /* value_table */
73       };
74
75       misc_type = g_type_register_static (GTK_TYPE_WIDGET, "GtkMisc",
76                                           &misc_info, G_TYPE_FLAG_ABSTRACT);
77     }
78
79   return misc_type;
80 }
81
82 static void
83 gtk_misc_class_init (GtkMiscClass *class)
84 {
85   GObjectClass   *gobject_class;
86   GtkWidgetClass *widget_class;
87
88   gobject_class = G_OBJECT_CLASS (class);
89   widget_class = (GtkWidgetClass*) class;
90
91   gobject_class->set_property = gtk_misc_set_property;
92   gobject_class->get_property = gtk_misc_get_property;
93   
94   widget_class->realize = gtk_misc_realize;
95
96   g_object_class_install_property (gobject_class,
97                                    PROP_XALIGN,
98                                    g_param_spec_float ("xalign",
99                                                        P_("X align"),
100                                                        P_("The horizontal alignment, from 0 (left) to 1 (right). Reversed for RTL layouts"),
101                                                        0.0,
102                                                        1.0,
103                                                        0.5,
104                                                        G_PARAM_READWRITE));
105
106   g_object_class_install_property (gobject_class,
107                                    PROP_YALIGN,
108                                    g_param_spec_float ("yalign",
109                                                        P_("Y align"),
110                                                        P_("The vertical alignment, from 0 (top) to 1 (bottom)"),
111                                                        0.0,
112                                                        1.0,
113                                                        0.5,
114                                                        G_PARAM_READWRITE));
115
116   g_object_class_install_property (gobject_class,
117                                    PROP_XPAD,
118                                    g_param_spec_int ("xpad",
119                                                      P_("X pad"),
120                                                      P_("The amount of space to add on the left and right of the widget, in pixels"),
121                                                      0,
122                                                      G_MAXINT,
123                                                      0,
124                                                      G_PARAM_READWRITE));
125
126   g_object_class_install_property (gobject_class,
127                                    PROP_YPAD,
128                                    g_param_spec_int ("ypad",
129                                                      P_("Y pad"),
130                                                      P_("The amount of space to add on the top and bottom of the widget, in pixels"),
131                                                      0,
132                                                      G_MAXINT,
133                                                      0,
134                                                      G_PARAM_READWRITE));
135 }
136
137 static void
138 gtk_misc_init (GtkMisc *misc)
139 {
140   misc->xalign = 0.5;
141   misc->yalign = 0.5;
142   misc->xpad = 0;
143   misc->ypad = 0;
144 }
145
146 static void
147 gtk_misc_set_property (GObject      *object,
148                        guint         prop_id,
149                        const GValue *value,
150                        GParamSpec   *pspec)
151 {
152   GtkMisc *misc;
153
154   misc = GTK_MISC (object);
155
156   switch (prop_id)
157     {
158     case PROP_XALIGN:
159       gtk_misc_set_alignment (misc, g_value_get_float (value), misc->yalign);
160       break;
161     case PROP_YALIGN:
162       gtk_misc_set_alignment (misc, misc->xalign, g_value_get_float (value));
163       break;
164     case PROP_XPAD:
165       gtk_misc_set_padding (misc, g_value_get_int (value), misc->ypad);
166       break;
167     case PROP_YPAD:
168       gtk_misc_set_padding (misc, misc->xpad, g_value_get_int (value));
169       break;
170     default:
171       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
172       break;
173     }
174 }
175
176 static void
177 gtk_misc_get_property (GObject      *object,
178                        guint         prop_id,
179                        GValue       *value,
180                        GParamSpec   *pspec)
181 {
182   GtkMisc *misc;
183
184   misc = GTK_MISC (object);
185
186   switch (prop_id)
187     {
188     case PROP_XALIGN:
189       g_value_set_float (value, misc->xalign);
190       break;
191     case PROP_YALIGN:
192       g_value_set_float (value, misc->yalign);
193       break;
194     case PROP_XPAD:
195       g_value_set_int (value, misc->xpad);
196       break;
197     case PROP_YPAD:
198       g_value_set_int (value, misc->ypad);
199       break;
200     default:
201       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
202       break;
203     }
204 }
205
206 void
207 gtk_misc_set_alignment (GtkMisc *misc,
208                         gfloat   xalign,
209                         gfloat   yalign)
210 {
211   g_return_if_fail (GTK_IS_MISC (misc));
212
213   if (xalign < 0.0)
214     xalign = 0.0;
215   else if (xalign > 1.0)
216     xalign = 1.0;
217
218   if (yalign < 0.0)
219     yalign = 0.0;
220   else if (yalign > 1.0)
221     yalign = 1.0;
222
223   if ((xalign != misc->xalign) || (yalign != misc->yalign))
224     {
225       misc->xalign = xalign;
226       misc->yalign = yalign;
227       
228       /* clear the area that was allocated before the change
229        */
230       if (GTK_WIDGET_DRAWABLE (misc))
231         {
232           GtkWidget *widget;
233           
234           widget = GTK_WIDGET (misc);
235           gtk_widget_queue_draw (widget);
236         }
237
238       g_object_freeze_notify (G_OBJECT (misc));
239       if (xalign != misc->xalign)
240         g_object_notify (G_OBJECT (misc), "xalign");
241
242       if (yalign != misc->yalign)
243         g_object_notify (G_OBJECT (misc), "yalign");
244       g_object_thaw_notify (G_OBJECT (misc));
245     }
246 }
247
248 /**
249  * gtk_misc_get_alignment:
250  * @misc: a #GtkMisc
251  * @xalign: location to store X alignment of @misc, or %NULL
252  * @yalign: location to store Y alignment of @misc, or %NULL
253  *
254  * Gets the X and Y alignment of the widget within its allocation. See
255  * gtk_misc_set_alignment().
256  **/
257 void
258 gtk_misc_get_alignment (GtkMisc *misc,
259                         gfloat  *xalign,
260                         gfloat  *yalign)
261 {
262   g_return_if_fail (GTK_IS_MISC (misc));
263
264   if (xalign)
265     *xalign = misc->xalign;
266   if (yalign)
267     *yalign = misc->yalign;
268 }
269
270 void
271 gtk_misc_set_padding (GtkMisc *misc,
272                       gint     xpad,
273                       gint     ypad)
274 {
275   GtkRequisition *requisition;
276   
277   g_return_if_fail (GTK_IS_MISC (misc));
278   
279   if (xpad < 0)
280     xpad = 0;
281   if (ypad < 0)
282     ypad = 0;
283   
284   if ((xpad != misc->xpad) || (ypad != misc->ypad))
285     {
286       requisition = &(GTK_WIDGET (misc)->requisition);
287       requisition->width -= misc->xpad * 2;
288       requisition->height -= misc->ypad * 2;
289       
290       misc->xpad = xpad;
291       misc->ypad = ypad;
292       
293       requisition->width += misc->xpad * 2;
294       requisition->height += misc->ypad * 2;
295       
296       if (GTK_WIDGET_DRAWABLE (misc))
297         gtk_widget_queue_resize (GTK_WIDGET (misc));
298
299       g_object_freeze_notify (G_OBJECT (misc));
300       if (xpad != misc->xpad)
301         g_object_notify (G_OBJECT (misc), "xpad");
302
303       if (ypad != misc->ypad)
304         g_object_notify (G_OBJECT (misc), "ypad");
305       g_object_thaw_notify (G_OBJECT (misc));
306     }
307 }
308
309 /**
310  * gtk_misc_get_padding:
311  * @misc: a #GtkMisc
312  * @xpad: location to store padding in the X direction, or %NULL
313  * @ypad: location to store padding in the Y direction, or %NULL
314  *
315  * Gets the padding in the X and Y directions of the widget. See gtk_misc_set_padding().
316  **/
317 void
318 gtk_misc_get_padding (GtkMisc *misc,
319                       gint    *xpad,
320                       gint    *ypad)
321 {
322   g_return_if_fail (GTK_IS_MISC (misc));
323
324   if (xpad)
325     *xpad = misc->xpad;
326   if (ypad)
327     *ypad = misc->ypad;
328 }
329
330 static void
331 gtk_misc_realize (GtkWidget *widget)
332 {
333   GtkMisc *misc;
334   GdkWindowAttr attributes;
335   gint attributes_mask;
336
337   g_return_if_fail (GTK_IS_MISC (widget));
338
339   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
340   misc = GTK_MISC (widget);
341
342   if (GTK_WIDGET_NO_WINDOW (widget))
343     {
344       widget->window = gtk_widget_get_parent_window (widget);
345       g_object_ref (widget->window);
346       widget->style = gtk_style_attach (widget->style, widget->window);
347     }
348   else
349     {
350       attributes.window_type = GDK_WINDOW_CHILD;
351       attributes.x = widget->allocation.x;
352       attributes.y = widget->allocation.y;
353       attributes.width = widget->allocation.width;
354       attributes.height = widget->allocation.height;
355       attributes.wclass = GDK_INPUT_OUTPUT;
356       attributes.visual = gtk_widget_get_visual (widget);
357       attributes.colormap = gtk_widget_get_colormap (widget);
358       attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
359       attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
360
361       widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
362       gdk_window_set_user_data (widget->window, widget);
363
364       widget->style = gtk_style_attach (widget->style, widget->window);
365       gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
366     }
367 }