[gtk+/extended-layout-jhs: 16/64] Add gtk_extended_layout_get_padding. Implement



commit 5f9c698cdd95a43b71fb2b8e0ebbc5b3e12c66ca
Author: Mathias Hasselmann <mathias hasselmann gmx de>
Date:   Thu Jun 28 22:21:28 2007 +0000

    Add gtk_extended_layout_get_padding. Implement
    
    2007-06-29  Mathias Hasselmann  <mathias hasselmann gmx de>
    
    	* gtk/gtkextendedlayout.h, gtk/gtkextendedlayout.c,
    	gtk/gtk.symbols: Add gtk_extended_layout_get_padding.
    	* gtk/gtkalignment.c, gtk/gtkbin.c, gtk/gtkbutton.c,
    	gtk/gtkframe.c: Implement gtk_extended_layout_get_padding.
    	* tests/autotestextendedlayout.c: Verify padding information
    	provided via gtk_extended_layout_get_padding.
    
    svn path=/branches/extended-layout/; revision=18283

 ChangeLog.gtk-extended-layout  |    9 +++
 gtk/gtk.symbols                |    1 +
 gtk/gtkalignment.c             |  126 ++++++++++++++++++++++++--------------
 gtk/gtkbin.c                   |   26 +++++---
 gtk/gtkbutton.c                |  133 +++++++++++++++++++++++++---------------
 gtk/gtkextendedlayout.c        |   24 +++++++
 gtk/gtkextendedlayout.h        |   25 +++++---
 gtk/gtkframe.c                 |   80 +++++++++++++++++++-----
 tests/autotestextendedlayout.c |   79 +++++++++++++++++++----
 9 files changed, 358 insertions(+), 145 deletions(-)
---
diff --git a/ChangeLog.gtk-extended-layout b/ChangeLog.gtk-extended-layout
index 353805b..5579820 100644
--- a/ChangeLog.gtk-extended-layout
+++ b/ChangeLog.gtk-extended-layout
@@ -1,3 +1,12 @@
+2007-06-29  Mathias Hasselmann  <mathias hasselmann gmx de>
+
+	* gtk/gtkextendedlayout.h, gtk/gtkextendedlayout.c,
+	gtk/gtk.symbols: Add gtk_extended_layout_get_padding.
+	* gtk/gtkalignment.c, gtk/gtkbin.c, gtk/gtkbutton.c, 
+	gtk/gtkframe.c: Implement gtk_extended_layout_get_padding.
+	* tests/autotestextendedlayout.c: Verify padding information 
+	provided via gtk_extended_layout_get_padding.
+
 2007-06-28  Mathias Hasselmann  <mathias hasselmann gmx de>
 
 	* gtk/gtkhbox.c: Merge separate, but nearly identical child allocation
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols
index 24216c5..28ae853 100644
--- a/gtk/gtk.symbols
+++ b/gtk/gtk.symbols
@@ -1293,6 +1293,7 @@ gtk_extended_layout_get_width_for_height
 gtk_extended_layout_get_natural_size
 gtk_extended_layout_get_baselines
 gtk_extended_layout_get_single_baseline
+gtk_extended_layout_get_padding
 #endif
 #endif
 
diff --git a/gtk/gtkalignment.c b/gtk/gtkalignment.c
index 5f852d0..904fcbb 100644
--- a/gtk/gtkalignment.c
+++ b/gtk/gtkalignment.c
@@ -26,6 +26,7 @@
 
 #include <config.h>
 #include "gtkalignment.h"
+#include "gtkextendedlayout.h"
 #include "gtkprivate.h"
 #include "gtkintl.h"
 #include "gtkalias.h"
@@ -50,10 +51,7 @@ enum {
 
 struct _GtkAlignmentPrivate
 {
-  guint padding_top;
-  guint padding_bottom;
-  guint padding_left;
-  guint padding_right;
+  GtkBorder padding;
 };
 
 static void gtk_alignment_size_request  (GtkWidget         *widget,
@@ -69,7 +67,11 @@ static void gtk_alignment_get_property (GObject         *object,
                                         GValue          *value,
                                         GParamSpec      *pspec);
 
-G_DEFINE_TYPE (GtkAlignment, gtk_alignment, GTK_TYPE_BIN)
+static void gtk_alignment_extended_layout_init (GtkExtendedLayoutIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtkAlignment, gtk_alignment, GTK_TYPE_BIN,
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
+						gtk_alignment_extended_layout_init))
 
 static void
 gtk_alignment_class_init (GtkAlignmentClass *class)
@@ -211,10 +213,10 @@ gtk_alignment_init (GtkAlignment *alignment)
 
   /* Initialize padding with default values: */
   priv = GTK_ALIGNMENT_GET_PRIVATE (alignment);
-  priv->padding_top = 0;
-  priv->padding_bottom = 0;
-  priv->padding_left = 0;
-  priv->padding_right = 0;
+  priv->padding.top = 0;
+  priv->padding.bottom = 0;
+  priv->padding.left = 0;
+  priv->padding.right = 0;
 }
 
 GtkWidget*
