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