[gtk+/native-layout] Added documentation, implemented gtk_extended_layout_is_height_for_width() where needed.



commit 9306a73dfd5f061326a584a6c11971361fa7095a
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date:   Wed Apr 21 01:32:55 2010 -0400

    Added documentation, implemented gtk_extended_layout_is_height_for_width() where needed.

 gtk/gtkbin.c            |   32 ++++++++++++++------
 gtk/gtkbox.c            |   11 ++++++-
 gtk/gtkextendedlayout.c |   74 +++++++++++++++++++++++++++++++++++++++++++++-
 gtk/gtklabel.c          |   45 ++++++++++++++++++-----------
 4 files changed, 132 insertions(+), 30 deletions(-)
---
diff --git a/gtk/gtkbin.c b/gtk/gtkbin.c
index 691fb89..ed2796a 100644
--- a/gtk/gtkbin.c
+++ b/gtk/gtkbin.c
@@ -41,16 +41,16 @@ static void gtk_bin_forall      (GtkContainer   *container,
 static GType gtk_bin_child_type (GtkContainer   *container);
 
 
-static void gtk_bin_extended_layout_init  (GtkExtendedLayoutIface *iface);
-static void gtk_bin_get_width_for_height  (GtkExtendedLayout      *layout,
-					   gint                    height,
-					   gint                   *minimum_width,
-					   gint                   *natural_width);
-static void gtk_bin_get_height_for_width  (GtkExtendedLayout      *layout,
-					   gint                    width,
-					   gint                   *minimum_height,
-					   gint                   *natural_height);
-
+static void     gtk_bin_extended_layout_init  (GtkExtendedLayoutIface *iface);
+static gboolean gtk_bin_is_height_for_width   (GtkExtendedLayout      *layout);
+static void     gtk_bin_get_width_for_height  (GtkExtendedLayout      *layout,
+					       gint                    height,
+					       gint                   *minimum_width,
+					       gint                   *natural_width);
+static void     gtk_bin_get_height_for_width  (GtkExtendedLayout      *layout,
+					       gint                    width,
+					       gint                   *minimum_height,
+					       gint                   *natural_height);
 
 static GtkExtendedLayoutIface *parent_extended_layout_iface;
 
@@ -159,10 +159,22 @@ gtk_bin_extended_layout_init (GtkExtendedLayoutIface *iface)
 {
   parent_extended_layout_iface = g_type_interface_peek_parent (iface);
 
+  iface->is_height_for_width   = gtk_bin_is_height_for_width;
   iface->get_width_for_height  = gtk_bin_get_width_for_height;
   iface->get_height_for_width  = gtk_bin_get_height_for_width;
 }
 
+static gboolean 
+gtk_bin_is_height_for_width (GtkExtendedLayout      *layout)
+{
+  GtkBin *bin = GTK_BIN (layout);
+
+  if (bin->child)
+    return gtk_extended_layout_is_height_for_width (GTK_EXTENDED_LAYOUT (bin->child));
+
+  return TRUE;
+}
+
 static void
 get_child_padding_delta (GtkBin         *bin,
 			 gint           *delta_h,
diff --git a/gtk/gtkbox.c b/gtk/gtkbox.c
index 6d47035..9600969 100644
--- a/gtk/gtkbox.c
+++ b/gtk/gtkbox.c
@@ -110,6 +110,7 @@ static GType gtk_box_child_type        (GtkContainer   *container);
 
 
 static void     gtk_box_extended_layout_init (GtkExtendedLayoutIface *iface);
+static gboolean gtk_box_is_height_for_width  (GtkExtendedLayout      *layout);
 static void     gtk_box_get_desired_width    (GtkExtendedLayout      *layout,
 					      gint                   *minimum_size,
 					      gint                   *natural_size);
@@ -765,18 +766,26 @@ gtk_box_pack (GtkBox      *box,
 }
 
 
-
 static void
 gtk_box_extended_layout_init (GtkExtendedLayoutIface *iface)
 {
   parent_extended_layout_iface = g_type_interface_peek_parent (iface);
 
+  iface->is_height_for_width  = gtk_box_is_height_for_width;
   iface->get_desired_width    = gtk_box_get_desired_width;
   iface->get_desired_height   = gtk_box_get_desired_height;
   iface->get_height_for_width = gtk_box_get_height_for_width;
   iface->get_width_for_height = gtk_box_get_width_for_height;
 }
 
+static gboolean 
+gtk_box_is_height_for_width  (GtkExtendedLayout      *layout)
+{
+  GtkBoxPrivate *private = GTK_BOX_GET_PRIVATE (layout);
+
+  return (private->orientation == GTK_ORIENTATION_VERTICAL);
+}
+
 static void
 gtk_box_get_desired_size (GtkExtendedLayout      *layout,
 			  GtkOrientation          orientation,
diff --git a/gtk/gtkextendedlayout.c b/gtk/gtkextendedlayout.c
index c3108f0..da4ac26 100644
--- a/gtk/gtkextendedlayout.c
+++ b/gtk/gtkextendedlayout.c
@@ -22,6 +22,64 @@
  */
 
 
+/**
+ * SECTION:gtkextendedlayout
+ * @Short_Description: Height for Width Geometry management
+ * @Title: GtkExtendedLayout
+ *
+ * The extended layout is GTK+'s height for width geometry management
+ * system.
+ *
+ * <refsect2>
+ * <title>Implementing GtkExtendedLayout</title>
+ * <para>
+ * Some important things to keep in mind when implementing 
+ * or using the extended layout.
+ *
+ * The Extended Layout system will query a logical heirarchy in
+ * only one orientation at a time. When widgets are initially queried
+ * for their minimum sizes it is generally done in a dual pass
+ * in the direction chosen by the toplevel.
+ *
+ * For instance when queried in the normal height-for-width mode:
+ * First the default minimum and natural width for each widget
+ * in the interface will computed and collectively returned to 
+ * the toplevel by way of gtk_extended_layout_get_desired_width(). 
+ * Next; the toplevel will use the minimum width to query for the 
+ * minimum height contextual to that width using gtk_extended_layout_get_height_for_width()
+ * which will also be a highly recursive operation. This minimum
+ * for minimum size can be used to set the minimum size constraint 
+ * on the toplevel.
+ *
+ * When allocating; each container can use the minimum and natural
+ * sizes reported by thier children to allocate natural sizes and
+ * expose as much content as possible with the given allocation.
+ *
+ * That means that the request operation at allocation time will
+ * usually fire again in contexts of different allocated sizes than
+ * the ones originally queried for.
+ *
+ * A Widget that does not actually do height-for-width 
+ * or width-for-height size negotiations only has to implement
+ * get_desired_width() and get_desired_height()
+ *
+ * If a widget does move content around to smartly use up the
+ * allocated size, then it must support the request properly in
+ * both orientations; even if the request only makes sense in
+ * one orientation.
+ *
+ * For instance; a GtkLabel that does height-for-width word wrapping
+ * will not expect to have get_desired_height() called because that
+ * call is specific to a width-for-height request, in this case the
+ * label must return the heights contextual to its minimum possible
+ * width. By following this rule any widget that handles height-for-width
+ * or width-for-height requests will always be allocated at least
+ * enough space to fit its own content.
+ * </para>
+ * </refsect2>
+ */
+
+
 #include <config.h>
 #include "gtkextendedlayout.h"
 #include "gtksizegroup.h"
@@ -73,7 +131,11 @@ gtk_extended_layout_get_type (void)
 }
 
 /* looks for a cached size request for this for_size. If not
- * found, returns the oldest entry so it can be overwritten */
+ * found, returns the oldest entry so it can be overwritten 
+ *
+ * Note that this caching code was directly derived from 
+ * the Clutter toolkit.
+ */
 static gboolean
 get_cached_desired_size (gint           for_size,
 			 DesiredSize   *cached_sizes,
@@ -283,6 +345,10 @@ compute_size_for_orientation (GtkExtendedLayout *layout,
  * Returns: %TRUE if the widget prefers height-for-width, %FALSE if
  * the widget should be treated with a width-for-height preference.
  *
+ * <note><para>#GtkBin widgets generally propagate the preference of thier child, 
+ * container widgets need to request something either in context of their
+ * children or in context of their allocation capabilities.</para></note>
+ *
  * Since: 3.0
  */
 gboolean
@@ -306,7 +372,9 @@ gtk_extended_layout_is_height_for_width (GtkExtendedLayout *layout)
  * @minimum_width: location to store the minimum size, or %NULL
  * @natural_width: location to store the natural size, or %NULL
  *
- * Retreives a widget's minimum and natural size in a single dimension.
+ * Retreives a widget's initial minimum and natural width.
+ *
+ * <note><para>This call is specific to height for width requests.</para></note>
  *
  * Since: 3.0
  */
@@ -327,6 +395,8 @@ gtk_extended_layout_get_desired_width (GtkExtendedLayout *layout,
  *
  * Retreives a widget's minimum and natural size in a single dimension.
  *
+ * <note><para>This call is specific to width for height requests.</para></note>
+ *
  * Since: 3.0
  */
 void
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
index 05c3e31..6a3359e 100644
--- a/gtk/gtklabel.c
+++ b/gtk/gtklabel.c
@@ -304,22 +304,22 @@ static void          gtk_label_get_link_colors  (GtkWidget  *widget,
 static void          emit_activate_link         (GtkLabel     *label,
                                                  GtkLabelLink *link);
 
-static void gtk_label_extended_layout_init  (GtkExtendedLayoutIface *iface);
-
-static void gtk_label_get_desired_width     (GtkExtendedLayout      *layout,
-                                             gint                   *minimum_size,
-                                             gint                   *natural_size);
-static void gtk_label_get_desired_height    (GtkExtendedLayout      *layout,
-                                             gint                   *minimum_size,
-                                             gint                   *natural_size);
-static void gtk_label_get_width_for_height  (GtkExtendedLayout      *layout,
-                                             gint                    height,
-                                             gint                   *minimum_width,
-                                             gint                   *natural_width);
-static void gtk_label_get_height_for_width  (GtkExtendedLayout      *layout,
-                                             gint                    width,
-                                             gint                   *minimum_height,
-                                             gint                   *natural_height);
+static void     gtk_label_extended_layout_init  (GtkExtendedLayoutIface *iface);
+static gboolean gtk_label_is_height_for_width   (GtkExtendedLayout      *layout);
+static void     gtk_label_get_desired_width     (GtkExtendedLayout      *layout,
+						 gint                   *minimum_size,
+						 gint                   *natural_size);
+static void     gtk_label_get_desired_height    (GtkExtendedLayout      *layout,
+						 gint                   *minimum_size,
+						 gint                   *natural_size);
+static void     gtk_label_get_width_for_height  (GtkExtendedLayout      *layout,
+						 gint                    height,
+						 gint                   *minimum_width,
+						 gint                   *natural_width);
+static void     gtk_label_get_height_for_width  (GtkExtendedLayout      *layout,
+						 gint                    width,
+						 gint                   *minimum_height,
+						 gint                   *natural_height);
 
 static GQuark quark_angle = 0;
 
@@ -3027,7 +3027,6 @@ get_label_width (GtkLabel *label,
     }
   else
     {
-      /* XXX Do something about width_chars/max_width_chars when no ellipsize/wrap is set */
       *minimum = text_width;
       *natural = *minimum;
     }
@@ -3284,12 +3283,24 @@ get_single_line_height (GtkWidget   *widget,
 static void
 gtk_label_extended_layout_init (GtkExtendedLayoutIface *iface)
 {
+  iface->is_height_for_width  = gtk_label_is_height_for_width;
   iface->get_desired_width    = gtk_label_get_desired_width;
   iface->get_desired_height   = gtk_label_get_desired_height;
   iface->get_width_for_height = gtk_label_get_width_for_height;
   iface->get_height_for_width = gtk_label_get_height_for_width;
 }
 
+static gboolean 
+gtk_label_is_height_for_width (GtkExtendedLayout      *layout)
+{
+  GtkLabel *label = GTK_LABEL (layout);
+  gdouble   angle = gtk_label_get_angle (label);
+
+  if (angle == 90 || angle == 270)
+    return FALSE;
+  
+  return TRUE;
+}
 
 static void
 get_size_for_allocation (GtkLabel        *label,



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