appwindow.inc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. (* Application main window
  2. *
  3. * Demonstrates a typical application window, with menubar, toolbar, statusbar.
  4. *)
  5. var
  6. appwindow_registered : gboolean;
  7. procedure menuitem_cb (callback_data : gpointer;
  8. callback_action : guint;
  9. widget : PGtkWidget);cdecl;
  10. var
  11. dialog : PGtkWidget;
  12. begin
  13. dialog := gtk_message_dialog_new (GTK_WINDOW (callback_data),
  14. GTK_DIALOG_DESTROY_WITH_PARENT,
  15. GTK_MESSAGE_INFO,
  16. GTK_BUTTONS_CLOSE,
  17. 'You selected or toggled the menu item: "%s"',
  18. [gtk_item_factory_path_from_widget (widget)]);
  19. // Close dialog on user response
  20. g_signal_connect (G_OBJECT (dialog),
  21. 'response',
  22. G_CALLBACK (@gtk_widget_destroy),
  23. NULL);
  24. gtk_widget_show (dialog);
  25. end;
  26. procedure toolbar_cb (button : PGtkWidget;
  27. data : gpointer); cdecl;
  28. var
  29. dialog: PGtkWidget;
  30. begin
  31. dialog := gtk_message_dialog_new (GTK_WINDOW (data),
  32. GTK_DIALOG_DESTROY_WITH_PARENT,
  33. GTK_MESSAGE_INFO,
  34. GTK_BUTTONS_CLOSE,
  35. 'You selected a toolbar button');
  36. (* Close dialog on user response *)
  37. g_signal_connect (G_OBJECT (dialog),
  38. 'response',
  39. G_CALLBACK (@gtk_widget_destroy),
  40. NULL);
  41. gtk_widget_show (dialog);
  42. end;
  43. const
  44. menu_items : array [1..18] of TGtkItemFactoryEntry = (
  45. ( path: '/_File'; accelerator: NULL; callback: nil;
  46. callback_action: 0; item_type : '<Branch>'; extra_data: NULL),
  47. ( path: '/File/_New'; accelerator: '<control>N' ; callback: TGtkItemfactoryCallback(@menuitem_cb);
  48. callback_action: 0; item_type : '<StockItem>'; extra_data: NULL{GTK_STOCK_NEW}),
  49. ( path: '/File/_Open'; accelerator: '<control>O' ; callback: TGtkItemfactoryCallback(@menuitem_cb);
  50. callback_action: 0; item_type : '<StockItem>'; extra_data: NULL {GTK_STOCK_OPEN}),
  51. ( path: '/File/_Save'; accelerator: '<control>S' ; callback: TGtkItemfactoryCallback(@menuitem_cb);
  52. callback_action: 0; item_type : '<StockItem>'; extra_data: NULL {GTK_STOCK_SAVE}),
  53. ( path: '/File/Save _As'; accelerator: NULL ; callback: TGtkItemfactoryCallback(@menuitem_cb);
  54. callback_action: 0; item_type : '<StockItem>'; extra_data: NULL {GTK_STOCK_SAVE_AS}),
  55. ( path: '/File/sep1'; accelerator: NULL; callback: TGtkItemfactoryCallback(@menuitem_cb);
  56. callback_action: 0; item_type : '<Separator>'; extra_data: NULL),
  57. ( path: '/File/_Quit'; accelerator: '<control>Q' ; callback: TGtkItemfactoryCallback(@menuitem_cb);
  58. callback_action: 0; item_type : '<StockItem>'; extra_data: NULL),
  59. ( path: '/Preferences'; accelerator: NULL ; callback: nil;
  60. callback_action: 0; item_type : '<Branch>'; extra_data: NULL),
  61. ( path: '/Preferences/_Color'; accelerator: NULL ; callback: nil;
  62. callback_action: 0; item_type : '<Branch>'; extra_data: NULL),
  63. ( path: '/Preferences/Color/_Red'; accelerator: NULL ; callback: TGtkItemfactoryCallback(@menuitem_cb);
  64. callback_action: 0; item_type : '<RadioItem>'; extra_data: NULL),
  65. ( path: '/Preferences/Color/_Green'; accelerator: NULL ; callback: TGtkItemfactoryCallback(@menuitem_cb);
  66. callback_action: 0; item_type : '/Preferences/Color/Red'; extra_data: NULL),
  67. ( path: '/Preferences/Color/_Blue'; accelerator: NULL ; callback: TGtkItemfactoryCallback(@menuitem_cb);
  68. callback_action: 0; item_type : '/Preferences/Color/Red'; extra_data: NULL),
  69. ( path: '/Preferences/_Shape'; accelerator: NULL ; callback: nil;
  70. callback_action: 0; item_type : '<Branch>'; extra_data: NULL),
  71. ( path: '/Preferences/Shape/_Square'; accelerator: NULL ; callback: TGtkItemfactoryCallback(@menuitem_cb);
  72. callback_action: 0; item_type : '<RadioItem>'; extra_data: NULL),
  73. ( path: '/Preferences/Shape/_Rectangle'; accelerator: NULL ; callback: TGtkItemfactoryCallback(@menuitem_cb);
  74. callback_action: 0; item_type : '/Preferences/Shape/Square'; extra_data: NULL),
  75. ( path: '/Preferences/Shape/_Oval'; accelerator: NULL ; callback: TGtkItemfactoryCallback(@menuitem_cb);
  76. callback_action: 0; item_type : '/Preferences/Shape/Rectangle'; extra_data: NULL),
  77. (* If you wanted this to be right justified you would use "<LastBranch>", not "<Branch>".
  78. * Right justified help menu items are generally considered a bad idea now days.
  79. *)
  80. ( path: '/_Help'; accelerator: NULL ; callback: nil;
  81. callback_action: 0; item_type : '<Branch>'; extra_data: NULL),
  82. ( path: '/Help/_About'; accelerator: NULL ; callback: nil;
  83. callback_action: 0; item_type : NULL; extra_data: NULL)
  84. );
  85. var
  86. application_window : PGtkWidget; // global variable (originally called window)
  87. (* This function registers our custom toolbar icons, so they can be themed.
  88. *
  89. * It's totally optional to do this, you could just manually insert icons
  90. * and have them not be themeable, especially if you never expect people
  91. * to theme your app.
  92. *)
  93. const
  94. items :array [1..1] of TGtkStockItem = (
  95. ( stock_id: 'demo-gtk-logo'; _label: '_GTK!';
  96. modifier: 0; keyval: 0; translation_domain : NULL)
  97. );
  98. procedure register_stock_icons;
  99. var
  100. pixbuf : PGdkPixbuf;
  101. factory : PGtkIconFactory;
  102. filename : pgchar;
  103. icon_set : PGtkIconSet;
  104. transparent : PGdkPixbuf;
  105. begin
  106. if not appwindow_registered then
  107. begin
  108. appwindow_registered := TRUE;
  109. (* Register our stock items *)
  110. gtk_stock_add (@items[1], high(items));
  111. (* Add our custom icon factory to the list of defaults *)
  112. factory := gtk_icon_factory_new ();
  113. gtk_icon_factory_add_default (factory);
  114. (* demo_find_file() looks in the the current directory first,
  115. * so you can run gtk-demo without installing GTK, then looks
  116. * in the location where the file is installed.
  117. *)
  118. pixbuf := NULL;
  119. filename := demo_find_file ('gtk-logo-rgb.gif', NULL);
  120. if filename <> NULL then begin
  121. pixbuf := gdk_pixbuf_new_from_file (filename, NULL);
  122. g_free (filename);
  123. end;
  124. (* Register icon to accompany stock item *)
  125. if pixbuf <> NULL then
  126. begin
  127. (* The gtk-logo-rgb icon has a white background, make it transparent *)
  128. transparent := gdk_pixbuf_add_alpha (pixbuf, TRUE, $ff, $ff, $ff);
  129. icon_set := gtk_icon_set_new_from_pixbuf (transparent);
  130. gtk_icon_factory_add (factory, 'demo-gtk-logo', icon_set);
  131. gtk_icon_set_unref (icon_set);
  132. g_object_unref (G_OBJECT (pixbuf));
  133. g_object_unref (G_OBJECT (transparent));
  134. end
  135. else
  136. g_warning ('failed to load GTK logo for toolbar');
  137. (* Drop our reference to the factory, GTK will hold a reference. *)
  138. g_object_unref (G_OBJECT (factory));
  139. end;
  140. end;
  141. procedure update_statusbar ( buffer : PGtkTextBuffer;
  142. statusbar : PGtkStatusbar);
  143. var
  144. msg : pgchar;
  145. row,
  146. col : gint;
  147. count : gint;
  148. iter : TGtkTextIter;
  149. begin
  150. gtk_statusbar_pop (statusbar, 0); (* clear any previous message, underflow is allowed *)
  151. count := gtk_text_buffer_get_char_count (buffer);
  152. gtk_text_buffer_get_iter_at_mark (buffer,
  153. @iter,
  154. gtk_text_buffer_get_insert (buffer));
  155. row := gtk_text_iter_get_line (@iter);
  156. col := gtk_text_iter_get_line_offset (@iter);
  157. msg := g_strdup_printf ('Cursor at row %d column %d - %d chars in document',
  158. [row, col, count]);
  159. gtk_statusbar_push (statusbar, 0, msg);
  160. g_free (msg);
  161. end;
  162. procedure mark_set_callback (buffer : PGtkTextBuffer;
  163. new_location : PGtkTextIter;
  164. mark : PGtkTextMark;
  165. data : gpointer); cdecl;
  166. begin
  167. update_statusbar (buffer, GTK_STATUSBAR (data));
  168. end;
  169. function do_appwindow : PGtkWidget;
  170. var
  171. table,
  172. toolbar,
  173. statusbar,
  174. contents,
  175. sw : PGtkWidget;
  176. buffer : PGtkTextBuffer;
  177. accel_group : PGtkAccelGroup;
  178. item_factory : PGtkItemFactory;
  179. begin
  180. if application_window = NULL then
  181. begin
  182. register_stock_icons ();
  183. (* Create the toplevel window
  184. *)
  185. application_window := gtk_window_new (GTK_WINDOW_TOPLEVEL);
  186. gtk_window_set_title (GTK_WINDOW (application_window ), 'Application Window');
  187. (* NULL window variable when window is closed *)
  188. g_signal_connect (G_OBJECT (application_window ), 'destroy',
  189. G_CALLBACK (@gtk_widget_destroyed),
  190. @application_window );
  191. table := gtk_table_new (1, 4, FALSE);
  192. gtk_container_add (GTK_CONTAINER (application_window ), table);
  193. (* Create the menubar
  194. *)
  195. accel_group := gtk_accel_group_new ();
  196. gtk_window_add_accel_group (GTK_WINDOW (application_window), accel_group);
  197. g_object_unref (accel_group);
  198. item_factory := gtk_item_factory_new (GTK_TYPE_MENU_BAR, '<main>', accel_group);
  199. (* Set up item factory to go away with the window *)
  200. g_object_ref (item_factory);
  201. gtk_object_sink (GTK_OBJECT (item_factory));
  202. g_object_set_data_full (G_OBJECT (application_window ),
  203. '<main>',
  204. item_factory,
  205. TGDestroyNotify (@g_object_unref));
  206. (* create menu items *)
  207. menu_items[2].extra_data:=PChar(GTK_STOCK_NEW);
  208. menu_items[3].extra_data:=PChar(GTK_STOCK_OPEN);
  209. menu_items[4].extra_data:=PChar(GTK_STOCK_SAVE);
  210. menu_items[5].extra_data:=PChar(GTK_STOCK_SAVE_AS);
  211. menu_items[7].extra_data:=PChar(GTK_STOCK_QUIT);
  212. gtk_item_factory_create_items (item_factory, high (menu_items),
  213. @menu_items[1], application_window );
  214. gtk_table_attach (GTK_TABLE (table),
  215. gtk_item_factory_get_widget (item_factory, '<main>'),
  216. (* X direction *) (* Y direction *)
  217. 0, 1, 0, 1,
  218. GTK_EXPAND or GTK_FILL, 0,
  219. 0, 0);
  220. (* Create the toolbar
  221. *)
  222. toolbar := gtk_toolbar_new ();
  223. gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
  224. GTK_STOCK_OPEN,
  225. 'This is a demo button with an ''open'' icon',
  226. NULL,
  227. G_CALLBACK (@toolbar_cb),
  228. application_window , (* user data for callback *)
  229. -1); (* -1 means "append" *)
  230. gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
  231. GTK_STOCK_QUIT,
  232. 'This is a demo button with a ''quit'' icon',
  233. NULL,
  234. G_CALLBACK (@toolbar_cb),
  235. application_window , (* user data for callback *)
  236. -1); (* -1 means "append" *)
  237. gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
  238. gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
  239. 'demo-gtk-logo',
  240. 'This is a demo button with a ''gtk'' icon',
  241. NULL,
  242. G_CALLBACK (@toolbar_cb),
  243. application_window , (* user data for callback *)
  244. -1); (* -1 means "append" *)
  245. gtk_table_attach (GTK_TABLE (table),
  246. toolbar,
  247. (* X direction *) (* Y direction *)
  248. 0, 1, 1, 2,
  249. GTK_EXPAND or GTK_FILL, 0,
  250. 0, 0);
  251. (* Create document
  252. *)
  253. sw := gtk_scrolled_window_new (NULL, NULL);
  254. gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
  255. GTK_POLICY_AUTOMATIC,
  256. GTK_POLICY_AUTOMATIC);
  257. gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
  258. GTK_SHADOW_IN);
  259. gtk_table_attach (GTK_TABLE (table),
  260. sw,
  261. (* X direction *) (* Y direction *)
  262. 0, 1, 2, 3,
  263. GTK_EXPAND or GTK_FILL, GTK_EXPAND or GTK_FILL,
  264. 0, 0);
  265. gtk_window_set_default_size (GTK_WINDOW (application_window ),
  266. 200, 200);
  267. contents := gtk_text_view_new ();
  268. gtk_container_add (GTK_CONTAINER (sw),
  269. contents);
  270. (* Create statusbar *)
  271. statusbar := gtk_statusbar_new ();
  272. gtk_table_attach (GTK_TABLE (table),
  273. statusbar,
  274. (* X direction *) (* Y direction *)
  275. 0, 1, 3, 4,
  276. GTK_EXPAND or GTK_FILL, 0,
  277. 0, 0);
  278. (* Show text widget info in the statusbar *)
  279. buffer := gtk_text_view_get_buffer (GTK_TEXT_VIEW (contents));
  280. g_signal_connect_object (buffer,
  281. 'changed',
  282. G_CALLBACK (@update_statusbar),
  283. statusbar,
  284. 0);
  285. g_signal_connect_object (buffer,
  286. 'mark_set', (* cursor moved *)
  287. G_CALLBACK (@mark_set_callback),
  288. statusbar,
  289. 0);
  290. update_statusbar (buffer, GTK_STATUSBAR (statusbar));
  291. end;
  292. if not (GTK_WIDGET_VISIBLE (application_window )) then
  293. gtk_widget_show_all (application_window )
  294. else begin
  295. gtk_widget_destroy (application_window);
  296. application_window := NULL;
  297. end;
  298. do_appwindow := application_window ;
  299. end;