# ::tko_optionmenu --
#
#   Implementation of ::tko::optionmenu widget.
#
# Copyright (c) 2021 <r.zaumseil@freenet.de>

::tko::widget ::tko::optionmenu ::ttk::menubutton *

#-------------------------------------------------------------------------------

# Command will be called on setting the optionmenu variable.
::oo::define ::tko::optionmenu ::tko_option -command command Command {} {}

#-------------------------------------------------------------------------------

## List of {value label image compound}
::oo::define ::tko::optionmenu ::tko_option -entries entries Entries {} {
    $tko(.).mn delete 0 end

    foreach myList $tko(-entries) {
        lassign $myList myV myL myI myC
        set myArgs [list -variable $tko(-variable) -value $myV];# always
        if {$myI eq {}} {;# only label
            if {$myL eq {}} {set myL $myV}
            lappend myArgs -label $myL
        } else {
            if {$myL eq {}} {;# only image
                lappend myArgs -image $myI
            } elseif {$myC eq {}} {
                lappend myArgs -image $myI -label $myL
            } else {
                lappend myArgs -image $myI -label $myL -compound $myC
            }
        }
        $tko(.).mn add radiobutton {*}$myArgs
    }

    my _trace {} {} {}
}

#-------------------------------------------------------------------------------

# Variable will be keep in sync with selected optionmenu item.
::oo::define ::tko::optionmenu ::tko_option -variable variable Variable {} {
    set myCmd [list [namespace which my] _trace]
    ::trace remove variable [my cget -variable] write $myCmd
    if {$tko(-variable) eq {}} {
        set tko(-variable) ::$tko(.)
    } elseif {[string range $tko(-variable) 0 1] ne {::}} {
        set tko(-variable) ::$tko(-variable)
    }
    if {![info exists $tko(-variable)]} {set $tko(-variable) {}}
    set myNr    [$tko(.).mn index end]
    if {$myNr ne {none}} {
        for {set i 0} {$i < $myNr} {incr i} {
            $tko(.).mn entryconfigure $i -variable $tko(-variable)
        }
    }
    my _trace {} {} {}
    ::trace add variable $tko(-variable) write $myCmd
}

#-------------------------------------------------------------------------------

# Create optionmenu widget.
# args  - ??-option value? ..?
::oo::define ::tko::optionmenu constructor {args} {
    my _tko_constructor $args ::ttk::menubutton
    set tko(-menu) [::menu $tko(.).mn -tearoff 0]
    my _tko_init
    ::oo::objdefine [self] method -menu {} {error readable}
}

# Destroy the widget.
::oo::define ::tko::optionmenu destructor {
    if {$tko(-variable) ne {}} {
        ::trace remove variable $tko(-variable) write\
            [list [namespace which my] _trace]
    }
    unset -nocomplain $tko(.)
    my _tko_destructor
}

#---PRIVATE---------------------------------------------------------------------

# Function used in variable write trace.
# a - Name of variable
# f - Field name of variable
# o - Operation on variable
::oo::define ::tko::optionmenu method _trace {a f o} {
    if {[info exists $tko(-variable)]} {
        set myIndex [lsearch -index 0 $tko(-entries) [set $tko(-variable)]]
        if {$myIndex >= 0} {
            lassign [lindex $tko(-entries) $myIndex] myV myL myI myC
            my configure -text $myL -image $myI
        }
    }
    # only call command when variable is set
    if {$a ne {} && $tko(-command) ne {}} {catch {{*}$tko(-command)}}
}

# vim: set ts=4 sw=4 sts=4 et :
