Manual Pages for UNIX Darwin command on man snit
MyWebUniversity

Manual Pages for UNIX Darwin command on man snit

snit(n) Snit snit(n)

NAME

snit - Snit's Not Incr Tcl

SYNOPSIS

package require TTccll 88..44 package require ssnniitt ??00..9933??

$$oobbjjeecctt method args...

$$oobbjjeecctt ccoonnffiigguurree ?option? ?value? ...

$$oobbjjeecctt ccoonnffiigguurreelliisstt optionlist

$$oobbjjeecctt ccggeett option

$$oobbjjeecctt ddeessttrrooyy

$$oobbjjeecctt iinnffoo ttyyppee

$$oobbjjeecctt iinnffoo vvaarrss ?pattern?

$$oobbjjeecctt iinnffoo ttyyppeevvaarrss ?pattern?

$$oobbjjeecctt iinnffoo ooppttiioonnss ?pattern?

vvaarrnnaammee name ttyyppeevvaarrnnaammee name ccooddeennaammee name ffrroomm argvName option ?defvalue? vvaarriiaabbllee name ttyyppeevvaarriiaabbllee name iinnssttaallll compName uussiinngg objType objName args... iinnssttaallllhhuullll uussiinngg widgetType args... iinnssttaallllhhuullll name mmyymmeetthhoodd name ?args...? ssnniitt::::ttyyppee name definition ttyyppeevvaarriiaabbllee name ?value? ttyyppeemmeetthhoodd name arglist body ooppttiioonn namespec ?defaultValue? vvaarriiaabbllee name ?value? mmeetthhoodd name arglist body ccoonnssttrruuccttoorr arglist body ddeessttrruuccttoorr body oonnccoonnffiigguurree name arglist body oonnccggeett name body pprroocc name args body ddeelleeggaattee mmeetthhoodd name ttoo comp ddeelleeggaattee mmeetthhoodd name ttoo comp aass target ddeelleeggaattee mmeetthhoodd ** ttoo comp ddeelleeggaattee mmeetthhoodd ** ttoo comp eexxcceepptt exceptions ddeelleeggaattee ooppttiioonn namespec ttoo comp ddeelleeggaattee ooppttiioonn namespec ttoo comp aass target ddeelleeggaattee ooppttiioonn ** ttoo comp ddeelleeggaattee ooppttiioonn ** ttoo comp eexxcceepptt exceptions eexxppoossee comp eexxppoossee comp aass method ssnniitt::::wwiiddggeett name definition wwiiddggeettccllaassss name hhuullllttyyppee type ssnniitt::::wwiiddggeettaaddaappttoorr name definition ssnniitt::::ttyyppeemmeetthhoodd type name arglist body ssnniitt::::mmeetthhoodd type name arglist body

$$ttyyppee typemethod args...

$$ttyyppee ccrreeaattee name ?option value ...?

$$ttyyppee iinnffoo ttyyppeevvaarrss ?pattern?

$$ttyyppee iinnffoo iinnssttaanncceess ?pattern?

$$ttyyppee ddeessttrrooyy

DESCRIPTION

Snit is yet another pure Tcl object and megawidget system. It's unique among Tcl object systems (so far as I know) in that it's a system based

not on inheritance but on delegation. Object systems based on inheri-

tance only allow you to inherit from classes defined using the same system, and that's a shame. In Tcl, an object is anything that acts like an object; it shouldn't matter how the object was implemented. I designed Snit to help me build applications out of the materials at hand; thus, Snit is designed to be able to incorporate and build on any

object, whether it's a hand-coded object, a TTkk widget, an IInnccrr TTccll

object, a BBWWiiddggeett or almost anything else. This man page is intended to be a reference only; see the accompanying ssnniittffaaqq for a gentler, more tutorial introduction to Snit concepts. RREEFFEERREENNCCEE The Instance Command A Snit type or widget's ccrreeaattee type method creates objects of the type;

each object has a unique name which is also a Tcl command. This com-

mand is used to access the object's methods and data, and has this form:

$$oobbjjeecctt method args...

The method can be any of the standard instance methods defined in the next section, or any instance method defined in the type definition. The subsequent args depend on the specific method chosen. Standard Instance Methods

In addition to any delegated or locally-defined instance methods in the

type's definition, all Snit objects will have at least the following methods:

$$oobbjjeecctt ccoonnffiigguurree ?option? ?value? ...

Assigns new values to one or more options. If called with one argument, an option name, returns a list describing the option, as Tk widgets do; if called with no arguments, returns a list of lists describing all options, as Tk widgets do. Warning: This information will be available for delegated options only if the component to which they are delegated has a ccoonnffiigguurree method that returns this same kind of information.

$$oobbjjeecctt ccoonnffiigguurreelliisstt optionlist

Like ccoonnffiigguurree, but takes one argument, a list of options and their values. It's mostly useful in the type constructor, but can be used anywhere.

