Permit multiple selection, which can be dragged as one unit.
Wed Nov 16 20:23:16 WET 2005 Malcolm.Wallace@cs.york.ac.uk
* Permit multiple selection, which can be dragged as one unit.
Rather than being allowed to select only one node, edge, or control
point, it is now possible to add multiple items into the selection by
holding down the Meta key when clicking an entity. (Meta = Cmd
(helicopter) key on MacOS, probably either Alt or Box on Windows.)
The Meta-click acts as a toggle, so you can remove items from
the selection also.
The multiple selection can be dragged to new positions on the canvas,
just like a single selection. However, because of this, it only makes
sense to allow nodes and control points within a multiple selection. An
edge has no location independent of the nodes/controls, so cannot itself
be moved.
{
hunk ./src/Document.hs 35
+ | MultipleSelection [Int] [(Int,Int)]
hunk ./src/GUIEvents.hs 3
+import List (nub,(\\))
hunk ./src/GUIEvents.hs 26
+ sel = getSelection doc
hunk ./src/GUIEvents.hs 44
- pickupVia edgeNr viaNr doubleMousePoint state
+ case getSelection doc of
+ MultipleSelection ns vs | (edgeNr,viaNr) `elem` vs->
+ pickupMultiple ns vs doubleMousePoint state
+ _ -> pickupVia edgeNr viaNr doubleMousePoint state
hunk ./src/GUIEvents.hs 54
- pickupNode nodeNr doubleMousePoint state
+ case getSelection doc of
+ MultipleSelection ns vs | nodeNr `elem` ns ->
+ pickupMultiple ns vs doubleMousePoint state
+ _ -> pickupNode nodeNr doubleMousePoint state
hunk ./src/GUIEvents.hs 76
- createNode doubleMousePoint state -- shift click in empty area = create new node
+ -- shift click in empty area = create new node
+ createNode doubleMousePoint state
hunk ./src/GUIEvents.hs 87
+leftMouseDownWithMeta :: (InfoKind n g, InfoKind e g) =>
+ Point -> State g n e -> IO ()
+leftMouseDownWithMeta mousePoint state =
+ do{ pDoc <- getDocument state
+ ; doc <- PD.getDocument pDoc
+ ; ppi <- getScreenPPI
+ ; let network = getNetwork doc
+ doubleMousePoint = screenToLogicalPoint ppi mousePoint
+ ; case clickedNode doubleMousePoint doc of
+ Just j -> do -- meta click on node = toggle whether node in selection
+ case getSelection doc of
+ NodeSelection i | i == j -> selectNothing state
+ | i /= j -> selectMultiple (nub [i,j]) [] state
+ ViaSelection e v -> selectMultiple [j] [(e,v)] state
+ MultipleSelection ns vs | j `elem` ns ->
+ selectMultiple (ns\\[j]) vs state
+ | otherwise ->
+ selectMultiple (j:ns) vs state
+ _ -> selectNode j state
+ Nothing ->
+ case clickedVia doubleMousePoint network of
+ Just via@(e,v) -> -- meta click on via point = toggle inclusion
+ case getSelection doc of
+ NodeSelection i -> selectMultiple [i] [(e,v)] state
+ ViaSelection e' v'
+ | e==e' && v==v' -> selectNothing state
+ | otherwise -> selectMultiple [] [via,(e',v')] state
+ MultipleSelection ns vs
+ | via `elem` vs -> selectMultiple ns (vs\\[via]) state
+ | otherwise -> selectMultiple ns (via:vs) state
+ _ -> selectVia e v state
+ Nothing -> return ()
+ }
+
hunk ./src/GUIEvents.hs 134
+ MultipleSelection ns vs ->
+ dragMultiple ns vs doubleMousePoint canvas state
hunk ./src/GUIEvents.hs 153
+ MultipleSelection ns vs ->
+ dropMultiple hasMoved ns vs offset doubleMousePoint state
hunk ./src/NetworkControl.hs 5
- , selectNothing
- , pickupNode, dragNode, dropNode
- , pickupVia, dragVia, dropVia
+ , selectNothing, selectMultiple
+ , pickupNode, dragNode, dropNode
+ , pickupVia, dragVia, dropVia
+ , pickupMultiple, dragMultiple, dropMultiple
hunk ./src/NetworkControl.hs 248
+
+selectMultiple :: [Int] -> [(Int,Int)] -> State g n e -> IO ()
+selectMultiple nodeNrs viaNrs state = [_$_]
+ do{ pDoc <- getDocument state
+ ; PD.superficialUpdateDocument
+ (setSelection (MultipleSelection nodeNrs viaNrs))
+ pDoc
+ ; repaintAll state
+ }
+
+pickupMultiple :: [Int] -> [(Int,Int)] -> DoublePoint -> State g n e -> IO ()
+pickupMultiple _nodeNrs _viaNrs mousePoint state = [_$_]
+ do{ setDragging (Just (False, mousePoint)) state
+-- ; selectMultiple nodeNrs viaNrs state -- already selected
+ }
+
+dragMultiple :: [Int] -> [(Int,Int)] -> DoublePoint -> ScrolledWindow ()
+ -> State g n e -> IO ()
+dragMultiple nodeNrs viaNrs mousePoint canvas state = [_$_]
+ do{ pDoc <- getDocument state
+ -- ; doc <- PD.getDocument pDoc
+ ; Just (hasMoved, origin) <- getDragging state
+ ; let offset = mousePoint `subtractDoublePoint` origin
+ ; when (mousePoint /= origin) $
+ do{ -- The first time the point is moved we have to remember
+ -- the document in the undo history
+ ; (if not hasMoved then PD.updateDocument "move control point" [_$_]
+ else PD.superficialUpdateDocument)
+ (updateNetwork (updateMultiple nodeNrs viaNrs offset))
+ pDoc
+ ; Graphics.UI.WX.repaint canvas
+ ; setDragging (Just (True, mousePoint)) state [_$_]
+ -- yes, the point has really moved [_$_]
+ }
+ }
+
+updateMultiple :: [Int] -> [(Int,Int)] -> DoublePoint -> Network g n e
+ -> Network g n e
+updateMultiple ns vs o network =
+ ( foldr (\n z-> updateNode n (offsetNode o) . z) id ns
+ . foldr (\ (e,v) z-> updateVia e v (offsetVia o e v) . z) id vs
+ ) network
+ where
+ offsetNode off node = setPosition (getPosition node `translate` off) node
+ offsetVia off edgeNr via = ((getEdgeVia (getEdge edgeNr network))!!via)
+ `translate` off
+
+dropMultiple :: Bool -> [Int] -> [(Int,Int)] -> DoublePoint -> DoublePoint
+ -> State g n e -> IO ()
+dropMultiple hasMoved nodeNrs viaNrs origin mousePoint state = [_$_]
+ do{ when hasMoved $
+ do{ pDoc <- getDocument state
+ ; PD.superficialUpdateDocument
+ (updateNetwork
+ (updateMultiple nodeNrs viaNrs
+ (mousePoint`subtractDoublePoint`origin)))
+ pDoc
+ }
+ ; canvas <- getCanvas state
+ ; Graphics.UI.WX.repaint canvas
+ ; setDragging Nothing state
+ }
+
hunk ./src/NetworkUI.hs 262
+ | metaDown mods -> leftMouseDownWithMeta mousePoint state
hunk ./src/NetworkView.hs 56
- -- draw edges, highlight the selected one (if any)
- ; mapM (\edge -> drawEdge edge []) (getEdges network)
+ -- draw edges, highlight the selected ones (if any)
+ ; mapM_ (\edge -> drawEdge edge []) (getEdges network)
hunk ./src/NetworkView.hs 63
+ MultipleSelection _ viaNrs -> do
+ mapM_ (\ (e,v)-> drawVia (getEdge e network) v kSELECTED_OPTIONS)
+ viaNrs
hunk ./src/NetworkView.hs 68
- -- draw nodes, highlight the selected one (if any)
- ; mapM (\(nodeNr, _) -> drawNode nodeNr [ ]) (getNodeAssocs network)
+ -- draw nodes, highlight the selected ones (if any)
+ ; mapM_ (\(nodeNr, _) -> drawNode nodeNr [ ]) (getNodeAssocs network)
hunk ./src/NetworkView.hs 74
+ MultipleSelection nodeNrs _ ->
+ mapM_ (\n-> drawNode n (kSELECTED_OPTIONS
+ ++ [ penColor := wxcolor activeSelectionColor ]))
+ nodeNrs
}