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,648 @@
1
+ /* frame.c,v 1.56 2007/11/25 17:17:09 jenglish Exp
2
+ * Copyright (c) 2004, Joe English
3
+ *
4
+ * ttk::frame and ttk::labelframe widgets.
5
+ */
6
+
7
+ #include <tk.h>
8
+
9
+ #include "tkTheme.h"
10
+ #include "widget.h"
11
+ #include "manager.h"
12
+
13
+ /* ======================================================================
14
+ * +++ Frame widget:
15
+ */
16
+
17
+ typedef struct {
18
+ Tcl_Obj *borderWidthObj;
19
+ Tcl_Obj *paddingObj;
20
+ Tcl_Obj *reliefObj;
21
+ Tcl_Obj *widthObj;
22
+ Tcl_Obj *heightObj;
23
+ } FramePart;
24
+
25
+ typedef struct {
26
+ WidgetCore core;
27
+ FramePart frame;
28
+ } Frame;
29
+
30
+ static Tk_OptionSpec FrameOptionSpecs[] =
31
+ {
32
+ {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", NULL,
33
+ Tk_Offset(Frame,frame.borderWidthObj), -1,
34
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
35
+ {TK_OPTION_STRING, "-padding", "padding", "Pad", NULL,
36
+ Tk_Offset(Frame,frame.paddingObj), -1,
37
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
38
+ {TK_OPTION_RELIEF, "-relief", "relief", "Relief", NULL,
39
+ Tk_Offset(Frame,frame.reliefObj), -1,
40
+ TK_OPTION_NULL_OK,0,0 },
41
+ {TK_OPTION_PIXELS, "-width", "width", "Width", "0",
42
+ Tk_Offset(Frame,frame.widthObj), -1,
43
+ 0,0,GEOMETRY_CHANGED },
44
+ {TK_OPTION_PIXELS, "-height", "height", "Height", "0",
45
+ Tk_Offset(Frame,frame.heightObj), -1,
46
+ 0,0,GEOMETRY_CHANGED },
47
+
48
+ WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
49
+ };
50
+
51
+ static WidgetCommandSpec FrameCommands[] =
52
+ {
53
+ { "configure", TtkWidgetConfigureCommand },
54
+ { "cget", TtkWidgetCgetCommand },
55
+ { "instate", TtkWidgetInstateCommand },
56
+ { "state", TtkWidgetStateCommand },
57
+ { "identify", TtkWidgetIdentifyCommand },
58
+ { NULL, NULL }
59
+ };
60
+
61
+ /*
62
+ * FrameMargins --
63
+ * Compute internal margins for a frame widget.
64
+ * This includes the -borderWidth, plus any additional -padding.
65
+ */
66
+ static Ttk_Padding FrameMargins(Frame *framePtr)
67
+ {
68
+ Ttk_Padding margins = Ttk_UniformPadding(0);
69
+
70
+ /* Check -padding:
71
+ */
72
+ if (framePtr->frame.paddingObj) {
73
+ Ttk_GetPaddingFromObj(NULL,
74
+ framePtr->core.tkwin, framePtr->frame.paddingObj, &margins);
75
+ }
76
+
77
+ /* Add padding for border:
78
+ */
79
+ if (framePtr->frame.borderWidthObj) {
80
+ int border = 0;
81
+ Tk_GetPixelsFromObj(NULL,
82
+ framePtr->core.tkwin, framePtr->frame.borderWidthObj, &border);
83
+ margins = Ttk_AddPadding(margins, Ttk_UniformPadding((short)border));
84
+ }
85
+
86
+ return margins;
87
+ }
88
+
89
+ /* FrameSize procedure --
90
+ * The frame doesn't request a size of its own by default,
91
+ * but it does have an internal border. See also <<NOTE-SIZE>>
92
+ */
93
+ static int FrameSize(void *recordPtr, int *widthPtr, int *heightPtr)
94
+ {
95
+ Frame *framePtr = recordPtr;
96
+ Ttk_SetMargins(framePtr->core.tkwin, FrameMargins(framePtr));
97
+ return 0;
98
+ }
99
+
100
+ /*
101
+ * FrameConfigure -- configure hook.
102
+ * <<NOTE-SIZE>> Usually the size of a frame is controlled by
103
+ * a geometry manager (pack, grid); the -width and -height
104
+ * options are only effective if geometry propagation is turned
105
+ * off or if the [place] GM is used for child widgets.
106
+ *
107
+ * To avoid geometry blinking, we issue a geometry request
108
+ * in the Configure hook instead of the Size hook, and only
109
+ * if -width and/or -height is nonzero and one of them
110
+ * or the other size-related options (-borderwidth, -padding)
111
+ * has been changed.
112
+ */
113
+
114
+ static int FrameConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
115
+ {
116
+ Frame *framePtr = recordPtr;
117
+ int width, height;
118
+
119
+ /*
120
+ * Make sure -padding resource, if present, is correct:
121
+ */
122
+ if (framePtr->frame.paddingObj) {
123
+ Ttk_Padding unused;
124
+ if (Ttk_GetPaddingFromObj(interp,
125
+ framePtr->core.tkwin,
126
+ framePtr->frame.paddingObj,
127
+ &unused) != TCL_OK) {
128
+ return TCL_ERROR;
129
+ }
130
+ }
131
+
132
+ /* See <<NOTE-SIZE>>
133
+ */
134
+ if ( TCL_OK != Tk_GetPixelsFromObj(
135
+ interp,framePtr->core.tkwin,framePtr->frame.widthObj,&width)
136
+ || TCL_OK != Tk_GetPixelsFromObj(
137
+ interp,framePtr->core.tkwin,framePtr->frame.heightObj,&height)
138
+ )
139
+ {
140
+ return TCL_ERROR;
141
+ }
142
+
143
+ if ((width > 0 || height > 0) && (mask & GEOMETRY_CHANGED)) {
144
+ Tk_GeometryRequest(framePtr->core.tkwin, width, height);
145
+ }
146
+
147
+ return TtkCoreConfigure(interp, recordPtr, mask);
148
+ }
149
+
150
+ static WidgetSpec FrameWidgetSpec =
151
+ {
152
+ "TFrame", /* className */
153
+ sizeof(Frame), /* recordSize */
154
+ FrameOptionSpecs, /* optionSpecs */
155
+ FrameCommands, /* subcommands */
156
+ TtkNullInitialize, /* initializeProc */
157
+ TtkNullCleanup, /* cleanupProc */
158
+ FrameConfigure, /* configureProc */
159
+ TtkNullPostConfigure, /* postConfigureProc */
160
+ TtkWidgetGetLayout, /* getLayoutProc */
161
+ FrameSize, /* sizeProc */
162
+ TtkWidgetDoLayout, /* layoutProc */
163
+ TtkWidgetDisplay /* displayProc */
164
+ };
165
+
166
+ TTK_BEGIN_LAYOUT(FrameLayout)
167
+ TTK_NODE("Frame.border", TTK_FILL_BOTH)
168
+ TTK_END_LAYOUT
169
+
170
+ /* ======================================================================
171
+ * +++ Labelframe widget:
172
+ */
173
+
174
+ #define DEFAULT_LABELINSET 8
175
+ #define DEFAULT_BORDERWIDTH 2
176
+
177
+ int TtkGetLabelAnchorFromObj(
178
+ Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_PositionSpec *anchorPtr)
179
+ {
180
+ const char *string = Tcl_GetString(objPtr);
181
+ char c = *string++;
182
+ Ttk_PositionSpec flags = 0;
183
+
184
+ /* First character determines side:
185
+ */
186
+ switch (c) {
187
+ case 'w' : flags = TTK_PACK_LEFT; break;
188
+ case 'e' : flags = TTK_PACK_RIGHT; break;
189
+ case 'n' : flags = TTK_PACK_TOP; break;
190
+ case 's' : flags = TTK_PACK_BOTTOM; break;
191
+ default : goto error;
192
+ }
193
+
194
+ /* Remaining characters are as per -sticky:
195
+ */
196
+ while ((c = *string++) != '\0') {
197
+ switch (c) {
198
+ case 'w' : flags |= TTK_STICK_W; break;
199
+ case 'e' : flags |= TTK_STICK_E; break;
200
+ case 'n' : flags |= TTK_STICK_N; break;
201
+ case 's' : flags |= TTK_STICK_S; break;
202
+ default : goto error;
203
+ }
204
+ }
205
+
206
+ *anchorPtr = flags;
207
+ return TCL_OK;
208
+
209
+ error:
210
+ if (interp) {
211
+ Tcl_ResetResult(interp);
212
+ Tcl_AppendResult(interp,
213
+ "Bad label anchor specification ", Tcl_GetString(objPtr),
214
+ NULL);
215
+ }
216
+ return TCL_ERROR;
217
+ }
218
+
219
+ /* LabelAnchorSide --
220
+ * Returns the side corresponding to a LabelAnchor value.
221
+ */
222
+ static Ttk_Side LabelAnchorSide(Ttk_PositionSpec flags)
223
+ {
224
+ if (flags & TTK_PACK_LEFT) return TTK_SIDE_LEFT;
225
+ else if (flags & TTK_PACK_RIGHT) return TTK_SIDE_RIGHT;
226
+ else if (flags & TTK_PACK_TOP) return TTK_SIDE_TOP;
227
+ else if (flags & TTK_PACK_BOTTOM) return TTK_SIDE_BOTTOM;
228
+ /*NOTREACHED*/
229
+ return TTK_SIDE_TOP;
230
+ }
231
+
232
+ /*
233
+ * Labelframe widget record:
234
+ */
235
+ typedef struct {
236
+ Tcl_Obj *labelAnchorObj;
237
+ Tcl_Obj *textObj;
238
+ Tcl_Obj *underlineObj;
239
+ Tk_Window labelWidget;
240
+
241
+ Ttk_Manager *mgr;
242
+ Ttk_Layout labelLayout; /* Sublayout for label */
243
+ Ttk_Box labelParcel; /* Set in layoutProc */
244
+ } LabelframePart;
245
+
246
+ typedef struct {
247
+ WidgetCore core;
248
+ FramePart frame;
249
+ LabelframePart label;
250
+ } Labelframe;
251
+
252
+ #define LABELWIDGET_CHANGED 0x100
253
+
254
+ static Tk_OptionSpec LabelframeOptionSpecs[] =
255
+ {
256
+ {TK_OPTION_STRING, "-labelanchor", "labelAnchor", "LabelAnchor",
257
+ "nw", Tk_Offset(Labelframe, label.labelAnchorObj),-1,
258
+ 0,0,GEOMETRY_CHANGED},
259
+ {TK_OPTION_STRING, "-text", "text", "Text", "",
260
+ Tk_Offset(Labelframe,label.textObj), -1,
261
+ 0,0,GEOMETRY_CHANGED },
262
+ {TK_OPTION_INT, "-underline", "underline", "Underline",
263
+ "-1", Tk_Offset(Labelframe,label.underlineObj), -1,
264
+ 0,0,0 },
265
+ {TK_OPTION_WINDOW, "-labelwidget", "labelWidget", "LabelWidget", NULL,
266
+ -1, Tk_Offset(Labelframe,label.labelWidget),
267
+ TK_OPTION_NULL_OK,0,LABELWIDGET_CHANGED|GEOMETRY_CHANGED },
268
+
269
+ WIDGET_INHERIT_OPTIONS(FrameOptionSpecs)
270
+ };
271
+
272
+ /*
273
+ * Labelframe style parameters:
274
+ */
275
+ typedef struct {
276
+ int borderWidth; /* border width */
277
+ Ttk_Padding padding; /* internal padding */
278
+ Ttk_PositionSpec labelAnchor; /* corner/side to place label */
279
+ Ttk_Padding labelMargins; /* extra space around label */
280
+ int labelOutside; /* true=>place label outside border */
281
+ } LabelframeStyle;
282
+
283
+ static void LabelframeStyleOptions(Labelframe *lf, LabelframeStyle *style)
284
+ {
285
+ Ttk_Layout layout = lf->core.layout;
286
+ Tcl_Obj *objPtr;
287
+
288
+ style->borderWidth = DEFAULT_BORDERWIDTH;
289
+ style->padding = Ttk_UniformPadding(0);
290
+ style->labelAnchor = TTK_PACK_TOP | TTK_STICK_W;
291
+ style->labelOutside = 0;
292
+
293
+ if ((objPtr = Ttk_QueryOption(layout, "-borderwidth", 0)) != NULL) {
294
+ Tk_GetPixelsFromObj(NULL, lf->core.tkwin, objPtr, &style->borderWidth);
295
+ }
296
+ if ((objPtr = Ttk_QueryOption(layout, "-padding", 0)) != NULL) {
297
+ Ttk_GetPaddingFromObj(NULL, lf->core.tkwin, objPtr, &style->padding);
298
+ }
299
+ if ((objPtr = Ttk_QueryOption(layout,"-labelanchor", 0)) != NULL) {
300
+ TtkGetLabelAnchorFromObj(NULL, objPtr, &style->labelAnchor);
301
+ }
302
+ if ((objPtr = Ttk_QueryOption(layout,"-labelmargins", 0)) != NULL) {
303
+ Ttk_GetBorderFromObj(NULL, objPtr, &style->labelMargins);
304
+ } else {
305
+ if (style->labelAnchor & (TTK_PACK_TOP|TTK_PACK_BOTTOM)) {
306
+ style->labelMargins =
307
+ Ttk_MakePadding(DEFAULT_LABELINSET,0,DEFAULT_LABELINSET,0);
308
+ } else {
309
+ style->labelMargins =
310
+ Ttk_MakePadding(0,DEFAULT_LABELINSET,0,DEFAULT_LABELINSET);
311
+ }
312
+ }
313
+ if ((objPtr = Ttk_QueryOption(layout,"-labeloutside", 0)) != NULL) {
314
+ Tcl_GetBooleanFromObj(NULL, objPtr, &style->labelOutside);
315
+ }
316
+
317
+ return;
318
+ }
319
+
320
+ /* LabelframeLabelSize --
321
+ * Extract the requested width and height of the labelframe's label:
322
+ * taken from the label widget if specified, otherwise the text label.
323
+ */
324
+ static void
325
+ LabelframeLabelSize(Labelframe *lframePtr, int *widthPtr, int *heightPtr)
326
+ {
327
+ Tk_Window labelWidget = lframePtr->label.labelWidget;
328
+
329
+ if (labelWidget) {
330
+ *widthPtr = Tk_ReqWidth(labelWidget);
331
+ *heightPtr = Tk_ReqHeight(labelWidget);
332
+ } else {
333
+ Ttk_LayoutSize(lframePtr->label.labelLayout, 0, widthPtr, heightPtr);
334
+ }
335
+ }
336
+
337
+ /*
338
+ * LabelframeSize --
339
+ * Like the frame, this doesn't request a size of its own
340
+ * but it does have internal padding and a minimum size.
341
+ */
342
+ static int LabelframeSize(void *recordPtr, int *widthPtr, int *heightPtr)
343
+ {
344
+ Labelframe *lframePtr = recordPtr;
345
+ WidgetCore *corePtr = &lframePtr->core;
346
+ Ttk_Padding margins;
347
+ LabelframeStyle style;
348
+ int labelWidth, labelHeight;
349
+
350
+ LabelframeStyleOptions(lframePtr, &style);
351
+
352
+ /* Compute base margins (See also: FrameMargins)
353
+ */
354
+ margins = Ttk_AddPadding(
355
+ style.padding, Ttk_UniformPadding((short)style.borderWidth));
356
+
357
+ /* Adjust margins based on label size and position:
358
+ */
359
+ LabelframeLabelSize(lframePtr, &labelWidth, &labelHeight);
360
+ labelWidth += Ttk_PaddingWidth(style.labelMargins);
361
+ labelHeight += Ttk_PaddingHeight(style.labelMargins);
362
+
363
+ switch (LabelAnchorSide(style.labelAnchor)) {
364
+ case TTK_SIDE_LEFT: margins.left += labelWidth; break;
365
+ case TTK_SIDE_RIGHT: margins.right += labelWidth; break;
366
+ case TTK_SIDE_TOP: margins.top += labelHeight; break;
367
+ case TTK_SIDE_BOTTOM: margins.bottom += labelHeight; break;
368
+ }
369
+
370
+ Ttk_SetMargins(corePtr->tkwin,margins);
371
+
372
+ /* Request minimum size based on border width and label size:
373
+ */
374
+ Tk_SetMinimumRequestSize(corePtr->tkwin,
375
+ labelWidth + 2*style.borderWidth,
376
+ labelHeight + 2*style.borderWidth);
377
+
378
+ return 0;
379
+ }
380
+
381
+ /*
382
+ * LabelframeGetLayout --
383
+ * Getlayout widget hook.
384
+ */
385
+
386
+ static Ttk_Layout LabelframeGetLayout(
387
+ Tcl_Interp *interp, Ttk_Theme theme, void *recordPtr)
388
+ {
389
+ Labelframe *lf = recordPtr;
390
+ Ttk_Layout frameLayout = TtkWidgetGetLayout(interp, theme, recordPtr);
391
+ Ttk_Layout labelLayout;
392
+
393
+ if (!frameLayout) {
394
+ return NULL;
395
+ }
396
+
397
+ labelLayout = Ttk_CreateSublayout(
398
+ interp, theme, frameLayout, ".Label", lf->core.optionTable);
399
+
400
+ if (labelLayout) {
401
+ if (lf->label.labelLayout) {
402
+ Ttk_FreeLayout(lf->label.labelLayout);
403
+ }
404
+ Ttk_RebindSublayout(labelLayout, recordPtr);
405
+ lf->label.labelLayout = labelLayout;
406
+ }
407
+
408
+ return frameLayout;
409
+ }
410
+
411
+ /*
412
+ * LabelframeDoLayout --
413
+ * Labelframe layout hook.
414
+ *
415
+ * Side effects: Computes labelParcel.
416
+ */
417
+
418
+ static void LabelframeDoLayout(void *recordPtr)
419
+ {
420
+ Labelframe *lframePtr = recordPtr;
421
+ WidgetCore *corePtr = &lframePtr->core;
422
+ int lw, lh; /* Label width and height */
423
+ LabelframeStyle style;
424
+ Ttk_Box borderParcel = Ttk_WinBox(lframePtr->core.tkwin);
425
+ Ttk_Box labelParcel;
426
+
427
+ /*
428
+ * Compute label parcel:
429
+ */
430
+ LabelframeStyleOptions(lframePtr, &style);
431
+ LabelframeLabelSize(lframePtr, &lw, &lh);
432
+ lw += Ttk_PaddingWidth(style.labelMargins);
433
+ lh += Ttk_PaddingHeight(style.labelMargins);
434
+
435
+ labelParcel = Ttk_PadBox(
436
+ Ttk_PositionBox(&borderParcel, lw, lh, style.labelAnchor),
437
+ style.labelMargins);
438
+
439
+ if (!style.labelOutside) {
440
+ /* Move border edge so it's over label:
441
+ */
442
+ switch (LabelAnchorSide(style.labelAnchor)) {
443
+ case TTK_SIDE_LEFT: borderParcel.x -= lw / 2;
444
+ case TTK_SIDE_RIGHT: borderParcel.width += lw/2; break;
445
+ case TTK_SIDE_TOP: borderParcel.y -= lh / 2;
446
+ case TTK_SIDE_BOTTOM: borderParcel.height += lh / 2; break;
447
+ }
448
+ }
449
+
450
+ /*
451
+ * Place border and label:
452
+ */
453
+ Ttk_PlaceLayout(corePtr->layout, corePtr->state, borderParcel);
454
+ Ttk_PlaceLayout(lframePtr->label.labelLayout, corePtr->state, labelParcel);
455
+ /* labelWidget placed in LabelframePlaceSlaves GM hook */
456
+ lframePtr->label.labelParcel = labelParcel;
457
+ }
458
+
459
+ static void LabelframeDisplay(void *recordPtr, Drawable d)
460
+ {
461
+ Labelframe *lframePtr = recordPtr;
462
+ Ttk_DrawLayout(lframePtr->core.layout, lframePtr->core.state, d);
463
+ Ttk_DrawLayout(lframePtr->label.labelLayout, lframePtr->core.state, d);
464
+ }
465
+
466
+ /* +++ Labelframe geometry manager hooks.
467
+ */
468
+
469
+ /* LabelframePlaceSlaves --
470
+ * Sets the position and size of the labelwidget.
471
+ */
472
+ static void LabelframePlaceSlaves(void *recordPtr)
473
+ {
474
+ Labelframe *lframe = recordPtr;
475
+
476
+ if (Ttk_NumberSlaves(lframe->label.mgr) == 1) {
477
+ Ttk_Box b;
478
+ LabelframeDoLayout(recordPtr);
479
+ b = lframe->label.labelParcel;
480
+ /* ASSERT: slave #0 is lframe->label.labelWidget */
481
+ Ttk_PlaceSlave(lframe->label.mgr, 0, b.x,b.y,b.width,b.height);
482
+ }
483
+ }
484
+
485
+ static int LabelRequest(void *managerData, int index, int width, int height)
486
+ {
487
+ return 1;
488
+ }
489
+
490
+ /* LabelRemoved --
491
+ * Unset the -labelwidget option.
492
+ *
493
+ * <<NOTE-LABELREMOVED>>:
494
+ * This routine is also called when the widget voluntarily forgets
495
+ * the slave in LabelframeConfigure.
496
+ */
497
+ static void LabelRemoved(void *managerData, int slaveIndex)
498
+ {
499
+ Labelframe *lframe = managerData;
500
+ lframe->label.labelWidget = 0;
501
+ }
502
+
503
+ static Ttk_ManagerSpec LabelframeManagerSpec = {
504
+ { "labelframe", Ttk_GeometryRequestProc, Ttk_LostSlaveProc },
505
+ LabelframeSize,
506
+ LabelframePlaceSlaves,
507
+ LabelRequest,
508
+ LabelRemoved
509
+ };
510
+
511
+ /* LabelframeInitialize --
512
+ * Initialization hook.
513
+ */
514
+ static int LabelframeInitialize(Tcl_Interp *interp, void *recordPtr)
515
+ {
516
+ Labelframe *lframe = recordPtr;
517
+
518
+ lframe->label.mgr = Ttk_CreateManager(
519
+ &LabelframeManagerSpec, lframe, lframe->core.tkwin);
520
+ lframe->label.labelWidget = 0;
521
+ lframe->label.labelLayout = 0;
522
+ lframe->label.labelParcel = Ttk_MakeBox(-1,-1,-1,-1);
523
+
524
+ return TCL_OK;
525
+ }
526
+
527
+ /* LabelframeCleanup --
528
+ * Cleanup hook.
529
+ */
530
+ static void LabelframeCleanup(void *recordPtr)
531
+ {
532
+ Labelframe *lframe = recordPtr;
533
+ Ttk_DeleteManager(lframe->label.mgr);
534
+ }
535
+
536
+ /* RaiseLabelWidget --
537
+ * Raise the -labelwidget to ensure that the labelframe doesn't
538
+ * obscure it (if it's not a direct child), or bring it to
539
+ * the top of the stacking order (if it is).
540
+ */
541
+ static void RaiseLabelWidget(Labelframe *lframe)
542
+ {
543
+ Tk_Window parent = Tk_Parent(lframe->label.labelWidget);
544
+ Tk_Window sibling = NULL;
545
+ Tk_Window w = lframe->core.tkwin;
546
+
547
+ while (w && w != parent) {
548
+ sibling = w;
549
+ w = Tk_Parent(w);
550
+ }
551
+
552
+ Tk_RestackWindow(lframe->label.labelWidget, Above, sibling);
553
+ }
554
+
555
+ /* LabelframeConfigure --
556
+ * Configuration hook.
557
+ */
558
+ static int LabelframeConfigure(Tcl_Interp *interp,void *recordPtr,int mask)
559
+ {
560
+ Labelframe *lframePtr = recordPtr;
561
+ Tk_Window labelWidget = lframePtr->label.labelWidget;
562
+ Ttk_PositionSpec unused;
563
+
564
+ /* Validate options:
565
+ */
566
+ if (mask & LABELWIDGET_CHANGED && labelWidget != NULL) {
567
+ if (!Ttk_Maintainable(interp, labelWidget, lframePtr->core.tkwin)) {
568
+ return TCL_ERROR;
569
+ }
570
+ }
571
+
572
+ if (TtkGetLabelAnchorFromObj(
573
+ interp, lframePtr->label.labelAnchorObj, &unused) != TCL_OK)
574
+ {
575
+ return TCL_ERROR;
576
+ }
577
+
578
+ /* Base class configuration:
579
+ */
580
+ if (FrameConfigure(interp, recordPtr, mask) != TCL_OK) {
581
+ return TCL_ERROR;
582
+ }
583
+
584
+ /* Update -labelwidget changes, if any:
585
+ */
586
+ if (mask & LABELWIDGET_CHANGED) {
587
+ if (Ttk_NumberSlaves(lframePtr->label.mgr) == 1) {
588
+ Ttk_ForgetSlave(lframePtr->label.mgr, 0);
589
+ /* Restore labelWidget field (see <<NOTE-LABELREMOVED>>)
590
+ */
591
+ lframePtr->label.labelWidget = labelWidget;
592
+ }
593
+
594
+ if (labelWidget) {
595
+ Ttk_InsertSlave(lframePtr->label.mgr, 0, labelWidget, NULL);
596
+ RaiseLabelWidget(lframePtr);
597
+ }
598
+ }
599
+
600
+ if (mask & GEOMETRY_CHANGED) {
601
+ Ttk_ManagerSizeChanged(lframePtr->label.mgr);
602
+ Ttk_ManagerLayoutChanged(lframePtr->label.mgr);
603
+ }
604
+
605
+ return TCL_OK;
606
+ }
607
+
608
+ static WidgetSpec LabelframeWidgetSpec =
609
+ {
610
+ "TLabelframe", /* className */
611
+ sizeof(Labelframe), /* recordSize */
612
+ LabelframeOptionSpecs, /* optionSpecs */
613
+ FrameCommands, /* subcommands */
614
+ LabelframeInitialize, /* initializeProc */
615
+ LabelframeCleanup, /* cleanupProc */
616
+ LabelframeConfigure, /* configureProc */
617
+ TtkNullPostConfigure, /* postConfigureProc */
618
+ LabelframeGetLayout, /* getLayoutProc */
619
+ LabelframeSize, /* sizeProc */
620
+ LabelframeDoLayout, /* layoutProc */
621
+ LabelframeDisplay /* displayProc */
622
+ };
623
+
624
+ TTK_BEGIN_LAYOUT(LabelframeLayout)
625
+ TTK_NODE("Labelframe.border", TTK_FILL_BOTH)
626
+ TTK_END_LAYOUT
627
+
628
+ TTK_BEGIN_LAYOUT(LabelSublayout)
629
+ TTK_GROUP("Label.fill", TTK_FILL_BOTH,
630
+ TTK_NODE("Label.text", TTK_FILL_BOTH))
631
+ TTK_END_LAYOUT
632
+
633
+ /* ======================================================================
634
+ * +++ Initialization.
635
+ */
636
+
637
+ void TtkFrame_Init(Tcl_Interp *interp)
638
+ {
639
+ Ttk_Theme theme = Ttk_GetDefaultTheme(interp);
640
+
641
+ Ttk_RegisterLayout(theme, "TFrame", FrameLayout);
642
+ Ttk_RegisterLayout(theme, "TLabelframe", LabelframeLayout);
643
+ Ttk_RegisterLayout(theme, "TLabelframe.Label", LabelSublayout);
644
+
645
+ RegisterWidget(interp, "ttk::frame", &FrameWidgetSpec);
646
+ RegisterWidget(interp, "ttk::labelframe", &LabelframeWidgetSpec);
647
+ }
648
+