Using the User Interface code

# Interfacing the Application with the User Interface

## Generated code and naming conventions

All of the code that describes the layout for a user interface panel is contained in a single procedure. If the panel is named `panel`, then the procedure `panel_ui` will be created, and stored in a file called `panel.ui.tcl`.

To instantiate the user interface, the application program needs to `source` the code in `panel.ui.tcl` and call `panel_ui` with a single argument, the name of a frame or toplevel that the panel's widgets will be instantiated in. This frame or toplevel should already be created by the application.

The names of the widget commands are the window path of the container frame plus the `item_name` option for that widget. All of the widgets in a panel are siblings in the Tk widget hierarchy, no matter what grid or sub-grid the widget is placed in for layout purposes. So, for a button with an item name of 'foo', in an interface put into the frame '.bar', the widget name is '.bar.foo'.

The widget command option field is used to call out from the widget to the application code. The special escape sequences: %R, %B, %W, and %M can be used when entering the text for any command option to refer to the fully resolved names of the widgets, even though the frame it is instantiated in may not be known in advance.

## An example application

Suppose we created a sample application, called example that consists of a single button, whose `item_name` is button#1 (the default name), and whose command option is:

            puts "Hello, I'm %W"

. The code generated by SpecTcl will be in `example.ui.tcl` and look like:

    # interface generated by SpecTcl version 1.0 from untitled.ui
    # root is the parent window for this user interface proc untitled_ui {root args}
    {
    # this treats "." as a special case
    if {$root == "."} {
      set base ""
    } else {
      set base $root
    }

    button $base.button#1 \
      -command "puts \
       "Hello, I'm $base.button#1 "" \
        -padx 9 \
        -pady 3 \
        -text hello
    # Geometry management
    grid $base.button#1 -in $root -row 1 -column 1 \
       -sticky {}
    # Resize behavior management
    grid rowconfigure $root 1 -weight 0.0 -minsize 30
    grid rowconfigure $root 2 -weight 0.0 -minsize 30
    grid columnconfigure $root 1 -weight 0.0 -minsize 30
    grid columnconfigure $root 2 -weight 0.0 -minsize 30
    # additional interface code
    # end additional interface code
    }

Notice that the text of the `command` option is grouped with (")'s, which is required to expand the variable `$base` which was part of the substitution for `%W`. In this case, the internal (")'s are appropriately protected.

When SpecTcl tests the application, it will look to see if the file `example.tcl` exists. If the file does not exist, The follow program is written and run:

    tk appname test_example
    wm title . "SpecTcl - example"
    source /home/user/project/example.ui.tcl example_ui .

If `example.tcl` does exist, then SpecTcl will try to run:

    tk appname test_example
    wm title . "SpecTcl - example"
    source /home/user/project/example.ui.tcl
    source /home/user/project/example.tcl

In this case, the code in `example.tcl` needs to instantiate the interface by sourcing `example.ui.tcl` and then calling `example_ui`.