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,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
+