@@ -282,29 +284,29 @@ gtk_alignment_set_property (GObject         *object,
     case PROP_TOP_PADDING:
       gtk_alignment_set_padding (alignment,
 			 g_value_get_uint (value),
-			 priv->padding_bottom,
-			 priv->padding_left,
-			 priv->padding_right);
+			 priv->padding.bottom,
+			 priv->padding.left,
+			 priv->padding.right);
       break;
     case PROP_BOTTOM_PADDING:
       gtk_alignment_set_padding (alignment,
-			 priv->padding_top,
+			 priv->padding.top,
 			 g_value_get_uint (value),
-			 priv->padding_left,
-			 priv->padding_right);
+			 priv->padding.left,
+			 priv->padding.right);
       break;
     case PROP_LEFT_PADDING:
       gtk_alignment_set_padding (alignment,
-			 priv->padding_top,
-			 priv->padding_bottom,
+			 priv->padding.top,
+			 priv->padding.bottom,
 			 g_value_get_uint (value),
-			 priv->padding_right);
+			 priv->padding.right);
       break;
     case PROP_RIGHT_PADDING:
       gtk_alignment_set_padding (alignment,
-			 priv->padding_top,
-			 priv->padding_bottom,
-			 priv->padding_left,
+			 priv->padding.top,
+			 priv->padding.bottom,
+			 priv->padding.left,
 			 g_value_get_uint (value));
       break;
     
@@ -343,16 +345,16 @@ gtk_alignment_get_property (GObject         *object,
 
     /* Padding: */
     case PROP_TOP_PADDING:
-      g_value_set_uint (value, priv->padding_top);
+      g_value_set_uint (value, priv->padding.top);
       break;
     case PROP_BOTTOM_PADDING:
-      g_value_set_uint (value, priv->padding_bottom);
+      g_value_set_uint (value, priv->padding.bottom);
       break;
     case PROP_LEFT_PADDING:
-      g_value_set_uint (value, priv->padding_left);
+      g_value_set_uint (value, priv->padding.left);
       break;
     case PROP_RIGHT_PADDING:
-      g_value_set_uint (value, priv->padding_right);
+      g_value_set_uint (value, priv->padding.right);
       break;
       
     default:
@@ -433,8 +435,8 @@ gtk_alignment_size_request (GtkWidget      *widget,
       requisition->height += child_requisition.height;
 
       /* Request extra space for the padding: */
-      requisition->width += (priv->padding_left + priv->padding_right);
-      requisition->height += (priv->padding_top + priv->padding_bottom);
+      requisition->width += (priv->padding.left + priv->padding.right);
+      requisition->height += (priv->padding.top + priv->padding.bottom);
     }
 }
 
