1. Tcl/Tk Conference - Chicago 2010
2. Accelerating Tk Development with Wize 3.1
By Peter MacDonald, peter@pdqi.com
PDQ Interfaces Inc, http://pdqi.com
3. Wize
What is Wize?
- an attempt at making Tk an unparalleled development environment by:
- increasing power while decreasing complexity
- expanding the class of applications which Tk is suitable for
- improving non-native appearance (ie. on Linux to)
4. Wize Features
What does Wize provide?
- an abstract Tk layout engine: Gui
- workhorse widgets: TreeView and Tabset
- a data extension: tree
- code and data validation for Tcl
- validation of Tk sub-commands via Class name
- access to Tk introspection with a single key sequence
- extended capabilities for Tk
- a set of common support components
- running applications directly from a .zip file
5. Window Inspector
- Tk already provides extensive introspection facilities
- Wize's window inspector simply exposes these
- can be opened on any window with <Control-Alt-Shift-2>
- the inspector also includes a Menu with:
- a proc browser
- a var browser
- a namespace browser
- a window-tree browser
- an introspect application
- light and heavyweight editors
- and the venerable Tk console
6. Validation
What is validation?
- the force-compiling of proc bodies to do checking
- the detection of most syntax errors
- verifying that call parameters match expected number and type
- reporting calls without preceding proc or extern definitions
- checking for uninitialized array elements, eg. for _ and Declare arrays
- compile of code object-args, eg. for expr and catch
7. Warnings
How do we validate a program?
- to validate a program we run it with:
wize -Wall myapp.tcl; # or ...
./myapp.tcl -Wall arg1 arg2 ...
8. Extern
- validation simply verifies extern definitions, and their types
- the format for an extern is:
extern NAME ARGS TYPES CLASS COMMENT
- wize provides declarations for all built-ins, eg:
extern incr {varName {amount 1}} {Int var Int} I "Increment variable"
extern text {w args} {. tkwin {opts -fg -bg -width -height}} I "Text widget"
extern source {file args} {. {vopts ?-encoding type?} .} I "Evaluate file"
- types can also be added to a proc with #TYPES: as in:
proc bad {n} { #TYPES: . Int
}
9. Extern Types
- most extern types are simple such as int and bool
- several special types are used extensively by builtin externs:
- opts - a list of names in the name/value pairs to 'args
- topts - is like opts but each name has an accompanying type
- vopts - provides optional prefixing options, eg. string -strict
- here is an example using topts:
extern text {w args} {. tkwin {topts -bg tkcolor -width tkpixel}} I
10. CAPI
Inline modules Tcl -> C; enforces extern and unloads args:
# Build with: % wize /zvfs/wiz/capi.tcl math.tcl
# % gcc -g -shared -DUSE_TCL_STUBS -o libAppmath.so math.c
namespace eval ::app::math {
namespace ensemble create
namespace export {[a-z]*}
proc add {i j} {#TYPES: . Double Double
return [expr {$i+$j}]
#CBODY:
Tcl_SetObjResult(interp,
Tcl_NewDoubleObj(arg_i + arg_j));
}
proc sub {i j} {#TYPES: . Double Double
return [expr {$i-$j}]
#CBODY:
Tcl_SetObjResult(interp,
Tcl_NewDoubleObj(arg_i - arg_j));
}
}
11. GUI
- Gui is an engine for laying out Tk user interfaces:
- it use the file extension .gui
- evaluates its content fault-tolerantly
- models content after HTML/CSS/Javascript
- as with web content there are 3 elements in a Gui:
- Layout - HTML/XML
- Style - CSS
- Script - Javascript.
12. Layout
A Gui layout uses:
- nested pair-list of tag/attrs + value (these map to/from XML)
- tags using the Tk class name
- attributes to control packing, scrollbars, etc.
- and the "+" flag to explicitly indicate a subtree
12.1 Example: layout.gui!!
{Toplevel + -title "Simple Editor"} {
{Text - -id txt -pos * -scroll *} {}
{Frame + -pos _ -subpos l} {
Button Quit
Button Load
{Button - -id save} Save
{Entry - -id status -pos *l} {}
}
}
13. Layout Attributes
- Gui attributes are analogous to HTML attributes.
- the most commonly used are:
- -pos : controls pack positioning (* _ |)
- -id : identifier used for styles and variables
- -scroll : adds scrollbars
- -msg : event message (ie. proc in the script)
- -subpos/-subattr/... : inherited by subtrees
14. Styles
A Gui 'style' uses pattern rules to apply colors, fonts, images, etc, eg.
14.1 Example: styles.gui!!
{Toplevel + -title "Simple Editor"} {
{style} {
Button { -bg DarkKhaki }
.txtwin { -bg Khaki }
}
{Text - -id txtwin -pos * -scroll *} {}
{Frame + -pos _ -subpos l} {
{Button - -id save} Save
Button Quit
}
}
15. Style Patterns
- a style pattern is: Class.id/parentid@group, with parts:
- Class = the widget class (ie. from [winfo class])
- .id = the window name (from a gui -id)
- /parentid = window is a child of parentid
- @group = the group name (from a gui '-gid')
- each part of the pattern can contain glob wildcards:
style {
.txt* {}
Text.fi*@main {}
Label.first*@last* {}
T*.[a-e]*@solo {}
}
16. Style Actions
- style actions are name/value pairs; leading char gives type:
- - : for a Tcl option.
- * : for a Tk DB option starting at window.
- @ : for a macro, eg @tip, @bind, ``@@`` (for gui attributes).
- = : to expand a previous definition.
16.1 Example: actions.gui
{Toplevel +} {
style {
Text { -bg Cyan @tip "See manual" }
.frm { *background SteelBlue }
Button - Text { -font "Verdana 10 italic" }
}
{Frame + -id frm -subpos l -pos *} {
Button Ok Button Cancel
}
Text {}
}
17. Script
- a script tag contains plain Tcl where:
- the first argument to a proc is an object/array "_"
- the use of upvar $_ {} gives access to data elements $(ELEMENT)
- widgets paths are stored in (w,ID)
- widget -*variable are in (v,ID)/(t,ID)
17.1 Example: script.gui
{Toplevel +} {
{Button - -id save} Ok
{Entry - -id status} {}
{script} {
proc Ok {_} {
upvar $_ {}
Button conf $(w,save) -bg Green
set (v,status) "Done..."
}
}
}
18. Main Window
- an application is:
- one or more Toplevel windows each with:
- an initializer proc Main
- a terminator proc Cleanup
- zero or more Menu windows
19. Main Window Example
{Toplevel + -eventmsg Event} {
{Text - -id txtwin} {}
{Button} Go
{script} {
proc Event {_ w} {
upvar $_ {}
Text insert $(w,txtwin) end "Event: [winfo name $w]\n"
}
proc Main {_} {
upvar $_ {}
Text insert $(w,txtwin) end "Starting ..."
}
proc Cleanup {_} {
# Nothing to do.
}
}
}
20. Dialogs
- application popup/dialogs are defined with Toplevel/Menu:
- the -id namespace is shared with the main window
- a Toplevel dialogs may use any id except main
- a Menu dialog id must not match *mainmenu.
- dialogs can be invoked with a style @bind
{Toplevel + -id tlfind} {
Listbox {}
Button Ok
}
{Toplevel +} {
{style} {
.txtwin { @bind { <Control-f> !tlfind } }
}
{Text - -id txtwin} {}
}
21. Gui in a .tcl file
- a Gui can be inlined into a .tcl file with Tk::gui::create
- to keep the Gui in a separate file use: include FILE.gui
package require Gui
namespace eval ::mygapp {
proc Save {_} {
set fn [tk_getSaveFile]
}
proc Main {_} {
upvar $_ {}
set (v,status) Starting...
}
proc Cleanup {_} {
}
Tk::gui::create { include layout.gui }
}
22. Guild
- Guild is a Gui builder that provides:
- a tree-edit oriented Gui builder
- dynamically list available tags/attributes
- supports Tk, Ttk, BLT, Table, TreeCtrl, etc.
- has dialogs for grid, tabset, etc.
- styles and script currently just use an editor
- can be interactively invoked from the window inspector:
23. New Widgets:
BLT widgets:
- Tabset, a notebook widget
- TreeView, a tree-list widget
- blt::tile : label, button, checkbutton, radiobutton
- and blt::tile::scrollbar with marker icon on the slider
}
24. Tabset
Tabset provides:
- symbolic names and tearoff panes
- tabs can be multi-level and/or scrolled
- tab options: slant, side, rotation and shadow
- multiple images per tab, and background tiling
- option to limit length of displayed label
- widget left/right images, eg. New/Close
#!/usr/bin/env wize
script {
proc DoStart {_} { upvar $_ {}; $(w,txt1) insert end "\nDoStart" }
proc DoEnd {_} { upvar $_ {}; $(w,txt1) insert end "\nDoEnd" }
proc Closer {_ w tab} {
# Handle tab deletion.
set win [$w tab cget $tab -window]
destroy $win
$w delete $tab
}
}
style {
Toplevel {
@defimages { myimg configure }
}
Tabset.ts1 {
@@ {
-pos * -slant none -closebut {-msg Closer -prompt 1}
-startimgs {editadd editremove} -endimgs editremove
-startmsg DoStart -endmsg DoEnd -tiers 2 -accelids txt1
}
-image ^myimg
}
Tabset.ts2 { @@ {
-pos * -slant right
} }
Tabset::tab { -underline 0 }
Text { -height 10 @@ {
-pos * } @eval { %W insert end "%I"
}}
}
{Tabset + -id ts1} {
{tab + -label Able} { {Text - -id txt1} {} }
{tab + -label Baker} { Text {} }
{tab + -label Charlie} { Text {} }
{tab + -label Delta} { Text {} }
{tab + -label Echo} { Text {} }
{tab + -label Foxtrot} { Text {} }
{tab + -label Romeo} { Text {} }
{tab + -label Tango} { Text {} }
{tab + -label Zulu} { Text {} }
}
{Tabset + -id ts2 -side bottom} {
{tab + -closebut 1 -label Able} { Text {} }
{tab + -closebut 1 -label Baker} { Text {} }
{tab + -closebut 1 -label Charlie} { Text {} }
{tab + -label Delta} { Text {} }
{tab + -label Echo} { Text {} }
{tab + -label Foxtrot} { Text {} }
{tab + -label Romeo} { Text {} }
{tab + -label Tango} { Text {} }
{tab + -label Zulu} { Text {} }
}
25. TreeView
TreeView provides a tree widget with the power
to handle modern applications:
- auto sized column-width/row-height
- hide/move columns or rows
- sorting and editing support built-in
- styles: automatic and manual
- tags used for marking/grouping
- data stored externally in a tree
26. TreeView Styles
TreeView styles make it easy to enhance appearance by:
- adding colors, fonts, icons and tiled backgrounds
- applying styles to columns, rows, and/or cells
- supports automatic styles: rendering style based on location
- -levelstyles : style depends on depth in tree
- -altrow : even number rows get this style
- can use a priority to override the default ordering
27. TreeView Screenshot
- screenshot demonstrating several capabilities:
- tiled scrollbars with markers
- tiled TreeView rows and columns
- the builtin editing facility and gradient generation
^ tdboptions.gif
28. TreeView Data
- TreeView supports an intuitive notation for data access, eg.
pack [treeview .t -autocreate 1 -width 300] -fill both -expand y
.t column insert end A B
.t insert end "Menu Dinner" -data "A 10 B {x 20 y 30}"
.t entry incr 0->Menu->Dinner A
.t entry set 0->Menu->Dinner B(x) 40
- of particular interest in this example:
- tree-path indexing, eg. 0->Menu->Dinner
- dict sub-elements using array notation, eg. B(x)
29. TreeView and Tree
- TreeView can be configured to use an external tree,
- an external tree can also attach to a TreeView
- this can extend TreeView capabilities to include:
- dump and restore: part or all of a tree.
- a set of tag-iterating commands, and a with statement
- a trace facility: read, write, delete, rename, tag, etc.
- and an sqlite interface
source [file dirname [info script]]/treeview.tcl
set t [tree create]
$t attach [.t cget -tree]
$t insert 0->Menu -label "Breakfast" -data {A 15 B "x 25 y 35"}
$t set 0->Menu->Dinner A 50
$t incr 0->Menu->Breakfast B(x) -1
30. Sqlite Table Editor
- traces can let us implement a simple sqlite table editor:
{Toplevel +} {
{style} {
.tv { -width 600 -height 400 }
TreeView::column.tv { -bd 1 -relief raised }
}
{script} {
proc Add {_} {
upvar $_ {}; $(w,tv) insert end
update idletasks; $(w,tv) entry select end
}
proc Del {_} { upvar $_ {}; $(w,tv) delete focus }
proc Main {_ dbfile table} {
upvar $_ {};
*sqlsync new [db open $dbfile] $table -treeview $(w,tv)
}
}
{TreeView - -id tv -pos * -scroll * -istable 1 -nice 1 } {}
{Frame + -subpos l} { Button Add Button Del}
}
31. Blt Tile Widgets
- blt::tile widgets: label, button, checkbutton, radiobutton, scrollbar.
- they provide new features:
- shaped buttons with complex image tiles
- widget shadow, text shadow and rotatable text.
- rounded frames (eg. by packing in label)
- indicators fully replaceable with 9 icons
- storing variable/textvariable data in a tree instead of variables.
32. Extension DLLs
- Two sharedlib extensions are provided:
33. Wize Applications
Wize now includes the following "test" applications:
- Slider : A presentation program
- Ted : A Tcl aware editor
- Ledger : A finance application
- Guild : A Gui builder
- Gsqlite : An sqlite frontend
- Gradient : A gradient editor
- Tdb : A gdb frontend
34. Tdb
Tdb is a new frontend for an old program (gdb) providing:
- a Stack browser.
- a Variable tree inspector.
- a Types tree inspector.
- Files and Functions tree with searches.
- Memory, Registers, Threads and Disassembly.
- a GDB help tree browser with searches.
- a GDB options tree browse and modify.
- direct access to the GDB interface.
- converts gdb-MI directly to Tcl list
35. Summary
To summarize, wize:
- increases power and reduces complexity
- improves the maintainability of Tcl/Tk
- has introspection available with: <Control-Alt-Shift-2>
- improves cross-platform look and feel in Tk
© 2008 Peter MacDonald