$$oobbjjeecctt ccggeett option

Returns the option's value.

$$oobbjjeecctt ddeessttrrooyy

Destroys the object, calling the ddeessttrruuccttoorr and freeing all related memory. Note: The ddeessttrrooyy method isn't defined for ssnniitt::::wwiiddggeett or ssnniitt::::wwiiddggeettaaddaappttoorr objects; instances of these are destroyed by calling the TTkk ddeessttrrooyy command, just as a normal widget is.

$$oobbjjeecctt iinnffoo ttyyppee

Returns the instance's type.

$$oobbjjeecctt iinnffoo vvaarrss ?pattern?

Returns a list of the object's instance variables (excluding Snit internal variables). The names are fully qualified. If pattern is given, it's used as a ssttrriinngg mmaattcchh pattern; only names which match the pattern are returned.

$$oobbjjeecctt iinnffoo ttyyppeevvaarrss ?pattern?

Returns a list of the object's type's type variables (excluding Snit internal variables). The names are fully qualified. If pattern is given, it's used as a ssttrriinngg mmaattcchh pattern; only names which match the pattern are returned.

$$oobbjjeecctt iinnffoo ooppttiioonnss ?pattern?

Returns a list of the object's option names. This always includes local options and explicitly delegated options. If unknown options are delegated as well, and if the component to

which they are delegated responds to $$oobbjjeecctt ccoonnffiigguurree like Tk

widgets do, then the result will include all possible unknown options which could be delegated to the component. If pattern is given, it's used as a ssttrriinngg mmaattcchh pattern; only names which match the pattern are returned. Note that the return value might be different for different instances of the same type, if component object types can vary from one instance to another. Commands for use in Object Code Snit defines the following commands for use in your object code: that

is, for use in type methods, instance methods, constructors, destruc-

tors, onconfigure handlers, oncget handlers, and procs. They do not

reside in the ::snit:: namespace; instead, they are created with the

type, and can be used without qualification. vvaarrnnaammee name Given an instance variable name, returns the fully qualified name. Use this if you're passing the variable to some other

object, e.g., as a -tteexxttvvaarriiaabbllee to a Tk label widget.

ttyyppeevvaarrnnaammee name Given an type variable name, returns the fully qualified name. Use this if you're passing the variable to some other object,

e.g., as a -tteexxttvvaarriiaabbllee to a Tk label widget.

ccooddeennaammee name Given the name of a proc (but not a type or instance method),

returns the fully-qualified command name, suitable for passing

as a callback. ffrroomm argvName option ?defvalue? The ffrroomm command plucks an option value from a list of options and their values, such as is passed into a type's ccoonnssttrruuccttoorr. argvName must be the name of a variable containing such a list; option is the name of the specific option. ffrroomm looks for option in the option list. If it is found, it and its value are removed from the list, and the value is

returned. If option doesn't appear in the list, then the def-

value is returned. If the option is a normal (undelegated) option, and defvalue is not specified, then the option's default value as specified in the type definition will be returned instead. vvaarriiaabbllee name Normally, instance variables are defined in the type definition along with the options, methods, and so forth; such instance

variables are automatically visible in all instance-specific

code. However, instance code (e.g., method bodies) can declare such variables explicitly using the vvaarriiaabbllee command, if desired; or, instance code can use the vvaarriiaabbllee command to

declare instance variables that don't appear in the type defini-

tion. It's generally best to define all instance variables in the type definition, and omit declaring them in methods and so forth. Note that this is not the same as the standard Tcl ::::vvaarriiaabbllee command. ttyyppeevvaarriiaabbllee name Normally, type variables are defined in the type definition,

along with the instance variables; such type variables are auto-

matically visible in all of the type's code. However, type methods, instance methods and so forth can use ttyyppeevvaarriiaabbllee to declare type variables explicitly, if desired; or, they can use ttyyppeevvaarriiaabbllee to declare type variables that don't appear in the type definition. It's generally best to declare all type variables in the type definition, and omit declaring them in methods, type methods, and so forth. iinnssttaallll compName uussiinngg objType objName args... Creates a new object and installs it as a component, as described under Components and Delegation. If this is a ssnniitt::::ttyyppee, then the following two commands are equivalent:

install myComp using myObjType $self.myComp options...

set myComp [myObjType $self.myComp options...]

Note that whichever method is used, compName must still be

declared in the type definition using vvaarriiaabbllee, or must be ref-

erenced in at least one ddeelleeggaattee statement. If this is a ssnniitt::::wwiiddggeett or ssnniitt::::wwiiddggeettaaddaappttoorr, and if options have been delegated to component compName, then those options will receive default values from the Tk option database. Note that it doesn't matter whether the component to be installed is a widget or not. See The Tk Option Database for more information. iinnssttaallllhhuullll uussiinngg widgetType args... iinnssttaallllhhuullll name The constructor of a ssnniitt::::wwiiddggeettaaddaappttoorr must create a widget to be the object's hull component; the widget is installed as the

