]> gerrit.simantics Code Review - simantics/district.git/blobdiff - org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/RoutingMode.java
Merge "Initial version of the district network Routes view."
[simantics/district.git] / org.simantics.district.network.ui / src / org / simantics / district / network / ui / participants / RoutingMode.java
diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/RoutingMode.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/RoutingMode.java
new file mode 100644 (file)
index 0000000..d274a61
--- /dev/null
@@ -0,0 +1,212 @@
+package org.simantics.district.network.ui.participants;
+
+import java.awt.AlphaComposite;
+import java.awt.Cursor;
+import java.util.Collection;
+
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.simantics.db.Resource;
+import org.simantics.diagram.ui.DiagramModelHints;
+import org.simantics.district.network.ui.internal.Activator;
+import org.simantics.district.route.Route;
+import org.simantics.district.route.RouteService;
+import org.simantics.district.route.Waypoint;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.canvas.IMouseCursorContext;
+import org.simantics.g2d.canvas.IMouseCursorHandle;
+import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
+import org.simantics.g2d.canvas.impl.HintReflection.HintListener;
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup;
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
+import org.simantics.g2d.diagram.handler.PickContext;
+import org.simantics.g2d.diagram.participant.Selection;
+import org.simantics.g2d.diagram.participant.pointertool.AbstractMode;
+import org.simantics.g2d.element.ElementUtils;
+import org.simantics.g2d.element.IElement;
+import org.simantics.g2d.participant.TransformUtil;
+import org.simantics.scenegraph.g2d.G2DParentNode;
+import org.simantics.scenegraph.g2d.events.Event;
+import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
+import org.simantics.scenegraph.g2d.events.KeyEvent.KeyPressedEvent;
+import org.simantics.scenegraph.g2d.events.command.Command;
+import org.simantics.scenegraph.g2d.events.command.CommandEvent;
+import org.simantics.scenegraph.g2d.events.command.Commands;
+import org.simantics.scenegraph.g2d.nodes.SingleElementNode;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+import org.simantics.utils.datastructures.hints.IHintObservable;
+import org.simantics.utils.ui.AdaptionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This participant creates routes on district network diagrams using
+ * {@link RouteService}.
+ *
+ * @author Tuukka Lehtonen
+ * @since 6.09
+ */
+public class RoutingMode extends AbstractMode {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(RoutingMode.class);
+
+    @Dependency
+    protected TransformUtil        util;
+
+    @Dependency
+    protected PickContext          pickContext;
+
+    @Dependency
+    protected Selection            selection;
+
+    protected IMouseCursorHandle   cursor;
+
+    private RouteService           routeService;
+
+    private Route                  route;
+
+    /**
+     * The node under which the mutated diagram is ghosted in the scene graph.
+     */
+    protected G2DParentNode        parent;
+
+    /**
+     * This stays null until the translated diagram parts have been initialized
+     * into the scene graph. After that, only the translations of the nodes in
+     * the scene graph are modified.
+     */
+    protected SingleElementNode    node = null;
+
+    public RoutingMode(int mouseId) {
+        super(mouseId);
+    }
+
+    @Override
+    public void addedToContext(ICanvasContext ctx) {
+        super.addedToContext(ctx);
+        IMouseCursorContext mcc = getContext().getMouseCursorContext();
+        cursor = mcc == null ? null : mcc.setCursor(mouseId, new Cursor(Cursor.CROSSHAIR_CURSOR));
+        routeService = Activator.getInstance().getRouteService();
+        if (routeService != null) {
+            Resource diagramResource = getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE);
+            LOGGER.info("Diagram resource: " + diagramResource);
+            route = routeService.createRoute("Current", diagramResource);
+            routeService.registerRoute(route);
+        }
+    }
+
+    @Override
+    public void removedFromContext(ICanvasContext ctx) {
+        if (cursor != null) {
+            cursor.remove();
+            cursor = null;
+        }
+        // Discard route if it hasn't been persisted before this
+        if (route != null) {
+            routeService.discardRoute(route);
+            route = null;
+            routeService = null;
+        }
+        super.removedFromContext(ctx);
+    }
+
+    @HintListener(Class = Selection.class, Field = "SELECTION0")
+    public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
+        Collection<IElement> elements = AdaptionUtils.adaptToCollection(newValue, IElement.class);
+        for (IElement element : elements) {
+            addRoutePoint(element);
+        }
+    }
+
+    private void addRoutePoint(IElement element) {
+        if (route == null)
+            return;
+
+        Object o = ElementUtils.getObject(element);
+        if (o instanceof Resource) {
+            Waypoint wp = route.createWaypoint(o);
+            route.addWaypoint(wp);
+        }
+    }
+
+    @SGInit
+    public void initSG(G2DParentNode parent) {
+        this.parent = parent;
+        node = parent.addNode("route highlight", SingleElementNode.class);
+        node.setZIndex(1000);
+        node.setVisible(Boolean.TRUE);
+        node.setComposite(AlphaComposite.SrcOver.derive(0.75f));
+    }
+
+    @SGCleanup
+    public void cleanupSG() {
+        if (node != null) {
+            node.remove();
+            node = null;
+        }
+        parent = null;
+    }
+
+    @EventHandler(priority = 30)
+    public boolean handleEvent(Event e) {
+        if (e instanceof KeyPressedEvent) {
+            if (route == null)
+                return false;
+            KeyPressedEvent kpe = (KeyPressedEvent) e;
+            if (kpe.keyCode == java.awt.event.KeyEvent.VK_ENTER) {
+                routeService.persistRoute(route);
+                route = null;
+                dispose();
+            }
+        } else if (e instanceof CommandEvent) {
+            Command cmd = ((CommandEvent) e).command;
+            if (cmd.equals(Commands.CANCEL)) {
+                return dispose();
+            } else if (cmd.equals(Commands.RENAME)) {
+                InputDialog dialog = new InputDialog(
+                        PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
+                        "Rename Route",
+                        "Route name",
+                        route.getName(),
+                        s -> s.trim().length() > 0 ? null : "Name must be non-empty");
+                if (dialog.open() == Window.OK) {
+                    route.setName(dialog.getValue());
+                }
+            }
+        }
+        return false;
+    }
+
+    protected boolean dispose() {
+        setDirty();
+        remove();
+        return false;
+    }
+
+    static class RenameDialog extends InputDialog {
+
+        public RenameDialog(Shell parent, String title, String message, String initialValue, IInputValidator validator) {
+            super(parent, title, message, initialValue, validator);
+        }
+
+        @Override
+        protected IDialogSettings getDialogBoundsSettings() {
+            String sectionName = getClass().getName() + "_dialogBounds"; //$NON-NLS-1$
+            IDialogSettings settings= Activator.getInstance().getDialogSettings();
+            IDialogSettings section= settings.getSection(sectionName);
+            if (section == null)
+                section= settings.addNewSection(sectionName);
+            return section;
+        }
+
+        @Override
+        protected int getDialogBoundsStrategy() {
+            return DIALOG_PERSISTLOCATION;
+        }
+    }
+
+}