GRIDPLUS2 - User Defined Grid Widgets | ![]() |
||||||
|
GRIDPLUS User Defined Grid Widgets |
GRIDPLUS has a facility to create user defined widgets which can be used in that same way as for native GRIDPLUS widget grid widgets when using the "&type" and "&type:style/optionset" widget option syntax.
See the example below.
Naming |
User Defined Widget Grid Widgets must be identified by a single letter (upper or lower case) prefixed with "=".
Example:
For a "File Selection Field" widget which is to be named "=f" the widget procedure will be called:-
::gridplus::widget:=f
It is strongly recommended that option database options for user defined widgets are also prefixed with "=". This will ensure that they do not clash with options for standard GRIDPLUS widgets.
Example:
*Gridplus.=myWidgetOption
Examination of the example below should give a good idea as to the usage.
Interface |
The following parameters are passed to a widget procedure:-
name | Name for widget. |
window | Name of toplevel window containing the widget (Null if root window). |
basename | Name for widget taking into account the -basename option (**). |
style | Style for widget taking into account the -style, &type:style/optionset and #style options. |
width | Width/size for widget taking into account the -width, integer and integer1/integer2 options. |
fixed | Fixed width for widget taking into account the -fixed and integer1/integer2 options. |
state | State for widget taking into account the -state, >, < options and the Groups facility. |
widgetOptions | Dict containing the +value, -value, *groupname, ~command, :icon, !name, =default and "text" widget options. |
The %group and ?helptext options do work as documented with User Defined Widgets - However, these options are not included in the "widgetOptions" dict.
It is recommended that the widget options are used, where possible, for the intended purpose.
NOTE: (**) The names used for Embedded Grid Widgets and the names of commands invoked by Embedded Grid widgets follow the rules of the -basename option. In effect, they are based on the name of the parent Grid.
Widget Grid Options |
The widget grid options can be accessed from the options array. The example below shows the recommended method to do this.
Support Procedures |
There are a number of support procedures which simplify and make GRIDPLUS widget procedures more readable. While use of these procedures is not mandatory - it is recommended.
Examination of the example below and the widget procedures in the GRIDPLUS source code should give a good idea as to the usage.
Returns value of "key" element from "dict". If "key" is not found then "default" is returned. The default value for "default" is null.
Syntax:
= dict key ?default?
Examples:
set icon [= $widgetOptions :]...Sets the value of "icon" to be the element from "$widgetOptions" with key ":". If the element does not exist the value of "icon" will be set to null.
set command [= $widgetOptions ~ $name]...Sets the value of "command" to be the element from "$widgetOptions" with key "~". If the element does not exist the value of command will be the value of "$name".
Returns "state" of widget "name". If widget is part of a group the state for the Group is returned. If "flag" is set to '!' and the state is 'disabled' then 'readonly" is returned.
Syntax:
=% name state ?flag?
Creates "icon" image and returns the name of the image.
Syntax:
=: icon
Example:
::ttk::label $name.icon -image [=: $icon]...Creates the image specified by "$icon" and returns its name to be used as the value of the "-image" option for a "::ttk::label" command.
Returns true if "dict" "key" exists otherwise false.
Syntax:
=? dict key
Example:
if {[=? $widgetOptions +]} {focus $name}...Gives focus to the widget identified by "$name" if "$widgetOptions" contains an element with key "+".
Returns default value for widget "name" if one has been set using gpdefault - otherwise returns "default". The default value for "default" is null.
Syntax:
=@ name ?default?
Returns GRIDPLUS option database "option" if one has been set - Otherwise returns "default". The default value for "default" is null.
Syntax:
=< option ?default?
Example:
set state [=< entryDisabled readonly]...Sets the value of "state" to be the "*Gridplus.entryDisabled" option database option if one has been set - Otherwise the value of "state" will be "readonly'.
Provides a "pop-up" Cut/Copy/Paste menu for entry type widgets.
Syntax:
::gridplus::gpEntryEdit entryWindow X Y ?variable?
entryWindow | Name of toplevel window containing entry widget. |
X | X position for menu. |
Y | Y position for menu. |
variable | Name of variable associated with entry. |
NOTE: The default for "variable" is the name of the widget/window containing "X" and "Y". If the value of the null named array variable identified by "variable" is null the "Cut" and "Copy" menu options are disabled.
Example:
::gridplus::gpEntryEdit {$window} %X %Y $name...When invoked will display an edit menu for "$window" at position "X,Y". If the value of the array variable "($name)" is null the "Copy" and "Cut" options are disabled.
Example |
This example creates a "File Selection Field" widget:-
Window:
Source Code:
#-------------------------------------# # User Defined Grid Widget procedure. # #-------------------------------------# proc ::gridplus::widget:=f {name window basename style width fixed state widgetOptions} { upvar 1 options options global {} set folder [= $widgetOptions +] set icon [= $widgetOptions : [=< =fileSelectIcon]] set ($name) [= $widgetOptions = [=@ $name]] ::ttk::frame $name ::ttk::entry $name.entry -width $width -style $style -state $state -takefocus $options(-takefocus) -textvariable ($name) set command [subst -nocommands {set ($name) [tk_getOpenFile -initialdir "$folder"]}] if {$icon ne ""} { ::ttk::button $name.button -image [=: $icon] -style $style -state $state -takefocus $options(-takefocus) -command $command } else { ::ttk::button $name.button -text "..." -width 3 -style $style -state $state -takefocus $options(-takefocus) -command $command } grid $name.entry $name.button bind $name.entry <Button-3> "::gridplus::gpEntryEdit {$window} %X %Y $name" bind $name <Destroy> "rename ::$name {}" rename ::$name ::gridplus::$name:frame proc ::$name {- > state} "$name.button configure -state \$state; $name.entry configure -state \$state" } #---------------------------------------------------# # Create sample widget grid using the above widget. # #---------------------------------------------------# gridplus widget .mygrid -title MyGrid -wtitle "User Defined Widgets" { {&=f "User1" .user1 30} {&=f "User2" .user2 30 +c:/windows %mygrp "?This is User2"} } pack .mygrid
Comments:
proc ::gridplus::widget:=f {name window basename style width fixed state widgetOptions} {
upvar 1 options options global {}
set folder [= $widgetOptions +]
This enables the "+" widget option to be used to set the initial folder for the file selection dialog. If this is not specified the current folder is used.
set icon [= $widgetOptions : [=< =fileSelectIcon]]
This enables the ":" widget option to be used to specify an icon to be displayed on the file selection invoke button.
set ($name) [= $widgetOptions = [=@ $name]]
This enables the "=" widget option to be used to specify a default value for the "File Selection Field" widget.
::ttk::frame $name
::ttk::entry $name.entry -width $width -style $style -state $state -takefocus $options(-takefocus) -textvariable ($name)
set command [subst -nocommands {set ($name) [tk_getOpenFile -initialdir "$folder"]}]
The command will set the value of the null named array "$name" element to be the name of the selected file.
if {$icon ne ""} { ::ttk::button $name.button -image [=: $icon] -style $style -state $state -takefocus $options(-takefocus) -command $command } else { ::ttk::button $name.button -text "..." -width 3 -style $style -state $state -takefocus $options(-takefocus) -command $command }
...otherwise...
Create a button with the text set to "...".
In either case the "-style" and "-state" values are taken from the procedure parameters, "-takefocus" uses the appropriate widget grid option.
grid $name.entry $name.button
bind $name.entry <Button-3> "::gridplus::gpEntryEdit {$window} %X %Y $name"
A procedure with the same name as the GRIDPLUS widget is required which sets the widget state appropriately when called as:-
name configure -state state
bind $name <Destroy> "rename ::$name {}"
rename ::$name ::gridplus::$name:frame
proc ::$name {- > state} "$name.button configure -state \$state; $name.entry configure -state \$state"
Example using the User Defined Grid Widget created above...
gridplus widget .mygrid -title MyGrid -wtitle "User Defined Widgets" { {&=f "User1" .user1 30} {&=f "User2" .user2 30 +c:/windows %mygrp "?This is User2"} } pack .mygrid
This creates a widget grid called ".mygrid" contaning two "File Selection Field" widgets:-
The "File Selection Field" widget can show an icon on place of the default "..."
Making use of the built-in GRIDPLUS "folder" icon - If the following command is inserted before the "gridplus widget" command...
gpoptions =fileSelectIcon folder
...The following will be created...
...however, this widget probably looks better with a slightly smaller icon.
Assuming there is an icon Library/Directory named "Icons" which contains an appropriate icon named "folder_small" - If the following command is inserted before the "gridplus widget" command...
gpoptions { iconFile Icons =fileSelectIcon folder_small }
...Something like the following will be created...
It is also possible to set an icon for individual widgets using the ":" widget option.
If the "gridplus widget" command in the original example is replaced with...
gridplus widget .mygrid -title MyGrid -wtitle "User Defined Widgets" { {&=f "User1" .user1 30} {&=f "User2" .user2 30 :folder +c:/windows %mygrp "?This is User2"} }
...The following will be created...