hull component using this command. Note that the installed wid-

get's name must be $$wwiinn. This command has two forms. The first

form specifies the widgetType and the args... (that is, the hardcoded option list) to use in creating the hull. Given this form, iinnssttaallllhhuullll creates the hull widget, and initializes any options delegated to the hull from the Tk option database. In the second form, the hull widget has already been created; note

that its name must be "$win". In this case, the Tk option data-

base is not queried for any options delegated to the hull. See

The Tk Option Database for more information about ssnniitt::::wwiidd-

ggeettaaddaappttoorrs and the option database. The longer form is pre-

ferred; however, the shorter form allows the programmer to adapt a widget created elsewhere, which is sometimes useful. For example, it can be used to adapt a "page" widget created by a BWidgets tabbed notebook or pages manager widget. The command which creates the hull widget usually just passes its result to iinnssttaallllhhuullll as follows:

installhull [frame $win options....]

mmyymmeetthhoodd name ?args...? The mmyymmeetthhoodd command is used for formatting callback commands to be passed to other objects. It returns a command that when called will invoke method name with the specified arguments, plus of course any arguments added by the caller. In other words, both of the following commands will cause my object's

ddoossoommeetthhiinngg method to be called when $$bbuuttttoonn is pressed:

$button configure -command [list $self dosomething myargument]

$button configure -command [mymethod dosomething myargument]

The chief distinction between the two is that the latter form will not break if the creator of my object renames its object command. Type and Widget Definitions Snit provides the following commands for defining new types: ssnniitt::::ttyyppee name definition Defines a new abstract data type called name. If name is not a fully qualified command name, it is assumed to be a name in the namespace in which the ssnniitt::::ttyyppee command appears (usually the global namespace). It returns the fully qualified type name. The type name is then a command which is used to create objects of the new type, along with other activities. The ssnniitt::::ttyyppee definition block is a script which may contain the following definitions: ttyyppeevvaarriiaabbllee name ?value? Defines a type variable with the specified name, and optionally the specified value. Type variables are shared by all instances of the type. This definition can be used to define array variables, but cannot initialize their elements. ttyyppeemmeetthhoodd name arglist body Defines a type method with the specified name, argument list, and body. The variable ttyyppee is automatically

defined in the body to the type's fully-qualified name.

The arglist is a normal Tcl argument list and may contain default arguments and the aarrggss argument; however, it may not contain the argument names ttyyppee, sseellff, sseellffnnss, or wwiinn.

Type variables defined in the type definition are auto-

matically visible in the body of every type method. ooppttiioonn namespec ?defaultValue?

Defines an option for instances of this type, and option-

ally gives it an initial value. (The option's value

defaults to the empty string if no initial value is spec-

ified.) An option defined in this way is said to be locally defined. The namespec is a list defining the option's name, resource name, and class name, e.g.:

option {-font font Font} {Courier 12}

The option name must begin with a hyphen, and must not contain any upper case letters. The resource name and class name are optional; if not specified, the resource name defaults to the option name, minus the hyphen, and the class name defaults to the resource name with the first letter capitalized. Thus, the following statement is equivalent to the previous example:

option -font {Courier 12}

See The Tk Option Database for more information about resource and class names. Options are normally set and retrieved using the standard ccoonnffiigguurree and ccggeett instance methods. vvaarriiaabbllee name ?value?

Defines an instance variable, a private variable associ-

ated with each instance of this type, and optionally its initial value. This definition can be used to define array instance variables, but cannot initialize their elements. Note that the ddeelleeggaattee statement implicitly defines an instance variable for the named component. mmeetthhoodd name arglist body Defines an instance method, a subcommand of each instance of this type, with the specified name, argument list and body. The arglist is a standard Tcl argument list, and may contain default values and the argument names. The arglist is a normal Tcl argument list and may contain default arguments and the aarrggss argument. In addition, the method is implicitly passed the following arguments

as well: ttyyppee, which contains the fully-qualified type

name; sseellff, which contains the current instance command name; sseellffnnss, which contains the name of the instance's private namespace; and wwiinn, which contains the original instance name. Consequently, the arglist may not contain the argument names ttyyppee, sseellff, sseellffnnss, or wwiinn. An instance method defined in this way is said to be locally defined.

Type and instance variables defined in the type defini-

tion are automatically visible in all instance methods. If the type has locally defined options, the ooppttiioonnss array is also visible. ccoonnssttrruuccttoorr arglist body The constructor definition specifies a body of code to be executed when a new instance is created. The arglist is a normal Tcl argument list and may contain

default arguments and the aarrggss argument. As with meth-

