]> Pileus Git - ~andy/gtk/blob - examples/bloatpad.c
Bloatpad: Add a View menu for fullscreen
[~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 change_fullscreen_state (GSimpleAction *action,
18                          GVariant      *state,
19                          gpointer       user_data)
20 {
21   if (g_variant_get_boolean (state))
22     gtk_window_fullscreen (user_data);
23   else
24     gtk_window_unfullscreen (user_data);
25
26   g_simple_action_set_state (action, state);
27 }
28
29 static GtkClipboard *
30 get_clipboard (GtkWidget *widget)
31 {
32   return gtk_widget_get_clipboard (widget, gdk_atom_intern_static_string ("CLIPBOARD"));
33 }
34
35 static void
36 window_copy (GSimpleAction *action,
37              GVariant      *parameter,
38              gpointer       user_data)
39 {
40   GtkWindow *window = GTK_WINDOW (user_data);
41   GtkTextView *text = g_object_get_data ((GObject*)window, "bloatpad-text");
42
43   gtk_text_buffer_copy_clipboard (gtk_text_view_get_buffer (text),
44                                   get_clipboard ((GtkWidget*) text));
45 }
46
47 static void
48 window_paste (GSimpleAction *action,
49               GVariant      *parameter,
50               gpointer       user_data)
51 {
52   GtkWindow *window = GTK_WINDOW (user_data);
53   GtkTextView *text = g_object_get_data ((GObject*)window, "bloatpad-text");
54   
55   gtk_text_buffer_paste_clipboard (gtk_text_view_get_buffer (text),
56                                    get_clipboard ((GtkWidget*) text),
57                                    NULL,
58                                    TRUE);
59
60 }
61
62 static GActionEntry win_entries[] = {
63   { "copy", window_copy, NULL, NULL, NULL },
64   { "paste", window_paste, NULL, NULL, NULL },
65   { "fullscreen", activate_toggle, NULL, "false", change_fullscreen_state }
66 };
67
68 static void
69 new_window (GApplication *app,
70             GFile        *file)
71 {
72   GtkWidget *window, *grid, *scrolled, *view;
73
74   window = gtk_application_window_new (GTK_APPLICATION (app));
75   gtk_window_set_default_size ((GtkWindow*)window, 640, 480);
76   g_action_map_add_action_entries (G_ACTION_MAP (window), win_entries, G_N_ELEMENTS (win_entries), window);
77   gtk_window_set_title (GTK_WINDOW (window), "Bloatpad");
78
79   grid = gtk_grid_new ();
80   gtk_container_add (GTK_CONTAINER (window), grid);
81
82   scrolled = gtk_scrolled_window_new (NULL, NULL);
83   gtk_widget_set_hexpand (scrolled, TRUE);
84   gtk_widget_set_vexpand (scrolled, TRUE);
85   view = gtk_text_view_new ();
86
87   g_object_set_data ((GObject*)window, "bloatpad-text", view);
88
89   gtk_container_add (GTK_CONTAINER (scrolled), view);
90
91   gtk_grid_attach (GTK_GRID (grid), scrolled, 0, 0, 1, 1);
92
93   if (file != NULL)
94     {
95       gchar *contents;
96       gsize length;
97
98       if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
99         {
100           GtkTextBuffer *buffer;
101
102           buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
103           gtk_text_buffer_set_text (buffer, contents, length);
104           g_free (contents);
105         }
106     }
107
108   gtk_widget_show_all (GTK_WIDGET (window));
109 }
110
111 static void
112 bloat_pad_activate (GApplication *application)
113 {
114   new_window (application, NULL);
115 }
116
117 static void
118 bloat_pad_open (GApplication  *application,
119                 GFile        **files,
120                 gint           n_files,
121                 const gchar   *hint)
122 {
123   gint i;
124
125   for (i = 0; i < n_files; i++)
126     new_window (application, files[i]);
127 }
128
129 typedef GtkApplication BloatPad;
130 typedef GtkApplicationClass BloatPadClass;
131
132 G_DEFINE_TYPE (BloatPad, bloat_pad, GTK_TYPE_APPLICATION)
133
134 static void
135 bloat_pad_finalize (GObject *object)
136 {
137   G_OBJECT_CLASS (bloat_pad_parent_class)->finalize (object);
138 }
139
140 static void
141 show_about (GSimpleAction *action,
142             GVariant      *parameter,
143             gpointer       user_data)
144 {
145   GtkWindow *window = user_data;
146
147   gtk_show_about_dialog (window,
148                          "program-name", "Bloatpad",
149                          "title", "About Bloatpad",
150                          "comments", "Not much to say, really.",
151                          NULL);
152 }
153
154
155 static void
156 quit_app (GSimpleAction *action,
157           GVariant      *parameter,
158           gpointer       user_data)
159 {
160   GList *list, *next;
161   GtkWindow *win;
162
163   g_print ("Going down...\n");
164
165   list = gtk_application_get_windows (GTK_APPLICATION (g_application_get_default ()));
166   while (list)
167     {
168       win = list->data;
169       next = list->next;
170
171       gtk_widget_destroy (GTK_WIDGET (win));
172
173       list = next;
174     }
175 }
176
177 static GActionEntry app_entries[] = {
178   { "about", show_about, NULL, NULL, NULL },
179   { "quit", quit_app, NULL, NULL, NULL },
180 };
181
182 static GActionGroup *
183 create_app_actions (void)
184 {
185   GSimpleActionGroup *actions = g_simple_action_group_new ();
186   g_simple_action_group_add_entries (actions,
187                                      app_entries, G_N_ELEMENTS (app_entries),
188                                      NULL);
189
190   return G_ACTION_GROUP (actions);
191 }
192
193 static GMenuModel *
194 create_app_menu (void)
195 {
196   GMenu *menu = g_menu_new ();
197   g_menu_append (menu, "_About Bloatpad", "app.about");
198   g_menu_append (menu, "_Quit", "app.quit");
199
200   return G_MENU_MODEL (menu);
201 }
202
203 static GMenuModel *
204 create_window_menu (void)
205 {
206   GMenu *menu;
207   GMenu *submenu;
208
209   submenu = g_menu_new ();
210   g_menu_append (submenu, "_Copy", "win.copy");
211   g_menu_append (submenu, "_Paste", "win.paste");
212
213   menu = g_menu_new ();
214   g_menu_append_submenu (menu, "_Edit", (GMenuModel*)submenu);
215   g_object_unref (submenu);
216
217   submenu = g_menu_new ();
218   g_menu_append (submenu, "_Fullscreen", "win.fullscreen");
219
220   g_menu_append_submenu (menu, "_View", (GMenuModel*)submenu);
221   g_object_unref (submenu);
222
223   return G_MENU_MODEL (menu);
224 }
225
226 static void
227 bloat_pad_init (BloatPad *app)
228 {
229   GActionGroup *actions;
230   GMenuModel *app_menu;
231   GMenuModel *window_menu;
232
233   actions = create_app_actions ();
234   g_application_set_action_group (G_APPLICATION (app), actions);
235   g_object_unref (actions);
236
237   app_menu = create_app_menu ();
238   g_application_set_app_menu (G_APPLICATION (app), app_menu);
239   g_object_unref (app_menu);
240
241   window_menu = create_window_menu ();
242   g_application_set_menubar (G_APPLICATION (app), window_menu);
243   g_object_unref (window_menu);
244 }
245
246 static void
247 bloat_pad_class_init (BloatPadClass *class)
248 {
249   G_OBJECT_CLASS (class)->finalize = bloat_pad_finalize;
250
251   G_APPLICATION_CLASS (class)->activate = bloat_pad_activate;
252   G_APPLICATION_CLASS (class)->open = bloat_pad_open;
253 }
254
255 BloatPad *
256 bloat_pad_new (void)
257 {
258   g_type_init ();
259
260   return g_object_new (bloat_pad_get_type (),
261                        "application-id", "org.gtk.Test.bloatpad",
262                        "flags", G_APPLICATION_HANDLES_OPEN,
263                        NULL);
264 }
265
266 int
267 main (int argc, char **argv)
268 {
269   BloatPad *bloat_pad;
270   int status;
271
272   bloat_pad = bloat_pad_new ();
273   status = g_application_run (G_APPLICATION (bloat_pad), argc, argv);
274   g_object_unref (bloat_pad);
275
276   return status;
277 }