toolbar.pp 13 KB

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