ods, the arguments ttyyppee, sseellff, sseellffnnss, and wwiinn, are defined implicitly. If the constructor is not defined, it defaults to this: constructor {args} {

$self configurelist $args

}

For standard Tk widget behavior (or to achieve the behav-

ior of previous versions of snit) the argument list

should be the single name aarrggss, as shown. ddeessttrruuccttoorr body The destructor is used to code any actions which must take place when an instance of the type is destroyed: typically, the destruction of anything created in the constructor. As with arguments, the parameters ttyyppee, sseellff, sseellffnnss, and wwiinn, are defined implicitly. oonnccoonnffiigguurree name arglist body

Every locally-defined option has an oonnccoonnffiigguurree handler

which is called when the option is set to a new value by the ccoonnffiigguurree or ccoonnffiigguurreelliisstt instance method. The arglist may contain exactly one argument name. As with methods, the arguments ttyyppee, sseellff, sseellffnnss, and wwiinn, are defined implicitly. If no explicit onconfigure handler is defined for an option, the handler is defined as follows: onconfigure name {value} {

set options(name) $value

} If an explicit onconfigure handler is defined, the options array will be updated with the new value only if the handler so updates it. oonnccggeett name body

Every locally-defined option has an oonnccggeett handler which

is called when the option's value is retrieved. Although there is no explicit argument list, the arguments ttyyppee, sseellff, sseellffnnss, and wwiinn, are defined implicitly, just as they are for methods. The variables ttyyppee, sseellff, sseellffnnss, and wwiinn are defined as usual in the handler's body. Whatever the handler returns will be the return value of the call to the ccggeett instance method. If no explicit oncget handler is defined for an option, the handler is defined as follows: oncget name {

return $options(name)

} pprroocc name args body Defines a new Tcl procedure in the type's namespace. The new proc differs from a normal Tcl proc in that all type

variables defined in the type definition are automati-

cally visible. Although they are not implicitly defined for procs, the argument names ttyyppee, sseellff, sseellffnnss, and wwiinn should be avoided. ddeelleeggaattee mmeetthhoodd name ttoo comp ddeelleeggaattee mmeetthhoodd name ttoo comp aass target ddeelleeggaattee mmeetthhoodd ** ttoo comp ddeelleeggaattee mmeetthhoodd ** ttoo comp eexxcceepptt exceptions Delegates one or more instance methods to a component of the object. When a method name is explicitly stated, it will automatically be delegated to the named component as though the method were defined as follows: method name {args...} {

$comp mymethod args...

} If desired, the delegated method may target a method with a different name by using the aass clause; the target may

also include arguments add to the beginning of the argu-

ment list. The form "delegate method *" delegates all unknown method names to the specified component. The eexxcceepptt clause can be used to specify a list of exceptions, i.e., method names that will not be so delegated. A method cannot be both locally defined and delegated. ddeelleeggaattee ooppttiioonn namespec ttoo comp ddeelleeggaattee ooppttiioonn namespec ttoo comp aass target ddeelleeggaattee ooppttiioonn ** ttoo comp ddeelleeggaattee ooppttiioonn ** ttoo comp eexxcceepptt exceptions Defines a delegated option; the namespec is defined as

for the ooppttiioonn statement. When the ccoonnffiigguurree, ccoonnffiigg-

uurreelliisstt, or ccggeett instance method is used to set or retrieve the option's value, the equivalent ccoonnffiigguurree or ccggeett command will be applied to the component as though these oonnccoonnffiigguurree and oonnccggeett handlers were defined, where name is the option name from the namespec: onconfigure name {value} {

$comp configure name $value

} oncget name {

return [$comp cget name]

} If the aass clause is specified, then the target option name is used in place of name. The form "delegate option *" delegates all unknown method names to the specified comp. The eexxcceepptt clause can be used to specify a list of exceptions, i.e., option names that will not be so delegated. Warning: options can only be delegated to a component if it supports the ccoonnffiigguurree and ccggeett instance methods. Note that an option cannot be both locally defined and delegated. eexxppoossee comp eexxppoossee comp aass method Exposes component comp as a method of the type. In the first form, the method name is comp; in the second form, the method name is method. This differs from delegation in that it maps an instance method to the component itself instead of to one of the component's methods. Calling the new instance method is just like calling the component, except that if the method is called with no arguments it returns the component. ssnniitt::::wwiiddggeett name definition This command defines a Snit megawidget type with the specified name. The definition is defined identically to that for ssnniitt::::ttyyppee. A ssnniitt::::wwiiddggeett differs from a ssnniitt::::ttyyppee in these ways:

+o Every ssnniitt::::wwiiddggeett instance has an automatically-created

component called hhuullll, which is normally a Tk frame wid-

get. Other widgets created as part of the megawidget will be created within this widget. The hull component is initially created with the

requested widget name; then Snit does some magic, renam-

