Tk classes

Now that basic concepts have been exposed, let come back to how using Tk with the object layer. In our model, each Tk option is defined as a slot. For instance, a simplified definition of a Tk button could be:
    (defclass <Button> (<Label>)
       ((command :accessor command
                 :initarg :command
                 :allocation :pseudo
                 :type 'any))
       :metaclass <Tk>)

This definition says that a <Button> is a (inherits from) <Label> with an extra slot called command. This slot's allocation scheme is said to be :pseudo3. Pseudo-slots are special purpose slots: they can be used as normal slots but they are not allocated in the Scheme world (i.e. their value is stored in one of the structures manipulated by the Tk library instead of in a Scheme object). Of course, accessors will take into account this fact and functions for reading or writing such slots are unchanged. For example,

    (set! (command b) '(display "OK"))
permits to set the script associated to the b button.

Preceding defclass states that the command slot can contain a value of any type. Type of a slot permits to the system to apply the adequate coercion function when a slot is read. Since Tk always computes results as strings, this conversion can be done automatically when we know the type of the slot (e.g. a border width is always stored as an integer in Tk structures). No conversion is done when a slot is written; this work is done by Tk since it will reject bad values.

Note that using the object extension of STK permits the user to forget some Tk idiosyncrasies. In particular, it permits to avoid the knowledge of pure Tk naming conventions. The only thing the user has to know when creating a new object is it's parent. An example of widgets creation is shown below:

    (define f (make <Frame>))
    (define b1 (make <Button> 
                     :text "B1" 
                     :parent f))
    (define b2 (make <Button> 
                     :text "B2" 
                     :parent f))
Created buttons here specify that their parent is the frame f. Since this frame does not specify a particular parent, it is supposed to be a direct descendant of the root window ".". This parent's notion is also used for canvas items: a canvas item is considered as a son of the canvas which contains it. For instance,
    (define c (make <Canvas>))
    (define r (make <Rectangle> 
                    :parent c 
                    :coords '(0 0 50 50)))
defines a rectangle called r in the c canvas. User can now forget that r is included in c since this information is embedded in the Scheme object. To move this rectangle, one can use for example the following expression:
    (move r 10 10)
which is more natural than the things we have to do at STK first level.