# widgettab.tcl
#
# Copyright 2001 Digi International (www.digi.com)
#    Jeff Adamczak <jeff_adamczak@digi.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the 
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
# PURPOSE.  See the GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#

## This tool is used to control the tab order of widgets.  It takes 
## a list of widgets as an argument and links them with "Tab" and 
## "Shift-Tab" on the keyboard.
## A virtual event <<ShiftTab>> must be defined by user for platform
## independence. Ex:
## switch -exact -- $tcl_platform(platform) {
##	"unix" {
##		event add <<ShiftTab>> <ISO_Left_Tab> <Shift-Tab>
##	}
##	"windows" {
##		event add <<ShiftTab>> <Shift-Tab>
##	}
## }

package provide Tools 1.0
namespace eval WidgetTab {}

proc WidgetTab::order {lstWidgets} {
	set numWidgets [llength $lstWidgets]
	## Loop will be skipped if only 2 widgets.
	for {set i 1} { $i <= [expr {$numWidgets - 2}]} {incr i} {
		set widgetBefore [lindex $lstWidgets [expr $i - 1]]
		set widgetThis [lindex $lstWidgets $i ]
		if { [llength $lstWidgets] > 2 } {
			set widgetAfter [lindex $lstWidgets [expr $i + 1]]			
		} else {
			set widgetAfter $widgetBefore
		}
		_bindTabs $widgetBefore $widgetThis $widgetAfter				
	}
	## Handle first widget 
	set widgetLast [lindex $lstWidgets end]
	set widgetFirst [lindex $lstWidgets 0]
	set widgetSecond [lindex $lstWidgets 1]
	_bindTabs $widgetLast $widgetFirst $widgetSecond
	
	## Handle last widget
	set widgetSecondToLast [lindex $lstWidgets [expr {$numWidgets - 2}]]
	_bindTabs $widgetSecondToLast $widgetLast $widgetFirst
}

proc WidgetTab::_bindTabs { widgetBefore widgetThis widgetAfter } {
	bind $widgetThis <<ShiftTab>> "focus -force $widgetBefore; break"
	bind $widgetThis <Tab> "focus -force $widgetAfter; break"
}