Gnocl Cookbook‎ > ‎


Gnocl has a wide range of buttons, choosers and menu functionality but there is not a simple menu button. There is the toolbar menu button but this is a megawidget comprised of two buttons and geared more towards offering a recent choices type pulldown menu enhancement to a basic file open button. A menubar could be used, but this would ruin the style of the layout which, as a button, should look like a button and not a menu label. Working with popups is the best solution here. The gnocl::menuButton command below is simply a wrap around the standard gnocl::button plus the addition a unique option, -menu. The creation and packing of a menu into a popup window is achieved with the menu popup command. The trick but is making sure that the popup behaves like pulldown appearing beneath its parent widget rather than placed under the mouse pointer.

# the next line restarts using tclsh \
exec tclsh "$0" "$@"

if { [catch { package present Gnocl } ] } { package require Gnocl }

## display menuButton menu, adjust positionsing for right-edge/bottom of screen
#/param w button widget-id
#/param d menu widget-id
#/returns none
proc gnocl::mbPopup { w d } {
    lassign [gnocl::winfo geometry $w] x y w h               
    lassign [gnocl::winfo geometry $d] mx my mw mh
    lassign [gnocl::screen geometry] sw sh
    if { [expr $y+$h+$mh] > $sh  } {
        set y [expr $y - $mh]
        puts 1
    } else {
        set y [expr $y + $h]
        puts 2

    if { [expr ($x+$mw) > $sw ] } { set x [expr $sw - $mw] }
    $d popup $x $y


## implement widget commands
#/param args standard series of options for gnocl::button, plus -menu
#/returns menu button widget-id
proc gnocl::menuButton { args } {
    # extract -menu option and discard -onClicked
    array set tmp $args
    set menu $tmp(-menu)
    array unset tmp -menu
    array unset tmp -onClicked
    set res [gnocl::button {*}[array get tmp]]
    $res configure -onClicked "gnocl::mbPopup $res $menu"
    return $res

## Demonstrate menuButton
proc main { args } {

    # create menu
    set ::app(languages) [list {"Sanskrit (D)" sk} {"Sanskrit (I)" sk} {"Pali (I)" pa} {"Pali (D)" pa} {Chinese zh} {"Tibetan (U)" bo} {"Tibetan (W)" bo} ]

    set menu [gnocl::menu -title "menu" -tearoff 0]
    foreach item $::app(languages) {
        $menu add [gnocl::menuCheckItem -text [lindex $item 0] -onToggled {puts "load item 1"}]

    # create menuButton and attach to a window
    gnocl::window -title MB -child [gnocl::menuButton -menu $menu -icon %#Preferences -text "Click Me"] -width 100 -height 100

    # Assinging the same functionality to a toolbar button
    set vBox [gnocl::vBox]
    set tbar [gnocl::toolBar -style icons]

    $vBox add $tbar

    gnocl::window -title MB2 -child $vBox -setSize 0.25
    set but [$tbar add item -icon %#Preferences]

    $but configure -onClicked "gnocl::mbPopup $but $menu"