Pratt 1.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,958 @@
1
+ /* paned.c,v 1.21 2007/11/25 17:17:10 jenglish Exp
2
+ *
3
+ * Copyright (c) 2005, Joe English. Freely redistributable.
4
+ *
5
+ * ttk::panedwindow widget implementation.
6
+ *
7
+ * TODO: track active/pressed sash.
8
+ */
9
+
10
+ #include <string.h>
11
+ #include <tk.h>
12
+ #include "manager.h"
13
+ #include "tkTheme.h"
14
+ #include "widget.h"
15
+
16
+ #define MIN_SASH_THICKNESS 5
17
+
18
+ /*------------------------------------------------------------------------
19
+ * +++ Layout algorithm.
20
+ *
21
+ * (pos=x/y, size=width/height, depending on -orient=horizontal/vertical)
22
+ *
23
+ * Each pane carries two pieces of state: the request size and the
24
+ * position of the following sash. (The final pane has no sash,
25
+ * its sash position is used as a sentinel value).
26
+ *
27
+ * Pane geometry is determined by the sash positions.
28
+ * When resizing, sash positions are computed from the request sizes,
29
+ * the available space, and pane weights (see PlaceSashes()).
30
+ * This ensures continuous resize behavior (that is: changing
31
+ * the size by X pixels then changing the size by Y pixels
32
+ * gives the same result as changing the size by X+Y pixels
33
+ * in one step).
34
+ *
35
+ * The request size is initially set to the slave window's requested size.
36
+ * When the user drags a sash, each pane's request size is set to its
37
+ * actual size. This ensures that panes "stay put" on the next resize.
38
+ *
39
+ * If reqSize == 0, use 0 for the weight as well. This ensures that
40
+ * "collapsed" panes stay collapsed during a resize, regardless of
41
+ * their nominal -weight.
42
+ *
43
+ * +++ Invariants.
44
+ *
45
+ * #sash = #pane - 1
46
+ * pos(pane[0]) = 0
47
+ * pos(sash[i]) = pos(pane[i]) + size(pane[i]), 0 <= i <= #sash
48
+ * pos(pane[i+1]) = pos(sash[i]) + size(sash[i]), 0 <= i < #sash
49
+ * pos(sash[#sash]) = size(pw) // sentinel value, constraint
50
+ *
51
+ * size(pw) = sum(size(pane(0..#pane))) + sum(size(sash(0..#sash)))
52
+ * size(pane[i]) >= 0, for 0 <= i < #pane
53
+ * size(sash[i]) >= 0, for 0 <= i < #sash
54
+ * ==> pos(pane[i]) <= pos(sash[i]) <= pos(pane[i+1]), for 0 <= i < #sash
55
+ *
56
+ * Assumption: all sashes are the same size.
57
+ */
58
+
59
+ /*------------------------------------------------------------------------
60
+ * +++ Widget record.
61
+ */
62
+
63
+ typedef struct {
64
+ Tcl_Obj *orientObj;
65
+ int orient;
66
+ int width;
67
+ int height;
68
+ Ttk_Manager *mgr;
69
+ Tk_OptionTable paneOptionTable;
70
+ Ttk_Layout sashLayout;
71
+ int sashThickness;
72
+ } PanedPart;
73
+
74
+ typedef struct {
75
+ WidgetCore core;
76
+ PanedPart paned;
77
+ } Paned;
78
+
79
+ /* @@@ NOTE: -orient is readonly 'cause dynamic oriention changes NYI
80
+ */
81
+ static Tk_OptionSpec PanedOptionSpecs[] = {
82
+ {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "vertical",
83
+ Tk_Offset(Paned,paned.orientObj), Tk_Offset(Paned,paned.orient),
84
+ 0,(ClientData)ttkOrientStrings,READONLY_OPTION|STYLE_CHANGED },
85
+ {TK_OPTION_INT, "-width", "width", "Width", "0",
86
+ -1,Tk_Offset(Paned,paned.width),
87
+ 0,0,GEOMETRY_CHANGED },
88
+ {TK_OPTION_INT, "-height", "height", "Height", "0",
89
+ -1,Tk_Offset(Paned,paned.height),
90
+ 0,0,GEOMETRY_CHANGED },
91
+
92
+ WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
93
+ };
94
+
95
+ /*------------------------------------------------------------------------
96
+ * +++ Slave pane record.
97
+ */
98
+ typedef struct {
99
+ int reqSize; /* Pane request size */
100
+ int sashPos; /* Folowing sash position */
101
+ int weight; /* Pane -weight, for resizing */
102
+ } Pane;
103
+
104
+ static Tk_OptionSpec PaneOptionSpecs[] = {
105
+ {TK_OPTION_INT, "-weight", "weight", "Weight", "0",
106
+ -1,Tk_Offset(Pane,weight), 0,0,GEOMETRY_CHANGED },
107
+ {TK_OPTION_END, 0,0,0, NULL, -1,-1, 0,0,0}
108
+ };
109
+
110
+ /* CreatePane --
111
+ * Create a new pane record.
112
+ */
113
+ static Pane *CreatePane(Tcl_Interp *interp, Paned *pw, Tk_Window slaveWindow)
114
+ {
115
+ Tk_OptionTable optionTable = pw->paned.paneOptionTable;
116
+ void *record = ckalloc(sizeof(Pane));
117
+ Pane *pane = record;
118
+
119
+ memset(record, 0, sizeof(Pane));
120
+ if (Tk_InitOptions(interp, record, optionTable, slaveWindow) != TCL_OK) {
121
+ ckfree(record);
122
+ return NULL;
123
+ }
124
+
125
+ pane->reqSize
126
+ = pw->paned.orient == TTK_ORIENT_HORIZONTAL
127
+ ? Tk_ReqWidth(slaveWindow) : Tk_ReqHeight(slaveWindow);
128
+
129
+ return pane;
130
+ }
131
+
132
+ /* DestroyPane --
133
+ * Free pane record.
134
+ */
135
+ static void DestroyPane(Paned *pw, Pane *pane)
136
+ {
137
+ void *record = pane;
138
+ Tk_FreeConfigOptions(record, pw->paned.paneOptionTable, pw->core.tkwin);
139
+ ckfree(record);
140
+ }
141
+
142
+ /* ConfigurePane --
143
+ * Set pane options.
144
+ */
145
+ static int ConfigurePane(
146
+ Tcl_Interp *interp, Paned *pw, Pane *pane, Tk_Window slaveWindow,
147
+ int objc, Tcl_Obj *CONST objv[])
148
+ {
149
+ Ttk_Manager *mgr = pw->paned.mgr;
150
+ Tk_SavedOptions savedOptions;
151
+ int mask = 0;
152
+
153
+ if (Tk_SetOptions(interp, (void*)pane, pw->paned.paneOptionTable,
154
+ objc, objv, slaveWindow, &savedOptions, &mask) != TCL_OK)
155
+ {
156
+ return TCL_ERROR;
157
+ }
158
+
159
+ /* Sanity-check:
160
+ */
161
+ if (pane->weight < 0) {
162
+ Tcl_AppendResult(interp, "-weight must be nonnegative", NULL);
163
+ goto error;
164
+ }
165
+
166
+ /* Done.
167
+ */
168
+ Tk_FreeSavedOptions(&savedOptions);
169
+ Ttk_ManagerSizeChanged(mgr);
170
+ return TCL_OK;
171
+
172
+ error:
173
+ Tk_RestoreSavedOptions(&savedOptions);
174
+ return TCL_ERROR;
175
+ }
176
+
177
+
178
+ /*------------------------------------------------------------------------
179
+ * +++ Sash adjustment.
180
+ */
181
+
182
+ /* ShoveUp --
183
+ * Place sash i at specified position, recursively shoving
184
+ * previous sashes upwards as needed, until hitting the top
185
+ * of the window. If that happens, shove back down.
186
+ *
187
+ * Returns: final position of sash i.
188
+ */
189
+
190
+ static int ShoveUp(Paned *pw, int i, int pos)
191
+ {
192
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, i);
193
+ int sashThickness = pw->paned.sashThickness;
194
+
195
+ if (i == 0) {
196
+ if (pos < 0)
197
+ pos = 0;
198
+ } else {
199
+ Pane *prevPane = Ttk_SlaveData(pw->paned.mgr, i-1);
200
+ if (pos < prevPane->sashPos + sashThickness)
201
+ pos = ShoveUp(pw, i-1, pos - sashThickness) + sashThickness;
202
+ }
203
+ return pane->sashPos = pos;
204
+ }
205
+
206
+ /* ShoveDown --
207
+ * Same as ShoveUp, but going in the opposite direction
208
+ * and stopping at the sentinel sash.
209
+ */
210
+ static int ShoveDown(Paned *pw, int i, int pos)
211
+ {
212
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr,i);
213
+ int sashThickness = pw->paned.sashThickness;
214
+
215
+ if (i == Ttk_NumberSlaves(pw->paned.mgr) - 1) {
216
+ pos = pane->sashPos; /* Sentinel value == master window size */
217
+ } else {
218
+ Pane *nextPane = Ttk_SlaveData(pw->paned.mgr,i+1);
219
+ if (pos + sashThickness > nextPane->sashPos)
220
+ pos = ShoveDown(pw, i+1, pos + sashThickness) - sashThickness;
221
+ }
222
+ return pane->sashPos = pos;
223
+ }
224
+
225
+ /* PanedSize --
226
+ * Compute the requested size of the paned widget
227
+ * from the individual pane request sizes.
228
+ *
229
+ * Used as the WidgetSpec sizeProc and the ManagerSpec sizeProc.
230
+ */
231
+ static int PanedSize(void *recordPtr, int *widthPtr, int *heightPtr)
232
+ {
233
+ Paned *pw = recordPtr;
234
+ int nPanes = Ttk_NumberSlaves(pw->paned.mgr);
235
+ int nSashes = nPanes - 1;
236
+ int sashThickness = pw->paned.sashThickness;
237
+ int width = 0, height = 0;
238
+ int index;
239
+
240
+ if (pw->paned.orient == TTK_ORIENT_HORIZONTAL) {
241
+ for (index = 0; index < nPanes; ++index) {
242
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, index);
243
+ Tk_Window slaveWindow = Ttk_SlaveWindow(pw->paned.mgr, index);
244
+
245
+ if (height < Tk_ReqHeight(slaveWindow))
246
+ height = Tk_ReqHeight(slaveWindow);
247
+ width += pane->reqSize;
248
+ }
249
+ width += nSashes * sashThickness;
250
+ } else {
251
+ for (index = 0; index < nPanes; ++index) {
252
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, index);
253
+ Tk_Window slaveWindow = Ttk_SlaveWindow(pw->paned.mgr, index);
254
+
255
+ if (width < Tk_ReqWidth(slaveWindow))
256
+ width = Tk_ReqWidth(slaveWindow);
257
+ height += pane->reqSize;
258
+ }
259
+ height += nSashes * sashThickness;
260
+ }
261
+
262
+ *widthPtr = pw->paned.width > 0 ? pw->paned.width : width;
263
+ *heightPtr = pw->paned.height > 0 ? pw->paned.height : height;
264
+ return 1;
265
+ }
266
+
267
+ /* AdjustPanes --
268
+ * Set pane request sizes from sash positions.
269
+ *
270
+ * NOTE:
271
+ * AdjustPanes followed by PlaceSashes (called during relayout)
272
+ * will leave the sashes in the same place, as long as available size
273
+ * remains contant.
274
+ */
275
+ static void AdjustPanes(Paned *pw)
276
+ {
277
+ int sashThickness = pw->paned.sashThickness;
278
+ int pos = 0;
279
+ int index;
280
+
281
+ for (index = 0; index < Ttk_NumberSlaves(pw->paned.mgr); ++index) {
282
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, index);
283
+ int size = pane->sashPos - pos;
284
+ pane->reqSize = size >= 0 ? size : 0;
285
+ pos = pane->sashPos + sashThickness;
286
+ }
287
+ }
288
+
289
+ /* PlaceSashes --
290
+ * Set sash positions from pane request sizes and available space.
291
+ * The sentinel sash position is set to the available space.
292
+ *
293
+ * Allocate pane->reqSize pixels to each pane, and distribute
294
+ * the difference = available size - requested size according
295
+ * to pane->weight.
296
+ *
297
+ * If there's still some left over, squeeze panes from the bottom up
298
+ * (This can happen if all weights are zero, or if one or more panes
299
+ * are too small to absorb the required shrinkage).
300
+ *
301
+ * Notes:
302
+ * This doesn't distribute the remainder pixels as evenly as it could
303
+ * when more than one pane has weight > 1.
304
+ */
305
+ static void PlaceSashes(Paned *pw, int width, int height)
306
+ {
307
+ Ttk_Manager *mgr = pw->paned.mgr;
308
+ int nPanes = Ttk_NumberSlaves(mgr);
309
+ int sashThickness = pw->paned.sashThickness;
310
+ int available = pw->paned.orient == TTK_ORIENT_HORIZONTAL ? width : height;
311
+ int reqSize = 0, totalWeight = 0;
312
+ int difference, delta, remainder, pos, i;
313
+
314
+ if (nPanes == 0)
315
+ return;
316
+
317
+ /* Compute total required size and total available weight:
318
+ */
319
+ for (i = 0; i < nPanes; ++i) {
320
+ Pane *pane = Ttk_SlaveData(mgr, i);
321
+ reqSize += pane->reqSize;
322
+ totalWeight += pane->weight * (pane->reqSize != 0);
323
+ }
324
+
325
+ /* Compute difference to be redistributed:
326
+ */
327
+ difference = available - reqSize - sashThickness*(nPanes-1);
328
+ if (totalWeight != 0) {
329
+ delta = difference / totalWeight;
330
+ remainder = difference % totalWeight;
331
+ if (remainder < 0) {
332
+ --delta;
333
+ remainder += totalWeight;
334
+ }
335
+ } else {
336
+ delta = remainder = 0;
337
+ }
338
+ /* ASSERT: 0 <= remainder < totalWeight */
339
+
340
+ /* Place sashes:
341
+ */
342
+ pos = 0;
343
+ for (i = 0; i < nPanes; ++i) {
344
+ Pane *pane = Ttk_SlaveData(mgr, i);
345
+ int weight = pane->weight * (pane->reqSize != 0);
346
+ int size = pane->reqSize + delta * weight;
347
+
348
+ if (weight > remainder)
349
+ weight = remainder;
350
+ remainder -= weight;
351
+ size += weight;
352
+
353
+ if (size < 0)
354
+ size = 0;
355
+
356
+ pane->sashPos = (pos += size);
357
+ pos += sashThickness;
358
+ }
359
+
360
+ /* Handle emergency shrink/emergency stretch:
361
+ * Set sentinel sash position to end of widget,
362
+ * shove preceding sashes up.
363
+ */
364
+ ShoveUp(pw, nPanes - 1, available);
365
+ }
366
+
367
+ /* PlacePanes --
368
+ * Places slave panes based on sash positions.
369
+ */
370
+ static void PlacePanes(Paned *pw)
371
+ {
372
+ int horizontal = pw->paned.orient == TTK_ORIENT_HORIZONTAL;
373
+ int width = Tk_Width(pw->core.tkwin), height = Tk_Height(pw->core.tkwin);
374
+ int sashThickness = pw->paned.sashThickness;
375
+ int pos = 0;
376
+ int index;
377
+
378
+ for (index = 0; index < Ttk_NumberSlaves(pw->paned.mgr); ++index) {
379
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, index);
380
+ int size = pane->sashPos - pos;
381
+
382
+ if (size > 0) {
383
+ if (horizontal) {
384
+ Ttk_PlaceSlave(pw->paned.mgr, index, pos, 0, size, height);
385
+ } else {
386
+ Ttk_PlaceSlave(pw->paned.mgr, index, 0, pos, width, size);
387
+ }
388
+ } else {
389
+ Ttk_UnmapSlave(pw->paned.mgr, index);
390
+ }
391
+
392
+ pos = pane->sashPos + sashThickness;
393
+ }
394
+ }
395
+
396
+ /*------------------------------------------------------------------------
397
+ * +++ Manager specification.
398
+ */
399
+
400
+ static void PanedPlaceSlaves(void *managerData)
401
+ {
402
+ Paned *pw = managerData;
403
+ PlaceSashes(pw, Tk_Width(pw->core.tkwin), Tk_Height(pw->core.tkwin));
404
+ PlacePanes(pw);
405
+ }
406
+
407
+ static void PaneRemoved(void *managerData, int index)
408
+ {
409
+ Paned *pw = managerData;
410
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, index);
411
+ DestroyPane(pw, pane);
412
+ }
413
+
414
+ static int AddPane(
415
+ Tcl_Interp *interp, Paned *pw,
416
+ int destIndex, Tk_Window slaveWindow,
417
+ int objc, Tcl_Obj *const objv[])
418
+ {
419
+ Pane *pane;
420
+ if (!Ttk_Maintainable(interp, slaveWindow, pw->core.tkwin)) {
421
+ return TCL_ERROR;
422
+ }
423
+ if (Ttk_SlaveIndex(pw->paned.mgr, slaveWindow) >= 0) {
424
+ Tcl_AppendResult(interp,
425
+ Tk_PathName(slaveWindow), " already added",
426
+ NULL);
427
+ return TCL_ERROR;
428
+ }
429
+
430
+ pane = CreatePane(interp, pw, slaveWindow);
431
+ if (!pane) {
432
+ return TCL_ERROR;
433
+ }
434
+ if (ConfigurePane(interp, pw, pane, slaveWindow, objc, objv) != TCL_OK) {
435
+ DestroyPane(pw, pane);
436
+ return TCL_ERROR;
437
+ }
438
+
439
+ Ttk_InsertSlave(pw->paned.mgr, destIndex, slaveWindow, pane);
440
+ return TCL_OK;
441
+ }
442
+
443
+ /* PaneRequest --
444
+ * Only update pane request size if slave is currently unmapped.
445
+ * Geometry requests from mapped slaves are not directly honored
446
+ * in order to avoid unexpected pane resizes (esp. while the
447
+ * user is dragging a sash [#1325286]).
448
+ */
449
+ static int PaneRequest(void *managerData, int index, int width, int height)
450
+ {
451
+ Paned *pw = managerData;
452
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, index);
453
+ Tk_Window slaveWindow = Ttk_SlaveWindow(pw->paned.mgr, index);
454
+ int horizontal = pw->paned.orient == TTK_ORIENT_HORIZONTAL;
455
+
456
+ if (!Tk_IsMapped(slaveWindow)) {
457
+ pane->reqSize = horizontal ? width : height;
458
+ }
459
+ return 1;
460
+ }
461
+
462
+ static Ttk_ManagerSpec PanedManagerSpec = {
463
+ { "panedwindow", Ttk_GeometryRequestProc, Ttk_LostSlaveProc },
464
+ PanedSize,
465
+ PanedPlaceSlaves,
466
+ PaneRequest,
467
+ PaneRemoved
468
+ };
469
+
470
+ /*------------------------------------------------------------------------
471
+ * +++ Event handler.
472
+ *
473
+ * <<NOTE-PW-LEAVE-NOTIFYINFERIOR>>
474
+ * Tk does not execute binding scripts for <Leave> events when
475
+ * the pointer crosses from a parent to a child. This widget
476
+ * needs to know when that happens, though, so it can reset
477
+ * the cursor.
478
+ *
479
+ * This event handler generates an <<EnteredChild>> virtual event
480
+ * on LeaveNotify/NotifyInferior.
481
+ */
482
+
483
+ static const unsigned PanedEventMask = LeaveWindowMask;
484
+ static void PanedEventProc(ClientData clientData, XEvent *eventPtr)
485
+ {
486
+ WidgetCore *corePtr = clientData;
487
+ if ( eventPtr->type == LeaveNotify
488
+ && eventPtr->xcrossing.detail == NotifyInferior)
489
+ {
490
+ TtkSendVirtualEvent(corePtr->tkwin, "EnteredChild");
491
+ }
492
+ }
493
+
494
+ /*------------------------------------------------------------------------
495
+ * +++ Initialization and cleanup hooks.
496
+ */
497
+
498
+ static int PanedInitialize(Tcl_Interp *interp, void *recordPtr)
499
+ {
500
+ Paned *pw = recordPtr;
501
+
502
+ Tk_CreateEventHandler(pw->core.tkwin,
503
+ PanedEventMask, PanedEventProc, recordPtr);
504
+ pw->paned.mgr = Ttk_CreateManager(&PanedManagerSpec, pw, pw->core.tkwin);
505
+ pw->paned.paneOptionTable = Tk_CreateOptionTable(interp,PaneOptionSpecs);
506
+ pw->paned.sashLayout = 0;
507
+ pw->paned.sashThickness = 1;
508
+
509
+ return TCL_OK;
510
+ }
511
+
512
+ static void PanedCleanup(void *recordPtr)
513
+ {
514
+ Paned *pw = recordPtr;
515
+
516
+ if (pw->paned.sashLayout)
517
+ Ttk_FreeLayout(pw->paned.sashLayout);
518
+ Tk_DeleteEventHandler(pw->core.tkwin,
519
+ PanedEventMask, PanedEventProc, recordPtr);
520
+ Ttk_DeleteManager(pw->paned.mgr);
521
+ }
522
+
523
+ /* Post-configuration hook.
524
+ */
525
+ static int PanedPostConfigure(Tcl_Interp *interp, void *clientData, int mask)
526
+ {
527
+ Paned *pw = clientData;
528
+
529
+ if (mask & GEOMETRY_CHANGED) {
530
+ /* User has changed -width or -height.
531
+ * Recalculate sash positions based on requested size.
532
+ */
533
+ Tk_Window tkwin = pw->core.tkwin;
534
+ PlaceSashes(pw,
535
+ pw->paned.width > 0 ? pw->paned.width : Tk_Width(tkwin),
536
+ pw->paned.height > 0 ? pw->paned.height : Tk_Height(tkwin));
537
+ }
538
+
539
+ return TCL_OK;
540
+ }
541
+
542
+ /*------------------------------------------------------------------------
543
+ * +++ Layout management hooks.
544
+ */
545
+ static Ttk_Layout PanedGetLayout(
546
+ Tcl_Interp *interp, Ttk_Theme themePtr, void *recordPtr)
547
+ {
548
+ Paned *pw = recordPtr;
549
+ Ttk_Layout panedLayout = TtkWidgetGetLayout(interp, themePtr, recordPtr);
550
+
551
+ if (panedLayout) {
552
+ int horizontal = pw->paned.orient == TTK_ORIENT_HORIZONTAL;
553
+ const char *layoutName =
554
+ horizontal ? ".Vertical.Sash" : ".Horizontal.Sash";
555
+ Ttk_Layout sashLayout = Ttk_CreateSublayout(
556
+ interp, themePtr, panedLayout, layoutName, pw->core.optionTable);
557
+
558
+ if (sashLayout) {
559
+ int sashWidth, sashHeight;
560
+
561
+ Ttk_LayoutSize(sashLayout, 0, &sashWidth, &sashHeight);
562
+ pw->paned.sashThickness = horizontal ? sashWidth : sashHeight;
563
+
564
+ if (pw->paned.sashLayout)
565
+ Ttk_FreeLayout(pw->paned.sashLayout);
566
+ pw->paned.sashLayout = sashLayout;
567
+ } else {
568
+ Ttk_FreeLayout(panedLayout);
569
+ return 0;
570
+ }
571
+ }
572
+
573
+ /* Sanity-check:
574
+ */
575
+ if (pw->paned.sashThickness < MIN_SASH_THICKNESS)
576
+ pw->paned.sashThickness = MIN_SASH_THICKNESS;
577
+
578
+ return panedLayout;
579
+ }
580
+
581
+ /*------------------------------------------------------------------------
582
+ * +++ Drawing routines.
583
+ */
584
+
585
+ static void DrawSash(Paned *pw, Drawable d, Ttk_Box b)
586
+ {
587
+ Ttk_Layout sashLayout = pw->paned.sashLayout;
588
+ Ttk_State state = pw->core.state;
589
+
590
+ Ttk_PlaceLayout(sashLayout, state, b);
591
+ Ttk_DrawLayout(sashLayout, state, d);
592
+ }
593
+
594
+ static void PanedDisplay(void *recordPtr, Drawable d)
595
+ {
596
+ Paned *pw = recordPtr;
597
+ int nPanes = Ttk_NumberSlaves(pw->paned.mgr),
598
+ horizontal = pw->paned.orient == TTK_ORIENT_HORIZONTAL,
599
+ thickness = pw->paned.sashThickness,
600
+ height = Tk_Height(pw->core.tkwin),
601
+ width = Tk_Width(pw->core.tkwin);
602
+ int i;
603
+
604
+ TtkWidgetDisplay(recordPtr, d);
605
+
606
+ /* Draw sashes:
607
+ */
608
+ for (i = 0; i < nPanes; ++i) {
609
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, i);
610
+ if (horizontal) {
611
+ DrawSash(pw, d, Ttk_MakeBox(pane->sashPos, 0, thickness, height));
612
+ } else {
613
+ DrawSash(pw, d, Ttk_MakeBox(0, pane->sashPos, width, thickness));
614
+ }
615
+ }
616
+ }
617
+
618
+ /*------------------------------------------------------------------------
619
+ * +++ Widget commands.
620
+ */
621
+
622
+ /* $pw add window [ options ... ]
623
+ */
624
+ static int PanedAddCommand(
625
+ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
626
+ {
627
+ Paned *pw = recordPtr;
628
+ Tk_Window slaveWindow;
629
+
630
+ if (objc < 3) {
631
+ Tcl_WrongNumArgs(interp, 2, objv, "window");
632
+ return TCL_ERROR;
633
+ }
634
+
635
+ slaveWindow = Tk_NameToWindow(
636
+ interp, Tcl_GetString(objv[2]), pw->core.tkwin);
637
+
638
+ if (!slaveWindow) {
639
+ return TCL_ERROR;
640
+ }
641
+
642
+ return AddPane(interp, pw, Ttk_NumberSlaves(pw->paned.mgr), slaveWindow,
643
+ objc - 3, objv + 3);
644
+ }
645
+
646
+ /* $pw insert $index $slave ?options...?
647
+ * Insert new slave, or move existing one.
648
+ */
649
+ static int PanedInsertCommand(
650
+ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
651
+ {
652
+ Paned *pw = recordPtr;
653
+ int nSlaves = Ttk_NumberSlaves(pw->paned.mgr);
654
+ int srcIndex, destIndex;
655
+ Tk_Window slaveWindow;
656
+
657
+ if (objc < 4) {
658
+ Tcl_WrongNumArgs(interp, 2,objv, "index slave ?options...?");
659
+ return TCL_ERROR;
660
+ }
661
+
662
+ slaveWindow = Tk_NameToWindow(
663
+ interp, Tcl_GetString(objv[3]), pw->core.tkwin);
664
+ if (!slaveWindow) {
665
+ return TCL_ERROR;
666
+ }
667
+
668
+ if (!strcmp(Tcl_GetString(objv[2]), "end")) {
669
+ destIndex = Ttk_NumberSlaves(pw->paned.mgr);
670
+ } else if (TCL_OK != Ttk_GetSlaveIndexFromObj(
671
+ interp,pw->paned.mgr,objv[2],&destIndex))
672
+ {
673
+ return TCL_ERROR;
674
+ }
675
+
676
+ srcIndex = Ttk_SlaveIndex(pw->paned.mgr, slaveWindow);
677
+ if (srcIndex < 0) { /* New slave: */
678
+ return AddPane(interp, pw, destIndex, slaveWindow, objc-4, objv+4);
679
+ } /* else -- move existing slave: */
680
+
681
+ if (destIndex >= nSlaves)
682
+ destIndex = nSlaves - 1;
683
+ Ttk_ReorderSlave(pw->paned.mgr, srcIndex, destIndex);
684
+
685
+ return objc == 4 ? TCL_OK :
686
+ ConfigurePane(interp, pw,
687
+ Ttk_SlaveData(pw->paned.mgr, destIndex),
688
+ Ttk_SlaveWindow(pw->paned.mgr, destIndex),
689
+ objc-4,objv+4);
690
+ }
691
+
692
+ /* $pw forget $pane
693
+ */
694
+ static int PanedForgetCommand(
695
+ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
696
+ {
697
+ Paned *pw = recordPtr;
698
+ int paneIndex;
699
+
700
+ if (objc != 3) {
701
+ Tcl_WrongNumArgs(interp, 2,objv, "pane");
702
+ return TCL_ERROR;
703
+ }
704
+
705
+ if (TCL_OK != Ttk_GetSlaveIndexFromObj(
706
+ interp, pw->paned.mgr, objv[2], &paneIndex))
707
+ {
708
+ return TCL_ERROR;
709
+ }
710
+ Ttk_ForgetSlave(pw->paned.mgr, paneIndex);
711
+
712
+ return TCL_OK;
713
+ }
714
+
715
+ /* $pw identify $x $y --
716
+ * Return index of sash at $x,$y
717
+ */
718
+ static int PanedIdentifyCommand(
719
+ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
720
+ {
721
+ Paned *pw = recordPtr;
722
+ int sashThickness = pw->paned.sashThickness;
723
+ int nSashes = Ttk_NumberSlaves(pw->paned.mgr) - 1;
724
+ int x, y, pos;
725
+ int index;
726
+
727
+ if (objc != 4) {
728
+ Tcl_WrongNumArgs(interp, 2,objv, "x y");
729
+ return TCL_ERROR;
730
+ }
731
+ if ( Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK
732
+ || Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK
733
+ ) {
734
+ return TCL_ERROR;
735
+ }
736
+
737
+ pos = pw->paned.orient == TTK_ORIENT_HORIZONTAL ? x : y;
738
+ for (index = 0; index < nSashes; ++index) {
739
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, index);
740
+ if (pane->sashPos <= pos && pos <= pane->sashPos + sashThickness) {
741
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
742
+ return TCL_OK;
743
+ }
744
+ }
745
+
746
+ return TCL_OK; /* return empty string */
747
+ }
748
+
749
+ /* $pw pane $pane ?-option ?value -option value ...??
750
+ * Query/modify pane options.
751
+ */
752
+ static int PanedPaneCommand(
753
+ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
754
+ {
755
+ Paned *pw = recordPtr;
756
+ int paneIndex;
757
+ Tk_Window slaveWindow;
758
+ Pane *pane;
759
+
760
+ if (objc < 3) {
761
+ Tcl_WrongNumArgs(interp, 2,objv, "pane ?-option value...?");
762
+ return TCL_ERROR;
763
+ }
764
+
765
+ if (TCL_OK != Ttk_GetSlaveIndexFromObj(
766
+ interp,pw->paned.mgr,objv[2],&paneIndex))
767
+ {
768
+ return TCL_ERROR;
769
+ }
770
+
771
+ pane = Ttk_SlaveData(pw->paned.mgr, paneIndex);
772
+ slaveWindow = Ttk_SlaveWindow(pw->paned.mgr, paneIndex);
773
+
774
+ switch (objc) {
775
+ case 3:
776
+ return TtkEnumerateOptions(interp, pane, PaneOptionSpecs,
777
+ pw->paned.paneOptionTable, slaveWindow);
778
+ case 4:
779
+ return TtkGetOptionValue(interp, pane, objv[3],
780
+ pw->paned.paneOptionTable, slaveWindow);
781
+ default:
782
+ return ConfigurePane(interp, pw, pane, slaveWindow, objc-3,objv+3);
783
+ }
784
+ }
785
+
786
+ /* $pw panes --
787
+ * Return list of managed panes.
788
+ */
789
+ static int PanedPanesCommand(
790
+ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
791
+ {
792
+ Paned *pw = recordPtr;
793
+ Ttk_Manager *mgr = pw->paned.mgr;
794
+ Tcl_Obj *panes;
795
+ int i;
796
+
797
+ if (objc != 2) {
798
+ Tcl_WrongNumArgs(interp, 2, objv, "");
799
+ return TCL_ERROR;
800
+ }
801
+
802
+ panes = Tcl_NewListObj(0, NULL);
803
+ for (i = 0; i < Ttk_NumberSlaves(mgr); ++i) {
804
+ const char *pathName = Tk_PathName(Ttk_SlaveWindow(mgr,i));
805
+ Tcl_ListObjAppendElement(interp, panes, Tcl_NewStringObj(pathName,-1));
806
+ }
807
+ Tcl_SetObjResult(interp, panes);
808
+
809
+ return TCL_OK;
810
+ }
811
+
812
+
813
+ /* $pw sashpos $index ?$newpos?
814
+ * Query or modify sash position.
815
+ */
816
+ static int PanedSashposCommand(
817
+ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
818
+ {
819
+ Paned *pw = recordPtr;
820
+ int sashIndex, position = -1;
821
+ Pane *pane;
822
+
823
+ if (objc < 3 || objc > 4) {
824
+ Tcl_WrongNumArgs(interp, 2,objv, "index ?newpos?");
825
+ return TCL_ERROR;
826
+ }
827
+ if (Tcl_GetIntFromObj(interp, objv[2], &sashIndex) != TCL_OK) {
828
+ return TCL_ERROR;
829
+ }
830
+ if (sashIndex < 0 || sashIndex >= Ttk_NumberSlaves(pw->paned.mgr) - 1) {
831
+ Tcl_AppendResult(interp,
832
+ "sash index ", Tcl_GetString(objv[2]), " out of range",
833
+ NULL);
834
+ return TCL_ERROR;
835
+ }
836
+
837
+ pane = Ttk_SlaveData(pw->paned.mgr, sashIndex);
838
+
839
+ if (objc == 3) {
840
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(pane->sashPos));
841
+ return TCL_OK;
842
+ }
843
+ /* else -- set new sash position */
844
+
845
+ if (Tcl_GetIntFromObj(interp, objv[3], &position) != TCL_OK) {
846
+ return TCL_ERROR;
847
+ }
848
+
849
+ if (position < pane->sashPos) {
850
+ ShoveUp(pw, sashIndex, position);
851
+ } else {
852
+ ShoveDown(pw, sashIndex, position);
853
+ }
854
+
855
+ AdjustPanes(pw);
856
+ Ttk_ManagerLayoutChanged(pw->paned.mgr);
857
+
858
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(pane->sashPos));
859
+ return TCL_OK;
860
+ }
861
+
862
+ static WidgetCommandSpec PanedCommands[] =
863
+ {
864
+ { "add", PanedAddCommand },
865
+ { "configure", TtkWidgetConfigureCommand },
866
+ { "cget", TtkWidgetCgetCommand },
867
+ { "forget", PanedForgetCommand },
868
+ { "identify", PanedIdentifyCommand },
869
+ { "insert", PanedInsertCommand },
870
+ { "instate", TtkWidgetInstateCommand },
871
+ { "pane", PanedPaneCommand },
872
+ { "panes", PanedPanesCommand },
873
+ { "sashpos", PanedSashposCommand },
874
+ { "state", TtkWidgetStateCommand },
875
+ { 0,0 }
876
+ };
877
+
878
+ /*------------------------------------------------------------------------
879
+ * +++ Widget specification.
880
+ */
881
+
882
+ static WidgetSpec PanedWidgetSpec =
883
+ {
884
+ "TPanedwindow", /* className */
885
+ sizeof(Paned), /* recordSize */
886
+ PanedOptionSpecs, /* optionSpecs */
887
+ PanedCommands, /* subcommands */
888
+ PanedInitialize, /* initializeProc */
889
+ PanedCleanup, /* cleanupProc */
890
+ TtkCoreConfigure, /* configureProc */
891
+ PanedPostConfigure, /* postConfigureProc */
892
+ PanedGetLayout, /* getLayoutProc */
893
+ PanedSize, /* sizeProc */
894
+ TtkWidgetDoLayout, /* layoutProc */
895
+ PanedDisplay /* displayProc */
896
+ };
897
+
898
+ /*------------------------------------------------------------------------
899
+ * +++ Elements and layouts.
900
+ */
901
+
902
+ typedef struct {
903
+ Tcl_Obj *thicknessObj;
904
+ } SashElement;
905
+
906
+ static Ttk_ElementOptionSpec SashElementOptions[] = {
907
+ { "-sashthickness", TK_OPTION_INT,
908
+ Tk_Offset(SashElement,thicknessObj), "5" },
909
+ {NULL}
910
+ };
911
+
912
+ static void SashElementSize(
913
+ void *clientData, void *elementRecord, Tk_Window tkwin,
914
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
915
+ {
916
+ SashElement *sash = elementRecord;
917
+ int thickness = MIN_SASH_THICKNESS;
918
+ Tcl_GetIntFromObj(NULL, sash->thicknessObj, &thickness);
919
+ *widthPtr = *heightPtr = thickness;
920
+ }
921
+
922
+ static Ttk_ElementSpec SashElementSpec = {
923
+ TK_STYLE_VERSION_2,
924
+ sizeof(SashElement),
925
+ SashElementOptions,
926
+ SashElementSize,
927
+ TtkNullElementDraw
928
+ };
929
+
930
+ TTK_BEGIN_LAYOUT(PanedLayout)
931
+ TTK_NODE("Panedwindow.background", 0)/* @@@ BUG: empty layouts don't work */
932
+ TTK_END_LAYOUT
933
+
934
+ TTK_BEGIN_LAYOUT(HorizontalSashLayout)
935
+ TTK_NODE("Sash.hsash", TTK_FILL_X)
936
+ TTK_END_LAYOUT
937
+
938
+ TTK_BEGIN_LAYOUT(VerticalSashLayout)
939
+ TTK_NODE("Sash.vsash", TTK_FILL_Y)
940
+ TTK_END_LAYOUT
941
+
942
+ /*------------------------------------------------------------------------
943
+ * +++ Registration routine.
944
+ */
945
+
946
+ void TtkPanedwindow_Init(Tcl_Interp *interp)
947
+ {
948
+ Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp);
949
+ RegisterWidget(interp, "ttk::panedwindow", &PanedWidgetSpec);
950
+
951
+ Ttk_RegisterElement(interp, themePtr, "hsash", &SashElementSpec, 0);
952
+ Ttk_RegisterElement(interp, themePtr, "vsash", &SashElementSpec, 0);
953
+
954
+ Ttk_RegisterLayout(themePtr, "TPanedwindow", PanedLayout);
955
+ Ttk_RegisterLayout(themePtr, "Horizontal.Sash", HorizontalSashLayout);
956
+ Ttk_RegisterLayout(themePtr, "Vertical.Sash", VerticalSashLayout);
957
+ }
958
+