ing the hull component and installing its own instance command in its place. The hull component's new name is saved in an instance variable called hhuullll. +o The name of an instance must be valid Tk window name, and the parent window must exist. A ssnniitt::::wwiiddggeett definition can include any of statements allowed in a ssnniitt::::ttyyppee definition, and may also include these as well: wwiiddggeettccllaassss name Sets the ssnniitt::::wwiiddggeett's widget class to name, overriding

the default. See The Tk Option Database for more infor-

mation. hhuullllttyyppee type Determined the kind of widget used as the ssnniitt::::wwiiddggeett's hull. The type may be ffrraammee (the default) or ttoopplleevveell. ssnniitt::::wwiiddggeettaaddaappttoorr name definition This command defines a Snit megawidget type with the specified name. It differs from ssnniitt::::wwiiddggeett in that the instance's hhuullll component is not created automatically, but is created in the constructor and installed using the iinnssttaallllhhuullll command. Once the hull is installed, its instance command is renamed and replaced as with normal ssnniitt::::wwiiddggeetts. The original command is again accessible in the instance variable hhuullll. Note that in general it is not possible to change the widget class of a ssnniitt::::wwiiddggeettaaddaappttoorr's hull widget. See The Tk Option Database for information on how ssnniitt::::wwiiddggeettaaddaappttoorrs interact with the option database. ssnniitt::::ttyyppeemmeetthhoodd type name arglist body Defines a new typemethod (or redefines an existing typemethod) for a previously existing type. ssnniitt::::mmeetthhoodd type name arglist body Defines a new instance method (or redefines an existing instance method) for a previously existing type. Note that delegated instance methods can't be redefined. The Type Command A type or widget definition creates a type command, which is used to create instances of the type. The type command this form.

$$ttyyppee typemethod args...

The typemethod can be any of the standard type methods defined

in the next section, or any type method defined in the type def-

inition. The subsequent args depend on the specific typemethod chosen. Standard Type Methods In addition to any typemethods in the type's definition, all types and widgets will have at least the following method:

$$ttyyppee ccrreeaattee name ?option value ...?

Creates a new instance of the type, giving it the specified name and calling the type's constructor.

For ssnniitt::::ttyyppees, if name is not a fully-qualified command name,

it is assumed to be a name in the namespace in which the call to

ssnniitt::::ttyyppee appears. The method returns the fully-qualified

instance name. For ssnniitt::::wwiiddggeetts and ssnniitt::::wwiiddggeettaaddaappttoorrs, name must be a valid widget name; the method returns the widget name. So long as name does not conflict with any defined type method name, the ccrreeaattee keyword may be omitted.

If the name includes the string %%AAUUTTOO%%, it will be replaced with

the string $$ttyyppee$$ccoouunntteerr where $$ttyyppee is the type name and

$$ccoouunntteerr is a counter that increments each time %%AAUUTTOO%% is used

for this type. By default, any arguments following the name will be a list of option names and their values; however, a type's constructor can specify a different argument list.

$$ttyyppee iinnffoo ttyyppeevvaarrss ?pattern?

Returns a list of the type's type variables (excluding Snit

internal variables); all variable names are fully-qualified.

If pattern is given, it's used as a ssttrriinngg mmaattcchh pattern; only names which match the pattern are returned.

$$ttyyppee iinnffoo iinnssttaanncceess ?pattern?

Returns a list of the type's instances. For ssnniitt::::ttyyppees, it

will be a list of fully-qualified instance names; for ssnniitt::::wwiidd-

ggeetts, it will be a list of Tk widget names. If pattern is given, it's used as a ssttrriinngg mmaattcchh pattern; only names which match the pattern are returned.

$$ttyyppee ddeessttrrooyy

Destroys the type's instances, the type's namespace, and the type command itself. This method is defined only for ssnniitt::::ttyyppees; ssnniitt::::wwiiddggeetts use the Tk ddeessttrrooyy command instead. Components and Delegation

When an object includes other objects, as when a toolbar contains but-

tons or a GUI object contains an object that references a database, the

included object is called a component. The standard way to handle com-

ponent objects owned by a Snit object is to assign their names to a instance variable. In the following example, a ddoogg object has a ttaaiill object:

snit::type dog {

variable mytail constructor {args} {

set mytail [tail %AUTO% -partof $self]

$self configurelist $args

} method wag {} {

$mytail wag

} }

snit::type tail {

option -length 5

option -partof

method wag {} { return "Wag, wag, wag."} } Because the ttaaiill object's name is stored in an instance variable, it's easily accessible in any method.

As of Snit 0.84, the iinnssttaallll command provides an alternate way to cre-

ate and install the component:

snit::type dog {

variable mytail constructor {args} {

install mytail using tail %AUTO% -partof $self

$self configurelist $args

} method wag {} {

$mytail wag

} } For ssnniitt::::ttyyppees, the two methods are equivalent; for ssnniitt::::wwiiddggeetts and

