Saturday, May 31, 2014

Dialog bindings completely re-written.

The legacy code to create a gnocl::dialog has always been problematic. The way the code was originally devised was to build up a set of control buttons using what Gtk libs describe as "activation widgets", that is: custom made widgets added to the bottom row of buttons. Apart from this approach going against the Gnome user interface guidelines, it always results in an application crash. Looking at other dialogs in the library indicates why. The idea is that the dialog 'runs' within its own loop which is only exited when a response button is activated. The dialog either gathers or gives information and then returns to the calling script a response decision obtained the user. Using activation widgets that call the -onResponse signal break this process. If programmers have used the activation widgets for something more complex then those widgets ought to be packed as children into the main body of the dialog.
I've now resolved this problem by completely re-writing the gnocl dialog bindings with the planned redundancy of the existing dialog code on the next incremental release.

The much simplified code has the following options:


Download and compile today's gnocl nightly build to test for yourselves. All comments and feedback most welcome especially regarding applications using glade or builder files.

The following test script shows how complex dialogs and alternative message dialogs can be made.

(In the development release the command gnocl::messageDialog is currently used to access this new  code, this will be changed to gnocl::dialog when the old code is retired.)

# test-dialog.tcl
exec tclsh "$0" "$@"

package require Gnocl

set vbox [gnocl::vBox]
set but1 [gnocl::button -text Dialog1-Chooser -onClicked { dialog1 $win} ]
set but2 [gnocl::button -text Dialog2-Message -onClicked { dialog2 $win} ]

set txt [gnocl::text]

$vbox add $but1
$vbox add $but2
$vbox add $txt -fill {1 1} -expand 1

set win [gnocl::window -child $vbox -setSize 0.25 -onDelete {exit}]

# Test Form-Chooser Dialog.
proc dialog1 {win} {
    set table [gnocl::table -homogeneous 1]

    $table addRow [list [gnocl::button -text "1"] "" [gnocl::button -text "2"]]
    $table addColumn [list [gnocl::button -text "3"] "" [gnocl::button -text "4"]]
    $table add [gnocl::button -text "5"] 1 0 -rowSpan 3
    $table add [gnocl::button -text "6"] 2 1 -columnSpan 2
    set response [gnocl::messageDialog \
        -parent $win \
        -primary HELLO \
        -modal 1 \
        -setSize 0.4 \
        -child $table \
        -title "HOW NOW BROWN COW." ]

    switch $response {
        "#OK" {
            puts "${::apple}. Well, that's alright then!"
        "#CANCEL" {
            puts "Oh, maybe next time then!"
        default {
            puts $response


# Test Message Dialog, with widget and optional graphic.

set apple "Granny Smith"

proc dialog2 {win} {
    # NOTE: variables created/access in global namespace

    set tmp $::apple

    set ent [gnocl::entry -variable tmp -tooltip "Change your mind here."]
    set txt [gnocl::text -wrapMode word]
    $txt lorem

    set im [gnocl::image -image %#Index -stockSize dialog -tooltip "Pointy Finger."]
    # the "-type question" setting will be overidden by "image $im"
    set response [gnocl::messageDialog \
        -resizable 1 \
        -title "CHOOSE!" \
        -buttons ok-cancel \
        -child $txt \
        -type  other \
        -image $im \
        -parent $win \
        -primary "WE RECOMMEND:\n$::apple" \
        -secondary "What do you like?" \
        -backgroundColor #F2F4C0 \
        -tooltip "It's time to decide."]
    switch $response {
        "#OK" {
            set ::apple $::tmp
            puts "${::apple}. Well, that's alright then!"
        "#CANCEL" {
            puts "Oh, maybe next time then!"
        "#DELETE" {
            puts "Dialog delete! How rude!"
    unset ::tmp

No comments: