[gtk/constraint-guide-2: 5/6] Split GtkConstraintGuide into its own file



commit f2a604ba9f7edbb1aeecb6d303baa7ca19e98692
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Jun 27 19:25:04 2019 +0000

    Split GtkConstraintGuide into its own file
    
    Lest gtkconstraintlayout.c turns too big and messy.

 gtk/gtkconstraintguide.c        | 262 ++++++++++++++++++++++++
 gtk/gtkconstraintguide.h        |  45 +++++
 gtk/gtkconstraintguideprivate.h |  61 ++++++
 gtk/gtkconstraintlayout.c       | 427 +++++++---------------------------------
 gtk/gtkconstraintlayout.h       |  17 +-
 gtk/meson.build                 |   1 +
 6 files changed, 441 insertions(+), 372 deletions(-)
---
diff --git a/gtk/gtkconstraintguide.c b/gtk/gtkconstraintguide.c
new file mode 100644
index 0000000000..f9f58bba8f
--- /dev/null
+++ b/gtk/gtkconstraintguide.c
@@ -0,0 +1,262 @@
+/* gtkconstraintguide.c: Flexible space for constraints
+ * Copyright 2019 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Matthias Clasen
+ */
+
+#include "config.h"
+
+#include "gtkconstraintguide.h"
+
+#include "gtkconstraintguideprivate.h"
+#include "gtkconstraintlayoutprivate.h"
+#include "gtkconstraintexpressionprivate.h"
+#include "gtkconstraintsolverprivate.h"
+
+#include "gtkdebug.h"
+#include "gtkintl.h"
+#include "gtkprivate.h"
+
+
+struct _GtkConstraintGuideClass {
+  GObjectClass parent_class;
+};
+
+enum {
+  GUIDE_PROP_MIN_WIDTH = 1,
+  GUIDE_PROP_MIN_HEIGHT,
+  GUIDE_PROP_NAT_WIDTH,
+  GUIDE_PROP_NAT_HEIGHT,
+  GUIDE_PROP_MAX_WIDTH,
+  GUIDE_PROP_MAX_HEIGHT,
+  LAST_GUIDE_PROP
+};
+
+static GParamSpec *guide_props[LAST_GUIDE_PROP];
+
+static void
+gtk_constraint_guide_constraint_target_iface_init (GtkConstraintTargetInterface *iface)
+{
+}
+
+G_DEFINE_TYPE_WITH_CODE (GtkConstraintGuide, gtk_constraint_guide, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_CONSTRAINT_TARGET,
+                                                gtk_constraint_guide_constraint_target_iface_init))
+
+static void
+gtk_constraint_guide_init (GtkConstraintGuide *guide)
+{
+  guide->bound_attributes =
+    g_hash_table_new_full (g_str_hash, g_str_equal,
+                           NULL,
+                           (GDestroyNotify) gtk_constraint_variable_unref);
+}
+
+void
+gtk_constraint_guide_update (GtkConstraintGuide *guide,
+                             GuideValue          index)
+{
+  GtkConstraintSolver *solver;
+  GtkConstraintVariable *var;
+  int attr[LAST_GUIDE_VALUE] = {
+    GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
+    GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
+    GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
+    GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
+    GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
+    GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
+  };
+  int relation[LAST_GUIDE_VALUE] = {
+    GTK_CONSTRAINT_RELATION_GE,
+    GTK_CONSTRAINT_RELATION_GE,
+    GTK_CONSTRAINT_RELATION_EQ,
+    GTK_CONSTRAINT_RELATION_EQ,
+    GTK_CONSTRAINT_RELATION_LE,
+    GTK_CONSTRAINT_RELATION_LE,
+  };
+  double weight[LAST_GUIDE_VALUE] = {
+    GTK_CONSTRAINT_WEIGHT_REQUIRED,
+    GTK_CONSTRAINT_WEIGHT_REQUIRED,
+    GTK_CONSTRAINT_WEIGHT_MEDIUM,
+    GTK_CONSTRAINT_WEIGHT_MEDIUM,
+    GTK_CONSTRAINT_WEIGHT_REQUIRED,
+    GTK_CONSTRAINT_WEIGHT_REQUIRED,
+  };
+
+  if (!guide->layout)
+    return;
+
+  solver = gtk_constraint_layout_get_solver (guide->layout);
+  if (!solver)
+    return;
+
+  if (guide->constraints[index] != NULL)
+    gtk_constraint_solver_remove_constraint (solver, guide->constraints[index]);
+
+  var = gtk_constraint_layout_get_attribute (guide->layout, attr[index], "guide", NULL, 
guide->bound_attributes);
+  guide->constraints[index] =
+    gtk_constraint_solver_add_constraint (solver,
+                                          var,
+                                          relation[index],
+                                          gtk_constraint_expression_new (guide->values[index]),
+                                          weight[index]);
+}
+
+void
+gtk_constraint_guide_detach (GtkConstraintGuide *guide)
+{
+  GtkConstraintSolver *solver;
+  int i;
+
+  if (!guide->layout)
+    return;
+
+  solver = gtk_constraint_layout_get_solver (guide->layout);
+  if (!solver)
+    return;
+
+  for (i = 0; i < LAST_GUIDE_VALUE; i++)
+    {
+      gtk_constraint_solver_remove_constraint (solver, guide->constraints[i]);
+      guide->constraints[i] = NULL;
+    }
+
+  g_hash_table_remove_all (guide->bound_attributes);
+}
+
+static void
+gtk_constraint_guide_set_property (GObject      *gobject,
+                                   guint         prop_id,
+                                   const GValue *value,
+                                   GParamSpec   *pspec)
+{
+  GtkConstraintGuide *self = GTK_CONSTRAINT_GUIDE (gobject);
+  int val;
+  GuideValue index;
+
+  switch (prop_id)
+    {
+    case GUIDE_PROP_MIN_WIDTH:
+    case GUIDE_PROP_MIN_HEIGHT:
+    case GUIDE_PROP_NAT_WIDTH:
+    case GUIDE_PROP_NAT_HEIGHT:
+    case GUIDE_PROP_MAX_WIDTH:
+    case GUIDE_PROP_MAX_HEIGHT:
+      val = g_value_get_int (value);
+      index = prop_id - 1;
+      if (self->values[index] != val)
+        {
+          self->values[index] = val;
+          g_object_notify_by_pspec (gobject, pspec);
+          gtk_constraint_guide_update (self, index);
+        }
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_constraint_guide_get_property (GObject    *gobject,
+                                   guint       prop_id,
+                                   GValue     *value,
+                                   GParamSpec *pspec)
+{
+  GtkConstraintGuide *self = GTK_CONSTRAINT_GUIDE (gobject);
+
+  switch (prop_id)
+    {
+    case GUIDE_PROP_MIN_WIDTH:
+    case GUIDE_PROP_MIN_HEIGHT:
+    case GUIDE_PROP_NAT_WIDTH:
+    case GUIDE_PROP_NAT_HEIGHT:
+    case GUIDE_PROP_MAX_WIDTH:
+    case GUIDE_PROP_MAX_HEIGHT:
+      g_value_set_int (value, self->values[prop_id - 1]);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_constraint_guide_finalize (GObject *object)
+{
+  GtkConstraintGuide *self = GTK_CONSTRAINT_GUIDE (object);
+
+  g_clear_pointer (&self->bound_attributes, g_hash_table_unref);
+
+  G_OBJECT_CLASS (gtk_constraint_guide_parent_class)->finalize (object);
+}
+
+static void
+gtk_constraint_guide_class_init (GtkConstraintGuideClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->finalize = gtk_constraint_guide_finalize;
+  object_class->set_property = gtk_constraint_guide_set_property;
+  object_class->get_property = gtk_constraint_guide_get_property;
+
+  guide_props[GUIDE_PROP_MIN_WIDTH] =
+      g_param_spec_int ("min-width",
+                        "Minimum width",
+                        "Minimum width",
+                        0, G_MAXINT, 0,
+                        G_PARAM_READWRITE|
+                        G_PARAM_EXPLICIT_NOTIFY);
+  guide_props[GUIDE_PROP_MIN_HEIGHT] =
+      g_param_spec_int ("min-height",
+                        "Minimum height",
+                        "Minimum height",
+                        0, G_MAXINT, 0,
+                        G_PARAM_READWRITE|
+                        G_PARAM_EXPLICIT_NOTIFY);
+  guide_props[GUIDE_PROP_NAT_WIDTH] =
+      g_param_spec_int ("nat-width",
+                        "Natural width",
+                        "Natural width",
+                        0, G_MAXINT, 0,
+                        G_PARAM_READWRITE|
+                        G_PARAM_EXPLICIT_NOTIFY);
+  guide_props[GUIDE_PROP_NAT_HEIGHT] =
+      g_param_spec_int ("nat-height",
+                        "Natural height",
+                        "Natural height",
+                        0, G_MAXINT, 0,
+                        G_PARAM_READWRITE|
+                        G_PARAM_EXPLICIT_NOTIFY);
+  guide_props[GUIDE_PROP_MAX_WIDTH] =
+      g_param_spec_int ("max-width",
+                        "Maximum width",
+                        "Maximum width",
+                        0, G_MAXINT, G_MAXINT,
+                        G_PARAM_READWRITE|
+                        G_PARAM_EXPLICIT_NOTIFY);
+  guide_props[GUIDE_PROP_MAX_HEIGHT] =
+      g_param_spec_int ("max-height",
+                        "Maximum height",
+                        "Maximum height",
+                        0, G_MAXINT, G_MAXINT,
+                        G_PARAM_READWRITE|
+                        G_PARAM_EXPLICIT_NOTIFY);
+
+  g_object_class_install_properties (object_class, LAST_GUIDE_PROP, guide_props);
+}
diff --git a/gtk/gtkconstraintguide.h b/gtk/gtkconstraintguide.h
new file mode 100644
index 0000000000..2c54df396a
--- /dev/null
+++ b/gtk/gtkconstraintguide.h
@@ -0,0 +1,45 @@
+/* gtkconstraintguide.h: Flexible space for constraints
+ * Copyright 2019 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Matthias Clasen
+ */
+
+#pragma once
+
+#include <gtk/gtktypes.h>
+#include <gtk/gtkenums.h>
+
+G_BEGIN_DECLS
+
+
+#define GTK_TYPE_CONSTRAINT_GUIDE (gtk_constraint_guide_get_type ())
+
+/**
+ * GtkConstraintGuide:
+ *
+ * An object that can be added to a #GtkConstraintLayout and be
+ * used in constraints like a widget, without being drawn. Guides
+ * have a minimal and natural size. Depending on the constraints
+ * that are applied, they can act like a guideline that widgets
+ * can be aligned to, or like 'flexible space'.
+ */
+GDK_AVAILABLE_IN_ALL
+G_DECLARE_FINAL_TYPE (GtkConstraintGuide, gtk_constraint_guide, GTK, CONSTRAINT_GUIDE, GObject)
+
+GDK_AVAILABLE_IN_ALL
+GtkConstraintGuide *    gtk_constraint_guide_new                (void);
+
+G_END_DECLS
diff --git a/gtk/gtkconstraintguideprivate.h b/gtk/gtkconstraintguideprivate.h
new file mode 100644
index 0000000000..ad6d5cef76
--- /dev/null
+++ b/gtk/gtkconstraintguideprivate.h
@@ -0,0 +1,61 @@
+/* gtkconstraintguideprivate.h: Constraint between two widgets
+ * Copyright 2019 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Matthias Clasen
+ */
+
+#pragma once
+
+#include "gtkconstraintguide.h"
+#include "gtkconstraintlayout.h"
+#include "gtkconstrainttypesprivate.h"
+
+G_BEGIN_DECLS
+
+typedef enum {
+  GUIDE_MIN_WIDTH,
+  GUIDE_MIN_HEIGHT,
+  GUIDE_NAT_WIDTH,
+  GUIDE_NAT_HEIGHT,
+  GUIDE_MAX_WIDTH,
+  GUIDE_MAX_HEIGHT,
+  LAST_GUIDE_VALUE
+} GuideValue;
+
+struct _GtkConstraintGuide
+{
+  GObject parent_instance;
+
+  int values[LAST_GUIDE_VALUE];
+
+  GtkConstraintLayout *layout;
+
+  /* HashTable<static string, Variable>; a hash table of variables,
+   * one for each attribute; we use these to query and suggest the
+   * values for the solver. The string is static and does not need
+   * to be freed.
+   */
+  GHashTable *bound_attributes;
+
+  GtkConstraintRef *constraints[LAST_GUIDE_VALUE];
+};
+
+void gtk_constraint_guide_update (GtkConstraintGuide *guide,
+                                  GuideValue          index);
+void gtk_constraint_guide_detach (GtkConstraintGuide *guide);
+
+
+G_END_DECLS
diff --git a/gtk/gtkconstraintlayout.c b/gtk/gtkconstraintlayout.c
index b346cf2f35..f4a4d81d27 100644
--- a/gtk/gtkconstraintlayout.c
+++ b/gtk/gtkconstraintlayout.c
@@ -60,11 +60,13 @@
 #include "config.h"
 
 #include "gtkconstraintlayout.h"
+#include "gtkconstraintlayoutprivate.h"
 
 #include "gtkconstraintprivate.h"
 #include "gtkconstraintexpressionprivate.h"
 #include "gtkconstraintsolverprivate.h"
 #include "gtklayoutchild.h"
+#include "gtkconstraintguideprivate.h"
 
 #include "gtkdebug.h"
 #include "gtkintl.h"
@@ -84,34 +86,6 @@ struct _GtkConstraintLayoutChild
   GHashTable *bound_attributes;
 };
 
-typedef enum {
-  GUIDE_MIN_WIDTH,
-  GUIDE_MIN_HEIGHT,
-  GUIDE_NAT_WIDTH,
-  GUIDE_NAT_HEIGHT,
-  GUIDE_MAX_WIDTH,
-  GUIDE_MAX_HEIGHT,
-  LAST_GUIDE_VALUE
-} GuideValue;
-
-struct _GtkConstraintGuide
-{
-  GObject parent_instance;
-
-  int values[LAST_GUIDE_VALUE];
-
-  GtkConstraintLayout *layout;
-
-  /* HashTable<static string, Variable>; a hash table of variables,
-   * one for each attribute; we use these to query and suggest the
-   * values for the solver. The string is static and does not need
-   * to be freed.
-   */
-  GHashTable *bound_attributes;
-
-  GtkConstraintRef *constraints[LAST_GUIDE_VALUE];
-};
-
 struct _GtkConstraintLayout
 {
   GtkLayoutManager parent_instance;
@@ -140,7 +114,7 @@ struct _GtkConstraintLayout
 
 G_DEFINE_TYPE (GtkConstraintLayoutChild, gtk_constraint_layout_child, GTK_TYPE_LAYOUT_CHILD)
 
-static inline GtkConstraintSolver *
+GtkConstraintSolver *
 gtk_constraint_layout_get_solver (GtkConstraintLayout *self)
 {
   GtkWidget *widget;
@@ -184,14 +158,49 @@ get_attribute_name (GtkConstraintAttribute attr)
   return attribute_names[attr];
 }
 
-static GtkConstraintVariable *
-get_attribute (GHashTable             *bound_attributes,
-               GtkConstraintSolver    *solver,
-               const char             *prefix,
-               GtkConstraintAttribute  attr)
+static GtkConstraintAttribute
+resolve_direction (GtkConstraintAttribute  attr,
+                   GtkWidget              *widget)
+{
+  GtkTextDirection text_dir;
+
+  /* Resolve the start/end attributes depending on the layout's text direction */
+
+  if (widget)
+    text_dir = gtk_widget_get_direction (widget);
+  else
+    text_dir = GTK_TEXT_DIR_LTR;
+
+  if (attr == GTK_CONSTRAINT_ATTRIBUTE_START)
+    {
+      if (text_dir == GTK_TEXT_DIR_RTL)
+        attr = GTK_CONSTRAINT_ATTRIBUTE_RIGHT;
+      else
+        attr = GTK_CONSTRAINT_ATTRIBUTE_LEFT;
+    }
+  else if (attr == GTK_CONSTRAINT_ATTRIBUTE_END)
+    {
+      if (text_dir == GTK_TEXT_DIR_RTL)
+        attr = GTK_CONSTRAINT_ATTRIBUTE_LEFT;
+      else
+        attr = GTK_CONSTRAINT_ATTRIBUTE_RIGHT;
+    }
+
+  return attr;
+}
+
+GtkConstraintVariable *
+gtk_constraint_layout_get_attribute (GtkConstraintLayout    *layout,
+                                     GtkConstraintAttribute  attr,
+                                     const char             *prefix,
+                                     GtkWidget              *widget,
+                                     GHashTable             *bound_attributes)
 {
   const char *attr_name;
   GtkConstraintVariable *res;
+  GtkConstraintSolver *solver = layout->solver;
+
+  attr = resolve_direction (attr, widget);
 
   attr_name = get_attribute_name (attr);
   res = g_hash_table_lookup (bound_attributes, attr_name);
@@ -214,8 +223,8 @@ get_attribute (GHashTable             *bound_attributes,
         GtkConstraintVariable *left, *width;
         GtkConstraintExpression *expr;
 
-        left = get_attribute (bound_attributes, solver, prefix, GTK_CONSTRAINT_ATTRIBUTE_LEFT);
-        width = get_attribute (bound_attributes, solver, prefix, GTK_CONSTRAINT_ATTRIBUTE_WIDTH);
+        left = gtk_constraint_layout_get_attribute (layout, GTK_CONSTRAINT_ATTRIBUTE_LEFT, prefix, widget, 
bound_attributes);
+        width = gtk_constraint_layout_get_attribute (layout, GTK_CONSTRAINT_ATTRIBUTE_WIDTH, prefix, widget, 
bound_attributes);
 
         gtk_constraint_expression_builder_init (&builder, solver);
         gtk_constraint_expression_builder_term (&builder, left);
@@ -236,8 +245,8 @@ get_attribute (GHashTable             *bound_attributes,
         GtkConstraintVariable *top, *height;
         GtkConstraintExpression *expr;
 
-        top = get_attribute (bound_attributes, solver, prefix, GTK_CONSTRAINT_ATTRIBUTE_TOP);
-        height = get_attribute (bound_attributes, solver, prefix, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT);
+        top = gtk_constraint_layout_get_attribute (layout, GTK_CONSTRAINT_ATTRIBUTE_TOP, prefix, widget, 
bound_attributes);
+        height = gtk_constraint_layout_get_attribute (layout, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT, prefix, 
widget, bound_attributes);
 
         gtk_constraint_expression_builder_init (&builder, solver);
         gtk_constraint_expression_builder_term (&builder, top);
@@ -258,8 +267,8 @@ get_attribute (GHashTable             *bound_attributes,
         GtkConstraintVariable *left, *width;
         GtkConstraintExpression *expr;
 
-        left = get_attribute (bound_attributes, solver, prefix, GTK_CONSTRAINT_ATTRIBUTE_LEFT);
-        width = get_attribute (bound_attributes, solver, prefix, GTK_CONSTRAINT_ATTRIBUTE_WIDTH);
+        left = gtk_constraint_layout_get_attribute (layout, GTK_CONSTRAINT_ATTRIBUTE_LEFT, prefix, widget, 
bound_attributes);
+        width = gtk_constraint_layout_get_attribute (layout, GTK_CONSTRAINT_ATTRIBUTE_WIDTH, prefix, widget, 
bound_attributes);
 
         gtk_constraint_expression_builder_init (&builder, solver);
         gtk_constraint_expression_builder_term (&builder, width);
@@ -282,8 +291,8 @@ get_attribute (GHashTable             *bound_attributes,
         GtkConstraintVariable *top, *height;
         GtkConstraintExpression *expr;
 
-        top = get_attribute (bound_attributes, solver, prefix, GTK_CONSTRAINT_ATTRIBUTE_TOP);
-        height = get_attribute (bound_attributes, solver, prefix, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT);
+        top = gtk_constraint_layout_get_attribute (layout, GTK_CONSTRAINT_ATTRIBUTE_TOP, prefix, widget, 
bound_attributes);
+        height = gtk_constraint_layout_get_attribute (layout, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT, prefix, 
widget, bound_attributes);
 
         gtk_constraint_expression_builder_init (&builder, solver);
         gtk_constraint_expression_builder_term (&builder, height);
@@ -332,62 +341,28 @@ get_attribute (GHashTable             *bound_attributes,
   return res;
 }
 
-static GtkConstraintAttribute
-resolve_direction (GtkConstraintAttribute  attr,
-                   GtkWidget              *widget)
-{
-  GtkTextDirection text_dir;
-
-  /* Resolve the start/end attributes depending on the layout's text direction */
-
-  if (widget)
-    text_dir = gtk_widget_get_direction (widget);
-  else
-    text_dir = GTK_TEXT_DIR_LTR;
-
-  if (attr == GTK_CONSTRAINT_ATTRIBUTE_START)
-    {
-      if (text_dir == GTK_TEXT_DIR_RTL)
-        attr = GTK_CONSTRAINT_ATTRIBUTE_RIGHT;
-      else
-        attr = GTK_CONSTRAINT_ATTRIBUTE_LEFT;
-    }
-  else if (attr == GTK_CONSTRAINT_ATTRIBUTE_END)
-    {
-      if (text_dir == GTK_TEXT_DIR_RTL)
-        attr = GTK_CONSTRAINT_ATTRIBUTE_LEFT;
-      else
-        attr = GTK_CONSTRAINT_ATTRIBUTE_RIGHT;
-    }
-
-  return attr;
-}
-
 static GtkConstraintVariable *
-get_child_attribute (GtkConstraintLayoutChild *self,
-                     GtkConstraintSolver      *solver,
-                     GtkWidget                *widget,
-                     GtkConstraintAttribute    attr)
+get_child_attribute (GtkConstraintLayout    *layout,
+                     GtkWidget              *widget,
+                     GtkConstraintAttribute  attr)
 {
+  GtkConstraintLayoutChild *child_info;
   const char *prefix = gtk_widget_get_name (widget);
 
-  attr = resolve_direction (attr, widget);
+  child_info = GTK_CONSTRAINT_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (GTK_LAYOUT_MANAGER 
(layout), widget));
 
-  return get_attribute (self->bound_attributes, solver, prefix, attr);
+  return gtk_constraint_layout_get_attribute (layout, attr, prefix, widget, child_info->bound_attributes);
 }
 
 static GtkConstraintVariable *
 get_guide_attribute (GtkConstraintLayout    *layout,
                      GtkConstraintGuide     *guide,
-                     GtkConstraintSolver    *solver,
                      GtkConstraintAttribute  attr)
 {
   GtkLayoutManager *manager = GTK_LAYOUT_MANAGER (layout);
   GtkWidget *widget = gtk_layout_manager_get_widget (manager);
 
-  attr = resolve_direction (attr, widget);
-
-  return get_attribute (guide->bound_attributes, solver, "guide", attr);
+  return gtk_constraint_layout_get_attribute (layout, attr, "guide", widget, guide->bound_attributes);
 }
 
 static void
@@ -647,20 +622,14 @@ layout_add_constraint (GtkConstraintLayout *self,
   else if (GTK_IS_WIDGET (target) &&
            gtk_widget_get_parent (GTK_WIDGET (target)) == layout_widget)
     {
-      GtkLayoutChild *child_info;
-
-      child_info = gtk_layout_manager_get_layout_child (GTK_LAYOUT_MANAGER (self), GTK_WIDGET (target));
-      target_attr = get_child_attribute (GTK_CONSTRAINT_LAYOUT_CHILD (child_info),
-                                         solver,
-                                         GTK_WIDGET (target),
-                                         attr);
+      target_attr = get_child_attribute (self, GTK_WIDGET (target), attr);
     }
   else if (GTK_IS_CONSTRAINT_GUIDE (target))
     {
       GtkConstraintGuide *guide;
 
       guide = (GtkConstraintGuide*)g_hash_table_lookup (self->guides, target);
-      target_attr = get_guide_attribute (self, guide, solver, attr);
+      target_attr = get_guide_attribute (self, guide, attr);
     }
   else
     {
@@ -688,20 +657,14 @@ layout_add_constraint (GtkConstraintLayout *self,
       else if (GTK_IS_WIDGET (source) &&
                gtk_widget_get_parent (GTK_WIDGET (source)) == layout_widget)
         {
-          GtkLayoutChild *child_info;
-
-          child_info = gtk_layout_manager_get_layout_child (GTK_LAYOUT_MANAGER (self), GTK_WIDGET (source));
-          source_attr = get_child_attribute (GTK_CONSTRAINT_LAYOUT_CHILD (child_info),
-                                             solver,
-                                             GTK_WIDGET (source),
-                                             attr);
+          source_attr = get_child_attribute (self, GTK_WIDGET (source), attr);
         }
       else if (GTK_IS_CONSTRAINT_GUIDE (source))
         {
           GtkConstraintGuide *guide;
 
           guide = (GtkConstraintGuide*)g_hash_table_lookup (self->guides, source);
-          source_attr = get_guide_attribute (self, guide, solver, attr);
+          source_attr = get_guide_attribute (self, guide, attr);
         }
       else
         {
@@ -765,7 +728,6 @@ gtk_constraint_layout_measure (GtkLayoutManager *manager,
        child != NULL;
        child = _gtk_widget_get_next_sibling (child))
     {
-      GtkConstraintLayoutChild *child_info;
       GtkConstraintVariable *width_var, *height_var;
       GtkConstraintRef *constraint;
       int min_size = 0, nat_size = 0;
@@ -773,8 +735,6 @@ gtk_constraint_layout_measure (GtkLayoutManager *manager,
       if (!gtk_widget_should_layout (child))
         continue;
 
-      child_info = GTK_CONSTRAINT_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (manager, child));
-
       gtk_widget_measure (child, orientation, -1,
                           &min_size, &nat_size,
                           NULL, NULL);
@@ -782,8 +742,7 @@ gtk_constraint_layout_measure (GtkLayoutManager *manager,
       switch (orientation)
         {
         case GTK_ORIENTATION_HORIZONTAL:
-          width_var = get_child_attribute (child_info, solver, child,
-                                           GTK_CONSTRAINT_ATTRIBUTE_WIDTH);
+          width_var = get_child_attribute (self, child, GTK_CONSTRAINT_ATTRIBUTE_WIDTH);
 
           constraint =
             gtk_constraint_solver_add_constraint (solver,
@@ -803,8 +762,7 @@ gtk_constraint_layout_measure (GtkLayoutManager *manager,
           break;
 
         case GTK_ORIENTATION_VERTICAL:
-          height_var = get_child_attribute (child_info, solver, child,
-                                            GTK_CONSTRAINT_ATTRIBUTE_HEIGHT);
+          height_var = get_child_attribute (self, child, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT);
 
           constraint =
             gtk_constraint_solver_add_constraint (solver,
@@ -946,7 +904,6 @@ gtk_constraint_layout_allocate (GtkLayoutManager *manager,
        child != NULL;
        child = _gtk_widget_get_next_sibling (child))
     {
-      GtkConstraintLayoutChild *child_info;
       GtkConstraintVariable *width_var, *height_var;
       GtkRequisition min_req, nat_req;
       GtkConstraintRef *constraint;
@@ -954,12 +911,9 @@ gtk_constraint_layout_allocate (GtkLayoutManager *manager,
       if (!gtk_widget_should_layout (child))
         continue;
 
-      child_info = GTK_CONSTRAINT_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (manager, child));
-
       gtk_widget_get_preferred_size (child, &min_req, &nat_req);
 
-      width_var = get_child_attribute (child_info, solver, child,
-                                       GTK_CONSTRAINT_ATTRIBUTE_WIDTH);
+      width_var = get_child_attribute (self, child, GTK_CONSTRAINT_ATTRIBUTE_WIDTH);
 
       constraint =
         gtk_constraint_solver_add_constraint (solver,
@@ -977,8 +931,7 @@ gtk_constraint_layout_allocate (GtkLayoutManager *manager,
                                               GTK_CONSTRAINT_WEIGHT_MEDIUM);
       g_ptr_array_add (size_constraints, constraint);
 
-      height_var = get_child_attribute (child_info, solver, child,
-                                        GTK_CONSTRAINT_ATTRIBUTE_HEIGHT);
+      height_var = get_child_attribute (self, child, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT);
 
       constraint =
         gtk_constraint_solver_add_constraint (solver,
@@ -1003,21 +956,18 @@ gtk_constraint_layout_allocate (GtkLayoutManager *manager,
     {
       GtkConstraintVariable *var_top, *var_left, *var_width, *var_height;
       GtkConstraintVariable *var_baseline;
-      GtkConstraintLayoutChild *child_info;
       GtkAllocation child_alloc;
       int child_baseline = -1;
 
       if (!gtk_widget_should_layout (child))
         continue;
 
-      child_info = GTK_CONSTRAINT_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (manager, child));
-
       /* Retrieve all the values associated with the child */
-      var_top = get_child_attribute (child_info, solver, child, GTK_CONSTRAINT_ATTRIBUTE_TOP);
-      var_left = get_child_attribute (child_info, solver, child, GTK_CONSTRAINT_ATTRIBUTE_LEFT);
-      var_width = get_child_attribute (child_info, solver, child, GTK_CONSTRAINT_ATTRIBUTE_WIDTH);
-      var_height = get_child_attribute (child_info, solver, child, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT);
-      var_baseline = get_child_attribute (child_info, solver, child, GTK_CONSTRAINT_ATTRIBUTE_BASELINE);
+      var_top = get_child_attribute (self, child, GTK_CONSTRAINT_ATTRIBUTE_TOP);
+      var_left = get_child_attribute (self, child, GTK_CONSTRAINT_ATTRIBUTE_LEFT);
+      var_width = get_child_attribute (self, child, GTK_CONSTRAINT_ATTRIBUTE_WIDTH);
+      var_height = get_child_attribute (self, child, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT);
+      var_baseline = get_child_attribute (self, child, GTK_CONSTRAINT_ATTRIBUTE_BASELINE);
 
       GTK_NOTE (LAYOUT,
                 g_print ("Allocating child '%s'[%p] with { .x: %g, .y: %g, .w: %g, .h: %g, .b: %g }\n",
@@ -1058,10 +1008,6 @@ gtk_constraint_layout_allocate (GtkLayoutManager *manager,
   gtk_constraint_solver_remove_constraint (solver, stay_l);
 }
 
-static void gtk_constraint_guide_update (GtkConstraintGuide *guide,
-                                         GuideValue          index);
-static void gtk_constraint_guide_detach (GtkConstraintGuide *guide);
-
 static void
 gtk_constraint_layout_root (GtkLayoutManager *manager)
 {
@@ -1227,237 +1173,6 @@ gtk_constraint_layout_remove_constraint (GtkConstraintLayout *manager,
   gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (manager));
 }
 
-static void
-gtk_constraint_guide_constraint_target_iface_init (GtkConstraintTargetInterface *iface)
-{
-}
-
-struct _GtkConstraintGuideClass {
-  GObjectClass parent_class;
-};
-
-enum {
-  GUIDE_PROP_MIN_WIDTH = 1,
-  GUIDE_PROP_MIN_HEIGHT,
-  GUIDE_PROP_NAT_WIDTH,
-  GUIDE_PROP_NAT_HEIGHT,
-  GUIDE_PROP_MAX_WIDTH,
-  GUIDE_PROP_MAX_HEIGHT,
-  LAST_GUIDE_PROP
-};
-
-static GParamSpec *guide_props[LAST_GUIDE_PROP];
-
-G_DEFINE_TYPE_WITH_CODE (GtkConstraintGuide, gtk_constraint_guide, G_TYPE_OBJECT,
-                         G_IMPLEMENT_INTERFACE (GTK_TYPE_CONSTRAINT_TARGET,
-                                                gtk_constraint_guide_constraint_target_iface_init))
-
-static void
-gtk_constraint_guide_init (GtkConstraintGuide *guide)
-{
-  guide->bound_attributes =
-    g_hash_table_new_full (g_str_hash, g_str_equal,
-                           NULL,
-                           (GDestroyNotify) gtk_constraint_variable_unref);
-}
-
-static void
-gtk_constraint_guide_update (GtkConstraintGuide *guide,
-                             GuideValue          index)
-{
-  GtkConstraintSolver *solver;
-  GtkConstraintVariable *var;
-  int attr[LAST_GUIDE_VALUE] = {
-    GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
-    GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
-    GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
-    GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
-    GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
-    GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
-  };
-  int relation[LAST_GUIDE_VALUE] = {
-    GTK_CONSTRAINT_RELATION_GE,
-    GTK_CONSTRAINT_RELATION_GE,
-    GTK_CONSTRAINT_RELATION_EQ,
-    GTK_CONSTRAINT_RELATION_EQ,
-    GTK_CONSTRAINT_RELATION_LE,
-    GTK_CONSTRAINT_RELATION_LE,
-  };
-  double weight[LAST_GUIDE_VALUE] = {
-    GTK_CONSTRAINT_WEIGHT_REQUIRED,
-    GTK_CONSTRAINT_WEIGHT_REQUIRED,
-    GTK_CONSTRAINT_WEIGHT_MEDIUM,
-    GTK_CONSTRAINT_WEIGHT_MEDIUM,
-    GTK_CONSTRAINT_WEIGHT_REQUIRED,
-    GTK_CONSTRAINT_WEIGHT_REQUIRED,
-  };
-
-  if (!guide->layout)
-    return;
-
-  solver = guide->layout->solver;
-
-  if (!solver)
-    return;
-
-  if (guide->constraints[index] != NULL)
-    gtk_constraint_solver_remove_constraint (solver, guide->constraints[index]);
-
-  var = get_guide_attribute (guide->layout, guide, solver, attr[index]);
-  guide->constraints[index] =
-    gtk_constraint_solver_add_constraint (solver,
-                                          var,
-                                          relation[index],
-                                          gtk_constraint_expression_new (guide->values[index]),
-                                          weight[index]);
-}
-
-static void
-gtk_constraint_guide_detach (GtkConstraintGuide *guide)
-{
-  GtkConstraintSolver *solver;
-  int i;
-
-  if (!guide->layout)
-    return;
-
-  solver = guide->layout->solver;
-  if (!solver)
-    return;
-
-  for (i = 0; i < LAST_GUIDE_VALUE; i++)
-    {
-      gtk_constraint_solver_remove_constraint (solver, guide->constraints[i]);
-      guide->constraints[i] = NULL;
-    }
-
-  g_hash_table_remove_all (guide->bound_attributes);
-}
-
-static void
-gtk_constraint_guide_set_property (GObject      *gobject,
-                                   guint         prop_id,
-                                   const GValue *value,
-                                   GParamSpec   *pspec)
-{
-  GtkConstraintGuide *self = GTK_CONSTRAINT_GUIDE (gobject);
-  int val;
-  GuideValue index;
-
-  switch (prop_id)
-    {
-    case GUIDE_PROP_MIN_WIDTH:
-    case GUIDE_PROP_MIN_HEIGHT:
-    case GUIDE_PROP_NAT_WIDTH:
-    case GUIDE_PROP_NAT_HEIGHT:
-    case GUIDE_PROP_MAX_WIDTH:
-    case GUIDE_PROP_MAX_HEIGHT:
-      val = g_value_get_int (value);
-      index = prop_id - 1;
-      if (self->values[index] != val)
-        {
-          self->values[index] = val;
-          g_object_notify_by_pspec (gobject, pspec);
-          gtk_constraint_guide_update (self, index);
-        }
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
-      break;
-    }
-}
-
-static void
-gtk_constraint_guide_get_property (GObject    *gobject,
-                                   guint       prop_id,
-                                   GValue     *value,
-                                   GParamSpec *pspec)
-{
-  GtkConstraintGuide *self = GTK_CONSTRAINT_GUIDE (gobject);
-
-  switch (prop_id)
-    {
-    case GUIDE_PROP_MIN_WIDTH:
-    case GUIDE_PROP_MIN_HEIGHT:
-    case GUIDE_PROP_NAT_WIDTH:
-    case GUIDE_PROP_NAT_HEIGHT:
-    case GUIDE_PROP_MAX_WIDTH:
-    case GUIDE_PROP_MAX_HEIGHT:
-      g_value_set_int (value, self->values[prop_id - 1]);
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
-      break;
-    }
-}
-
-static void
-gtk_constraint_guide_finalize (GObject *object)
-{
-  GtkConstraintGuide *self = GTK_CONSTRAINT_GUIDE (object);
-
-  g_clear_pointer (&self->bound_attributes, g_hash_table_unref);
-
-  G_OBJECT_CLASS (gtk_constraint_guide_parent_class)->finalize (object);
-}
-
-static void
-gtk_constraint_guide_class_init (GtkConstraintGuideClass *class)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (class);
-
-  object_class->finalize = gtk_constraint_guide_finalize;
-  object_class->set_property = gtk_constraint_guide_set_property;
-  object_class->get_property = gtk_constraint_guide_get_property;
-
-  guide_props[GUIDE_PROP_MIN_WIDTH] =
-      g_param_spec_int ("min-width",
-                        "Minimum width",
-                        "Minimum width",
-                        0, G_MAXINT, 0,
-                        G_PARAM_READWRITE|
-                        G_PARAM_EXPLICIT_NOTIFY);
-  guide_props[GUIDE_PROP_MIN_HEIGHT] =
-      g_param_spec_int ("min-height",
-                        "Minimum height",
-                        "Minimum height",
-                        0, G_MAXINT, 0,
-                        G_PARAM_READWRITE|
-                        G_PARAM_EXPLICIT_NOTIFY);
-  guide_props[GUIDE_PROP_NAT_WIDTH] =
-      g_param_spec_int ("nat-width",
-                        "Natural width",
-                        "Natural width",
-                        0, G_MAXINT, 0,
-                        G_PARAM_READWRITE|
-                        G_PARAM_EXPLICIT_NOTIFY);
-  guide_props[GUIDE_PROP_NAT_HEIGHT] =
-      g_param_spec_int ("nat-height",
-                        "Natural height",
-                        "Natural height",
-                        0, G_MAXINT, 0,
-                        G_PARAM_READWRITE|
-                        G_PARAM_EXPLICIT_NOTIFY);
-  guide_props[GUIDE_PROP_MAX_WIDTH] =
-      g_param_spec_int ("max-width",
-                        "Maximum width",
-                        "Maximum width",
-                        0, G_MAXINT, G_MAXINT,
-                        G_PARAM_READWRITE|
-                        G_PARAM_EXPLICIT_NOTIFY);
-  guide_props[GUIDE_PROP_MAX_HEIGHT] =
-      g_param_spec_int ("max-height",
-                        "Maximum height",
-                        "Maximum height",
-                        0, G_MAXINT, G_MAXINT,
-                        G_PARAM_READWRITE|
-                        G_PARAM_EXPLICIT_NOTIFY);
-
-  g_object_class_install_properties (object_class, LAST_GUIDE_PROP, guide_props);
-}
-
 /**
  * gtk_constraint_layout_add_guide:
  * @layout: a #GtkConstraintLayout
diff --git a/gtk/gtkconstraintlayout.h b/gtk/gtkconstraintlayout.h
index 758fcefb20..eed95e53ec 100644
--- a/gtk/gtkconstraintlayout.h
+++ b/gtk/gtkconstraintlayout.h
@@ -20,12 +20,12 @@
 
 #include <gtk/gtklayoutmanager.h>
 #include <gtk/gtkconstraint.h>
+#include <gtk/gtkconstraintguide.h>
 
 G_BEGIN_DECLS
 
 #define GTK_TYPE_CONSTRAINT_LAYOUT (gtk_constraint_layout_get_type ())
 #define GTK_TYPE_CONSTRAINT_LAYOUT_CHILD (gtk_constraint_layout_child_get_type ())
-#define GTK_TYPE_CONSTRAINT_GUIDE (gtk_constraint_guide_get_type ())
 
 /**
  * GtkConstraintLayoutChild:
@@ -35,21 +35,6 @@ G_BEGIN_DECLS
 GDK_AVAILABLE_IN_ALL
 G_DECLARE_FINAL_TYPE (GtkConstraintLayoutChild, gtk_constraint_layout_child, GTK, CONSTRAINT_LAYOUT_CHILD, 
GtkLayoutChild)
 
-/**
- * GtkConstraintGuide:
- *
- * An object that can be added to a #GtkConstraintLayout and be
- * used in constraints like a widget, without being drawn. Guides
- * have a minimal and natural size. Depending on the constraints
- * that are applied, they can act like a guideline that widgets
- * can be aligned to, or like 'flexible space'.
- */
-GDK_AVAILABLE_IN_ALL
-G_DECLARE_FINAL_TYPE (GtkConstraintGuide, gtk_constraint_guide, GTK, CONSTRAINT_GUIDE, GObject)
-
-GDK_AVAILABLE_IN_ALL
-GtkConstraintGuide *    gtk_constraint_guide_new                (void);
-
 /**
  * GtkConstraintLayout:
  *
diff --git a/gtk/meson.build b/gtk/meson.build
index a79e3e7ecc..860af504bf 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -202,6 +202,7 @@ gtk_public_sources = files([
   'gtkcombobox.c',
   'gtkcomboboxtext.c',
   'gtkcomposetable.c',
+  'gtkconstraintguide.c',
   'gtkconstraintlayout.c',
   'gtkconstraint.c',
   'gtkcontainer.c',



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