[gtk/constraint-editor-fun: 2/3] constraint editor: Allow editing children
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/constraint-editor-fun: 2/3] constraint editor: Allow editing children
- Date: Tue, 2 Jul 2019 22:42:38 +0000 (UTC)
commit bc1f2ded846d8396670ab9249a470a460ead9f85
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Jul 2 22:21:07 2019 +0000
constraint editor: Allow editing children
Just name and size, for now.
demos/constraint-editor/child-editor.c | 262 +++++++++++++++++++++
demos/constraint-editor/child-editor.h | 32 +++
demos/constraint-editor/child-editor.ui | 84 +++++++
demos/constraint-editor/constraint-editor-window.c | 60 +++--
.../constraint-editor.gresource.xml | 1 +
demos/constraint-editor/constraint-view.c | 6 +-
demos/constraint-editor/meson.build | 1 +
7 files changed, 426 insertions(+), 20 deletions(-)
---
diff --git a/demos/constraint-editor/child-editor.c b/demos/constraint-editor/child-editor.c
new file mode 100644
index 0000000000..be22e391ef
--- /dev/null
+++ b/demos/constraint-editor/child-editor.c
@@ -0,0 +1,262 @@
+/*
+ * 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 "child-editor.h"
+
+struct _ChildEditor
+{
+ GtkWidget parent_instance;
+
+ GtkWidget *grid;
+ GtkWidget *name;
+ GtkWidget *min_width;
+ GtkWidget *min_height;
+ GtkWidget *button;
+
+ GtkWidget *child;
+
+ gboolean constructed;
+};
+
+enum {
+ PROP_CHILD = 1,
+ LAST_PROP
+};
+
+static GParamSpec *pspecs[LAST_PROP];
+
+enum {
+ DONE,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE(ChildEditor, child_editor, GTK_TYPE_WIDGET);
+
+void
+child_editor_serialize_child (GString *str,
+ int indent,
+ GtkWidget *child)
+{
+ int min_width, min_height;
+ const char *name;
+
+ name = gtk_widget_get_name (child);
+ if (!name)
+ name = "";
+
+ gtk_widget_get_size_request (child, &min_width, &min_height);
+
+ g_string_append_printf (str, "%*s<child>\n", indent, "");
+ g_string_append_printf (str, "%*s <object class=\"GtkLabel\" id=\"%s\">\n", indent, "", name);
+ g_string_append_printf (str, "%*s <property name=\"label\">%s</property>\n", indent, "", name);
+ if (min_width != -1)
+ g_string_append_printf (str, "%*s <property name=\"width-request\">%d</property>\n", indent, "",
min_width);
+ if (min_height != -1)
+ g_string_append_printf (str, "%*s <property name=\"height-request\">%d</property>\n", indent, "",
min_height);
+ g_string_append_printf (str, "%*s </object>\n", indent, "");
+ g_string_append_printf (str, "%*s</child>\n", indent, "");
+}
+
+static void
+apply (GtkButton *button,
+ ChildEditor *editor)
+{
+ const char *name;
+ int w, h;
+
+ name = gtk_editable_get_text (GTK_EDITABLE (editor->name));
+ w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->min_width));
+ h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->min_height));
+
+ gtk_widget_set_size_request (editor->child, w, h);
+ gtk_widget_set_name (editor->child, name);
+
+ g_signal_emit (editor, signals[DONE], 0, editor->child);
+}
+
+static void
+child_editor_init (ChildEditor *editor)
+{
+ gtk_widget_init_template (GTK_WIDGET (editor));
+}
+
+static int
+min_input (GtkSpinButton *spin_button,
+ double *new_val)
+{
+ if (strcmp (gtk_editable_get_text (GTK_EDITABLE (spin_button)), "") == 0)
+ {
+ *new_val = 0.0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+min_output (GtkSpinButton *spin_button)
+{
+ GtkAdjustment *adjustment;
+ double value;
+ GtkWidget *box, *text;
+
+ adjustment = gtk_spin_button_get_adjustment (spin_button);
+ value = gtk_adjustment_get_value (adjustment);
+
+ box = gtk_widget_get_first_child (GTK_WIDGET (spin_button));
+ text = gtk_widget_get_first_child (box);
+
+ if (value <= 0.0)
+ {
+ gtk_editable_set_text (GTK_EDITABLE (spin_button), "");
+ gtk_text_set_placeholder_text (GTK_TEXT (text), "unset");
+ return TRUE;
+ }
+ else
+ {
+ gtk_text_set_placeholder_text (GTK_TEXT (text), "");
+ return FALSE;
+ }
+}
+
+static void
+child_editor_constructed (GObject *object)
+{
+ ChildEditor *editor = CHILD_EDITOR (object);
+ const char *nick;
+ int w, h;
+
+ g_signal_connect (editor->min_width, "input", G_CALLBACK (min_input), NULL);
+ g_signal_connect (editor->min_width, "output", G_CALLBACK (min_output), NULL);
+
+ g_signal_connect (editor->min_height, "input", G_CALLBACK (min_input), NULL);
+ g_signal_connect (editor->min_height, "output", G_CALLBACK (min_output), NULL);
+
+ nick = gtk_widget_get_name (editor->child);
+ if (nick)
+ gtk_editable_set_text (GTK_EDITABLE (editor->name), nick);
+
+ gtk_widget_get_size_request (editor->child, &w, &h);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_width), w);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_height), h);
+
+ editor->constructed = TRUE;
+}
+
+static void
+child_editor_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ChildEditor *self = CHILD_EDITOR (object);
+
+ switch (property_id)
+ {
+ case PROP_CHILD:
+ self->child = g_value_dup_object (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+child_editor_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ChildEditor *self = CHILD_EDITOR (object);
+
+ switch (property_id)
+ {
+ case PROP_CHILD:
+ g_value_set_object (value, self->child);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+child_editor_dispose (GObject *object)
+{
+ ChildEditor *self = (ChildEditor *)object;
+
+ g_clear_pointer (&self->grid, gtk_widget_unparent);
+ g_clear_object (&self->child);
+
+ G_OBJECT_CLASS (child_editor_parent_class)->dispose (object);
+}
+
+static void
+child_editor_class_init (ChildEditorClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+ object_class->constructed = child_editor_constructed;
+ object_class->dispose = child_editor_dispose;
+ object_class->set_property = child_editor_set_property;
+ object_class->get_property = child_editor_get_property;
+
+ pspecs[PROP_CHILD] =
+ g_param_spec_object ("child", "child", "child",
+ GTK_TYPE_WIDGET,
+ G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
+
+ g_object_class_install_properties (object_class, LAST_PROP, pspecs);
+
+ signals[DONE] =
+ g_signal_new ("done",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 1, GTK_TYPE_WIDGET);
+
+ gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/org/gtk/gtk4/constraint-editor/child-editor.ui");
+
+ gtk_widget_class_bind_template_child (widget_class, ChildEditor, grid);
+ gtk_widget_class_bind_template_child (widget_class, ChildEditor, name);
+ gtk_widget_class_bind_template_child (widget_class, ChildEditor, min_width);
+ gtk_widget_class_bind_template_child (widget_class, ChildEditor, min_height);
+ gtk_widget_class_bind_template_child (widget_class, ChildEditor, button);
+
+ gtk_widget_class_bind_template_callback (widget_class, apply);
+}
+
+ChildEditor *
+child_editor_new (GtkWidget *child)
+{
+ return g_object_new (CHILD_EDITOR_TYPE,
+ "child", child,
+ NULL);
+}
diff --git a/demos/constraint-editor/child-editor.h b/demos/constraint-editor/child-editor.h
new file mode 100644
index 0000000000..71bd90e034
--- /dev/null
+++ b/demos/constraint-editor/child-editor.h
@@ -0,0 +1,32 @@
+/*
+ * 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 CHILD_EDITOR_TYPE (child_editor_get_type ())
+
+G_DECLARE_FINAL_TYPE (ChildEditor, child_editor, CHILD, EDITOR, GtkWidget)
+
+ChildEditor * child_editor_new (GtkWidget *child);
+
+void child_editor_serialize_child (GString *str,
+ int indent,
+ GtkWidget *child);
diff --git a/demos/constraint-editor/child-editor.ui b/demos/constraint-editor/child-editor.ui
new file mode 100644
index 0000000000..f66f375982
--- /dev/null
+++ b/demos/constraint-editor/child-editor.ui
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <object class="GtkAdjustment" id="min_width_adj">
+ <property name="lower">0</property>
+ <property name="upper">2147483647</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ <property name="page-size">0</property>
+ </object>
+ <object class="GtkAdjustment" id="min_height_adj">
+ <property name="lower">0</property>
+ <property name="upper">2147483647</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ <property name="page-size">0</property>
+ </object>
+ <template class="ChildEditor" parent="GtkWidget">
+ <child>
+ <object class="GtkGrid" id="grid">
+ <property name="margin">20</property>
+ <property name="row-spacing">10</property>
+ <property name="column-spacing">10</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="label">Name</property>
+ <layout>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkEntry" id="name">
+ <property name="max-width-chars">20</property>
+ <layout>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ <property name="column-span">2</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label">Min Size</property>
+ <layout>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="min_width">
+ <property name="adjustment">min_width_adj</property>
+ <property name="max-width-chars">5</property>
+ <layout>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="min_height">
+ <property name="adjustment">min_height_adj</property>
+ <property name="max-width-chars">5</property>
+ <layout>
+ <property name="left-attach">2</property>
+ <property name="top-attach">1</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="button">
+ <property name="label">Apply</property>
+ <signal name="clicked" handler="apply"/>
+ <layout>
+ <property name="left-attach">2</property>
+ <property name="top-attach">5</property>
+ </layout>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/demos/constraint-editor/constraint-editor-window.c
b/demos/constraint-editor/constraint-editor-window.c
index 2b5654b98a..152547f245 100644
--- a/demos/constraint-editor/constraint-editor-window.c
+++ b/demos/constraint-editor/constraint-editor-window.c
@@ -23,6 +23,7 @@
#include "constraint-view.h"
#include "constraint-editor.h"
#include "guide-editor.h"
+#include "child-editor.h"
struct _ConstraintEditorWindow
{
@@ -453,6 +454,33 @@ edit_guide (ConstraintEditorWindow *win,
gtk_widget_show (window);
}
+static void
+child_editor_done (ChildEditor *editor,
+ GtkWidget *child,
+ ConstraintEditorWindow *win)
+{
+ gtk_widget_destroy (gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_WINDOW));
+}
+
+static void
+edit_child (ConstraintEditorWindow *win,
+ GtkWidget *child)
+{
+ GtkWidget *window;
+ ChildEditor *editor;
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
+ gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (win));
+ gtk_window_set_title (GTK_WINDOW (window), "Edit Child");
+
+ editor = child_editor_new (child);
+ gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (editor));
+
+ g_signal_connect (editor, "done", G_CALLBACK (child_editor_done), win);
+ gtk_widget_show (window);
+}
+
static void
row_activated (GtkListBox *list,
GtkListBoxRow *row,
@@ -466,6 +494,8 @@ row_activated (GtkListBox *list,
edit_constraint (win, GTK_CONSTRAINT (item));
else if (GTK_IS_CONSTRAINT_GUIDE (item))
edit_guide (win, GTK_CONSTRAINT_GUIDE (item));
+ else if (GTK_IS_WIDGET (item))
+ edit_child (win, GTK_WIDGET (item));
}
static void
@@ -506,6 +536,8 @@ row_edit (GtkButton *button,
edit_constraint (win, GTK_CONSTRAINT (item));
else if (GTK_IS_CONSTRAINT_GUIDE (item))
edit_guide (win, GTK_CONSTRAINT_GUIDE (item));
+ else if (GTK_IS_WIDGET (item))
+ edit_child (win, GTK_WIDGET (item));
}
static void
@@ -594,25 +626,15 @@ create_widget_func (gpointer item,
gtk_container_add (GTK_CONTAINER (row), box);
gtk_container_add (GTK_CONTAINER (box), label);
- if (GTK_IS_CONSTRAINT (item) || GTK_IS_CONSTRAINT_GUIDE (item))
- {
- button = gtk_button_new_from_icon_name ("document-edit-symbolic");
- gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
- g_signal_connect (button, "clicked", G_CALLBACK (row_edit), win);
- g_object_set_data (G_OBJECT (row), "edit", button);
- gtk_container_add (GTK_CONTAINER (box), button);
- button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
- gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
- g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
- gtk_container_add (GTK_CONTAINER (box), button);
- }
- else if (GTK_IS_WIDGET (item))
- {
- button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
- gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
- g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
- gtk_container_add (GTK_CONTAINER (box), button);
- }
+ button = gtk_button_new_from_icon_name ("document-edit-symbolic");
+ gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+ g_signal_connect (button, "clicked", G_CALLBACK (row_edit), win);
+ g_object_set_data (G_OBJECT (row), "edit", button);
+ gtk_container_add (GTK_CONTAINER (box), button);
+ button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
+ gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+ g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
+ gtk_container_add (GTK_CONTAINER (box), button);
g_free (freeme);
diff --git a/demos/constraint-editor/constraint-editor.gresource.xml
b/demos/constraint-editor/constraint-editor.gresource.xml
index e57964b1a7..a6393b34e0 100644
--- a/demos/constraint-editor/constraint-editor.gresource.xml
+++ b/demos/constraint-editor/constraint-editor.gresource.xml
@@ -4,6 +4,7 @@
<file preprocess="xml-stripblanks">constraint-editor-window.ui</file>
<file preprocess="xml-stripblanks">constraint-editor.ui</file>
<file preprocess="xml-stripblanks">guide-editor.ui</file>
+ <file preprocess="xml-stripblanks">child-editor.ui</file>
<file>constraint-editor.css</file>
</gresource>
</gresources>
diff --git a/demos/constraint-editor/constraint-view.c b/demos/constraint-editor/constraint-view.c
index 063e445f91..fb0b7e45d7 100644
--- a/demos/constraint-editor/constraint-view.c
+++ b/demos/constraint-editor/constraint-view.c
@@ -216,11 +216,15 @@ constraint_view_add_child (ConstraintView *view,
GtkWidget *frame;
GtkWidget *label;
- label = gtk_label_new (name);
frame = gtk_frame_new (NULL);
gtk_style_context_add_class (gtk_widget_get_style_context (frame), "child");
gtk_widget_set_name (frame, name);
+ label = gtk_label_new (name);
gtk_container_add (GTK_CONTAINER (frame), label);
+ g_object_bind_property (frame, "name",
+ label, "label",
+ G_BINDING_DEFAULT);
+
gtk_widget_set_parent (frame, GTK_WIDGET (view));
update_weak_position (view, frame, 100, 100);
diff --git a/demos/constraint-editor/meson.build b/demos/constraint-editor/meson.build
index 9c01a7b50b..f5abd13445 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',
+ 'child-editor.c',
'guide-placeholder.c',
]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]