############################################################################### # # tools.tk - Routines to implement several useful routines # # Copyright 1993 # Bradford W. Mott # November 19,1993 ############################################################################### # $Id: tools.tk,v 1.1 1996/08/02 14:57:12 bwmott Exp $ ############################################################################### ############################################################################### # Simple dialog to get a value from the user ############################################################################### proc Tool:EntryDialog {parent_window label regular_expression} { global ReturnValue global EntryDialogRegExp global EntryDialogParent ## Put application in modal mode set mode [GetApplicationMode] SetApplicationMode ModalMode set EntryDialogRegExp $regular_expression set EntryDialogParent $parent_window ## Just in case destroy the window catch {destroy $EntryDialogParent.entryDialog} ## Create the dialog frame frame $EntryDialogParent.entryDialog -relief raised -borderwidth 3 ## Create the dialog label message $EntryDialogParent.entryDialog.message -text $label \ -width 3i -justify left ## Create Entry field entry $EntryDialogParent.entryDialog.entry -width 20 -relief sunken $EntryDialogParent.entryDialog.entry icursor 0 bind $EntryDialogParent.entryDialog.entry { set ReturnValue [$EntryDialogParent.entryDialog.entry get] if {[regexp $EntryDialogRegExp $ReturnValue]} { destroy $EntryDialogParent.entryDialog } else { bell } } ## Create the OK and Cancel button field frame $parent_window.entryDialog.buttons button $EntryDialogParent.entryDialog.buttons.ok -text "Ok" \ -command { set ReturnValue [$EntryDialogParent.entryDialog.entry get] if {[regexp $EntryDialogRegExp $ReturnValue]} { destroy $EntryDialogParent.entryDialog } else { bell } } button $EntryDialogParent.entryDialog.buttons.cancel -text "Cancel" \ -command {set ReturnValue ""; destroy $EntryDialogParent.entryDialog} pack $EntryDialogParent.entryDialog.buttons.ok -side left -expand 1 \ -fill x -padx 4 pack $EntryDialogParent.entryDialog.buttons.cancel -side right -expand 1 \ -fill x -padx 4 pack $EntryDialogParent.entryDialog.message -side top -fill x -pady 4 -padx 4 pack $EntryDialogParent.entryDialog.entry -side top -fill x -pady 4 -padx 4 pack $EntryDialogParent.entryDialog.buttons -side top -fill x -pady 4 place $EntryDialogParent.entryDialog -relx 0.5 -rely 0.5 -anchor center focus $EntryDialogParent.entryDialog.entry ## Wait for ok or cancel to be pressed tkwait window $EntryDialogParent.entryDialog ## Restore application mode SetApplicationMode $mode return $ReturnValue } ############################################################################### # Ask the user what they what to do about the file that exists? ############################################################################### proc Tool:GetWritingMode {window mode_list} { global Tool set Tool(window) $window ## Put application in modal mode set mode [GetApplicationMode] SetApplicationMode ModalMode ## Just in case destroy the window catch {destroy $Tool(window).writeModeDialog} frame $Tool(window).writeModeDialog -relief raised -borderwidth 3 frame $Tool(window).writeModeDialog.title label $Tool(window).writeModeDialog.title.label -bitmap question \ -relief ridge -height 0.6i -width 0.5i -borderwidth 3 message $Tool(window).writeModeDialog.title.message -text \ "The file you specified already exists! What would you like to do?" \ -width 3i -justify left pack $Tool(window).writeModeDialog.title.label -side left pack $Tool(window).writeModeDialog.title.message -side left pack $Tool(window).writeModeDialog.title -side top -padx 8 -pady 8 ## Create an overwrite button if it's a specified mode if {[lsearch -exact $mode_list "overwrite"] != -1} { button $Tool(window).writeModeDialog.overwrite -text "Overwrite it" \ -command { destroy $Tool(window).writeModeDialog set Tool(return) "overwrite" } pack $Tool(window).writeModeDialog.overwrite -fill x -expand 1 \ -side left -padx 4 -pady 4 } ## Create an append button if it's a specified mode if {[lsearch -exact $mode_list "append"] != -1} { button $Tool(window).writeModeDialog.append -text "Append to it" \ -command { destroy $Tool(window).writeModeDialog set Tool(return) "append" } pack $Tool(window).writeModeDialog.append -fill x -expand 1 \ -side left -padx 4 -pady 4 } button $Tool(window).writeModeDialog.cancel -text "Cancel" \ -command { destroy $Tool(window).writeModeDialog set Tool(return) "" } pack $Tool(window).writeModeDialog.cancel -fill x -expand 1 \ -side left -padx 4 -pady 4 place $Tool(window).writeModeDialog -relx 0.5 -rely 0.5 -anchor center ## Wait for ok to be pressed tkwait window $Tool(window).writeModeDialog ## Restore application mode SetApplicationMode $mode return $Tool(return) } ############################################################################### # Bring up a "child" alert dialog with the given message ############################################################################### proc Tool:AlertDialog {parent_window the_message} { global AlertDialogParent ## Put application in modal mode set mode [GetApplicationMode] SetApplicationMode ModalMode set AlertDialogParent $parent_window ## Just in case destroy the window catch {destroy $AlertDialogParent.alertDialog} frame $AlertDialogParent.alertDialog -relief raised -borderwidth 3 label $AlertDialogParent.alertDialog.label -bitmap warning -relief ridge \ -height 0.6i -width 0.4i -borderwidth 3 message $AlertDialogParent.alertDialog.message -text $the_message \ -width 3i -justify left button $AlertDialogParent.alertDialog.button -text "Ok" \ -command {destroy $AlertDialogParent.alertDialog} pack $AlertDialogParent.alertDialog.label -side left -padx 8 -pady 8 pack $AlertDialogParent.alertDialog.message -side top -padx 4 -pady 8 pack $AlertDialogParent.alertDialog.button -side top -fill x -padx 4 -pady 4 place $AlertDialogParent.alertDialog -relx 0.5 -rely 0.5 -anchor center ## Wait for ok to be pressed tkwait window $AlertDialogParent.alertDialog ## Restore application mode SetApplicationMode $mode } ############################################################################### # Popup a modal open file selector using either the built-in Tcl/Tk selector # or the BtkFileSelector ############################################################################### proc Tool:OpenFileSelector {args} { ## Put the application in modal mode set mode [GetApplicationMode] SetApplicationMode "ModalMode" ## Which file selector should we use? if {[info commands tk_getOpenFile] == ""} { set command "BtkFileSelector $args" } else { set command "tk_getOpenFile $args" } set result [eval $command] ## Reset the application mode SetApplicationMode $mode return $result } ############################################################################### # Popup a modal save file selector using either the built-in Tcl/Tk selector # or the BtkFileSelector ############################################################################### proc Tool:SaveFileSelector {args} { ## Put the application in modal mode set mode [GetApplicationMode] SetApplicationMode "ModalMode" ## Which file selector should we use? if {[info commands tk_getSaveFile] == ""} { set command "BtkFileSelector $args" } else { set command "tk_getSaveFile $args" } set result [eval $command] ## Reset the application mode SetApplicationMode $mode return $result } ############################################################################### ## Animate the specified image in the specified widget ############################################################################### proc Tool:StartAnimation {image width height delay widget} { ## Calculate the number of frames in the animation set number [expr [image width $image] / $width] ## Create an image that we'll use to display a single frame in set single [image create photo -width $width -height $height] ## Copy the first frame of the animation $single copy $image -from 0 0 $width $height ## Place the image in the animation window $widget configure -image $single ## Schedule the next update after $delay Tool:NextAnimationFrame 0 $number $single $image \ $width $height $delay $widget } ############################################################################### ## Called each time a new frame of an animation needs displaying ############################################################################### proc Tool:NextAnimationFrame {current number single image \ width height delay widget} { global AnimateTable ## If the animation window has been destroyed then stop the animation if {[winfo exists $widget] == 0} { image delete $single $image return } ## Calculate next frame to display set next [expr ($current + 1) % $number] $single copy $image -from [expr $next * $width] 0 \ [expr $next * $width + $width] $height ## Schedule another call to handle the next frame after $delay Tool:NextAnimationFrame $next $number $single $image \ $width $height $delay $widget }