bindings
TCL/TK UseCase4
Abstract : Houses all the event action procedures.
Comments : For Use Case 4 we have switch from having Tcl/Tk track objects
(which was done through label name) to have C++ track them
with a unique ID number passed to Tcl/Tk. This will allow for
better tracking and object manipulation. In files edge.tcl,
vertex.tcl, and bindings.tcl, most any referrence to the
varible "name" or "$name" is actually the ID number.
###
# This file contains the actions to be taken on bound
# events in the canvas.
#
# : Event procedures are based on the tool
# : name. Special checks are done to see if
# : there is a procedure for the action that
# : happened and the tool that made the action.
# : If the procedure exists, it does it. If it doesn't,
# : it doesn't.
###
#Make sure the correct action is taken depending on the tool currently selected
###
proc conditionalCall { procName name x y } {
if {[info procs $procName] != ""} {
$procName $name $x $y
}
}
###
#calls conditionalCall after a bendy point is clicked on with the left mouse
#button and the mouse is moved while the button is still held down.
###
proc onOvalMove { name x y } {
global tool_type
conditionalCall onOvalMove_$tool_type $name $x $y
}
###
#action taken when using the select tool and the left mouse button is clicked
#on a bendy point and the mouse is moved.
#So long as the button is held down, this just moves the bubble around the
#screen. The actual redrawing of the edge and recomputation of positions is
#done on the release of the button.
###
proc onOvalMove_Select { name x y } {
global can
set itemID [$can find withtag current]
if {$itemID == ""} {
return
}
set crds [calcOval $x $y]
$can coords $itemID [lindex $crds 0] [lindex $crds 1] \
[lindex $crds 2] [lindex $crds 3]
}
###
#Calls conditionalCall when the left button is double clicked while on an edge.
###
proc onEdgeLineDbl { name x y } {
global tool_type
conditionalCall onEdgeLineDbl_$tool_type $name $x $y
}
###
#Called when on an edge and the left button is double clicked while using the
#select tool. It creates a new bendy point
###
proc onEdgeLineDbl_Select { name x y } {
global can
#
# Don't allow bends to be added for same start/end vertex edges.
if {[getEdgeSrcVert $name] == [getEdgeDstVert $name]} {
ask "You're lucky even to have an edge that can \
start and end from the same vertex. You won't be able to \
delete additional bends once they are created, so please only move them."
return
}
set itemID [$can find withtag current]
set index [getEdgeItemIndex [getEdgeLineIDs $name] $itemID]
# If edge is an Alter, divide the number of items in the list
# by 2 because each pair of lines counts as 2 items.
if {[getEdgeType $name] == "Alter"} {
set index [expr (($index / 2)) ]
}
set Coords [getEdgeNodeCoords $name]
set Coords [linsert $Coords $index "$x $y"]
setEdgeNodeCoords $name $Coords
createEdge $name
}
###
#Calls conditionalCall when the left mouse button is released while on a bendy
#point
###
proc onEdgeOvalUp { name x y } {
global tool_type
conditionalCall onEdgeOvalUp_$tool_type $name $x $y
}
###
#When the left mouse button is released while on a bendy point and using the
#select tool. This redraws the edge and bendy point in the new position and
#recomputes the positions.
###
proc onEdgeOvalUp_Select { name x y } {
global can
# puts "onEdgeOvalUp $name $x $y"
set itemID [$can find withtag current]
if {$itemID == ""} {
return
}
set Ovals [getEdgeOvalIDs $name]
set Coords [getEdgeNodeCoords $name]
set index [lindex [lindex $Ovals [findListEntry $Ovals $itemID]] 1]
incr index -1
set Coords [lreplace $Coords $index $index "$x $y"]
setEdgeNodeCoords $name $Coords
createEdge $name
}
###
#This calls conditionalCall when on a bendy point and the RIGHT mouse button
#is double clicked.
###
proc onEdgeOvalDbl { name x y } {
global tool_type
conditionalCall onEdgeOvalDbl_$tool_type $name $x $y
}
###
#When on a bendy point and the right mouse button is double clicked while using
#the select tool. The bendy point you are currently on is removed.
###
proc onEdgeOvalDbl_Select { name x y } {
global can
#
# Don't allow bends to be removed for same start/end vertex edges.
if {[getEdgeSrcVert $name] == [getEdgeDstVert $name]} {
ask "You're lucky even to have an edge that can \
start and end from the same vertex. Only move the bends please. \
What if you delete them all?"
return
}
set itemID [$can find withtag current]
if {$itemID == ""} {
return
}
set Ovals [getEdgeOvalIDs $name]
set Coords [getEdgeNodeCoords $name]
set index [lindex [lindex $Ovals [findListEntry $Ovals $itemID]] 1]
incr index -1
set Coords [lreplace $Coords $index $index ]
setEdgeNodeCoords $name $Coords
createEdge $name
}
###
#Calls conditionalCall after an edge label has been clicked on and the mouse
#has been moved.
###
proc onEdgeLblMove { name x y } {
global tool_type
conditionalCall onEdgeLblMove_$tool_type $name $x $y
}
###
#When an edge label has been clicked on and the mouse moved while the select
#tool is being used. It moves the
#edge along on the screen and updates the coordinates
###
proc onEdgeLblMove_Select { name x y } {
global can
set id [getEdgeLabelID $name]
set coords [edgeCalcMidpoint $name]
set offX [expr $x - [getXCoord $coords]]
set offY [expr $y - [getYCoord $coords]]
setEdgeLabelOff $name "$offX $offY"
$can coords $id $x $y
}
###
#Calls conditionalCall when the left mouse button is released while on an edge
###
proc onEdgeUp { name x y } {
global tool_type
conditionalCall onEdgeUp_$tool_type $name $x $y
}
###
#When using the delete tool, and the left mouse button is released while on
#an edge. This deletes the edge and updates the appropriate variables.
###
proc onEdgeUp_Delete { name x y } {
global iGraph flagno
yesno "You are about to delete this edge. Do you wish to continue?"\
$x $y
if {$flagno == 1} {
if {[getEdgeType $name] == "Constr"} {
clearDocument
# puts "Sending: $name"
$iGraph cppDelCEdge: [fixID $name]
} else {
# puts "Sending: $name"
clearDocument
$iGraph cppDelAEdge: [fixID $name]
}
}
}
###
#When using the Rename tool, and the left mouse button is released while on
#an edge. This prompts the user for a name and renames the edge.
###
proc onEdgeUp_Rename { name x y } {
global iGraph
if {[getEdgeType $name] != "Constr"} {
return
}
set newName [asklabel "Enter new label:" $x $y]
if {($newName != "") && ([checkElabel [getEdgeSrcVert $name] $newName]\
== 1)} {
clearDocument
# puts "Sending: $name $newName"
$iGraph cppRenEdge: [fixID $name] $newName
}
}
###
#calls conditionalCall when the left mouse button is clicked down on a vertex.
###
proc onVertDown { name x y } {
global tool_type
conditionalCall onVertDown_$tool_type $name $x $y
}
###
#When the left mouse button is clicked down on a vertex and the tool selected
#is the construction edge tool. This hilights the edge.
###
proc onVertDown_Req_Constr_Edge { name x y } {
vertHilite $name yellow
}
###
#when the left mouse button is clicked down on a vertex and the tool selected
#is the alternation edge tool. If the vertex type is not of alternation then
#this simply returns without doing anything. If it is of type vertex then the
#vertex is highlighted.
###
proc onVertDown_Req_Alter_Edge { name x y } {
if {[getVertexType $name] != "Alter"} {
return
}
vertHilite $name yellow
}
###
#Calls conditionalCall after a vertex has been clicked on with the left mouse
#button and the mouse has been moved.
###
proc onVertMove { name x y } {
global tool_type
conditionalCall onVertMove_$tool_type $name $x $y
}
###
#When a vertex has been clicked on and the mouse moved with the select tool
#enabled. This calls
#moveVertex to do the move the vertex around the screen.
###
proc onVertMove_Select { name x y } {
moveVertex $name "$x $y"
}
###
#Used when the mouse has been moved after a construction edge is clicked on
#with the left mouse button, so long as the tool selected is the construction
#edge tool. This keeps the original vertex clicked on highlighted and
#highlights the next closest vertex. . . so long as it is within certain
#boundaries. These boundaries are defined by TCL.
###
proc onVertMove_Req_Constr_Edge { name x y } {
global can lastHilited
set itemID [$can find closest $x $y]
set tags [$can gettags $itemID]
set dstName [lindex $tags 0]
if {($dstName != $lastHilited) && ($lastHilited != $name)} {
vertUnhilite $lastHilited
}
if {($dstName == "") || \
([lsearch $tags _vertex_] == -1)} {
return
}
vertHilite $dstName yellow
}
###
#Used when the mouse has been moved after an alternation edge is clicked on
#with the left mouse button, so long as the tool selected is the construction
#edge tool. If the vertex is not an alternation edge this procedure simple
#exits. If it is an alternation edge onVertMove_Req_Constr_Edge is called.
###
proc onVertMove_Req_Alter_Edge { name x y } {
if {[getVertexType $name] != "Alter"} {
return
}
onVertMove_Req_Constr_Edge $name $x $y
}
###
#Calls conditionalCall when the left mouse button is released while on a
#vertex
###
proc onVertUp { name x y } {
global tool_type
conditionalCall onVertUp_$tool_type $name $x $y
}
###
#If the left mouse button is released while on a vertex and the select tool
#is enabled, the command vertRedrawEdges is called to redraw the edges.
###
proc onVertUp_Select { name x y } {
vertRedrawEdges $name
}
###
#If the left mouse button is released while on a vertex and the delete tool
#is enabled, the vertex is deleted after confirmation from the user.
###
proc onVertUp_Delete { name x y } {
global flagno iGraph
yesno "You are about to delete this vertex and any connecting \
edges. Do you wish to continue?" $x $y
if {$flagno == 1} {
clearDocument
# puts "Passing: $name"
$iGraph cppDelVertex: [fixID $name]
}
}
###
#If the left mouse button is released while on a vertex and the rename tool
#is enabled, a new vertex name is requested from the user and the change is
#implemented
###
proc onVertUp_Rename { name x y } {
global iGraph
set newName [asklabel "Enter new label:" $x $y]
if {($newName != "") && ([checkVlabel $newName] == 1)} {
clearDocument
# puts "Passing: $name $newName"
$iGraph cppRenVertex: [fixID $name] $newName
}
}
###
#If the left mouse button is released while near a vertex
#(see onVertMove_Req_c#onstr_Edge) and the construction
#edge tool is enabled, a construction edge is placed between the initial node
#clicked and the other node highlighted. Due to lack of thought from the
#group leader (zaphod), an edge cannot be placed from a vertex and back to
#itself. This will be fixed in later versions.
###
# Hey, I can't think of everything................Zaphod :^)
# Just fixed it. Ha.
###
proc onVertUp_Req_Constr_Edge { name x y } {
global constrSrcName constrDstName can inform flagno iGraph
set itemID [$can find closest $x $y]
set tags [$can gettags $itemID]
set dstName [lindex $tags 0]
if {($dstName == "") || ([lsearch $tags _vertex_] == -1)} {
vertUnhilite $name
return
}
if {([$iGraph cppCheckCEdge: [fixID $name] ] != 1)} {
vertUnhilite $name
vertUnhilite $dstName
return
}
#
# Should the user make an edge start and end at the same vertex.
if {($name == $dstName)} {
yesno "This edge will start and end on the same\
vertex. Do you wish to continue?" $x $y
if {$flagno == 1} {
set edgeName [asklabel "Enter label name:" $x $y]
if {($edgeName != "") && ([checkElabel $name $edgeName] == 1)} {
set default1 "30 30"
set points [getVertexCoords $dstName]
set node1 "[expr [getXCoord $points] + 0] [expr [getYCoord $points] + 20]"
set node2 "[expr [getXCoord $points] + 20] [expr [getYCoord $points] + 20]"
set node3 "[expr [getXCoord $points] + 20] [expr [getYCoord $points] + 0]"
set default2 "{$node1} {$node2} {$node3}"
set inform 1
tclCEdge fakeid $edgeName $name $dstName $default1 $default2
# setEdgeNodeCoords $name $default2
set inform 0
}
}
vertUnhilite $name
return
}
set edgeName [asklabel "Enter label name:" $x $y]
if {($edgeName != "") && ([checkElabel $name $edgeName] == 1)} {
set inform 1
tclCEdge fakeid $edgeName $name $dstName
set inform 0
}
vertUnhilite $name
vertUnhilite $dstName
}
###
#If the left mouse button is released while near a vertex (see OnVertMove_Req_c#onstr_Edge)
#and the alternation edge tool is enabled, an alternation edge is
#placed between the initial node clicked and the other node highlighted. Once
#again, due
#to lack of thought by the group leader (zaphod the incompetent), an edge
#cannot be placed from a vertex to itself. this will be fixed in a
#later version.
###
# Next time you write it Allanon....................Zaphod:^)
###
proc onVertUp_Req_Alter_Edge { name x y } {
#Removed vertex checking. Prop-Group wants this control.
# if {[getVertexType $name] != "Alter"} {
# return
# }
global can inform flagno iGraph
set itemID [$can find closest $x $y]
set tags [$can gettags $itemID]
set dstName [lindex $tags 0]
if {($dstName == "") || ([lsearch $tags _vertex_] == -1) ||\
($name == $dstName)} {
vertUnhilite $name
return
}
if {([$iGraph cppCheckAEdge: [fixID $name] ] != 1)} {
# Circular Inheridance checking not ready yet.
# || ([$iGraph cppCheckCircInher: [fixID $name] [fixID $dstName]] != 1)
vertUnhilite $name
vertUnhilite $dstName
return
}
set inform 1
tclAEdge fakeid $name $dstName
set inform 0
vertUnhilite $name
vertUnhilite $dstName
}
###
#Calls conditionalCall when a vertex label has been clicked on with the left
#mouse button, and the mouse has been subsequently moved.
###
proc onVertLblMove { name x y } {
global tool_type
conditionalCall onVertLblMove_$tool_type $name $x $y
}
###
#When a vertex label has been clicked on with the left mouse button, and the
#mouse has been subsequently moved, so long as the tool enabled is Select.
#This simply moves the label around.
###
proc onVertLblMove_Select { name x y } {
set id [getVertexLabelID $name]
set coords [getVertexCoords $name]
set offX [expr $x - [getXCoord $coords]]
set offY [expr $y - [getYCoord $coords]]
moveVertexLabel $name "$offX $offY"
}
###
#When the mouse cursor enters the area of a vertex, conditionalCall is called.
###
proc onVertEnter { name x y } {
global tool_type
#puts "That is object: $name"
conditionalCall onVertEnter_$tool_type $name $x $y
}
###
#when the mouse cursor enters the area of a vertex and the tool enabled is
#Select, the vertex is highlighted green.
###
proc onVertEnter_Select { name x y } {
vertHilite $name green
}
###
#When the mouse cursor enters the area of a vertex and the tool enabled is
#the alternation edge tool, the vertex is highlighted yellow.
###
proc onVertEnter_Req_Alter_Edge { name x y } {
if {[getVertexType $name] == "Alter"} {
vertHilite $name yellow
}
}
###
#When the mouse cursor enters the area of a vertex and the tool enabled is
#the delete tool, the vertex is highlighted red
###
proc onVertEnter_Delete { name x y } {
vertHilite $name red
}
###
#when the mouse cursor enters the area of a vertex and the tool enabled is
#the rename tool, the vertex is highlighted purple.
###
proc onVertEnter_Rename { name x y } {
vertHilite $name purple
}
###
#When the mouse cursor leaves the area of a vertex, conditionalCall is called.
###
proc onVertLeave { name x y } {
global tool_type
conditionalCall onVertLeave_$tool_type $name $x $y
}
###
#When the mouse cursor leaves the area of a vertex and the tool enabled is
#the delete tool, the vertex is unhighlighted. The reason zaphod calls
#onVertLeave_Select to do this instead of vertUnhilite is a mystery. The only
#answer he could give is that, THEY told him to do it this way. Asked who
#they were, he would grow fearful and run from the room screaming of little
#pink mushrooms.
###
# When the men come, or when in my mind the men come in their six
# black shiny ships, do they come in your mind too?............Zaphod:^)
###
proc onVertLeave_Delete { name x y } {
onVertLeave_Select $name $x $y
}
###
#When the mouse cursor leaves the area of a vertex and the tool enabled is
#the select tool, the vertex is unhighlighted.
###
proc onVertLeave_Select { name x y } {
vertUnhilite $name
}
###
#When the mouse cursor leaves the area of a vertex and the tool enabled is
#the rename tool, the vertex is unhighlighted.
###
proc onVertLeave_Rename { name x y } {
vertUnhilite $name
}
###
#When the mouse cursor leaves the area of a vertex and the tool enabled is
#the alternation edge tool, the vertex is unhighlighted
###
proc onVertLeave_Req_Alter_Edge { name x y } {
vertUnhilite $name
}
###
#conditionalCall is called when the mouse cursor enters an edge area.
###
proc onEdgeEnter { name x y } {
global tool_type
conditionalCall onEdgeEnter_$tool_type $name $x $y
}
###
#when the mouse cursor is placed on an edge and the tool enabled is the select
#tool, the edge is colored blue
###
proc onEdgeEnter_Select { name x y } {
global can
$can itemconfigure $name -fill blue
}
###
#when the mouse cursor is placed on an edge and the tool enabled is the delete
#tool, the edge is colored red
###
proc onEdgeEnter_Delete { name x y } {
global can
$can itemconfigure $name -fill red
}
###
#when the mouse cursor is placed on an edge and the tool enabled is the rename
#tool, the edge is colored purple if it is a construction edge, if not it just
#returns
###
proc onEdgeEnter_Rename { name x y } {
if {[getEdgeType $name] != "Constr"} {
return
}
global can
$can itemconfigure $name -fill purple
}
###
#when the mouse cursor moves off an edge, conditionalCall is called.
###
proc onEdgeLeave { name x y } {
global tool_type
conditionalCall onEdgeLeave_$tool_type $name $x $y
}
###
#when the mouse cursor moves off an edge and the tool enabled is the select
#tool, the edge is colored back to black
###
proc onEdgeLeave_Select { name x y } {
global can
$can itemconfigure $name -fill black
}
###
#when the mouse cursor moves off an edge and the tool enabled is the delete
#tool, the edge is colored back to black
###
proc onEdgeLeave_Delete { name x y } {
global can
$can itemconfigure $name -fill black
}
###
#when the mouse cursor moves off an edge and the tool enabled is the rename
#tool, the edge is colored back to black
###
proc onEdgeLeave_Rename { name x y } {
global can
$can itemconfigure $name -fill black
}
###
#When the left mouse button is pressed down on the canvas, a construction
#vertex is
#created. This is a special procedure that is not called through
#conditionalCall. fakeid is a dummy ID until C++ assigns it one.
###
proc onBtn1Down_Canvas_Constr {x y} {
global inform
set name [asklabel "Enter label name:" $x $y]
if {( $name != "" ) && ( [checkVlabel $name] == 1 )} {
set inform 1
tclCVert fakeid $name "$x $y"
set inform 0
}
}
###
#When the left mouse button is pressed down on the canvas, an alternation
#vertex is
#created. This is a special procedure that is not called through
#conditionalCall. fakeid is a dummy ID until C++ assigns it one.
###
proc onBtn1Down_Canvas_Alter {x y} {
global inform
set name [asklabel "Enter label name:" $x $y]
if {($name != "") && ([checkVlabel $name] == 1)} {
set inform 1
tclAVert fakeid $name "$x $y"
set inform 0
}
}
###
#this function is not used
###
# I hate when I do that..........Zaphod:^)
###
proc onBtn1Up_Node_Req_Constr_Edge { x y } {
global name
global NodesToNames
global saveConstrSrcName
if {$saveConstrSrcName == ""} {
return
}
set itemID [.area find closest $x $y]
if {[lsearch [.area gettags $itemID] node] == -1} {
return
}
set nodeName $NodesToNames($itemID)
if {$saveConstrSrcName == $nodeName} {
return
}
asklabel "Enter label name:"
if {$name != ""} {
tclCEdge $name $saveConstrSrcName $nodeName
}
unhiliteNodes
}