ssnniitt::::wwiiddggeettaaddaappttoorrs, the iinnssttaallll command properly initializes dele-

gated options by querying the Tk option database. In the above examples, the ddoogg object's wwaagg method simply calls the ttaaiill component's wwaagg method. In OO circles, this is called delegation. Snit provides an easier way to do this, as shown:

snit::type dog {

delegate method wag to mytail constructor {args} {

set mytail [tail %AUTO% -partof $self]

$self configurelist $args

} } The ddeelleeggaattee statement in the type definition implicitly defines the instance variable mmyyttaaiill to hold the component's name; it also defines the ddoogg object's wwaagg method, delegating it to the ttaaiill component.

If desired, all otherwise unknown methods can be delegated to a spe-

cific component:

snit::type dog {

delegate method * to mytail constructor {args} {

set mytail [tail %AUTO% -partof $self]

$self configurelist $args

} method bark { return "Bark, bark, bark!" } } In this case, a ddoogg object will handle its own bbaarrkk method; but wwaagg will be passed along to mmyyttaaiill. Any other method, being recognized by neither ddoogg nor ttaaiill, will simply raise an error. Option delegation is similar to method delegation, except for the interactions with the Tk option database; this is described in the next section. The Tk Option Database This section describes how Snit interacts with the Tk option database, and assumes the reader has a working knowledge of the option database and its uses. The book Practical Programming in Tcl and Tk by Welch et al has a good introduction to the option database, as does Effective Tcl/Tk Programming. Snit is implemented so that most of the time it will simply do the

right thing with respect to the option database, provided that the wid-

get developer does the right thing by Snit. The body of this section goes into great deal about what Snit requires. The following is a brief statement of the requirements, for reference. +o If the widget's default widget class is not what is desired, set it explicitly using wwiiddggeettccllaassss in the widget definition. +o When defining or delegating options, specify the resource and class names explicitly when necessary.

+o Use iinnssttaallllhhuullll uussiinngg to install the hull for ssnniitt::::wwiiddggeettaaddaapp-

ttoorrs. +o Use iinnssttaallll to install all other components. The interaction of Tk widgets with the option database is a complex thing; the interaction of Snit with the option database is even more so, and repays attention to detail. Setting the widget class: Every Tk widget has a widget class. For Tk widgets, the widget class name is the just the widget type name with an initial capital letter, e.g., the widget class for bbuuttttoonn widgets is "Button".

Similarly, the widget class of a ssnniitt::::wwiiddggeett defaults to the unquali-

fied type name with the first letter capitalized. For example, the widget class of is "ScrolledText". The widget class can also be set explicitly using the wwiiddggeettccllaassss statement within the ssnniitt::::wwiiddggeett definition. Note that only ffrraammee and ttoopplleevveell widgets allow the user to change the widget class name, which is why they are the allowable hull types for normal ssnniitt::::wwiiddggeetts. The widget class of a ssnniitt::::wwiiddggeettaaddaappttoorr is just the widget class of its hull widget; this cannot be changed unless the hull widget is a ffrraammee or ttoopplleevveell, in which case it will usually make more sense to use ssnniitt::::wwiiddggeett rather than ssnniitt::::wwiiddggeettaaddaappttoorr. Setting option resource names and classes: In Tk, every option has three names: the option name, the resource name, and the class name. The option name begins with a hyphen is all lowercase; it's used when creating widgets, and with the ccoonnffiigguurree and ccggeett commands.

The resource and class names are used to initialize option default val-

ues by querying the Tk option database. The resource name is usually

just the option name minus the hyphen, but may contain uppercase let-

ters at word boundaries; the class name is usually just the resource name with an initial capital, but not always. For example, here are the option, resource, and class names for several tteexxtt widget options:

-background background Background

-borderwidth borderWidth BorderWidth

-insertborderwidth insertBorderWidth BorderWidth

-padx padX Pad

As is easily seen, sometimes the resource and class names can be inferred from the option name, but not always. Snit options also have a resource name and a class name. By default, these names follow the rule given above: the resource name is the option name without the hyphen, and the class name is the resource name

with an initial capital. This is true for both locally-defined options

and explicitly delegated options:

snit::widget mywidget {

option -background

delegate option -borderwidth to hull

delegate option * to text

# ...

} In this case, the widget class name is "Mywidget". The widget has the

following options: -background, which is locally defined, -borderwidth,

which is explicitly delegated; all other widgets are delegated to a component called "text", which is probably a Tk tteexxtt widget. If so, mmyywwiiddggeett has all the same options as a tteexxtt widget. The option, resource, and class names are as follows:

-background background Background

-borderwidth borderwidth Borderwidth

-padx padX Pad

Note that the locally defined option, "-background", happens to have

the same three names as the standard Tk "-background" option; and

"-pad", which is delegated implicitly to the "text" component has the

