1 | /* |
2 | * Copyright © 2019 Benjamin Otte |
3 | * |
4 | * This library is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2.1 of the License, or (at your option) any later version. |
8 | * |
9 | * This library is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Lesser General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Lesser General Public |
15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
16 | * |
17 | * Authors: Benjamin Otte <otte@gnome.org> |
18 | */ |
19 | |
20 | #include "config.h" |
21 | |
22 | #include "node-editor-application.h" |
23 | |
24 | #include "node-editor-window.h" |
25 | |
26 | #include "demo_conf.h" |
27 | |
28 | static const char *css = |
29 | "textview.editor {" |
30 | " color: rgb(192, 197, 206);" |
31 | " caret-color: currentColor;" |
32 | "}" |
33 | "textview.editor > text {" |
34 | " background-color: rgb(43, 48, 59);" |
35 | "}" |
36 | ; |
37 | |
38 | struct _NodeEditorApplication |
39 | { |
40 | GtkApplication parent; |
41 | }; |
42 | |
43 | struct _NodeEditorApplicationClass |
44 | { |
45 | GtkApplicationClass parent_class; |
46 | }; |
47 | |
48 | G_DEFINE_TYPE(NodeEditorApplication, node_editor_application, GTK_TYPE_APPLICATION); |
49 | |
50 | static void |
51 | node_editor_application_init (NodeEditorApplication *app) |
52 | { |
53 | } |
54 | |
55 | static void |
56 | activate_about (GSimpleAction *action, |
57 | GVariant *parameter, |
58 | gpointer user_data) |
59 | { |
60 | GtkApplication *app = user_data; |
61 | char *version; |
62 | GString *s; |
63 | GskRenderer *gsk_renderer; |
64 | const char *renderer; |
65 | char *os_name; |
66 | char *os_version; |
67 | GtkWidget *dialog; |
68 | |
69 | os_name = g_get_os_info (G_OS_INFO_KEY_NAME); |
70 | os_version = g_get_os_info (G_OS_INFO_KEY_VERSION_ID); |
71 | s = g_string_new (init: "" ); |
72 | if (os_name && os_version) |
73 | g_string_append_printf (string: s, format: "OS\t%s %s\n\n" , os_name, os_version); |
74 | |
75 | g_string_append (string: s, val: "System libraries\n" ); |
76 | g_string_append_printf (string: s, format: "\tGLib\t%d.%d.%d\n" , |
77 | glib_major_version, |
78 | glib_minor_version, |
79 | glib_micro_version); |
80 | g_string_append_printf (string: s, format: "\tPango\t%s\n" , |
81 | pango_version_string ()); |
82 | g_string_append_printf (string: s, format: "\tGTK \t%d.%d.%d\n" , |
83 | gtk_get_major_version (), |
84 | gtk_get_minor_version (), |
85 | gtk_get_micro_version ()); |
86 | |
87 | gsk_renderer = gtk_native_get_renderer (self: GTK_NATIVE (ptr: gtk_application_get_active_window (application: app))); |
88 | if (strcmp (G_OBJECT_TYPE_NAME (gsk_renderer), s2: "GskVulkanRenderer" ) == 0) |
89 | renderer = "Vulkan" ; |
90 | else if (strcmp (G_OBJECT_TYPE_NAME (gsk_renderer), s2: "GskGLRenderer" ) == 0) |
91 | renderer = "OpenGL" ; |
92 | else if (strcmp (G_OBJECT_TYPE_NAME (gsk_renderer), s2: "GskCairoRenderer" ) == 0) |
93 | renderer = "Cairo" ; |
94 | else |
95 | renderer = "Unknown" ; |
96 | |
97 | g_string_append_printf (string: s, format: "\nRenderer\n\t%s" , renderer); |
98 | |
99 | version = g_strdup_printf (format: "%s%s%s\nRunning against GTK %d.%d.%d" , |
100 | PACKAGE_VERSION, |
101 | g_strcmp0 (str1: PROFILE, str2: "devel" ) == 0 ? "-" : "" , |
102 | g_strcmp0 (str1: PROFILE, str2: "devel" ) == 0 ? VCS_TAG : "" , |
103 | gtk_get_major_version (), |
104 | gtk_get_minor_version (), |
105 | gtk_get_micro_version ()); |
106 | |
107 | dialog = g_object_new (GTK_TYPE_ABOUT_DIALOG, |
108 | first_property_name: "transient-for" , gtk_application_get_active_window (application: app), |
109 | "program-name" , g_strcmp0 (str1: PROFILE, str2: "devel" ) == 0 |
110 | ? "GTK Node Editor (Development)" |
111 | : "GTK Node Editor" , |
112 | "version" , version, |
113 | "copyright" , "© 2019—2021 The GTK Team" , |
114 | "license-type" , GTK_LICENSE_LGPL_2_1, |
115 | "website" , "http://www.gtk.org" , |
116 | "comments" , "Program to test GTK rendering" , |
117 | "authors" , (const char *[]){ "Benjamin Otte" , "Timm Bäder" , NULL}, |
118 | "logo-icon-name" , "org.gtk.gtk4.NodeEditor" , |
119 | "title" , "About GTK Node Editor" , |
120 | "system-information" , s->str, |
121 | NULL); |
122 | gtk_about_dialog_add_credit_section (GTK_ABOUT_DIALOG (dialog), |
123 | section_name: "Artwork by" , people: (const char *[]) { "Jakub Steiner" , NULL }); |
124 | |
125 | gtk_window_present (GTK_WINDOW (dialog)); |
126 | |
127 | g_string_free (string: s, TRUE); |
128 | g_free (mem: version); |
129 | g_free (mem: os_name); |
130 | g_free (mem: os_version); |
131 | } |
132 | |
133 | static void |
134 | activate_quit (GSimpleAction *action, |
135 | GVariant *parameter, |
136 | gpointer data) |
137 | { |
138 | g_application_quit (G_APPLICATION (data)); |
139 | } |
140 | |
141 | static void |
142 | activate_inspector (GSimpleAction *action, |
143 | GVariant *parameter, |
144 | gpointer user_data) |
145 | { |
146 | gtk_window_set_interactive_debugging (TRUE); |
147 | } |
148 | |
149 | static void |
150 | activate_help (GSimpleAction *action, |
151 | GVariant *parameter, |
152 | gpointer user_data) |
153 | { |
154 | GtkBuilder *builder; |
155 | GtkWidget *window; |
156 | GtkTextBuffer *buffer; |
157 | GBytes *bytes; |
158 | const char *text; |
159 | gsize len; |
160 | |
161 | builder = gtk_builder_new (); |
162 | gtk_builder_add_from_resource (builder, resource_path: "/org/gtk/gtk4/node-editor/help-window.ui" , NULL); |
163 | window = GTK_WIDGET (gtk_builder_get_object (builder, "window" )); |
164 | buffer = GTK_TEXT_BUFFER (gtk_builder_get_object (builder, "buffer" )); |
165 | |
166 | bytes = g_resources_lookup_data (path: "/org/gtk/gtk4/node-editor/node-format.md" , |
167 | lookup_flags: G_RESOURCE_LOOKUP_FLAGS_NONE, |
168 | NULL); |
169 | text = g_bytes_get_data (bytes, size: &len); |
170 | gtk_text_buffer_set_text (buffer, text, len); |
171 | g_bytes_unref (bytes); |
172 | |
173 | gtk_window_present (GTK_WINDOW (window)); |
174 | g_object_unref (object: builder); |
175 | } |
176 | |
177 | static GActionEntry app_entries[] = |
178 | { |
179 | { "about" , activate_about, NULL, NULL, NULL }, |
180 | { "quit" , activate_quit, NULL, NULL, NULL }, |
181 | { "inspector" , activate_inspector, NULL, NULL, NULL }, |
182 | { "help" , activate_help, NULL, NULL, NULL }, |
183 | }; |
184 | |
185 | static void |
186 | node_editor_application_startup (GApplication *app) |
187 | { |
188 | const char *help_accels[2] = { "F1" , NULL }; |
189 | const char *quit_accels[2] = { "<Ctrl>Q" , NULL }; |
190 | const char *open_accels[2] = { "<Ctrl>O" , NULL }; |
191 | GtkCssProvider *provider; |
192 | |
193 | G_APPLICATION_CLASS (node_editor_application_parent_class)->startup (app); |
194 | |
195 | g_action_map_add_action_entries (G_ACTION_MAP (app), |
196 | entries: app_entries, G_N_ELEMENTS (app_entries), |
197 | user_data: app); |
198 | gtk_application_set_accels_for_action (GTK_APPLICATION (app), detailed_action_name: "app.help" , accels: help_accels); |
199 | gtk_application_set_accels_for_action (GTK_APPLICATION (app), detailed_action_name: "app.quit" , accels: quit_accels); |
200 | gtk_application_set_accels_for_action (GTK_APPLICATION (app), detailed_action_name: "win.open" , accels: open_accels); |
201 | |
202 | |
203 | provider = gtk_css_provider_new (); |
204 | gtk_css_provider_load_from_data (css_provider: provider, data: css, length: -1); |
205 | gtk_style_context_add_provider_for_display (display: gdk_display_get_default (), |
206 | GTK_STYLE_PROVIDER (provider), |
207 | GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); |
208 | } |
209 | |
210 | static void |
211 | node_editor_application_activate (GApplication *app) |
212 | { |
213 | NodeEditorWindow *win; |
214 | |
215 | win = node_editor_window_new (NODE_EDITOR_APPLICATION (app)); |
216 | |
217 | if (g_strcmp0 (str1: PROFILE, str2: "devel" ) == 0) |
218 | gtk_widget_add_css_class (GTK_WIDGET (win), css_class: "devel" ); |
219 | |
220 | gtk_window_present (GTK_WINDOW (win)); |
221 | } |
222 | |
223 | static void |
224 | node_editor_application_open (GApplication *app, |
225 | GFile **files, |
226 | int n_files, |
227 | const char *hint) |
228 | { |
229 | NodeEditorWindow *win; |
230 | int i; |
231 | |
232 | for (i = 0; i < n_files; i++) |
233 | { |
234 | win = node_editor_window_new (NODE_EDITOR_APPLICATION (app)); |
235 | node_editor_window_load (self: win, file: files[i]); |
236 | gtk_window_present (GTK_WINDOW (win)); |
237 | } |
238 | } |
239 | |
240 | static void |
241 | node_editor_application_class_init (NodeEditorApplicationClass *class) |
242 | { |
243 | GApplicationClass *application_class = G_APPLICATION_CLASS (class); |
244 | |
245 | application_class->startup = node_editor_application_startup; |
246 | application_class->activate = node_editor_application_activate; |
247 | application_class->open = node_editor_application_open; |
248 | } |
249 | |
250 | NodeEditorApplication * |
251 | node_editor_application_new (void) |
252 | { |
253 | return g_object_new (NODE_EDITOR_APPLICATION_TYPE, |
254 | first_property_name: "application-id" , "org.gtk.gtk4.NodeEditor" , |
255 | "flags" , G_APPLICATION_HANDLES_OPEN, |
256 | NULL); |
257 | } |
258 | |