1 #include <gtk/gtk.h>
2 
3 
4 
5 /* Callback function for the "copy" action */
6 static void
copy_callback(GSimpleAction * simple,GVariant * parameter,gpointer user_data)7 copy_callback (GSimpleAction *simple,
8             GVariant      *parameter,
9             gpointer       user_data)
10 {
11    g_print ("\"Copy\" activated\n");
12 }
13 
14 
15 
16 /* Callback function for the "paste" action */
17 static void
paste_callback(GSimpleAction * simple,GVariant * parameter,gpointer user_data)18 paste_callback (GSimpleAction *simple,
19             GVariant      *parameter,
20             gpointer       user_data)
21 {
22    g_print ("\"Paste\" activated\n");
23 }
24 
25 
26 
27 /* Callback function for the "shape" action */
28 static void
shape_callback(GSimpleAction * simple,GVariant * parameter,gpointer user_data)29 shape_callback (GSimpleAction *simple,
30             GVariant      *parameter,
31             gpointer       user_data)
32 {
33    /* We first gather the value of the GVariant instance with a string type.
34     * The overall goal here is to see if shape is set to line, triangle, etc,
35     * and put that value within the variable "answer".
36     */
37    const gchar *answer = g_variant_get_string (parameter, NULL);
38    g_printf ("Shape is set to %s.\n", answer);
39    /* Note that we set the state of the action */
40    g_simple_action_set_state (simple, parameter);
41 }
42 
43 
44 
45 /* Callback function in which closes the about_dialog created below */
46 static void
on_close(GtkDialog * dialog,gint response_id,gpointer user_data)47 on_close (GtkDialog *dialog,
48           gint       response_id,
49           gpointer   user_data)
50 {
51   gtk_widget_destroy (GTK_WIDGET (dialog));
52 }
53 
54 
55 
56 /* Callback function for the about action (see aboutdialog.c example) */
57 static void
about_callback(GSimpleAction * simple,GVariant * parameter,gpointer user_data)58 about_callback (GSimpleAction *simple,
59             GVariant      *parameter,
60             gpointer       user_data)
61 {
62    GtkWidget *about_dialog;
63 
64    about_dialog = gtk_about_dialog_new ();
65 
66    const gchar *authors[] = {"GNOME Documentation Team", NULL};
67    const gchar *documenters[] = {"GNOME Documentation Team", NULL};
68 
69    /* Fill in the about_dialog with the desired information */
70    gtk_about_dialog_set_program_name (GTK_ABOUT_DIALOG (about_dialog), "AboutDialog Example");
71    gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG (about_dialog), "Copyright \xc2\xa9 2012 GNOME Documentation Team");
72    gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG (about_dialog), authors);
73    gtk_about_dialog_set_documenters (GTK_ABOUT_DIALOG (about_dialog), documenters);
74    gtk_about_dialog_set_website_label (GTK_ABOUT_DIALOG (about_dialog), "GNOME Developer Website");
75    gtk_about_dialog_set_website (GTK_ABOUT_DIALOG (about_dialog), "http://developer.gnome.org");
76 
77    /* The "response" signal is emitted when the dialog receives a delete event,
78     * therefore we connect that signal to the on_close callback function
79     * created above.
80     */
81    g_signal_connect (GTK_DIALOG (about_dialog), "response",
82                     G_CALLBACK (on_close), NULL);
83 
84    /* Show the about dialog */
85    gtk_widget_show (about_dialog);
86 }
87 
88 
89 
90 static void
activate(GtkApplication * app,gpointer user_data)91 activate (GtkApplication *app,
92           gpointer        user_data)
93 {
94   GtkWidget *window;
95 
96   GSimpleAction *copy_action;
97   GSimpleAction *paste_action;
98   GSimpleAction *shape_action;
99   GSimpleAction *about_action;
100 
101   /* Create a window with a title and a default size */
102   window = gtk_application_window_new (app);
103   gtk_window_set_title (GTK_WINDOW (window), "MenuBar Example");
104   gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
105 
106   /* Begin creating the "copy" action.
107    * Note that it is an action without a state.
108    */
109   copy_action = g_simple_action_new ("copy", NULL);
110   /* Connected to a callback function */
111   g_signal_connect (copy_action, "activate", G_CALLBACK (copy_callback),
112                     GTK_WINDOW (window));
113   /* Added to the window */
114   g_action_map_add_action (G_ACTION_MAP (window), G_ACTION (copy_action));
115 
116   /* Begin creating the "paste" action.
117    * Note that it is an action without a state.
118    */
119   paste_action = g_simple_action_new ("paste", NULL);
120   /* Connect the action to a callback function */
121   g_signal_connect (paste_action, "activate", G_CALLBACK (paste_callback),
122                     GTK_WINDOW (window));
123   /* Add it to the window */
124   g_action_map_add_action (G_ACTION_MAP (window), G_ACTION (paste_action));
125 
126   /* Begin creating the "shape" action.
127    * Note that it is an action with a state.
128    * First we state that the parameter type of the simple action is a string.
129    * When using g_variant_type_new, it is appropriate to free the return value
130    * once you're done with it.
131    */
132   GVariantType *type_string = g_variant_type_new ("s");
133   /* parameters for the g_simple_action_new_stateful are: (name, parameter type,
134    * initial state).
135    */
136   shape_action = g_simple_action_new_stateful ("shape", type_string,
137                                                g_variant_new_string ("line"));
138   /* Connect the action to a callback function */
139   g_signal_connect (shape_action, "activate", G_CALLBACK (shape_callback),
140                     GTK_WINDOW (window));
141   /* Add it to the window */
142   g_action_map_add_action (G_ACTION_MAP (window), G_ACTION (shape_action));
143   g_variant_type_free (type_string);
144 
145   /* Begin creating the "about" action.
146    * Note that it is an action without a state.
147    */
148   about_action = g_simple_action_new ("about", NULL);
149   /* Connect the action to a callback function */
150   g_signal_connect (about_action, "activate", G_CALLBACK (about_callback),
151                     GTK_WINDOW (window));
152   /* Add it to the window */
153   g_action_map_add_action (G_ACTION_MAP (window), G_ACTION (about_action));
154 
155   gtk_widget_show_all (window);
156 }
157 
158 
159 
160 /* Callback function for the "new" action */
161 static void
new_callback(GSimpleAction * simple,GVariant * parameter,gpointer user_data)162 new_callback (GSimpleAction *simple,
163          GVariant      *parameter,
164          gpointer       user_data)
165 {
166   g_print ("You clicked \"New\"\n");
167 }
168 
169 
170 
171 /* Callback function for the "quit" action */
172 static void
quit_callback(GSimpleAction * simple,GVariant * parameter,gpointer user_data)173 quit_callback (GSimpleAction *simple,
174          GVariant      *parameter,
175          gpointer       user_data)
176 {
177   GApplication *application = user_data;
178 
179   g_print ("You clicked \"Quit\"\n");
180   g_application_quit (application);
181 }
182 
183 
184 
185 /* Callback function for the "state" action */
186 static void
state_callback(GSimpleAction * simple,GVariant * parameter,gpointer user_data)187 state_callback (GSimpleAction *simple,
188          GVariant      *parameter,
189          gpointer       user_data)
190 {
191    /* The two possibilities in this case for the "answer" variable are either
192     * "on" or "off".
193     */
194    const gchar *answer = g_variant_get_string (parameter, NULL);
195    /* We print the information to the user */
196    g_printf ("State is set to %s.\n", answer);
197    /* Note that we set the state of the action */
198    g_simple_action_set_state (simple, parameter);
199 }
200 
201 
202 
203 /* Callback function for the "awesome" action */
204 static void
awesome_callback(GSimpleAction * simple,GVariant * parameter,gpointer user_data)205 awesome_callback (GSimpleAction *simple,
206          GVariant      *parameter,
207          gpointer       user_data)
208 {
209   GVariant *action_state = g_action_get_state (G_ACTION (simple));
210   gboolean active = g_variant_get_boolean (action_state);
211   GVariant *new_state = g_variant_new_boolean (!active);
212   /* Set the new state for the action.
213    * (Keeps track of whether it was last checked or unchecked).
214    */
215   g_simple_action_set_state (simple, new_state);
216 
217   if (active)
218      g_print ("You unchecked \"Awesome\"\n");
219   else
220      g_print ("You checked \"Awesome\"\n");
221 }
222 
223 
224 
225 /* Startup function for the menu we are creating in this sample */
226 static void
startup(GApplication * app,gpointer user_data)227 startup (GApplication *app,
228          gpointer      user_data)
229 {
230   /* Initialize variables */
231   GSimpleAction *new_action;
232   GSimpleAction *quit_action;
233   GSimpleAction *state_action;
234   GSimpleAction *awesome_action;
235 
236   GtkBuilder *builder;
237 
238   GError *error = NULL;
239 
240   /* Begin creating the "new" action.
241    * Note that it is an action without a state.
242    */
243   new_action = g_simple_action_new ("new", NULL);
244   g_signal_connect (new_action, "activate", G_CALLBACK (new_callback), app);
245   /* It is added to the overall application */
246   g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (new_action));
247 
248   /* Begin creating the "quit" action.
249    * Note that it is an action without a state.
250    */
251   quit_action = g_simple_action_new ("quit", NULL);
252   g_signal_connect (quit_action, "activate", G_CALLBACK (quit_callback), app);
253   /* It is added to the overall application */
254   g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (quit_action));
255 
256   /* Begin creating the "state" action.
257    * Note that it is an action with a state.
258    */
259   GVariantType *type_string2 = g_variant_type_new ("s");
260   state_action = g_simple_action_new_stateful ("state", type_string2,
261                                                g_variant_new_string ("off"));
262   g_signal_connect (state_action, "activate", G_CALLBACK (state_callback), app);
263   /* It is added to the overall application */
264   g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (state_action));
265   g_variant_type_free (type_string2);
266 
267   /* Begin creating the "awesome" action.
268    * Note that it is an action with a state.
269    */
270   awesome_action = g_simple_action_new_stateful ("awesome", NULL, g_variant_new_boolean (FALSE));
271   g_signal_connect (awesome_action, "activate", G_CALLBACK (awesome_callback), app);
272   /* It is added to the overall application */
273   g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (awesome_action));
274 
275   /* A builder to add the User Interface designed with GLADE to the grid: */
276   builder = gtk_builder_new ();
277   /* Get the file (if it is there):
278    * Note: you must make sure that the file is in the current directory for
279    * this to work. The function used here returns a non-null value within
280    * our variable "error" if an error is indeed found.
281    */
282   gtk_builder_add_from_file (builder, "menubar.ui", &error);
283   if (error != NULL) {
284      g_print ("%s\n", error->message);
285      g_error_free (error);
286   }
287 
288   /* Extract the menubar */
289   GObject *menubar = gtk_builder_get_object (builder, "menubar");
290   gtk_application_set_menubar (GTK_APPLICATION (app), G_MENU_MODEL (menubar));
291 
292   /* Extract the appmenu */
293   GObject *appmenu = gtk_builder_get_object (builder, "appmenu");
294   gtk_application_set_app_menu (GTK_APPLICATION (app), G_MENU_MODEL (appmenu));
295 }
296 
297 
298 
299 /* Startup function for the application */
300 int
main(int argc,char ** argv)301 main (int argc, char **argv)
302 {
303   GtkApplication *app;
304   int status;
305 
306   app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
307   g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
308   g_signal_connect (app, "startup", G_CALLBACK (startup), NULL);
309   status = g_application_run (G_APPLICATION (app), argc, argv);
310   g_object_unref (app);
311 
312   return status;
313 }
314