Skip to main content

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:

-backgroundColor,
-backgroundImage
-buttons,
-child,
-extra,
-image,
-modal,
-parent,
-primary,
-resizeable,
-resizeGrip,
-secondary,
-setSize,
-title,
-tooltip,
-type,

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
#
#!/bin/sh
#\
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
}

Comments

Popular posts from this blog

Simple Runtime Debugging Message Dialog

At times it's useful to see what values variables hold, or offer some pause point before the code goes elsewhere before causing havoc. Its possible to write output to the terminal but this can get lost in copious forms of other outputs, besides, there's no pausing the script execution either. The following proc creates a custom dialog which displays ad message along with the point in the calling script from which it was invoked. ## simple runtime debugging feedback dialog, alternative to console based gnocl::msg # @param msg message to display # @returns none # proc xxx::msg {txt} { set frame [info frame -1] append msg "Message:\n\n" append msg " $txt \n\n\n" append msg "Called from:\n\n" append msg "Proc:\t[lindex [info level -1] 0]\n" append msg "File:\t[file tail [dict get $frame file]]\n" append msg "Line:\t[dict get $frame line]\n" gnocl::dialog \ -type info \ -text $msg

Creating a button box with right aligned widgets

The dialog widget has its own internal functionaluty to create and position buttons at the bottom right corner of the window container. When creating these for ourselves it must be born in mind that default settings for fill and expand are both 0.5. Failing to set these will always place the child objects in the centre, regardless of alignment. For most cases these defaults are acceptable but, to create that dialog-button arrangement, use the following snippet as a model!   # to right align completely, set expand and fill to 0 set hbox [gnocl::hBox] set b1 [gnocl::button -text Select \                -data $lst                 -onClicked { puts DO-SOMETHING-WITH-%d} ] set b2 [gnocl::button -text Cancel -onClicked { puts DONE! } ] $vbox add $hbox -expand 0 -fill 0 -align right $hbox add $b1 $hbox add $b2

Changing Namespaces

I've been toying with the idea of changing the namespace used by gnocl, to something simplier, a proposition much more appealing now that I've begun migration to Gtk3 and soon to Gtk4. The changes from Gtk2 to Gtk4 will be subtantial due to many chages occuring within the Gtk api. Before committing myself, I thought how it would be useful to swap namespaces on the fly. So, here's a first quick solution:   package require -exact Gnocl 0.9.96 proc xxxx {ns1 ns2}  {     namespace eval ::${ns2} {}     set map [list $ns1 $ns2]          foreach type {commands vars procs } {         foreach item [info $type ${ns1}::*] {             set err ""             catch { rename $item [string map $map $item] } err             if { $err != "" } { puts $err }         }     }          namespace delete $ns1 } xxxx g set b1 [g::button -text BUTTON] set w1 [g::window -child $b1] set l1 [g::label -text rename] $w1 configure -child $l1 -title TEST