mirror of
https://github.com/supleed2/ELEC60015-HLP-CW.git
synced 2024-11-10 02:05:48 +00:00
Documentation
Original Commit by inigo-selwood
This commit is contained in:
parent
c43910e438
commit
464c09a7dc
|
@ -334,21 +334,38 @@ let RISegsToVertices (segList: RISeg list) =
|
||||||
|> List.scan getRISegEnd segList[0].Start
|
|> List.scan getRISegEnd segList[0].Start
|
||||||
|> List.map (fun pos -> pos.X, pos.Y)
|
|> List.map (fun pos -> pos.X, pos.Y)
|
||||||
|
|
||||||
/// Get initial list of wire vertices given port locations corresponding to the enpoints of a wire
|
/// Get initial list of wire vertices given port locations corresponding to the
|
||||||
let initialWireVerticesFromPorts (startPort:XYPos) (endPort:XYPos) (routetype:routeType) =
|
/// enpoints of a wire
|
||||||
let startX, startY, endX, endY = startPort.X, startPort.Y, endPort.X, endPort.Y
|
let initialWireVerticesFromPorts
|
||||||
|
(startPort: XYPos)
|
||||||
|
(endPort: XYPos)
|
||||||
|
(routetype: routeType): (list<XYPos> * bool) =
|
||||||
|
|
||||||
match routetype with
|
let startX, startY, endX, endY =
|
||||||
| Oppositeside ->
|
startPort.X, startPort.Y, endPort.X, endPort.Y
|
||||||
// adjust length of segments 0 and 6 - the sticks - so that when two ports are aligned and close you still get left-to-right routing.
|
|
||||||
|
// Oppositeside -> the two ports face one another
|
||||||
|
if routetype = Oppositeside then
|
||||||
|
|
||||||
|
// Adjust length of segments 0 and 6 - the sticks - so that when two
|
||||||
|
// ports are aligned and close, you still get left-to-right routing
|
||||||
let stickLength =
|
let stickLength =
|
||||||
if (endX - startX > 0.0) then
|
if (endX - startX > 0.0) then
|
||||||
let d = List.max [ abs (startX - endX) ; abs (startY - endY) ; Wire.stickLength / 4.0 ]
|
[
|
||||||
min d (Wire.stickLength / 2.0)
|
abs (startX - endX)
|
||||||
|
abs (startY - endY)
|
||||||
|
Wire.stickLength / 4.0
|
||||||
|
]
|
||||||
|
|> List.max
|
||||||
|
|> min (Wire.stickLength / 2.0)
|
||||||
else
|
else
|
||||||
Wire.stickLength / 2.0
|
Wire.stickLength / 2.0
|
||||||
|
|
||||||
|
// Wire travelling left to right (positive X) from output port to input
|
||||||
|
// port
|
||||||
|
// S - + - + - + - E
|
||||||
if endX - startX >= stickLength * 2.0 then
|
if endX - startX >= stickLength * 2.0 then
|
||||||
[ // Wire travelling left to right (positive X) from output port to input port
|
[
|
||||||
{X = startX; Y = startY}
|
{X = startX; Y = startY}
|
||||||
{X = startX + stickLength; Y = startY};
|
{X = startX + stickLength; Y = startY};
|
||||||
{X = startX + stickLength; Y = startY} ;
|
{X = startX + stickLength; Y = startY} ;
|
||||||
|
@ -357,87 +374,165 @@ let initialWireVerticesFromPorts (startPort:XYPos) (endPort:XYPos) (routetype:ro
|
||||||
{X = endX - stickLength; Y = endY}
|
{X = endX - stickLength; Y = endY}
|
||||||
{X = endX - stickLength; Y = endY}
|
{X = endX - stickLength; Y = endY}
|
||||||
{X = endX; Y = endY}
|
{X = endX; Y = endY}
|
||||||
], true // left to right
|
],
|
||||||
|
true // left to right
|
||||||
|
|
||||||
|
// Wire travelling right to left (negative X), but ports are (almost)
|
||||||
|
// aligned vertically An offset is added to the main horizontal segment
|
||||||
|
// so it can be seen / dragged more easily
|
||||||
|
//
|
||||||
|
// E - + - + + - + - S
|
||||||
|
// | |
|
||||||
|
// + - +
|
||||||
elif abs (startY - endY) < 4.0 then
|
elif abs (startY - endY) < 4.0 then
|
||||||
[ // Wire travelling right to left (negative X), but ports are (almost) aligned vertically
|
[
|
||||||
// An offset is added to the main horizontal segment so it can be seen / dragged more easily
|
|
||||||
{X = startX; Y = startY}
|
{X = startX; Y = startY}
|
||||||
{X = startX+Wire.stickLength; Y = startY}
|
{X = startX + Wire.stickLength; Y = startY}
|
||||||
{X = startX+Wire.stickLength; Y = startY}
|
{X = startX + Wire.stickLength; Y = startY}
|
||||||
{X = startX+Wire.stickLength; Y = startY + Wire.stickLength}
|
{X = startX + Wire.stickLength; Y = startY + Wire.stickLength}
|
||||||
{X = endX-Wire.stickLength; Y = startY + Wire.stickLength}
|
{X = endX - Wire.stickLength; Y = startY + Wire.stickLength}
|
||||||
{X = endX-Wire.stickLength; Y = endY}
|
{X = endX - Wire.stickLength; Y = endY}
|
||||||
{X = endX-Wire.stickLength; Y = endY}
|
{X = endX - Wire.stickLength; Y = endY}
|
||||||
{X = endX; Y = endY}
|
{X = endX; Y = endY}
|
||||||
], false // not left to right
|
],
|
||||||
|
false // not left to right
|
||||||
|
|
||||||
|
// Wire travelling right to left (negative X), bending back on itself
|
||||||
|
//
|
||||||
|
// + - + - S
|
||||||
|
// |
|
||||||
|
// E - + - +
|
||||||
else
|
else
|
||||||
[ // Wire travelling right to left (negative X), bending back on itself
|
[
|
||||||
{X = startX; Y = startY}
|
{X = startX; Y = startY}
|
||||||
{X = startX+Wire.stickLength; Y = startY}
|
{X = startX + Wire.stickLength; Y = startY}
|
||||||
{X = startX+Wire.stickLength; Y = startY}
|
{X = startX + Wire.stickLength; Y = startY}
|
||||||
{X = startX+Wire.stickLength; Y = (startY+endY)/2.0}
|
{X = startX + Wire.stickLength; Y = (startY + endY) / 2.0}
|
||||||
{X = endX-Wire.stickLength; Y = (startY+endY)/2.0}
|
{X = endX - Wire.stickLength; Y = (startY + endY) / 2.0}
|
||||||
{X = endX-Wire.stickLength; Y = endY}
|
{X = endX - Wire.stickLength; Y = endY}
|
||||||
{X = endX-Wire.stickLength; Y = endY}
|
{X = endX - Wire.stickLength; Y = endY}
|
||||||
{X = endX; Y = endY}
|
{X = endX; Y = endY}
|
||||||
], false // not left to right
|
],
|
||||||
|Rightangle ->
|
false // not left to right
|
||||||
if (abs(endX-startX) >= Wire.stickLength) && (abs(endY-startY)>=Wire.stickLength) then
|
|
||||||
|
// Rightangle -> there's a 90 degree angle between the two ports
|
||||||
|
elif routetype = Rightangle then
|
||||||
|
|
||||||
|
// If the angle is a longer than the stick length, add a kink to the
|
||||||
|
// wire which will space it out more evenly
|
||||||
|
//
|
||||||
|
// S - + - +
|
||||||
|
// |
|
||||||
|
// +
|
||||||
|
// |
|
||||||
|
// E
|
||||||
|
if (endX - startX >= Wire.stickLength)
|
||||||
|
&& (endY - startY >= Wire.stickLength) then
|
||||||
|
|
||||||
[
|
[
|
||||||
{X = startX; Y = startY};
|
{X = startX; Y = startY};
|
||||||
{X = startX + Wire.stickLength; Y = startY};
|
{X = startX + Wire.stickLength; Y = startY};
|
||||||
{X = startX + Wire.stickLength; Y = startY};
|
{X = startX + Wire.stickLength; Y = startY};
|
||||||
{X = endX; Y = startY};
|
{X = endX; Y = startY};
|
||||||
{X = endX; Y = startY};
|
{X = endX; Y = startY};
|
||||||
{X = endX ; Y = endY-Wire.stickLength}
|
{X = endX ; Y = endY - Wire.stickLength}
|
||||||
{X = endX ; Y = endY-Wire.stickLength}
|
{X = endX ; Y = endY - Wire.stickLength}
|
||||||
{X = endX; Y = endY}
|
{X = endX; Y = endY}
|
||||||
], true
|
],
|
||||||
|
true // Left-to-right
|
||||||
|
|
||||||
|
// Otherwise, if either X or Y delta is smaller than the stick length,
|
||||||
|
// add some creative meandering
|
||||||
|
//
|
||||||
|
// + ---- +
|
||||||
|
// | |
|
||||||
|
// | + - S
|
||||||
|
// + - +
|
||||||
|
// |
|
||||||
|
// E
|
||||||
else
|
else
|
||||||
[
|
[
|
||||||
{X = startX; Y = startY};
|
{X = startX; Y = startY};
|
||||||
{X = startX + Wire.stickLength; Y = startY};
|
{X = startX + Wire.stickLength; Y = startY};
|
||||||
{X = startX + Wire.stickLength; Y = startY};
|
{X = startX + Wire.stickLength; Y = startY};
|
||||||
{X = (startX + endX) / 2.0; Y = startY};
|
{X = (startX + endX) / 2.0; Y = startY};
|
||||||
{X = (startX + endX) / 2.0; Y = endY-Wire.stickLength};
|
{X = (startX + endX) / 2.0; Y = endY - Wire.stickLength};
|
||||||
{X = endX; Y = endY-Wire.stickLength};
|
{X = endX; Y = endY - Wire.stickLength};
|
||||||
{X = endX; Y = endY-Wire.stickLength};
|
{X = endX; Y = endY - Wire.stickLength};
|
||||||
{X = endX; Y = endY}
|
{X = endX; Y = endY}
|
||||||
], false
|
],
|
||||||
| Sameside ->
|
false // Not left-to-right
|
||||||
if abs (endX-startX) >= Wire.stickLength*2.0 && endY >= startY then
|
|
||||||
|
// Sameside -> the two ports are facing in the same direction
|
||||||
|
elif routetype = Sameside then
|
||||||
|
|
||||||
|
// If the X distance is more than twice the sticklength, and
|
||||||
|
// the output port is *above* the input port
|
||||||
|
//
|
||||||
|
// E E
|
||||||
|
// | |
|
||||||
|
// S + or + S
|
||||||
|
// | | | |
|
||||||
|
// + - + + - +
|
||||||
|
if abs (endX - startX) >= Wire.stickLength * 2.0
|
||||||
|
&& endY >= startY then
|
||||||
|
|
||||||
[
|
[
|
||||||
{X = startX; Y = startY};
|
{X = startX; Y = startY};
|
||||||
{X = startX ; Y = startY- Wire.stickLength};
|
{X = startX ; Y = startY - Wire.stickLength};
|
||||||
{X = startX ; Y = startY- Wire.stickLength};
|
{X = startX ; Y = startY - Wire.stickLength};
|
||||||
{X = endX; Y = startY- Wire.stickLength};
|
{X = endX; Y = startY - Wire.stickLength};
|
||||||
{X = endX; Y = startY- Wire.stickLength};
|
{X = endX; Y = startY - Wire.stickLength};
|
||||||
{X = endX ; Y = endY-Wire.stickLength}
|
{X = endX ; Y = endY - Wire.stickLength}
|
||||||
{X = endX ; Y = endY-Wire.stickLength}
|
{X = endX ; Y = endY - Wire.stickLength}
|
||||||
{X = endX; Y = endY}
|
{X = endX; Y = endY}
|
||||||
], true
|
],
|
||||||
elif abs (endX-startX) >= Wire.stickLength*2.0 then
|
true // Left-to-right
|
||||||
|
|
||||||
|
// Otherwise if the start port is above the end port:
|
||||||
|
//
|
||||||
|
// S S
|
||||||
|
// | |
|
||||||
|
// E + or + E
|
||||||
|
// | | | |
|
||||||
|
// + - + + - +
|
||||||
|
elif abs (endX - startX) >= Wire.stickLength * 2.0 then
|
||||||
[
|
[
|
||||||
{X = startX; Y = startY};
|
{X = startX; Y = startY};
|
||||||
{X = startX ; Y = startY- Wire.stickLength};
|
{X = startX ; Y = startY - Wire.stickLength};
|
||||||
{X = startX ; Y = endY- Wire.stickLength};
|
{X = startX ; Y = endY - Wire.stickLength};
|
||||||
{X = endX; Y = endY- Wire.stickLength};
|
{X = endX; Y = endY - Wire.stickLength};
|
||||||
{X = endX; Y = endY- Wire.stickLength};
|
{X = endX; Y = endY - Wire.stickLength};
|
||||||
{X = endX ; Y = endY-Wire.stickLength}
|
{X = endX ; Y = endY - Wire.stickLength}
|
||||||
{X = endX ; Y = endY-Wire.stickLength}
|
{X = endX ; Y = endY - Wire.stickLength}
|
||||||
{X = endX; Y = endY}
|
{X = endX; Y = endY}
|
||||||
], true
|
],
|
||||||
|
true // Left-to-right
|
||||||
|
|
||||||
|
// And last but not least, if the X distance is less than two stick
|
||||||
|
// lengths' worth:
|
||||||
|
//
|
||||||
|
// S E
|
||||||
|
// | |
|
||||||
|
// + - + E or S + - +
|
||||||
|
// | | | |
|
||||||
|
// + - + + - +
|
||||||
else
|
else
|
||||||
[
|
[
|
||||||
{X = startX; Y = startY};
|
{X = startX; Y = startY};
|
||||||
{X = startX ; Y = startY-Wire.stickLength};
|
{X = startX ; Y = startY - Wire.stickLength};
|
||||||
{X = startX ; Y = startY-Wire.stickLength};
|
{X = startX ; Y = startY - Wire.stickLength};
|
||||||
{X = startX + Wire.stickLength*2.0 ; Y = startY-Wire.stickLength};
|
{X = startX + Wire.stickLength * 2.0 ; Y = startY - Wire.stickLength};
|
||||||
{X = startX + Wire.stickLength*2.0 ; Y = endY-Wire.stickLength};
|
{X = startX + Wire.stickLength * 2.0 ; Y = endY - Wire.stickLength};
|
||||||
{X = endX; Y = endY-Wire.stickLength};
|
{X = endX; Y = endY - Wire.stickLength};
|
||||||
{X = endX; Y = endY-Wire.stickLength};
|
{X = endX; Y = endY - Wire.stickLength};
|
||||||
{X = endX; Y = endY}
|
{X = endX; Y = endY}
|
||||||
], false
|
],
|
||||||
|
false // Not left-to-right
|
||||||
|
|
||||||
|
else
|
||||||
|
failwith "route type not recognized"
|
||||||
|
|
||||||
|
|
||||||
/// Infer whether wire is LeftToRight from vertices
|
/// Infer whether wire is LeftToRight from vertices
|
||||||
let inferOrientationFromVertices (xyVerticesList: XYPos list) : bool option =
|
let inferOrientationFromVertices (xyVerticesList: XYPos list) : bool option =
|
||||||
|
@ -667,11 +762,22 @@ let makeASegPos (seg : ASeg) =
|
||||||
let makeRISegPos (seg: RISeg) =
|
let makeRISegPos (seg: RISeg) =
|
||||||
{ seg with Start = absXYPos seg.Start }
|
{ seg with Start = absXYPos seg.Start }
|
||||||
|
|
||||||
/// Initial list of absolute segments based on positions of ports to be connected
|
/// Initial list of absolute segments based on positions of ports to be
|
||||||
|
/// connected.
|
||||||
|
/// Does some cool stuff to allow for routing between ports of rotated
|
||||||
|
/// components using reflection/rotation of 3 basic patterns
|
||||||
let makeInitialASegList (hostId: ConnectionId)
|
let makeInitialASegList (hostId: ConnectionId)
|
||||||
(inputPort: Symbol.PortOrientation * XYPos) (outputPort: Symbol.PortOrientation * XYPos) : list<ASeg> =
|
(inputPort: Symbol.PortOrientation * XYPos)
|
||||||
let inputPortPos, (inputPortOri:Symbol.PortOrientation), outputPortPos,(outputPortOri:Symbol.PortOrientation) = snd inputPort, fst inputPort, snd outputPort, fst outputPort
|
(outputPort: Symbol.PortOrientation * XYPos)
|
||||||
|
: list<ASeg> =
|
||||||
|
|
||||||
|
// Get (input, output) port positions and orientations
|
||||||
|
let inputPortPos, outputPortPos = snd inputPort, snd outputPort
|
||||||
|
let (inputPortOri: Symbol.PortOrientation),
|
||||||
|
(outputPortOri: Symbol.PortOrientation) =
|
||||||
|
fst inputPort, fst outputPort
|
||||||
|
|
||||||
|
// Lil' cheeky functor to flip positions about the x axis
|
||||||
let reverse_rotate =
|
let reverse_rotate =
|
||||||
function
|
function
|
||||||
| PosY -> PosY
|
| PosY -> PosY
|
||||||
|
@ -679,39 +785,64 @@ let makeInitialASegList (hostId: ConnectionId)
|
||||||
| NegY -> NegY
|
| NegY -> NegY
|
||||||
| NegX -> PosX
|
| NegX -> PosX
|
||||||
|
|
||||||
|
// There's 3 types of route conditions:
|
||||||
|
// - SameSide
|
||||||
|
// - RightAngle
|
||||||
|
// - OppositeSide
|
||||||
|
//
|
||||||
|
// Based on the direction of the port coming out of the input (and into the
|
||||||
|
// output), we pick a shape of route, a rotation direction, and whether or
|
||||||
|
// not the wire requires reflection.
|
||||||
|
let routetype, rotation, yreflect =
|
||||||
|
match outputPortOri, inputPortOri with
|
||||||
|
| Symbol.Top, Symbol.Top -> Sameside, PosY, false
|
||||||
|
| Symbol.Top, Symbol.Right -> Rightangle, NegX, true
|
||||||
|
| Symbol.Top, Symbol.Bottom -> Oppositeside, NegX, false
|
||||||
|
| Symbol.Top, Symbol.Left -> Rightangle, NegX, false
|
||||||
|
|
||||||
|
| Symbol.Right, Symbol.Top -> Rightangle, PosY, false
|
||||||
|
| Symbol.Right, Symbol.Right -> Sameside, PosX, false
|
||||||
|
| Symbol.Right, Symbol.Bottom -> Rightangle,NegY, true
|
||||||
|
| Symbol.Right, Symbol.Left -> Oppositeside, PosY, false
|
||||||
|
|
||||||
let routetype,rotation,yreflect =
|
| Symbol.Bottom, Symbol.Top -> Oppositeside, PosX, false
|
||||||
match outputPortOri,inputPortOri with
|
| Symbol.Bottom, Symbol.Right -> Rightangle, PosX, false
|
||||||
| Symbol.Top, Symbol.Top -> Sameside, PosY, false
|
| Symbol.Bottom, Symbol.Bottom -> Sameside, NegY, false
|
||||||
| Symbol.Top , Symbol.Right -> Rightangle, NegX, true
|
| Symbol.Bottom, Symbol.Left -> Rightangle, PosX, true
|
||||||
| Symbol.Top , Symbol.Bottom -> Oppositeside, NegX, false
|
|
||||||
| Symbol.Top , Symbol.Left -> Rightangle, NegX, false
|
|
||||||
| Symbol.Right , Symbol.Top -> Rightangle, PosY, false
|
|
||||||
| Symbol.Right , Symbol.Right -> Sameside, PosX, false
|
|
||||||
| Symbol.Right , Symbol.Bottom -> Rightangle,NegY, true
|
|
||||||
| Symbol.Right , Symbol.Left -> Oppositeside, PosY, false
|
|
||||||
| Symbol.Bottom , Symbol.Top -> Oppositeside, PosX, false
|
|
||||||
| Symbol.Bottom , Symbol.Right -> Rightangle, PosX, false
|
|
||||||
| Symbol.Bottom , Symbol.Bottom -> Sameside, NegY, false
|
|
||||||
| Symbol.Bottom , Symbol.Left -> Rightangle, PosX, true
|
|
||||||
| Symbol.Left , Symbol.Top -> Rightangle, PosY, true
|
|
||||||
| Symbol.Left , Symbol.Right -> Oppositeside, NegY, false
|
|
||||||
| Symbol.Left , Symbol.Bottom -> Rightangle, NegY, false
|
|
||||||
| Symbol.Left , Symbol.Left -> Sameside, NegX, false
|
|
||||||
|
|
||||||
let inputPortPos' =
|
| Symbol.Left, Symbol.Top -> Rightangle, PosY, true
|
||||||
let relativePos=
|
| Symbol.Left, Symbol.Right -> Oppositeside, NegY, false
|
||||||
inputPortPos-outputPortPos
|
| Symbol.Left, Symbol.Bottom -> Rightangle, NegY, false
|
||||||
|
| Symbol.Left, Symbol.Left -> Sameside, NegX, false
|
||||||
|
|
||||||
|
// Get the adjusted input port position, applying any rotations and
|
||||||
|
// reflections
|
||||||
|
let inputPortPos': XYPos =
|
||||||
|
let relativePos =
|
||||||
|
inputPortPos - outputPortPos
|
||||||
|> rotate_rel (reverse_rotate rotation)
|
|> rotate_rel (reverse_rotate rotation)
|
||||||
|> yReflect yreflect
|
|> yReflect yreflect
|
||||||
|
|
||||||
relativePos + outputPortPos
|
relativePos + outputPortPos
|
||||||
|
|
||||||
printfn $"outputPortPos:{outputPortPos},inputPortPos':{inputPortPos'},inputPortPos:{inputPortPos}"
|
(*
|
||||||
printfn $"inputPortOri:{inputPortOri},outputPortOri:{outputPortOri}"
|
printfn $"outputPortPos:{outputPortPos}, inputPortPos':{inputPortPos'}, inputPortPos:{inputPortPos}"
|
||||||
printfn $"routetype:{routetype},rotation:{rotation},yreflect:{yreflect}"
|
printfn $"inputPortOri:{inputPortOri}, outputPortOri:{outputPortOri}"
|
||||||
let xyPairs, isLeftToRight = initialWireVerticesFromPorts outputPortPos inputPortPos' routetype
|
printfn $"routetype:{routetype}, rotation:{rotation}, yreflect:{yreflect}"
|
||||||
xyPairs |> convertVerticesToASegs hostId isLeftToRight routetype rotation yreflect outputPortPos
|
*)
|
||||||
|
|
||||||
|
let (xyPairs: list<XYPos>), (isLeftToRight: bool) =
|
||||||
|
initialWireVerticesFromPorts outputPortPos inputPortPos' routetype
|
||||||
|
|
||||||
|
// Does a thing
|
||||||
|
convertVerticesToASegs
|
||||||
|
hostId
|
||||||
|
isLeftToRight
|
||||||
|
routetype
|
||||||
|
rotation
|
||||||
|
yreflect
|
||||||
|
outputPortPos
|
||||||
|
xyPairs
|
||||||
|
|
||||||
// TODO: native RISeg implementation
|
// TODO: native RISeg implementation
|
||||||
// Initial list of rotation invariant segments based on positions of ports to be connected
|
// Initial list of rotation invariant segments based on positions of ports to be connected
|
||||||
|
@ -1872,30 +2003,52 @@ let update (msg : Msg) (model : Model) : Model * Cmd<Msg> =
|
||||||
|> Map.filter (fun id _ -> not (List.contains id connectionIds))
|
|> Map.filter (fun id _ -> not (List.contains id connectionIds))
|
||||||
{model with WX = newWX}, Cmd.ofMsg BusWidths
|
{model with WX = newWX}, Cmd.ofMsg BusWidths
|
||||||
|
|
||||||
|
// Handles wire dragging request
|
||||||
| DragWire (connId : ConnectionId, mMsg: MouseT) ->
|
| DragWire (connId : ConnectionId, mMsg: MouseT) ->
|
||||||
match mMsg.Op with
|
match mMsg.Op with
|
||||||
|
|
||||||
|
// On a mouse press, select that given segment
|
||||||
| Down ->
|
| Down ->
|
||||||
let segId = getClickedSegment model connId mMsg.Pos
|
let segId = getClickedSegment model connId mMsg.Pos
|
||||||
{model with SelectedSegment = segId }, Cmd.none
|
{model with SelectedSegment = segId }, Cmd.none
|
||||||
|
|
||||||
|
// On a mouse drag, move the segment the mouse is hovering over
|
||||||
| Drag ->
|
| Drag ->
|
||||||
let aSeg =
|
|
||||||
let aSegOption =
|
// Get the segment
|
||||||
|
let aSeg: ASeg =
|
||||||
|
|
||||||
|
// Picks the segment being selected from a list of all the
|
||||||
|
// wire's segments
|
||||||
|
let aSegOption: option<ASeg> =
|
||||||
|
|
||||||
|
let choiceFunctor (segment: ASeg): option<ASeg> =
|
||||||
|
if segment.Id = model.SelectedSegment then Some segment
|
||||||
|
else None
|
||||||
|
|
||||||
riSegWireToASegs model.WX[connId]
|
riSegWireToASegs model.WX[connId]
|
||||||
|> List.choose ( fun aSeg -> if aSeg.Id = model.SelectedSegment then Some aSeg else None )
|
|> List.choose choiceFunctor
|
||||||
|> List.tryExactlyOne
|
|> List.tryExactlyOne
|
||||||
|
|
||||||
|
// Make sure a segment was found
|
||||||
match aSegOption with
|
match aSegOption with
|
||||||
| Some aSeg -> aSeg
|
| Some aSeg -> aSeg
|
||||||
| None -> failwithf "Error: Segment Id not found in segment list"
|
| None -> failwithf "Error: Segment Id not found in list"
|
||||||
|
|
||||||
|
// Check the segment is draggable; otherwise, do nothing
|
||||||
if aSeg.Draggable then
|
if aSeg.Draggable then
|
||||||
|
|
||||||
|
// Evaluate the drag distance (perpendicular to the segment's
|
||||||
|
// direction) to the mouse position
|
||||||
let distanceToMove =
|
let distanceToMove =
|
||||||
match aSeg.Dir with
|
match aSeg.Dir with
|
||||||
| Horizontal -> mMsg.Pos.Y - abs aSeg.Start.Y
|
| Horizontal -> mMsg.Pos.Y - abs aSeg.Start.Y
|
||||||
| Vertical -> mMsg.Pos.X - abs aSeg.Start.X
|
| Vertical -> mMsg.Pos.X - abs aSeg.Start.X
|
||||||
|
|
||||||
|
// Create a new wire segment by dragging the current one, and
|
||||||
|
// insert it into the model
|
||||||
let newWire = moveSegment aSeg distanceToMove model
|
let newWire = moveSegment aSeg distanceToMove model
|
||||||
let newWX = Map.add aSeg.HostId newWire model.WX
|
let newWX = Map.add aSeg.HostId newWire model.WX
|
||||||
|
|
||||||
{model with WX = newWX}, Cmd.none
|
{model with WX = newWX}, Cmd.none
|
||||||
else
|
else
|
||||||
model, Cmd.none
|
model, Cmd.none
|
||||||
|
|
Loading…
Reference in a new issue