# widgettab.tcl
#
# ****************************************************************************
# Copyright (c) 2001 Digi International Inc., All Rights Reserved
# 
# This software contains proprietary and confidential information of Digi
# International Inc.  By accepting transfer of this copy, Recipient agrees
# to retain this software in confidence, to prevent disclosure to others,
# and to make no use of this software other than that for which it was
# delivered.  This is an unpublished copyrighted work of Digi International
# Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
# prohibited.
# 
# Restricted Rights Legend
#
# Use, duplication, or disclosure by the Government is subject to
# restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
# Technical Data and Computer Software clause at DFARS 252.227-7031 or
# subparagraphs (c)(1) and (2) of the Commercial Computer Software -
# Restricted Rights at 48 CFR 52.227-19, as applicable.
#
# Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
#
# ***************************************************************************

## 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>> "if {[winfo exists $widgetBefore]} {focus -force $widgetBefore; break}"
	bind $widgetThis <Tab> "if {[winfo exists $widgetAfter]} {focus -force $widgetAfter; break}"
}