0 | module CyBy.Draw.Internal.Navigation
3 | import CyBy.Draw.Internal.Atom
4 | import CyBy.Draw.Internal.Graph
5 | import CyBy.Draw.Internal.Role
7 | import Data.Graph.Indexed
14 | data Direction = N | W | S | E
16 | dirAngle : Direction -> Angle
17 | dirAngle N = threeHalfPi
24 | bondAnglesWithNodes : CDIGraph k -> Fin k -> List (Angle, Fin k)
25 | bondAnglesWithNodes g x =
26 | let p := pointId (lab g x)
27 | ns := visibleNeighbours g x
28 | in mapMaybe (\fn => (,fn) <$> angle (pointId (lab g fn) - p)) ns
33 | bestPointId : Direction -> (Point Id, Fin k) -> (Point Id, Fin k) -> Fin k
34 | bestPointId E (p1, i1) (p2, i2) = if p1.x >= p2.x then i1 else i2
35 | bestPointId S (p1, i1) (p2, i2) = if p1.y >= p2.y then i1 else i2
36 | bestPointId W (p1, i1) (p2, i2) = if p1.x <= p2.x then i1 else i2
37 | bestPointId N (p1, i1) (p2, i2) = if p1.y <= p2.y then i1 else i2
41 | DirectionMargin : Angle
42 | DirectionMargin = Geom.Angle.angle (7 * pi / 16)
46 | angleEdge : CDIGraph k -> Fin k -> Fin k -> Maybe Angle
48 | let p1 := pointId (lab g n1)
49 | p2 := pointId (lab g n2)
59 | moveActive : Direction -> CDGraph -> CDGraph
60 | moveActive d (G k g) =
61 | G k $
case hoveredItem g of
63 | case minBy (minDelta (dirAngle d) . fst) (bondAnglesWithNodes g i) of
65 | if minDelta b (dirAngle d) < DirectionMargin
66 | then updateEdge j i (set Hover) (updateNode i (unset Hover) g)
70 | case angleEdge g x y of
72 | if minDelta (dirAngle d) angl <= DirectionMargin ||
73 | minDelta (dirAngle d) (angl + pi) <= DirectionMargin
75 | let g := updateEdge x y (unset Hover) g
76 | n := bestPointId d (pointAt g x, x) (pointAt g y, y)
77 | in updateNode n (set Hover) g