]> Pileus Git - ~andy/gtk/blob - perf/appwindow.c
Shut up CVS
[~andy/gtk] / perf / appwindow.c
1 /* This file contains utility functions to create what would be a typical "main
2  * window" for an application.
3  *
4  * TODO:
5  *
6  * Measurements happen from the start of the destruction of the last window.  Use
7  * GTimer rather than X timestamps to fix this (it uses gettimeofday() internally!)
8  *
9  * Make non-interactive as well by using the above.
10  *
11  */
12
13 #include <string.h>
14 #include <gtk/gtk.h>
15
16 static void
17 quit_cb (GtkWidget *widget, gpointer data)
18 {
19   gtk_main_quit ();
20 }
21
22 static void
23 noop_cb (GtkWidget *widget, gpointer data)
24 {
25   /* nothing */
26 }
27
28 static const GtkActionEntry menu_action_entries[] = {
29   { "FileMenu", NULL, "_File" },
30   { "EditMenu", NULL, "_Edit" },
31   { "ViewMenu", NULL, "_View" },
32   { "HelpMenu", NULL, "_Help" },
33
34   { "New", GTK_STOCK_NEW, "_New", "<control>N", "Create a new document", G_CALLBACK (noop_cb) },
35   { "Open", GTK_STOCK_OPEN, "_Open", "<control>O", "Open a file", G_CALLBACK (noop_cb) },
36   { "Save", GTK_STOCK_SAVE, "_Save", "<control>S", "Save the document", G_CALLBACK (noop_cb) },
37   { "SaveAs", GTK_STOCK_SAVE_AS, "Save _As...", NULL, "Save the document with a different name", NULL},
38   { "PrintPreview", GTK_STOCK_PRINT_PREVIEW, "Print Previe_w", NULL, "See how the document will be printed", G_CALLBACK (noop_cb) },
39   { "Print", GTK_STOCK_PRINT, "_Print", "<control>P", "Print the document", G_CALLBACK (noop_cb) },
40   { "Close", GTK_STOCK_CLOSE, "_Close", "<control>W", "Close the document", G_CALLBACK (noop_cb) },
41   { "Quit", GTK_STOCK_QUIT, "_Quit", "<control>Q", "Quit the program", G_CALLBACK (quit_cb) },
42
43   { "Undo", GTK_STOCK_UNDO, "_Undo", "<control>Z", "Undo the last action", G_CALLBACK (noop_cb) },
44   { "Redo", GTK_STOCK_REDO, "_Redo", "<control>Y", "Redo the last action", G_CALLBACK (noop_cb) },
45   { "Cut", GTK_STOCK_CUT, "Cu_t", "<control>X", "Cut the selection to the clipboard", G_CALLBACK (noop_cb) },
46   { "Copy", GTK_STOCK_COPY, "_Copy", "<control>C", "Copy the selection to the clipboard", G_CALLBACK (noop_cb) },
47   { "Paste", GTK_STOCK_PASTE, "_Paste", "<control>V", "Paste the contents of the clipboard", G_CALLBACK (noop_cb) },
48   { "Delete", GTK_STOCK_DELETE, "_Delete", "Delete", "Delete the selection", G_CALLBACK (noop_cb) },
49   { "SelectAll", NULL, "Select _All", "<control>A", "Select the whole document", G_CALLBACK (noop_cb) },
50   { "Preferences", GTK_STOCK_PREFERENCES, "Pr_eferences", NULL, "Configure the application", G_CALLBACK (noop_cb) },
51
52   { "ZoomFit", GTK_STOCK_ZOOM_FIT, "Zoom to _Fit", NULL, "Zoom the document to fit the window", G_CALLBACK (noop_cb) },
53   { "Zoom100", GTK_STOCK_ZOOM_100, "Zoom _1:1", NULL, "Zoom to 1:1 scale", G_CALLBACK (noop_cb) },
54   { "ZoomIn", GTK_STOCK_ZOOM_IN, "Zoom _In", NULL, "Zoom into the document", G_CALLBACK (noop_cb) },
55   { "ZoomOut", GTK_STOCK_ZOOM_OUT, "Zoom _Out", NULL, "Zoom away from the document", G_CALLBACK (noop_cb) },
56   { "FullScreen", GTK_STOCK_FULLSCREEN, "Full _Screen", "F11", "Use the whole screen to view the document", G_CALLBACK (noop_cb) },
57
58   { "HelpContents", GTK_STOCK_HELP, "_Contents", "F1", "Show the table of contents for the help system", G_CALLBACK (noop_cb) },
59   { "About", GTK_STOCK_ABOUT, "_About", NULL, "About this application", G_CALLBACK (noop_cb) }
60 };
61
62 static const char ui_description[] =
63 "<ui>"
64 "  <menubar name=\"MainMenu\">"
65 "    <menu action=\"FileMenu\">"
66 "      <menuitem action=\"New\"/>"
67 "      <menuitem action=\"Open\"/>"
68 "      <menuitem action=\"Save\"/>"
69 "      <menuitem action=\"SaveAs\"/>"
70 "      <separator/>"
71 "      <menuitem action=\"PrintPreview\"/>"
72 "      <menuitem action=\"Print\"/>"
73 "      <separator/>"
74 "      <menuitem action=\"Close\"/>"
75 "      <menuitem action=\"Quit\"/>"
76 "    </menu>"
77 "    <menu action=\"EditMenu\">"
78 "      <menuitem action=\"Undo\"/>"
79 "      <menuitem action=\"Redo\"/>"
80 "      <separator/>"
81 "      <menuitem action=\"Cut\"/>"
82 "      <menuitem action=\"Copy\"/>"
83 "      <menuitem action=\"Paste\"/>"
84 "      <menuitem action=\"Delete\"/>"
85 "      <separator/>"
86 "      <menuitem action=\"SelectAll\"/>"
87 "      <separator/>"
88 "      <menuitem action=\"Preferences\"/>"
89 "    </menu>"
90 "    <menu action=\"ViewMenu\">"
91 "      <menuitem action=\"ZoomFit\"/>"
92 "      <menuitem action=\"Zoom100\"/>"
93 "      <menuitem action=\"ZoomIn\"/>"
94 "      <menuitem action=\"ZoomOut\"/>"
95 "      <separator/>"
96 "      <menuitem action=\"FullScreen\"/>"
97 "    </menu>"
98 "    <menu action=\"HelpMenu\">"
99 "      <menuitem action=\"HelpContents\"/>"
100 "      <menuitem action=\"About\"/>"
101 "    </menu>"
102 "  </menubar>"
103 "  <toolbar name=\"MainToolbar\">"
104 "    <toolitem action=\"New\"/>"
105 "    <toolitem action=\"Open\"/>"
106 "    <toolitem action=\"Save\"/>"
107 "    <separator/>"
108 "    <toolitem action=\"Print\"/>"
109 "    <separator/>"
110 "    <toolitem action=\"Undo\"/>"
111 "    <toolitem action=\"Redo\"/>"
112 "    <separator/>"
113 "    <toolitem action=\"Cut\"/>"
114 "    <toolitem action=\"Copy\"/>"
115 "    <toolitem action=\"Paste\"/>"
116 "  </toolbar>"
117 "</ui>";
118
119 static GtkUIManager *
120 uimanager_new (void)
121 {
122   GtkUIManager *ui;
123   GtkActionGroup *action_group;
124   GError *error;
125
126   ui = gtk_ui_manager_new ();
127
128   action_group = gtk_action_group_new ("Actions");
129   gtk_action_group_add_actions (action_group, menu_action_entries, G_N_ELEMENTS (menu_action_entries), NULL);
130
131   gtk_ui_manager_insert_action_group (ui, action_group, 0);
132   g_object_unref (action_group);
133
134   error = NULL;
135   if (!gtk_ui_manager_add_ui_from_string (ui, ui_description, -1, &error))
136     g_error ("Could not parse the uimanager XML: %s", error->message);
137
138   return ui;
139 }
140
141 static GtkWidget *
142 menubar_new (GtkUIManager *ui)
143 {
144   return gtk_ui_manager_get_widget (ui, "/MainMenu");
145 }
146
147 static GtkWidget *
148 toolbar_new (GtkUIManager *ui)
149 {
150   return gtk_ui_manager_get_widget (ui, "/MainToolbar");
151 }
152
153 struct row_data {
154   char *stock_id;
155   char *text1;
156   char *text2;
157 };
158
159 static struct row_data row_data[] = {
160   { GTK_STOCK_NEW,              "First",                "Here bygynneth the Book of the tales of Caunterbury." },
161   { GTK_STOCK_OPEN,             "Second",               "Whan that Aprille, with hise shoures soote," },
162   { GTK_STOCK_ABOUT,            "Third",                "The droghte of March hath perced to the roote" },
163   { GTK_STOCK_ADD,              "Fourth",               "And bathed every veyne in swich licour," },
164   { GTK_STOCK_APPLY,            "Fifth",                "Of which vertu engendred is the flour;" },
165   { GTK_STOCK_BOLD,             "Sixth",                "Whan Zephirus eek with his swete breeth" },
166   { GTK_STOCK_CANCEL,           "Seventh",              "Inspired hath in every holt and heeth" },
167   { GTK_STOCK_CDROM,            "Eighth",               "The tendre croppes, and the yonge sonne" },
168   { GTK_STOCK_CLEAR,            "Ninth",                "Hath in the Ram his halfe cours yronne," },
169   { GTK_STOCK_CLOSE,            "Tenth",                "And smale foweles maken melodye," },
170   { GTK_STOCK_COLOR_PICKER,     "Eleventh",             "That slepen al the nyght with open eye-" },
171   { GTK_STOCK_CONVERT,          "Twelfth",              "So priketh hem Nature in hir corages-" },
172   { GTK_STOCK_CONNECT,          "Thirteenth",           "Thanne longen folk to goon on pilgrimages" },
173   { GTK_STOCK_COPY,             "Fourteenth",           "And palmeres for to seken straunge strondes" },
174   { GTK_STOCK_CUT,              "Fifteenth",            "To ferne halwes, kowthe in sondry londes;" },
175   { GTK_STOCK_DELETE,           "Sixteenth",            "And specially, from every shires ende" },
176   { GTK_STOCK_DIRECTORY,        "Seventeenth",          "Of Engelond, to Caunturbury they wende," },
177   { GTK_STOCK_DISCONNECT,       "Eighteenth",           "The hooly blisful martir for the seke" },
178   { GTK_STOCK_EDIT,             "Nineteenth",           "That hem hath holpen, whan that they were seeke." },
179   { GTK_STOCK_EXECUTE,          "Twentieth",            "Bifil that in that seson, on a day," },
180   { GTK_STOCK_FILE,             "Twenty-first",         "In Southwerk at the Tabard as I lay," },
181   { GTK_STOCK_FIND,             "Twenty-second",        "Redy to wenden on my pilgrymage" },
182   { GTK_STOCK_FIND_AND_REPLACE, "Twenty-third",         "To Caunterbury, with ful devout corage," },
183   { GTK_STOCK_FLOPPY,           "Twenty-fourth",        "At nyght were come into that hostelrye" },
184   { GTK_STOCK_FULLSCREEN,       "Twenty-fifth",         "Wel nyne and twenty in a compaignye" },
185   { GTK_STOCK_GOTO_BOTTOM,      "Twenty-sixth",         "Of sondry folk, by aventure yfalle" },
186 };
187
188 static GtkTreeModel *
189 tree_model_new (void)
190 {
191   GtkListStore *list;
192   int i;
193
194   list = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
195
196   for (i = 0; i < G_N_ELEMENTS (row_data); i++)
197     {
198       GtkTreeIter iter;
199
200       gtk_list_store_append (list, &iter);
201       gtk_list_store_set (list,
202                           &iter,
203                           0, row_data[i].stock_id,
204                           1, row_data[i].text1,
205                           2, row_data[i].text2,
206                           -1);
207     }
208
209   return GTK_TREE_MODEL (list);
210 }
211
212 static GtkWidget *
213 tree_view_new (void)
214 {
215   GtkWidget *sw;
216   GtkWidget *tree;
217   GtkTreeModel *model;
218   GtkTreeViewColumn *column;
219
220   sw = gtk_scrolled_window_new (NULL, NULL);
221
222   model = tree_model_new ();
223   tree = gtk_tree_view_new_with_model (model);
224   g_object_unref (model);
225
226   gtk_widget_set_size_request (tree, 300, 100);
227
228   column = gtk_tree_view_column_new_with_attributes ("Icon",
229                                                      gtk_cell_renderer_pixbuf_new (),
230                                                      "stock-id", 0,
231                                                      NULL);
232   gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
233
234   column = gtk_tree_view_column_new_with_attributes ("Index",
235                                                      gtk_cell_renderer_text_new (),
236                                                      "text", 1,
237                                                      NULL);
238   gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
239
240   column = gtk_tree_view_column_new_with_attributes ("Canterbury Tales",
241                                                      gtk_cell_renderer_text_new (),
242                                                      "text", 2,
243                                                      NULL);
244   gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
245
246   gtk_container_add (GTK_CONTAINER (sw), tree);
247
248   return sw;
249 }
250
251 static GtkWidget *
252 left_pane_new (void)
253 {
254   return tree_view_new ();
255 }
256
257 static GtkWidget *
258 text_view_new (void)
259 {
260   GtkWidget *sw;
261   GtkWidget *text_view;
262   GtkTextBuffer *buffer;
263
264   sw = gtk_scrolled_window_new (NULL, NULL);
265
266   text_view = gtk_text_view_new ();
267   gtk_widget_set_size_request (text_view, 400, 300);
268   gtk_container_add (GTK_CONTAINER (sw), text_view);
269
270   buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
271
272   gtk_text_buffer_set_text (buffer,
273                             "In felaweshipe, and pilgrimes were they alle,\n"
274                             "That toward Caunterbury wolden ryde.\n"
275                             "The chambres and the stables weren wyde,\n"
276                             "And wel we weren esed atte beste;\n"
277                             "And shortly, whan the sonne was to reste,\n"
278                             "\n"
279                             "So hadde I spoken with hem everychon \n"
280                             "That I was of hir felaweshipe anon, \n"
281                             "And made forward erly for to ryse \n"
282                             "To take our wey, ther as I yow devyse. \n"
283                             "   But nathelees, whil I have tyme and space, \n"
284                             " \n"
285                             "Er that I ferther in this tale pace, \n"
286                             "Me thynketh it acordaunt to resoun \n"
287                             "To telle yow al the condicioun \n"
288                             "Of ech of hem, so as it semed me, \n"
289                             "And whiche they weren, and of what degree, \n"
290                             " \n"
291                             "And eek in what array that they were inne; \n"
292                             "And at a knyght than wol I first bigynne. \n"
293                             "   A knyght ther was, and that a worthy man, \n"
294                             "That fro the tyme that he first bigan \n"
295                             "To riden out, he loved chivalrie, \n"
296                             " \n"
297                             "Trouthe and honour, fredom and curteisie. \n"
298                             "Ful worthy was he in his lordes werre, \n"
299                             " \n"
300                             "And therto hadde he riden, no man ferre, \n"
301                             "As wel in Cristendom as in Hethenesse, \n"
302                             "And evere honoured for his worthynesse. \n"
303                             " \n"
304                             "   At Alisaundre he was, whan it was wonne; \n"
305                             "Ful ofte tyme he hadde the bord bigonne \n"
306                             "Aboven alle nacions in Pruce; \n"
307                             "In Lettow hadde he reysed, and in Ruce, \n"
308                             "No cristen man so ofte of his degree. \n",
309                             -1);
310
311   return sw;
312 }
313
314 static GtkWidget *
315 upper_right_new (void)
316 {
317   GtkWidget *notebook;
318
319   notebook = gtk_notebook_new ();
320
321   gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
322                             text_view_new (),
323                             gtk_label_new ("First"));
324
325   gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
326                             text_view_new (),
327                             gtk_label_new ("Second"));
328
329   gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
330                             text_view_new (),
331                             gtk_label_new ("Third"));
332
333   return notebook;
334 }
335
336 static GtkWidget *
337 lower_right_new (void)
338 {
339   return tree_view_new ();
340 }
341
342 static GtkWidget *
343 right_pane_new (void)
344 {
345   GtkWidget *paned;
346   GtkWidget *upper_right;
347   GtkWidget *lower_right;
348
349   paned = gtk_vpaned_new ();
350
351   upper_right = upper_right_new ();
352   gtk_paned_pack1 (GTK_PANED (paned), upper_right, TRUE, TRUE);
353
354   lower_right = lower_right_new ();
355   gtk_paned_pack2 (GTK_PANED (paned), lower_right, TRUE, TRUE);
356
357   return paned;
358 }
359
360 static GtkWidget *
361 content_area_new (void)
362 {
363   GtkWidget *hpaned;
364   GtkWidget *left, *right;
365
366   hpaned = gtk_hpaned_new ();
367
368   left = left_pane_new ();
369   gtk_paned_pack1 (GTK_PANED (hpaned), left, TRUE, TRUE);
370
371   right = right_pane_new ();
372   gtk_paned_pack2 (GTK_PANED (hpaned), right, TRUE, TRUE);
373
374   return hpaned;
375 }
376
377 static GtkWidget *
378 status_bar_new (void)
379 {
380   return gtk_statusbar_new ();
381 }
382
383 static gboolean
384 delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
385 {
386   gtk_main_quit ();
387   return FALSE;
388 }
389
390 GtkWidget *
391 appwindow_new (void)
392 {
393   GtkWidget *window;
394   GtkUIManager *ui;
395   GtkWidget *vbox;
396   GtkWidget *widget;
397
398   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
399   gtk_window_set_title (GTK_WINDOW (window), "Main window");
400   g_signal_connect (window, "delete-event",
401                     G_CALLBACK (delete_event_cb), NULL);
402
403   ui = uimanager_new ();
404   g_signal_connect_swapped (window, "destroy",
405                             G_CALLBACK (g_object_unref), ui);
406
407   vbox = gtk_vbox_new (FALSE, 0);
408   gtk_container_add (GTK_CONTAINER (window), vbox);
409
410   widget = menubar_new (ui);
411   gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
412
413   widget = toolbar_new (ui);
414   gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
415
416   widget = content_area_new ();
417   gtk_box_pack_start (GTK_BOX (vbox), widget, TRUE, TRUE, 0);
418
419   widget = status_bar_new ();
420   gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
421
422   return window;
423 }