]> Pileus Git - ~andy/gtk/blob - examples/bloatpad.c
Bloatpad: Set the application name
[~andy/gtk] / examples / bloatpad.c
1 #include <stdlib.h>
2 #include <gtk/gtk.h>
3
4 static void
5 activate_toggle (GSimpleAction *action,
6                  GVariant      *parameter,
7                  gpointer       user_data)
8 {
9   GVariant *state;
10
11   state = g_action_get_state (G_ACTION (action));
12   g_action_change_state (G_ACTION (action), g_variant_new_boolean (!g_variant_get_boolean (state)));
13   g_variant_unref (state);
14 }
15
16 static void
17 activate_radio (GSimpleAction *action,
18                 GVariant      *parameter,
19                 gpointer       user_data)
20 {
21   g_action_change_state (G_ACTION (action), parameter);
22 }
23
24 static void
25 change_fullscreen_state (GSimpleAction *action,
26                          GVariant      *state,
27                          gpointer       user_data)
28 {
29   if (g_variant_get_boolean (state))
30     gtk_window_fullscreen (user_data);
31   else
32     gtk_window_unfullscreen (user_data);
33
34   g_simple_action_set_state (action, state);
35 }
36
37 static void
38 change_justify_state (GSimpleAction *action,
39                       GVariant      *state,
40                       gpointer       user_data)
41 {
42   GtkTextView *text = g_object_get_data (user_data, "bloatpad-text");
43   const gchar *str;
44
45   str = g_variant_get_string (state, NULL);
46
47   if (g_str_equal (str, "left"))
48     gtk_text_view_set_justification (text, GTK_JUSTIFY_LEFT);
49   else if (g_str_equal (str, "center"))
50     gtk_text_view_set_justification (text, GTK_JUSTIFY_CENTER);
51   else if (g_str_equal (str, "right"))
52     gtk_text_view_set_justification (text, GTK_JUSTIFY_RIGHT);
53   else
54     /* ignore this attempted change */
55     return;
56
57   g_simple_action_set_state (action, state);
58 }
59
60 static GtkClipboard *
61 get_clipboard (GtkWidget *widget)
62 {
63   return gtk_widget_get_clipboard (widget, gdk_atom_intern_static_string ("CLIPBOARD"));
64 }
65
66 static void
67 window_copy (GSimpleAction *action,
68              GVariant      *parameter,
69              gpointer       user_data)
70 {
71   GtkWindow *window = GTK_WINDOW (user_data);
72   GtkTextView *text = g_object_get_data ((GObject*)window, "bloatpad-text");
73
74   gtk_text_buffer_copy_clipboard (gtk_text_view_get_buffer (text),
75                                   get_clipboard ((GtkWidget*) text));
76 }
77
78 static void
79 window_paste (GSimpleAction *action,
80               GVariant      *parameter,
81               gpointer       user_data)
82 {
83   GtkWindow *window = GTK_WINDOW (user_data);
84   GtkTextView *text = g_object_get_data ((GObject*)window, "bloatpad-text");
85   
86   gtk_text_buffer_paste_clipboard (gtk_text_view_get_buffer (text),
87                                    get_clipboard ((GtkWidget*) text),
88                                    NULL,
89                                    TRUE);
90
91 }
92
93 static GActionEntry win_entries[] = {
94   { "copy", window_copy, NULL, NULL, NULL },
95   { "paste", window_paste, NULL, NULL, NULL },
96   { "fullscreen", activate_toggle, NULL, "false", change_fullscreen_state },
97   { "justify", activate_radio, "s", "'left'", change_justify_state }
98 };
99
100 static void
101 new_window (GApplication *app,
102             GFile        *file)
103 {
104   GtkWidget *window, *grid, *scrolled, *view;
105   GtkWidget *toolbar;
106   GtkToolItem *button;
107   GtkWidget *sw, *box, *label;
108
109   window = gtk_application_window_new (GTK_APPLICATION (app));
110   gtk_window_set_default_size ((GtkWindow*)window, 640, 480);
111   g_action_map_add_action_entries (G_ACTION_MAP (window), win_entries, G_N_ELEMENTS (win_entries), window);
112   gtk_window_set_title (GTK_WINDOW (window), "Bloatpad");
113
114   grid = gtk_grid_new ();
115   gtk_container_add (GTK_CONTAINER (window), grid);
116
117   toolbar = gtk_toolbar_new ();
118   button = gtk_toggle_tool_button_new_from_stock (GTK_STOCK_JUSTIFY_LEFT);
119   gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.justify::left");
120   gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (button));
121
122   button = gtk_toggle_tool_button_new_from_stock (GTK_STOCK_JUSTIFY_CENTER);
123   gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.justify::center");
124   gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (button));
125
126   button = gtk_toggle_tool_button_new_from_stock (GTK_STOCK_JUSTIFY_RIGHT);
127   gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.justify::right");
128   gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (button));
129
130   button = gtk_separator_tool_item_new ();
131   gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (button), FALSE);
132   gtk_tool_item_set_expand (GTK_TOOL_ITEM (button), TRUE);
133   gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (button));
134
135   button = gtk_tool_item_new ();
136   box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
137   gtk_container_add (GTK_CONTAINER (button), box);
138   label = gtk_label_new ("Fullscreen:");
139   gtk_container_add (GTK_CONTAINER (box), label);
140   sw = gtk_switch_new ();
141   gtk_actionable_set_action_name (GTK_ACTIONABLE (sw), "win.fullscreen");
142   gtk_container_add (GTK_CONTAINER (box), sw);
143   gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (button));
144
145   gtk_grid_attach (GTK_GRID (grid), toolbar, 0, 0, 1, 1);
146
147   scrolled = gtk_scrolled_window_new (NULL, NULL);
148   gtk_widget_set_hexpand (scrolled, TRUE);
149   gtk_widget_set_vexpand (scrolled, TRUE);
150   view = gtk_text_view_new ();
151
152   g_object_set_data ((GObject*)window, "bloatpad-text", view);
153
154   gtk_container_add (GTK_CONTAINER (scrolled), view);
155
156   gtk_grid_attach (GTK_GRID (grid), scrolled, 0, 1, 1, 1);
157
158   if (file != NULL)
159     {
160       gchar *contents;
161       gsize length;
162
163       if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
164         {
165           GtkTextBuffer *buffer;
166
167           buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
168           gtk_text_buffer_set_text (buffer, contents, length);
169           g_free (contents);
170         }
171     }
172
173   gtk_widget_show_all (GTK_WIDGET (window));
174 }
175
176 static void
177 bloat_pad_activate (GApplication *application)
178 {
179   new_window (application, NULL);
180 }
181
182 static void
183 bloat_pad_open (GApplication  *application,
184                 GFile        **files,
185                 gint           n_files,
186                 const gchar   *hint)
187 {
188   gint i;
189
190   for (i = 0; i < n_files; i++)
191     new_window (application, files[i]);
192 }
193
194 typedef GtkApplication BloatPad;
195 typedef GtkApplicationClass BloatPadClass;
196
197 G_DEFINE_TYPE (BloatPad, bloat_pad, GTK_TYPE_APPLICATION)
198
199 static void
200 bloat_pad_finalize (GObject *object)
201 {
202   G_OBJECT_CLASS (bloat_pad_parent_class)->finalize (object);
203 }
204
205 static void
206 new_activated (GSimpleAction *action,
207                GVariant      *parameter,
208                gpointer       user_data)
209 {
210   GApplication *app = user_data;
211
212   g_application_activate (app);
213 }
214
215 static void
216 about_activated (GSimpleAction *action,
217                  GVariant      *parameter,
218                  gpointer       user_data)
219 {
220   gtk_show_about_dialog (NULL,
221                          "program-name", "Bloatpad",
222                          "title", "About Bloatpad",
223                          "comments", "Not much to say, really.",
224                          NULL);
225 }
226
227 static void
228 quit_app (GtkApplication *app)
229 {
230   GList *list, *next;
231   GtkWindow *win;
232
233   g_print ("Going down...\n");
234
235   list = gtk_application_get_windows (app);
236   while (list)
237     {
238       win = list->data;
239       next = list->next;
240
241       gtk_widget_destroy (GTK_WIDGET (win));
242
243       list = next;
244     }
245 }
246
247 static void
248 quit_activated (GSimpleAction *action,
249                 GVariant      *parameter,
250                 gpointer       user_data)
251 {
252   GtkApplication *app = user_data;
253
254   quit_app (app);
255 }
256
257 static GActionEntry app_entries[] = {
258   { "new", new_activated, NULL, NULL, NULL },
259   { "about", about_activated, NULL, NULL, NULL },
260   { "quit", quit_activated, NULL, NULL, NULL },
261 };
262
263 static void
264 bloat_pad_startup (GApplication *application)
265 {
266   GtkBuilder *builder;
267
268   G_APPLICATION_CLASS (bloat_pad_parent_class)
269     ->startup (application);
270
271   g_action_map_add_action_entries (G_ACTION_MAP (application), app_entries, G_N_ELEMENTS (app_entries), application);
272
273   builder = gtk_builder_new ();
274   gtk_builder_add_from_string (builder,
275                                "<interface>"
276                                "  <menu id='app-menu'>"
277                                "    <section>"
278                                "      <item label='_New Window' action='app.new' accel='<Primary>n'/>"
279                                "    </section>"
280                                "    <section>"
281                                "      <item label='_About Bloatpad' action='app.about'/>"
282                                "    </section>"
283                                "    <section>"
284                                "      <item label='_Quit' action='app.quit' accel='<Primary>q'/>"
285                                "    </section>"
286                                "  </menu>"
287                                "  <menu id='menubar'>"
288                                "    <submenu label='_Edit'>"
289                                "      <section>"
290                                "        <item label='_Copy' action='win.copy' accel='<Primary>c'/>"
291                                "        <item label='_Paste' action='win.paste' accel='<Primary>v'/>"
292                                "      </section>"
293                                "    </submenu>"
294                                "    <submenu label='_View'>"
295                                "      <section>"
296                                "        <item label='_Fullscreen' action='win.fullscreen'/>"
297                                "      </section>"
298                                "    </submenu>"
299                                "  </menu>"
300                                "</interface>", -1, NULL);
301   gtk_application_set_app_menu (GTK_APPLICATION (application), G_MENU_MODEL (gtk_builder_get_object (builder, "app-menu")));
302   gtk_application_set_menubar (GTK_APPLICATION (application), G_MENU_MODEL (gtk_builder_get_object (builder, "menubar")));
303   g_object_unref (builder);
304 }
305
306 static void
307 bloat_pad_init (BloatPad *app)
308 {
309 }
310
311 static void
312 bloat_pad_class_init (BloatPadClass *class)
313 {
314   GApplicationClass *application_class = G_APPLICATION_CLASS (class);
315   GObjectClass *object_class = G_OBJECT_CLASS (class);
316
317   application_class->startup = bloat_pad_startup;
318   application_class->activate = bloat_pad_activate;
319   application_class->open = bloat_pad_open;
320
321   object_class->finalize = bloat_pad_finalize;
322
323 }
324
325 static void
326 quit_cb (GtkApplication *app)
327 {
328   g_print ("Session manager to us to quit\n");
329
330   quit_app (app);
331 }
332
333 BloatPad *
334 bloat_pad_new (void)
335 {
336   GtkApplication *bloat_pad;
337
338   g_type_init ();
339
340   g_set_application_name ("Bloatpad");
341
342   bloat_pad = g_object_new (bloat_pad_get_type (),
343                             "application-id", "org.gtk.Test.bloatpad",
344                             "flags", G_APPLICATION_HANDLES_OPEN,
345                             "inactivity-timeout", 30000,
346                             "register-session", TRUE,
347                             NULL);
348
349   g_signal_connect (bloat_pad, "quit", G_CALLBACK (quit_cb), NULL);
350
351   return bloat_pad;
352 }
353
354 int
355 main (int argc, char **argv)
356 {
357   BloatPad *bloat_pad;
358   int status;
359
360   bloat_pad = bloat_pad_new ();
361
362   gtk_application_add_accelerator (GTK_APPLICATION (bloat_pad),
363                                    "F11", "win.fullscreen", NULL);
364
365   status = g_application_run (G_APPLICATION (bloat_pad), argc, argv);
366
367   g_object_unref (bloat_pad);
368
369   return status;
370 }