[egg-list-box/flow-box-enhancements] Implement width-for-height in EggFlowBoxChild



commit 331564e41686ac5a9f64c2736add5593e80eb360
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Sep 28 18:02:37 2013 -0400

    Implement width-for-height in EggFlowBoxChild
    
    This is used in vertical orientation.

 TODO           |    3 -
 egg-flow-box.c |  144 ++++++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 110 insertions(+), 37 deletions(-)
---
diff --git a/TODO b/TODO
index f82c2f4..8f68210 100644
--- a/TODO
+++ b/TODO
@@ -4,9 +4,6 @@ EggFlowBox
 Maybe we want to support baseline alignment in rows. That will make
 size allocation a bit trickier, but may not be that hard.
 
-EggFlowBoxChild doesn't seem to support width-for-height mode, which is
-what flowbox uses in vertical mode. This probably needs to be added.
-
 fit_aligned_item_requests() - maybe this should do a binary search
 instead? Remembering last value as a start.
 
diff --git a/egg-flow-box.c b/egg-flow-box.c
index f2b4423..c35ae25 100644
--- a/egg-flow-box.c
+++ b/egg-flow-box.c
@@ -374,27 +374,53 @@ egg_flow_box_child_get_full_border (EggFlowBoxChild *child,
   full_border->bottom = padding.bottom + border.bottom + focus_width + focus_pad;
 }
 
