]> Pileus Git - ~andy/gtk/blob - demos/gtk-demo/appwindow.c
fixes to compile with G_DISABLE_COMPAT
[~andy/gtk] / demos / gtk-demo / appwindow.c
1 /* Application main window
2  *
3  * Demonstrates a typical application window, with menubar, toolbar, statusbar.
4  */
5
6 #include <gtk/gtk.h>
7
8 static GtkWidget *window = NULL;
9
10
11 static void
12 menuitem_cb (gpointer             callback_data,
13              guint                callback_action,
14              GtkWidget           *widget)
15 {
16   GtkWidget *dialog;
17   
18   dialog = gtk_message_dialog_new (GTK_WINDOW (callback_data),
19                                    GTK_DIALOG_DESTROY_WITH_PARENT,
20                                    GTK_MESSAGE_INFO,
21                                    GTK_BUTTONS_CLOSE,
22                                    "You selected or toggled the menu item: \"%s\"",
23                                     gtk_item_factory_path_from_widget (widget));
24
25   /* Close dialog on user response */
26   g_signal_connect (G_OBJECT (dialog),
27                     "response",
28                     G_CALLBACK (gtk_widget_destroy),
29                     NULL);
30   
31   gtk_widget_show (dialog);
32 }
33
34
35 static GtkItemFactoryEntry menu_items[] =
36 {
37   { "/_File",            NULL,         0,                     0, "<Branch>" },
38   { "/File/tearoff1",    NULL,         menuitem_cb,       0, "<Tearoff>" },
39   { "/File/_New",        "<control>N", menuitem_cb,       0, "<StockItem>", GTK_STOCK_NEW },
40   { "/File/_Open",       "<control>O", menuitem_cb,       0, "<StockItem>", GTK_STOCK_OPEN },
41   { "/File/_Save",       "<control>S", menuitem_cb,       0, "<StockItem>", GTK_STOCK_SAVE },
42   { "/File/Save _As...", NULL,         menuitem_cb,       0, "<StockItem>", GTK_STOCK_SAVE },
43   { "/File/sep1",        NULL,         menuitem_cb,       0, "<Separator>" },
44   { "/File/_Quit",       "<control>Q", menuitem_cb,       0, "<StockItem>", GTK_STOCK_QUIT },
45
46   { "/_Preferences",                    NULL, 0,               0, "<Branch>" },
47   { "/_Preferences/_Color",             NULL, 0,               0, "<Branch>" },
48   { "/_Preferences/Color/_Red",         NULL, menuitem_cb, 0, "<RadioItem>" },
49   { "/_Preferences/Color/_Green",       NULL, menuitem_cb, 0, "/Preferences/Color/Red" },
50   { "/_Preferences/Color/_Blue",        NULL, menuitem_cb, 0, "/Preferences/Color/Red" },
51   { "/_Preferences/_Shape",             NULL, 0,               0, "<Branch>" },
52   { "/_Preferences/Shape/_Square",      NULL, menuitem_cb, 0, "<RadioItem>" },
53   { "/_Preferences/Shape/_Rectangle",   NULL, menuitem_cb, 0, "/Preferences/Shape/Square" },
54   { "/_Preferences/Shape/_Oval",        NULL, menuitem_cb, 0, "/Preferences/Shape/Rectangle" },
55
56   { "/_Help",            NULL,         0,                     0, "<LastBranch>" },
57   { "/Help/_About",      NULL,         menuitem_cb,       0 },
58 };
59
60 static void
61 toolbar_cb (GtkWidget *button,
62             gpointer   data)
63 {
64   GtkWidget *dialog;
65   
66   dialog = gtk_message_dialog_new (GTK_WINDOW (data),
67                                    GTK_DIALOG_DESTROY_WITH_PARENT,
68                                    GTK_MESSAGE_INFO,
69                                    GTK_BUTTONS_CLOSE,
70                                    "You selected a toolbar button");
71
72   /* Close dialog on user response */
73   g_signal_connect (G_OBJECT (dialog),
74                     "response",
75                     G_CALLBACK (gtk_widget_destroy),
76                     NULL);
77   
78   gtk_widget_show (dialog);
79 }
80
81 /* This function registers our custom toolbar icons, so they can be themed.
82  *
83  * It's totally optional to do this, you could just manually insert icons
84  * and have them not be themeable, especially if you never expect people
85  * to theme your app.
86  */
87 static void
88 register_stock_icons (void)
89 {
90   static gboolean registered = FALSE;
91   
92   if (!registered)
93     {
94       GdkPixbuf *pixbuf;
95       GtkIconFactory *factory;
96
97       static GtkStockItem items[] = {
98         { "demo-gtk-logo",
99           "_GTK!",
100           0, 0, NULL }
101       };
102       
103       registered = TRUE;
104
105       /* Register our stock items */
106       gtk_stock_add (items, G_N_ELEMENTS (items));
107       
108       /* Add our custom icon factory to the list of defaults */
109       factory = gtk_icon_factory_new ();
110       gtk_icon_factory_add_default (factory);
111
112       /* Try current directory */
113       pixbuf = gdk_pixbuf_new_from_file ("./gtk-logo-rgb.gif", NULL);
114
115       /* Try install directory */
116       if (pixbuf == NULL)
117         pixbuf = gdk_pixbuf_new_from_file (DEMOCODEDIR"/gtk-logo-rgb.gif", NULL);
118
119       /* Register icon to accompany stock item */
120       if (pixbuf != NULL)
121         {
122           GtkIconSet *icon_set;
123           GdkPixbuf *transparent;
124
125           /* The gtk-logo-rgb icon has a white background, make it transparent */
126           transparent = gdk_pixbuf_add_alpha (pixbuf, TRUE, 0xff, 0xff, 0xff);
127           
128           icon_set = gtk_icon_set_new_from_pixbuf (transparent);
129           gtk_icon_factory_add (factory, "demo-gtk-logo", icon_set);
130           gtk_icon_set_unref (icon_set);
131           g_object_unref (G_OBJECT (pixbuf));
132           g_object_unref (G_OBJECT (transparent));
133         }
134       else
135         g_warning ("failed to load GTK logo for toolbar");
136       
137       /* Drop our reference to the factory, GTK will hold a reference. */
138       g_object_unref (G_OBJECT (factory));
139     }
140 }
141
142 static void
143 update_statusbar (GtkTextBuffer *buffer,
144                   GtkStatusbar  *statusbar)
145 {
146   gchar *msg;
147   gint row, col;
148   gint count;
149   GtkTextIter iter;
150   
151   gtk_statusbar_pop (statusbar, 0); /* clear any previous message, underflow is allowed */
152
153   count = gtk_text_buffer_get_char_count (buffer);
154
155   gtk_text_buffer_get_iter_at_mark (buffer,
156                                     &iter,
157                                     gtk_text_buffer_get_insert (buffer));
158
159   row = gtk_text_iter_get_line (&iter);
160   col = gtk_text_iter_get_line_offset (&iter);
161
162   msg = g_strdup_printf ("Cursor at row %d column %d - %d chars in document",
163                          row, col, count);
164
165   gtk_statusbar_push (statusbar, 0, msg);
166
167   g_free (msg);
168 }
169
170 static void
171 mark_set_callback (GtkTextBuffer     *buffer,
172                    const GtkTextIter *new_location,
173                    GtkTextMark       *mark,
174                    gpointer           data)
175 {
176   update_statusbar (buffer, GTK_STATUSBAR (data));
177 }
178
179 GtkWidget *
180 do_appwindow (void)
181 {  
182   if (!window)
183     {
184       GtkWidget *table;
185       GtkWidget *toolbar;
186       GtkWidget *statusbar;
187       GtkWidget *contents;
188       GtkWidget *sw;
189       GtkTextBuffer *buffer;
190       GtkAccelGroup *accel_group;      
191       GtkItemFactory *item_factory;
192
193       register_stock_icons ();
194       
195       /* Create the toplevel window
196        */
197       
198       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
199       gtk_window_set_title (GTK_WINDOW (window), "Application Window");
200
201       /* NULL window variable when window is closed */
202       g_signal_connect (G_OBJECT (window), "destroy",
203                         G_CALLBACK (gtk_widget_destroyed),
204                         &window);
205
206       table = gtk_table_new (1, 4, FALSE);
207       
208       gtk_container_add (GTK_CONTAINER (window), table);
209       
210       /* Create the menubar
211        */
212       
213       accel_group = gtk_accel_group_new ();
214       gtk_accel_group_attach (accel_group, GTK_OBJECT (window));
215       gtk_accel_group_unref (accel_group);
216       
217       item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", accel_group);
218
219       /* Set up item factory to go away with the window */
220       gtk_object_ref (GTK_OBJECT (item_factory));
221       gtk_object_sink (GTK_OBJECT (item_factory));
222       g_object_set_data_full (G_OBJECT (window),
223                               "<main>",
224                               item_factory,
225                               (GDestroyNotify) g_object_unref);
226
227       /* create menu items */
228       gtk_item_factory_create_items (item_factory, G_N_ELEMENTS (menu_items),
229                                      menu_items, window);
230
231       gtk_table_attach (GTK_TABLE (table),
232                         gtk_item_factory_get_widget (item_factory, "<main>"),
233                         /* X direction */          /* Y direction */
234                         0, 1,                      0, 1,
235                         GTK_EXPAND | GTK_FILL,     0,
236                         0,                         0);
237
238       /* Create the toolbar
239        */
240       toolbar = gtk_toolbar_new ();
241
242       gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
243                                 GTK_STOCK_OPEN,
244                                 "This is a demo button with an 'open' icon",
245                                 NULL,
246                                 G_CALLBACK (toolbar_cb),
247                                 window, /* user data for callback */
248                                 -1);  /* -1 means "append" */
249
250       gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
251                                 GTK_STOCK_QUIT,
252                                 "This is a demo button with a 'quit' icon",
253                                 NULL,
254                                 G_CALLBACK (toolbar_cb),
255                                 window, /* user data for callback */
256                                 -1);  /* -1 means "append" */
257
258       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
259
260       gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
261                                 "demo-gtk-logo",
262                                 "This is a demo button with a 'gtk' icon",
263                                 NULL,
264                                 G_CALLBACK (toolbar_cb),
265                                 window, /* user data for callback */
266                                 -1);  /* -1 means "append" */
267
268       gtk_table_attach (GTK_TABLE (table),
269                         toolbar,
270                         /* X direction */       /* Y direction */
271                         0, 1,                   1, 2,
272                         GTK_EXPAND | GTK_FILL,  0,
273                         0,                      0);
274
275       /* Create document
276        */
277
278       sw = gtk_scrolled_window_new (NULL, NULL);
279
280       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
281                                       GTK_POLICY_AUTOMATIC,
282                                       GTK_POLICY_AUTOMATIC);
283
284       gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
285                                            GTK_SHADOW_IN);
286       
287       gtk_table_attach (GTK_TABLE (table),
288                         sw,
289                         /* X direction */       /* Y direction */
290                         0, 1,                   2, 3,
291                         GTK_EXPAND | GTK_FILL,  GTK_EXPAND | GTK_FILL,
292                         0,                      0);
293
294       gtk_window_set_default_size (GTK_WINDOW (window),
295                                    200, 200);
296       
297       contents = gtk_text_view_new ();
298
299       gtk_container_add (GTK_CONTAINER (sw),
300                          contents);
301
302       /* Create statusbar */
303
304       statusbar = gtk_statusbar_new ();
305       gtk_table_attach (GTK_TABLE (table),
306                         statusbar,
307                         /* X direction */       /* Y direction */
308                         0, 1,                   3, 4,
309                         GTK_EXPAND | GTK_FILL,  0,
310                         0,                      0);
311
312       /* Show text widget info in the statusbar */
313       buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (contents));
314       
315       g_signal_connect (G_OBJECT (buffer),
316                         "changed",
317                         G_CALLBACK (update_statusbar),
318                         statusbar);
319
320       g_signal_connect (G_OBJECT (buffer),
321                         "mark_set", /* cursor moved */
322                         G_CALLBACK (mark_set_callback),
323                         statusbar);
324       
325       update_statusbar (buffer, GTK_STATUSBAR (statusbar));
326     }
327
328   if (!GTK_WIDGET_VISIBLE (window))
329     {
330       gtk_widget_show_all (window);
331     }
332   else
333     {    
334       gtk_widget_destroy (window);
335       window = NULL;
336     }
337
338   return window;
339 }
340