#!/usr/bin/wish
##
## Ethan Gold <etgold@cs.columbia.edu> 7/2/98
## updated for launcher 0.60 on 2/5/99
## tweaked keybindings 4/8/99
## updated for launcher 0.85 on 5/31/99
##
## this simple script presents a listbox
## from items passed in on the command-line
## and returns an index. It expects a tcl
## list to be passed to it. this is yucky
## if you want to use it for something else.
##

## I don't think ~/ will work in the context in which
## $env(HOME) is used, so we'll try [pwd]
if {![info exists env(HOME)]} {set env(HOME) [pwd]}

set prompt [lindex $argv 0]
set choices [lrange $argv 1 end]

label .label -text "open $prompt with:" -width 35
frame .frame
listbox .frame.listbox -yscrollcommand ".frame.scrolly set" \
	-height 6 -width 30 -exportselection 0 -background white
scrollbar .frame.scrolly -command ".frame.listbox yview" -takefocus 0
button .cancel -text "Cancel" -command {puts -1; exit} -width 8
button .ok -text "OK" -command {chose; exit} -width 8 -default active

set counter 1
foreach choice $choices {
    if {[llength $choice] == 0} {continue}
    .frame.listbox insert end "[string trim $choice \{\}]"
    incr counter
}

.frame.listbox selection set 0

## trivial choosing procedure
proc chose {} {
    puts [.frame.listbox curselection]
}

## listbox bindings
bind .frame.listbox <Key> {
    ## typeahead
    set thekey %A
    if {[regexp {[a-z]|[A-Z]} $thekey]} {
	  set itemcount 0
	  foreach item $choices {
		if {[llength $choice] > 0} {
		    if {[regexp -nocase "^$thekey.*" $item]} {
			  .frame.listbox selection clear 0 end
			  .frame.listbox selection set $itemcount $itemcount
			  .frame.listbox activate $itemcount
			  .frame.listbox see $itemcount
			  break
		    }
		}
		incr itemcount
	  }
	  unset itemcount
    }
}

bind  .frame.listbox <Double-1> {
    chose
    exit
}

bind .frame.listbox <Return> {
    chose
    exit
}

bind .frame.listbox <Control-n> {event generate .frame.listbox <Down>}
bind .frame.listbox <Control-p> {event generate .frame.listbox <Up>}

bind .frame.listbox <Control-v> {.frame.listbox yview scroll 1 page}
bind .frame.listbox <space> {.frame.listbox yview scroll 1 page}
bind .frame.listbox <Meta-v> {.frame.listbox yview scroll -1 page}

bind .cancel <Return> {.cancel invoke}

bind .ok <Return> {.ok invoke}

bind .frame.listbox <Control-c> {exit}
bind .frame.listbox <Escape> {exit}
bind .ok <Control-c> {exit}
bind .cancel <Control-c> {exit}
bind .cancel <Escape> {exit}
bind .ok <Escape> {exit}

## launcher specific binding
bind .frame.listbox <Button-3> {
    if {[info exists env(HOME)]} {
	  catch {exec launcherconfig &}
    }
}

pack .label -side top
pack .frame.listbox -side left -anchor n -fill both -expand 1 
pack .frame.scrolly -side right -anchor n -fill y
pack .frame -side top -expand y -fill both
pack .cancel -side left -anchor s -padx 4 -pady 4
pack .ok -side right -anchor s

focus .frame.listbox
set mouseloc 1
if {$mouseloc} {
    set mx [winfo pointerx .]
    set my [winfo pointery .]
    if {$mx >= 0 && $my >= 0} {
		  set mx [expr $mx - [winfo reqwidth .]]
		  set my [expr $my - 12]
		  ## make sure we don't end up off the screen
		  set scx [winfo screenwidth .]
		  set scy [winfo screenheight .]
		  if {$mx < 0} {
				set mx "+0"
		  } elseif {$mx > [expr $scx - [winfo reqwidth .]]} {
				set mx "-0"
		  } else {set mx "+$mx"}

		  if {$my < 0} {
				set my "+0"
		  } elseif {$my > [expr $scy - [winfo reqheight .]]} {
				set my "-[winfo reqheight .]"
		  } else { set my "+$my"}
		  set location "$mx$my"
    }
}
wm geometry . $location
update

