Commit | Line | Data |
d4567ecb |
1 | Snit's Not Incr Tcl README.txt |
2 | ----------------------------------------------------------------- |
3 | |
4 | Snit is pure-Tcl object and megawidget framework. See snit.html |
5 | for full details. |
6 | |
7 | Snit is part of "tcllib", the standard Tcl Library. |
8 | |
9 | Snit lives in "tcllib" now, but it is available separately at |
10 | http://www.wjduquette.com/snit. If you have any questions, bug |
11 | reports, suggestions, or comments, feel free to contact me, Will |
12 | Duquette, at will@wjduquette.com; or, join the Snit mailing list (see |
13 | http://www.wjduquette.com/snit for details). |
14 | |
15 | Differences Between Snit 2.1 and Snit 1.x |
16 | -------------------------------------------------------------------- |
17 | |
18 | V2.0 and V1.x are being developed in parallel. |
19 | |
20 | Version 2.1 takes advantage of some new Tcl/Tk 8.5 commands |
21 | ([dict], [namespace ensemble], and [namespace upvar]) to improve |
22 | Snit's run-time efficiency. Otherwise, it's intended to be |
23 | feature-equivalent with V1.x. When running with Tcl/Tk 8.5, both |
24 | V2.0 and V1.x are available; when running with Tcl/Tk 8.3 or Tcl/Tk |
25 | 8.4, only V1.x is available. |
26 | |
27 | Snit 1.x is implemented in snit.tcl; Snit 2.1 in snit2.tcl. |
28 | |
29 | V2.1 includes the following enhancements over V1.x: |
30 | |
31 | * A type's code (methods, type methods, etc.) can now call commands |
32 | from the type's parent namespace without qualifying or importing |
33 | them, i.e., type ::parentns::mytype's code can call |
34 | ::parentns::someproc as just "someproc". |
35 | |
36 | This is extremely useful when a type is defined as part of a larger |
37 | package, and shares a parent namespace with the rest of the package; |
38 | it means that the type can call other commands defined by the |
39 | package without any extra work. |
40 | |
41 | This feature depends on the new Tcl 8.5 [namespace path] command, |
42 | which is why it hasn't been implemented for V1.x. V1.x code can |
43 | achieve something similar by placing |
44 | |
45 | namespace import [namespace parent]::* |
46 | |
47 | in a type constructor. This is less useful, however, as it picks up |
48 | only those commands which have already been exported by the parent |
49 | namespace at the time the type is defined. |
50 | |
51 | There are four incompatibilities between V2.1 and V1.x: |
52 | |
53 | * Implicit naming of objects now only works if you set |
54 | |
55 | pragma -hastypemethods 0 |
56 | |
57 | in the type definition. Otherwise, |
58 | |
59 | set obj [mytype] |
60 | |
61 | will fail; you must use |
62 | |
63 | set obj [mytype %AUTO%] |
64 | |
65 | * In Snit 1.x and earlier, hierarchical methods and type methods |
66 | could be called in two ways: |
67 | |
68 | snit::type mytype { |
69 | method {foo bar} {} { puts "Foobar!"} |
70 | } |
71 | |
72 | set obj [mytype %AUTO%] |
73 | $obj foo bar ;# This is the first way |
74 | $obj {foo bar} ;# This is the second way |
75 | |
76 | In Snit 2.1, the second way no longer works. |
77 | |
78 | * In Snit 1.x and earlier, [$obj info methods] and |
79 | [$obj info typemethods] returned a complete list of all known |
80 | hierarchical methods. In the example just above, for example, |
81 | the list returned by [$obj info methods] would include |
82 | "foo bar". In Snit 2.1, only the first word of a hierarchical |
83 | method name is returned, [$obj info methods] would include |
84 | "foo" but not "foo bar". |
85 | |
86 | * Because a type's code (methods, type methods, etc.) can now |
87 | call commands from the type's parent namespace without qualifying |
88 | or importing them, this means that all commands defined in the |
89 | parent namespace are visible--and can shadow commands defined |
90 | in the global namespace, including the standard Tcl commands. |
91 | There was a case in Tcllib where the Snit type ::tie::std::file |
92 | contained a bug with Snit 2.1 because the type's own name |
93 | shadowed the standard [file] command in the type's own code. |
94 | |
95 | |
96 | Changes in V1.2 |
97 | -------------------------------------------------------------------- |
98 | |
99 | * Defined a family of validation types. Validation types are used |
100 | to validate data values; for example, snit::integer and its |
101 | subtypes can validate a variety of classes of integer value, e.g., |
102 | integers between 3 and 9 or integers greater than 0. |
103 | |
104 | Changes in V1.1 |
105 | -------------------------------------------------------------------- |
106 | |
107 | * It's now explicitly an error to call an object's "destroy" method |
108 | in the object's constructor. (If you need to do it, just throw |
109 | an error; construction will fail and the object will be cleaned |
110 | up. |
111 | |
112 | * The Tile "ttk::frame" widget is now a valid hulltype for |
113 | snit::widgets. Any widget with a -class option can be used |
114 | as a hulltype; lappend the widget name to |
115 | snit::hulltypes to enable its use as a hulltype. |
116 | |
117 | * The TK labelframe widget and the Tile ttk::labelframe widget are |
118 | now valid hulltypes for snit::widgets. |
119 | |
120 | Changes in V1.0 |
121 | -------------------------------------------------------------------- |
122 | |
123 | Functionally, V1.0 is identical to version V0.97. |
124 | |
125 | * Added a number of speed optimizations provided by Jeff Hobbs. |
126 | (Thanks, Jeff!) |
127 | |
128 | * Returned to the name "Snit's Not Incr Tcl". |
129 | |
130 | * Fixed SourceForge Tcllib Bug 1161779; it's no longer an error |
131 | if the destructor is defined before the constructor. |
132 | |
133 | * Fixed SourceForge Tcllib Bug 1106375; the hull widget is now |
134 | destroyed properly if there's an error in the constructor of |
135 | a widget or widgetadaptor. |
136 | |
137 | Changes in V0.97 |
138 | -------------------------------------------------------------------- |
139 | |
140 | The changes listed here were actually made over time in Snit V0.96; |
141 | now that they are complete, the result has been renumbered Snit V0.97. |
142 | |
143 | * Bug fix: methods called via [mymethod] can now return exotic |
144 | return codes (e.g., "return -code break"). |
145 | |
146 | * Added the -hasinfo pragma, which controls whether there's an |
147 | "info" instance method or not. By default, there is. |
148 | |
149 | * POSSIBLE INCOMPATIBILITY: If no options are defined for a type, neither |
150 | locally nor delegated, then Snit will not define the "configure", |
151 | "configurelist", and "cget" instance methods or the "options" |
152 | instance variable. |
153 | |
154 | * If a snit::type's command is called without arguments, AND the type |
155 | can have instances, then an instance is created using %AUTO% to |
156 | create its name. E.g., the following commands are all equivalent: |
157 | |
158 | snit::type dog { ... } |
159 | |
160 | set mydog [dog create %AUTO%] |
161 | set mydog [dog %AUTO%] |
162 | set mydog [dog] |
163 | |
164 | This doesn't work for widgets, for obvious reasons. |
165 | |
166 | * Added pragma -hastypemethods. If its value is "yes" (the |
167 | default), then the type has traditional Snit behavior with |
168 | respect to typemethods. If its value is "no", then the type |
169 | has no typemethods (even if typemethods were included |
170 | explicitly in the type definition). Instead, the first argument |
171 | of the type proc is the name of the object to create. As above, |
172 | the first argument defaults to "%AUTO%" for snit::types but not |
173 | for snit::widgets. |
174 | |
175 | * Added pragma -simpledispatch. This pragma is intended to make |
176 | simple, heavily used types (e.g. stacks or queues) more efficient. |
177 | If its value is "no" (the default), then the type has traditional |
178 | Snit behavior with respect to method dispatch. If its value is |
179 | "yes", then a simpler, faster scheme is used; however, there are |
180 | corresponding limitations. See the man page for details. |
181 | |
182 | * Bug fix: the "pragma" statement now throws an error if the specified |
183 | pragma isn't defined, e.g., "pragma -boguspragma yes" is now an |
184 | error. |
185 | |
186 | * Bug fix: -readonly options weren't. Now they are. |
187 | |
188 | * Added support for hierarchical methods, like the Tk text widget's |
189 | tag, mark, and image methods. You define the methods like so: |
190 | |
191 | method {tag add} {args} {...} |
192 | method {tag configure} {args} {...} |
193 | method {tag cget} {args} {...} |
194 | |
195 | and call them like so: |
196 | |
197 | $widget tag add .... |
198 | |
199 | The "delegate method" statement also supports hierarchical methods. |
200 | However, hierarchical methods cannot be used with -simpledispatch. |
201 | |
202 | * Similarly, added support for hierarchical typemethods. |
203 | |
204 | Changes in V0.96 |
205 | -------------------------------------------------------------------- |
206 | |
207 | V0.96 was the development version in which most of the V0.97 changes |
208 | were implemented. The name was changed to V0.97 when the changes |
209 | were complete, so that the contents of V0.97 will be stable. |
210 | |
211 | Changes in V0.95 |
212 | -------------------------------------------------------------------- |
213 | |
214 | The changes listed here were actually made over time in Snit V0.94; |
215 | now that they are complete, the result has been renumbered Snit V0.95. |
216 | |
217 | * Snit method invocation (both local and delegated) has been |
218 | optimized by the addition of a "method cache". The primary |
219 | remaining cost in method invocation is the cost of declaring |
220 | instance variables. |
221 | |
222 | * Snit typemethod invocation now also uses a cache. |
223 | |
224 | * Added the "myproc" command, which parallels "mymethod". "codename" |
225 | is now deprecated. |
226 | |
227 | * Added the "mytypemethod" command, which parallels "mymethod". |
228 | |
229 | * Added the "myvar" and "mytypevar" commands. "varname" is now |
230 | deprecated. |
231 | |
232 | * Added ::snit::macro. |
233 | |
234 | * Added the "component" type definition statement. This replaces |
235 | "variable" for declaring components explicitly, and has two nifty |
236 | options, "-public" and "-inherit". |
237 | |
238 | * Reimplemented the "delegate method" and "delegate option" |
239 | statements; among other things, they now have more descriptive error |
240 | messages. |
241 | |
242 | * Added the "using" clause to the "delegate method" statement. The |
243 | "using" clause allows the programmer to specify an arbitrary command |
244 | prefix into which the component and method names (among other |
245 | things) can be automatically substituted. It's now possible to |
246 | delegate a method just about any way you'd like. |
247 | |
248 | * Added ::snit::compile. |
249 | |
250 | * Added the "delegate typemethod" statement. It's similar to |
251 | "delegate method" and has the same syntax, but delegates typemethods |
252 | to commands whose names are stored in typevariables. |
253 | |
254 | * Added the "typecomponent" type definition statement. Parallel to |
255 | "component", "typecomponent" is used to declare targets for the new |
256 | "delegate typemethod" statement. |
257 | |
258 | * "delegate method" can now delegate methods to components or |
259 | typecomponents. |
260 | |
261 | * The option definition syntax has been extended; see snit.man. You |
262 | can now define methods to handle cget or configure of any option; as |
263 | a result, The "oncget" and "onconfigure" statements are now deprecated. |
264 | Existing "oncget" and "onconfigure" handlers continue to function as |
265 | expected, with one difference: they get a new implicit argument, |
266 | "_option", which is the name of the option being set. If your |
267 | existing handlers use "_option" as a variable name, they will need |
268 | to be changed. |
269 | |
270 | * In addition, the "option" statement also allows you to define a |
271 | validation method. If defined, it will be called before the value |
272 | is saved; its job is to validate the option value and call "error" |
273 | if there's a problem. |
274 | |
275 | * In addition, options can be defined to be "-readonly". A readonly |
276 | option's value can be set at creation time (i.e., in the type's |
277 | constructor) but not afterwards. |
278 | |
279 | * There's a new type definition statement called "pragma" that |
280 | allows you to control how Snit generates the type from the |
281 | definition. For example, you can disable all standard typemethods |
282 | (including "create"); this allows you to use snit::type to define |
283 | an ensemble command (like "string" or "file") using typevariables |
284 | and typemethods. |
285 | |
286 | * In the past, you could create an instance of a snit::type with the |
287 | same name as an existing command; for example, you could create an |
288 | instance called "::info" or "::set". This is no longer allowed, as |
289 | it can lead to errors that are hard to debug. You can recover the |
290 | old behavior using the "-canreplace" pragma. |
291 | |
292 | * In type and widget definitions, the "variable" and "typevariable" |
293 | statements can now initialize arrays as well as scalars. |
294 | |
295 | * Added new introspection commands "$type info typemethods", |
296 | "$self info methods", and "$self info typemethods". |
297 | |
298 | * Sundry other internal changes. |
299 | |
300 | Changes in V0.94 |
301 | -------------------------------------------------------------------- |
302 | |
303 | V0.94 was the development version in which most of the V0.95 changes |
304 | were implemented. The name was changed to V0.95 when the changes |
305 | were complete, so that the contents of V0.95 will be stable. |
306 | |
307 | Changes in V0.93 |
308 | -------------------------------------------------------------------- |
309 | |
310 | * Enhancement: Added the snit::typemethod and snit::method commands; |
311 | these allow typemethods and methods to be defined (and redefined) |
312 | after the class already exists. See the Snit man page for |
313 | details. |
314 | |
315 | * Documentation fixes: a number of minor corrections were made to the |
316 | Snit man page and FAQ. Thanks to everyone who pointed them out, |
317 | especially David S. Cargo. |
318 | |
319 | * Bug fix: when using %AUTO% to create object names, the counter |
320 | will wrap around to 0 after it reaches (2^32 - 1), to prevent |
321 | integer overflow errors. (Credit Marty Backe) |
322 | |
323 | * Bug fix: in a normal Tcl proc, the command |
324 | |
325 | variable ::my::namespace::var |
326 | |
327 | makes variable "::my::namespace::var" available to the proc under the |
328 | local name "var". Snit redefines the "variable" command for use in |
329 | instance methods, and had lost this behavior. (Credit Jeff |
330 | Hobbs) |
331 | |
332 | * Bug fix: in some cases, the "info vars" instance method didn't |
333 | include the "options" instance variable in its output. |
334 | |
335 | * Fixed bug: in some cases the type command was created even if there |
336 | was an error defining the type. The type command is now cleaned |
337 | up in these cases. (Credit Andy Goth) |
338 | |
339 | |
340 | Changes in V0.92 |
341 | -------------------------------------------------------------------- |
342 | |
343 | * Bug fix: In type methods, constructors, and methods, the "errorCode" |
344 | of a thrown error was not propagated properly; no matter what it was |
345 | set to, it always emerged as "NONE". |
346 | |
347 | Changes in V0.91 |
348 | -------------------------------------------------------------------- |
349 | |
350 | * Bug fix: On a system with both 0.9 and 0.81 installed, |
351 | "package require snit 0.9" would get snit 0.81. Here's why: to me |
352 | it was clear enough that 0.9 is later than 0.81, but to Tcl the |
353 | minor version number 9 is less than minor version number 81. |
354 | From now on, all pre-1.0 Snit version numbers will have two |
355 | digits. |
356 | |
357 | * Bug fix: If a method or typemethod had an argument list which was |
358 | broken onto multiple lines, the type definition would fail. It now |
359 | works as expected. |
360 | |
361 | * Added the "expose" statement; this allows you to expose an entire |
362 | component as part of your type's public interface. See the man page |
363 | and the Snit FAQ list for more information. |
364 | |
365 | * The "info" type and instance methods now take "string match" |
366 | patterns as appropriate. |
367 | |
368 | Changes in V0.9 |
369 | -------------------------------------------------------------------- |
370 | |
371 | For specific changes, please see the file ChangeLog in this directory. |
372 | Here are the highlights: |
373 | |
374 | * Snit widgets and widget adaptors now support the Tk option database. |
375 | |
376 | * It's possible set the hull type of a Snit widget to be either a |
377 | frame or a toplevel. |
378 | |
379 | * It's possible to explicitly set the widget class of a Snit widget. |
380 | |
381 | * It's possible to explicitly set the resource and class names for |
382 | all locally defined and explicitly delegated options. |
383 | |
384 | * Option and method names can be excluded from "delegate option *" by |
385 | using the "except" clause, e.g., |
386 | |
387 | delegate option * to hull except {-borderwidth -background} |
388 | |
389 | * Any Snit type or widget can define a "type constructor": a body of |
390 | code that's executed when the type is defined. The type constructor |
391 | is typically used to initialize array-valued type variables, and to |
392 | add values to the Tk option database. |
393 | |
394 | * Components should generally be created and installed using the new |
395 | "install" command. |
396 | |
397 | * snit::widgetadaptor hulls should generally be created and installed |
398 | using the new "installhull using" form of the "installhull" command. |
399 | |
400 | See the Snit man page and FAQ list for more information on these new |
401 | features. |
402 | |
403 | |
404 | Changes in V0.81 |
405 | -------------------------------------------------------------------- |
406 | |
407 | * All documentation errors people e-mailed to me have been fixed. |
408 | |
409 | * Bug fix: weird type names. In Snit 0.8, type names like |
410 | "hyphenated-name" didn't work because the type name is used as a |
411 | namespace name, and Tcl won't parse "-" as part of a namespace name |
412 | unless you quote it somehow. Kudos to Michael Cleverly who both |
413 | noticed the problem and contributed the patch. |
414 | |
415 | * Bug fix: Tcl 8.4.2 incompatibility. There was a bug in Tcl 8.4.1 |
416 | (and in earlier versions, likely) that if the Tcl command "catch" |
417 | evaluated a block that contained an explicit "return", "catch" |
418 | returned 0. The documentation evidently indicated that it should |
419 | return 2, and so this was fixed in Tcl 8.4.2. This broke a bit |
420 | of code in Snit. |
421 | |
422 | Changes in V0.8 |
423 | -------------------------------------------------------------------- |
424 | |
425 | * Note that there are many incompatibilities between Snit V0.8 and |
426 | earlier versions; they are all included in this list. |
427 | |
428 | * Bug fix: In Snit 0.71 and Snit 0.72, if two instances of a |
429 | snit::type are created with the same name, the first instance's |
430 | private data is not destroyed. Hence, [$type info instances] will |
431 | report that the first instance still exists. This is now fixed. |
432 | |
433 | * Snit now requires Tcl 8.4, as it depends on the new command |
434 | tracing facility. |
435 | |
436 | * The snit::widgettype command, which was previously deprecated, has |
437 | now been deleted. |
438 | |
439 | * The snit::widget command has been renamed snit::widgetadaptor; its |
440 | usage is unchanged, except that the idiom "component hull is ..." |
441 | is no longer used to define the hull component. Instead, use the |
442 | "installhull" command: |
443 | |
444 | constructor {args} { |
445 | installhull [label $win ...] |
446 | $self configurelist $args |
447 | } |
448 | |
449 | * The "component" command is now obsolete, and has been removed. |
450 | Instead, the "delegate" command implicitly defines an instance |
451 | variable for the named component; the constructor should assign an |
452 | object name to that instance variable. For example, whereas you |
453 | used to write this: |
454 | |
455 | snit::type dog { |
456 | delegate method wag to tail |
457 | |
458 | constructor {args} { |
459 | component tail is [tail $self.tail -partof self] |
460 | } |
461 | |
462 | method gettail {} { |
463 | return [component tail] |
464 | } |
465 | } |
466 | |
467 | you now write this: |
468 | |
469 | snit::type dog { |
470 | delegate method wag to tail |
471 | |
472 | constructor {args} { |
473 | set tail [tail $self.tail -partof self] |
474 | } |
475 | |
476 | method gettail {} { |
477 | return $tail |
478 | } |
479 | } |
480 | |
481 | * There is a new snit::widget command; unlike snit::widgetadaptor, |
482 | snit::widget automatically creates a Tk frame widget as the hull |
483 | widget; the constructor doesn't need to create and set a hull component. |
484 | |
485 | * Snit objects may now be renamed without breaking; many of the |
486 | specific changes which follow are related to this. However, |
487 | there are some new practices for type authors to follow if they wish |
488 | to write renameable types and widgets. In particular, |
489 | |
490 | * In an instance method, $self will always contain the object's |
491 | current name, so instance methods can go on calling other instance |
492 | methods using $self. |
493 | |
494 | * If the object is renamed, then $self's value will change. Therefore, |
495 | don't use $self for anything that will break if $self changes. |
496 | For example, don't pass a callback as "[list $self methodname]". |
497 | |
498 | * If the object passes "[list $self methodname arg1 arg2]" as a callback, |
499 | the callback will fail when the object is renamed. Instead, the |
500 | object should pass "[mymethod methodname arg1 arg2]". The [mymethod] |
501 | command returns the desired command as a list beginning with a |
502 | name for the object that never changes. |
503 | |
504 | For example, in Snit V0.71 you might have used this code to call a |
505 | method when a Tk button is pushed: |
506 | |
507 | .btn configure -command [list $self buttonpress] |
508 | |
509 | This still works in V0.8--but the callback will break if your |
510 | instance is renamed. Here's the safe way to do it: |
511 | |
512 | .btn configure -command [mymethod buttonpress] |
513 | |
514 | * Every object has a private namespace; the name of this namespace |
515 | is now available in method bodies, etc., as "$selfns". This value is |
516 | constant for the life the object. Use "$selfns" instead of "$self" if |
517 | you need a unique token to identify the object. |
518 | |
519 | * When a snit::widget's instance command is renamed, its Tk window |
520 | name remains the same--and is still extremely important. |
521 | Consequently, the Tk window name is now available in snit::widget |
522 | method bodies, etc., as "$win". This value is constant for the |
523 | life of the object. When creating child windows, it's best to |
524 | use "$win.child" rather than "$self.child" as the name of the |
525 | child window. |
526 | |
527 | * The names "selfns" and "win" may no longer be used as explicit argument |
528 | names for typemethods, methods, constructors, or onconfigure |
529 | handlers. |
530 | |
531 | * procs defined in a Snit type or widget definition used to be able to |
532 | reference instance variables if "$self" was passed to them |
533 | explicitly as the argument "self"; this is no longer the case. |
534 | |
535 | * procs defined in a Snit type or widget definition can now reference |
536 | instance variables if "$selfns" is passed to them explicitly as the |
537 | argument "selfns". However, this usage is deprecated. |
538 | |
539 | * All Snit type and widget instances can be destroyed by renaming the |
540 | instance command to "". |
541 | |
542 | Changes in V0.72 |
543 | -------------------------------------------------------------------- |
544 | |
545 | * Updated the pkgIndex.tcl file to references snit 0.72 instead of |
546 | snit 0.7. |
547 | |
548 | * Fixed a bug in widget destruction that caused errors like |
549 | "can't rename "::hull1.f": command doesn't exist". |
550 | |
551 | Changes in V0.71 |
552 | -------------------------------------------------------------------- |
553 | |
554 | * KNOWN BUG: The V0.7 documentation implies that a snit::widget can |
555 | serve as the hull of another snit::widget. Unfortunately, it |
556 | doesn't work. The fix for this turns out to be extremely |
557 | complicated, so I plan to fix it in Snit V0.8. |
558 | |
559 | Note that a snit::widget can still be composed of other |
560 | snit::widgets; it's only a problem when the hull component in |
561 | particular is a snit::widget. |
562 | |
563 | * KNOWN BUG: If you rename a Snit type or instance command (i.e., using |
564 | Tcl's [rename] command) it will no longer work properly. This is |
565 | part of the reason for the previous bug, and should also be fixed in |
566 | Snit V0.8. |
567 | |
568 | * Enhancement: Snit now preserves the call stack (i.e., the |
569 | "errorInfo") when rethrowing errors thrown by Snit methods, |
570 | typemethods, and so forth. This should make debugging Snit types |
571 | and widgets much easier. In Snit V0.8, I hope to clean up the |
572 | call stack so that Snit internals are hidden. |
573 | |
574 | * Bug fix: Option default values were being processed incorrectly. In |
575 | particular, if the default value contained brackets, it was treated |
576 | as a command interpolation. For example, |
577 | |
578 | option -regexp {[a-z]+} |
579 | |
580 | yield the error that "a-z" isn't a known command. Credit to Keith |
581 | Waclena for finding this one. |
582 | |
583 | * Bug fix: the [$type info instances] command failed to find |
584 | instances that weren't defined in the global namespace, and found |
585 | some things that weren't instances. Credit to Keith Waclena for |
586 | finding this one as well. |
587 | |
588 | * Internal Change: the naming convention for instance namespaces |
589 | within the type namespace has changed. But then, your code |
590 | shouldn't have depended on that anyway. |
591 | |
592 | * Bug fix: snit::widget destruction was seriously broken if the hull |
593 | component was itself a megawidget (e.g., a BWidget). |
594 | Each layer of megawidget code needs its opportunity |
595 | to clean up properly, and that wasn't happening. In addition, the |
596 | snit::widget destruction code was bound as follows: |
597 | |
598 | bind $widgetName <Destroy> {....} |
599 | |
600 | which means that if the user of a Snit widget needs to bind to |
601 | <Destroy> on the widget name they've just wiped out Snit's |
602 | destructor. Consequently, Snit now creates a bindtag called |
603 | |
604 | Snit<widgettype> |
605 | |
606 | e.g., |
607 | |
608 | Snit::rotext |
609 | |
610 | and binds its destroy handler to that. This bindtag is inserted in |
611 | the snit::widget's bindtags immediately after the widget name. |
612 | |
613 | Destruction is always going to be somewhat tricky when multiple |
614 | levels of megawidgets are involved, as you need to make sure that |
615 | the destructors are called in inverse order of creation. |
616 | |
617 | Changes in V0.7 |
618 | ---------------------------------------------------------------------- |
619 | |
620 | * INCOMPATIBILITY: Snit constructor definitions can now have arbitrary |
621 | argument lists, as methods do. That is, the type's create method |
622 | expects the instance name followed by exactly the arguments defined |
623 | in the constructor's argument list: |
624 | |
625 | snit::type dog { |
626 | variable data |
627 | constructor {breed color} { |
628 | set data(breed) $breed |
629 | set data(color) $color |
630 | } |
631 | } |
632 | |
633 | dog spot labrador chocolate |
634 | |
635 | To get the V0.6 behavior, use the argument "args". That is, the |
636 | default constructor would be defined in this way: |
637 | |
638 | snit::type dog { |
639 | constructor {args} { |
640 | $self configurelist $args |
641 | } |
642 | } |
643 | |
644 | * Added a "$type destroy" type method. It destroys all instances of |
645 | the type properly (if possible) then deletes the type's namespace |
646 | and type command. |
647 | |
648 | Changes in V0.6 |
649 | ----------------------------------------------------------------- |
650 | |
651 | * Minor corrections to the man page. |
652 | |
653 | * The command snit::widgettype is deprecated, in favor of |
654 | snit::widget. |
655 | |
656 | * The variable "type" is now automatically defined in all methods, |
657 | constructors, destructors, typemethods, onconfigure handlers, and |
658 | oncget handlers. Thus, a method can call type methods as "$type |
659 | methodname". |
660 | |
661 | * The new standard instance method "info" is used for introspection on |
662 | type and widget instances: |
663 | |
664 | $object info type |
665 | Returns the object's type. |
666 | |
667 | $object info vars |
668 | Returns a list of the object's instance variables (excluding Snit |
669 | internal variables). The names are fully qualified. |
670 | |
671 | $object info typevars |
672 | Returns a list of the object's type's type variables (excluding |
673 | Snit internal variables). The names are fully qualified. |
674 | |
675 | $object info options |
676 | Returns a list of the object's option names. This always |
677 | includes local options and explicitly delegated options. If |
678 | unknown options are delegated as well, and if the component to |
679 | which they are delegated responds to "$object configure" like Tk |
680 | widgets do, then the result will include all possible unknown |
681 | options which could be delegated to the component. |
682 | |
683 | Note that the return value might be different for different |
684 | instances of the same type, if component object types can vary |
685 | from one instance to another. |
686 | |
687 | * The new standard typemethod "info" is used for introspection on |
688 | types: |
689 | |
690 | $type info typevars |
691 | Returns a list of the type's type variables (excluding Snit |
692 | internal variables). |
693 | |
694 | $type info instances |
695 | Returns a list of the instances of the type. For non-widget |
696 | types, each instance will be the fully-qualified instance command |
697 | name; for widget types, each instance will be a widget name. |
698 | |
699 | * Bug fixed: great confusion resulted if the hull component of a |
700 | snit::widgettype was another snit::widgettype. Snit takes over the |
701 | hull widget's Tk widget command by renaming it to a known name, and |
702 | putting its own command in its place. The code made no allowance |
703 | for the fact that this might happen more than once; the second time, |
704 | the original Tk widget command would be lost. Snit now ensures that |
705 | the renamed widget command is given a unique name. |
706 | |
707 | * Previously, instance methods could call typemethods by name, as |
708 | though they were normal procs. The downside to this was that |
709 | if a typemethod name was the same as a standard Tcl command, the |
710 | typemethod shadowed the standard command in all of the object's |
711 | code. This is extremely annoying should you wish to define a |
712 | typemethod called "set". Instance methods must now call typemethods |
713 | using the type's command, as in "$type methodname". |
714 | |
715 | * Typevariable declarations are no longer required in |
716 | typemethods, methods, or procs provided that the typevariables are defined |
717 | in the main type or widget definition. |
718 | |
719 | * Instance variable declarations are no longer required in methods provided |
720 | that the instance variables are defined in the main type or widget |
721 | declaration. |
722 | |
723 | * Instance variable declarations are no longer required in procs, |
724 | provided that the instance variables are defined in the main type or |
725 | widget declaration. Any proc that includes "self" in its argument |
726 | list will pick up all such instance variables automatically. |
727 | |
728 | * The "configure" method now returns output consistent with Tk's when |
729 | called with 0 or 1 arguments, i.e., it returns information about one |
730 | or all options. For options defined by Snit objects, the "dbname" |
731 | and "classname" returned in the output will be {}. "configure" does |
732 | its best to do the right thing in the face of delegation. |
733 | |
734 | * If the string "%AUTO%" appears in the "name" argument to "$type create" |
735 | or "$widgettype create", it will be replaced with a string that |
736 | looks like "$type$n", where "$type" is the type name and "$n" is |
737 | a counter that's incremented each time a |
738 | widget of this type is created. This allows the caller to create |
739 | effectively anonymous instances: |
740 | |
741 | widget mylabel {...} |
742 | |
743 | set w [mylabel .pane.toolbar.%AUTO% ...] |
744 | $w configure -text "Some text" |
745 | |
746 | * The "create" typemethod is now optional for ordinary types so long |
747 | as the desired instance name is different than any typemethod name |
748 | for that type. Thus, the following code creates two dogs, ::spot |
749 | and ::fido. |
750 | |
751 | type dog {...} |
752 | |
753 | dog create spot |
754 | dog fido |
755 | |
756 | If there's a conflict between the instance name and a typemethod, |
757 | either use "create" explicitly, or fully qualify the instance name: |
758 | |
759 | dog info -color black ;# Error; assumes "info" typemethod. |
760 | dog create info -color black ;# OK |
761 | dog ::info -color black ;# also OK |
762 | |
763 | * Bug fix: If any Snit method, typemethod, constructor, or onconfigure |
764 | handler defines an explicit argument called "type" or "self", the type |
765 | definition now throws an error, preventing confusing runtime |
766 | behavior. |
767 | |
768 | * Bug fix: If a Snit type or widget definition attempts to define a |
769 | method or option locally and also delegate it to a component, the |
770 | type definition now throws an error, preventing confusing runtime |
771 | behavior. |
772 | |
773 | * Bug(?) Fix: Previously, the "$self" command couldn't be used in |
774 | snit::widget constructors until after the hull component was |
775 | defined. It is now possible to use the "$self" command to call |
776 | instance methods at any point in the snit::widget's |
777 | constructor--always bearing in mind that it's an error to configure |
778 | delegated options or are call delegated methods before creating the |
779 | component to which they are delegated. |
780 | |
781 | Changes in V0.5 |
782 | ------------------------------------------------------------------ |
783 | |
784 | * Updated the test suite so that Tk-related tests are only run if |
785 | Tk is available. Credit Jose Nazario for pointing out the problem. |
786 | |
787 | * For snit::widgettypes, the "create" keyword is now optional when |
788 | creating a new instance. That is, either of the following will |
789 | work: |
790 | |
791 | ::snit::widgettype mylabel { } |
792 | |
793 | mylabel create .lab1 -text "Using create typemethod" |
794 | mylabel .lab2 -text "Implied create typemethod" |
795 | |
796 | This means that snit::widgettypes can be used identically to normal |
797 | Tk widgets. Credit goes to Colin McCormack for suggesting this. |
798 | |
799 | * Destruction code is now defined using the "destructor" keyword |
800 | instead of by defining a "destroy" method. If you've been |
801 | defining the "destroy" method, you need to replace it with |
802 | "destructor" immediately. See the man page for the syntax. |
803 | |
804 | * widgettype destruction is now handled properly (it was buggy). |
805 | Use the Tk command "destroy" to destroy instances of a widgettype; |
806 | the "destroy" method isn't automatically defined for widgettypes as |
807 | it is for normal types, and has no special significance even if it |
808 | is defined. |
809 | |
810 | * Added the "from" command to aid in parsing out specific option |
811 | values in constructors. |
812 | |
813 | Changes in V0.4 |
814 | ------------------------------------------------------------------ |
815 | |
816 | * Added the "codename" command, to qualify type method and private |
817 | proc names. |
818 | |
819 | * Changed the internal implementation of Snit types and widget types |
820 | to prevent an obscure kind of error and to make it easier to pass |
821 | private procs as callback commands to other objects. Credit to Rolf |
822 | Ade for discovering the hole. |
823 | |
824 | Changes in V0.3 |
825 | ------------------------------------------------------------------ |
826 | |
827 | * First public release. |
828 | |
829 | |