GRIDPLUS2 - User Defined Grid Widgets
Home Reference Manpage Examples Download License Contact

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:-

nameName for widget.
windowName of toplevel window containing the widget (Null if root window).
basenameName for widget taking into account the -basename option (**).
styleStyle for widget taking into account the -style, &type:style/optionset and #style options.
widthWidth/size for widget taking into account the -width, integer and integer1/integer2 options.
fixedFixed width for widget taking into account the -fixed and integer1/integer2 options.
stateState for widget taking into account the -state, >, < options and the Groups facility.
widgetOptionsDict 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.


::gridplus::=

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".


::gridplus::=%

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?


::gridplus::=:

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.


::gridplus::=?

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 "+".


::gridplus::=@

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?


::gridplus::=<

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'.


::gridplus::gpEntryEdit

Provides a "pop-up" Cut/Copy/Paste menu for entry type widgets.

Syntax:

::gridplus::gpEntryEdit entryWindow X Y ?variable?

entryWindowName of toplevel window containing entry widget.
XX position for menu.
YY position for menu.
variableName 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

User Defined Grid Widget 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} {
Create a widget procedure - The widget will have type "=f".

upvar 1 options options

global {}
Make the "options" and null named arrays available.

set folder [=  $widgetOptions +]
Set the value of "folder" to the value of the widget option with key "+". If the widget option has not been set the value will be null.

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]]
Set the value of "icon" to the value of the widget option with key ":". If the widget option has not been set then use the value of "*Gridplus.=fileSelectIcon" from the option database. If neither has been set the value will be null.

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]]
Set the value of the null named array element identified by "$name" to the value of the widget option with key "=". If the widget option has not been set then use the default value for the widget set using gpdefault. If neither has been set the value will be null.

This enables the "=" widget option to be used to specify a default value for the "File Selection Field" widget.

::ttk::frame $name
Create frame with the name of the GRIDPLUS widget to contain the widget elements.

::ttk::entry  $name.entry -width $width -style $style -state $state -takefocus $options(-takefocus) -textvariable ($name)
Create entry using the "width", "style", "state" widget parameter, and "-takefocus" grid option, values. The "-textvariable" is associated with the null named array "$name" element.

set command [subst -nocommands {set ($name) [tk_getOpenFile -initialdir "$folder"]}]
Set the value of "command" to represent the command to be invoked when the button is pressed to display a tk_getOpenFile file selection dialog.

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
}
If the value of "icon" is not null then create a button using the specified icon image.

...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
Use the grid geometry manager to arrange the entry and button in the frame.

bind $name.entry <Button-3> "::gridplus::gpEntryEdit {$window} %X %Y $name"
Set "Button-3" (Right mouse button) to invoke a "Cut/Copy/Paste" entry edit menu.

The following three lines of code are required to enable this User Defined Grid Widget to work with the groups facility.

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 {}"
When the existing "$name" widget is destroyed delete the procedure called "::$name".

rename ::$name ::gridplus::$name:frame
Rename "::$name" procedure so that a new procdure with this name can be created...

proc ::$name {- > state} "$name.button configure -state \$state; $name.entry configure -state \$state"
Create a procedure called "::$name" to set the state of the entry and button components of the User Defined Grid Widget to the required state. The first two parameters passed to this procedure are not used and can be given "dummy" names.


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...


Copyright © 2014 Adrian Davis.