2 ( createNode, selectNode
3 , createEdge, selectEdge
7 , selectNothing, selectMultiple
8 , pickupNode, dragNode, dropNode
9 , pickupVia, dragVia, dropVia
10 , pickupMultiple, dragMultiple, dropMultiple
11 , pickupArea, dragArea, dropArea
15 , renameNode, reinfoNodeOrEdge
19 {- pickupX functions with X belonging to {Node, Edge, Via, Area, Multiple} do
28 import NetworkView (edgeContains)
37 import qualified PersistentDocument as PD
39 import Text.Parse as Parse
40 import Data.Char (isSpace)
42 import Graphics.UI.WX hiding (Selection)
43 import Graphics.UI.WXCore
47 changeNamePosition :: Bool -> State g n e -> IO ()
48 changeNamePosition above state =
49 do{ pDoc <- getDocument state
50 ; doc <- PD.getDocument pDoc
51 ; canvas <- getActiveCanvas state
52 ; case getSelection doc of
53 NodeSelection canv nodeNr _ | canv == canvas ->
54 do{ PD.updateDocument "move label"
57 (setNameAbove above)) canvas) pDoc
63 changeNodeShape :: InfoKind n g => String -> n -> State g n e -> IO ()
64 changeNodeShape shapename info state =
65 do{ pDoc <- getDocument state
66 ; doc <- PD.getDocument pDoc
67 ; canvas <- getActiveCanvas state
68 ; case getSelection doc of
69 NodeSelection canv nodeNr _ | canv == canvas ->
70 do{ PD.updateDocument "change shape"
73 (setInfo info . setShape shapename)) canvas) pDoc
79 deleteSelection :: State g n e -> IO ()
80 deleteSelection state =
81 do{ pDoc <- getDocument state
82 ; doc <- PD.getDocument pDoc
83 ; canvas <- getActiveCanvas state
84 ; case getSelection doc of
85 NodeSelection canv nodeNr _ | canv == canvas ->
86 do{ PD.updateDocument "delete node"
87 ( setSelection NoSelection
88 . removeMappingElemWithNode canv nodeNr
89 . updateSelNetwork (removeNode nodeNr) canvas
93 EdgeSelection canv edgeNr | canv == canvas ->
94 do{ PD.updateDocument "delete edge"
95 ( setSelection NoSelection
96 . updateSelNetwork (removeEdge edgeNr) canvas
100 ViaSelection canv edgeNr viaNr | canv == canvas ->
101 do{ PD.updateDocument "delete control point"
102 ( setSelection NoSelection
103 . updateSelNetwork (removeVia edgeNr viaNr) canvas
107 MultipleSelection canv area nodeNrs viaNrs | canv == canvas ->
108 do{ PD.updateDocument "delete multiple selection"
109 ( setSelection NoSelection
110 . updateSelNetwork (foldr (\edgeNr r -> removeNode edgeNr . r) id nodeNrs) canvas
117 createNode :: InfoKind n g => DoublePoint -> State g n e -> IO ()
118 createNode mousePoint state =
119 do{ pDoc <- getDocument state
120 ; shapeName <- getCurrentShape state
121 ; canvas <- getActiveCanvas state
122 ; doc1 <- PD.getDocument pDoc
124 ; let palette = getPalette doc1
125 (nodeNr, doc2) = updateSelNetworkEx
126 (setNewPosition . addNode shapeName palette)
128 doc3 = setSelection (NodeSelection canvas nodeNr Nothing) doc2
129 ; PD.setDocument ("add node on " ++ show' canvas) doc3 pDoc
132 where setNewPosition (nodeNr, newNet) =
133 (nodeNr, updateNode nodeNr ( setPosition mousePoint) newNet )
135 selectNothing :: State g n e -> IO ()
136 selectNothing state =
137 do{ pDoc <- getDocument state
138 ; PD.superficialUpdateDocument (setSelection NoSelection) pDoc
142 selectEdge :: Int -> State g n e -> IO ()
143 selectEdge edgeNr state =
144 do{ pDoc <- getDocument state
145 ; canvas <- getActiveCanvas state
146 ; PD.superficialUpdateDocument (setSelection (EdgeSelection canvas edgeNr)) pDoc
150 createEdge :: (InfoKind e g) => NodeNr -> PortName -> NodeNr -> PortName -> State g n e -> IO ()
151 createEdge fromNodeNr fromPort toNodeNr toPort state =
152 do{ pDoc <- getDocument state
153 ; canvas <- getActiveCanvas state
154 ; doc <- PD.getDocument pDoc
155 ; PD.updateDocument "add edge"
156 ( setSelection (NodeSelection canvas fromNodeNr $ Just fromPort)
157 . updateSelNetwork (addEdge (getPalette doc) fromNodeNr fromPort toNodeNr toPort)
162 createMapping :: RuleName -- ^ rule to add the mapping to
163 -> NodeNr -- ^ LHS node number
164 -> NodeNr -- ^ RHS node number
165 -> State g n e -> IO ()
166 createMapping rule nNrL nNrR state =
167 do{ pDoc <- getDocument state
168 ; PD.updateDocument ("add mapping to rule " ++ rule)
172 $ addMapping (nNrL, nNrR)
177 createVia :: DoublePoint -> State g n e -> IO ()
178 createVia mousepoint state =
179 do{ pDoc <- getDocument state
180 ; doc <- PD.getDocument pDoc
181 ; canvas <- getActiveCanvas state
182 ; let network = selectNetwork doc canvas
183 ; case getSelection doc of
184 EdgeSelection canv edgeNr | canv == canvas ->
185 do{ ifJust (edgeContains (getEdge edgeNr network) mousepoint network)
187 do{ PD.updateDocument "add control point to edge"
188 ( setSelection (ViaSelection canvas edgeNr viaNr)
189 . updateSelNetwork (newViaEdge edgeNr viaNr mousepoint) canvas
197 selectVia :: Int -> Int -> State g n e -> IO ()
198 selectVia edgeNr viaNr state =
199 do{ pDoc <- getDocument state
200 ; canvas <- getActiveCanvas state
201 ; PD.superficialUpdateDocument (setSelection (ViaSelection canvas edgeNr viaNr))
206 pickupVia :: Int -> Int -> DoublePoint -> State g n e -> IO ()
207 pickupVia edgeNr viaNr mousePoint state =
208 do{ pDoc <- getDocument state
209 ; doc <- PD.getDocument pDoc
210 ; canvas <- getActiveCanvas state
211 ; let network = selectNetwork doc canvas
212 viaPos = (getEdgeVia (getEdge edgeNr network))!!viaNr
213 ; setDragging (Just (False, mousePoint `subtractDoublePoint` viaPos)) state
214 ; selectVia edgeNr viaNr state
217 selectNode :: Int -> State g n e -> IO ()
218 selectNode nodeNr state = selectPort nodeNr Nothing state
220 selectPort :: Int -> Maybe PortName -> State g n e -> IO ()
221 selectPort nodeNr mPort state =
222 do{ pDoc <- getDocument state
223 ; canvas <- getActiveCanvas state
224 ; PD.superficialUpdateDocument (setSelection $ NodeSelection canvas nodeNr mPort) pDoc
228 pickupNode :: Int -> Maybe PortName -> DoublePoint -> State g n e -> IO ()
229 pickupNode nodeNr mPort mousePoint state =
230 do{ pDoc <- getDocument state
231 ; doc <- PD.getDocument pDoc
232 ; canvas <- getActiveCanvas state
233 ; let network = selectNetwork doc canvas
234 nodePos = getNodePosition network nodeNr
235 ; setDragging (Just (False, mousePoint `subtractDoublePoint` nodePos)) state
236 ; selectPort nodeNr mPort state
239 dragNode :: Int -> DoublePoint -> State g n e -> IO ()
240 dragNode nodeNr mousePoint state =
241 do{ pDoc <- getDocument state
242 ; doc <- PD.getDocument pDoc
243 ; canvas <- getActiveCanvas state
244 ; Just (hasMoved, offset) <- getDragging state
245 ; let newPosition = mousePoint `subtractDoublePoint` offset
246 oldPosition = getNodePosition (selectNetwork doc canvas) nodeNr
247 ; when (newPosition /= oldPosition) $
248 do{ -- The first time the node is moved we have to remember
249 -- the document in the undo history
250 ; (if not hasMoved then PD.updateDocument "move node"
251 else PD.superficialUpdateDocument)
252 (updateSelNetwork (updateNode nodeNr
253 (setPosition newPosition)) canvas )
256 ; setDragging (Just (True, offset)) state
257 -- yes, the node has really moved
261 dropNode :: Bool -> Int -> DoublePoint -> DoublePoint -> State g n e -> IO ()
262 dropNode hasMoved nodeNr offset mousePoint state =
264 do{ let newPosition = mousePoint `subtractDoublePoint` offset
265 ; pDoc <- getDocument state
266 ; canvas <- getActiveCanvas state
267 ; PD.superficialUpdateDocument
268 (updateSelNetwork (updateNode nodeNr
269 (setPosition newPosition)) canvas) pDoc
272 ; setDragging Nothing state
275 dragVia :: Int -> Int -> DoublePoint -> State g n e -> IO ()
276 dragVia edgeNr viaNr mousePoint state =
277 do{ pDoc <- getDocument state
278 ; doc <- PD.getDocument pDoc
279 ; canvas <- getActiveCanvas state
280 ; Just (hasMoved, offset) <- getDragging state
281 ; let newPosition = mousePoint `subtractDoublePoint` offset
282 oldPosition = (getEdgeVia (getEdge edgeNr (selectNetwork doc canvas)))!!viaNr
283 ; when (newPosition /= oldPosition) $
284 do{ -- The first time the point is moved we have to remember
285 -- the document in the undo history
286 ; (if not hasMoved then PD.updateDocument "move control point"
287 else PD.superficialUpdateDocument)
288 (updateSelNetwork (updateVia edgeNr viaNr newPosition) canvas)
291 ; setDragging (Just (True, offset)) state
292 -- yes, the point has really moved
296 dropVia :: Bool -> Int -> Int -> DoublePoint -> DoublePoint -> State g n e -> IO ()
297 dropVia hasMoved edgeNr viaNr offset mousePoint state =
299 do{ let newPosition = mousePoint `subtractDoublePoint` offset
300 ; pDoc <- getDocument state
301 ; canvas <- getActiveCanvas state
302 ; PD.superficialUpdateDocument
303 (updateSelNetwork (updateVia edgeNr viaNr newPosition) canvas)
307 ; setDragging Nothing state
310 selectMultiple :: Maybe (DoublePoint,DoublePoint) -> [Int] -> [(Int,Int)]
311 -> State g n e -> IO ()
312 selectMultiple area nodeNrs viaNrs state =
313 do{ pDoc <- getDocument state
314 ; canvas <- getActiveCanvas state
315 ; PD.superficialUpdateDocument
316 (setSelection (MultipleSelection canvas area nodeNrs viaNrs))
321 pickupMultiple :: [Int] -> [(Int,Int)] -> DoublePoint -> State g n e -> IO ()
322 pickupMultiple _nodeNrs _viaNrs mousePoint state =
323 do{ setDragging (Just (False, mousePoint)) state
324 -- ; selectMultiple Nothing nodeNrs viaNrs state -- already selected
327 dragMultiple :: [Int] -> [(Int,Int)] -> DoublePoint -> State g n e -> IO ()
328 dragMultiple nodeNrs viaNrs mousePoint state =
329 do{ pDoc <- getDocument state
330 ; canvas <- getActiveCanvas state
331 -- ; doc <- PD.getDocument pDoc
332 ; Just (hasMoved, origin) <- getDragging state
333 ; let offset = mousePoint `subtractDoublePoint` origin
334 ; when (mousePoint /= origin) $
335 do{ -- The first time the point is moved we have to remember
336 -- the document in the undo history
337 ; (if not hasMoved then PD.updateDocument "move control point"
338 else PD.superficialUpdateDocument)
339 (updateSelNetwork (updateMultiple nodeNrs viaNrs offset) canvas)
342 ; setDragging (Just (True, mousePoint)) state
343 -- yes, the point has really moved
347 updateMultiple :: [Int] -> [(Int,Int)] -> DoublePoint -> Network g n e
349 updateMultiple ns vs o network =
350 ( foldr (\n z-> updateNode n (offsetNode o) . z) id ns
351 . foldr (\ (e,v) z-> updateVia e v (offsetVia o e v) . z) id vs
354 offsetNode off node = setPosition (getPosition node `translate` off) node
355 offsetVia off edgeNr via = ((getEdgeVia (getEdge edgeNr network))!!via)
358 dropMultiple :: Bool -> [Int] -> [(Int,Int)] -> DoublePoint -> DoublePoint
359 -> State g n e -> IO ()
360 dropMultiple hasMoved nodeNrs viaNrs origin mousePoint state =
362 do{ pDoc <- getDocument state
363 ; canvas <- getActiveCanvas state
364 ; PD.superficialUpdateDocument
366 (updateMultiple nodeNrs viaNrs
367 (mousePoint`subtractDoublePoint`origin)) canvas)
371 ; setDragging Nothing state
374 pickupArea :: DoublePoint -> State g n e -> IO ()
375 pickupArea mousePoint state =
376 do{ setDragging (Just (False, mousePoint)) state
377 ; selectMultiple (Just (mousePoint,mousePoint)) [] [] state
380 -- dragArea is not like dragging a selection. It does not move anything.
381 -- It only adds items into a multiple selection.
382 dragArea :: DoublePoint -> State g n e -> IO ()
383 dragArea mousePoint state =
384 do{ pDoc <- getDocument state
385 ; doc <- PD.getDocument pDoc
386 ; canvas <- getActiveCanvas state
387 ; Just (_, origin) <- getDragging state
388 ; let (ns,vs) = itemsEnclosedWithin mousePoint origin (selectNetwork doc canvas)
389 ; selectMultiple (Just (origin,mousePoint)) ns vs state
392 itemsEnclosedWithin p0 p1 network =
394 . Prelude.filter (\ (_,n)-> enclosedInRectangle (getPosition n) p0 p1)
395 . getNodeAssocs ) network
396 , ( Prelude.concatMap (\ (i,e)-> map (\ (j,_)-> (i,j))
398 (\ (_,v)-> enclosedInRectangle
400 (zip [0..] (getEdgeVia e))))
401 . getEdgeAssocs ) network
404 dropArea :: DoublePoint -> DoublePoint -> State g n e -> IO ()
405 dropArea _origin mousePoint state =
406 do{ dragArea mousePoint state -- calculate enclosure area
407 ; pDoc <- getDocument state
408 ; doc <- PD.getDocument pDoc
409 ; canvas <- getActiveCanvas state
410 ; case getSelection doc of
411 MultipleSelection _ _ [] [] ->
412 PD.superficialUpdateDocument (setSelection NoSelection) pDoc
413 MultipleSelection canv _ ns vs | canvas == canv ->
414 PD.superficialUpdateDocument
415 (setSelection (MultipleSelection canvas Nothing ns vs)) pDoc
417 PD.superficialUpdateDocument (setSelection NoSelection) pDoc
419 ; setDragging Nothing state
424 renameNode :: Frame () -> State g n e -> IO ()
425 renameNode theFrame state =
426 do{ pDoc <- getDocument state
427 ; doc <- PD.getDocument pDoc
428 ; canvas <- getActiveCanvas state
429 ; let network = selectNetwork doc canvas
430 ; case getSelection doc of
431 NodeSelection canv nodeNr _ | canv == canvas ->
432 do{ let oldName = getNodeName network nodeNr
433 ; result <- myTextDialog theFrame SingleLine
434 "Rename node" oldName True
435 ; ifJust result $ \newName ->
436 do{ PD.updateDocument "rename node"
438 (updateNode nodeNr (Network.setName newName)) canvas) pDoc
445 reinfoNodeOrEdge :: (InfoKind n g, InfoKind e g) =>
446 Frame () -> State g n e -> IO ()
447 reinfoNodeOrEdge theFrame state =
448 do{ pDoc <- getDocument state
449 ; doc <- PD.getDocument pDoc
450 ; canvas <- getActiveCanvas state
451 ; let network = selectNetwork doc canvas
452 ; case getSelection doc of
453 NodeSelection canv nodeNr _ | canv == canvas ->
454 do{ let oldInfo = getNodeInfo network nodeNr
455 ; result <- myTextDialog theFrame MultiLine
456 "Edit node info" (show oldInfo) True
457 ; ifJust result $ \newInfo ->
458 case Parse.runParser Parse.parse newInfo of
460 do{ when (not (null s || all isSpace s)) $
461 errorDialog theFrame "Edit warning"
462 ("Excess text after parsed value."
463 ++"\nRemaining text: "++s)
464 ; case check (getNodeName network nodeNr)
465 (getGlobalInfo network) x of
467 e -> errorDialog theFrame "Validity warning"
468 ("Validity check fails:\n"
470 ; PD.updateDocument "edit node info"
472 (updateNode nodeNr (setInfo x)) canvas) pDoc
475 (Left err, s) -> errorDialog theFrame "Edit warning"
476 ("Cannot parse entered text."
478 ++"\nRemaining text: "++s)
480 EdgeSelection canv edgeNr | canv == canvas ->
481 do{ let oldInfo = getEdgeInfo (getEdge edgeNr network)
482 ; result <- myTextDialog theFrame MultiLine
483 "Edit edge info" (show oldInfo) True
484 ; ifJust result $ \newInfo ->
485 case Parse.runParser Parse.parse newInfo of
487 do{ when (not (null s || all isSpace s)) $
488 errorDialog theFrame "Edit warning"
489 ("Excess text after parsed value."
490 ++"\nRemaining text: "++s)
491 -- ; case check (getNodeName network nodeNr)
492 -- (getGlobalInfo network) x of
494 -- e -> errorDialog theFrame "Validity warning"
495 -- ("Validity check fails:\n"
497 ; PD.updateDocument "edit edge info"
499 (updateEdge edgeNr (setEdgeInfo x)) canvas) pDoc
502 (Left err, s) -> errorDialog theFrame "Edit warning"
503 ("Cannot parse entered text."
505 ++"\nRemaining text: "++s)
510 changeGlobalInfo :: (Show g, Parse g) => Frame () -> State g n e -> IO ()
511 changeGlobalInfo theFrame state =
512 do{ pDoc <- getDocument state
513 ; doc <- PD.getDocument pDoc
514 ; canvas <- getActiveCanvas state
515 ; let network = selectNetwork doc canvas
516 ; let info = show (getGlobalInfo network)
517 ; result <- myTextDialog theFrame MultiLine "Edit global info" info True
518 ; ifJust result $ \newInfo->
519 case Parse.runParser Parse.parse newInfo of
521 do{ when (not (null s || all isSpace s)) $
522 errorDialog theFrame "Edit warning"
523 ("Excess text after parsed value."
524 ++"\nRemaining text: "++s)
525 ; PD.updateDocument "edit global info"
526 (updateSelNetwork (setGlobalInfo x) canvas) pDoc
527 ; repaintAll state -- no visible change?
529 (Left err, s) -> errorDialog theFrame "Edit warning"
530 ("Cannot parse entered text."
532 ++"\nRemaining text: "++s)