@@ -465,8 +467,8 @@ gtk_alignment_size_allocate (GtkWidget     *widget,
       border_width = GTK_CONTAINER (alignment)->border_width;
 
       priv = GTK_ALIGNMENT_GET_PRIVATE (widget);
-      padding_horizontal = priv->padding_left + priv->padding_right;
-      padding_vertical = priv->padding_top + priv->padding_bottom;
+      padding_horizontal = priv->padding.left + priv->padding.right;
+      padding_vertical = priv->padding.top + priv->padding.bottom;
 
       width = allocation->width - padding_horizontal - 2 * border_width;
       height = allocation->height - padding_vertical - 2 * border_width;
@@ -486,11 +488,11 @@ gtk_alignment_size_allocate (GtkWidget     *widget,
 	child_allocation.height = height;
 
       if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
-	child_allocation.x = (1.0 - alignment->xalign) * (width - child_allocation.width) + allocation->x + border_width + priv->padding_right;
+	child_allocation.x = (1.0 - alignment->xalign) * (width - child_allocation.width) + allocation->x + border_width + priv->padding.right;
       else 
-	child_allocation.x = alignment->xalign * (width - child_allocation.width) + allocation->x + border_width + priv->padding_left;
+	child_allocation.x = alignment->xalign * (width - child_allocation.width) + allocation->x + border_width + priv->padding.left;
 
-      child_allocation.y = alignment->yalign * (height - child_allocation.height) + allocation->y + border_width + priv->padding_top;
+      child_allocation.y = alignment->yalign * (height - child_allocation.height) + allocation->y + border_width + priv->padding.top;
 
       gtk_widget_size_allocate (bin->child, &child_allocation);
     }
@@ -526,24 +528,24 @@ gtk_alignment_set_padding (GtkAlignment    *alignment,
 
   g_object_freeze_notify (G_OBJECT (alignment));
 
-  if (priv->padding_top != padding_top)
+  if (priv->padding.top != padding_top)
     {
-      priv->padding_top = padding_top;
+      priv->padding.top = padding_top;
       g_object_notify (G_OBJECT (alignment), "top-padding");
     }
-  if (priv->padding_bottom != padding_bottom)
+  if (priv->padding.bottom != padding_bottom)
     {
-      priv->padding_bottom = padding_bottom;
+      priv->padding.bottom = padding_bottom;
       g_object_notify (G_OBJECT (alignment), "bottom-padding");
     }
-  if (priv->padding_left != padding_left)
+  if (priv->padding.left != padding_left)
     {
-      priv->padding_left = padding_left;
+      priv->padding.left = padding_left;
       g_object_notify (G_OBJECT (alignment), "left-padding");
     }
-  if (priv->padding_right != padding_right)
+  if (priv->padding.right != padding_right)
     {
-      priv->padding_right = padding_right;
+      priv->padding.right = padding_right;
       g_object_notify (G_OBJECT (alignment), "right-padding");
     }
 
@@ -579,16 +581,50 @@ gtk_alignment_get_padding (GtkAlignment    *alignment,
   GtkAlignmentPrivate *priv;
  
   g_return_if_fail (GTK_IS_ALIGNMENT (alignment));
-
   priv = GTK_ALIGNMENT_GET_PRIVATE (alignment);
+
   if(padding_top)
-    *padding_top = priv->padding_top;
+    *padding_top = priv->padding.top;
   if(padding_bottom)
-    *padding_bottom = priv->padding_bottom;
+    *padding_bottom = priv->padding.bottom;
   if(padding_left)
-    *padding_left = priv->padding_left;
+    *padding_left = priv->padding.left;
   if(padding_right)
-    *padding_right = priv->padding_right;
+    *padding_right = priv->padding.right;
+}
+
+static GtkExtendedLayoutFeatures
+gtk_alignment_extended_layout_get_features (GtkExtendedLayout *layout)
+{
+  GtkExtendedLayoutFeatures features;
+
+  features = 
+    GTK_EXTENDED_LAYOUT_CLASS (gtk_alignment_parent_class)->
+    get_features (layout);
+
+  return features | GTK_EXTENDED_LAYOUT_PADDING;
+}
+
+static void
+gtk_alignment_extended_layout_get_padding (GtkExtendedLayout *layout,
+                                           GtkBorder         *padding)
+{
+  GtkAlignmentPrivate *priv = GTK_ALIGNMENT_GET_PRIVATE (layout);
+  gint border_width = GTK_CONTAINER (layout)->border_width;
+
+  *padding = priv->padding;
+
+  padding->top += border_width;
+  padding->left += border_width;
+  padding->right += border_width;
+  padding->bottom += border_width;
+}
+
+static void
+gtk_alignment_extended_layout_init (GtkExtendedLayoutIface *iface)
+{
+  iface->get_features = gtk_alignment_extended_layout_get_features;
+  iface->get_padding = gtk_alignment_extended_layout_get_padding;
 }
 
 #define __GTK_ALIGNMENT_C__
diff --git a/gtk/gtkbin.c b/gtk/gtkbin.c
index 4ccc83f..fdc7b21 100644
--- a/gtk/gtkbin.c
+++ b/gtk/gtkbin.c
@@ -207,23 +207,29 @@ gtk_bin_extended_layout_get_baselines (GtkExtendedLayout  *layout,
                                        gint              **baselines)
 {
   GtkBin *bin = GTK_BIN (layout);
-  gint *baseptr, *baseend;
-  gint num_lines, dy;
+  gint num_lines;
 
   g_return_val_if_fail (GTK_IS_EXTENDED_LAYOUT (bin->child), -1);
 
-  layout = GTK_EXTENDED_LAYOUT (bin->child);
-  num_lines = gtk_extended_layout_get_baselines (layout, baselines);
+  num_lines = gtk_extended_layout_get_baselines (
+    GTK_EXTENDED_LAYOUT (bin->child), baselines);
 
-  if (baselines &&
-      gtk_widget_translate_coordinates (bin->child, GTK_WIDGET (bin),
-                                        0, 0, NULL, &dy))
+  if (baselines)
     {
-      baseptr = *baselines;
-      baseend = baseptr + num_lines;
+      gint *baseptr = *baselines;
+      gint *baseend = baseptr + num_lines;
+
+      GtkBorder padding;
+
+      if (GTK_EXTENDED_LAYOUT_HAS_PADDING (bin))
+        {
+          gtk_extended_layout_get_padding (layout, &padding);
+        }
+      else
+        padding.top = GTK_CONTAINER (bin)->border_width;
 
       while (baseptr < baseend)
-        *baseptr++ += dy;
+        *baseptr++ += padding.top;
     }
 
   return num_lines;
diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c
index 1b7db39..5692756 100644
--- a/gtk/gtkbutton.c
+++ b/gtk/gtkbutton.c
@@ -26,8 +26,9 @@
 
 #include <config.h>
 #include <string.h>
-#include "gtkalignment.h"
 #include "gtkbutton.h"
+#include "gtkalignment.h"
+#include "gtkextendedlayout.h"
 #include "gtklabel.h"
 #include "gtkmain.h"
 #include "gtkmarshalers.h"
@@ -141,10 +142,13 @@ static void gtk_button_state_changed   (GtkWidget             *widget,
 static void gtk_button_grab_notify     (GtkWidget             *widget,
 					gboolean               was_grabbed);
 
+static void gtk_button_extended_layout_init (GtkExtendedLayoutIface *iface);
 
 static guint button_signals[LAST_SIGNAL] = { 0 };
 
-G_DEFINE_TYPE (GtkButton, gtk_button, GTK_TYPE_BIN)
+G_DEFINE_TYPE_WITH_CODE (GtkButton, gtk_button, GTK_TYPE_BIN,
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
+						gtk_button_extended_layout_init))
 
 static void
 gtk_button_class_init (GtkButtonClass *klass)
@@ -1137,26 +1141,56 @@ gtk_button_size_request (GtkWidget      *widget,
 }
 
 static void
-gtk_button_size_allocate (GtkWidget     *widget,
-			  GtkAllocation *allocation)
+gtk_button_extended_layout_get_padding (GtkExtendedLayout *layout,
+                                        GtkBorder         *padding)
 {
-  GtkButton *button = GTK_BUTTON (widget);
-  GtkAllocation child_allocation;
+  GtkWidget *widget = GTK_WIDGET (layout);
 
   gint border_width = GTK_CONTAINER (widget)->border_width;
-  gint xthickness = GTK_WIDGET (widget)->style->xthickness;
-  gint ythickness = GTK_WIDGET (widget)->style->ythickness;
+  gint xthickness = widget->style->xthickness;
+  gint ythickness = widget->style->ythickness;
   GtkBorder default_border;
   GtkBorder inner_border;
   gint focus_width;
   gint focus_pad;
 
-  gtk_button_get_props (button, &default_border, NULL, &inner_border, NULL);
-  gtk_widget_style_get (GTK_WIDGET (widget),
+  gtk_button_get_props (GTK_BUTTON (layout), 
+                        &default_border, NULL,
+                        &inner_border, NULL);
+
+  gtk_widget_style_get (widget,
 			"focus-line-width", &focus_width,
 			"focus-padding", &focus_pad,
 			NULL);
- 
+
+  padding->left = border_width + inner_border.left + xthickness;
+  padding->right = border_width + inner_border.right + xthickness;
+  padding->bottom = border_width + inner_border.bottom + ythickness;
+  padding->top = border_width + inner_border.top + ythickness;
+      
+  if (GTK_WIDGET_CAN_DEFAULT (widget))
+    {
+      padding->left += default_border.left;
+      padding->right += default_border.right;
+      padding->bottom += default_border.bottom;
+      padding->top += default_border.top;
+    }
+
+  if (GTK_WIDGET_CAN_FOCUS (widget))
+    {
+      padding->left += focus_width + focus_pad;
+      padding->right += focus_width + focus_pad;
+      padding->bottom += focus_width + focus_pad;
+      padding->top += focus_width + focus_pad;
+    }
+}
+
+static void
+gtk_button_size_allocate (GtkWidget     *widget,
+			  GtkAllocation *allocation)
+{
+  GtkButton *button = GTK_BUTTON (widget);
+  gint border_width = GTK_CONTAINER (widget)->border_width;
 			    
   widget->allocation = *allocation;
 
@@ -1169,48 +1203,29 @@ gtk_button_size_allocate (GtkWidget     *widget,
 
   if (GTK_BIN (button)->child && GTK_WIDGET_VISIBLE (GTK_BIN (button)->child))
     {
-      child_allocation.x = widget->allocation.x + border_width + inner_border.left + xthickness;
-      child_allocation.y = widget->allocation.y + border_width + inner_border.top + ythickness;
-      
-      child_allocation.width = MAX (1, widget->allocation.width -
-                                    xthickness * 2 -
-                                    inner_border.left -
-                                    inner_border.right -
-				    border_width * 2);
-      child_allocation.height = MAX (1, widget->allocation.height -
-                                     ythickness * 2 -
-                                     inner_border.top -
-                                     inner_border.bottom -
-				     border_width * 2);
-
-      if (GTK_WIDGET_CAN_DEFAULT (button))
-	{
-	  child_allocation.x += default_border.left;
-	  child_allocation.y += default_border.top;
-	  child_allocation.width =  MAX (1, child_allocation.width - default_border.left - default_border.right);
-	  child_allocation.height = MAX (1, child_allocation.height - default_border.top - default_border.bottom);
-	}
+      GtkAllocation child_allocation;
+      GtkBorder padding;
 
-      if (GTK_WIDGET_CAN_FOCUS (button))
-	{
-	  child_allocation.x += focus_width + focus_pad;
-	  child_allocation.y += focus_width + focus_pad;
-	  child_allocation.width =  MAX (1, child_allocation.width - (focus_width + focus_pad) * 2);
-	  child_allocation.height = MAX (1, child_allocation.height - (focus_width + focus_pad) * 2);
-	}
+      gtk_button_extended_layout_get_padding (GTK_EXTENDED_LAYOUT (widget), &padding);
+
+      child_allocation.x = widget->allocation.x + padding.left;
+      child_allocation.y = widget->allocation.y + padding.top;
+      child_allocation.width = MAX (1, widget->allocation.width - padding.left - padding.right);
+      child_allocation.height = MAX (1, widget->allocation.height - padding.bottom - padding.top);
 
       if (button->depressed)
-	{
-	  gint child_displacement_x;
-	  gint child_displacement_y;
-	  
-	  gtk_widget_style_get (widget,
-				"child-displacement-x", &child_displacement_x, 
-				"child-displacement-y", &child_displacement_y,
-				NULL);
-	  child_allocation.x += child_displacement_x;
-	  child_allocation.y += child_displacement_y;
-	}
+        {
+          gint child_displacement_x;
+          gint child_displacement_y;
+          
+          gtk_widget_style_get (widget,
+                                "child-displacement-x", &child_displacement_x, 
+                                "child-displacement-y", &child_displacement_y,
+                                NULL);
+
+          child_allocation.x += child_displacement_x;
+          child_allocation.y += child_displacement_y;
+        }
 
       gtk_widget_size_allocate (GTK_BIN (button)->child, &child_allocation);
     }
@@ -2060,6 +2075,24 @@ gtk_button_get_image_position (GtkButton *button)
   return priv->image_position;
 }
 
+static GtkExtendedLayoutFeatures
+gtk_button_extended_layout_get_features (GtkExtendedLayout *layout)
+{
+  GtkExtendedLayoutFeatures features;
+
+  features = 
+    GTK_EXTENDED_LAYOUT_CLASS (gtk_button_parent_class)->
+    get_features (layout);
+
+  return features | GTK_EXTENDED_LAYOUT_PADDING;
+}
+
+static void
+gtk_button_extended_layout_init (GtkExtendedLayoutIface *iface)
+{
+  iface->get_features = gtk_button_extended_layout_get_features;
+  iface->get_padding = gtk_button_extended_layout_get_padding;
+}
 
 #define __GTK_BUTTON_C__
 #include "gtkaliasdef.c"  
diff --git a/gtk/gtkextendedlayout.c b/gtk/gtkextendedlayout.c
index d7bfa3b..2760fec 100644
--- a/gtk/gtkextendedlayout.c
+++ b/gtk/gtkextendedlayout.c
@@ -215,5 +215,29 @@ gtk_extended_layout_get_single_baseline (GtkExtendedLayout *layout,
   return offset;
 }
 
+/**
+ * gtk_extended_layout_get_padding:
+ * @layout: a #GtkExtendedLayout
+ * @padding: an #GtkBorder to be filled with the padding
+ *
+ * Query the padding this layout item puts arround its content.
+ *
+ * Since: 2.14
+ **/
+void
+gtk_extended_layout_get_padding (GtkExtendedLayout *layout,
+                                 GtkBorder         *padding)
+{
+  GtkExtendedLayoutIface *iface;
+
+  g_return_if_fail (GTK_IS_EXTENDED_LAYOUT (layout));
+  g_return_if_fail (NULL != padding);
+
+  iface = GTK_EXTENDED_LAYOUT_GET_IFACE (layout);
+
+  g_return_if_fail (iface->get_padding);
+  iface->get_padding(layout, padding);
+}
+
 #define __GTK_EXTENDED_LAYOUT_C__
 #include "gtkaliasdef.c"
diff --git a/gtk/gtkextendedlayout.h b/gtk/gtkextendedlayout.h
index cb6ef75..6b4a31a 100644
--- a/gtk/gtkextendedlayout.h
+++ b/gtk/gtkextendedlayout.h
@@ -26,7 +26,7 @@ G_BEGIN_DECLS
 
 #define GTK_TYPE_EXTENDED_LAYOUT            (gtk_extended_layout_get_type ())
 #define GTK_EXTENDED_LAYOUT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_EXTENDED_LAYOUT, GtkExtendedLayout))
-#define GTK_EXTENDED_LAYOUT_CLASS(obj)      (G_TYPE_CHECK_CLASS_CAST ((obj), GTK_TYPE_EXTENDED_LAYOUT, GtkExtendedLayoutIface))
+#define GTK_EXTENDED_LAYOUT_CLASS(klass)    ((GtkExtendedLayoutIface*)g_type_interface_peek ((klass), GTK_TYPE_EXTENDED_LAYOUT))
 #define GTK_IS_EXTENDED_LAYOUT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_EXTENDED_LAYOUT))
 #define GTK_EXTENDED_LAYOUT_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_TYPE_EXTENDED_LAYOUT, GtkExtendedLayoutIface))
 
@@ -42,19 +42,22 @@ G_BEGIN_DECLS
 #define GTK_EXTENDED_LAYOUT_HAS_BASELINES(obj) \
   (gtk_extended_layout_get_features (GTK_EXTENDED_LAYOUT ((obj))) & \
    GTK_EXTENDED_LAYOUT_BASELINES)
+#define GTK_EXTENDED_LAYOUT_HAS_PADDING(obj) \
+  (gtk_extended_layout_get_features (GTK_EXTENDED_LAYOUT ((obj))) & \
+   GTK_EXTENDED_LAYOUT_PADDING)
 
 typedef struct _GtkExtendedLayout           GtkExtendedLayout;
 typedef struct _GtkExtendedLayoutIface      GtkExtendedLayoutIface;
-typedef enum   _GtkExtendedLayoutFeatures   GtkExtendedLayoutFeatures;
 
 /*< flags >*/
-enum _GtkExtendedLayoutFeatures 
-{
-  GTK_EXTENDED_LAYOUT_WIDTH_FOR_HEIGHT = (1 << 0), 
-  GTK_EXTENDED_LAYOUT_HEIGHT_FOR_WIDTH = (1 << 1),
-  GTK_EXTENDED_LAYOUT_NATURAL_SIZE  =    (1 << 2),
-  GTK_EXTENDED_LAYOUT_BASELINES =        (1 << 3)
-};
+typedef enum {
+  GTK_EXTENDED_LAYOUT_NONE             = 0,
+  GTK_EXTENDED_LAYOUT_WIDTH_FOR_HEIGHT = 1 << 0, 
+  GTK_EXTENDED_LAYOUT_HEIGHT_FOR_WIDTH = 1 << 1,
+  GTK_EXTENDED_LAYOUT_NATURAL_SIZE     = 1 << 2,
+  GTK_EXTENDED_LAYOUT_BASELINES        = 1 << 3,
+  GTK_EXTENDED_LAYOUT_PADDING          = 1 << 4
+} GtkExtendedLayoutFeatures;
 
 struct _GtkExtendedLayoutIface
 {
@@ -71,6 +74,8 @@ struct _GtkExtendedLayoutIface
                                                      GtkRequisition     *requisition);
   gint                      (*get_baselines)        (GtkExtendedLayout  *layout,
                                                      gint              **baselines);
+  void                      (*get_padding)          (GtkExtendedLayout  *layout,
+                                                     GtkBorder          *padding);
 };
 
 
@@ -86,6 +91,8 @@ gint                      gtk_extended_layout_get_baselines        (GtkExtendedL
                                                                     gint              **baselines);
 gint                      gtk_extended_layout_get_single_baseline  (GtkExtendedLayout  *layout,
                                                                     GtkBaselinePolicy   policy);
+void                      gtk_extended_layout_get_padding          (GtkExtendedLayout  *layout,
+                                                                    GtkBorder          *padding);
 
 G_END_DECLS
 
diff --git a/gtk/gtkframe.c b/gtk/gtkframe.c
index f597402..d70de57 100644
--- a/gtk/gtkframe.c
+++ b/gtk/gtkframe.c
@@ -27,6 +27,7 @@
 #include <config.h>
 #include <string.h>
 #include "gtkframe.h"
+#include "gtkextendedlayout.h"
 #include "gtklabel.h"
 #include "gtkprivate.h"
 #include "gtkintl.h"
@@ -73,7 +74,20 @@ static void gtk_frame_compute_child_allocation      (GtkFrame      *frame,
 static void gtk_frame_real_compute_child_allocation (GtkFrame      *frame,
 						     GtkAllocation *child_allocation);
 
-G_DEFINE_TYPE (GtkFrame, gtk_frame, GTK_TYPE_BIN)
+/* GtkBuildable */
+static void gtk_frame_buildable_init                (GtkBuildableIface *iface);
+static void gtk_frame_buildable_add                 (GtkBuildable *buildable,
+						     GtkBuilder   *builder,
+						     GObject      *child,
+						     const gchar  *type);
+
+static void gtk_frame_extended_layout_init (GtkExtendedLayoutIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtkFrame, gtk_frame, GTK_TYPE_BIN,
+			 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
+						gtk_frame_buildable_init);
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
+						gtk_frame_extended_layout_init))
 
 static void
 gtk_frame_class_init (GtkFrameClass *class)
@@ -658,33 +672,65 @@ gtk_frame_compute_child_allocation (GtkFrame      *frame,
 }
 
 static void
-gtk_frame_real_compute_child_allocation (GtkFrame      *frame,
-					 GtkAllocation *child_allocation)
+gtk_frame_extended_layout_get_padding (GtkExtendedLayout *layout,
+                                       GtkBorder         *padding)
 {
-  GtkWidget *widget = GTK_WIDGET (frame);
-  GtkAllocation *allocation = &widget->allocation;
-  GtkRequisition child_requisition;
+  GtkFrame *frame = GTK_FRAME (layout);
+  GtkWidget *widget = GTK_WIDGET (layout);
+  gint border_width = GTK_CONTAINER (layout)->border_width;
+
   gint top_margin;
 
   if (frame->label_widget)
     {
+      GtkRequisition child_requisition;
       gtk_widget_get_child_requisition (frame->label_widget, &child_requisition);
       top_margin = MAX (child_requisition.height, widget->style->ythickness);
     }
   else
     top_margin = widget->style->ythickness;
+
+  padding->left = padding->right = border_width + widget->style->xthickness;
+  padding->bottom = border_width + widget->style->ythickness;
+  padding->top = border_width + top_margin;
+
+  g_debug ("%s: padding %d/%d/%d/%d", __FUNCTION__, padding->left, padding->top, padding->right, padding->bottom);
+  g_debug ("%s: border-width: %d, thickness: %d/%d", __FUNCTION__, border_width, widget->style->xthickness, widget->style->ythickness);
+}
+
+static void
+gtk_frame_real_compute_child_allocation (GtkFrame      *frame,
+					 GtkAllocation *child_allocation)
+{
+  GtkAllocation *allocation = &GTK_WIDGET (frame)->allocation;
+  GtkBorder padding;
+
+  gtk_frame_extended_layout_get_padding ((GtkExtendedLayout*)frame, &padding);
   
-  child_allocation->x = (GTK_CONTAINER (frame)->border_width +
-			 widget->style->xthickness);
-  child_allocation->width = MAX(1, (gint)allocation->width - child_allocation->x * 2);
-  
-  child_allocation->y = (GTK_CONTAINER (frame)->border_width + top_margin);
-  child_allocation->height = MAX (1, ((gint)allocation->height - child_allocation->y -
-				      (gint)GTK_CONTAINER (frame)->border_width -
-				      (gint)widget->style->ythickness));
-  
-  child_allocation->x += allocation->x;
-  child_allocation->y += allocation->y;
+  child_allocation->x = padding.left + allocation->x;
+  child_allocation->y = padding.top + allocation->y;
+
+  child_allocation->width = MAX(1, (gint)allocation->width - padding.left - padding.right);
+  child_allocation->height = MAX (1, (gint)allocation->height - padding.top - padding.bottom);
+}
+
+static GtkExtendedLayoutFeatures
+gtk_frame_extended_layout_get_features (GtkExtendedLayout *layout)
+{
+  GtkExtendedLayoutFeatures features;
+
+  features = 
+    GTK_EXTENDED_LAYOUT_CLASS (gtk_frame_parent_class)->
+    get_features (layout);
+
+  return features | GTK_EXTENDED_LAYOUT_PADDING;
+}
+
+static void
+gtk_frame_extended_layout_init (GtkExtendedLayoutIface *iface)
+{
+  iface->get_features = gtk_frame_extended_layout_get_features;
+  iface->get_padding = gtk_frame_extended_layout_get_padding;
 }
 
 #define __GTK_FRAME_C__
diff --git a/tests/autotestextendedlayout.c b/tests/autotestextendedlayout.c
index 74f141e..09cd8c1 100644
--- a/tests/autotestextendedlayout.c
+++ b/tests/autotestextendedlayout.c
@@ -7,13 +7,13 @@
 /*****************************************************************************/
 
 #define log_test(condition) \
-  log_test_impl(G_STRFUNC, (condition), #condition)
+  log_test_impl(G_STRFUNC, __LINE__, (condition), #condition)
 #define log_testf(condition, format, ...) \
-  log_test_impl(G_STRFUNC, (condition), #condition " (" format ")", __VA_ARGS__)
+  log_test_impl(G_STRFUNC, __LINE__, (condition), #condition " (" format ")", __VA_ARGS__)
 #define log_testi(expected, number) G_STMT_START { \
     const gint i = (expected), j = (number); \
-    log_test_impl(G_STRFUNC, i == j, \
-                  #number " is " #expected " (actual number %d)", j); \
+    log_test_impl(G_STRFUNC, __LINE__, i == j, \
+                  #number " is " #expected " (actual number %d, expected: %d)", j, i); \
   } G_STMT_END
 
 #define log_info(format, ...) \
@@ -70,6 +70,7 @@ log_int_array_impl (const gchar *function,
 
 static void
 log_test_impl (const gchar *function,
+               gint         lineno,
                gboolean     passed, 
                const gchar *test_name, ...)
 {
@@ -83,7 +84,10 @@ log_test_impl (const gchar *function,
   str = g_strdup_vprintf (test_name, args);
   va_end (args);
 
-  g_printf ("%s: %s: %s\n", passed ? "PASS" : "FAIL", function, str);
+  g_printf ("%s: %s, line %d: %s\033[0m\n",
+            passed ? "PASS" : "\033[1;31mFAIL", 
+            function, lineno, str);
+
   g_free (str);
 }
 
@@ -327,26 +331,37 @@ gtk_bin_test_extended_layout (void)
 {
   const GType types[] = 
     { 
-      GTK_TYPE_ALIGNMENT, GTK_TYPE_BUTTON, 
-      GTK_TYPE_EVENT_BOX, GTK_TYPE_FRAME, 
+      GTK_TYPE_ALIGNMENT, GTK_TYPE_BUTTON,
+      GTK_TYPE_EVENT_BOX, GTK_TYPE_FRAME,
       G_TYPE_INVALID
     };
 
   GtkExtendedLayoutFeatures features;
   GtkExtendedLayoutIface *iface;
   GtkExtendedLayout *layout;
+
+  GtkWindow *window;
   GtkWidget *label;
-  GtkBin *bin;
+  GtkWidget *bin;
+
+  gint baseline_label;
+  gint baseline_bin;
 
-  int i;
+  int i, y;
 
   for (i = 0; types[i]; ++i)
     {
-      bin = g_object_ref_sink (g_object_new (types[i], NULL));
-      layout = GTK_EXTENDED_LAYOUT (bin);
+      log_info ("Testing %s", g_type_name (types[i]));
 
       label = gtk_label_new (g_type_name (types[i]));
+
+      bin = g_object_new (types[i], NULL);
       gtk_container_add (GTK_CONTAINER (bin), label);
+      layout = GTK_EXTENDED_LAYOUT (bin);
+
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+      gtk_container_add (GTK_CONTAINER (window), bin);
+      gtk_widget_show_all (window);
 
       /* vtable */
 
@@ -376,10 +391,46 @@ gtk_bin_test_extended_layout (void)
       log_test (0 != (features & GTK_EXTENDED_LAYOUT_NATURAL_SIZE));
       log_test (0 != (features & GTK_EXTENDED_LAYOUT_BASELINES));
 
-      g_object_unref (bin);
-    }
+      /* verify baseline propagation */
+
+      baseline_label =
+        gtk_extended_layout_get_single_baseline (
+        GTK_EXTENDED_LAYOUT (label), GTK_BASELINE_FIRST);
+      baseline_bin =
+        gtk_extended_layout_get_single_baseline (
+        GTK_EXTENDED_LAYOUT (bin), GTK_BASELINE_FIRST);
+
+      if (!gtk_widget_translate_coordinates (label, bin, 0, 0, NULL, &y))
+        log_testf (FALSE, "failed to translate GtkLabel coordinates "
+                          "into %s coordinates", g_type_name (types[i]));
+
+      log_testi (baseline_label + y, baseline_bin);
 
-  log_testf (FALSE, "%s", "TODO: Provide real tests for GtkBin");
+      gtk_container_set_border_width (GTK_CONTAINER (bin), 23);
+
+      baseline_bin =
+        gtk_extended_layout_get_single_baseline (
+        GTK_EXTENDED_LAYOUT (bin), GTK_BASELINE_FIRST);
+
+      log_testi (baseline_label + y + 23, baseline_bin);
+
+      /* verify padding injection */
+
+      if (GTK_TYPE_ALIGNMENT == types[i])
+        {
+          log_test (0 != (features & GTK_EXTENDED_LAYOUT_PADDING));
+
+          gtk_alignment_set_padding (GTK_ALIGNMENT (bin), 5, 7, 11, 13);
+
+          baseline_bin =
+            gtk_extended_layout_get_single_baseline (
+            GTK_EXTENDED_LAYOUT (bin), GTK_BASELINE_FIRST);
+
+          log_testi (baseline_label + y + 28, baseline_bin);
+        }
+
+      gtk_widget_destroy (window);
+    }
 }
 
 /*****************************************************************************/



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]