[gtk/path-work-rebased: 81/121] Ottie: Add ottie-editor
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/path-work-rebased: 81/121] Ottie: Add ottie-editor
- Date: Sun, 5 Dec 2021 03:58:59 +0000 (UTC)
commit 33d5acf1db3a464d821eac47c27cc56c2fd4979d
Author: Benjamin Otte <otte redhat com>
Date: Sat Dec 26 04:00:21 2020 +0100
Ottie: Add ottie-editor
meson.build | 1 +
ottie/editor/main.c | 28 +++
ottie/editor/meson.build | 31 +++
ottie/editor/ottie-editor-application.c | 215 ++++++++++++++++
ottie/editor/ottie-editor-application.h | 38 +++
ottie/editor/ottie-editor-window.c | 431 ++++++++++++++++++++++++++++++++
ottie/editor/ottie-editor-window.h | 42 ++++
ottie/editor/ottie-editor-window.ui | 133 ++++++++++
ottie/editor/ottie-editor.gresource.xml | 6 +
9 files changed, 925 insertions(+)
---
diff --git a/meson.build b/meson.build
index 38a09afac8..deec763780 100644
--- a/meson.build
+++ b/meson.build
@@ -786,6 +786,7 @@ subdir('gsk')
subdir('ottie')
subdir('gtk')
subdir('ottie/tools')
+subdir('ottie/editor')
subdir('modules')
if get_option('demos')
subdir('demos')
diff --git a/ottie/editor/main.c b/ottie/editor/main.c
new file mode 100644
index 0000000000..fabe2c2d6c
--- /dev/null
+++ b/ottie/editor/main.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright © 2020 Benjamin Otte
+ *
+ * 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: Benjamin Otte <otte gnome org>
+ */
+
+#include "config.h"
+
+#include <ottie-editor-application.h>
+
+int
+main (int argc, char *argv[])
+{
+ return g_application_run (G_APPLICATION (ottie_editor_application_new ()), argc, argv);
+}
diff --git a/ottie/editor/meson.build b/ottie/editor/meson.build
new file mode 100644
index 0000000000..f21ab6b833
--- /dev/null
+++ b/ottie/editor/meson.build
@@ -0,0 +1,31 @@
+ottie_editor_sources = [
+ 'main.c',
+ 'ottie-editor-application.c',
+ 'ottie-editor-window.c',
+]
+
+ottie_editor_resources = gnome.compile_resources('ottie_editor_resources',
+ 'ottie-editor.gresource.xml',
+ source_dir: '.',
+)
+
+executable('ottie-editor',
+ sources: [ottie_editor_sources, ottie_editor_resources],
+ dependencies: [libgtk_css_dep, libgdk_dep, libgsk_dep, libgtk_static_dep, libottie_dep],
+ include_directories: confinc,
+ c_args: [
+ '-DGTK_COMPILATION',
+ '-DG_LOG_DOMAIN="OttieEditor"',
+ ] + common_cflags,
+ gui_app: true,
+ link_with: [libgtk_static, libgtk_css, libgdk, libgsk, libottie],
+ link_args: common_ldflags,
+ install: false,
+)
+
+# icons, don't install them until we decide to install ottie-editor
+#icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
+
+#foreach size: ['scalable', 'symbolic']
+# install_subdir('data/' + size, install_dir: icontheme_dir)
+#endforeach
diff --git a/ottie/editor/ottie-editor-application.c b/ottie/editor/ottie-editor-application.c
new file mode 100644
index 0000000000..9ae643bf66
--- /dev/null
+++ b/ottie/editor/ottie-editor-application.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright © 2020 Benjamin Otte
+ *
+ * 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: Benjamin Otte <otte gnome org>
+ */
+
+#include "config.h"
+
+#include "ottie-editor-application.h"
+
+#include "ottie-editor-window.h"
+
+struct _OttieEditorApplication
+{
+ GtkApplication parent;
+};
+
+struct _OttieEditorApplicationClass
+{
+ GtkApplicationClass parent_class;
+};
+
+G_DEFINE_TYPE(OttieEditorApplication, ottie_editor_application, GTK_TYPE_APPLICATION);
+
+static void
+ottie_editor_application_init (OttieEditorApplication *app)
+{
+}
+
+static void
+activate_about (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GtkApplication *app = user_data;
+ char *version;
+ GString *s;
+ char *os_name;
+ char *os_version;
+ GtkWidget *dialog;
+
+ os_name = g_get_os_info (G_OS_INFO_KEY_NAME);
+ os_version = g_get_os_info (G_OS_INFO_KEY_VERSION_ID);
+ s = g_string_new ("");
+ if (os_name && os_version)
+ g_string_append_printf (s, "OS\t%s %s\n\n", os_name, os_version);
+
+ g_string_append (s, "System libraries\n");
+ g_string_append_printf (s, "\tGLib\t%d.%d.%d\n",
+ glib_major_version,
+ glib_minor_version,
+ glib_micro_version);
+ g_string_append_printf (s, "\tPango\t%s\n",
+ pango_version_string ());
+ g_string_append_printf (s, "\tGTK\t%d.%d.%d\n",
+ gtk_get_major_version (),
+ gtk_get_minor_version (),
+ gtk_get_micro_version ());
+
+ version = g_strdup_printf ("%s\nRunning against GTK %d.%d.%d",
+ PACKAGE_VERSION,
+ gtk_get_major_version (),
+ gtk_get_minor_version (),
+ gtk_get_micro_version ());
+
+ dialog = g_object_new (GTK_TYPE_ABOUT_DIALOG,
+ "transient-for", gtk_application_get_active_window (app),
+ "program-name", "GTK Node Editor",
+ "version", version,
+ "copyright", "© 2019—2020 The GTK Team",
+ "license-type", GTK_LICENSE_LGPL_2_1,
+ "website", "http://www.gtk.org",
+ "comments", "Program to test GTK rendering",
+ "authors", (const char *[]){ "Benjamin Otte", "Timm Bäder", NULL},
+ "logo-icon-name", "org.gtk.gtk4.OttieEditor.Devel",
+ "title", "About GTK Node Editor",
+ "system-information", s->str,
+ NULL);
+ gtk_about_dialog_add_credit_section (GTK_ABOUT_DIALOG (dialog),
+ "Artwork by", (const char *[]) { "Jakub Steiner", NULL });
+
+ gtk_window_present (GTK_WINDOW (dialog));
+
+ g_string_free (s, TRUE);
+ g_free (version);
+ g_free (os_name);
+ g_free (os_version);
+}
+
+static void
+activate_quit (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer data)
+{
+ g_application_quit (G_APPLICATION (data));
+}
+
+static void
+activate_inspector (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ gtk_window_set_interactive_debugging (TRUE);
+}
+
+static void
+activate_help (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GtkBuilder *builder;
+ GtkWidget *window;
+ GtkTextBuffer *buffer;
+ GBytes *bytes;
+ const char *text;
+ gsize len;
+
+ builder = gtk_builder_new ();
+ gtk_builder_add_from_resource (builder, "/org/gtk/gtk4/node-editor/help-window.ui", NULL);
+ window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
+ buffer = GTK_TEXT_BUFFER (gtk_builder_get_object (builder, "buffer"));
+
+ bytes = g_resources_lookup_data ("/org/gtk/gtk4/node-editor/node-format.md",
+ G_RESOURCE_LOOKUP_FLAGS_NONE,
+ NULL);
+ text = g_bytes_get_data (bytes, &len);
+ gtk_text_buffer_set_text (buffer, text, len);
+ g_bytes_unref (bytes);
+
+ gtk_window_present (GTK_WINDOW (window));
+ g_object_unref (builder);
+}
+
+static GActionEntry app_entries[] =
+{
+ { "about", activate_about, NULL, NULL, NULL },
+ { "quit", activate_quit, NULL, NULL, NULL },
+ { "inspector", activate_inspector, NULL, NULL, NULL },
+ { "help", activate_help, NULL, NULL, NULL },
+};
+
+static void
+ottie_editor_application_startup (GApplication *app)
+{
+ const char *help_accels[2] = { "F1", NULL };
+ const char *quit_accels[2] = { "<Ctrl>Q", NULL };
+ const char *open_accels[2] = { "<Ctrl>O", NULL };
+
+ G_APPLICATION_CLASS (ottie_editor_application_parent_class)->startup (app);
+
+ g_action_map_add_action_entries (G_ACTION_MAP (app),
+ app_entries, G_N_ELEMENTS (app_entries),
+ app);
+ gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.help", help_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);
+}
+
+static void
+ottie_editor_application_activate (GApplication *app)
+{
+ OttieEditorWindow *win;
+
+ win = ottie_editor_window_new (OTTIE_EDITOR_APPLICATION (app));
+ gtk_window_present (GTK_WINDOW (win));
+}
+
+static void
+ottie_editor_application_open (GApplication *app,
+ GFile **files,
+ int n_files,
+ const char *hint)
+{
+ OttieEditorWindow *win;
+ int i;
+
+ for (i = 0; i < n_files; i++)
+ {
+ win = ottie_editor_window_new (OTTIE_EDITOR_APPLICATION (app));
+ ottie_editor_window_load (win, files[i]);
+ gtk_window_present (GTK_WINDOW (win));
+ }
+}
+
+static void
+ottie_editor_application_class_init (OttieEditorApplicationClass *class)
+{
+ GApplicationClass *application_class = G_APPLICATION_CLASS (class);
+
+ application_class->startup = ottie_editor_application_startup;
+ application_class->activate = ottie_editor_application_activate;
+ application_class->open = ottie_editor_application_open;
+}
+
+OttieEditorApplication *
+ottie_editor_application_new (void)
+{
+ return g_object_new (OTTIE_EDITOR_APPLICATION_TYPE,
+ "application-id", "org.gtk.gtk4.OttieEditor",
+ "flags", G_APPLICATION_HANDLES_OPEN,
+ NULL);
+}
diff --git a/ottie/editor/ottie-editor-application.h b/ottie/editor/ottie-editor-application.h
new file mode 100644
index 0000000000..5e1e180f4d
--- /dev/null
+++ b/ottie/editor/ottie-editor-application.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright © 2020 Benjamin Otte
+ *
+ * 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: Benjamin Otte <otte gnome org>
+ */
+
+#ifndef __OTTIE_EDITOR_APPLICATION_H__
+#define __OTTIE_EDITOR_APPLICATION_H__
+
+#include <gtk/gtk.h>
+
+
+#define OTTIE_EDITOR_APPLICATION_TYPE (ottie_editor_application_get_type ())
+#define OTTIE_EDITOR_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OTTIE_EDITOR_APPLICATION_TYPE,
OttieEditorApplication))
+
+
+typedef struct _OttieEditorApplication OttieEditorApplication;
+typedef struct _OttieEditorApplicationClass OttieEditorApplicationClass;
+
+
+GType ottie_editor_application_get_type (void);
+OttieEditorApplication *ottie_editor_application_new (void);
+
+
+#endif /* __OTTIE_EDITOR_APPLICATION_H__ */
diff --git a/ottie/editor/ottie-editor-window.c b/ottie/editor/ottie-editor-window.c
new file mode 100644
index 0000000000..bda94d77bb
--- /dev/null
+++ b/ottie/editor/ottie-editor-window.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright © 2020 Benjamin Otte
+ *
+ * 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: Benjamin Otte <otte gnome org>
+ */
+
+#include "config.h"
+
+#include "ottie-editor-window.h"
+
+#include "ottie/ottiecreationprivate.h"
+#include "ottie/ottiecompositionlayerprivate.h"
+#include "ottie/ottiegroupshapeprivate.h"
+#include "ottie/ottieshapelayerprivate.h"
+#include "ottie/ottiepaintable.h"
+
+struct _OttieEditorWindow
+{
+ GtkApplicationWindow parent;
+
+ GFileMonitor *file_monitor;
+
+ OttieCreation *creation;
+ OttiePaintable *paintable;
+
+ GtkWidget *picture;
+ GtkWidget *listview;
+};
+
+struct _OttieEditorWindowClass
+{
+ GtkApplicationWindowClass parent_class;
+};
+
+G_DEFINE_TYPE(OttieEditorWindow, ottie_editor_window, GTK_TYPE_APPLICATION_WINDOW);
+
+static gboolean
+load_file_contents (OttieEditorWindow *self,
+ GFile *file)
+{
+ GBytes *bytes;
+
+ bytes = g_file_load_bytes (file, NULL, NULL, NULL);
+ if (bytes == NULL)
+ return FALSE;
+
+ if (!g_utf8_validate (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), NULL))
+ {
+ g_bytes_unref (bytes);
+ return FALSE;
+ }
+
+ ottie_creation_load_bytes (self->creation, bytes);
+#if 0
+ gtk_text_buffer_set_text (self->text_buffer,
+ g_bytes_get_data (bytes, NULL),
+ g_bytes_get_size (bytes));
+#endif
+
+ g_bytes_unref (bytes);
+
+ return TRUE;
+}
+
+static void
+file_changed_cb (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ OttieEditorWindow *self = user_data;
+
+ if (event_type == G_FILE_MONITOR_EVENT_CHANGED)
+ load_file_contents (self, file);
+}
+
+void
+ottie_editor_window_load (OttieEditorWindow *self,
+ GFile *file)
+{
+ GError *error = NULL;
+
+ if (!load_file_contents (self, file))
+ return;
+
+ g_clear_object (&self->file_monitor);
+ self->file_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error);
+
+ if (error)
+ {
+ g_warning ("couldn't monitor file: %s", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ g_signal_connect (self->file_monitor, "changed", G_CALLBACK (file_changed_cb), self);
+ }
+}
+
+static void
+open_response_cb (GtkWidget *dialog,
+ int response,
+ OttieEditorWindow *self)
+{
+ gtk_widget_hide (dialog);
+
+ if (response == GTK_RESPONSE_ACCEPT)
+ {
+ GFile *file;
+
+ file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
+ ottie_editor_window_load (self, file);
+ g_object_unref (file);
+ }
+
+ gtk_window_destroy (GTK_WINDOW (dialog));
+}
+
+static void
+show_open_filechooser (OttieEditorWindow *self)
+{
+ GtkWidget *dialog;
+
+ dialog = gtk_file_chooser_dialog_new ("Open lottie file",
+ GTK_WINDOW (self),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ "_Cancel", GTK_RESPONSE_CANCEL,
+ "_Load", GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+ GFile *cwd = g_file_new_for_path (".");
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), cwd, NULL);
+ g_object_unref (cwd);
+
+ g_signal_connect (dialog, "response", G_CALLBACK (open_response_cb), self);
+ gtk_widget_show (dialog);
+}
+
+static void
+open_cb (GtkWidget *button,
+ OttieEditorWindow *self)
+{
+ show_open_filechooser (self);
+}
+
+static void
+save_response_cb (GtkWidget *dialog,
+ int response,
+ OttieEditorWindow *self)
+{
+ gtk_widget_hide (dialog);
+
+ if (response == GTK_RESPONSE_ACCEPT)
+ {
+#if 0
+ GFile *file;
+ char *text;
+#endif
+ GError *error = NULL;
+
+#if 0
+ text = get_current_text (self->text_buffer);
+
+ file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
+ g_file_replace_contents (file, text, strlen (text),
+ NULL, FALSE,
+ G_FILE_CREATE_NONE,
+ NULL,
+ NULL,
+ &error);
+#endif
+
+ if (error != NULL)
+ {
+ GtkWidget *message_dialog;
+
+ message_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 (message_dialog),
+ "%s", error->message);
+ g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
+ gtk_widget_show (message_dialog);
+ g_error_free (error);
+ }
+
+#if 0
+ g_free (text);
+ g_object_unref (file);
+#endif
+ }
+
+ gtk_window_destroy (GTK_WINDOW (dialog));
+}
+
+static void
+save_cb (GtkWidget *button,
+ OttieEditorWindow *self)
+{
+ GtkWidget *dialog;
+
+ dialog = gtk_file_chooser_dialog_new ("Save file",
+ GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ "_Cancel", GTK_RESPONSE_CANCEL,
+ "_Save", GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+ GFile *cwd = g_file_new_for_path (".");
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), cwd, NULL);
+ g_object_unref (cwd);
+
+ g_signal_connect (dialog, "response", G_CALLBACK (save_response_cb), self);
+ gtk_widget_show (dialog);
+}
+
+static GdkTexture *
+create_texture (OttieEditorWindow *self)
+{
+ GtkSnapshot *snapshot;
+ GskRenderer *renderer;
+ GskRenderNode *node;
+ GdkTexture *texture;
+ int width, height;
+
+ width = gdk_paintable_get_intrinsic_width (GDK_PAINTABLE (self->paintable));
+ height = gdk_paintable_get_intrinsic_height (GDK_PAINTABLE (self->paintable));
+
+ if (width <= 0 || height <= 0)
+ return NULL;
+ snapshot = gtk_snapshot_new ();
+ gdk_paintable_snapshot (GDK_PAINTABLE (self->paintable), snapshot, width, height);
+ node = gtk_snapshot_free_to_node (snapshot);
+ if (node == NULL)
+ return NULL;
+
+ renderer = gtk_native_get_renderer (gtk_widget_get_native (GTK_WIDGET (self)));
+ texture = gsk_renderer_render_texture (renderer, node, NULL);
+ gsk_render_node_unref (node);
+
+ return texture;
+}
+
+static void
+export_image_response_cb (GtkWidget *dialog,
+ int response,
+ GdkTexture *texture)
+{
+ gtk_widget_hide (dialog);
+
+ if (response == GTK_RESPONSE_ACCEPT)
+ {
+ GFile *file;
+
+ file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
+ if (!gdk_texture_save_to_png (texture, g_file_peek_path (file)))
+ {
+ GtkWidget *message_dialog;
+
+ message_dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_window_get_transient_for (GTK_WINDOW
(dialog))),
+ GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_OK,
+ "Exporting to image failed");
+ g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
+ gtk_widget_show (message_dialog);
+ }
+
+ g_object_unref (file);
+ }
+
+ gtk_window_destroy (GTK_WINDOW (dialog));
+ g_object_unref (texture);
+}
+
+static void
+export_image_cb (GtkWidget *button,
+ OttieEditorWindow *self)
+{
+ GdkTexture *texture;
+ GtkWidget *dialog;
+
+ texture = create_texture (self);
+ if (texture == NULL)
+ return;
+
+ dialog = gtk_file_chooser_dialog_new ("",
+ GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ "_Cancel", GTK_RESPONSE_CANCEL,
+ "_Save", GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+ g_signal_connect (dialog, "response", G_CALLBACK (export_image_response_cb), texture);
+ gtk_widget_show (dialog);
+}
+
+static GListModel *
+create_object_children (gpointer item,
+ gpointer user_data)
+{
+ if (OTTIE_IS_COMPOSITION_LAYER (item))
+ {
+ return G_LIST_MODEL (g_object_ref (ottie_composition_layer_get_composition (item)));
+ }
+ else if (OTTIE_IS_SHAPE_LAYER (item))
+ {
+ return G_LIST_MODEL (g_object_ref (ottie_shape_layer_get_shape (item)));
+ }
+ else if (OTTIE_IS_GROUP_SHAPE (item))
+ {
+ return g_object_ref (item);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+static void
+notify_prepared_cb (OttieCreation *creation,
+ GParamSpec *pspec,
+ OttieEditorWindow *self)
+{
+ GtkTreeListModel *treemodel;
+ GtkSingleSelection *selection;
+
+ if (ottie_creation_is_prepared (creation))
+ {
+ treemodel = gtk_tree_list_model_new (G_LIST_MODEL (ottie_creation_get_composition (self->creation)),
+ FALSE,
+ TRUE,
+ create_object_children,
+ NULL,
+ NULL);
+ selection = gtk_single_selection_new (G_LIST_MODEL (treemodel));
+ gtk_list_view_set_model (GTK_LIST_VIEW (self->listview), GTK_SELECTION_MODEL (selection));
+ g_object_unref (selection);
+ }
+ else
+ {
+ gtk_list_view_set_model (GTK_LIST_VIEW (self->listview), NULL);
+ }
+}
+
+static void
+ottie_editor_window_finalize (GObject *object)
+{
+ //OttieEditorWindow *self = OTTIE_EDITOR_WINDOW (object);
+
+ G_OBJECT_CLASS (ottie_editor_window_parent_class)->finalize (object);
+}
+
+static void
+ottie_editor_window_class_init (OttieEditorWindowClass *class)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ object_class->finalize = ottie_editor_window_finalize;
+
+ g_type_ensure (OTTIE_TYPE_CREATION);
+ g_type_ensure (OTTIE_TYPE_PAINTABLE);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/org/gtk/gtk4/ottie-editor/ottie-editor-window.ui");
+
+ gtk_widget_class_bind_template_child (widget_class, OttieEditorWindow, creation);
+ gtk_widget_class_bind_template_child (widget_class, OttieEditorWindow, paintable);
+ gtk_widget_class_bind_template_child (widget_class, OttieEditorWindow, picture);
+ gtk_widget_class_bind_template_child (widget_class, OttieEditorWindow, listview);
+
+ 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, export_image_cb);
+ gtk_widget_class_bind_template_callback (widget_class, notify_prepared_cb);
+}
+
+static void
+window_open (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ OttieEditorWindow *self = user_data;
+
+ show_open_filechooser (self);
+}
+
+static GActionEntry win_entries[] = {
+ { "open", window_open, NULL, NULL, NULL },
+};
+
+static void
+ottie_editor_window_init (OttieEditorWindow *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ g_action_map_add_action_entries (G_ACTION_MAP (self), win_entries, G_N_ELEMENTS (win_entries), self);
+}
+
+OttieEditorWindow *
+ottie_editor_window_new (OttieEditorApplication *application)
+{
+ return g_object_new (OTTIE_EDITOR_WINDOW_TYPE,
+ "application", application,
+ NULL);
+}
diff --git a/ottie/editor/ottie-editor-window.h b/ottie/editor/ottie-editor-window.h
new file mode 100644
index 0000000000..b4d5e28299
--- /dev/null
+++ b/ottie/editor/ottie-editor-window.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2020 Benjamin Otte
+ *
+ * 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: Benjamin Otte <otte gnome org>
+ */
+
+#ifndef __OTTIE_EDITOR_WINDOW_H__
+#define __OTTIE_EDITOR_WINDOW_H__
+
+#include <gtk/gtk.h>
+
+#include "ottie-editor-application.h"
+
+#define OTTIE_EDITOR_WINDOW_TYPE (ottie_editor_window_get_type ())
+#define OTTIE_EDITOR_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OTTIE_EDITOR_WINDOW_TYPE,
OttieEditorWindow))
+
+
+typedef struct _OttieEditorWindow OttieEditorWindow;
+typedef struct _OttieEditorWindowClass OttieEditorWindowClass;
+
+
+GType ottie_editor_window_get_type (void);
+
+OttieEditorWindow * ottie_editor_window_new (OttieEditorApplication *application);
+
+void ottie_editor_window_load (OttieEditorWindow *self,
+ GFile *file);
+
+#endif /* __OTTIE_EDITOR_WINDOW_H__ */
diff --git a/ottie/editor/ottie-editor-window.ui b/ottie/editor/ottie-editor-window.ui
new file mode 100644
index 0000000000..33f1eef0a6
--- /dev/null
+++ b/ottie/editor/ottie-editor-window.ui
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <menu id="gear_menu">
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">_Help</attribute>
+ <attribute name="action">app.help</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">_Inspector</attribute>
+ <attribute name="action">app.inspector</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">_About Ottie Editor</attribute>
+ <attribute name="action">app.about</attribute>
+ </item>
+ </section>
+ </menu>
+
+ <object class="OttieCreation" id="creation">
+ <signal name="notify::prepared" handler="notify_prepared_cb"/>
+ </object>
+
+ <object class="OttiePaintable" id="paintable">
+ <property name="creation">creation</property>
+ </object>
+
+ <template class="OttieEditorWindow" parent="GtkApplicationWindow">
+ <property name="title" translatable="yes">Ottie Editor</property>
+ <property name="default-width">1024</property>
+ <property name="default-height">768</property>
+ <child type="titlebar">
+ <object class="GtkHeaderBar" id="header">
+ <child type="start">
+ <object class="GtkButton">
+ <property name="icon-name">document-open-symbolic</property>
+ <property name="tooltip-text">Open 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</property>
+ <signal name="clicked" handler="save_cb"/>
+ </object>
+ </child>
+ <child type="start">
+ <object class="GtkButton">
+ <property name="icon-name">insert-image-symbolic</property>
+ <property name="tooltip-text">Export to image</property>
+ <signal name="clicked" handler="export_image_cb"/>
+ </object>
+ </child>
+ <child type="end">
+ <object class="GtkMenuButton" id="gear_menu_button">
+ <property name="valign">center</property>
+ <property name="menu-model">gear_menu</property>
+ <property name="icon-name">open-menu-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkPaned">
+ <property name="shrink-end-child">false</property>
+ <property name="position">400</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="hexpand">1</property>
+ <property name="vexpand">1</property>
+ <child>
+ <object class="GtkListView" id="listview">
+ <property name="factory">
+ <object class="GtkBuilderListItemFactory">
+ <property name="bytes"><![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="GtkListItem">
+ <property name="child">
+ <object class="GtkTreeExpander" id="expander">
+ <binding name="list-row">
+ <lookup name="item">GtkListItem</lookup>
+ </binding>
+ <property name="child">
+ <object class="GtkLabel">
+ <property name="xalign">0</property>
+ <binding name="label">
+ <lookup name="name" type="OttieObject">
+ <lookup name="item">expander</lookup>
+ </lookup>
+ </binding>
+ </object>
+ </property>
+ </object>
+ </property>
+ </template>
+</interface>
+ ]]></property>
+ </object>
+ </property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="hexpand">1</property>
+ <property name="vexpand">1</property>
+ <property name="min-content-height">100</property>
+ <property name="min-content-width">100</property>
+ <child>
+ <object class="GtkViewport">
+ <child>
+ <object class="GtkPicture" id="picture">
+ <property name="can-shrink">0</property>
+ <property name="paintable">paintable</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/ottie/editor/ottie-editor.gresource.xml b/ottie/editor/ottie-editor.gresource.xml
new file mode 100644
index 0000000000..dde2a04f89
--- /dev/null
+++ b/ottie/editor/ottie-editor.gresource.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/org/gtk/gtk4/ottie-editor">
+ <file preprocess="xml-stripblanks">ottie-editor-window.ui</file>
+ </gresource>
+</gresources>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]