[gtk/constraint-editor-fun: 1/3] constraint editor: Better guide visualization



commit a5a6e9010549332d323060c62c308ed8ebb66f90
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Jul 2 21:46:38 2019 +0000

    constraint editor: Better guide visualization
    
    Replace the frame with a custom widget to avoid
    interference from the frames own min size.

 demos/constraint-editor/constraint-editor-window.c |   1 +
 demos/constraint-editor/constraint-editor.css      |   3 +-
 demos/constraint-editor/constraint-view.c          |  44 ++---
 demos/constraint-editor/guide-placeholder.c        | 179 +++++++++++++++++++++
 demos/constraint-editor/guide-placeholder.h        |  28 ++++
 demos/constraint-editor/meson.build                |   1 +
 6 files changed, 234 insertions(+), 22 deletions(-)
---
diff --git a/demos/constraint-editor/constraint-editor-window.c 
b/demos/constraint-editor/constraint-editor-window.c
index 823deb3c96..2b5654b98a 100644
--- a/demos/constraint-editor/constraint-editor-window.c
+++ b/demos/constraint-editor/constraint-editor-window.c
@@ -368,6 +368,7 @@ add_guide (ConstraintEditorWindow *win)
   name = g_strdup_printf ("Guide %d", guide_counter);
   guide = gtk_constraint_guide_new ();
   gtk_constraint_guide_set_name (guide, name);
+  gtk_constraint_guide_set_min_size (guide, 100, 25);
   g_free (name);
 
   constraint_view_add_guide (CONSTRAINT_VIEW (win->view), guide);
diff --git a/demos/constraint-editor/constraint-editor.css b/demos/constraint-editor/constraint-editor.css
index c9538bf268..27e53daf5a 100644
--- a/demos/constraint-editor/constraint-editor.css
+++ b/demos/constraint-editor/constraint-editor.css
@@ -7,6 +7,7 @@ constraintview .child {
   background: red;
 }
 