same three names for mmyywwiiddggeett as it does for the tteexxtt widget. "-bor-

derwidth", on the other hand, has different resource and class names than usual, because the internal word "width" isn't capitalized. For consistency, it should be; this is done as shown:

snit::widget mywidget {

option -background

delegate option {-borderwidth borderWidth} to hull

delegate option * to text

# ...

} The class name will default to "BorderWidth", as expected.

Suppose, however, that mmyywwiiddggeett also delegated "-padx" and "-pady" to

the hull. In this case, both the resource name and the class name must be specified explicitly:

snit::widget mywidget {

option -background

delegate option {-borderwidth borderWidth} to hull

delegate option {-padx padX Pad} to hull

delegate option {-pady padY Pad} to hull

delegate option * to text

# ...

} Querying the option database: If you set your widgetclass and option names as described above, Snit will query the option database when each instance is created, and will generally do the right thing when it comes to querying the option database. The remainder of this section goes into the gory details. Initializing locally defined options:

When an instance of a snit::widget is created, its locally defined

options are initialized as follows: each option's resource and class

names are used to query the Tk option database. If the result is non-

empty, it is used as the option's default; otherwise, the default hard-

coded in the type definition is used. In either case, the default can be overridden by the caller. For example, option add *Mywidget.texture pebbled

snit::widget mywidget {

option -texture smooth

# ...

}

mywidget .mywidget -texture greasy

Here, "-texture" would normally default to "smooth", but because of the

entry added to the option database it defaults to "pebbled". However, the caller has explicitly overridden the default, and so the new widget will be "greasy". Initializing options delegated to the hull: A ssnniitt::::wwiiddggeett's hull is a widget, and given that its class has been set it is expected to query the option database for itself. The only exception concerns options that are delegated to it with a different name. Consider the following code: option add *Mywidget.borderWidth 5 option add *Mywidget.relief sunken option add *Mywidget.hullbackground red option add *Mywidget.background green

snit::widget mywidget {

delegate option -borderwidth to hull

delegate option -hullbackground to hull as -background

delegate option * to hull

# ...

} mywidget .mywidget

set A [.mywidget cget -relief]

set B [.mywidget cget -hullbackground]

set C [.mywidget cget -background]

set D [.mywidget cget -borderwidth]

The question is, what are the values of variables A, B, C and D? The value of A is "sunken". The hull is a Tk frame which has been given the widget class "Mywidget"; it will automatically query the

option database and pick up this value. Since the -relief option is

implicitly delegated to the hull, Snit takes no action. The value of B is "red". The hull will automatically pick up the value

"green" for its -background option, just as it picked up the -relief

value. However, Snit knows that -hullbackground is mapped to the

hull's -background option; hence, it queries the option database for

-hullbackground and gets "red" and updates the hull accordingly.

The value of C is also "red", because -background is implicitly dele-

gated to the hull; thus, retrieving it is the same as retrieving -hull-

background. Note that this case is unusual; in practice, -background

would probably be explicitly delegated to some other component. The value of D is "5", but not for the reason you think. Note that as

it is defined above, the resource name for -borderwidth defaults to

"borderwidth", whereas the option database entry is "borderWidth". As

with -relief, the hull picks up its own "-borderwidth" option before

Snit does anything. Because the option is delegated under its own name, Snit assumes that the correct thing has happened, and doesn't worry about it any further.

For ssnniitt::::wwiiddggeettaaddaappttoorrs, the case is somewhat altered. Widget adap-

tors retain the widget class of their hull, and the hull is not created automatically by Snit. Instead, the ssnniitt::::wwiiddggeettaaddaappttoorr must call

iinnssttaallllhhuullll in its constructor. The normal way to do this is as fol-

lows:

snit::widgetadaptor mywidget {

# ...

constructor {args} {

# ...

installhull using text -foreground white

#

}

#...

}

In this case, the iinnssttaallllhhuullll command will create the hull using a com-

mand like this:

set hull [text $win -foreground white]

The hull is a tteexxtt widget, so its widget class is "Text". Just as with ssnniitt::::wwiiddggeett hulls, Snit assumes that it will pick up all of its normal option values automatically; options delegated from a different name are initialized from the option database in the same way. Initializing options delegated to other components:

Non-hull components are matched against the option database in two

ways. First, a component widget remains a widget still, and therefore is initialized from the option database in the usual way. Second, the option database is queried for all options delegated to the component,

and the component is initialized accordingly-provided that the iinnssttaallll

command is used to create it.

Before option database support was added to Snit, the usual way to cre-

ate a component was to simply create it in the constructor and assign its command name to the component variable:

snit::widget mywidget {

delegate option -background to myComp

constructor {args} {

set myComp [text $win.text -foreground black]

} }

The drawback of this method is that Snit has no opportunity to initial-

ize the component properly. Hence, the following approach is now used:

