]> Pileus Git - ~andy/gtk/blob - gtk/gtkalignment.c
281fa9cd331064a59cbd8ecb415983497b3064b8
[~andy/gtk] / gtk / gtkalignment.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 /**
28  * SECTION:gtkalignment
29  * @Short_description: A widget which controls the alignment and size of its child
30  * @Title: GtkAlignment
31  *
32  * The #GtkAlignment widget controls the alignment and size of its child widget.
33  * It has four settings: xscale, yscale, xalign, and yalign.
34  *
35  * The scale settings are used to specify how much the child widget should
36  * expand to fill the space allocated to the #GtkAlignment.
37  * The values can range from 0 (meaning the child doesn't expand at all) to
38  * 1 (meaning the child expands to fill all of the available space).
39  *
40  * The align settings are used to place the child widget within the available
41  * area. The values range from 0 (top or left) to 1 (bottom or right).
42  * Of course, if the scale settings are both set to 1, the alignment settings
43  * have no effect.
44  *
45  * <note>
46  * <para>
47  * Note that the desired effect can in most cases be achieved by using the
48  * #GtkWidget:halign, #GtkWidget:valign and #GtkWidget:margin properties
49  * on the child widget, so #GtkAlignment should not be used in new code.
50  * </para>
51  * </note>
52  */
53
54 #include "config.h"
55 #include "gtkalignment.h"
56 #include "gtksizerequest.h"
57 #include "gtkprivate.h"
58 #include "gtkintl.h"
59
60
61 struct _GtkAlignmentPrivate
62 {
63   gfloat        xalign;
64   gfloat        yalign;
65   gfloat        xscale;
66   gfloat        yscale;
67
68   guint         padding_bottom;
69   guint         padding_top;
70   guint         padding_left;
71   guint         padding_right;
72 };
73
74 enum {
75   PROP_0,
76
77   PROP_XALIGN,
78   PROP_YALIGN,
79   PROP_XSCALE,
80   PROP_YSCALE,
81
82   PROP_TOP_PADDING,
83   PROP_BOTTOM_PADDING,
84   PROP_LEFT_PADDING,
85   PROP_RIGHT_PADDING
86 };
87
88 static void gtk_alignment_size_allocate (GtkWidget         *widget,
89                                          GtkAllocation     *allocation);
90 static void gtk_alignment_set_property (GObject         *object,
91                                         guint            prop_id,
92                                         const GValue    *value,
93                                         GParamSpec      *pspec);
94 static void gtk_alignment_get_property (GObject         *object,
95                                         guint            prop_id,
96                                         GValue          *value,
97                                         GParamSpec      *pspec);
98
99 static void gtk_alignment_get_preferred_width          (GtkWidget           *widget,
100                                                         gint                *minimum_size,
101                                                         gint                *natural_size);
102 static void gtk_alignment_get_preferred_height         (GtkWidget           *widget,
103                                                         gint                *minimum_size,
104                                                         gint                *natural_size);
105 static void gtk_alignment_get_preferred_width_for_height (GtkWidget           *widget,
106                                                           gint                 for_size,
107                                                           gint                *minimum_size,
108                                                           gint                *natural_size);
109 static void gtk_alignment_get_preferred_height_for_width (GtkWidget           *widget,
110                                                           gint                 for_size,
111                                                           gint                *minimum_size,
112                                                           gint                *natural_size);
113
114 G_DEFINE_TYPE (GtkAlignment, gtk_alignment, GTK_TYPE_BIN)
115
116 static void
117 gtk_alignment_class_init (GtkAlignmentClass *class)
118 {
119   GObjectClass *gobject_class;
120   GtkWidgetClass *widget_class;
121
122   gobject_class = (GObjectClass*) class;
123   widget_class = (GtkWidgetClass*) class;
124   
125   gobject_class->set_property = gtk_alignment_set_property;
126   gobject_class->get_property = gtk_alignment_get_property;
127
128   widget_class->size_allocate        = gtk_alignment_size_allocate;
129   widget_class->get_preferred_width  = gtk_alignment_get_preferred_width;
130   widget_class->get_preferred_height = gtk_alignment_get_preferred_height;
131   widget_class->get_preferred_width_for_height = gtk_alignment_get_preferred_width_for_height;
132   widget_class->get_preferred_height_for_width = gtk_alignment_get_preferred_height_for_width;
133
134   g_object_class_install_property (gobject_class,
135                                    PROP_XALIGN,
136                                    g_param_spec_float("xalign",
137                                                       P_("Horizontal alignment"),
138                                                       P_("Horizontal position of child in available space. 0.0 is left aligned, 1.0 is right aligned"),
139                                                       0.0,
140                                                       1.0,
141                                                       0.5,
142                                                       GTK_PARAM_READWRITE));
143    
144   g_object_class_install_property (gobject_class,
145                                    PROP_YALIGN,
146                                    g_param_spec_float("yalign",
147                                                       P_("Vertical alignment"),
148                                                       P_("Vertical position of child in available space. 0.0 is top aligned, 1.0 is bottom aligned"),
149                                                       0.0,
150                                                       1.0,
151                                                       0.5,
152                                                       GTK_PARAM_READWRITE));
153   g_object_class_install_property (gobject_class,
154                                    PROP_XSCALE,
155                                    g_param_spec_float("xscale",
156                                                       P_("Horizontal scale"),
157                                                       P_("If available horizontal space is bigger than needed for the child, how much of it to use for the child. 0.0 means none, 1.0 means all"),
158                                                       0.0,
159                                                       1.0,
160                                                       1.0,
161                                                       GTK_PARAM_READWRITE));
162   g_object_class_install_property (gobject_class,
163                                    PROP_YSCALE,
164                                    g_param_spec_float("yscale",
165                                                       P_("Vertical scale"),
166                                                       P_("If available vertical space is bigger than needed for the child, how much of it to use for the child. 0.0 means none, 1.0 means all"),
167                                                       0.0,
168                                                       1.0,
169                                                       1.0,
170                                                       GTK_PARAM_READWRITE));
171
172
173 /**
174  * GtkAlignment:top-padding:
175  *
176  * The padding to insert at the top of the widget.
177  *
178  * Since: 2.4
179  */
180   g_object_class_install_property (gobject_class,
181                                    PROP_TOP_PADDING,
182                                    g_param_spec_uint("top-padding",
183                                                       P_("Top Padding"),
184                                                       P_("The padding to insert at the top of the widget."),
185                                                       0,
186                                                       G_MAXINT,
187                                                       0,
188                                                       GTK_PARAM_READWRITE));
189
190 /**
191  * GtkAlignment:bottom-padding:
192  *
193  * The padding to insert at the bottom of the widget.
194  *
195  * Since: 2.4
196  */
197   g_object_class_install_property (gobject_class,
198                                    PROP_BOTTOM_PADDING,
199                                    g_param_spec_uint("bottom-padding",
200                                                       P_("Bottom Padding"),
201                                                       P_("The padding to insert at the bottom of the widget."),
202                                                       0,
203                                                       G_MAXINT,
204                                                       0,
205                                                       GTK_PARAM_READWRITE));
206
207 /**
208  * GtkAlignment:left-padding:
209  *
210  * The padding to insert at the left of the widget.
211  *
212  * Since: 2.4
213  */
214   g_object_class_install_property (gobject_class,
215                                    PROP_LEFT_PADDING,
216                                    g_param_spec_uint("left-padding",
217                                                       P_("Left Padding"),
218                                                       P_("The padding to insert at the left of the widget."),
219                                                       0,
220                                                       G_MAXINT,
221                                                       0,
222                                                       GTK_PARAM_READWRITE));
223
224 /**
225  * GtkAlignment:right-padding:
226  *
227  * The padding to insert at the right of the widget.
228  *
229  * Since: 2.4
230  */
231   g_object_class_install_property (gobject_class,
232                                    PROP_RIGHT_PADDING,
233                                    g_param_spec_uint("right-padding",
234                                                       P_("Right Padding"),
235                                                       P_("The padding to insert at the right of the widget."),
236                                                       0,
237                                                       G_MAXINT,
238                                                       0,
239                                                       GTK_PARAM_READWRITE));
240
241   g_type_class_add_private (gobject_class, sizeof (GtkAlignmentPrivate));
242 }
243
244 static void
245 gtk_alignment_init (GtkAlignment *alignment)
246 {
247   GtkAlignmentPrivate *priv;
248
249   alignment->priv = G_TYPE_INSTANCE_GET_PRIVATE (alignment,
250                                                  GTK_TYPE_ALIGNMENT,
251                                                  GtkAlignmentPrivate);
252   priv = alignment->priv;
253
254   gtk_widget_set_has_window (GTK_WIDGET (alignment), FALSE);
255   gtk_widget_set_redraw_on_allocate (GTK_WIDGET (alignment), FALSE);
256
257   priv->xalign = 0.5;
258   priv->yalign = 0.5;
259   priv->xscale = 1.0;
260   priv->yscale = 1.0;
261
262   /* Initialize padding with default values: */
263   priv->padding_top = 0;
264   priv->padding_bottom = 0;
265   priv->padding_left = 0;
266   priv->padding_right = 0;
267 }
268
269 /**
270  * gtk_alignment_new:
271  * @xalign: the horizontal alignment of the child widget, from 0 (left) to 1
272  *  (right).
273  * @yalign: the vertical alignment of the child widget, from 0 (top) to 1
274  *  (bottom).
275  * @xscale: the amount that the child widget expands horizontally to fill up
276  *  unused space, from 0 to 1.
277  *  A value of 0 indicates that the child widget should never expand.
278  *  A value of 1 indicates that the child widget will expand to fill all of the
279  *  space allocated for the #GtkAlignment.
280  * @yscale: the amount that the child widget expands vertically to fill up
281  *  unused space, from 0 to 1. The values are similar to @xscale.
282  *
283  * Creates a new #GtkAlignment.
284  *
285  * Returns: the new #GtkAlignment.
286  */
287 GtkWidget*
288 gtk_alignment_new (gfloat xalign,
289                    gfloat yalign,
290                    gfloat xscale,
291                    gfloat yscale)
292 {
293   GtkAlignment *alignment;
294   GtkAlignmentPrivate *priv;
295
296   alignment = g_object_new (GTK_TYPE_ALIGNMENT, NULL);
297
298   priv = alignment->priv;
299
300   priv->xalign = CLAMP (xalign, 0.0, 1.0);
301   priv->yalign = CLAMP (yalign, 0.0, 1.0);
302   priv->xscale = CLAMP (xscale, 0.0, 1.0);
303   priv->yscale = CLAMP (yscale, 0.0, 1.0);
304
305   return GTK_WIDGET (alignment);
306 }
307
308 static void
309 gtk_alignment_set_property (GObject         *object,
310                             guint            prop_id,
311                             const GValue    *value,
312                             GParamSpec      *pspec)
313 {
314   GtkAlignment *alignment = GTK_ALIGNMENT (object);
315   GtkAlignmentPrivate *priv = alignment->priv;
316
317   switch (prop_id)
318     {
319     case PROP_XALIGN:
320       gtk_alignment_set (alignment,
321                          g_value_get_float (value),
322                          priv->yalign,
323                          priv->xscale,
324                          priv->yscale);
325       break;
326     case PROP_YALIGN:
327       gtk_alignment_set (alignment,
328                          priv->xalign,
329                          g_value_get_float (value),
330                          priv->xscale,
331                          priv->yscale);
332       break;
333     case PROP_XSCALE:
334       gtk_alignment_set (alignment,
335                          priv->xalign,
336                          priv->yalign,
337                          g_value_get_float (value),
338                          priv->yscale);
339       break;
340     case PROP_YSCALE:
341       gtk_alignment_set (alignment,
342                          priv->xalign,
343                          priv->yalign,
344                          priv->xscale,
345                          g_value_get_float (value));
346       break;
347       
348     /* Padding: */
349     case PROP_TOP_PADDING:
350       gtk_alignment_set_padding (alignment,
351                          g_value_get_uint (value),
352                          priv->padding_bottom,
353                          priv->padding_left,
354                          priv->padding_right);
355       break;
356     case PROP_BOTTOM_PADDING:
357       gtk_alignment_set_padding (alignment,
358                          priv->padding_top,
359                          g_value_get_uint (value),
360                          priv->padding_left,
361                          priv->padding_right);
362       break;
363     case PROP_LEFT_PADDING:
364       gtk_alignment_set_padding (alignment,
365                          priv->padding_top,
366                          priv->padding_bottom,
367                          g_value_get_uint (value),
368                          priv->padding_right);
369       break;
370     case PROP_RIGHT_PADDING:
371       gtk_alignment_set_padding (alignment,
372                          priv->padding_top,
373                          priv->padding_bottom,
374                          priv->padding_left,
375                          g_value_get_uint (value));
376       break;
377     
378     default:
379       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
380       break;
381     }
382 }
383
384 static void
385 gtk_alignment_get_property (GObject         *object,
386                             guint            prop_id,
387                             GValue          *value,
388                             GParamSpec      *pspec)
389 {
390   GtkAlignment *alignment = GTK_ALIGNMENT (object);
391   GtkAlignmentPrivate *priv = alignment->priv;
392
393   switch (prop_id)
394     {
395     case PROP_XALIGN:
396       g_value_set_float(value, priv->xalign);
397       break;
398     case PROP_YALIGN:
399       g_value_set_float(value, priv->yalign);
400       break;
401     case PROP_XSCALE:
402       g_value_set_float(value, priv->xscale);
403       break;
404     case PROP_YSCALE:
405       g_value_set_float(value, priv->yscale);
406       break;
407
408     /* Padding: */
409     case PROP_TOP_PADDING:
410       g_value_set_uint (value, priv->padding_top);
411       break;
412     case PROP_BOTTOM_PADDING:
413       g_value_set_uint (value, priv->padding_bottom);
414       break;
415     case PROP_LEFT_PADDING:
416       g_value_set_uint (value, priv->padding_left);
417       break;
418     case PROP_RIGHT_PADDING:
419       g_value_set_uint (value, priv->padding_right);
420       break;
421       
422     default:
423       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
424       break;
425     }
426 }
427
428 /**
429  * gtk_alignment_set:
430  * @alignment: a #GtkAlignment.
431  * @xalign: the horizontal alignment of the child widget, from 0 (left) to 1
432  *  (right).
433  * @yalign: the vertical alignment of the child widget, from 0 (top) to 1
434  *  (bottom).
435  * @xscale: the amount that the child widget expands horizontally to fill up
436  *  unused space, from 0 to 1.
437  *  A value of 0 indicates that the child widget should never expand.
438  *  A value of 1 indicates that the child widget will expand to fill all of the
439  *  space allocated for the #GtkAlignment.
440  * @yscale: the amount that the child widget expands vertically to fill up
441  *  unused space, from 0 to 1. The values are similar to @xscale.
442  *
443  * Sets the #GtkAlignment values.
444  */
445 void
446 gtk_alignment_set (GtkAlignment *alignment,
447                    gfloat        xalign,
448                    gfloat        yalign,
449                    gfloat        xscale,
450                    gfloat        yscale)
451 {
452   GtkAlignmentPrivate *priv;
453   GtkWidget *child;
454
455   g_return_if_fail (GTK_IS_ALIGNMENT (alignment));
456
457   priv = alignment->priv;
458
459   xalign = CLAMP (xalign, 0.0, 1.0);
460   yalign = CLAMP (yalign, 0.0, 1.0);
461   xscale = CLAMP (xscale, 0.0, 1.0);
462   yscale = CLAMP (yscale, 0.0, 1.0);
463
464   if (   (priv->xalign != xalign)
465       || (priv->yalign != yalign)
466       || (priv->xscale != xscale)
467       || (priv->yscale != yscale))
468     {
469       g_object_freeze_notify (G_OBJECT (alignment));
470       if (priv->xalign != xalign)
471         {
472            priv->xalign = xalign;
473            g_object_notify (G_OBJECT (alignment), "xalign");
474         }
475       if (priv->yalign != yalign)
476         {
477            priv->yalign = yalign;
478            g_object_notify (G_OBJECT (alignment), "yalign");
479         }
480       if (priv->xscale != xscale)
481         {
482            priv->xscale = xscale;
483            g_object_notify (G_OBJECT (alignment), "xscale");
484         }
485       if (priv->yscale != yscale)
486         {
487            priv->yscale = yscale;
488            g_object_notify (G_OBJECT (alignment), "yscale");
489         }
490       g_object_thaw_notify (G_OBJECT (alignment));
491
492       child = gtk_bin_get_child (GTK_BIN (alignment));
493       if (child)
494         gtk_widget_queue_resize (child);
495       gtk_widget_queue_draw (GTK_WIDGET (alignment));
496     }
497 }
498
499
500 static void
501 gtk_alignment_size_allocate (GtkWidget     *widget,
502                              GtkAllocation *allocation)
503 {
504   GtkAlignment *alignment = GTK_ALIGNMENT (widget);
505   GtkAlignmentPrivate *priv = alignment->priv;
506   GtkBin *bin;
507   GtkAllocation child_allocation;
508   GtkWidget *child;
509   gint width, height;
510   guint border_width;
511   gint padding_horizontal, padding_vertical;
512
513   padding_horizontal = 0;
514   padding_vertical = 0;
515
516   gtk_widget_set_allocation (widget, allocation);
517   bin = GTK_BIN (widget);
518
519   child = gtk_bin_get_child (bin);
520   if (child && gtk_widget_get_visible (child))
521     {
522       gint child_nat_width;
523       gint child_nat_height;
524       gint child_width, child_height;
525
526       border_width = gtk_container_get_border_width (GTK_CONTAINER (alignment));
527
528       padding_horizontal = priv->padding_left + priv->padding_right;
529       padding_vertical = priv->padding_top + priv->padding_bottom;
530
531       width  = MAX (1, allocation->width - padding_horizontal - 2 * border_width);
532       height = MAX (1, allocation->height - padding_vertical - 2 * border_width);
533
534       if (gtk_widget_get_request_mode (child) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
535         {
536           gtk_widget_get_preferred_width (child, NULL, &child_nat_width);
537
538           child_width = MIN (width, child_nat_width);
539
540           gtk_widget_get_preferred_height_for_width (child, child_width, NULL, &child_nat_height);
541
542           child_height = MIN (height, child_nat_height);
543         }
544       else
545         {
546           gtk_widget_get_preferred_height (child, NULL, &child_nat_height);
547
548           child_height = MIN (height, child_nat_height);
549
550           gtk_widget_get_preferred_width_for_height (child, child_height, NULL, &child_nat_width);
551
552           child_width = MIN (width, child_nat_width);
553         }
554
555       if (width > child_width)
556         child_allocation.width = (child_width *
557                                   (1.0 - priv->xscale) +
558                                   width * priv->xscale);
559       else
560         child_allocation.width = width;
561
562       if (height > child_height)
563         child_allocation.height = (child_height *
564                                    (1.0 - priv->yscale) +
565                                    height * priv->yscale);
566       else
567         child_allocation.height = height;
568
569       if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
570         child_allocation.x = (1.0 - priv->xalign) * (width - child_allocation.width) + allocation->x + border_width + priv->padding_right;
571       else 
572         child_allocation.x = priv->xalign * (width - child_allocation.width) + allocation->x + border_width + priv->padding_left;
573
574       child_allocation.y = priv->yalign * (height - child_allocation.height) + allocation->y + border_width + priv->padding_top;
575
576       gtk_widget_size_allocate (child, &child_allocation);
577     }
578 }
579
580
581 static void
582 gtk_alignment_get_preferred_size (GtkWidget      *widget,
583                                   GtkOrientation  orientation,
584                                   gint            for_size,
585                                   gint           *minimum_size,
586                                   gint           *natural_size)
587 {
588   GtkAlignment *alignment = GTK_ALIGNMENT (widget);
589   GtkAlignmentPrivate *priv = alignment->priv;
590   GtkWidget *child;
591   guint minimum, natural;
592
593   natural = minimum = gtk_container_get_border_width (GTK_CONTAINER (widget)) * 2;
594
595   if ((child = gtk_bin_get_child (GTK_BIN (widget))) && gtk_widget_get_visible (child))
596     {
597       gint child_min, child_nat;
598
599       /* Request extra space for the padding: */
600       if (orientation == GTK_ORIENTATION_HORIZONTAL)
601         {
602           minimum += (priv->padding_left + priv->padding_right);
603
604           if (for_size < 0)
605             gtk_widget_get_preferred_width (child, &child_min, &child_nat);
606           else
607             {
608               gint min_height;
609
610               gtk_widget_get_preferred_height (child, &min_height, NULL);
611
612               for_size -= (priv->padding_top + priv->padding_bottom);
613
614               if (for_size > min_height)
615                 for_size = (min_height * (1.0 - priv->yscale) +
616                             for_size * priv->yscale);
617
618               gtk_widget_get_preferred_width_for_height (child, for_size, &child_min, &child_nat);
619             }
620         }
621       else
622         {
623           minimum += (priv->padding_top + priv->padding_bottom);
624
625           if (for_size < 0)
626             gtk_widget_get_preferred_height (child, &child_min, &child_nat);
627           else
628             {
629               gint min_width;
630
631               gtk_widget_get_preferred_width (child, &min_width, NULL);
632
633               for_size -= (priv->padding_left + priv->padding_right);
634
635               if (for_size > min_width)
636                 for_size = (min_width * (1.0 - priv->xscale) +
637                             for_size * priv->xscale);
638
639               gtk_widget_get_preferred_height_for_width (child, for_size, &child_min, &child_nat);
640             }
641         }
642
643       natural = minimum;
644
645       minimum += child_min;
646       natural += child_nat;
647     }
648
649   if (minimum_size)
650     *minimum_size = minimum;
651
652   if (natural_size)
653     *natural_size = natural;
654 }
655
656 static void
657 gtk_alignment_get_preferred_width (GtkWidget      *widget,
658                                    gint           *minimum_size,
659                                    gint           *natural_size)
660 {
661   gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, -1, minimum_size, natural_size);
662 }
663
664 static void
665 gtk_alignment_get_preferred_height (GtkWidget      *widget,
666                                     gint           *minimum_size,
667                                     gint           *natural_size)
668 {
669   gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, -1, minimum_size, natural_size);
670 }
671
672
673 static void 
674 gtk_alignment_get_preferred_width_for_height (GtkWidget           *widget,
675                                               gint                 for_size,
676                                               gint                *minimum_size,
677                                               gint                *natural_size)
678 {
679   gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, for_size, minimum_size, natural_size);
680 }
681
682 static void
683 gtk_alignment_get_preferred_height_for_width (GtkWidget           *widget,
684                                               gint                 for_size,
685                                               gint                *minimum_size,
686                                               gint                *natural_size)
687 {
688   gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, for_size, minimum_size, natural_size);
689 }
690
691 /**
692  * gtk_alignment_set_padding:
693  * @alignment: a #GtkAlignment
694  * @padding_top: the padding at the top of the widget
695  * @padding_bottom: the padding at the bottom of the widget
696  * @padding_left: the padding at the left of the widget
697  * @padding_right: the padding at the right of the widget.
698  *
699  * Sets the padding on the different sides of the widget.
700  * The padding adds blank space to the sides of the widget. For instance,
701  * this can be used to indent the child widget towards the right by adding
702  * padding on the left.
703  *
704  * Since: 2.4
705  */
706 void
707 gtk_alignment_set_padding (GtkAlignment    *alignment,
708                            guint            padding_top,
709                            guint            padding_bottom,
710                            guint            padding_left,
711                            guint            padding_right)
712 {
713   GtkAlignmentPrivate *priv;
714   GtkWidget *child;
715   
716   g_return_if_fail (GTK_IS_ALIGNMENT (alignment));
717
718   priv = alignment->priv;
719
720   g_object_freeze_notify (G_OBJECT (alignment));
721
722   if (priv->padding_top != padding_top)
723     {
724       priv->padding_top = padding_top;
725       g_object_notify (G_OBJECT (alignment), "top-padding");
726     }
727   if (priv->padding_bottom != padding_bottom)
728     {
729       priv->padding_bottom = padding_bottom;
730       g_object_notify (G_OBJECT (alignment), "bottom-padding");
731     }
732   if (priv->padding_left != padding_left)
733     {
734       priv->padding_left = padding_left;
735       g_object_notify (G_OBJECT (alignment), "left-padding");
736     }
737   if (priv->padding_right != padding_right)
738     {
739       priv->padding_right = padding_right;
740       g_object_notify (G_OBJECT (alignment), "right-padding");
741     }
742
743   g_object_thaw_notify (G_OBJECT (alignment));
744   
745   /* Make sure that the widget and children are redrawn with the new setting: */
746   child = gtk_bin_get_child (GTK_BIN (alignment));
747   if (child)
748     gtk_widget_queue_resize (child);
749
750   gtk_widget_queue_draw (GTK_WIDGET (alignment));
751 }
752
753 /**
754  * gtk_alignment_get_padding:
755  * @alignment: a #GtkAlignment
756  * @padding_top: (out) (allow-none): location to store the padding for
757  *     the top of the widget, or %NULL
758  * @padding_bottom: (out) (allow-none): location to store the padding
759  *     for the bottom of the widget, or %NULL
760  * @padding_left: (out) (allow-none): location to store the padding
761  *     for the left of the widget, or %NULL
762  * @padding_right: (out) (allow-none): location to store the padding
763  *     for the right of the widget, or %NULL
764  *
765  * Gets the padding on the different sides of the widget.
766  * See gtk_alignment_set_padding ().
767  *
768  * Since: 2.4
769  */
770 void
771 gtk_alignment_get_padding (GtkAlignment    *alignment,
772                            guint           *padding_top,
773                            guint           *padding_bottom,
774                            guint           *padding_left,
775                            guint           *padding_right)
776 {
777   GtkAlignmentPrivate *priv;
778
779   g_return_if_fail (GTK_IS_ALIGNMENT (alignment));
780
781   priv = alignment->priv;
782
783   if(padding_top)
784     *padding_top = priv->padding_top;
785   if(padding_bottom)
786     *padding_bottom = priv->padding_bottom;
787   if(padding_left)
788     *padding_left = priv->padding_left;
789   if(padding_right)
790     *padding_right = priv->padding_right;
791 }