Skip to content

Commit 0f9e567

Browse files
Feat: Drag drop reroute multi sections (#633)
* Feat: New Short-cut multi-selection trainrun sections => press s => split into two trainrun section left / right and add a node in the middle. * Feat: New Short-cut multi-selection trainrun sections => press s => split into two trainrun section left / right and add a node in the middle. * formater fix * formater fix * fix * fix * fix * bug fixed ! * position fix * test fixed, this test must be fail because i changed the object. No it's correct. * position calc updated * fix * fix format * fix * if the node gets removed, check whether we have to close as well the (node side bar) * fix ui behavior * fix ui behavior * doc * doc * doc * Update CREATE_NODES.md * Update CREATE_NODES.md * Update CREATE_NODES.md * Update src/app/services/data/trainrunsection.service.ts Co-authored-by: Louis Greiner <[email protected]> * Update src/app/services/data/node.service.ts Co-authored-by: Louis Greiner <[email protected]> * fix: review issue why returning this? This value is never used * fix: review - removed unused * Update src/app/view/editor-main-view/data-views/editor.keyEvents.ts Oh, i was not aware of this. Thanks -> make sense Co-authored-by: Louis Greiner <[email protected]> * fix - review -simplified code by refactoring into small self-speaking methods. * Update src/app/view/editor-main-view/data-views/editor.keyEvents.ts Co-authored-by: Louis Greiner <[email protected]> * Update src/app/view/editor-main-view/data-views/editor.keyEvents.ts Co-authored-by: Louis Greiner <[email protected]> * fix: review suggestions fixed (github UI used - but it had broken the code :-)) * Update documentation/AdvancedEditingShortcuts.md Co-authored-by: Louis Greiner <[email protected]> * Update documentation/CREATE_TRAINRUN.md Co-authored-by: Louis Greiner <[email protected]> * Update src/app/services/data/trainrunsection.service.ts Co-authored-by: Louis Greiner <[email protected]> * build fix and format issue fixed (lint) * issue resolved * small fix - hover issue solve * small fix - hover issue solve --------- Co-authored-by: Louis Greiner <[email protected]>
1 parent 5408a97 commit 0f9e567

File tree

15 files changed

+428
-54
lines changed

15 files changed

+428
-54
lines changed

documentation/AdvancedEditingShortcuts.md

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,26 @@ easier to manage and edit complex network structures.
1010
1111
### Short-cuts
1212

13-
| Keyboard | description |
14-
| :--------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
15-
| | |
16-
| `delete` | Delete nodes, comments, and selected trainruns. |
17-
| `ctrl`+`d` / `insert` | Duplicate nodes, comments, and selected trainruns (if multiple nodes are selected, trains including nodes will be duplicated). |
18-
| `insert` | Add new nodes under the mouse on the drawing area. |
19-
| `escape` | Select trainruns / In multi-node move mode, all selected nodes will be unselected. |
20-
| `shift` + `left mouse button` pressed and move (or alternatively with the `right mouse button` pressed and move) | Multi-select nodes and notes for subsequent moving or delete all selected elements by using `Delete`. |
21-
| `ctrl`+`z` | Undo - Reverse the previous action. |
22-
| `ctrl`+`c` | Copy the currently visible trainruns. The copied content remains in the browser's memory/cache and can be pasted into different variants (even after closing the browser, the data remains saved). |
23-
| `ctrl`+`v` | Paste the copied trainruns. |
24-
| `ctrl`+`a` | Select all. |
25-
| | |
26-
| `Arrow left` | Aligns objects along their left edges (nodes). |
27-
| `Arrow up` | Aligns objects along their top edges (nodes). |
28-
| `Arrow right` | Aligns objects along their right edges (nodes). |
29-
| `Arrow down` | Aligns objects along their bottom edges (nodes). |
13+
| Keyboard | description |
14+
| :--------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
15+
| | |
16+
| `delete` | Delete nodes, comments, and selected trainruns. |
17+
| `ctrl`+`d` / `insert` | Duplicate nodes, comments, and selected trainruns (if multiple nodes are selected, trains including nodes will be duplicated). |
18+
| `insert` | Add new nodes under the mouse on the drawing area. |
19+
| `escape` | Select trainruns / In multi-node move mode, all selected nodes will be unselected. |
20+
| `shift` + `left mouse button` pressed and move (or alternatively with the `right mouse button` pressed and move) | Multi-select nodes and notes for subsequent moving or delete all selected elements by using `Delete`. |
21+
| `ctrl`+`z` | Undo - Reverse the previous action. |
22+
| `ctrl`+`c` | Copy the currently visible trainruns. The copied content remains in the browser's memory/cache and can be pasted into different variants (even after closing the browser, the data remains saved). |
23+
| `ctrl`+`v` | Paste the copied trainruns. |
24+
| `ctrl`+`a` | Select all. |
25+
| | |
26+
| `s` (without trainrun sections selection) | Hover the mouse cursor over a node and press `s`. The node will be deleted, and all trainrun sections connected to it will be undocked. |
27+
| `s` (with trainrun sections selection) | Hold the `left mouse button` or use `Shift + mouse button` to select multiple nodes. You can also select trainrun sections by drawing a selection box over their names. When at least one trainrun section is selected, press `s` to create a new node, dock the selected trainrun sections to it, and split them accordingly. |
28+
| |
29+
| `Arrow left` | Aligns objects along their left edges (nodes). |
30+
| `Arrow up` | Aligns objects along their top edges (nodes). |
31+
| `Arrow right` | Aligns objects along their right edges (nodes). |
32+
| `Arrow down` | Aligns objects along their bottom edges (nodes). |
3033

3134
---
3235

documentation/CREATE_NODES.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ If you want to move a node process as follows:
8888
symbol.)
8989
- As long as the left mouse button is pressed you can move the node by just drag-and-drop.
9090

