Pratt 1.5.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (283) hide show
  1. data/.exrc +61 -0
  2. data/.gitignore +4 -0
  3. data/History.txt +6 -0
  4. data/Manifest.txt +46 -0
  5. data/Pratt.gemspec +351 -0
  6. data/README.txt +66 -0
  7. data/Rakefile +85 -0
  8. data/TODO +54 -0
  9. data/VERSION +1 -0
  10. data/bin/pratt.rb +13 -0
  11. data/config.rb +34 -0
  12. data/lib/pratt.rb +527 -0
  13. data/lib/pratt/array.rb +11 -0
  14. data/lib/pratt/string.rb +18 -0
  15. data/models/app.rb +40 -0
  16. data/models/customer.rb +24 -0
  17. data/models/payment.rb +22 -0
  18. data/models/pratt.rb +19 -0
  19. data/models/project.rb +82 -0
  20. data/models/whence.rb +70 -0
  21. data/pkgs/tile-0.8.2.tar.gz +0 -0
  22. data/pkgs/tile-0.8.2/ANNOUNCE.txt +95 -0
  23. data/pkgs/tile-0.8.2/ChangeLog +4651 -0
  24. data/pkgs/tile-0.8.2/Makefile +250 -0
  25. data/pkgs/tile-0.8.2/Makefile.in +250 -0
  26. data/pkgs/tile-0.8.2/README.txt +86 -0
  27. data/pkgs/tile-0.8.2/aclocal.m4 +2 -0
  28. data/pkgs/tile-0.8.2/altTheme.o +0 -0
  29. data/pkgs/tile-0.8.2/blink.o +0 -0
  30. data/pkgs/tile-0.8.2/button.o +0 -0
  31. data/pkgs/tile-0.8.2/cache.o +0 -0
  32. data/pkgs/tile-0.8.2/clamTheme.o +0 -0
  33. data/pkgs/tile-0.8.2/classicTheme.o +0 -0
  34. data/pkgs/tile-0.8.2/config.log +1330 -0
  35. data/pkgs/tile-0.8.2/config.status +795 -0
  36. data/pkgs/tile-0.8.2/configure +15248 -0
  37. data/pkgs/tile-0.8.2/configure.in +89 -0
  38. data/pkgs/tile-0.8.2/demos/autocomplete.tcl +59 -0
  39. data/pkgs/tile-0.8.2/demos/demo.tcl +870 -0
  40. data/pkgs/tile-0.8.2/demos/dirbrowser.tcl +167 -0
  41. data/pkgs/tile-0.8.2/demos/dlgtest.tcl +97 -0
  42. data/pkgs/tile-0.8.2/demos/iconlib.tcl +110 -0
  43. data/pkgs/tile-0.8.2/demos/repeater.tcl +117 -0
  44. data/pkgs/tile-0.8.2/demos/toolbutton.tcl +101 -0
  45. data/pkgs/tile-0.8.2/doc/Geometry.3 +230 -0
  46. data/pkgs/tile-0.8.2/doc/INDEX.MAP +153 -0
  47. data/pkgs/tile-0.8.2/doc/Makefile +36 -0
  48. data/pkgs/tile-0.8.2/doc/TILE.XML +45 -0
  49. data/pkgs/tile-0.8.2/doc/Theme.3 +34 -0
  50. data/pkgs/tile-0.8.2/doc/button.n +75 -0
  51. data/pkgs/tile-0.8.2/doc/checkbutton.n +61 -0
  52. data/pkgs/tile-0.8.2/doc/combobox.n +98 -0
  53. data/pkgs/tile-0.8.2/doc/converting.txt +97 -0
  54. data/pkgs/tile-0.8.2/doc/dialog.n +122 -0
  55. data/pkgs/tile-0.8.2/doc/entry.n +438 -0
  56. data/pkgs/tile-0.8.2/doc/frame.n +43 -0
  57. data/pkgs/tile-0.8.2/doc/html/Geometry.html +304 -0
  58. data/pkgs/tile-0.8.2/doc/html/Theme.html +48 -0
  59. data/pkgs/tile-0.8.2/doc/html/button.html +120 -0
  60. data/pkgs/tile-0.8.2/doc/html/category-index.html +18 -0
  61. data/pkgs/tile-0.8.2/doc/html/checkbutton.html +94 -0
  62. data/pkgs/tile-0.8.2/doc/html/combobox.html +164 -0
  63. data/pkgs/tile-0.8.2/doc/html/converting.txt +97 -0
  64. data/pkgs/tile-0.8.2/doc/html/dialog.html +159 -0
  65. data/pkgs/tile-0.8.2/doc/html/entry.html +613 -0
  66. data/pkgs/tile-0.8.2/doc/html/frame.html +76 -0
  67. data/pkgs/tile-0.8.2/doc/html/image.html +100 -0
  68. data/pkgs/tile-0.8.2/doc/html/index.html +25 -0
  69. data/pkgs/tile-0.8.2/doc/html/keyword-index.html +228 -0
  70. data/pkgs/tile-0.8.2/doc/html/label.html +133 -0
  71. data/pkgs/tile-0.8.2/doc/html/labelframe.html +91 -0
  72. data/pkgs/tile-0.8.2/doc/html/manpage.css +212 -0
  73. data/pkgs/tile-0.8.2/doc/html/menubutton.html +63 -0
  74. data/pkgs/tile-0.8.2/doc/html/notebook.html +280 -0
  75. data/pkgs/tile-0.8.2/doc/html/paned.html +149 -0
  76. data/pkgs/tile-0.8.2/doc/html/progressbar.html +138 -0
  77. data/pkgs/tile-0.8.2/doc/html/radiobutton.html +89 -0
  78. data/pkgs/tile-0.8.2/doc/html/scrollbar.html +221 -0
  79. data/pkgs/tile-0.8.2/doc/html/separator.html +48 -0
  80. data/pkgs/tile-0.8.2/doc/html/sizegrip.html +62 -0
  81. data/pkgs/tile-0.8.2/doc/html/style.html +172 -0
  82. data/pkgs/tile-0.8.2/doc/html/tile-intro.html +164 -0
  83. data/pkgs/tile-0.8.2/doc/html/treeview.html +634 -0
  84. data/pkgs/tile-0.8.2/doc/html/widget.html +342 -0
  85. data/pkgs/tile-0.8.2/doc/image.n +81 -0
  86. data/pkgs/tile-0.8.2/doc/internals.txt +409 -0
  87. data/pkgs/tile-0.8.2/doc/label.n +75 -0
  88. data/pkgs/tile-0.8.2/doc/labelframe.n +64 -0
  89. data/pkgs/tile-0.8.2/doc/man.macros +239 -0
  90. data/pkgs/tile-0.8.2/doc/menubutton.n +41 -0
  91. data/pkgs/tile-0.8.2/doc/notebook.n +188 -0
  92. data/pkgs/tile-0.8.2/doc/paned.n +95 -0
  93. data/pkgs/tile-0.8.2/doc/progressbar.n +79 -0
  94. data/pkgs/tile-0.8.2/doc/radiobutton.n +57 -0
  95. data/pkgs/tile-0.8.2/doc/scrollbar.n +160 -0
  96. data/pkgs/tile-0.8.2/doc/separator.n +30 -0
  97. data/pkgs/tile-0.8.2/doc/sizegrip.n +53 -0
  98. data/pkgs/tile-0.8.2/doc/style.n +119 -0
  99. data/pkgs/tile-0.8.2/doc/tile-intro.n +165 -0
  100. data/pkgs/tile-0.8.2/doc/tmml.options +4 -0
  101. data/pkgs/tile-0.8.2/doc/treeview.n +415 -0
  102. data/pkgs/tile-0.8.2/doc/widget.n +227 -0
  103. data/pkgs/tile-0.8.2/doc/xml/Geometry.tmml +379 -0
  104. data/pkgs/tile-0.8.2/doc/xml/INDEX.MAP +153 -0
  105. data/pkgs/tile-0.8.2/doc/xml/Theme.tmml +63 -0
  106. data/pkgs/tile-0.8.2/doc/xml/button.tmml +134 -0
  107. data/pkgs/tile-0.8.2/doc/xml/checkbutton.tmml +119 -0
  108. data/pkgs/tile-0.8.2/doc/xml/combobox.tmml +184 -0
  109. data/pkgs/tile-0.8.2/doc/xml/dialog.tmml +195 -0
  110. data/pkgs/tile-0.8.2/doc/xml/entry.tmml +630 -0
  111. data/pkgs/tile-0.8.2/doc/xml/frame.tmml +98 -0
  112. data/pkgs/tile-0.8.2/doc/xml/image.tmml +101 -0
  113. data/pkgs/tile-0.8.2/doc/xml/label.tmml +154 -0
  114. data/pkgs/tile-0.8.2/doc/xml/labelframe.tmml +116 -0
  115. data/pkgs/tile-0.8.2/doc/xml/menubutton.tmml +80 -0
  116. data/pkgs/tile-0.8.2/doc/xml/notebook.tmml +306 -0
  117. data/pkgs/tile-0.8.2/doc/xml/paned.tmml +154 -0
  118. data/pkgs/tile-0.8.2/doc/xml/progressbar.tmml +151 -0
  119. data/pkgs/tile-0.8.2/doc/xml/radiobutton.tmml +109 -0
  120. data/pkgs/tile-0.8.2/doc/xml/scrollbar.tmml +233 -0
  121. data/pkgs/tile-0.8.2/doc/xml/separator.tmml +59 -0
  122. data/pkgs/tile-0.8.2/doc/xml/sizegrip.tmml +82 -0
  123. data/pkgs/tile-0.8.2/doc/xml/style.tmml +171 -0
  124. data/pkgs/tile-0.8.2/doc/xml/tile-intro.tmml +192 -0
  125. data/pkgs/tile-0.8.2/doc/xml/treeview.tmml +604 -0
  126. data/pkgs/tile-0.8.2/doc/xml/widget.tmml +372 -0
  127. data/pkgs/tile-0.8.2/entry.o +0 -0
  128. data/pkgs/tile-0.8.2/frame.o +0 -0
  129. data/pkgs/tile-0.8.2/generic/Makefile.in +221 -0
  130. data/pkgs/tile-0.8.2/generic/TODO +493 -0
  131. data/pkgs/tile-0.8.2/generic/altTheme.c +1172 -0
  132. data/pkgs/tile-0.8.2/generic/blink.c +168 -0
  133. data/pkgs/tile-0.8.2/generic/button.c +858 -0
  134. data/pkgs/tile-0.8.2/generic/cache.c +354 -0
  135. data/pkgs/tile-0.8.2/generic/clamTheme.c +974 -0
  136. data/pkgs/tile-0.8.2/generic/classicTheme.c +518 -0
  137. data/pkgs/tile-0.8.2/generic/configure +10334 -0
  138. data/pkgs/tile-0.8.2/generic/configure.in +100 -0
  139. data/pkgs/tile-0.8.2/generic/entry.c +1922 -0
  140. data/pkgs/tile-0.8.2/generic/frame.c +648 -0
  141. data/pkgs/tile-0.8.2/generic/gunk.h +44 -0
  142. data/pkgs/tile-0.8.2/generic/image.c +416 -0
  143. data/pkgs/tile-0.8.2/generic/label.c +663 -0
  144. data/pkgs/tile-0.8.2/generic/layout.c +1215 -0
  145. data/pkgs/tile-0.8.2/generic/manager.c +554 -0
  146. data/pkgs/tile-0.8.2/generic/manager.h +91 -0
  147. data/pkgs/tile-0.8.2/generic/notebook.c +1380 -0
  148. data/pkgs/tile-0.8.2/generic/paned.c +958 -0
  149. data/pkgs/tile-0.8.2/generic/pkgIndex.tcl.in +7 -0
  150. data/pkgs/tile-0.8.2/generic/progress.c +549 -0
  151. data/pkgs/tile-0.8.2/generic/scale.c +526 -0
  152. data/pkgs/tile-0.8.2/generic/scroll.c +253 -0
  153. data/pkgs/tile-0.8.2/generic/scrollbar.c +346 -0
  154. data/pkgs/tile-0.8.2/generic/separator.c +132 -0
  155. data/pkgs/tile-0.8.2/generic/square.c +306 -0
  156. data/pkgs/tile-0.8.2/generic/tagset.c +147 -0
  157. data/pkgs/tile-0.8.2/generic/tile.c +296 -0
  158. data/pkgs/tile-0.8.2/generic/tkElements.c +1280 -0
  159. data/pkgs/tile-0.8.2/generic/tkTheme.c +1708 -0
  160. data/pkgs/tile-0.8.2/generic/tkTheme.h +419 -0
  161. data/pkgs/tile-0.8.2/generic/tkThemeInt.h +45 -0
  162. data/pkgs/tile-0.8.2/generic/tkstate.c +268 -0
  163. data/pkgs/tile-0.8.2/generic/trace.c +145 -0
  164. data/pkgs/tile-0.8.2/generic/track.c +174 -0
  165. data/pkgs/tile-0.8.2/generic/treeview.c +3211 -0
  166. data/pkgs/tile-0.8.2/generic/ttk.decls +154 -0
  167. data/pkgs/tile-0.8.2/generic/ttkDecls.h +340 -0
  168. data/pkgs/tile-0.8.2/generic/ttkStubInit.c +61 -0
  169. data/pkgs/tile-0.8.2/generic/ttkStubLib.c +70 -0
  170. data/pkgs/tile-0.8.2/generic/widget.c +785 -0
  171. data/pkgs/tile-0.8.2/generic/widget.h +263 -0
  172. data/pkgs/tile-0.8.2/image.o +0 -0
  173. data/pkgs/tile-0.8.2/label.o +0 -0
  174. data/pkgs/tile-0.8.2/layout.o +0 -0
  175. data/pkgs/tile-0.8.2/library/altTheme.tcl +101 -0
  176. data/pkgs/tile-0.8.2/library/aquaTheme.tcl +62 -0
  177. data/pkgs/tile-0.8.2/library/button.tcl +85 -0
  178. data/pkgs/tile-0.8.2/library/clamTheme.tcl +139 -0
  179. data/pkgs/tile-0.8.2/library/classicTheme.tcl +108 -0
  180. data/pkgs/tile-0.8.2/library/combobox.tcl +439 -0
  181. data/pkgs/tile-0.8.2/library/cursors.tcl +36 -0
  182. data/pkgs/tile-0.8.2/library/defaults.tcl +118 -0
  183. data/pkgs/tile-0.8.2/library/dialog.tcl +274 -0
  184. data/pkgs/tile-0.8.2/library/entry.tcl +580 -0
  185. data/pkgs/tile-0.8.2/library/fonts.tcl +153 -0
  186. data/pkgs/tile-0.8.2/library/icons.tcl +105 -0
  187. data/pkgs/tile-0.8.2/library/keynav.tcl +192 -0
  188. data/pkgs/tile-0.8.2/library/menubutton.tcl +171 -0
  189. data/pkgs/tile-0.8.2/library/notebook.tcl +193 -0
  190. data/pkgs/tile-0.8.2/library/paned.tcl +87 -0
  191. data/pkgs/tile-0.8.2/library/progress.tcl +51 -0
  192. data/pkgs/tile-0.8.2/library/scale.tcl +54 -0
  193. data/pkgs/tile-0.8.2/library/scrollbar.tcl +125 -0
  194. data/pkgs/tile-0.8.2/library/sizegrip.tcl +77 -0
  195. data/pkgs/tile-0.8.2/library/tile.tcl +211 -0
  196. data/pkgs/tile-0.8.2/library/treeview.tcl +382 -0
  197. data/pkgs/tile-0.8.2/library/utils.tcl +254 -0
  198. data/pkgs/tile-0.8.2/library/winTheme.tcl +77 -0
  199. data/pkgs/tile-0.8.2/library/xpTheme.tcl +63 -0
  200. data/pkgs/tile-0.8.2/libtile0.8.2.so +0 -0
  201. data/pkgs/tile-0.8.2/libttkstub.a +0 -0
  202. data/pkgs/tile-0.8.2/license.terms +24 -0
  203. data/pkgs/tile-0.8.2/macosx/aquaTheme.c +1076 -0
  204. data/pkgs/tile-0.8.2/manager.o +0 -0
  205. data/pkgs/tile-0.8.2/notebook.o +0 -0
  206. data/pkgs/tile-0.8.2/paned.o +0 -0
  207. data/pkgs/tile-0.8.2/pkgIndex.tcl +3 -0
  208. data/pkgs/tile-0.8.2/progress.o +0 -0
  209. data/pkgs/tile-0.8.2/scale.o +0 -0
  210. data/pkgs/tile-0.8.2/scroll.o +0 -0
  211. data/pkgs/tile-0.8.2/scrollbar.o +0 -0
  212. data/pkgs/tile-0.8.2/separator.o +0 -0
  213. data/pkgs/tile-0.8.2/tagset.o +0 -0
  214. data/pkgs/tile-0.8.2/tclconfig/install-sh +119 -0
  215. data/pkgs/tile-0.8.2/tclconfig/tcl.m4 +4069 -0
  216. data/pkgs/tile-0.8.2/tclconfig/teax.m4 +109 -0
  217. data/pkgs/tile-0.8.2/tests/all.tcl +18 -0
  218. data/pkgs/tile-0.8.2/tests/bwidget.test +103 -0
  219. data/pkgs/tile-0.8.2/tests/cbtest.tcl +125 -0
  220. data/pkgs/tile-0.8.2/tests/combobox.test +51 -0
  221. data/pkgs/tile-0.8.2/tests/compound.tcl +92 -0
  222. data/pkgs/tile-0.8.2/tests/entry.test +285 -0
  223. data/pkgs/tile-0.8.2/tests/entrytest.tcl +78 -0
  224. data/pkgs/tile-0.8.2/tests/image.test +94 -0
  225. data/pkgs/tile-0.8.2/tests/labelframe.tcl +41 -0
  226. data/pkgs/tile-0.8.2/tests/labelframe.test +137 -0
  227. data/pkgs/tile-0.8.2/tests/layout.test +33 -0
  228. data/pkgs/tile-0.8.2/tests/misc.test +35 -0
  229. data/pkgs/tile-0.8.2/tests/nbtest.tcl +66 -0
  230. data/pkgs/tile-0.8.2/tests/notebook.test +500 -0
  231. data/pkgs/tile-0.8.2/tests/paned.test +298 -0
  232. data/pkgs/tile-0.8.2/tests/progress.test +92 -0
  233. data/pkgs/tile-0.8.2/tests/pwtest.tcl +90 -0
  234. data/pkgs/tile-0.8.2/tests/sbtest.tcl +79 -0
  235. data/pkgs/tile-0.8.2/tests/scrollbar.test +77 -0
  236. data/pkgs/tile-0.8.2/tests/sgtest.tcl +52 -0
  237. data/pkgs/tile-0.8.2/tests/testutils.tcl +20 -0
  238. data/pkgs/tile-0.8.2/tests/tile.test +674 -0
  239. data/pkgs/tile-0.8.2/tests/treetags.test +78 -0
  240. data/pkgs/tile-0.8.2/tests/treeview.test +563 -0
  241. data/pkgs/tile-0.8.2/tests/tvtest.tcl +332 -0
  242. data/pkgs/tile-0.8.2/tests/validate.test +278 -0
  243. data/pkgs/tile-0.8.2/tile.o +0 -0
  244. data/pkgs/tile-0.8.2/tkElements.o +0 -0
  245. data/pkgs/tile-0.8.2/tkTheme.o +0 -0
  246. data/pkgs/tile-0.8.2/tkstate.o +0 -0
  247. data/pkgs/tile-0.8.2/tools/genStubs.tcl +861 -0
  248. data/pkgs/tile-0.8.2/trace.o +0 -0
  249. data/pkgs/tile-0.8.2/track.o +0 -0
  250. data/pkgs/tile-0.8.2/treeview.o +0 -0
  251. data/pkgs/tile-0.8.2/ttkStubInit.o +0 -0
  252. data/pkgs/tile-0.8.2/ttkStubLib.o +0 -0
  253. data/pkgs/tile-0.8.2/widget.o +0 -0
  254. data/pkgs/tile-0.8.2/win/Tile.dsp +261 -0
  255. data/pkgs/tile-0.8.2/win/makefile.vc +527 -0
  256. data/pkgs/tile-0.8.2/win/monitor.c +164 -0
  257. data/pkgs/tile-0.8.2/win/nmakehlp.c +483 -0
  258. data/pkgs/tile-0.8.2/win/rules.vc +512 -0
  259. data/pkgs/tile-0.8.2/win/tile.rc +40 -0
  260. data/pkgs/tile-0.8.2/win/winTheme.c +734 -0
  261. data/pkgs/tile-0.8.2/win/xpTheme.c +1029 -0
  262. data/spec/app_spec.rb +48 -0
  263. data/spec/customer_spec.rb +31 -0
  264. data/spec/fixtures/graph.expectation +18 -0
  265. data/spec/payment_spec.rb +19 -0
  266. data/spec/pratt_spec.rb +148 -0
  267. data/spec/project_spec.rb +163 -0
  268. data/spec/rcov.opts +0 -0
  269. data/spec/spec.opts +1 -0
  270. data/spec/spec_helper.rb +21 -0
  271. data/spec/whence_spec.rb +54 -0
  272. data/tasks/pratt.rb +84 -0
  273. data/templates/model.eruby +12 -0
  274. data/templates/spec.eruby +8 -0
  275. data/views/env.rb +22 -0
  276. data/views/graph.eruby +20 -0
  277. data/views/invoice.eruby +148 -0
  278. data/views/main.rb +92 -0
  279. data/views/pid.eruby +3 -0
  280. data/views/pop.rb +94 -0
  281. data/views/pop2.rb +75 -0
  282. data/views/raw.eruby +11 -0
  283. metadata +390 -0
@@ -0,0 +1,91 @@
1
+ /* manager.h,v 1.11 2007/11/25 17:17:09 jenglish Exp
2
+ *
3
+ * Copyright (c) 2005, Joe English. Freely redistributable.
4
+ *
5
+ * Geometry manager utilities.
6
+ */
7
+
8
+ #ifndef _TTKMANAGER
9
+ #define _TTKMANAGER
10
+
11
+ typedef struct TtkManager_ Ttk_Manager;
12
+
13
+ /*
14
+ * Geometry manager specification record:
15
+ *
16
+ * RequestedSize computes the requested size of the master window.
17
+ *
18
+ * PlaceSlaves sets the position and size of all managed slaves
19
+ * by calling Ttk_PlaceSlave().
20
+ *
21
+ * SlaveRemoved() is called immediately before a slave is removed.
22
+ * NB: the associated slave window may have been destroyed when this
23
+ * routine is called.
24
+ *
25
+ * SlaveRequest() is called when a slave requests a size change.
26
+ * It should return 1 if the request should propagate, 0 otherwise.
27
+ */
28
+ typedef struct { /* Manager hooks */
29
+ Tk_GeomMgr tkGeomMgr; /* "real" Tk Geometry Manager */
30
+
31
+ int (*RequestedSize)(void *managerData, int *widthPtr, int *heightPtr);
32
+ void (*PlaceSlaves)(void *managerData);
33
+ int (*SlaveRequest)(void *managerData, int slaveIndex, int w, int h);
34
+ void (*SlaveRemoved)(void *managerData, int slaveIndex);
35
+ } Ttk_ManagerSpec;
36
+
37
+ /*
38
+ * Default implementations for Tk_GeomMgr hooks:
39
+ */
40
+ extern void Ttk_GeometryRequestProc(ClientData, Tk_Window slave);
41
+ extern void Ttk_LostSlaveProc(ClientData, Tk_Window slave);
42
+
43
+ /*
44
+ * Public API:
45
+ */
46
+ extern Ttk_Manager *Ttk_CreateManager(
47
+ Ttk_ManagerSpec *, void *managerData, Tk_Window masterWindow);
48
+ extern void Ttk_DeleteManager(Ttk_Manager *);
49
+
50
+ extern void Ttk_InsertSlave(
51
+ Ttk_Manager *, int position, Tk_Window, void *slaveData);
52
+
53
+ extern void Ttk_ForgetSlave(Ttk_Manager *, int slaveIndex);
54
+
55
+ extern void Ttk_ReorderSlave(Ttk_Manager *, int fromIndex, int toIndex);
56
+ /* Rearrange slave positions */
57
+
58
+ extern void Ttk_PlaceSlave(
59
+ Ttk_Manager *, int slaveIndex, int x, int y, int width, int height);
60
+ /* Position and map the slave */
61
+
62
+ extern void Ttk_UnmapSlave(Ttk_Manager *, int slaveIndex);
63
+ /* Unmap the slave */
64
+
65
+ extern void Ttk_ManagerSizeChanged(Ttk_Manager *);
66
+ extern void Ttk_ManagerLayoutChanged(Ttk_Manager *);
67
+ /* Notify manager that size (resp. layout) needs to be recomputed */
68
+
69
+ /* Utilities:
70
+ */
71
+ extern int Ttk_SlaveIndex(Ttk_Manager *, Tk_Window);
72
+ /* Returns: index in slave array of specified window, -1 if not found */
73
+
74
+ extern int Ttk_GetSlaveIndexFromObj(
75
+ Tcl_Interp *, Ttk_Manager *, Tcl_Obj *, int *indexPtr);
76
+
77
+ /* Accessor functions:
78
+ */
79
+ extern int Ttk_NumberSlaves(Ttk_Manager *);
80
+ /* Returns: number of managed slaves */
81
+
82
+ extern void *Ttk_SlaveData(Ttk_Manager *, int slaveIndex);
83
+ /* Returns: client data associated with slave */
84
+
85
+ extern Tk_Window Ttk_SlaveWindow(Ttk_Manager *, int slaveIndex);
86
+ /* Returns: slave window */
87
+
88
+ extern int Ttk_Maintainable(Tcl_Interp *, Tk_Window slave, Tk_Window master);
89
+ /* Returns: 1 if master can manage slave; 0 otherwise leaving error msg */
90
+
91
+ #endif /* _TTKMANAGER */
@@ -0,0 +1,1380 @@
1
+ /* notebook.c,v 1.97 2007/11/25 18:09:51 jenglish Exp
2
+ * Copyright (c) 2004, Joe English
3
+ */
4
+
5
+ #include <string.h>
6
+ #include <ctype.h>
7
+ #include <stdio.h>
8
+ #include <tk.h>
9
+
10
+ #include "tkTheme.h"
11
+ #include "widget.h"
12
+ #include "manager.h"
13
+
14
+ #define MIN(a,b) ((a) < (b) ? (a) : (b))
15
+ #define MAX(a,b) ((a) > (b) ? (a) : (b))
16
+
17
+ /*------------------------------------------------------------------------
18
+ * +++ Tab resources.
19
+ */
20
+
21
+ #define DEFAULT_MIN_TAB_WIDTH 24
22
+
23
+ static const char *TabStateStrings[] = { "normal", "disabled", "hidden", 0 };
24
+ typedef enum {
25
+ TAB_STATE_NORMAL, TAB_STATE_DISABLED, TAB_STATE_HIDDEN
26
+ } TAB_STATE;
27
+
28
+ typedef struct
29
+ {
30
+ /* Internal data:
31
+ */
32
+ int width, height; /* Requested size of tab */
33
+ Ttk_Box parcel; /* Tab position */
34
+
35
+ /* Tab options:
36
+ */
37
+ TAB_STATE state;
38
+
39
+ /* Child window options:
40
+ */
41
+ Tcl_Obj *paddingObj; /* Padding inside pane */
42
+ Ttk_Padding padding;
43
+ Tcl_Obj *stickyObj;
44
+ Ttk_Sticky sticky;
45
+
46
+ /* Label options:
47
+ */
48
+ Tcl_Obj *textObj;
49
+ Tcl_Obj *imageObj;
50
+ Tcl_Obj *compoundObj;
51
+ Tcl_Obj *underlineObj;
52
+
53
+ } Tab;
54
+
55
+ /* Two different option tables are used for tabs:
56
+ * TabOptionSpecs is used to draw the tab, and only includes resources
57
+ * relevant to the tab.
58
+ *
59
+ * PaneOptionSpecs includes additional options for child window placement
60
+ * and is used to configure the slave.
61
+ */
62
+ static Tk_OptionSpec TabOptionSpecs[] =
63
+ {
64
+ {TK_OPTION_STRING_TABLE, "-state", "", "",
65
+ "normal", -1,Tk_Offset(Tab,state),
66
+ 0,(ClientData)TabStateStrings,0 },
67
+ {TK_OPTION_STRING, "-text", "text", "Text", "",
68
+ Tk_Offset(Tab,textObj), -1, 0,0,GEOMETRY_CHANGED },
69
+ {TK_OPTION_STRING, "-image", "image", "Image", NULL/*default*/,
70
+ Tk_Offset(Tab,imageObj), -1, TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
71
+ {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
72
+ "none", Tk_Offset(Tab,compoundObj), -1,
73
+ 0,(ClientData)ttkCompoundStrings,GEOMETRY_CHANGED },
74
+ {TK_OPTION_INT, "-underline", "underline", "Underline", "-1",
75
+ Tk_Offset(Tab,underlineObj), -1, 0,0,GEOMETRY_CHANGED },
76
+ {TK_OPTION_END}
77
+ };
78
+
79
+ static Tk_OptionSpec PaneOptionSpecs[] =
80
+ {
81
+ {TK_OPTION_STRING, "-padding", "padding", "Padding", "0",
82
+ Tk_Offset(Tab,paddingObj), -1, 0,0,GEOMETRY_CHANGED },
83
+ {TK_OPTION_STRING, "-sticky", "sticky", "Sticky", "nsew",
84
+ Tk_Offset(Tab,stickyObj), -1, 0,0,GEOMETRY_CHANGED },
85
+
86
+ WIDGET_INHERIT_OPTIONS(TabOptionSpecs)
87
+ };
88
+
89
+ /*------------------------------------------------------------------------
90
+ * +++ Notebook resources.
91
+ */
92
+ typedef struct
93
+ {
94
+ Tcl_Obj *widthObj; /* Default width */
95
+ Tcl_Obj *heightObj; /* Default height */
96
+ Tcl_Obj *paddingObj; /* Padding around notebook */
97
+
98
+ Ttk_Manager *mgr; /* Geometry manager */
99
+ Tk_OptionTable tabOptionTable; /* Tab options */
100
+ Tk_OptionTable paneOptionTable; /* Tab+pane options */
101
+ int currentIndex; /* index of currently selected tab */
102
+ int activeIndex; /* index of currently active tab */
103
+ Ttk_Layout tabLayout; /* Sublayout for tabs */
104
+
105
+ Ttk_Box clientArea; /* Where to pack slave widgets */
106
+ } NotebookPart;
107
+
108
+ typedef struct
109
+ {
110
+ WidgetCore core;
111
+ NotebookPart notebook;
112
+ } Notebook;
113
+
114
+ static Tk_OptionSpec NotebookOptionSpecs[] =
115
+ {
116
+ WIDGET_TAKES_FOCUS,
117
+
118
+ {TK_OPTION_INT, "-width", "width", "Width", "0",
119
+ Tk_Offset(Notebook,notebook.widthObj),-1,
120
+ 0,0,GEOMETRY_CHANGED },
121
+ {TK_OPTION_INT, "-height", "height", "Height", "0",
122
+ Tk_Offset(Notebook,notebook.heightObj),-1,
123
+ 0,0,GEOMETRY_CHANGED },
124
+ {TK_OPTION_STRING, "-padding", "padding", "Padding", NULL,
125
+ Tk_Offset(Notebook,notebook.paddingObj),-1,
126
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
127
+
128
+ WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
129
+ };
130
+
131
+ /* Notebook style options:
132
+ */
133
+ typedef struct
134
+ {
135
+ Ttk_PositionSpec tabPosition; /* Where to place tabs */
136
+ Ttk_Padding tabMargins; /* Margins around tab row */
137
+ Ttk_PositionSpec tabPlacement; /* How to pack tabs within tab row */
138
+ Ttk_Orient tabOrient; /* ... */
139
+ int minTabWidth; /* Minimum tab width */
140
+ Ttk_Padding padding; /* External padding */
141
+ } NotebookStyle;
142
+
143
+ static void NotebookStyleOptions(Notebook *nb, NotebookStyle *nbstyle)
144
+ {
145
+ Tcl_Obj *objPtr;
146
+
147
+ nbstyle->tabPosition = TTK_PACK_TOP | TTK_STICK_W;
148
+ if ((objPtr = Ttk_QueryOption(nb->core.layout, "-tabposition", 0)) != 0) {
149
+ TtkGetLabelAnchorFromObj(NULL, objPtr, &nbstyle->tabPosition);
150
+ }
151
+
152
+ /* compute tabPlacement and tabOrient as function of tabPosition:
153
+ */
154
+ if (nbstyle->tabPosition & TTK_PACK_LEFT) {
155
+ nbstyle->tabPlacement = TTK_PACK_TOP | TTK_STICK_E;
156
+ nbstyle->tabOrient = TTK_ORIENT_VERTICAL;
157
+ } else if (nbstyle->tabPosition & TTK_PACK_RIGHT) {
158
+ nbstyle->tabPlacement = TTK_PACK_TOP | TTK_STICK_W;
159
+ nbstyle->tabOrient = TTK_ORIENT_VERTICAL;
160
+ } else if (nbstyle->tabPosition & TTK_PACK_BOTTOM) {
161
+ nbstyle->tabPlacement = TTK_PACK_LEFT | TTK_STICK_N;
162
+ nbstyle->tabOrient = TTK_ORIENT_HORIZONTAL;
163
+ } else { /* Assume TTK_PACK_TOP */
164
+ nbstyle->tabPlacement = TTK_PACK_LEFT | TTK_STICK_S;
165
+ nbstyle->tabOrient = TTK_ORIENT_HORIZONTAL;
166
+ }
167
+
168
+ nbstyle->tabMargins = Ttk_UniformPadding(0);
169
+ if ((objPtr = Ttk_QueryOption(nb->core.layout, "-tabmargins", 0)) != 0) {
170
+ Ttk_GetBorderFromObj(NULL, objPtr, &nbstyle->tabMargins);
171
+ }
172
+
173
+ nbstyle->padding = Ttk_UniformPadding(0);
174
+ if ((objPtr = Ttk_QueryOption(nb->core.layout, "-padding", 0)) != 0) {
175
+ Ttk_GetPaddingFromObj(NULL,nb->core.tkwin,objPtr,&nbstyle->padding);
176
+ }
177
+
178
+ nbstyle->minTabWidth = DEFAULT_MIN_TAB_WIDTH;
179
+ if ((objPtr = Ttk_QueryOption(nb->core.layout, "-mintabwidth", 0)) != 0) {
180
+ Tcl_GetIntFromObj(NULL, objPtr, &nbstyle->minTabWidth);
181
+ }
182
+ }
183
+
184
+ /*------------------------------------------------------------------------
185
+ * +++ Tab management.
186
+ */
187
+
188
+ static Tab *CreateTab(Tcl_Interp *interp, Notebook *nb, Tk_Window slaveWindow)
189
+ {
190
+ Tk_OptionTable optionTable = nb->notebook.paneOptionTable;
191
+ void *record = ckalloc(sizeof(Tab));
192
+ memset(record, 0, sizeof(Tab));
193
+
194
+ if (Tk_InitOptions(interp, record, optionTable, slaveWindow) != TCL_OK) {
195
+ ckfree(record);
196
+ return NULL;
197
+ }
198
+
199
+ return record;
200
+ }
201
+
202
+ static void DestroyTab(Notebook *nb, Tab *tab)
203
+ {
204
+ void *record = tab;
205
+ Tk_FreeConfigOptions(record, nb->notebook.paneOptionTable, nb->core.tkwin);
206
+ ckfree(record);
207
+ }
208
+
209
+ static int ConfigureTab(
210
+ Tcl_Interp *interp, Notebook *nb, Tab *tab, Tk_Window slaveWindow,
211
+ int objc, Tcl_Obj *CONST objv[])
212
+ {
213
+ Ttk_Sticky sticky = tab->sticky;
214
+ Ttk_Padding padding = tab->padding;
215
+ Tk_SavedOptions savedOptions;
216
+ int mask = 0;
217
+
218
+ if (Tk_SetOptions(interp, (ClientData)tab, nb->notebook.paneOptionTable,
219
+ objc, objv, slaveWindow, &savedOptions, &mask) != TCL_OK)
220
+ {
221
+ return TCL_ERROR;
222
+ }
223
+
224
+ /* Check options:
225
+ * @@@ TODO: validate -image option.
226
+ */
227
+ if (Ttk_GetStickyFromObj(interp, tab->stickyObj, &sticky) != TCL_OK)
228
+ {
229
+ goto error;
230
+ }
231
+ if (Ttk_GetPaddingFromObj(interp, slaveWindow, tab->paddingObj, &padding)
232
+ != TCL_OK)
233
+ {
234
+ goto error;
235
+ }
236
+
237
+ tab->sticky = sticky;
238
+ tab->padding = padding;
239
+
240
+ Tk_FreeSavedOptions(&savedOptions);
241
+ Ttk_ManagerSizeChanged(nb->notebook.mgr);
242
+
243
+ return TCL_OK;
244
+ error:
245
+ Tk_RestoreSavedOptions(&savedOptions);
246
+ return TCL_ERROR;
247
+ }
248
+
249
+ /*
250
+ * IdentifyTab --
251
+ * Return the index of the tab at point x,y,
252
+ * or -1 if no tab at that point.
253
+ */
254
+ static int IdentifyTab(Notebook *nb, int x, int y)
255
+ {
256
+ int index;
257
+ for (index = 0; index < Ttk_NumberSlaves(nb->notebook.mgr); ++index) {
258
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr,index);
259
+ if ( tab->state != TAB_STATE_HIDDEN
260
+ && Ttk_BoxContains(tab->parcel, x,y))
261
+ {
262
+ return index;
263
+ }
264
+ }
265
+ return -1;
266
+ }
267
+
268
+ /*
269
+ * ActivateTab --
270
+ * Set the active tab index, redisplay if necessary.
271
+ */
272
+ static void ActivateTab(Notebook *nb, int index)
273
+ {
274
+ if (index != nb->notebook.activeIndex) {
275
+ nb->notebook.activeIndex = index;
276
+ TtkRedisplayWidget(&nb->core);
277
+ }
278
+ }
279
+
280
+ /*
281
+ * TabState --
282
+ * Return the state of the specified tab, based on
283
+ * notebook state, currentIndex, activeIndex, and user-specified tab state.
284
+ * The USER1 bit is set for the leftmost tab, and USER2
285
+ * is set for the rightmost tab.
286
+ */
287
+ static Ttk_State TabState(Notebook *nb, int index)
288
+ {
289
+ Ttk_State state = nb->core.state;
290
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, index);
291
+
292
+ if (index == nb->notebook.currentIndex) {
293
+ state |= TTK_STATE_SELECTED;
294
+ } else {
295
+ state &= ~TTK_STATE_FOCUS;
296
+ }
297
+
298
+ if (index == nb->notebook.activeIndex) {
299
+ state |= TTK_STATE_ACTIVE;
300
+ }
301
+ if (index == 0) {
302
+ state |= TTK_STATE_USER1;
303
+ }
304
+ if (index == Ttk_NumberSlaves(nb->notebook.mgr) - 1) {
305
+ state |= TTK_STATE_USER2;
306
+ }
307
+ if (tab->state == TAB_STATE_DISABLED) {
308
+ state |= TTK_STATE_DISABLED;
309
+ }
310
+
311
+ return state;
312
+ }
313
+
314
+ /*------------------------------------------------------------------------
315
+ * +++ Geometry management - size computation.
316
+ */
317
+
318
+ /* TabrowSize --
319
+ * Compute max height and total width of all tabs (horizontal layouts)
320
+ * or total height and max width (vertical layouts).
321
+ *
322
+ * Side effects:
323
+ * Sets width and height fields for all tabs.
324
+ *
325
+ * Notes:
326
+ * Hidden tabs are included in the perpendicular computation
327
+ * (max height/width) but not parallel (total width/height).
328
+ */
329
+ static void TabrowSize(
330
+ Notebook *nb, Ttk_Orient orient, int *widthPtr, int *heightPtr)
331
+ {
332
+ Ttk_Layout tabLayout = nb->notebook.tabLayout;
333
+ int tabrowWidth = 0, tabrowHeight = 0;
334
+ int i;
335
+
336
+ for (i = 0; i < Ttk_NumberSlaves(nb->notebook.mgr); ++i) {
337
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i);
338
+ Ttk_State tabState = TabState(nb,i);
339
+
340
+ Ttk_RebindSublayout(tabLayout, tab);
341
+ Ttk_LayoutSize(tabLayout,tabState,&tab->width,&tab->height);
342
+
343
+ if (orient == TTK_ORIENT_HORIZONTAL) {
344
+ tabrowHeight = MAX(tabrowHeight, tab->height);
345
+ if (tab->state != TAB_STATE_HIDDEN) { tabrowWidth += tab->width; }
346
+ } else {
347
+ tabrowWidth = MAX(tabrowWidth, tab->width);
348
+ if (tab->state != TAB_STATE_HIDDEN) { tabrowHeight += tab->height; }
349
+ }
350
+ }
351
+
352
+ *widthPtr = tabrowWidth;
353
+ *heightPtr = tabrowHeight;
354
+ }
355
+
356
+ /* NotebookSize -- GM and widget size hook.
357
+ *
358
+ * Total height is tab height + client area height + pane internal padding
359
+ * Total width is max(client width, tab width) + pane internal padding
360
+ * Client area size determined by max size of slaves,
361
+ * overridden by -width and/or -height if nonzero.
362
+ */
363
+
364
+ static int NotebookSize(void *clientData, int *widthPtr, int *heightPtr)
365
+ {
366
+ Notebook *nb = clientData;
367
+ NotebookStyle nbstyle;
368
+ Ttk_Padding padding;
369
+ Ttk_LayoutNode *clientNode = Ttk_LayoutFindNode(nb->core.layout, "client");
370
+ int clientWidth = 0, clientHeight = 0,
371
+ reqWidth = 0, reqHeight = 0,
372
+ tabrowWidth = 0, tabrowHeight = 0;
373
+ int i;
374
+
375
+ NotebookStyleOptions(nb, &nbstyle);
376
+
377
+ /* Compute max requested size of all slaves:
378
+ */
379
+ for (i = 0; i < Ttk_NumberSlaves(nb->notebook.mgr); ++i) {
380
+ Tk_Window slaveWindow = Ttk_SlaveWindow(nb->notebook.mgr, i);
381
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i);
382
+ int slaveWidth
383
+ = Tk_ReqWidth(slaveWindow) + Ttk_PaddingWidth(tab->padding);
384
+ int slaveHeight
385
+ = Tk_ReqHeight(slaveWindow) + Ttk_PaddingHeight(tab->padding);
386
+
387
+ clientWidth = MAX(clientWidth, slaveWidth);
388
+ clientHeight = MAX(clientHeight, slaveHeight);
389
+ }
390
+
391
+ /* Client width/height overridable by widget options:
392
+ */
393
+ Tcl_GetIntFromObj(NULL, nb->notebook.widthObj,&reqWidth);
394
+ Tcl_GetIntFromObj(NULL, nb->notebook.heightObj,&reqHeight);
395
+ if (reqWidth > 0)
396
+ clientWidth = reqWidth;
397
+ if (reqHeight > 0)
398
+ clientHeight = reqHeight;
399
+
400
+ /* Tab row:
401
+ */
402
+ TabrowSize(nb, nbstyle.tabOrient, &tabrowWidth, &tabrowHeight);
403
+ tabrowHeight += Ttk_PaddingHeight(nbstyle.tabMargins);
404
+ tabrowWidth += Ttk_PaddingWidth(nbstyle.tabMargins);
405
+
406
+ /* Account for exterior and interior padding:
407
+ */
408
+ padding = nbstyle.padding;
409
+ if (clientNode) {
410
+ Ttk_Padding ipad =
411
+ Ttk_LayoutNodeInternalPadding(nb->core.layout, clientNode);
412
+ padding = Ttk_AddPadding(padding, ipad);
413
+ }
414
+
415
+ *widthPtr = MAX(tabrowWidth, clientWidth) + Ttk_PaddingWidth(padding);
416
+ *heightPtr = tabrowHeight + clientHeight + Ttk_PaddingHeight(padding);
417
+
418
+ return 1;
419
+ }
420
+
421
+ /*------------------------------------------------------------------------
422
+ * +++ Geometry management - layout.
423
+ */
424
+
425
+ /* SqueezeTabs --
426
+ * If the notebook is not wide enough to display all tabs,
427
+ * attempt to decrease tab widths to fit.
428
+ *
429
+ * All tabs are shrunk by an equal amount, but will not be made
430
+ * smaller than the minimum width. (If all the tabs still do
431
+ * not fit in the available space, the rightmost tabs are truncated).
432
+ *
433
+ * The algorithm does not always yield an optimal layout, but does
434
+ * have the important property that decreasing the available width
435
+ * by one pixel will cause at most one tab to shrink by one pixel;
436
+ * this means that tabs resize "smoothly" when the window shrinks
437
+ * and grows.
438
+ *
439
+ * @@@ <<NOTE-TABPOSITION>> bug: only works for horizontal orientations
440
+ */
441
+
442
+ static void SqueezeTabs(
443
+ Notebook *nb, int desiredWidth, int availableWidth, int minTabWidth)
444
+ {
445
+ int nTabs = Ttk_NumberSlaves(nb->notebook.mgr);
446
+ int shrinkage = desiredWidth - availableWidth;
447
+ int extra = 0;
448
+ int i;
449
+
450
+ for (i = 0; i < nTabs; ++i) {
451
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr,i);
452
+ int shrink = (shrinkage/nTabs) + (i < (shrinkage%nTabs)) + extra;
453
+ int shrinkability = MAX(0, tab->width - minTabWidth);
454
+ int delta = MIN(shrinkability, shrink);
455
+ tab->width -= delta;
456
+ extra = shrink - delta;
457
+ }
458
+ }
459
+
460
+ /* PlaceTabs --
461
+ * Compute all tab parcels.
462
+ */
463
+ static void PlaceTabs(
464
+ Notebook *nb, Ttk_Box tabrowBox, Ttk_PositionSpec tabPlacement)
465
+ {
466
+ Ttk_Layout tabLayout = nb->notebook.tabLayout;
467
+ int nTabs = Ttk_NumberSlaves(nb->notebook.mgr);
468
+ int i;
469
+
470
+ for (i = 0; i < nTabs; ++i) {
471
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i);
472
+ Ttk_State tabState = TabState(nb, i);
473
+
474
+ if (tab->state != TAB_STATE_HIDDEN) {
475
+ Ttk_Padding expand = Ttk_UniformPadding(0);
476
+ Tcl_Obj *expandObj = Ttk_QueryOption(tabLayout,"-expand",tabState);
477
+
478
+ if (expandObj) {
479
+ Ttk_GetBorderFromObj(NULL, expandObj, &expand);
480
+ }
481
+
482
+ tab->parcel =
483
+ Ttk_ExpandBox(
484
+ Ttk_PositionBox(&tabrowBox,
485
+ tab->width, tab->height, tabPlacement),
486
+ expand);
487
+ }
488
+ }
489
+ }
490
+
491
+ /* NotebookDoLayout --
492
+ * Computes notebook layout and places tabs.
493
+ *
494
+ * Side effects:
495
+ * Sets clientArea, used to place slave panes.
496
+ */
497
+ static void NotebookDoLayout(void *recordPtr)
498
+ {
499
+ Notebook *nb = recordPtr;
500
+ Tk_Window nbwin = nb->core.tkwin;
501
+ Ttk_Box cavity = Ttk_WinBox(nbwin);
502
+ int tabrowWidth = 0, tabrowHeight = 0;
503
+ Ttk_LayoutNode *clientNode = Ttk_LayoutFindNode(nb->core.layout, "client");
504
+ Ttk_Box tabrowBox;
505
+ NotebookStyle nbstyle;
506
+
507
+ NotebookStyleOptions(nb, &nbstyle);
508
+
509
+ /* Notebook internal padding:
510
+ */
511
+ cavity = Ttk_PadBox(cavity, nbstyle.padding);
512
+
513
+ /* Layout for notebook background (base layout):
514
+ */
515
+ Ttk_PlaceLayout(nb->core.layout, nb->core.state, Ttk_WinBox(nbwin));
516
+
517
+ /* Place tabs:
518
+ */
519
+ TabrowSize(nb, nbstyle.tabOrient, &tabrowWidth, &tabrowHeight);
520
+ tabrowBox = Ttk_PadBox(
521
+ Ttk_PositionBox(&cavity,
522
+ tabrowWidth + Ttk_PaddingWidth(nbstyle.tabMargins),
523
+ tabrowHeight + Ttk_PaddingHeight(nbstyle.tabMargins),
524
+ nbstyle.tabPosition),
525
+ nbstyle.tabMargins);
526
+
527
+ if (tabrowWidth > tabrowBox.width) {
528
+ SqueezeTabs(nb, tabrowWidth, tabrowBox.width, nbstyle.minTabWidth);
529
+ }
530
+ PlaceTabs(nb, tabrowBox, nbstyle.tabPlacement);
531
+
532
+ /* Layout for client area frame:
533
+ */
534
+ if (clientNode) {
535
+ Ttk_PlaceLayoutNode(nb->core.layout, clientNode, cavity);
536
+ cavity = Ttk_LayoutNodeInternalParcel(nb->core.layout, clientNode);
537
+ }
538
+
539
+ if (cavity.height <= 0) cavity.height = 1;
540
+ if (cavity.width <= 0) cavity.width = 1;
541
+
542
+ nb->notebook.clientArea = cavity;
543
+ }
544
+
545
+ /*
546
+ * NotebookPlaceSlave --
547
+ * Set the position and size of a child widget
548
+ * based on the current client area and slave options:
549
+ */
550
+ static void NotebookPlaceSlave(Notebook *nb, int slaveIndex)
551
+ {
552
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, slaveIndex);
553
+ Tk_Window slaveWindow = Ttk_SlaveWindow(nb->notebook.mgr, slaveIndex);
554
+ Ttk_Box slaveBox =
555
+ Ttk_StickBox(Ttk_PadBox(nb->notebook.clientArea, tab->padding),
556
+ Tk_ReqWidth(slaveWindow), Tk_ReqHeight(slaveWindow),tab->sticky);
557
+
558
+ Ttk_PlaceSlave(nb->notebook.mgr, slaveIndex,
559
+ slaveBox.x, slaveBox.y, slaveBox.width, slaveBox.height);
560
+ }
561
+
562
+ /* NotebookPlaceSlaves --
563
+ * Geometry manager hook.
564
+ */
565
+ static void NotebookPlaceSlaves(void *recordPtr)
566
+ {
567
+ Notebook *nb = recordPtr;
568
+ int currentIndex = nb->notebook.currentIndex;
569
+ if (currentIndex >= 0) {
570
+ NotebookDoLayout(nb);
571
+ NotebookPlaceSlave(nb, currentIndex);
572
+ }
573
+ }
574
+
575
+ /*
576
+ * SelectTab(nb, index) --
577
+ * Change the currently-selected tab.
578
+ */
579
+ static void SelectTab(Notebook *nb, int index)
580
+ {
581
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr,index);
582
+ int currentIndex = nb->notebook.currentIndex;
583
+
584
+ if (index == currentIndex) {
585
+ return;
586
+ }
587
+
588
+ if (TabState(nb, index) & TTK_STATE_DISABLED) {
589
+ return;
590
+ }
591
+
592
+ /* Unhide the tab if it is currently hidden and being selected.
593
+ */
594
+ if (tab->state == TAB_STATE_HIDDEN) {
595
+ tab->state = TAB_STATE_NORMAL;
596
+ }
597
+
598
+ if (currentIndex >= 0) {
599
+ Ttk_UnmapSlave(nb->notebook.mgr, currentIndex);
600
+ }
601
+
602
+ NotebookPlaceSlave(nb, index);
603
+
604
+ nb->notebook.currentIndex = index;
605
+ TtkRedisplayWidget(&nb->core);
606
+
607
+ TtkSendVirtualEvent(nb->core.tkwin, "NotebookTabChanged");
608
+ }
609
+
610
+ /* NextTab --
611
+ * Returns the index of the next tab after the specified tab
612
+ * in the normal state (e.g., not hidden or disabled),
613
+ * or -1 if all tabs are disabled or hidden.
614
+ */
615
+ static int NextTab(Notebook *nb, int index)
616
+ {
617
+ int nTabs = Ttk_NumberSlaves(nb->notebook.mgr);
618
+ int nextIndex;
619
+
620
+ /* Scan forward for following usable tab:
621
+ */
622
+ for (nextIndex = index + 1; nextIndex < nTabs; ++nextIndex) {
623
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, nextIndex);
624
+ if (tab->state == TAB_STATE_NORMAL) {
625
+ return nextIndex;
626
+ }
627
+ }
628
+
629
+ /* Not found -- scan backwards.
630
+ */
631
+ for (nextIndex = index - 1; nextIndex >= 0; --nextIndex) {
632
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, nextIndex);
633
+ if (tab->state == TAB_STATE_NORMAL) {
634
+ return nextIndex;
635
+ }
636
+ }
637
+
638
+ /* Still nothing. Give up.
639
+ */
640
+ return -1;
641
+ }
642
+
643
+ /* SelectNearestTab --
644
+ * Handles the case where the current tab is forgotten, hidden,
645
+ * or destroyed.
646
+ *
647
+ * Unmap the current tab and schedule the next available one
648
+ * to be mapped at the next GM update.
649
+ */
650
+ static void SelectNearestTab(Notebook *nb)
651
+ {
652
+ int currentIndex = nb->notebook.currentIndex;
653
+ int nextIndex = NextTab(nb, currentIndex);
654
+
655
+ if (currentIndex >= 0) {
656
+ Ttk_UnmapSlave(nb->notebook.mgr, currentIndex);
657
+ }
658
+ if (currentIndex != nextIndex) {
659
+ TtkSendVirtualEvent(nb->core.tkwin, "NotebookTabChanged");
660
+ }
661
+
662
+ nb->notebook.currentIndex = nextIndex;
663
+ Ttk_ManagerLayoutChanged(nb->notebook.mgr);
664
+ TtkRedisplayWidget(&nb->core);
665
+ }
666
+
667
+ /* TabRemoved -- GM SlaveRemoved hook.
668
+ * Select the next tab if the current one is being removed.
669
+ * Adjust currentIndex to account for removed slave.
670
+ */
671
+ static void TabRemoved(void *managerData, int index)
672
+ {
673
+ Notebook *nb = managerData;
674
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, index);
675
+
676
+ if (index == nb->notebook.currentIndex) {
677
+ SelectNearestTab(nb);
678
+ }
679
+
680
+ if (index < nb->notebook.currentIndex) {
681
+ --nb->notebook.currentIndex;
682
+ }
683
+
684
+ DestroyTab(nb, tab);
685
+
686
+ TtkRedisplayWidget(&nb->core);
687
+ }
688
+
689
+ static int TabRequest(void *managerData, int index, int width, int height)
690
+ {
691
+ return 1;
692
+ }
693
+
694
+ /* AddTab --
695
+ * Add new tab at specified index.
696
+ */
697
+ static int AddTab(
698
+ Tcl_Interp *interp, Notebook *nb,
699
+ int destIndex, Tk_Window slaveWindow,
700
+ int objc, Tcl_Obj *const objv[])
701
+ {
702
+ Tab *tab;
703
+ if (!Ttk_Maintainable(interp, slaveWindow, nb->core.tkwin)) {
704
+ return TCL_ERROR;
705
+ }
706
+ #if 0 /* can't happen */
707
+ if (Ttk_SlaveIndex(nb->notebook.mgr, slaveWindow) >= 0) {
708
+ Tcl_AppendResult(interp,
709
+ Tk_PathName(slaveWindow), " already added",
710
+ NULL);
711
+ return TCL_ERROR;
712
+ }
713
+ #endif
714
+
715
+ /* Create and insert tab.
716
+ */
717
+ tab = CreateTab(interp, nb, slaveWindow);
718
+ if (!tab) {
719
+ return TCL_ERROR;
720
+ }
721
+ if (ConfigureTab(interp, nb, tab, slaveWindow, objc, objv) != TCL_OK) {
722
+ DestroyTab(nb, tab);
723
+ return TCL_ERROR;
724
+ }
725
+
726
+ Ttk_InsertSlave(nb->notebook.mgr, destIndex, slaveWindow, tab);
727
+
728
+ /* Adjust indices and/or autoselect first tab:
729
+ */
730
+ if (nb->notebook.currentIndex < 0) {
731
+ SelectTab(nb, destIndex);
732
+ } else if (nb->notebook.currentIndex >= destIndex) {
733
+ ++nb->notebook.currentIndex;
734
+ }
735
+
736
+ return TCL_OK;
737
+ }
738
+
739
+ static Ttk_ManagerSpec NotebookManagerSpec = {
740
+ { "notebook", Ttk_GeometryRequestProc, Ttk_LostSlaveProc },
741
+ NotebookSize,
742
+ NotebookPlaceSlaves,
743
+ TabRequest,
744
+ TabRemoved
745
+ };
746
+
747
+ /*------------------------------------------------------------------------
748
+ * +++ Event handlers.
749
+ */
750
+
751
+ /* NotebookEventHandler --
752
+ * Tracks the active tab.
753
+ */
754
+ static const int NotebookEventMask
755
+ = StructureNotifyMask
756
+ | PointerMotionMask
757
+ | LeaveWindowMask
758
+ ;
759
+ static void NotebookEventHandler(ClientData clientData, XEvent *eventPtr)
760
+ {
761
+ Notebook *nb = clientData;
762
+
763
+ if (eventPtr->type == DestroyNotify) { /* Remove self */
764
+ Tk_DeleteEventHandler(nb->core.tkwin,
765
+ NotebookEventMask, NotebookEventHandler, clientData);
766
+ } else if (eventPtr->type == MotionNotify) {
767
+ int index = IdentifyTab(nb, eventPtr->xmotion.x, eventPtr->xmotion.y);
768
+ ActivateTab(nb, index);
769
+ } else if (eventPtr->type == LeaveNotify) {
770
+ ActivateTab(nb, -1);
771
+ }
772
+ }
773
+
774
+ /*------------------------------------------------------------------------
775
+ * +++ Utilities.
776
+ */
777
+
778
+ /* FindTabIndex --
779
+ * Find the index of the specified tab.
780
+ * Tab identifiers are one of:
781
+ *
782
+ * + positional specifications @x,y,
783
+ * + "current",
784
+ * + numeric indices [0..nTabs],
785
+ * + slave window names
786
+ *
787
+ * Stores index of specified tab in *index_rtn, -1 if not found.
788
+ *
789
+ * Returns TCL_ERROR and leaves an error message in interp->result
790
+ * if the tab identifier was incorrect.
791
+ *
792
+ * See also: GetTabIndex.
793
+ */
794
+ static int FindTabIndex(
795
+ Tcl_Interp *interp, Notebook *nb, Tcl_Obj *objPtr, int *index_rtn)
796
+ {
797
+ const char *string = Tcl_GetString(objPtr);
798
+ int x, y;
799
+
800
+ *index_rtn = -1;
801
+
802
+ /* Check for @x,y ...
803
+ */
804
+ if (string[0] == '@' && sscanf(string, "@%d,%d",&x,&y) == 2) {
805
+ *index_rtn = IdentifyTab(nb, x, y);
806
+ return TCL_OK;
807
+ }
808
+
809
+ /* ... or "current" ...
810
+ */
811
+ if (!strcmp(string, "current")) {
812
+ *index_rtn = nb->notebook.currentIndex;
813
+ return TCL_OK;
814
+ }
815
+
816
+ /* ... or integer index or slave window name:
817
+ */
818
+ if (Ttk_GetSlaveIndexFromObj(
819
+ interp, nb->notebook.mgr, objPtr, index_rtn) == TCL_OK)
820
+ {
821
+ return TCL_OK;
822
+ }
823
+
824
+ /* Nothing matched; Ttk_GetSlaveIndexFromObj will have left error message.
825
+ */
826
+ return TCL_ERROR;
827
+ }
828
+
829
+ /* GetTabIndex --
830
+ * Get the index of an existing tab.
831
+ * Tab identifiers are as per FindTabIndex.
832
+ * Returns TCL_ERROR if the tab does not exist.
833
+ */
834
+ static int GetTabIndex(
835
+ Tcl_Interp *interp, Notebook *nb, Tcl_Obj *objPtr, int *index_rtn)
836
+ {
837
+ int status = FindTabIndex(interp, nb, objPtr, index_rtn);
838
+
839
+ if (status == TCL_OK && *index_rtn < 0) {
840
+ Tcl_ResetResult(interp);
841
+ Tcl_AppendResult(interp,
842
+ "tab '", Tcl_GetString(objPtr), "' not found",
843
+ NULL);
844
+ status = TCL_ERROR;
845
+ }
846
+ return status;
847
+ }
848
+
849
+ /*------------------------------------------------------------------------
850
+ * +++ Widget command routines.
851
+ */
852
+
853
+ /* $nb add window ?options ... ?
854
+ */
855
+ static int NotebookAddCommand(
856
+ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
857
+ {
858
+ Notebook *nb = recordPtr;
859
+ int index = Ttk_NumberSlaves(nb->notebook.mgr);
860
+ Tk_Window slaveWindow;
861
+ int slaveIndex;
862
+ Tab *tab;
863
+
864
+ if (objc <= 2 || objc % 2 != 1) {
865
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?options...?");
866
+ return TCL_ERROR;
867
+ }
868
+
869
+ slaveWindow = Tk_NameToWindow(interp,Tcl_GetString(objv[2]),nb->core.tkwin);
870
+ if (!slaveWindow) {
871
+ return TCL_ERROR;
872
+ }
873
+ slaveIndex = Ttk_SlaveIndex(nb->notebook.mgr, slaveWindow);
874
+
875
+ if (slaveIndex < 0) { /* New tab */
876
+ return AddTab(interp, nb, index, slaveWindow, objc-3,objv+3);
877
+ }
878
+
879
+ tab = Ttk_SlaveData(nb->notebook.mgr, slaveIndex);
880
+ if (tab->state == TAB_STATE_HIDDEN) {
881
+ tab->state = TAB_STATE_NORMAL;
882
+ }
883
+ if (ConfigureTab(interp, nb, tab, slaveWindow, objc-4,objv+4) != TCL_OK) {
884
+ return TCL_ERROR;
885
+ }
886
+
887
+ TtkRedisplayWidget(&nb->core);
888
+
889
+ return TCL_OK;
890
+ }
891
+
892
+ /* $nb insert $index $tab ?options...?
893
+ * Insert new tab, or move existing one.
894
+ */
895
+ static int NotebookInsertCommand(
896
+ Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], void *recordPtr)
897
+ {
898
+ Notebook *nb = recordPtr;
899
+ int current = nb->notebook.currentIndex;
900
+ int nSlaves = Ttk_NumberSlaves(nb->notebook.mgr);
901
+ int srcIndex, destIndex;
902
+
903
+ if (objc < 4) {
904
+ Tcl_WrongNumArgs(interp, 2,objv, "index slave ?options...?");
905
+ return TCL_ERROR;
906
+ }
907
+
908
+ if (!strcmp(Tcl_GetString(objv[2]), "end")) {
909
+ destIndex = Ttk_NumberSlaves(nb->notebook.mgr);
910
+ } else if (TCL_OK != Ttk_GetSlaveIndexFromObj(
911
+ interp, nb->notebook.mgr, objv[2], &destIndex)) {
912
+ return TCL_ERROR;
913
+ }
914
+
915
+ if (Tcl_GetString(objv[3])[0] == '.') {
916
+ /* Window name -- could be new or existing slave.
917
+ */
918
+ Tk_Window slaveWindow =
919
+ Tk_NameToWindow(interp,Tcl_GetString(objv[3]),nb->core.tkwin);
920
+
921
+ if (!slaveWindow) {
922
+ return TCL_ERROR;
923
+ }
924
+
925
+ srcIndex = Ttk_SlaveIndex(nb->notebook.mgr, slaveWindow);
926
+ if (srcIndex < 0) { /* New slave */
927
+ return AddTab(interp, nb, destIndex, slaveWindow, objc-4,objv+4);
928
+ }
929
+ } else if (Ttk_GetSlaveIndexFromObj(
930
+ interp, nb->notebook.mgr, objv[3], &srcIndex) != TCL_OK)
931
+ {
932
+ return TCL_ERROR;
933
+ }
934
+
935
+ /* Move existing slave:
936
+ */
937
+ if (ConfigureTab(interp, nb,
938
+ Ttk_SlaveData(nb->notebook.mgr,srcIndex),
939
+ Ttk_SlaveWindow(nb->notebook.mgr,srcIndex),
940
+ objc-4,objv+4) != TCL_OK)
941
+ {
942
+ return TCL_ERROR;
943
+ }
944
+
945
+ if (destIndex >= nSlaves) {
946
+ destIndex = nSlaves - 1;
947
+ }
948
+ Ttk_ReorderSlave(nb->notebook.mgr, srcIndex, destIndex);
949
+
950
+ /* Adjust internal indexes:
951
+ */
952
+ nb->notebook.activeIndex = -1;
953
+ if (current == srcIndex) {
954
+ nb->notebook.currentIndex = destIndex;
955
+ } else if (destIndex <= current && current < srcIndex) {
956
+ ++nb->notebook.currentIndex;
957
+ } else if (srcIndex < current && current <= destIndex) {
958
+ --nb->notebook.currentIndex;
959
+ }
960
+
961
+ TtkRedisplayWidget(&nb->core);
962
+
963
+ return TCL_OK;
964
+ }
965
+
966
+ /* $nb forget $tab --
967
+ * Removes the specified tab.
968
+ */
969
+ static int NotebookForgetCommand(
970
+ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
971
+ {
972
+ Notebook *nb = recordPtr;
973
+ int index;
974
+
975
+ if (objc != 3) {
976
+ Tcl_WrongNumArgs(interp, 2, objv, "tab");
977
+ return TCL_ERROR;
978
+ }
979
+
980
+ if (GetTabIndex(interp, nb, objv[2], &index) != TCL_OK) {
981
+ return TCL_ERROR;
982
+ }
983
+
984
+ Ttk_ForgetSlave(nb->notebook.mgr, index);
985
+
986
+ return TCL_OK;
987
+ }
988
+
989
+ /* $nb hide $tab --
990
+ * Hides the specified tab.
991
+ */
992
+ static int NotebookHideCommand(
993
+ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
994
+ {
995
+ Notebook *nb = recordPtr;
996
+ int index;
997
+ Tab *tab;
998
+
999
+ if (objc != 3) {
1000
+ Tcl_WrongNumArgs(interp, 2, objv, "tab");
1001
+ return TCL_ERROR;
1002
+ }
1003
+
1004
+ if (GetTabIndex(interp, nb, objv[2], &index) != TCL_OK) {
1005
+ return TCL_ERROR;
1006
+ }
1007
+
1008
+ tab = Ttk_SlaveData(nb->notebook.mgr, index);
1009
+ tab->state = TAB_STATE_HIDDEN;
1010
+ if (index == nb->notebook.currentIndex) {
1011
+ SelectNearestTab(nb);
1012
+ }
1013
+
1014
+ return TCL_OK;
1015
+ }
1016
+
1017
+ /* $nb identify $x $y --
1018
+ * Returns name of tab element at $x,$y; empty string if none.
1019
+ */
1020
+ static int NotebookIdentifyCommand(
1021
+ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
1022
+ {
1023
+ Notebook *nb = recordPtr;
1024
+ Ttk_LayoutNode *node = NULL;
1025
+ int x, y, tabIndex;
1026
+
1027
+ if (objc != 4) {
1028
+ Tcl_WrongNumArgs(interp, 2, objv, "x y");
1029
+ return TCL_ERROR;
1030
+ }
1031
+
1032
+ if ( Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK
1033
+ || Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)
1034
+ {
1035
+ return TCL_ERROR;
1036
+ }
1037
+
1038
+ tabIndex = IdentifyTab(nb, x, y);
1039
+ if (tabIndex >= 0) {
1040
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, tabIndex);
1041
+ Ttk_State state = TabState(nb, tabIndex);
1042
+ Ttk_Layout tabLayout = nb->notebook.tabLayout;
1043
+
1044
+ Ttk_RebindSublayout(tabLayout, tab);
1045
+ Ttk_PlaceLayout(tabLayout, state, tab->parcel);
1046
+
1047
+ node = Ttk_LayoutIdentify(tabLayout, x, y);
1048
+ }
1049
+
1050
+ if (node) {
1051
+ const char *elementName = Ttk_LayoutNodeName(node);
1052
+ Tcl_SetObjResult(interp,Tcl_NewStringObj(elementName,-1));
1053
+ }
1054
+
1055
+ return TCL_OK;
1056
+ }
1057
+
1058
+ /* $nb index $item --
1059
+ * Returns the integer index of the tab specified by $item,
1060
+ * the empty string if $item does not identify a tab.
1061
+ * See above for valid item formats.
1062
+ */
1063
+ static int NotebookIndexCommand(
1064
+ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
1065
+ {
1066
+ Notebook *nb = recordPtr;
1067
+ int index, status;
1068
+
1069
+ if (objc != 3) {
1070
+ Tcl_WrongNumArgs(interp, 2, objv, "tab");
1071
+ return TCL_ERROR;
1072
+ }
1073
+
1074
+ /*
1075
+ * Special-case for "end":
1076
+ */
1077
+ if (!strcmp("end", Tcl_GetString(objv[2]))) {
1078
+ int nSlaves = Ttk_NumberSlaves(nb->notebook.mgr);
1079
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(nSlaves));
1080
+ return TCL_OK;
1081
+ }
1082
+
1083
+ status = FindTabIndex(interp, nb, objv[2], &index);
1084
+ if (status == TCL_OK && index >= 0) {
1085
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
1086
+ }
1087
+
1088
+ return status;
1089
+ }
1090
+
1091
+ /* $nb select ?$item? --
1092
+ * Select the specified tab, or return the widget path of
1093
+ * the currently-selected pane.
1094
+ */
1095
+ static int NotebookSelectCommand(
1096
+ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
1097
+ {
1098
+ Notebook *nb = recordPtr;
1099
+
1100
+ if (objc == 2) {
1101
+ if (nb->notebook.currentIndex >= 0) {
1102
+ Tk_Window pane = Ttk_SlaveWindow(
1103
+ nb->notebook.mgr, nb->notebook.currentIndex);
1104
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(pane), -1));
1105
+ }
1106
+ return TCL_OK;
1107
+ } else if (objc == 3) {
1108
+ int index, status = GetTabIndex(interp, nb, objv[2], &index);
1109
+ if (status == TCL_OK) {
1110
+ SelectTab(nb, index);
1111
+ }
1112
+ return status;
1113
+ } /*else*/
1114
+ Tcl_WrongNumArgs(interp, 2, objv, "?tab?");
1115
+ return TCL_ERROR;
1116
+ }
1117
+
1118
+ /* $nb tabs --
1119
+ * Return list of tabs.
1120
+ */
1121
+ static int NotebookTabsCommand(
1122
+ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
1123
+ {
1124
+ Notebook *nb = recordPtr;
1125
+ Ttk_Manager *mgr = nb->notebook.mgr;
1126
+ Tcl_Obj *result;
1127
+ int i;
1128
+
1129
+ if (objc != 2) {
1130
+ Tcl_WrongNumArgs(interp, 2, objv, "");
1131
+ return TCL_ERROR;
1132
+ }
1133
+
1134
+ result = Tcl_NewListObj(0, NULL);
1135
+ for (i = 0; i < Ttk_NumberSlaves(mgr); ++i) {
1136
+ const char *pathName = Tk_PathName(Ttk_SlaveWindow(mgr,i));
1137
+ Tcl_ListObjAppendElement(interp, result, Tcl_NewStringObj(pathName,-1));
1138
+ }
1139
+ Tcl_SetObjResult(interp, result);
1140
+
1141
+ return TCL_OK;
1142
+ }
1143
+
1144
+ /* $nb tab $tab ?-option ?value -option value...??
1145
+ */
1146
+ static int NotebookTabCommand(
1147
+ Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[], void *recordPtr)
1148
+ {
1149
+ Notebook *nb = recordPtr;
1150
+ Ttk_Manager *mgr = nb->notebook.mgr;
1151
+ int index;
1152
+ Tk_Window slaveWindow;
1153
+ Tab *tab;
1154
+
1155
+ if (objc < 3) {
1156
+ Tcl_WrongNumArgs(interp, 2, objv, "tab ?-option ?value??...");
1157
+ return TCL_ERROR;
1158
+ }
1159
+
1160
+ if (GetTabIndex(interp, nb, objv[2], &index) != TCL_OK) {
1161
+ return TCL_ERROR;
1162
+ }
1163
+
1164
+ tab = Ttk_SlaveData(mgr, index);
1165
+ slaveWindow = Ttk_SlaveWindow(mgr, index);
1166
+
1167
+ if (objc == 3) {
1168
+ return TtkEnumerateOptions(interp, tab,
1169
+ PaneOptionSpecs, nb->notebook.paneOptionTable, slaveWindow);
1170
+ } else if (objc == 4) {
1171
+ return TtkGetOptionValue(interp, tab, objv[3],
1172
+ nb->notebook.paneOptionTable, slaveWindow);
1173
+ } /* else */
1174
+
1175
+ if (ConfigureTab(interp, nb, tab, slaveWindow, objc-3,objv+3) != TCL_OK) {
1176
+ return TCL_ERROR;
1177
+ }
1178
+
1179
+ /* If the current tab has become disabled or hidden,
1180
+ * select the next nondisabled, unhidden one:
1181
+ */
1182
+ if (index == nb->notebook.currentIndex && tab->state != TAB_STATE_NORMAL) {
1183
+ SelectNearestTab(nb);
1184
+ }
1185
+
1186
+ TtkResizeWidget(&nb->core);
1187
+ return TCL_OK;
1188
+ }
1189
+
1190
+ /* Subcommand table:
1191
+ */
1192
+ static WidgetCommandSpec NotebookCommands[] =
1193
+ {
1194
+ { "add", NotebookAddCommand },
1195
+ { "configure", TtkWidgetConfigureCommand },
1196
+ { "cget", TtkWidgetCgetCommand },
1197
+ { "forget", NotebookForgetCommand },
1198
+ { "hide", NotebookHideCommand },
1199
+ { "identify", NotebookIdentifyCommand },
1200
+ { "index", NotebookIndexCommand },
1201
+ { "insert", NotebookInsertCommand },
1202
+ { "instate", TtkWidgetInstateCommand },
1203
+ { "select", NotebookSelectCommand },
1204
+ { "state", TtkWidgetStateCommand },
1205
+ { "tab", NotebookTabCommand },
1206
+ { "tabs", NotebookTabsCommand },
1207
+ { 0,0 }
1208
+ };
1209
+
1210
+ /*------------------------------------------------------------------------
1211
+ * +++ Widget class hooks.
1212
+ */
1213
+
1214
+ static int NotebookInitialize(Tcl_Interp *interp, void *recordPtr)
1215
+ {
1216
+ Notebook *nb = recordPtr;
1217
+
1218
+ nb->notebook.mgr = Ttk_CreateManager(
1219
+ &NotebookManagerSpec, recordPtr, nb->core.tkwin);
1220
+
1221
+ nb->notebook.tabOptionTable = Tk_CreateOptionTable(interp,TabOptionSpecs);
1222
+ nb->notebook.paneOptionTable = Tk_CreateOptionTable(interp,PaneOptionSpecs);
1223
+
1224
+ nb->notebook.currentIndex = -1;
1225
+ nb->notebook.activeIndex = -1;
1226
+ nb->notebook.tabLayout = 0;
1227
+
1228
+ nb->notebook.clientArea = Ttk_MakeBox(0,0,1,1);
1229
+
1230
+ Tk_CreateEventHandler(
1231
+ nb->core.tkwin, NotebookEventMask, NotebookEventHandler, recordPtr);
1232
+
1233
+ return TCL_OK;
1234
+ }
1235
+
1236
+ static void NotebookCleanup(void *recordPtr)
1237
+ {
1238
+ Notebook *nb = recordPtr;
1239
+
1240
+ Ttk_DeleteManager(nb->notebook.mgr);
1241
+ Tk_DeleteOptionTable(nb->notebook.tabOptionTable);
1242
+ Tk_DeleteOptionTable(nb->notebook.paneOptionTable);
1243
+
1244
+ if (nb->notebook.tabLayout)
1245
+ Ttk_FreeLayout(nb->notebook.tabLayout);
1246
+ }
1247
+
1248
+ static int NotebookConfigure(Tcl_Interp *interp, void *clientData, int mask)
1249
+ {
1250
+ Notebook *nb = clientData;
1251
+
1252
+ /*
1253
+ * Error-checks:
1254
+ */
1255
+ if (nb->notebook.paddingObj) {
1256
+ /* Check for valid -padding: */
1257
+ Ttk_Padding unused;
1258
+ if (Ttk_GetPaddingFromObj(
1259
+ interp, nb->core.tkwin, nb->notebook.paddingObj, &unused)
1260
+ != TCL_OK) {
1261
+ return TCL_ERROR;
1262
+ }
1263
+ }
1264
+
1265
+ return TtkCoreConfigure(interp, clientData, mask);
1266
+ }
1267
+
1268
+ /* NotebookGetLayout --
1269
+ * GetLayout widget hook.
1270
+ */
1271
+ static Ttk_Layout NotebookGetLayout(
1272
+ Tcl_Interp *interp, Ttk_Theme theme, void *recordPtr)
1273
+ {
1274
+ Notebook *nb = recordPtr;
1275
+ Ttk_Layout notebookLayout = TtkWidgetGetLayout(interp, theme, recordPtr);
1276
+ Ttk_Layout tabLayout;
1277
+
1278
+ if (!notebookLayout) {
1279
+ return NULL;
1280
+ }
1281
+
1282
+ tabLayout = Ttk_CreateSublayout(
1283
+ interp, theme, notebookLayout, ".Tab", nb->notebook.tabOptionTable);
1284
+
1285
+ if (tabLayout) {
1286
+ if (nb->notebook.tabLayout) {
1287
+ Ttk_FreeLayout(nb->notebook.tabLayout);
1288
+ }
1289
+ nb->notebook.tabLayout = tabLayout;
1290
+ }
1291
+
1292
+ return notebookLayout;
1293
+ }
1294
+
1295
+ /*------------------------------------------------------------------------
1296
+ * +++ Display routines.
1297
+ */
1298
+
1299
+ static void DisplayTab(Notebook *nb, int index, Drawable d)
1300
+ {
1301
+ Ttk_Layout tabLayout = nb->notebook.tabLayout;
1302
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, index);
1303
+ Ttk_State state = TabState(nb, index);
1304
+
1305
+ if (tab->state != TAB_STATE_HIDDEN) {
1306
+ Ttk_RebindSublayout(tabLayout, tab);
1307
+ Ttk_PlaceLayout(tabLayout, state, tab->parcel);
1308
+ Ttk_DrawLayout(tabLayout, state, d);
1309
+ }
1310
+ }
1311
+
1312
+ static void NotebookDisplay(void *clientData, Drawable d)
1313
+ {
1314
+ Notebook *nb = clientData;
1315
+ int nSlaves = Ttk_NumberSlaves(nb->notebook.mgr);
1316
+ int index;
1317
+
1318
+ /* Draw notebook background (base layout):
1319
+ */
1320
+ Ttk_DrawLayout(nb->core.layout, nb->core.state, d);
1321
+
1322
+ /* Draw tabs from left to right, but draw the current tab last
1323
+ * so it will overwrite its neighbors.
1324
+ */
1325
+ for (index = 0; index < nSlaves; ++index) {
1326
+ if (index != nb->notebook.currentIndex) {
1327
+ DisplayTab(nb, index, d);
1328
+ }
1329
+ }
1330
+ if (nb->notebook.currentIndex >= 0) {
1331
+ DisplayTab(nb, nb->notebook.currentIndex, d);
1332
+ }
1333
+ }
1334
+
1335
+ /*------------------------------------------------------------------------
1336
+ * +++ Widget specification and layout definitions.
1337
+ */
1338
+
1339
+ static WidgetSpec NotebookWidgetSpec =
1340
+ {
1341
+ "TNotebook", /* className */
1342
+ sizeof(Notebook), /* recordSize */
1343
+ NotebookOptionSpecs, /* optionSpecs */
1344
+ NotebookCommands, /* subcommands */
1345
+ NotebookInitialize, /* initializeProc */
1346
+ NotebookCleanup, /* cleanupProc */
1347
+ NotebookConfigure, /* configureProc */
1348
+ TtkNullPostConfigure, /* postConfigureProc */
1349
+ NotebookGetLayout, /* getLayoutProc */
1350
+ NotebookSize, /* geometryProc */
1351
+ NotebookDoLayout, /* layoutProc */
1352
+ NotebookDisplay /* displayProc */
1353
+ };
1354
+
1355
+ TTK_BEGIN_LAYOUT(NotebookLayout)
1356
+ TTK_NODE("Notebook.client", TTK_FILL_BOTH)
1357
+ TTK_END_LAYOUT
1358
+
1359
+ TTK_BEGIN_LAYOUT(TabLayout)
1360
+ TTK_GROUP("Notebook.tab", TTK_FILL_BOTH,
1361
+ TTK_GROUP("Notebook.padding", TTK_PACK_TOP|TTK_FILL_BOTH,
1362
+ TTK_GROUP("Notebook.focus", TTK_PACK_TOP|TTK_FILL_BOTH,
1363
+ TTK_NODE("Notebook.label", TTK_PACK_TOP))))
1364
+ TTK_END_LAYOUT
1365
+
1366
+ /*------------------------------------------------------------------------
1367
+ * +++ Initialization.
1368
+ */
1369
+
1370
+ void TtkNotebook_Init(Tcl_Interp *interp)
1371
+ {
1372
+ Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp);
1373
+
1374
+ Ttk_RegisterLayout(themePtr, "Tab", TabLayout);
1375
+ Ttk_RegisterLayout(themePtr, "TNotebook", NotebookLayout);
1376
+
1377
+ RegisterWidget(interp, "ttk::notebook", &NotebookWidgetSpec);
1378
+ }
1379
+
1380
+ /*EOF*/