-constraintview .guide {
+constraintview guide {
   background: blue;
+  border: 1px solid white;
 }
diff --git a/demos/constraint-editor/constraint-view.c b/demos/constraint-editor/constraint-view.c
index 982338c93d..063e445f91 100644
--- a/demos/constraint-editor/constraint-view.c
+++ b/demos/constraint-editor/constraint-view.c
@@ -16,6 +16,7 @@
 
 #include <gtk/gtk.h>
 #include "constraint-view.h"
+#include "guide-placeholder.h"
 
 struct _ConstraintView
 {
@@ -111,16 +112,19 @@ drag_begin (GtkGestureDrag *drag,
             ConstraintView *self)
 {
   GtkWidget *widget;
+  GtkWidget *target;
 
   widget = gtk_widget_pick (GTK_WIDGET (self), start_x, start_y, GTK_PICK_DEFAULT);
 
-  if (GTK_IS_LABEL (widget))
+  if (widget)
     {
-      widget = gtk_widget_get_ancestor (widget, GTK_TYPE_FRAME);
-      if (widget &&
-          gtk_widget_get_parent (widget) == (GtkWidget *)self)
+      target = gtk_widget_get_ancestor (widget, GUIDE_PLACEHOLDER_TYPE);
+      if (!target)
+        target = gtk_widget_get_ancestor (widget, GTK_TYPE_FRAME);
+      if (target &&
+          gtk_widget_get_parent (target) == (GtkWidget *)self)
         {
-          self->drag_widget = widget;
+          self->drag_widget = target;
         }
     }
 }
@@ -235,8 +239,7 @@ constraint_view_add_guide (ConstraintView *view,
                            GtkConstraintGuide *guide)
 {
   GtkConstraintLayout *layout;
-  GtkWidget *frame;
-  GtkWidget *label;
+  GtkWidget *placeholder;
   const char *name;
   GtkConstraint *constraint;
   struct {
@@ -251,25 +254,24 @@ constraint_view_add_guide (ConstraintView *view,
   int i;
 
   name = gtk_constraint_guide_get_name (guide);
-  label = gtk_label_new (name);
+
+  placeholder = guide_placeholder_new (guide);
+  gtk_widget_set_tooltip_text (placeholder, name);
   g_object_bind_property (guide, "name",
-                          label, "label",
+                          placeholder, "tooltip-text",
                           G_BINDING_DEFAULT);
 
-  frame = gtk_frame_new (NULL);
-  gtk_style_context_add_class (gtk_widget_get_style_context (frame), "guide");
-  g_object_set_data (G_OBJECT (frame), "internal", "yes");
-  gtk_container_add (GTK_CONTAINER (frame), label);
-  gtk_widget_insert_after (frame, GTK_WIDGET (view), NULL);
+  g_object_set_data (G_OBJECT (placeholder), "internal", "yes");
+  gtk_widget_insert_after (placeholder, GTK_WIDGET (view), NULL);
 
-  g_object_set_data (G_OBJECT (guide), "frame", frame);
+  g_object_set_data (G_OBJECT (guide), "placeholder", placeholder);
 
   layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (view)));
   gtk_constraint_layout_add_guide (layout, g_object_ref (guide));
 
   for (i = 0; i < G_N_ELEMENTS (names); i++)
     {
-      constraint = gtk_constraint_new (frame,
+      constraint = gtk_constraint_new (placeholder,
                                        names[i].attr,
                                        GTK_CONSTRAINT_RELATION_EQ,
                                        guide,
@@ -281,7 +283,7 @@ constraint_view_add_guide (ConstraintView *view,
       g_object_set_data (G_OBJECT (guide), names[i].name, constraint);
     }
 
-  update_weak_position (view, frame, 150, 150);
+  update_weak_position (view, placeholder, 150, 150);
 }
 
 void
@@ -289,7 +291,7 @@ constraint_view_remove_guide (ConstraintView     *view,
                               GtkConstraintGuide *guide)
 {
   GtkConstraintLayout *layout;
-  GtkWidget *frame;
+  GtkWidget *placeholder;
   GtkConstraint *constraint;
   const char *names[] = {
     "left-constraint",
@@ -307,9 +309,9 @@ constraint_view_remove_guide (ConstraintView     *view,
       gtk_constraint_layout_remove_constraint (layout, constraint);
     }
 
-  frame = (GtkWidget *)g_object_get_data (G_OBJECT (guide), "frame");
-  update_weak_position (view, frame, -100, -100);
-  gtk_widget_unparent (frame);
+  placeholder = (GtkWidget *)g_object_get_data (G_OBJECT (guide), "placeholder");
+  update_weak_position (view, placeholder, -100, -100);
+  gtk_widget_unparent (placeholder);
 
   gtk_constraint_layout_remove_guide (layout, guide);
 }
diff --git a/demos/constraint-editor/guide-placeholder.c b/demos/constraint-editor/guide-placeholder.c
new file mode 100644
index 0000000000..4375cbd37d
--- /dev/null
+++ b/demos/constraint-editor/guide-placeholder.c
@@ -0,0 +1,179 @@
+/*
+ * 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/>.
+ *
+ * Authors: Matthias Clasen
+ */
+
+#include "config.h"
+
+#include "guide-placeholder.h"
+
+struct _GuidePlaceholder {
+  GtkWidget parent_instance;
+
+  GtkWidget *label;
+
+  GtkConstraintGuide *guide;
+};
+
+enum {
+  PROP_GUIDE = 1,
+  LAST_PROP
+};
+
+static GParamSpec *props[LAST_PROP];
+
+
+G_DEFINE_TYPE (GuidePlaceholder, guide_placeholder, GTK_TYPE_WIDGET);
+
+static void
+guide_placeholder_measure (GtkWidget      *widget,
+                           GtkOrientation  orientation,
+                           int             for_size,
+                           int            *minimum,
+                           int            *natural,
+                           int            *minimum_baseline,
+                           int            *natural_baseline)
+{
+  GuidePlaceholder *self = GUIDE_PLACEHOLDER (widget);
+  int min_width, min_height;
+  int nat_width, nat_height;
+
+  gtk_constraint_guide_get_min_size (self->guide, &min_width, &min_height);
+  gtk_constraint_guide_get_nat_size (self->guide, &nat_width, &nat_height);
+
+  gtk_widget_measure (self->label, orientation, for_size, minimum, natural, NULL, NULL);
+
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+      *minimum = min_width;
+      *natural = nat_width;
+    }
+  else
+    {
+      *minimum = min_height;
+      *natural = nat_height;
+    }
+}
+
+static void
+guide_placeholder_size_allocate (GtkWidget *widget,
+                                 int        width,
+                                 int        height,
+                                 int        baseline)
+{
+  GuidePlaceholder *self = GUIDE_PLACEHOLDER (widget);
+
+  gtk_widget_allocate (self->label, width, height, baseline, NULL);
+}
+
+static void
+guide_changed (GObject *obj, GParamSpec *pspec, GuidePlaceholder *self)
+{
+  gtk_label_set_label (GTK_LABEL (self->label), gtk_constraint_guide_get_name (self->guide));
+  gtk_widget_queue_resize (GTK_WIDGET (self));
+}
+
+static void
+guide_placeholder_dispose (GObject *object)
+{
+  GuidePlaceholder *self = GUIDE_PLACEHOLDER (object);
+
+  g_signal_handlers_disconnect_by_func (self->guide, guide_changed, self);
+  g_object_unref (self->guide);
+
+  gtk_widget_unparent (self->label);
+
+  G_OBJECT_CLASS (guide_placeholder_parent_class)->dispose (object);
+}
+
+static void
+guide_placeholder_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+  GuidePlaceholder *self = GUIDE_PLACEHOLDER (object);
+
+  switch (prop_id)
+    {
+    case PROP_GUIDE:
+      self->guide = g_value_dup_object (value);
+      g_signal_connect (self->guide, "notify", G_CALLBACK (guide_changed), self);
+      guide_changed ((GObject *)self->guide, NULL, self);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+guide_placeholder_get_property (GObject     *object,
+                                guint        prop_id,
+                                GValue      *value,
+                                GParamSpec  *pspec)
+{
+  GuidePlaceholder *self = GUIDE_PLACEHOLDER (object);
+
+  switch (prop_id)
+    {
+    case PROP_GUIDE:
+      g_value_set_object (value, self->guide);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+guide_placeholder_class_init (GuidePlaceholderClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->dispose = guide_placeholder_dispose;
+  object_class->set_property = guide_placeholder_set_property;
+  object_class->get_property = guide_placeholder_get_property;
+
+  widget_class->measure = guide_placeholder_measure;
+  widget_class->size_allocate = guide_placeholder_size_allocate;
+
+  props[PROP_GUIDE] =
+    g_param_spec_object ("guide", "guide", "guide",
+                         GTK_TYPE_CONSTRAINT_GUIDE,
+                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+  g_object_class_install_properties (object_class, LAST_PROP, props);
+
+  gtk_widget_class_set_css_name (widget_class, "guide");
+}
+
+static void
+guide_placeholder_init (GuidePlaceholder *self)
+{
+  self->label = gtk_label_new ("");
+  gtk_widget_set_parent (self->label, GTK_WIDGET (self));
+}
+
+GtkWidget *
+guide_placeholder_new (GtkConstraintGuide *guide)
+{
+  return g_object_new (guide_placeholder_get_type (),
+                       "guide", guide,
+                       NULL);
+}
diff --git a/demos/constraint-editor/guide-placeholder.h b/demos/constraint-editor/guide-placeholder.h
new file mode 100644
index 0000000000..719449ea09
--- /dev/null
+++ b/demos/constraint-editor/guide-placeholder.h
@@ -0,0 +1,28 @@
+/*
+ * 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/>.
+ *
+ * Authors: Matthias Clasen
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+#define GUIDE_PLACEHOLDER_TYPE (guide_placeholder_get_type ())
+
+G_DECLARE_FINAL_TYPE (GuidePlaceholder, guide_placeholder, GUIDE, PLACEHOLDER, GtkWidget)
+
+GtkWidget * guide_placeholder_new (GtkConstraintGuide  *guide);
diff --git a/demos/constraint-editor/meson.build b/demos/constraint-editor/meson.build
index af66846437..9c01a7b50b 100644
--- a/demos/constraint-editor/meson.build
+++ b/demos/constraint-editor/meson.build
@@ -5,6 +5,7 @@ constraint_editor_sources = [
   'constraint-view.c',
   'constraint-editor.c',
   'guide-editor.c',
+  'guide-placeholder.c',
 ]
 
 constraint_editor_resources = gnome.compile_resources('constraint_editor_resources',


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