Yes, custom objects need some Tcl code too.
Take a look at the file "csphere.tcl"
.
This code, first, fills two important variables: "CSphere_props"
and "CSphereAttr"
.
global ay CSphere_props CSphereAttr CSphereAttrData set CSphere_props { Transformations Attributes Material Tags CSphereAttr } array set CSphereAttr { arr CSphereAttrData sproc "" gproc "" w fCSphereAttr }
"CSphere_props"
holds a list of all properties of the
CSphere. There are well known standard properties
"Transformations Attributes Material Tags"
and a new
special property "CSphereAttr"
.
The handling of the standard properties is done entirely by the core. No need for further adjustments.
The new special property "CSphereAttr"
, however, must be
introduced to the core properly now.
This is done by filling a global array named as the property,
in our case the property, and the array, are named "CSphereAttr"
.
The single elements denote:
sproc ""
)
the core will use the internal mechanism and call the
callback provided on registration of your object type.
This is the point where you may jump into own property
functionality, if you need to provide arguments to your
own functions or do some other magic (call other commands etc.pp.).Now the property GUI itself needs to be created:
array set CSphereAttrData { Closed 1 Radius 1.0 ZMin -1.0 ZMax 1.0 ThetaMax 1.0 } # create CSphereAttr-UI set w [frame $ay(pca).$CSphereAttr(w)] addCheck $w CSphereAttrData Closed addParam $w CSphereAttrData Radius addParam $w CSphereAttrData ZMin addParam $w CSphereAttrData ZMax addParam $w CSphereAttrData ThetaMax
The code is really simple and creates a static GUI consisting of a checkbox and four entries for parameters. The different available GUI elements are discussed in the next sections.
Finally, we create an entry in the main menu, for easy creation of our new object type:
# add menu entry to the Create/Custom Object sub-menu mmenu_addcustom CSphere "crtOb CSphere; uS; sL; rV" # tell the rest of Ayam (or other custom objects), that we are loaded lappend ay(co) CSphere
A property GUI is usually organized in list form.
The single list elements are mostly built by
calling a single Tcl command of the Ayam core. All elements
are implemented in the file "uie.tcl"
(UIE - User Interface
Elements).
The template for such a command (that creates a single line of a property GUI) is as follows:
add{type} w array name [default]
type
is the type of the entry. Predefined and heavily
used by the rest of Ayam are: Text, Param, Menu, Check, Color,
File, String and Command.
Depending on the type, the actual parameters are a bit different
but this is documented in detail later on...
w
is the window the new entry should be created in.
Just pass the name of the window of the property GUI.
array
is the name of the (global) array where
the parameters that should be edited are actually stored.
name
is the name of the variable in the global
array array
that this entry should manipulate.
In addition, this name is often used in a label to mark
the entry. You should use descriptive and not too
long variable names.
default
is a list of default values.
However, not all GUI elements support those!
You are, of course, not tied to the aforementioned entries. The seashell custom object, for instance, implements an own type, an entry consisting of a slider, that is even able to issue apply operations while dragging the slider.
The following sections document all core entry types.
addText w f text
adds a line containing the text text
to the property GUI.
f
is required to generate window names, use e1
,
e2
etc.; f
must be unique over all entries of a property
GUI.
Example:
set w [frame $ay(pca).$CSphereAttr(w)] addText $w CSphereAttrData e1 "CSphere Attributes"
addParam w array name [default]
creates the standard parameter manipulation entry consisting of a label, two buttons for quick parameter manipulation by doubling, dividing the value, and finally an entry for direct manipulation.
Example:
set w [frame $ay(pca).$CSphereAttr(w)] addParam $w CSphereAttrData Radius
addMenu w array name list
adds a menu button, that toggles between the elements
of the list list
. The variable name
always contains the index of the selected entry. Note, that the
variable name has to exist before the call to addMenu!
Example:
set CSphereAttrData(Type) 0 set w [frame $ay(pca).$CSphereAttr(w)] addMenu $w CSphereAttrData Type [list Simple Enhanced]
addCheck w array name
adds a single check button to the GUI. The variable name
will be set to either 0 or 1 according to the state of the check button.
set w [frame $ay(pca).$CSphereAttr(w)] addCheck $w CSphereAttrData Closed
addColor w array name [default]
adds a color selection facility. The color values will be
written to variables named {name}_R
,
{name}_G
, and {name}_B
.
Example:
set w [frame $ay(pca).$CSphereAttr(w)] addColor $w CSphereAttrData SphereCol
addFile w array name
adds a string entry and a small button, that starts the standard file requester, handy for strings that contain file names.
Example:
set w [frame $ay(pca).$CSphereAttr(w)] addFile $w CSphereAttrData FName
addString w array name [default]
adds a simple string entry.
Example:
set w [frame $ay(pca).$CSphereAttr(w)] addString $w CSphereAttrData Name
addCommand w f text command
adds a big button labelled with text
that starts
the command command
.
f
is (similar to text entries) a name for a window,
I suggest to name the windows c1
, c2
etc.;
f
must be unique over all entries of a property GUI.
Example:
set w [frame $ay(pca).$CSphereAttr(w)] addCommand $w c1 "PressMe!" "puts Hi"
You may link additional functionality of your custom object to entries in the custom menu.
The following example code snippet shows how to do that:
# link proc fooproc to Custom menu # we need access to global array "ay" global ay # always create a cascaded sub-menu $ay(cm) add cascade -menu $ay(cm).foo -label "Foo" # create menu set m [menu $ay(cm).foo] # create menu entry $m add command -label "Foo(l)" -command fooproc
Note, that you should always create a new sub-menu using a cascade entry instead of creating entries directly in the custom menu.