Wize 3.1 Tcl/Tk Conference Chicago 2010 Accelerating Tk Development with Wize 3.1 Peter MacDonald peter@pdqi.com PDQ Intefaces Inc. http://pdqi.com ------------------------------------------- Overview Introduction Introspection Validation Gui Widgets Summary ------------------------------------------- Introduction 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) ------------------------------------------- Introduction Wize 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 ------------------------------------------- Introduction Window Inspector Tk already provides extensive introspection facilities Wize's window inspector simply exposes these can be opened on any window with 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 ------------------------------------------- Introduction Minimal Wize Tk App #!/usr/bin/env wize namespace eval myapp { variable Opts { { -incr 1 "Incr value" -type Int } { -start 2 "Start value" } } variable _ array set _ { a 3 b 4 } proc Main {_} { upvar $_ {} set w $(w,.) pack [Text new $w.txt] -fill both -expand y pack [Entry new $w.inp] -fill x incr (a) $(-start) Text insert $w.txt end "[array get $_]\n" } Tk::create } ------------------------------------------- Validation Validation What is validation? the force-compiling of proc bodies to do checking detects most syntax errors verifies that call parameters match expected number and type reports calls without preceding proc or extern definitions checks for uninitialized array elements, eg. for _ and Declare arrays compiles code object-args, eg. for expr and catch ------------------------------------------- Validation Warnings to validate a program we run it with: wize -Wall myapp.tcl; # or ... ./myapp.tcl -Wall arg1 arg2 ... here is a sample program proc Bad {n} { set a b c set a [Bad] } and the output from wize -Wall bad.tcl:2: warning: too many args, expected parameters {varname {value {}}} for "set a b c" in proc [::Bad] . bad.tcl:3: warning: too few args, expected parameters {n} for "Bad" in proc [::Bad] . ------------------------------------------- Validation 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 } ------------------------------------------- Validation 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 ------------------------------------------- Validation 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)); } } ------------------------------------------- Gui 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. ------------------------------------------- Gui 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 {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} {} } } ------------------------------------------- Gui 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 ------------------------------------------- Gui Styles A Gui style uses pattern rules to apply colors, fonts, images, etc, eg. {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 } } ------------------------------------------- Gui 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 {} } ------------------------------------------- Gui 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. {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 {} } ------------------------------------------- Gui 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) {Toplevel +} { {Button - -id save} Ok {Entry - -id status} {} {script} { proc Ok {_} { upvar $_ {} Button conf $(w,save) -bg Green set (v,status) "Done..." } } } ------------------------------------------- Gui 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 ------------------------------------------- Gui 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. } } } ------------------------------------------- Gui 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 { !tlfind } } } {Text - -id txtwin} {} } ------------------------------------------- Gui 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 } } ------------------------------------------- Gui 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: ------------------------------------------- Widgets 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 ------------------------------------------- Widgets 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 ------------------------------------------- Widgets 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 ------------------------------------------- Widgets 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 ------------------------------------------- Widgets TreeView Screenshot screenshot demonstrating several capabilities: tiled scrollbars with markers tiled TreeView rows and columns the builtin editing facility and gradient generation ------------------------------------------- Widgets 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) ------------------------------------------- Widgets 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 ------------------------------------------- Widgets 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} } ------------------------------------------- Widgets 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. ------------------------------------------- Widgets Extension DLLs Two sharedlib extensions are provided: OpenGl canvas for Tk http://3dcanvas.tcl.tk Snack sound system ------------------------------------------- Apps 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 ------------------------------------------- Apps 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 ------------------------------------------- Summary Summary To summarize, wize: increases power and reduces complexity improves the maintainability of Tcl/Tk has introspection available with: improves cross-platform look and feel in Tk ------------------------------------------- The End -------------------------------------------