snit::widget mywidget {

delegate option -background to myComp

constructor {args} {

install myComp using text $win.text -foreground black

} } The iinnssttaallll command does the following: +o Builds a list of the options explicitly included in the iinnssttaallll

command - in this case, -foreground.

+o Queries the option database for all options delegated explicitly to the named component.

+o Creates the component using the specified command, after insert-

ing into it a list of options and values read from the option

database. Thus, the explicitly include options (-foreground)

will override anything read from the option database. +o If the widget definition implicitly delegated options to the component using "delegate option *", then Snit calls the newly created component's ccoonnffiigguurree method to receive a list of all of the component's options. From this Snit builds a list of options implicitly delegated to the component which were not explicitly included in the iinnssttaallll command. For all such options, Snit queries the option database and configures the component accordingly.

Non-widget components: The option database is never queried for

ssnniitt::::ttyyppees, since it can only be queried given a Tk widget name. How-

ever, ssnniitt::::wwiiddggeetts can have non-widget components. And if options are

delegated to those components, and if the iinnssttaallll command is used to install those components, then they will be initialized from the option database just as widget components are. CCAAVVEEAATTSS Please understand that while Snit is already very stable, it is still early days in Snit's development, and not be too critical. If you have problems, find bugs, or new ideas you are hereby cordially invited to

submit a report of your problem, bug, or idea at the SourceForge track-

ers for tcllib, which can be found at http://source-

forge.net/projects/tcllib/. The relevant category is snit.

One particular area to watch is the interaction of Snit with other megawidget packages. Some widgets in BWidgets for example place their

own binding not on a separate bind-tag, but on the widget

itself. When used as the hull of a ssnniitt::::wwiiddggeettaaddaappttoorr this causes them

to be called before Snit, removing the widget command. A previous ver-

sion of Snit was tripped by this and threw errors because it tried to operate on and with an already deleted widget command. Snit is now able to deal with this, despite the fact that the ultimate cause is at least bad behaviour of Bwidget, possibly even a bug. This however does not preclude that there might be other issues lurking.

So, if you use a ssnniitt::::wwiiddggeettaaddaappttoorr to adapt somebody else's megawid-

get, you need to be very careful about making sure the bbiinnddttaaggss are done properly. There's no way for Snit to take into account all the possible weird things other megawidget frameworks might do wrong.

KNOWN BUGS

+o Error stack traces returned by Snit are extremely ugly and typi-

cally contain far too much information about Snit internals.

+o Also see the SourceForge Trackers at http://source-

forge.net/projects/tcllib/, category snit.

HISTORY

During the course of developing Notebook (See http://www.wjdu-

quette.com/notebook), my Tcl-based personal notebook application, I

found I was writing it as a collection of objects. I wasn't using any

particular object-oriented framework; I was just writing objects in

pure Tcl following the guidelines in my Guide to Object Commands (See http://www.wjduquette.com/tcl/objects.html), along with a few other tricks I'd picked up since. And it was working very well. But on the other hand, it was getting tiresome. Writing objects in pure Tcl is straightforward, once you figure it out, but there's a fair amount of boilerplate code to write for each one, especially if you're trying to create megawidgets or create objects with options, like Tk widgets have.

So that was one thing-tedium is a powerful motivator. But the other

thing I noticed is that I wasn't using inheritance at all, and I wasn't missing it. Instead, I was using delegation: objects that created other objects and delegated methods to them. And I said to myself, "This is getting tedious...there has got to be a better way." And one afternoon, on a whim, I started working on Snit, an object system that works the way Tcl works. Snit doesn't support

inheritance, but it's great at delegation, and it makes creating megaw-

idgets easy. I should add, I'm not particularly down on Incr Tcl. But "Snit's Not Incr Tcl" occurred to me while I was casting about for a name, and I guess there was a certainly inevitability about it.

If you have any comments or suggestions (or bug reports!) don't hesi-

tate to send me e-mail at will@wjduquette.com. In addition, there's

now a Snit mailing list; you can find out more about it at the Snit

home page, see http://www.wjduquette.com/snit.

CCRREEDDIITTSS Snit has been designed and implemented from the very beginning by William H. Duquette. However, much credit belongs to the following people for using Snit and providing me with valuable feedback: Rolf Ade, Colin McCormack, Jose Nazario, Jeff Godfrey, Maurice Diamanti, Egon Pasztor, David S. Cargo, Tom Krehbiel, Michael Cleverly, Andreas Kupries, Marty Backe, Andy Goth, Jeff Hobbs, and Brian Griffin. KKEEYYWWOORRDDSS BWidget, C++, Incr Tcl, adaptors, class, mega widget, object, object oriented, widget, widget adaptors COPYRIGHT

Copyright (c) 2003-2004, by William H. Duquette

snit 0.93 snit(n)




Contact us      |      About us      |      Term of use      |       Copyright © 2000-2019 MyWebUniversity.com ™