91+
#### Multi-select nodes
92+
93+
When you use the `left mouse button` pressed and drag a box - you can select multiple nodes. Once you have them selected you can drag (move) the nodes like a single one but now as a group.
94+
95+
[chrome-capture-2025-11-21.webm](https://github.com/user-attachments/assets/9ddc0104-4e11-4b09-bfcc-e3197f793de6)
96+
9197
#### Trainrun sorting heuristics
9298

9399
##### Single trainrun

documentation/CREATE_TRAINRUN.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,31 @@ To reroute a train, follow these steps:
8282

8383
[2024-1-25-Rerouting_trainrunsections-001.webm](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/assets/2674075/9368c34c-fddf-4698-abf6-e07afba5a1d6)
8484

85+
### Remove Nodes // Add Intermediate Stop Nodes
86+
87+
Without deleting trainrun sections (undock transitions), resp. create node to split trainrun section into two
88+
and dock to the new intermediate stop node in between.
89+
90+
#### Remove a Node
91+
92+
- **What happens**
93+
Hover the mouse cursor over a node and press `s`. The node will be deleted.
94+
- **Result**
95+
All trainrun sections that were docked to this node will be undocked. They are no longer connected and become "free-floating."
96+
97+
#### Add an Intermediate Stop Node (Split & Dock)
98+
99+
- **How to select**
100+
- Hold the left mouse button to select multiple nodes.
101+
- Alternatively, use **Shift + mouse click** for multi-selection.
102+
- You can also select trainrun sections by drawing a selection box over their names.
103+
104+
- **What happens after selection**
105+
When at least one trainrun section is selected and you press `s`:
106+
- A new intermediate stop node is created.
107+
- The selected trainrun sections are docked to this new node.
108+
- The trainrun sections are split into segments aligned with the new intermediate stop node.
109+
85110
### Delete a trainrun section
86111

87112
To delete a trainrun section, process as follows:

src/app/services/data/node.service.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,28 @@ export class NodeService implements OnDestroy {
270270
this.operation.emit(new NodeOperation(OperationType.delete, node));
271271
}
272272

273+
deleteNodeUndockTransitions(
274+
nodeId: number,
275+
createIntermediateStop = false,
276+
enforceUpdate = true,
277+
) {
278+
const node = this.getNodeFromId(nodeId);
279+
node.getTransitions().forEach((tr) => {
280+
const ts = this.undockTransition(node.getId(), tr.getId(), false);
281+
if (ts && !createIntermediateStop) {
282+
ts.setNumberOfStops(Math.max(0, ts.getNumberOfStops() - 1));
283+
}
284+
});
285+
this.deleteNode(node.getId(), false);
286+
287+
if (enforceUpdate) {
288+
this.nodesUpdated();
289+
this.transitionsUpdated();
290+
this.trainrunService.trainrunsUpdated();
291+
this.trainrunSectionService.trainrunSectionsUpdated();
292+
}
293+
}
294+
273295
deleteAllVisibleNodes() {
274296
const nodes = this.nodesStore.nodes;
275297
nodes.forEach((node) => {
@@ -354,7 +376,11 @@ export class NodeService implements OnDestroy {
354376
}
355377
}
356378

357-
undockTransition(nodeId: number, transitionId: number, enforceUpdate = true) {
379+
undockTransition(
380+
nodeId: number,
381+
transitionId: number,
382+
enforceUpdate = true,
383+
): TrainrunSection | undefined {
358384
const transition: Transition = this.getTransition(nodeId, transitionId);
359385

360386
const isNonStop = transition.getIsNonStopTransit();
@@ -385,7 +411,7 @@ export class NodeService implements OnDestroy {
385411
const nonStop2 = transition2 !== undefined ? transition2.getIsNonStopTransit() : false;
386412

387413
if (oppNodeTrainrunSection1.getId() === oppNodeTrainrunSection2.getId()) {
388-
return;
414+
return undefined;
389415
}
390416
this.trainrunSectionService.deleteTrainrunSection(trainrunSection2.getId(), false);
391417

@@ -462,6 +488,8 @@ export class NodeService implements OnDestroy {
462488
this.transitionsUpdated();
463489
this.nodesUpdated();
464490
}
491+
492+
return trainrunSection1;
465493
}
466494

467495
addPortsToNodes(sourceNodeId: number, targetNodeId: number, trainrunSection: TrainrunSection) {

src/app/services/data/trainrun.service.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ export class TrainrunService {
172172

173173
setTrainrunAsSelected(trainrunId: number, enforceUpdate = true) {
174174
this.trainrunsStore.trainruns.forEach((tr) => tr.unselect());
175+
this.trainrunSectionService.unselectAllTrainrunSections(enforceUpdate);
175176
const trainrun = this.getTrainrunFromId(trainrunId);
176177
if (trainrun !== undefined) {
177178
trainrun.select();
@@ -183,6 +184,7 @@ export class TrainrunService {
183184

184185
unselectAllTrainruns(enforceUpdate = true) {
185186
this.trainrunsStore.trainruns.forEach((trainrun) => trainrun.unselect());
187+
this.trainrunSectionService.unselectAllTrainrunSections(enforceUpdate);
186188
if (enforceUpdate) {
187189
this.trainrunsUpdated();
188190
}

0 commit comments

Comments
 (0)