From e9d01c1a63a7893bc1529608df1fb09c77aac6fc Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 26 Dec 2020 04:00:21 +0100 Subject: [PATCH] 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(+) create mode 100644 ottie/editor/main.c create mode 100644 ottie/editor/meson.build create mode 100644 ottie/editor/ottie-editor-application.c create mode 100644 ottie/editor/ottie-editor-application.h create mode 100644 ottie/editor/ottie-editor-window.c create mode 100644 ottie/editor/ottie-editor-window.h create mode 100644 ottie/editor/ottie-editor-window.ui create mode 100644 ottie/editor/ottie-editor.gresource.xml diff --git a/meson.build b/meson.build index a502ecff8d..8d56d8d066 100644 --- a/meson.build +++ b/meson.build @@ -682,6 +682,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 . + * + * Authors: Benjamin Otte + */ + +#include "config.h" + +#include + +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 . + * + * Authors: Benjamin Otte + */ + +#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] = { "Q", NULL }; + const char *open_accels[2] = { "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 . + * + * Authors: Benjamin Otte + */ + +#ifndef __OTTIE_EDITOR_APPLICATION_H__ +#define __OTTIE_EDITOR_APPLICATION_H__ + +#include + + +#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 . + * + * Authors: Benjamin Otte + */ + +#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 . + * + * Authors: Benjamin Otte + */ + +#ifndef __OTTIE_EDITOR_WINDOW_H__ +#define __OTTIE_EDITOR_WINDOW_H__ + +#include + +#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 @@ + + + +
+ + _Help + app.help + + + _Inspector + app.inspector + + + _About Ottie Editor + app.about + +
+
+ + + + + + + creation + + + +
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 @@ + + + + ottie-editor-window.ui + +