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