+static GtkSizeRequestMode
+egg_flow_box_child_get_request_mode (GtkWidget *widget)
+{
+  EggFlowBox *box;
+
+  box = egg_flow_box_child_get_box (EGG_FLOW_BOX_CHILD (widget));
+  if (box)
+    return gtk_widget_get_request_mode (GTK_WIDGET (box));
+  else
+    return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
+}
+
+static void egg_flow_box_child_get_preferred_width_for_height (GtkWidget *widget,
+                                                               gint       height,
+                                                               gint      *minimum_width,
+                                                               gint      *natural_width);
+static void egg_flow_box_child_get_preferred_height           (GtkWidget *widget,
+                                                               gint      *minimum_height,
+                                                               gint      *natural_height);
+
 static void
 egg_flow_box_child_get_preferred_height_for_width (GtkWidget *widget,
                                                    gint       width,
                                                    gint      *minimum_height,
                                                    gint      *natural_height)
 {
-  GtkWidget *child;
-  gint child_min = 0, child_natural = 0;
-  GtkBorder full_border = { 0, };
+  if (egg_flow_box_child_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
+    {
+      GtkWidget *child;
+      gint child_min = 0, child_natural = 0;
+      GtkBorder full_border = { 0, };
 
-  egg_flow_box_child_get_full_border (EGG_FLOW_BOX_CHILD (widget), &full_border);
+      egg_flow_box_child_get_full_border (EGG_FLOW_BOX_CHILD (widget), &full_border);
+      child = gtk_bin_get_child (GTK_BIN (widget));
+      if (child && gtk_widget_get_visible (child))
+        gtk_widget_get_preferred_height_for_width (child, width - full_border.left - full_border.right,
+                                                   &child_min, &child_natural);
 
-  child = gtk_bin_get_child (GTK_BIN (widget));
-  if (child && gtk_widget_get_visible (child))
-      gtk_widget_get_preferred_height_for_width (child, width - full_border.left - full_border.right,
-                                                 &child_min, &child_natural);
-
-  if (minimum_height)
-    *minimum_height = full_border.top + child_min + full_border.bottom;
-  if (natural_height)
-    *natural_height = full_border.top + child_natural + full_border.bottom;
+      if (minimum_height)
+        *minimum_height = full_border.top + child_min + full_border.bottom;
+      if (natural_height)
+        *natural_height = full_border.top + child_natural + full_border.bottom;
+    }
+  else
+    {
+      egg_flow_box_child_get_preferred_height (widget, minimum_height, natural_height);
+    }
 }
 
 static void
@@ -402,21 +428,30 @@ egg_flow_box_child_get_preferred_width (GtkWidget *widget,
                                         gint      *minimum_width,
                                         gint      *natural_width)
 {
-  GtkWidget *child;
-  gint child_min = 0, child_natural = 0;
-  GtkBorder full_border = { 0, };
+  if (egg_flow_box_child_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
+    {
+      GtkWidget *child;
+      gint child_min = 0, child_natural = 0;
+      GtkBorder full_border = { 0, };
 
-  egg_flow_box_child_get_full_border (EGG_FLOW_BOX_CHILD (widget), &full_border);
+      egg_flow_box_child_get_full_border (EGG_FLOW_BOX_CHILD (widget), &full_border);
+      child = gtk_bin_get_child (GTK_BIN (widget));
+      if (child && gtk_widget_get_visible (child))
+        gtk_widget_get_preferred_width (child, &child_min, &child_natural);
 
-  child = gtk_bin_get_child (GTK_BIN (widget));
-  if (child && gtk_widget_get_visible (child))
-      gtk_widget_get_preferred_width (child,
-                                      &child_min, &child_natural);
+      if (minimum_width)
+        *minimum_width = full_border.left + child_min + full_border.right;
+      if (natural_width)
+        *natural_width = full_border.left + child_natural + full_border.right;
+    }
+  else
+    {
+      gint natural_height;
 
-  if (minimum_width)
-    *minimum_width = full_border.left + child_min + full_border.right;
-  if (natural_width)
-    *natural_width = full_border.left + child_natural + full_border.bottom;
+      egg_flow_box_child_get_preferred_height (widget, NULL, &natural_height);
+      egg_flow_box_child_get_preferred_width_for_height (widget, natural_height,
+                                                         minimum_width, natural_width);
+    }
 }
 
 static void
@@ -425,7 +460,27 @@ egg_flow_box_child_get_preferred_width_for_height (GtkWidget *widget,
                                                    gint      *minimum_width,
                                                    gint      *natural_width)
 {
-  egg_flow_box_child_get_preferred_width (widget, minimum_width, natural_width);
+  if (egg_flow_box_child_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
+    {
+      egg_flow_box_child_get_preferred_width (widget, minimum_width, natural_width);
+    }
+  else
+    {
+      GtkWidget *child;
+      gint child_min = 0, child_natural = 0;
+      GtkBorder full_border = { 0, };
+
+      egg_flow_box_child_get_full_border (EGG_FLOW_BOX_CHILD (widget), &full_border);
+      child = gtk_bin_get_child (GTK_BIN (widget));
+      if (child && gtk_widget_get_visible (child))
+        gtk_widget_get_preferred_width_for_height (child, height - full_border.top - full_border.bottom,
+                                                   &child_min, &child_natural);
+
+      if (minimum_width)
+        *minimum_width = full_border.left + child_min + full_border.right;
+      if (natural_width)
+        *natural_width = full_border.left + child_natural + full_border.right;
+    }
 }
 
 static void
@@ -433,10 +488,30 @@ egg_flow_box_child_get_preferred_height (GtkWidget *widget,
                                          gint      *minimum_height,
                                          gint      *natural_height)
 {
-  gint natural_width;
-  egg_flow_box_child_get_preferred_width (widget, NULL, &natural_width);
-  egg_flow_box_child_get_preferred_height_for_width (widget, natural_width,
-                                                     minimum_height, natural_height);
+  if (egg_flow_box_child_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
+    {
+      gint natural_width;
+
+      egg_flow_box_child_get_preferred_width (widget, NULL, &natural_width);
+      egg_flow_box_child_get_preferred_height_for_width (widget, natural_width,
+                                                         minimum_height, natural_height);
+    }
+  else
+    {
+      GtkWidget *child;
+      gint child_min = 0, child_natural = 0;
+      GtkBorder full_border = { 0, };
+
+      egg_flow_box_child_get_full_border (EGG_FLOW_BOX_CHILD (widget), &full_border);
+      child = gtk_bin_get_child (GTK_BIN (widget));
+      if (child && gtk_widget_get_visible (child))
+        gtk_widget_get_preferred_height (child, &child_min, &child_natural);
+
+      if (minimum_height)
+        *minimum_height = full_border.top + child_min + full_border.bottom;
+      if (natural_height)
+        *natural_height = full_border.top + child_natural + full_border.bottom;
+    }
 }
 
 static void
@@ -474,6 +549,7 @@ egg_flow_box_child_class_init (EggFlowBoxChildClass *class)
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
 
   widget_class->draw = egg_flow_box_child_draw;
+  widget_class->get_request_mode = egg_flow_box_child_get_request_mode;
   widget_class->get_preferred_height = egg_flow_box_child_get_preferred_height;
   widget_class->get_preferred_height_for_width = egg_flow_box_child_get_preferred_height_for_width;
   widget_class->get_preferred_width = egg_flow_box_child_get_preferred_width;


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