Version 4 of ToolBar -An Alternative to the BWidget ButtonBox

Updated 2006-06-06 13:54:02

WJG (06/06/06) Ah, 666, the number of the beast or the beastly BWidget ButtonBox? This stalwart member of the BWidget set is useful for making clusters of Buttons but what if you want other items such as everyone's favourite -ComboBox? Mmm, not really. So, here'a an alternative.

 #---------------
 # ToolBar.tcl
 #---------------
 # William J Giddings, 2006
 #---------------
 # Provide a ToolBar megawidget using the BWidget package.
 #
 # This is a hack of the code found at http://wiki.tcl.tk/1916.
 #---------------
 # Notes:
 # -----
 # BWidget has the ButtonBox widget but, this only adds buttons.
 # This method allows **any** other sort of widget to be added,
 # typically a ComboBox or spinbox.
 #----------------

 package require BWidget

 #---------------
 # define the widget
 #---------------
 namespace eval ToolBar {
    Widget::define ToolBar ToolBar

    # include other widgets
    Widget::tkinclude ToolBar frame .f

    Widget::declare ToolBar { }
 }

 #---------------
 # create the thing..
 #---------------
 proc ToolBar::create { path args } {

    # define maps
    array set maps [list ToolBar {} :cmd {} .f {}]
    array set maps [Widget::parseArgs ToolBar $args]

    # map the various args
    Widget::initFromODB ToolBar "$path" $maps(ToolBar)

    # add the container
    set frame [eval frame $path [Widget::subcget $path :cmd] \
     -class ToolBar -relief flat -bd 0 -highlightthickness 0]

    # include other widgets here..
    set fr [eval frame $frame.f $maps(.f)]
    pack $fr -fill both -expand true

    return [Widget::create ToolBar $path]
 }

 #---------------
 # change settings..
 #---------------
 proc ToolBar::configure { path args } {

    set res [Widget::configure $path $args]

    return $res
 }

 #---------------
 # inquire about currents settings..
 #---------------
 proc ToolBar::cget { path option } {
    return [Widget::cget $path $option]
 }

 #---------------
 # add a new widget to the toolbar
 #---------------
 proc ToolBar::add { path class indx args} {

  # add rule
  if {[string tolower $class] == "rule"} {
    frame $path.f.r$indx -width 2 -borderwidth 1 -relief ridge
    pack $path.f.r$indx -side left -anchor nw -fill y -padx 2
    return
  } 

  # add other types of widget
  # create some storage
  set args1 {}  ;# core widget options 
  set args2 {}  ;# anything else, add switches below
  foreach {arg val} $args {
      switch -- $arg {
        -help {
          append args1 "DynamicHelp::add $path.f.$indx -help ballon -text $val"
        }
        default {
          append args2 " $arg \{$val\} "
        }
      }
  }

  # create child widget
  eval "$class $path.f.$indx $args2"
  # do the extra stuff
  eval $args1
  pack $path.f.$indx -side left -padx 2
  return $path.f.$indx
 }

 #---------------
 # the ubiquitous demo
 #---------------
 proc ToolBar::demo {} {

 # create toolbar 1 -FILE
 pack [ToolBar .tb1 ] -side left  -padx 0 -anchor nw

 foreach {i img hlp} {
  1 New "New Document"
  2 Open "Open New File"
  3 Save "Save Work"
  } {
  .tb1 add button b$i \
    -image [Bitmap::get $img] \
    -relief flat -overrelief raised \
    -help abc \
    -command cmd$img
  }

 # create toolbar 2 -EDIT  
 pack [ToolBar .tb2 ] -side left -padx 0 -anchor nw

 .tb2 add Rule 1

 foreach {i img hlp} {
  1 Cut "Cut selection to clipboard"
  2 Copy "Copy selection to clipboard"
  3 Paste "Paste clipboard into selection"
  } {
  .tb2 add button b$i \
    -image [Bitmap::get $img] \
    -relief flat -overrelief raised \
    -help abc \
    -command cmd$img
  }

 # and some BWidget buttons  
 pack [ToolBar .tb3 ] -side left -padx 0 -anchor nw

 .tb3 add Rule 1

 foreach {i img hlp} {
  1 Bold "Embolden Selection"
  2 Overstrike "Overstrike Selection"
  3 Underline "Underline Selection"
  } {
  .tb3 add Button b$i \
    -image [Bitmap::get $img] \
    -relief link \
    -help abc \
    -command cmd$img
  }
 .tb3 add Rule 2

 # and, a combox
 .tb3 add ComboBox cmb1 -values {How Now Brown Cow}
 .tb3 add Rule 3
 .tb3 add checkbutton cb1 -text test
 }

 ToolBar::demo