forked from AuroraMiddleware/gtk
constraint editor: Implement saving
Save to a ui file.
This commit is contained in:
parent
377f0c1a0a
commit
c5e1b00994
@ -51,6 +51,7 @@ static void
|
|||||||
constraint_editor_application_startup (GApplication *app)
|
constraint_editor_application_startup (GApplication *app)
|
||||||
{
|
{
|
||||||
const char *quit_accels[2] = { "<Ctrl>Q", NULL };
|
const char *quit_accels[2] = { "<Ctrl>Q", NULL };
|
||||||
|
const char *open_accels[2] = { "<Ctrl>O", NULL };
|
||||||
GtkCssProvider *provider;
|
GtkCssProvider *provider;
|
||||||
|
|
||||||
G_APPLICATION_CLASS (constraint_editor_application_parent_class)->startup (app);
|
G_APPLICATION_CLASS (constraint_editor_application_parent_class)->startup (app);
|
||||||
@ -59,6 +60,7 @@ constraint_editor_application_startup (GApplication *app)
|
|||||||
app_entries, G_N_ELEMENTS (app_entries),
|
app_entries, G_N_ELEMENTS (app_entries),
|
||||||
app);
|
app);
|
||||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.quit", quit_accels);
|
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.quit", quit_accels);
|
||||||
|
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "win.open", open_accels);
|
||||||
|
|
||||||
provider = gtk_css_provider_new ();
|
provider = gtk_css_provider_new ();
|
||||||
gtk_css_provider_load_from_resource (provider, "/org/gtk/gtk4/constraint-editor/constraint-editor.css");
|
gtk_css_provider_load_from_resource (provider, "/org/gtk/gtk4/constraint-editor/constraint-editor.css");
|
||||||
@ -76,6 +78,23 @@ constraint_editor_application_activate (GApplication *app)
|
|||||||
gtk_window_present (GTK_WINDOW (win));
|
gtk_window_present (GTK_WINDOW (win));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_editor_application_open (GApplication *app,
|
||||||
|
GFile **files,
|
||||||
|
gint n_files,
|
||||||
|
const gchar *hint)
|
||||||
|
{
|
||||||
|
ConstraintEditorWindow *win;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
for (i = 0; i < n_files; i++)
|
||||||
|
{
|
||||||
|
win = constraint_editor_window_new (CONSTRAINT_EDITOR_APPLICATION (app));
|
||||||
|
constraint_editor_window_load (win, files[i]);
|
||||||
|
gtk_window_present (GTK_WINDOW (win));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
constraint_editor_application_class_init (ConstraintEditorApplicationClass *class)
|
constraint_editor_application_class_init (ConstraintEditorApplicationClass *class)
|
||||||
{
|
{
|
||||||
@ -83,6 +102,7 @@ constraint_editor_application_class_init (ConstraintEditorApplicationClass *clas
|
|||||||
|
|
||||||
application_class->startup = constraint_editor_application_startup;
|
application_class->startup = constraint_editor_application_startup;
|
||||||
application_class->activate = constraint_editor_application_activate;
|
application_class->activate = constraint_editor_application_activate;
|
||||||
|
application_class->open = constraint_editor_application_open;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstraintEditorApplication *
|
ConstraintEditorApplication *
|
||||||
@ -90,5 +110,6 @@ constraint_editor_application_new (void)
|
|||||||
{
|
{
|
||||||
return g_object_new (CONSTRAINT_EDITOR_APPLICATION_TYPE,
|
return g_object_new (CONSTRAINT_EDITOR_APPLICATION_TYPE,
|
||||||
"application-id", "org.gtk.gtk4.ConstraintEditor",
|
"application-id", "org.gtk.gtk4.ConstraintEditor",
|
||||||
|
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,151 @@ constraint_editor_window_load (ConstraintEditorWindow *self,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
open_response_cb (GtkNativeDialog *dialog,
|
||||||
|
gint response,
|
||||||
|
ConstraintEditorWindow *self)
|
||||||
|
{
|
||||||
|
gtk_native_dialog_hide (dialog);
|
||||||
|
|
||||||
|
if (response == GTK_RESPONSE_ACCEPT)
|
||||||
|
{
|
||||||
|
GFile *file;
|
||||||
|
|
||||||
|
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
||||||
|
constraint_editor_window_load (self, file);
|
||||||
|
g_object_unref (file);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_native_dialog_destroy (dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
open_cb (GtkWidget *button,
|
||||||
|
ConstraintEditorWindow *self)
|
||||||
|
{
|
||||||
|
GtkFileChooserNative *dialog;
|
||||||
|
|
||||||
|
dialog = gtk_file_chooser_native_new ("Open file",
|
||||||
|
GTK_WINDOW (self),
|
||||||
|
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||||
|
"_Load",
|
||||||
|
"_Cancel");
|
||||||
|
|
||||||
|
gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (dialog), TRUE);
|
||||||
|
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), ".");
|
||||||
|
g_signal_connect (dialog, "response", G_CALLBACK (open_response_cb), self);
|
||||||
|
gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
serialize_child (GString *str,
|
||||||
|
int indent,
|
||||||
|
GtkWidget *child)
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
name = gtk_widget_get_name (child);
|
||||||
|
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);
|
||||||
|
g_string_append_printf (str, "%*s </object>\n", indent, "");
|
||||||
|
g_string_append_printf (str, "%*s</child>\n", indent, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
serialize_model (GListModel *list)
|
||||||
|
{
|
||||||
|
GString *str = g_string_new ("");
|
||||||
|
int i;
|
||||||
|
|
||||||
|
g_string_append (str, "<interface>\n");
|
||||||
|
g_string_append (str, " <object class=\"GtkBox\" id=\"view\">\n");
|
||||||
|
g_string_append (str, " <property name=\"layout-manager\">\n");
|
||||||
|
g_string_append (str, " <object class=\"GtkConstraintLayout\">\n");
|
||||||
|
g_string_append (str, " <constraints>\n");
|
||||||
|
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||||
|
{
|
||||||
|
gpointer item = g_list_model_get_item (list, i);
|
||||||
|
g_object_unref (item);
|
||||||
|
if (GTK_IS_CONSTRAINT (item))
|
||||||
|
constraint_editor_serialize_constraint (str, 10, GTK_CONSTRAINT (item));
|
||||||
|
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||||
|
guide_editor_serialize_guide (str, 10, GTK_CONSTRAINT_GUIDE (item));
|
||||||
|
}
|
||||||
|
g_string_append (str, " </constraints>\n");
|
||||||
|
g_string_append (str, " </object>\n");
|
||||||
|
g_string_append (str, " </property>\n");
|
||||||
|
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||||
|
{
|
||||||
|
gpointer item = g_list_model_get_item (list, i);
|
||||||
|
g_object_unref (item);
|
||||||
|
if (GTK_IS_WIDGET (item))
|
||||||
|
serialize_child (str, 4, GTK_WIDGET (item));
|
||||||
|
}
|
||||||
|
g_string_append (str, " </object>\n");
|
||||||
|
g_string_append (str, "</interface>\n");
|
||||||
|
|
||||||
|
return g_string_free (str, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
save_response_cb (GtkNativeDialog *dialog,
|
||||||
|
gint response,
|
||||||
|
ConstraintEditorWindow *self)
|
||||||
|
{
|
||||||
|
gtk_native_dialog_hide (dialog);
|
||||||
|
|
||||||
|
if (response == GTK_RESPONSE_ACCEPT)
|
||||||
|
{
|
||||||
|
GListModel *model;
|
||||||
|
char *text, *filename;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
model = constraint_view_get_model (CONSTRAINT_VIEW (self->view));
|
||||||
|
text = serialize_model (model);
|
||||||
|
|
||||||
|
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
|
||||||
|
if (!g_file_set_contents (filename, text, -1, &error))
|
||||||
|
{
|
||||||
|
GtkWidget *dialog;
|
||||||
|
|
||||||
|
dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (self))),
|
||||||
|
GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
GTK_MESSAGE_INFO,
|
||||||
|
GTK_BUTTONS_OK,
|
||||||
|
"Saving failed");
|
||||||
|
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||||
|
"%s", error->message);
|
||||||
|
g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
|
||||||
|
gtk_widget_show (dialog);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
g_free (filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_native_dialog_destroy (dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
save_cb (GtkWidget *button,
|
||||||
|
ConstraintEditorWindow *self)
|
||||||
|
{
|
||||||
|
GtkFileChooserNative *dialog;
|
||||||
|
|
||||||
|
dialog = gtk_file_chooser_native_new ("Save constraints",
|
||||||
|
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
|
||||||
|
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||||
|
"_Save",
|
||||||
|
"_Cancel");
|
||||||
|
|
||||||
|
gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (dialog), TRUE);
|
||||||
|
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), ".");
|
||||||
|
g_signal_connect (dialog, "response", G_CALLBACK (save_response_cb), self);
|
||||||
|
gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
constraint_editor_window_finalize (GObject *object)
|
constraint_editor_window_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
@ -213,6 +358,8 @@ constraint_editor_window_class_init (ConstraintEditorWindowClass *class)
|
|||||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, view);
|
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, view);
|
||||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, list);
|
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, list);
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, open_cb);
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, save_cb);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, add_child);
|
gtk_widget_class_bind_template_callback (widget_class, add_child);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, add_guide);
|
gtk_widget_class_bind_template_callback (widget_class, add_guide);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, add_constraint);
|
gtk_widget_class_bind_template_callback (widget_class, add_constraint);
|
||||||
|
@ -11,6 +11,20 @@
|
|||||||
<object class="GtkHeaderBar" id="header">
|
<object class="GtkHeaderBar" id="header">
|
||||||
<property name="title" translatable="yes">GTK Constraint Editor</property>
|
<property name="title" translatable="yes">GTK Constraint Editor</property>
|
||||||
<property name="show-title-buttons">1</property>
|
<property name="show-title-buttons">1</property>
|
||||||
|
<child type="start">
|
||||||
|
<object class="GtkButton">
|
||||||
|
<property name="icon-name">document-open-symbolic</property>
|
||||||
|
<property name="tooltip-text">Open ui file</property>
|
||||||
|
<signal name="clicked" handler="open_cb"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child type="start">
|
||||||
|
<object class="GtkButton">
|
||||||
|
<property name="icon-name">document-save-symbolic</property>
|
||||||
|
<property name="tooltip-text">Save to ui file</property>
|
||||||
|
<signal name="clicked" handler="save_cb"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -236,6 +236,40 @@ get_strength_nick (GtkConstraintStrength strength)
|
|||||||
return nick;
|
return nick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
constraint_editor_serialize_constraint (GString *str,
|
||||||
|
int indent,
|
||||||
|
GtkConstraint *constraint)
|
||||||
|
{
|
||||||
|
const char *target;
|
||||||
|
const char *target_attr;
|
||||||
|
const char *relation;
|
||||||
|
const char *source;
|
||||||
|
const char *source_attr;
|
||||||
|
double multiplier;
|
||||||
|
double constant;
|
||||||
|
const char *strength;
|
||||||
|
|
||||||
|
target = get_target_name (gtk_constraint_get_target (constraint));
|
||||||
|
target_attr = get_attr_nick (gtk_constraint_get_target_attribute (constraint));
|
||||||
|
relation = get_relation_nick (gtk_constraint_get_relation (constraint));
|
||||||
|
source = get_target_name (gtk_constraint_get_source (constraint));
|
||||||
|
source_attr = get_attr_nick (gtk_constraint_get_source_attribute (constraint));
|
||||||
|
multiplier = gtk_constraint_get_multiplier (constraint);
|
||||||
|
constant = gtk_constraint_get_constant (constraint);
|
||||||
|
strength = get_strength_nick (gtk_constraint_get_strength (constraint));
|
||||||
|
|
||||||
|
g_string_append_printf (str, "%*s<constraint target=\"%s\" target-attribute=\"%s\"\n", indent, "", target, target_attr);
|
||||||
|
g_string_append_printf (str, "%*s relation=\"%s\"\n", indent, "", relation);
|
||||||
|
if (strcmp (source_attr, "none") != 0)
|
||||||
|
{
|
||||||
|
g_string_append_printf (str, "%*s source=\"%s\" source-attribute=\"%s\"\n", indent, "", source, source_attr);
|
||||||
|
g_string_append_printf (str, "%*s multiplier=\"%g\"\n", indent, "", multiplier);
|
||||||
|
}
|
||||||
|
g_string_append_printf (str, "%*s constant=\"%g\"\n", indent, "", constant);
|
||||||
|
g_string_append_printf (str, "%*s strength=\"%s\" />\n", indent, "", strength);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
create_constraint (GtkButton *button,
|
create_constraint (GtkButton *button,
|
||||||
ConstraintEditor *editor)
|
ConstraintEditor *editor)
|
||||||
|
@ -27,3 +27,7 @@ G_DECLARE_FINAL_TYPE (ConstraintEditor, constraint_editor, CONSTRAINT, EDITOR, G
|
|||||||
|
|
||||||
ConstraintEditor * constraint_editor_new (GListModel *model,
|
ConstraintEditor * constraint_editor_new (GListModel *model,
|
||||||
GtkConstraint *constraint);
|
GtkConstraint *constraint);
|
||||||
|
|
||||||
|
void constraint_editor_serialize_constraint (GString *str,
|
||||||
|
int indent,
|
||||||
|
GtkConstraint *constraint);
|
||||||
|
@ -89,6 +89,29 @@ get_strength_nick (GtkConstraintStrength strength)
|
|||||||
return nick;
|
return nick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
guide_editor_serialize_guide (GString *str,
|
||||||
|
int indent,
|
||||||
|
GtkConstraintGuide *guide)
|
||||||
|
{
|
||||||
|
int min_width, min_height;
|
||||||
|
int nat_width, nat_height;
|
||||||
|
int max_width, max_height;
|
||||||
|
const char *name;
|
||||||
|
const char *strength;
|
||||||
|
|
||||||
|
gtk_constraint_guide_get_min_size (guide, &min_width, &min_height);
|
||||||
|
gtk_constraint_guide_get_nat_size (guide, &nat_width, &nat_height);
|
||||||
|
gtk_constraint_guide_get_max_size (guide, &max_width, &max_height);
|
||||||
|
name = gtk_constraint_guide_get_name (guide);
|
||||||
|
strength = get_strength_nick (gtk_constraint_guide_get_strength (guide));
|
||||||
|
|
||||||
|
g_string_append_printf (str, "%*s<guide min-width=\"%d\" min-height=\"%d\"\n", indent, "", min_width, min_height);
|
||||||
|
g_string_append_printf (str, "%*s nat-width=\"%d\" nat-height=\"%d\"\n", indent, "", nat_width, nat_height);
|
||||||
|
g_string_append_printf (str, "%*s max-width=\"%d\" max-height=\"%d\"\n", indent, "", max_width, max_height);
|
||||||
|
g_string_append_printf (str, "%*s name=\"%s\" strength=\"%s\" />\n", indent, "", name, strength);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
create_guide (GtkButton *button,
|
create_guide (GtkButton *button,
|
||||||
GuideEditor *editor)
|
GuideEditor *editor)
|
||||||
|
@ -26,3 +26,7 @@
|
|||||||
G_DECLARE_FINAL_TYPE (GuideEditor, guide_editor, GUIDE, EDITOR, GtkWidget)
|
G_DECLARE_FINAL_TYPE (GuideEditor, guide_editor, GUIDE, EDITOR, GtkWidget)
|
||||||
|
|
||||||
GuideEditor * guide_editor_new (GtkConstraintGuide *guide);
|
GuideEditor * guide_editor_new (GtkConstraintGuide *guide);
|
||||||
|
|
||||||
|
void guide_editor_serialize_guide (GString *str,
|
||||||
|
int indent,
|
||||||
|
GtkConstraintGuide *guide);
|
||||||
|
Loading…
Reference in New Issue
Block a user