Creating custom widgets

One of the uses of the Slate is to rapidly create custom widgets. We'll use the Slate and some interactors to simulate a custom widget that mimics a "slider" as used on audio equipment. This example is a simple version of the complete Slider widget contained in the Slate directory.

First, clean the slate:

$slate delete all

Now, create some items that represent the slider components. The first is a text item to display the current value:

set value [$slate create text 50 20 -text 0 -anchor s -fill blue]

The second is the vertical "trough" of the slider:

set trough [$slate create Frame 48 23 52 143 -color darkgrey \
		-borderwidth 2 -relief sunken]

The third is the horizontal "bar" of the slider:

set bar [$slate create Frame 40 132 60 142  \
		-color darkseagreen -borderwidth 3]

When the bar is moved, we want to update the display of the slider value. Assuming the slider ranges from 0 to 11, this procedure will update it:

proc updatevalue {} {
	global slate bar value
	set position [expr [lindex [$slate coords $bar] 1] + 5]
	set x [expr (137.0-$position)/108.0 * 11.0]
	$slate itemconfigure $value -text [format %.1f $x]
}

Now, we need some interactors to move the bar. Firstly, create and bind an Alonger that moves the bar along the trough. It is given a value for its -bounds option to prevent it being moved past the ends of the trough:

set alonger [$slate interact create Alonger -along y \
		-dragcommand updatevalue -bounds {24 142}]
$alonger bind $bar -button 1
(Try moving the bar.) Now, suppose instead we want the bar to move in steps of 0.5 instead of continuously. To do this, create a Stepper interactor and cascade it with the Alonger interactor:
set stepper [$slate interact create Stepper -gridsize [expr 108.0/22] \
		-dragcommand updatevalue]
$alonger cascade $stepper
(Now try moving the bar. Depending on where the bar was when you invoked the above code, the displayed values may not be multiples of 0.5. For this simple example, we won't worry about fixing this.) To get back to the previous behavior, remove the stepper from the chain:
$alonger uncascade
We have just used a couple of interactors that use the mouse to manipulate graphical object -- most interactors are in fact of this type. To illustrate that there is more to interactors than just dragging things about with the mouse, let's first create a label underneath the slider:
set label [$slate create text 50 150 -text "A slider" -anchor n \
			-justify center]
And then attach an Editor interactor to it:
set editor [$slate interact create Editor]
$editor bind $label
Now, clicking on the label underneath the slider will place the insertion cursor in the label and allow you to edit it. Use shift with the cursor keys to select a region; use Control with the cursor keys to move left and right a word at a time. To remove the cursor from the label:
$editor stop
To disable editing completely:
$editor unbind $label
This example has created a slider directly onto a Slate. The complete Slider widget is an [incr Tk] mega-widget, and so can be created just like any other widget:
::tycho::Displayer .d
::tycho::Slider .d.s -label Fred -resolution 0.5 -to 11 -command puts
pack .d.s
.d centerOnScreen
(This Slider prints its current value to the Tcl console. There's actually a bug in it: it is performing too many prints...) The Slider widget has a more complex set of interaction mechanisms, and uses two more interactors we have not used in this tutorial:

See the Slider User's Guide for a description of its operation, the Slider class documentation for more information on its calling interface and options, and the Slate class documentation for detailed information on the interactors.

Next
Back up
Tycho Home Page


Copyright © 1996, The Regents of the University of California. All rights reserved.
Last updated: 96/12/11, comments to: johnr@eecs.berkeley.edu