# jcommand.tcl - procedures to manage user-invokable commands
#
###############################################################################
#  Copyright 1992-2001 by Jay Sekora.  This file may be freely distributed,   #
#  modified or unmodified, for any purpose, provided that this copyright      #
#  notice is retained verbatim in all copies and no attempt is made to        #
#  obscure the authorship of this file.  If you distribute any modified       #
#  versions, I ask, but do not require, that you clearly mark any changes     #
#  you make as such and that you provide your users with instructions for     #
#  getting the original sources.                                              #
###############################################################################

package provide aq 0.1

# following has side-effect of making sure ::aq namespace is defined
namespace eval ::aq {
  namespace export {[a-z]*}
  catch {
    package require jldb
    # following likely to fail, because done by other libraries too
    namespace import ::jldb::shortcuts::*
  }
}

######################################################################
# ::aq::command_register cmd ?name? - 
#   register the existence of a command procedure
######################################################################

proc ::aq::command_register { cmd {defaultname {}} } {
  ::aq::debug
  global J_CMDS
  set J_CMDS($cmd) 1
  
  if {[string length $defaultname]} {
    ::jldb::set_defaults [list [list $cmd $defaultname]]
  }
}

######################################################################
# ::aq::command_list - list all currently-registered command procedures
######################################################################

proc ::aq::command_list {} {
  ::aq::debug
  global J_CMDS
  return [array names J_CMDS]
}

######################################################################
# ::aq::command_button b cmd w - create a button to perform a command procedure
######################################################################

proc ::aq::command_button { b w cmd } {
  ::aq::debug
  set text [::jldb::short_text $cmd]
  set width [expr [string length $text] + 1]
  if {$width < 8} {set width 8}
  
  button $b \
    -width $width \
    -text $text \
    -command [list $cmd $w]
  
  return $b
}

######################################################################
# ::aq::command_buttonbar ?options? frame w commands -
#   make a buttonbar packed in frame to execute commands on w
######################################################################

proc ::aq::command_buttonbar {args} {
  ::aq::debug "::aq::command_buttonbar $args"
  ::aq::parse_args {
    {default "(NONE)"}
    {padx -1}
    {pady -1}
    {orient horizontal}
  }
  
  global AQSYSINFO				;# for padx and pady defaults

  if {[llength $args] != 3} {
    error [= misc:badargs {Improper arguments}]
  }
  
  set newframe [lindex $args 0]
  set w [lindex $args 1]
  set commands [lindex $args 2]
  
  if {$orient == "horizontal"} {
    set side right				;# for packing
  } else {
    set side bottom				;# for packing
  }
  
  # if padx or pady was not specified, default to 0 on tiny screens, or
  #   5 on normal screens:
  
  if {$padx < 0} {
    if {$AQSYSINFO(tinyscreen)} {
      set padx 0
    } else {
      set pady 5
    }
  }
  
  if {$pady < 0} {
    if {$AQSYSINFO(tinyscreen)} {
      set pady 0
    } else {
      set pady 5
    }
  }

  frame $newframe
  if {$padx} {
    pack [::aq::filler $newframe -width $padx] -in $newframe -side left
    pack [::aq::filler $newframe -width $padx] -in $newframe -side right
  }
  if {$pady} {
    pack [::aq::filler $newframe -height $pady] -in $newframe -side top
    pack [::aq::filler $newframe -height $pady] -in $newframe -side bottom
  }
  
  foreach cmd $commands {
    set button $newframe.$cmd
    ::aq::command_button $button $w $cmd
    pack $button -in $newframe -side $side
    if {[string match $default $cmd]} {
      $button configure -default active
    } else {
      if {$AQSYSINFO(tinyscreen)} {
        $button configure -default disabled
      } else {
        $button configure -default normal
      }
    }
  }
  return $newframe
}

######################################################################
# ::aq::command_bind - set up bindings for command accelerators
######################################################################

proc ::aq::command_bind { widgets w cmds } {
  ::aq::debug
  foreach cmd $cmds {
    set binding [::jldb::binding $cmd]
    if {"x$binding" != "x"} {
      foreach widget $widgets {
        if {[catch {bind $widget $binding [list $cmd $w]} error]} {
          ::aq::debug "binding of $binding failed: $error"
        }
      }
    }
  }
}
