toolbar.pp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. {
  2. Converted from C to Pascal by Artur Bac
  3. <[email protected]>
  4. Reda Poland
  5. }
  6. {$MODE objfpc}
  7. {$H+}
  8. {$S+}
  9. {$HINTS ON}
  10. {$ifdef win32}
  11. {$define extdecl := stdcall;}
  12. {$APPTYPE GUI}
  13. {$endif}
  14. {$ifdef Unix}
  15. {$define extdecl := cdecl;}
  16. {$endif}
  17. Program tool_bar;
  18. uses glib,gdk,gtk;
  19. Const
  20. //* XPM */
  21. gtk_xpm : array[0..44]of pgchar = (
  22. '32 39 5 1',
  23. '. c none',
  24. '+ c black',
  25. '@ c #3070E0',
  26. '# c #F05050',
  27. '$ c #35E035',
  28. '................+...............',
  29. '..............+++++.............',
  30. '............+++++@@++...........',
  31. '..........+++++@@@@@@++.........',
  32. '........++++@@@@@@@@@@++........',
  33. '......++++@@++++++++@@@++.......',
  34. '.....+++@@@+++++++++++@@@++.....',
  35. '...+++@@@@+++@@@@@@++++@@@@+....',
  36. '..+++@@@@+++@@@@@@@@+++@@@@@++..',
  37. '.++@@@@@@+++@@@@@@@@@@@@@@@@@@++',
  38. '.+#+@@@@@@++@@@@+++@@@@@@@@@@@@+',
  39. '.+##++@@@@+++@@@+++++@@@@@@@@$@.',
  40. '.+###++@@@@+++@@@+++@@@@@++$$$@.',
  41. '.+####+++@@@+++++++@@@@@+@$$$$@.',
  42. '.+#####+++@@@@+++@@@@++@$$$$$$+.',
  43. '.+######++++@@@@@@@++@$$$$$$$$+.',
  44. '.+#######+##+@@@@+++$$$$$$@@$$+.',
  45. '.+###+++##+##+@@++@$$$$$$++$$$+.',
  46. '.+###++++##+##+@@$$$$$$$@+@$$@+.',
  47. '.+###++++++#+++@$$@+@$$@++$$$@+.',
  48. '.+####+++++++#++$$@+@$$++$$$$+..',
  49. '.++####++++++#++$$@+@$++@$$$$+..',
  50. '.+#####+++++##++$$++@+++$$$$$+..',
  51. '.++####+++##+#++$$+++++@$$$$$+..',
  52. '.++####+++####++$$++++++@$$$@+..',
  53. '.+#####++#####++$$+++@++++@$@+..',
  54. '.+#####++#####++$$++@$$@+++$@@..',
  55. '.++####++#####++$$++$$$$$+@$@++.',
  56. '.++####++#####++$$++$$$$$$$$+++.',
  57. '.+++####+#####++$$++$$$$$$$@+++.',
  58. '..+++#########+@$$+@$$$$$$+++...',
  59. '...+++########+@$$$$$$$$@+++....',
  60. '.....+++######+@$$$$$$$+++......',
  61. '......+++#####+@$$$$$@++........',
  62. '.......+++####+@$$$$+++.........',
  63. '.........++###+$$$@++...........',
  64. '..........++##+$@+++............',
  65. '...........+++++++..............',
  66. '.............++++...............');
  67. { This function is connected to the Close button or
  68. closing the window from the WM }
  69. function BOOL_TO_GINT(data : boolean) : gint;
  70. Begin
  71. if data then
  72. BOOL_TO_GINT:=1
  73. else
  74. BOOL_TO_GINT:=0;
  75. end;
  76. function delete_event (widget : PGtkWidget ;
  77. event : PGdkEvent;
  78. data : gpointer) : boolean ; cdecl;
  79. Begin
  80. gtk_main_quit ();
  81. delete_event :=FALSE;
  82. end;
  83. {The above beginning seems for sure familiar to you if it's not your first GTK program.
  84. There is one additional thing though,
  85. we include a nice XPM picture to serve as an icon for all of the buttons.
  86. }
  87. Var
  88. close_button : PGtkWidget; { This button will emit signal to close application }
  89. tooltips_button : PGtkWidget; { to enable/disable tooltips }
  90. text_button : PGtkWidget;
  91. icon_button : PGtkWidget;
  92. both_button : PGtkWidget; { radio buttons for toolbar style }
  93. entry : PGtkWidget; { a text entry to show packing any widget into toolbar }
  94. //In fact not all of the above widgets are needed here,
  95. //but to make things clearer I put them all together.
  96. { that's easy... when one of the buttons is toggled, we just
  97. * check which one is active and set the style of the toolbar
  98. * accordingly
  99. * ATTENTION: our toolbar is passed as data to callback ! }
  100. Procedure radio_event (widget : PGTkWidget; data : gpointer); cdecl;
  101. Begin
  102. if (gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON (text_button))) then
  103. gtk_toolbar_set_style(GTK_TOOLBAR ( data ), GTK_TOOLBAR_TEXT)
  104. else begin
  105. if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (icon_button))) then
  106. gtk_toolbar_set_style(GTK_TOOLBAR ( data ), GTK_TOOLBAR_ICONS);
  107. if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (both_button))) then
  108. gtk_toolbar_set_style(GTK_TOOLBAR ( data ), GTK_TOOLBAR_BOTH);
  109. end;
  110. End;
  111. { even easier, just check given toggle button and enable/disable
  112. * tooltips }
  113. Procedure toggle_event (widget : PGtkWidget; data : gpointer); cdecl;
  114. Begin
  115. {Due to gtk specification
  116. void gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
  117. gboolean enable);
  118. In Pasal unit this functioni is implemented as
  119. procedure gtk_toolbar_set_tooltips (toolbar:PGtkToolbar;
  120. enable:gint);
  121. cdecl;external gtkdll name 'gtk_toolbar_set_tooltips';
  122. so we have to change boolean to gint with function BOOL_TO_GINT implemented
  123. on the top of source
  124. }
  125. gtk_toolbar_set_tooltips (GTK_TOOLBAR ( data ),
  126. BOOL_TO_GINT(
  127. gtk_toggle_button_get_active(
  128. GTK_TOGGLE_BUTTON (widget))));
  129. End;
  130. {The above are just two callback functions that will be called
  131. when one of the buttons on a toolbar is pressed.
  132. You should already be familiar with things like this if you've already used toggle buttons
  133. and radio buttons.
  134. }
  135. Var
  136. { Here is our main window (a dialog) and a handle for the handlebox }
  137. dialog : PGtkWidget;
  138. handlebox : PGtkWidget;
  139. { Ok, we need a toolbar, an icon with a mask (one for all of
  140. the buttons) and an icon widget to put this icon in (but
  141. we'll create a separate widget for each button) }
  142. toolbar : PGtkWidget;
  143. icon : PGdkPixmap;
  144. mask : PGdkBitmap;
  145. iconw : PGtkWidget;
  146. style : PGtkStyle;
  147. Begin
  148. { this is called in all GTK application. }
  149. gtk_set_locale (); //It important for apps taht use local language specific characters
  150. gtk_init (@argc, @argv);
  151. gtk_rc_init;
  152. { create a new window with a given title, and nice size }
  153. dialog := gtk_dialog_new ();
  154. gtk_window_set_title ( GTK_WINDOW ( dialog ) , 'GTKToolbar Tutorial');
  155. gtk_widget_set_usize( GTK_WIDGET ( dialog ) , 600 , 300 );
  156. set_allow_shrink(PGtkWindow(dialog)^,BM_ALLOW_SHRINK);
  157. { typically we quit if someone tries to close us }
  158. gtk_signal_connect ( GTK_OBJECT ( dialog ), 'delete_event',
  159. GTK_SIGNAL_FUNC ( @delete_event ), NULL);
  160. { we need to realize the window because we use pixmaps for
  161. * items on the toolbar in the context of it }
  162. gtk_widget_realize ( dialog );
  163. { to make it nice we'll put the toolbar into the handle box,
  164. * so that it can be detached from the main window }
  165. handlebox := gtk_handle_box_new ();
  166. gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG(dialog)^.vbox ),
  167. handlebox, FALSE, FALSE, 5 );
  168. {The above should be similar to any other GTK application.
  169. Just initialization of GTK, creating the window, etc.
  170. There is only one thing that probably needs some explanation:
  171. a handle box. A handle box is just another box that can be used to pack widgets in to.
  172. The difference between it and typical boxes is that it can be detached from
  173. a parent window (or, in fact, the handle box remains in the parent,
  174. but it is reduced to a very small rectangle, while all of its contents
  175. are reparented to a new freely floating window). It is usually nice
  176. to have a detachable toolbar, so these two widgets occur together quite often.
  177. toolbar will be horizontal, with both icons and text, and
  178. * with 5pxl spaces between items and finally,
  179. * we'll also put it into our handlebox }
  180. toolbar := gtk_toolbar_new ( GTK_ORIENTATION_HORIZONTAL,
  181. GTK_TOOLBAR_BOTH );
  182. gtk_container_set_border_width ( GTK_CONTAINER ( toolbar ) , 5 );
  183. gtk_toolbar_set_space_size ( GTK_TOOLBAR ( toolbar ), 5 );
  184. gtk_container_add ( GTK_CONTAINER ( handlebox ) , toolbar );
  185. { now we create icon with mask: we'll reuse it to create
  186. * icon widgets for toolbar items }
  187. style := gtk_widget_get_style( dialog );
  188. icon := gdk_pixmap_create_from_xpm_d ( dialog^.window, @mask,
  189. @style^.fg_gc, gtk_xpm );
  190. {Well, what we do above is just a straightforward initialization of the toolbar widget
  191. and creation of a GDK pixmap with its mask.
  192. If you want to know something more about using pixmaps,
  193. refer to GDK documentation or to the Pixmaps section earlier in this tutorial.}
  194. { our first item is <close> button }
  195. iconw := gtk_pixmap_new ( icon, mask ); { icon widget }
  196. close_button :=
  197. gtk_toolbar_append_item ( GTK_TOOLBAR (toolbar), { our toolbar }
  198. 'Close', { button label }
  199. 'Closes this app', { this button's tooltip }
  200. 'Private', { tooltip private info }
  201. iconw, { icon widget }
  202. GTK_SIGNAL_FUNC (@delete_event), { a signal }
  203. NULL );
  204. gtk_toolbar_append_space ( GTK_TOOLBAR ( toolbar ) ); { space after item }
  205. {In the above code you see the simplest case: adding a button to toolbar.
  206. Just before appending a new item, we have to construct a pixmap widget
  207. to serve as an icon for this item; this step will have to be repeated for each new item.
  208. Just after the item we also add a space, so the following items will not touch each other.
  209. As you see gtk_toolbar_append_item returns a pointer to our newly created button widget,
  210. so that we can work with it in the normal way.}
  211. { now, let's make our radio buttons group... }
  212. iconw := gtk_pixmap_new ( icon, mask );
  213. icon_button := gtk_toolbar_append_element(
  214. GTK_TOOLBAR(toolbar),
  215. GTK_TOOLBAR_CHILD_RADIOBUTTON, { a type of element }
  216. NULL, { pointer to widget }
  217. 'Icon', { label }
  218. 'Only icons in toolbar', { tooltip }
  219. 'Private', { tooltip private string }
  220. iconw, { icon }
  221. GTK_SIGNAL_FUNC (@radio_event), { signal }
  222. toolbar); { data for signal }
  223. gtk_toolbar_append_space ( GTK_TOOLBAR ( toolbar ) );
  224. {Here we begin creating a radio buttons group.
  225. To do this we use gtk_toolbar_append_element.
  226. In fact, using this function one can also +add simple items or even spaces
  227. (type := GTK_TOOLBAR_CHILD_SPACE or +GTK_TOOLBAR_CHILD_BUTTON).
  228. In the above case we start creating a radio group.
  229. In creating other radio buttons for this group a pointer to the previous button in the group
  230. is required, so that a list of buttons can be easily constructed
  231. (see the section on Radio Buttons earlier in this tutorial).
  232. following radio buttons refer to previous ones }
  233. iconw := gtk_pixmap_new ( icon, mask );
  234. text_button :=
  235. gtk_toolbar_append_element(GTK_TOOLBAR(toolbar),
  236. GTK_TOOLBAR_CHILD_RADIOBUTTON,
  237. icon_button,
  238. 'Text',
  239. 'Only texts in toolbar',
  240. 'Private',
  241. iconw,
  242. GTK_SIGNAL_FUNC (@radio_event),
  243. toolbar);
  244. gtk_toolbar_append_space ( GTK_TOOLBAR ( toolbar ) );
  245. iconw := gtk_pixmap_new ( icon, mask );
  246. both_button :=
  247. gtk_toolbar_append_element(GTK_TOOLBAR(toolbar),
  248. GTK_TOOLBAR_CHILD_RADIOBUTTON,
  249. text_button,
  250. 'Both',
  251. 'Icons and text in toolbar',
  252. 'Private',
  253. iconw,
  254. GTK_SIGNAL_FUNC (@radio_event),
  255. toolbar);
  256. gtk_toolbar_append_space ( GTK_TOOLBAR ( toolbar ) );
  257. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(both_button),TRUE);
  258. {In the end we have to set the state of one of the buttons manually
  259. (otherwise they all stay in active state, preventing us from switching between them).}
  260. { here we have just a simple toggle button }
  261. iconw := gtk_pixmap_new ( icon, mask );
  262. tooltips_button :=
  263. gtk_toolbar_append_element(GTK_TOOLBAR(toolbar),
  264. GTK_TOOLBAR_CHILD_TOGGLEBUTTON,
  265. NULL,
  266. 'Tooltips',
  267. 'Toolbar with or without tips',
  268. 'Private',
  269. iconw,
  270. GTK_SIGNAL_FUNC (@toggle_event),
  271. toolbar);
  272. gtk_toolbar_append_space ( GTK_TOOLBAR ( toolbar ) );
  273. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tooltips_button),TRUE);
  274. {A toggle button can be created in the obvious way
  275. (if one knows how to create radio buttons already).}
  276. { to pack a widget into toolbar, we only have to
  277. create it and append it with an appropriate tooltip }
  278. entry := gtk_entry_new ();
  279. gtk_toolbar_append_widget( GTK_TOOLBAR (toolbar),
  280. entry,
  281. 'This is just an entry',
  282. 'Private' );
  283. { well, it isn't created within thetoolbar, so we must still show it }
  284. gtk_widget_show ( entry );
  285. {As you see, adding any kind of widget to a toolbar is simple.
  286. The one thing you have to remember is that this widget must be shown manually
  287. (contrary to other items which will be shown together with the toolbar).}
  288. { that's it ! let's show everything. }
  289. gtk_widget_show ( toolbar );
  290. gtk_widget_show (handlebox);
  291. gtk_widget_show ( dialog );
  292. { rest in gtk_main and wait for the fun to begin! }
  293. gtk_main ();
  294. End.