Compare commits
3 Commits
matthiasc/
...
constraint
Author | SHA1 | Date | |
---|---|---|---|
|
a0a3e6ffaa | ||
|
bc1f2ded84 | ||
|
a5a6e90105 |
262
demos/constraint-editor/child-editor.c
Normal file
262
demos/constraint-editor/child-editor.c
Normal file
@@ -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);
|
||||
}
|
32
demos/constraint-editor/child-editor.h
Normal file
32
demos/constraint-editor/child-editor.h
Normal file
@@ -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);
|
84
demos/constraint-editor/child-editor.ui
Normal file
84
demos/constraint-editor/child-editor.ui
Normal file
@@ -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>
|
@@ -23,6 +23,7 @@
|
||||
#include "constraint-view.h"
|
||||
#include "constraint-editor.h"
|
||||
#include "guide-editor.h"
|
||||
#include "child-editor.h"
|
||||
|
||||
struct _ConstraintEditorWindow
|
||||
{
|
||||
@@ -368,6 +369,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);
|
||||
@@ -452,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,
|
||||
@@ -465,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
|
||||
@@ -505,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
|
||||
@@ -593,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);
|
||||
|
||||
|
@@ -212,6 +212,19 @@ get_relation_nick (GtkConstraintRelation relation)
|
||||
return nick;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_relation_to_string (GtkConstraintRelation relation)
|
||||
{
|
||||
switch (relation)
|
||||
{
|
||||
case GTK_CONSTRAINT_RELATION_LE: return "≤";
|
||||
case GTK_CONSTRAINT_RELATION_EQ: return "=";
|
||||
case GTK_CONSTRAINT_RELATION_GE: return "≥";
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static GtkConstraintStrength
|
||||
get_strength (const char *id)
|
||||
{
|
||||
@@ -290,9 +303,17 @@ create_constraint (GtkButton *button,
|
||||
target_attr = get_target_attr (id);
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source));
|
||||
source = get_target (editor->model, id);
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
|
||||
source_attr = get_target_attr (id);
|
||||
if (id != NULL)
|
||||
{
|
||||
source = get_target (editor->model, id);
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
|
||||
source_attr = get_target_attr (id);
|
||||
}
|
||||
else
|
||||
{
|
||||
source = NULL;
|
||||
source_attr = GTK_CONSTRAINT_ATTRIBUTE_NONE;
|
||||
}
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->relation));
|
||||
relation = get_relation (id);
|
||||
@@ -347,7 +368,7 @@ constraint_editor_constraint_to_string (GtkConstraint *constraint)
|
||||
|
||||
name = get_target_name (gtk_constraint_get_target (constraint));
|
||||
attr = get_attr_nick (gtk_constraint_get_target_attribute (constraint));
|
||||
relation = get_relation_nick (gtk_constraint_get_relation (constraint));
|
||||
relation = get_relation_to_string (gtk_constraint_get_relation (constraint));
|
||||
|
||||
if (name == NULL)
|
||||
name = "[ ]";
|
||||
@@ -408,14 +429,20 @@ update_preview (ConstraintEditor *editor)
|
||||
g_free (relation);
|
||||
|
||||
constant = gtk_editable_get_text (GTK_EDITABLE (editor->constant));
|
||||
c = g_ascii_strtod (constant, NULL);
|
||||
if (constant[0] != '\0')
|
||||
c = g_ascii_strtod (constant, NULL);
|
||||
else
|
||||
c = 0.0;
|
||||
|
||||
attr = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
|
||||
if (strcmp (attr, "none") != 0)
|
||||
{
|
||||
name = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source));
|
||||
multiplier = gtk_editable_get_text (GTK_EDITABLE (editor->multiplier));
|
||||
m = g_ascii_strtod (multiplier, NULL);
|
||||
if (multiplier[0] != '\0')
|
||||
m = g_ascii_strtod (multiplier, NULL);
|
||||
else
|
||||
m = 1.0;
|
||||
|
||||
if (name == NULL)
|
||||
name = "[ ]";
|
||||
@@ -441,8 +468,7 @@ update_preview (ConstraintEditor *editor)
|
||||
static void
|
||||
update_button (ConstraintEditor *editor)
|
||||
{
|
||||
if (gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target)) != NULL &&
|
||||
gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source)) != NULL)
|
||||
if (gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target)) != NULL)
|
||||
gtk_widget_set_sensitive (editor->button, TRUE);
|
||||
else
|
||||
gtk_widget_set_sensitive (editor->button, FALSE);
|
||||
|
@@ -7,6 +7,7 @@ constraintview .child {
|
||||
background: red;
|
||||
}
|
||||
|
||||
constraintview .guide {
|
||||
constraintview guide {
|
||||
background: blue;
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
@@ -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>
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -212,11 +216,16 @@ 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);
|
||||
gtk_widget_set_size_request (frame, 100, 25);
|
||||
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);
|
||||
@@ -235,8 +244,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 +259,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 +288,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 +296,7 @@ constraint_view_remove_guide (ConstraintView *view,
|
||||
GtkConstraintGuide *guide)
|
||||
{
|
||||
GtkConstraintLayout *layout;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *placeholder;
|
||||
GtkConstraint *constraint;
|
||||
const char *names[] = {
|
||||
"left-constraint",
|
||||
@@ -307,9 +314,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);
|
||||
}
|
||||
|
179
demos/constraint-editor/guide-placeholder.c
Normal file
179
demos/constraint-editor/guide-placeholder.c
Normal file
@@ -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);
|
||||
}
|
28
demos/constraint-editor/guide-placeholder.h
Normal file
28
demos/constraint-editor/guide-placeholder.h
Normal file
@@ -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);
|
@@ -5,6 +5,8 @@ constraint_editor_sources = [
|
||||
'constraint-view.c',
|
||||
'constraint-editor.c',
|
||||
'guide-editor.c',
|
||||
'child-editor.c',
|
||||
'guide-placeholder.c',
|
||||
]
|
||||
|
||||
constraint_editor_resources = gnome.compile_resources('constraint_editor_resources',
|
||||
|
Reference in New Issue
Block a user