]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/RoutingMode.java
d274a617931b11d1641149bbc722ae4826f45699
[simantics/district.git] / org.simantics.district.network.ui / src / org / simantics / district / network / ui / participants / RoutingMode.java
1 package org.simantics.district.network.ui.participants;
2
3 import java.awt.AlphaComposite;
4 import java.awt.Cursor;
5 import java.util.Collection;
6
7 import org.eclipse.jface.dialogs.IDialogSettings;
8 import org.eclipse.jface.dialogs.IInputValidator;
9 import org.eclipse.jface.dialogs.InputDialog;
10 import org.eclipse.jface.window.Window;
11 import org.eclipse.swt.widgets.Shell;
12 import org.eclipse.ui.PlatformUI;
13 import org.simantics.db.Resource;
14 import org.simantics.diagram.ui.DiagramModelHints;
15 import org.simantics.district.network.ui.internal.Activator;
16 import org.simantics.district.route.Route;
17 import org.simantics.district.route.RouteService;
18 import org.simantics.district.route.Waypoint;
19 import org.simantics.g2d.canvas.ICanvasContext;
20 import org.simantics.g2d.canvas.IMouseCursorContext;
21 import org.simantics.g2d.canvas.IMouseCursorHandle;
22 import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
23 import org.simantics.g2d.canvas.impl.HintReflection.HintListener;
24 import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup;
25 import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
26 import org.simantics.g2d.diagram.handler.PickContext;
27 import org.simantics.g2d.diagram.participant.Selection;
28 import org.simantics.g2d.diagram.participant.pointertool.AbstractMode;
29 import org.simantics.g2d.element.ElementUtils;
30 import org.simantics.g2d.element.IElement;
31 import org.simantics.g2d.participant.TransformUtil;
32 import org.simantics.scenegraph.g2d.G2DParentNode;
33 import org.simantics.scenegraph.g2d.events.Event;
34 import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
35 import org.simantics.scenegraph.g2d.events.KeyEvent.KeyPressedEvent;
36 import org.simantics.scenegraph.g2d.events.command.Command;
37 import org.simantics.scenegraph.g2d.events.command.CommandEvent;
38 import org.simantics.scenegraph.g2d.events.command.Commands;
39 import org.simantics.scenegraph.g2d.nodes.SingleElementNode;
40 import org.simantics.utils.datastructures.hints.IHintContext.Key;
41 import org.simantics.utils.datastructures.hints.IHintObservable;
42 import org.simantics.utils.ui.AdaptionUtils;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 /**
47  * This participant creates routes on district network diagrams using
48  * {@link RouteService}.
49  *
50  * @author Tuukka Lehtonen
51  * @since 6.09
52  */
53 public class RoutingMode extends AbstractMode {
54
55     private static final Logger LOGGER = LoggerFactory.getLogger(RoutingMode.class);
56
57     @Dependency
58     protected TransformUtil        util;
59
60     @Dependency
61     protected PickContext          pickContext;
62
63     @Dependency
64     protected Selection            selection;
65
66     protected IMouseCursorHandle   cursor;
67
68     private RouteService           routeService;
69
70     private Route                  route;
71
72     /**
73      * The node under which the mutated diagram is ghosted in the scene graph.
74      */
75     protected G2DParentNode        parent;
76
77     /**
78      * This stays null until the translated diagram parts have been initialized
79      * into the scene graph. After that, only the translations of the nodes in
80      * the scene graph are modified.
81      */
82     protected SingleElementNode    node = null;
83
84     public RoutingMode(int mouseId) {
85         super(mouseId);
86     }
87
88     @Override
89     public void addedToContext(ICanvasContext ctx) {
90         super.addedToContext(ctx);
91         IMouseCursorContext mcc = getContext().getMouseCursorContext();
92         cursor = mcc == null ? null : mcc.setCursor(mouseId, new Cursor(Cursor.CROSSHAIR_CURSOR));
93         routeService = Activator.getInstance().getRouteService();
94         if (routeService != null) {
95             Resource diagramResource = getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE);
96             LOGGER.info("Diagram resource: " + diagramResource);
97             route = routeService.createRoute("Current", diagramResource);
98             routeService.registerRoute(route);
99         }
100     }
101
102     @Override
103     public void removedFromContext(ICanvasContext ctx) {
104         if (cursor != null) {
105             cursor.remove();
106             cursor = null;
107         }
108         // Discard route if it hasn't been persisted before this
109         if (route != null) {
110             routeService.discardRoute(route);
111             route = null;
112             routeService = null;
113         }
114         super.removedFromContext(ctx);
115     }
116
117     @HintListener(Class = Selection.class, Field = "SELECTION0")
118     public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
119         Collection<IElement> elements = AdaptionUtils.adaptToCollection(newValue, IElement.class);
120         for (IElement element : elements) {
121             addRoutePoint(element);
122         }
123     }
124
125     private void addRoutePoint(IElement element) {
126         if (route == null)
127             return;
128
129         Object o = ElementUtils.getObject(element);
130         if (o instanceof Resource) {
131             Waypoint wp = route.createWaypoint(o);
132             route.addWaypoint(wp);
133         }
134     }
135
136     @SGInit
137     public void initSG(G2DParentNode parent) {
138         this.parent = parent;
139         node = parent.addNode("route highlight", SingleElementNode.class);
140         node.setZIndex(1000);
141         node.setVisible(Boolean.TRUE);
142         node.setComposite(AlphaComposite.SrcOver.derive(0.75f));
143     }
144
145     @SGCleanup
146     public void cleanupSG() {
147         if (node != null) {
148             node.remove();
149             node = null;
150         }
151         parent = null;
152     }
153
154     @EventHandler(priority = 30)
155     public boolean handleEvent(Event e) {
156         if (e instanceof KeyPressedEvent) {
157             if (route == null)
158                 return false;
159             KeyPressedEvent kpe = (KeyPressedEvent) e;
160             if (kpe.keyCode == java.awt.event.KeyEvent.VK_ENTER) {
161                 routeService.persistRoute(route);
162                 route = null;
163                 dispose();
164             }
165         } else if (e instanceof CommandEvent) {
166             Command cmd = ((CommandEvent) e).command;
167             if (cmd.equals(Commands.CANCEL)) {
168                 return dispose();
169             } else if (cmd.equals(Commands.RENAME)) {
170                 InputDialog dialog = new InputDialog(
171                         PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
172                         "Rename Route",
173                         "Route name",
174                         route.getName(),
175                         s -> s.trim().length() > 0 ? null : "Name must be non-empty");
176                 if (dialog.open() == Window.OK) {
177                     route.setName(dialog.getValue());
178                 }
179             }
180         }
181         return false;
182     }
183
184     protected boolean dispose() {
185         setDirty();
186         remove();
187         return false;
188     }
189
190     static class RenameDialog extends InputDialog {
191
192         public RenameDialog(Shell parent, String title, String message, String initialValue, IInputValidator validator) {
193             super(parent, title, message, initialValue, validator);
194         }
195
196         @Override
197         protected IDialogSettings getDialogBoundsSettings() {
198             String sectionName = getClass().getName() + "_dialogBounds"; //$NON-NLS-1$
199             IDialogSettings settings= Activator.getInstance().getDialogSettings();
200             IDialogSettings section= settings.getSection(sectionName);
201             if (section == null)
202                 section= settings.addNewSection(sectionName);
203             return section;
204         }
205
206         @Override
207         protected int getDialogBoundsStrategy() {
208             return DIALOG_PERSISTLOCATION;
209         }
210     }
211
212 }