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 }