]> Pileus Git - ~andy/gtk/blob - gtk/gtkmisc.c
docs: correct various spelling and grammar errors
[~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, see <http://www.gnu.org/licenses/>.
16  */
17
18 /*
19  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
20  * file for a list of people on the GTK+ Team.  See the ChangeLog
21  * files for a list of changes.  These files are distributed with
22  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
23  */
24
25 #include "config.h"
26 #include "gtkcontainer.h"
27 #include "gtkmisc.h"
28 #include "gtkintl.h"
29 #include "gtkprivate.h"
30
31
32 /**
33  * SECTION:gtkmisc
34  * @Short_description: Base class for widgets with alignments and padding
35  * @Title: GtkMisc
36  *
37  * The #GtkMisc widget is an abstract widget which is not useful itself, but
38  * is used to derive subclasses which have alignment and padding attributes.
39  *
40  * The horizontal and vertical padding attributes allows extra space to be
41  * added around the widget.
42  *
43  * The horizontal and vertical alignment attributes enable the widget to be
44  * positioned within its allocated area. Note that if the widget is added to
45  * a container in such a way that it expands automatically to fill its
46  * allocated area, the alignment settings will not alter the widgets position.
47  *
48  * <note>
49  * Note that the desired effect can in most cases be achieved by using the
50  * #GtkWidget:halign, #GtkWidget:valign and #GtkWidget:margin properties
51  * on the child widget, so GtkMisc should not be used in new code.
52  * </note>
53  */
54
55
56 struct _GtkMiscPrivate
57 {
58   gfloat        xalign;
59   gfloat        yalign;
60
61   guint16       xpad;
62   guint16       ypad;
63 };
64
65 enum {
66   PROP_0,
67   PROP_XALIGN,
68   PROP_YALIGN,
69   PROP_XPAD,
70   PROP_YPAD
71 };
72
73 static void gtk_misc_realize      (GtkWidget    *widget);
74 static void gtk_misc_set_property (GObject         *object,
75                                    guint            prop_id,
76                                    const GValue    *value,
77                                    GParamSpec      *pspec);
78 static void gtk_misc_get_property (GObject         *object,
79                                    guint            prop_id,
80                                    GValue          *value,
81                                    GParamSpec      *pspec);
82
83
84 G_DEFINE_ABSTRACT_TYPE (GtkMisc, gtk_misc, GTK_TYPE_WIDGET)
85
86 static void
87 gtk_misc_class_init (GtkMiscClass *class)
88 {
89   GObjectClass   *gobject_class;
90   GtkWidgetClass *widget_class;
91
92   gobject_class = G_OBJECT_CLASS (class);
93   widget_class = (GtkWidgetClass*) class;
94
95   gobject_class->set_property = gtk_misc_set_property;
96   gobject_class->get_property = gtk_misc_get_property;
97   
98   widget_class->realize = gtk_misc_realize;
99
100   g_object_class_install_property (gobject_class,
101                                    PROP_XALIGN,
102                                    g_param_spec_float ("xalign",
103                                                        P_("X align"),
104                                                        P_("The horizontal alignment, from 0 (left) to 1 (right). Reversed for RTL layouts."),
105                                                        0.0,
106                                                        1.0,
107                                                        0.5,
108                                                        GTK_PARAM_READWRITE));
109
110   g_object_class_install_property (gobject_class,
111                                    PROP_YALIGN,
112                                    g_param_spec_float ("yalign",
113                                                        P_("Y align"),
114                                                        P_("The vertical alignment, from 0 (top) to 1 (bottom)"),
115                                                        0.0,
116                                                        1.0,
117                                                        0.5,
118                                                        GTK_PARAM_READWRITE));
119
120   g_object_class_install_property (gobject_class,
121                                    PROP_XPAD,
122                                    g_param_spec_int ("xpad",
123                                                      P_("X pad"),
124                                                      P_("The amount of space to add on the left and right of the widget, in pixels"),
125                                                      0,
126                                                      G_MAXINT,
127                                                      0,
128                                                      GTK_PARAM_READWRITE));
129
130   g_object_class_install_property (gobject_class,
131                                    PROP_YPAD,
132                                    g_param_spec_int ("ypad",
133                                                      P_("Y pad"),
134                                                      P_("The amount of space to add on the top and bottom of the widget, in pixels"),
135                                                      0,
136                                                      G_MAXINT,
137                                                      0,
138                                                      GTK_PARAM_READWRITE));
139
140   g_type_class_add_private (class, sizeof (GtkMiscPrivate));
141 }
142
143 static void
144 gtk_misc_init (GtkMisc *misc)
145 {
146   GtkMiscPrivate *priv;
147
148   misc->priv = G_TYPE_INSTANCE_GET_PRIVATE (misc,
149                                             GTK_TYPE_MISC,
150                                             GtkMiscPrivate);
151   priv = misc->priv;
152
153   priv->xalign = 0.5;
154   priv->yalign = 0.5;
155   priv->xpad = 0;
156   priv->ypad = 0;
157 }
158
159 static void
160 gtk_misc_set_property (GObject      *object,
161                        guint         prop_id,
162                        const GValue *value,
163                        GParamSpec   *pspec)
164 {
165   GtkMisc *misc = GTK_MISC (object);
166   GtkMiscPrivate *priv = misc->priv;
167
168   switch (prop_id)
169     {
170     case PROP_XALIGN:
171       gtk_misc_set_alignment (misc, g_value_get_float (value), priv->yalign);
172       break;
173     case PROP_YALIGN:
174       gtk_misc_set_alignment (misc, priv->xalign, g_value_get_float (value));
175       break;
176     case PROP_XPAD:
177       gtk_misc_set_padding (misc, g_value_get_int (value), priv->ypad);
178       break;
179     case PROP_YPAD:
180       gtk_misc_set_padding (misc, priv->xpad, g_value_get_int (value));
181       break;
182     default:
183       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
184       break;
185     }
186 }
187
188 static void
189 gtk_misc_get_property (GObject      *object,
190                        guint         prop_id,
191                        GValue       *value,
192                        GParamSpec   *pspec)
193 {
194   GtkMisc *misc = GTK_MISC (object);
195   GtkMiscPrivate *priv = misc->priv;
196
197   switch (prop_id)
198     {
199     case PROP_XALIGN:
200       g_value_set_float (value, priv->xalign);
201       break;
202     case PROP_YALIGN:
203       g_value_set_float (value, priv->yalign);
204       break;
205     case PROP_XPAD:
206       g_value_set_int (value, priv->xpad);
207       break;
208     case PROP_YPAD:
209       g_value_set_int (value, priv->ypad);
210       break;
211     default:
212       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
213       break;
214     }
215 }
216
217 /**
218  * gtk_misc_set_alignment:
219  * @misc: a #GtkMisc.
220  * @xalign: the horizontal alignment, from 0 (left) to 1 (right).
221  * @yalign: the vertical alignment, from 0 (top) to 1 (bottom).
222  *
223  * Sets the alignment of the widget.
224  */
225 void
226 gtk_misc_set_alignment (GtkMisc *misc,
227                         gfloat   xalign,
228                         gfloat   yalign)
229 {
230   GtkMiscPrivate *priv;
231   GtkWidget *widget;
232
233   g_return_if_fail (GTK_IS_MISC (misc));
234
235   priv = misc->priv;
236
237   if (xalign < 0.0)
238     xalign = 0.0;
239   else if (xalign > 1.0)
240     xalign = 1.0;
241
242   if (yalign < 0.0)
243     yalign = 0.0;
244   else if (yalign > 1.0)
245     yalign = 1.0;
246
247   if ((xalign != priv->xalign) || (yalign != priv->yalign))
248     {
249       g_object_freeze_notify (G_OBJECT (misc));
250       if (xalign != priv->xalign)
251         g_object_notify (G_OBJECT (misc), "xalign");
252
253       if (yalign != priv->yalign)
254         g_object_notify (G_OBJECT (misc), "yalign");
255
256       priv->xalign = xalign;
257       priv->yalign = yalign;
258       
259       /* clear the area that was allocated before the change
260        */
261       widget = GTK_WIDGET (misc);
262       if (gtk_widget_is_drawable (widget))
263         gtk_widget_queue_draw (widget);
264
265       g_object_thaw_notify (G_OBJECT (misc));
266     }
267 }
268
269 /**
270  * gtk_misc_get_alignment:
271  * @misc: a #GtkMisc
272  * @xalign: (out) (allow-none): location to store X alignment of @misc, or %NULL
273  * @yalign: (out) (allow-none): location to store Y alignment of @misc, or %NULL
274  *
275  * Gets the X and Y alignment of the widget within its allocation. 
276  * See gtk_misc_set_alignment().
277  **/
278 void
279 gtk_misc_get_alignment (GtkMisc *misc,
280                         gfloat  *xalign,
281                         gfloat  *yalign)
282 {
283   GtkMiscPrivate *priv;
284
285   g_return_if_fail (GTK_IS_MISC (misc));
286
287   priv = misc->priv;
288
289   if (xalign)
290     *xalign = priv->xalign;
291   if (yalign)
292     *yalign = priv->yalign;
293 }
294
295 /**
296  * gtk_misc_set_padding:
297  * @misc: a #GtkMisc.
298  * @xpad: the amount of space to add on the left and right of the widget,
299  *   in pixels.
300  * @ypad: the amount of space to add on the top and bottom of the widget,
301  *   in pixels.
302  *
303  * Sets the amount of space to add around the widget.
304  */
305 void
306 gtk_misc_set_padding (GtkMisc *misc,
307                       gint     xpad,
308                       gint     ypad)
309 {
310   GtkMiscPrivate *priv;
311
312   g_return_if_fail (GTK_IS_MISC (misc));
313
314   priv = misc->priv;
315
316   if (xpad < 0)
317     xpad = 0;
318   if (ypad < 0)
319     ypad = 0;
320
321   if ((xpad != priv->xpad) || (ypad != priv->ypad))
322     {
323       g_object_freeze_notify (G_OBJECT (misc));
324       if (xpad != priv->xpad)
325         g_object_notify (G_OBJECT (misc), "xpad");
326
327       if (ypad != priv->ypad)
328         g_object_notify (G_OBJECT (misc), "ypad");
329
330       priv->xpad = xpad;
331       priv->ypad = ypad;
332
333       if (gtk_widget_is_drawable (GTK_WIDGET (misc)))
334         gtk_widget_queue_resize (GTK_WIDGET (misc));
335
336       g_object_thaw_notify (G_OBJECT (misc));
337     }
338 }
339
340 /**
341  * gtk_misc_get_padding:
342  * @misc: a #GtkMisc
343  * @xpad: (out) (allow-none): location to store padding in the X
344  *        direction, or %NULL
345  * @ypad: (out) (allow-none): location to store padding in the Y
346  *        direction, or %NULL
347  *
348  * Gets the padding in the X and Y directions of the widget. 
349  * See gtk_misc_set_padding().
350  **/
351 void
352 gtk_misc_get_padding (GtkMisc *misc,
353                       gint    *xpad,
354                       gint    *ypad)
355 {
356   GtkMiscPrivate *priv;
357
358   g_return_if_fail (GTK_IS_MISC (misc));
359
360   priv = misc->priv;
361
362   if (xpad)
363     *xpad = priv->xpad;
364   if (ypad)
365     *ypad = priv->ypad;
366 }
367
368 static void
369 gtk_misc_realize (GtkWidget *widget)
370 {
371   GtkAllocation allocation;
372   GdkWindow *window;
373   GdkWindowAttr attributes;
374   gint attributes_mask;
375
376   gtk_widget_set_realized (widget, TRUE);
377
378   if (!gtk_widget_get_has_window (widget))
379     {
380       window = gtk_widget_get_parent_window (widget);
381       gtk_widget_set_window (widget, window);
382       g_object_ref (window);
383     }
384   else
385     {
386       gtk_widget_get_allocation (widget, &allocation);
387
388       attributes.window_type = GDK_WINDOW_CHILD;
389       attributes.x = allocation.x;
390       attributes.y = allocation.y;
391       attributes.width = allocation.width;
392       attributes.height = allocation.height;
393       attributes.wclass = GDK_INPUT_OUTPUT;
394       attributes.visual = gtk_widget_get_visual (widget);
395       attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
396       attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
397
398       window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
399       gtk_widget_set_window (widget, window);
400       gtk_widget_register_window (widget, window);
401       gdk_window_set_background_pattern (window, NULL);
402     }
403 }
404
405 /* Semi-private function used by gtk widgets inheriting from
406  * GtkMisc that takes into account both css padding and border
407  * and the padding specified with the GtkMisc properties.
408  */
409 void
410 _gtk_misc_get_padding_and_border (GtkMisc   *misc,
411                                   GtkBorder *border)
412 {
413   GtkStyleContext *context;
414   GtkStateFlags state;
415   GtkBorder tmp;
416   gint xpad, ypad;
417
418   g_return_if_fail (GTK_IS_MISC (misc));
419
420   context = gtk_widget_get_style_context (GTK_WIDGET (misc));
421   state = gtk_widget_get_state_flags (GTK_WIDGET (misc));
422
423   gtk_style_context_get_padding (context, state, border);
424
425   gtk_misc_get_padding (misc, &xpad, &ypad);
426   border->top += ypad;
427   border->left += xpad;
428   border->bottom += ypad;
429   border->right += xpad;
430
431   gtk_style_context_get_border (context, state, &tmp);
432   border->top += tmp.top;
433   border->right += tmp.right;
434   border->bottom += tmp.bottom;
435   border->left += tmp.left;
436 }
437