]> Pileus Git - ~andy/gtk/blob - examples/bloatpad.c
bloatpad: Add an example app menu
[~andy/gtk] / examples / bloatpad.c
1 #include <stdlib.h>
2 #include <gtk/gtk.h>
3
4 static void
5 clicked (GtkButton *button, GtkMenu *menu)
6 {
7   gtk_menu_popup (menu, NULL, NULL, NULL, NULL, 0, 0);
8 }
9
10 static void
11 new_window (GApplication *app,
12             GFile        *file)
13 {
14   GtkWidget *window, *grid, *scrolled, *view;
15   GtkMenu *menu;
16
17   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
18   gtk_window_set_application (GTK_WINDOW (window), GTK_APPLICATION (app));
19   gtk_window_set_title (GTK_WINDOW (window), "Bloatpad");
20
21   grid = gtk_grid_new ();
22   gtk_container_add (GTK_CONTAINER (window), grid);
23
24   menu = gtk_application_get_menu (GTK_APPLICATION (app));
25   if (menu != NULL)
26     {
27       GtkWidget *button;
28
29       button = gtk_button_new ();
30       gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_icon_name ("help-about", GTK_ICON_SIZE_MENU));
31       gtk_widget_set_halign (button, GTK_ALIGN_START);
32       gtk_grid_attach (GTK_GRID (grid), button, 0, 0, 1, 1);
33       g_signal_connect (button, "clicked", G_CALLBACK (clicked), menu);
34     }
35
36   scrolled = gtk_scrolled_window_new (NULL, NULL);
37   gtk_widget_set_hexpand (scrolled, TRUE);
38   gtk_widget_set_vexpand (scrolled, TRUE);
39   view = gtk_text_view_new ();
40
41   gtk_container_add (GTK_CONTAINER (scrolled), view);
42
43   gtk_grid_attach (GTK_GRID (grid), scrolled, 0, 1, 1, 1);
44
45   if (file != NULL)
46     {
47       gchar *contents;
48       gsize length;
49
50       if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
51         {
52           GtkTextBuffer *buffer;
53
54           buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
55           gtk_text_buffer_set_text (buffer, contents, length);
56           g_free (contents);
57         }
58     }
59
60   gtk_widget_show_all (GTK_WIDGET (window));
61 }
62
63 static void
64 bloat_pad_activate (GApplication *application)
65 {
66   new_window (application, NULL);
67 }
68
69 static void
70 bloat_pad_open (GApplication  *application,
71                 GFile        **files,
72                 gint           n_files,
73                 const gchar   *hint)
74 {
75   gint i;
76
77   for (i = 0; i < n_files; i++)
78     new_window (application, files[i]);
79 }
80
81 typedef GtkApplication BloatPad;
82 typedef GtkApplicationClass BloatPadClass;
83
84 G_DEFINE_TYPE (BloatPad, bloat_pad, GTK_TYPE_APPLICATION)
85
86 static void
87 bloat_pad_finalize (GObject *object)
88 {
89   G_OBJECT_CLASS (bloat_pad_parent_class)->finalize (object);
90 }
91
92 static void
93 show_help (GSimpleAction *action,
94            GVariant      *parameter,
95            gpointer       user_data)
96 {
97   g_print ("Want help, eh ?!\n");
98 }
99
100 static void
101 show_about (GSimpleAction *action,
102             GVariant      *parameter,
103             gpointer       user_data)
104 {
105   GList *list;
106   GtkWindow *win;
107
108   list = gtk_application_get_windows (GTK_APPLICATION (g_application_get_default ()));
109   win = list->data;
110
111   gtk_show_about_dialog (win,
112                          "program-name", "Bloatpad",
113                          "title", "About Bloatpad",
114                          "comments", "Not much to say, really.",
115                          NULL);
116 }
117
118 static void
119 quit_app (GSimpleAction *action,
120           GVariant      *parameter,
121           gpointer       user_data)
122 {
123   GList *list, *next;
124   GtkWindow *win;
125
126   g_print ("Going down...\n");
127
128   list = gtk_application_get_windows (GTK_APPLICATION (g_application_get_default ()));
129   while (list)
130     {
131       win = list->data;
132       next = list->next;
133
134       gtk_widget_destroy (GTK_WIDGET (win));
135
136       list = next;
137     }
138 }
139
140 static GSimpleActionGroup *actions = NULL;
141 static GMenu *menu = NULL;
142
143 static void
144 remove_action (GSimpleAction *action,
145                GVariant      *parameter,
146                gpointer       user_data)
147 {
148   GAction *add;
149
150   g_menu_remove (menu, g_menu_model_get_n_items (G_MENU_MODEL (menu)) - 1);
151   g_simple_action_set_enabled (action, FALSE);
152   add = g_simple_action_group_lookup (actions, "add");
153   g_simple_action_set_enabled (G_SIMPLE_ACTION (add), TRUE);
154 }
155
156 static void
157 add_action (GSimpleAction *action,
158             GVariant      *parameter,
159             gpointer       user_data)
160 {
161   GAction *remove;
162
163   g_menu_append (menu, "Remove", "remove");
164   g_simple_action_set_enabled (action, FALSE);
165   remove = g_simple_action_group_lookup (actions, "remove");
166   g_simple_action_set_enabled (G_SIMPLE_ACTION (remove), TRUE);
167 }
168
169 static GActionEntry entries[] = {
170   { "help", show_help, NULL, NULL, NULL },
171   { "about", show_about, NULL, NULL, NULL },
172   { "quit", quit_app, NULL, NULL, NULL },
173   { "add", add_action, NULL, NULL, NULL },
174   { "remove", remove_action, NULL, NULL, NULL }
175 };
176
177 static GActionGroup *
178 get_actions (void)
179 {
180   actions = g_simple_action_group_new ();
181   g_simple_action_group_add_entries (actions,
182                                      entries, G_N_ELEMENTS (entries),
183                                      NULL);
184
185   return G_ACTION_GROUP (actions);
186 }
187
188 static GMenuModel *
189 get_menu (void)
190 {
191   menu = g_menu_new ();
192   g_menu_append (menu, "Help", "help");
193   g_menu_append (menu, "About Bloatpad", "about");
194   g_menu_append (menu, "Quit", "quit");
195   g_menu_append (menu, "Add", "add");
196
197   return G_MENU_MODEL (menu);
198 }
199
200 static void
201 bloat_pad_init (BloatPad *app)
202 {
203   g_application_set_action_group (G_APPLICATION (app), get_actions ());
204   g_application_set_menu (G_APPLICATION (app), get_menu ());
205 }
206
207 static void
208 bloat_pad_class_init (BloatPadClass *class)
209 {
210   G_OBJECT_CLASS (class)->finalize= bloat_pad_finalize;
211
212   G_APPLICATION_CLASS (class)->activate = bloat_pad_activate;
213   G_APPLICATION_CLASS (class)->open = bloat_pad_open;
214 }
215
216 BloatPad *
217 bloat_pad_new (void)
218 {
219   g_type_init ();
220
221   return g_object_new (bloat_pad_get_type (),
222                        "application-id", "org.gtk.Test.bloatpad",
223                        "flags", G_APPLICATION_HANDLES_OPEN,
224                        NULL);
225 }
226
227 int
228 main (int argc, char **argv)
229 {
230   BloatPad *bloat_pad;
231   int status;
232
233   bloat_pad = bloat_pad_new ();
234   status = g_application_run (G_APPLICATION (bloat_pad), argc, argv);
235   g_object_unref (bloat_pad);
236
237   return status;
238 }