From 5747d0df198d3b3de66c51796369a7f6af314ea7 Mon Sep 17 00:00:00 2001 From: jsimomaa Date: Fri, 13 Jan 2017 15:19:53 +0200 Subject: [PATCH] Implement district features to Simantics platform * Fix picking to pick vertex before edge * Do not create new vertices if one already exists (need to configure the picking threshold though) * Add visual aids to drawing before the drawing is persisted to db Change-Id: I7e1a59e032fcd47f75bd576c96ea3214ba172969 --- .../META-INF/MANIFEST.MF | 3 +- .../district/network/ui/DNEdgeBuilder.java | 173 +++++---- .../network/ui/DistrictDiagramViewer.java | 78 ++-- .../ui/nodes/DistrictNetworkEdgeNode.java | 189 +++++----- .../ui/nodes/DistrictNetworkVertexNode.java | 137 ++++--- .../network/ui/nodes/NetworkDrawingNode.java | 343 ++++++++++-------- .../ui/participants/DNPointerInteractor.java | 78 ++-- .../ui/participants/DNTranslateMode.java | 165 +++++---- org.simantics.district.ui.feature/feature.xml | 95 ++--- 9 files changed, 703 insertions(+), 558 deletions(-) diff --git a/org.simantics.district.network.ui/META-INF/MANIFEST.MF b/org.simantics.district.network.ui/META-INF/MANIFEST.MF index 267a0dd0..1a7ea47d 100644 --- a/org.simantics.district.network.ui/META-INF/MANIFEST.MF +++ b/org.simantics.district.network.ui/META-INF/MANIFEST.MF @@ -14,7 +14,8 @@ Require-Bundle: org.eclipse.e4.ui.model.workbench;bundle-version="1.1.100.v20150 org.simantics.district.network.ontology, org.simantics.utils.datastructures, org.simantics.district.network;bundle-version="1.0.0", - org.simantics.layer0.utils + org.simantics.layer0.utils, + org.simantics.district.maps Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Export-Package: org.simantics.district.network.ui.adapters Bundle-ActivationPolicy: lazy diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DNEdgeBuilder.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DNEdgeBuilder.java index b9b73e54..687ca337 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DNEdgeBuilder.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DNEdgeBuilder.java @@ -1,80 +1,93 @@ -package org.simantics.district.network.ui; - -import org.simantics.db.Resource; -import org.simantics.db.WriteGraph; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.exception.ServiceException; -import org.simantics.db.layer0.util.Layer0Utils; -import org.simantics.diagram.synchronization.IModifiableSynchronizationContext; -import org.simantics.diagram.synchronization.SynchronizationHints; -import org.simantics.diagram.synchronization.graph.AddElement; -import org.simantics.diagram.synchronization.graph.GraphSynchronizationHints; -import org.simantics.diagram.synchronization.graph.layer.GraphLayer; -import org.simantics.diagram.synchronization.graph.layer.GraphLayerManager; -import org.simantics.diagram.ui.DiagramModelHints; -import org.simantics.district.network.DistrictNetworkUtil; -import org.simantics.district.network.ontology.DistrictNetworkResource; -import org.simantics.g2d.diagram.IDiagram; - -public class DNEdgeBuilder { - - private Resource diagramResource; - private IDiagram diagram; - private GraphLayerManager glm; - - public DNEdgeBuilder(Resource diagramResource, IDiagram diagram) { - this.diagramResource = diagramResource; - this.diagram = diagram; - - IModifiableSynchronizationContext context = diagram.getHint(SynchronizationHints.CONTEXT); - glm = context.get(GraphSynchronizationHints.GRAPH_LAYER_MANAGER); - } - - public void create(WriteGraph graph, double[] start, double[] end) throws DatabaseException { - - DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); - - // 1. Get diagram edge to construct - Resource edge = getOrCreateEdge(graph); - - // 1.1 Give running name to connection and increment the counter attached to the diagram. - AddElement.claimFreshElementName(graph, diagramResource, edge); - - // 2. Add vertices - Resource startVertex = getOrCreateVertex(graph, start); - Resource endVertex = getOrCreateVertex(graph, end); - - graph.claim(edge, DN.HasStartVertex, startVertex); - graph.claim(edge, DN.HasEndVertex, endVertex); - - // 7. Put the element on all the currently active layers if possible. - if (glm != null) { - putOnActiveLayer(graph, edge); - putOnActiveLayer(graph, startVertex); - putOnActiveLayer(graph, endVertex); - } - - Layer0Utils.addCommentMetadata(graph, "Added edge " + edge); - graph.markUndoPoint(); - } - - private void putOnActiveLayer(WriteGraph graph, Resource res) throws DatabaseException { - glm.removeFromAllLayers(graph, res); - glm.putElementOnVisibleLayers(diagram, graph, res); - } - - private Resource getOrCreateVertex(WriteGraph graph, double[] coords) throws DatabaseException { - // TODO: check if vertex exists already, for now create always new - Resource vertex = null; - if (vertex == null) { - vertex = DistrictNetworkUtil.createVertex(graph, diagramResource, coords); - AddElement.claimFreshElementName(graph, diagramResource, vertex); - } - return vertex; - } - - private Resource getOrCreateEdge(WriteGraph graph) throws DatabaseException { - return DistrictNetworkUtil.createEdge(graph, diagramResource); - } - -} +package org.simantics.district.network.ui; + +import java.awt.geom.Rectangle2D; +import java.util.Collection; + +import org.simantics.databoard.Bindings; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.Layer0Utils; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.diagram.synchronization.IModifiableSynchronizationContext; +import org.simantics.diagram.synchronization.SynchronizationHints; +import org.simantics.diagram.synchronization.graph.AddElement; +import org.simantics.diagram.synchronization.graph.GraphSynchronizationHints; +import org.simantics.diagram.synchronization.graph.layer.GraphLayerManager; +import org.simantics.district.network.DistrictNetworkUtil; +import org.simantics.district.network.ontology.DistrictNetworkResource; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.layer0.Layer0; + +public class DNEdgeBuilder { + + private Resource diagramResource; + private IDiagram diagram; + private GraphLayerManager glm; + + public DNEdgeBuilder(Resource diagramResource, IDiagram diagram) { + this.diagramResource = diagramResource; + this.diagram = diagram; + + IModifiableSynchronizationContext context = diagram.getHint(SynchronizationHints.CONTEXT); + glm = context.get(GraphSynchronizationHints.GRAPH_LAYER_MANAGER); + } + + public void create(WriteGraph graph, double[] start, double[] end) throws DatabaseException { + + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + + // 1. Get diagram edge to construct + Resource edge = getOrCreateEdge(graph); + + // 1.1 Give running name to connection and increment the counter attached to the diagram. + AddElement.claimFreshElementName(graph, diagramResource, edge); + + // 2. Add vertices + Collection vertices = graph.syncRequest(new ObjectsWithType(diagramResource, Layer0.getInstance(graph).ConsistsOf, DistrictNetworkResource.getInstance(graph).Vertex)); + Resource startVertex = getOrCreateVertex(graph, vertices, start); + Resource endVertex = getOrCreateVertex(graph, vertices, end); + + graph.claim(edge, DN.HasStartVertex, startVertex); + graph.claim(edge, DN.HasEndVertex, endVertex); + + // 7. Put the element on all the currently active layers if possible. + if (glm != null) { + putOnActiveLayer(graph, edge); + putOnActiveLayer(graph, startVertex); + putOnActiveLayer(graph, endVertex); + } + + Layer0Utils.addCommentMetadata(graph, "Added edge " + edge); + graph.markUndoPoint(); + } + + private void putOnActiveLayer(WriteGraph graph, Resource res) throws DatabaseException { + glm.removeFromAllLayers(graph, res); + glm.putElementOnVisibleLayers(diagram, graph, res); + } + + private Resource getOrCreateVertex(WriteGraph graph, Collection vertices, double[] coords) throws DatabaseException { + Resource vertex = null; + for (Resource vertx : vertices) { + double[] existingCoords = graph.getRelatedValue2(vertx, DiagramResource.getInstance(graph).HasLocation, Bindings.DOUBLE_ARRAY); + Rectangle2D existing = new Rectangle2D.Double(existingCoords[0], existingCoords[1], 1, 1); + Rectangle2D tobecreated = new Rectangle2D.Double(coords[0], coords[1], 1, 1); + if (existing.intersects(tobecreated)) { + vertex = vertx; + break; + } + } + if (vertex == null) { + vertex = DistrictNetworkUtil.createVertex(graph, diagramResource, coords); + AddElement.claimFreshElementName(graph, diagramResource, vertex); + } + return vertex; + } + + private Resource getOrCreateEdge(WriteGraph graph) throws DatabaseException { + return DistrictNetworkUtil.createEdge(graph, diagramResource); + } + +} diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictDiagramViewer.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictDiagramViewer.java index 9acad52c..5155ccd2 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictDiagramViewer.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictDiagramViewer.java @@ -1,32 +1,46 @@ -package org.simantics.district.network.ui; - -import java.util.concurrent.TimeUnit; - -import org.simantics.district.network.ui.participants.DNPointerInteractor; -import org.simantics.g2d.canvas.ICanvasContext; -import org.simantics.g2d.diagram.handler.PickRequest.PickFilter; -import org.simantics.g2d.diagram.participant.DelayedBatchElementPainter; -import org.simantics.g2d.diagram.participant.ElementPainter; -import org.simantics.g2d.diagram.participant.Selection; -import org.simantics.g2d.diagram.participant.ZOrderHandler; -import org.simantics.g2d.participant.RenderingQualityInteractor; -import org.simantics.modeling.ui.diagramEditor.DiagramViewer; - -public class DistrictDiagramViewer extends DiagramViewer { - - @Override - protected void addDiagramParticipants(ICanvasContext ctx) { - ctx.add(new ZOrderHandler()); - ctx.add(new Selection()); - ctx.add(new ElementPainter()); - ctx.add(new DNPointerInteractor()); - - ctx.add(new NetworkDrawingParticipant()); - } - - @Override - protected void addPainterParticipants(ICanvasContext ctx) { - ctx.add(new RenderingQualityInteractor()); - ctx.add(new DelayedBatchElementPainter(PickFilter.FILTER_MONITORS, 500, TimeUnit.MILLISECONDS)); - } -} +package org.simantics.district.network.ui; + +import java.util.concurrent.TimeUnit; + +import org.simantics.district.network.ui.participants.DNPointerInteractor; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.canvas.impl.CanvasContext; +import org.simantics.g2d.diagram.handler.PickRequest.PickFilter; +import org.simantics.g2d.diagram.participant.DelayedBatchElementPainter; +import org.simantics.g2d.diagram.participant.ElementPainter; +import org.simantics.g2d.diagram.participant.Selection; +import org.simantics.g2d.diagram.participant.ZOrderHandler; +import org.simantics.g2d.participant.PanZoomRotateHandler; +import org.simantics.g2d.participant.RenderingQualityInteractor; +import org.simantics.maps.eclipse.MapPainter; +import org.simantics.modeling.ui.diagramEditor.DiagramViewer; +import org.simantics.utils.datastructures.hints.IHintContext; + +public class DistrictDiagramViewer extends DiagramViewer { + + @Override + protected void addDiagramParticipants(ICanvasContext ctx) { + ctx.add(new ZOrderHandler()); + ctx.add(new Selection()); + ctx.add(new ElementPainter()); + ctx.add(new DNPointerInteractor()); + + ctx.add(new MapPainter(100000)); + + ctx.add(new NetworkDrawingParticipant()); + } + + @Override + public void initializeCanvasContext(CanvasContext ctx) { + super.initializeCanvasContext(ctx); + IHintContext h = ctx.getDefaultHintContext(); + h.setHint(PanZoomRotateHandler.KEY_ZOOM_IN_LIMIT, 10000.0); + h.setHint(PanZoomRotateHandler.KEY_ZOOM_OUT_LIMIT, 0.01); + } + + @Override + protected void addPainterParticipants(ICanvasContext ctx) { + ctx.add(new RenderingQualityInteractor()); + ctx.add(new DelayedBatchElementPainter(PickFilter.FILTER_MONITORS, 500, TimeUnit.MILLISECONDS)); + } +} diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeNode.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeNode.java index eb1d26eb..4abeee8b 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeNode.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeNode.java @@ -1,86 +1,103 @@ -package org.simantics.district.network.ui.nodes; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.Shape; -import java.awt.Stroke; -import java.awt.geom.AffineTransform; -import java.awt.geom.Path2D; -import java.awt.geom.Rectangle2D; - -import org.simantics.district.network.ui.DistrictNetworkEdge; -import org.simantics.scenegraph.g2d.G2DNode; -import org.simantics.scenegraph.utils.NodeUtil; - -public class DistrictNetworkEdgeNode extends G2DNode { - - private static final long serialVersionUID = 8049769475036519806L; - - private static final Stroke SELECTION_STROKE = new BasicStroke(1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); - private static final Color SELECTION_COLOR = new Color(255, 0, 255, 96); - - private DistrictNetworkEdge edge; - private Rectangle2D bounds; - - @Override - public void render(Graphics2D g2d) { - - AffineTransform ot = null; - AffineTransform t = getTransform(); - if (t != null && !t.isIdentity()) { - ot = g2d.getTransform(); - g2d.transform(getTransform()); - } - - Object aaHint = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING); - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); - - Color oldColor = g2d.getColor(); -// boolean selected = isSelected(); -// if (selected) { -// Path2D selectionPath = edge.getPath(); -// Shape selectionShape = SELECTION_STROKE.createStrokedShape(selectionPath); -// g2d.setColor(SELECTION_COLOR); -// g2d.fill(selectionShape); -// } -// - g2d.setColor(Color.BLUE); - // render - g2d.draw(edge.getPath()); - - // Reset - g2d.setColor(oldColor); - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint); - - if (ot != null) - g2d.setTransform(ot); - } - - private boolean isSelected() { - return NodeUtil.isSelected(this, 1); - } - - @Override - public Rectangle2D getBoundsInLocal() { - return bounds; - } - - private void updateBounds() { - Rectangle2D oldBounds = bounds; - if (oldBounds == null) - oldBounds = new Rectangle2D.Double(); - bounds = calculateBounds(oldBounds); - } - - private Rectangle2D calculateBounds(Rectangle2D rect) { - return edge.getBounds(rect); - } - - public void setDNEdge(DistrictNetworkEdge edge) { - this.edge = edge; - updateBounds(); - } - -} +package org.simantics.district.network.ui.nodes; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.Stroke; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; + +import org.simantics.district.network.ui.DistrictNetworkEdge; +import org.simantics.scenegraph.g2d.G2DNode; +import org.simantics.scenegraph.utils.GeometryUtils; +import org.simantics.scenegraph.utils.NodeUtil; + +public class DistrictNetworkEdgeNode extends G2DNode { + + private static final long serialVersionUID = 8049769475036519806L; + + private static final Stroke SELECTION_STROKE = new BasicStroke(1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); + private static final Color SELECTION_COLOR = new Color(255, 0, 255, 96); + + private DistrictNetworkEdge edge; + private Rectangle2D bounds; + + private Stroke stroke = new BasicStroke(2); + private boolean scaleStroke = true; + + @Override + public void init() { + + } + + @Override + public void render(Graphics2D g2d) { + + AffineTransform ot = null; + AffineTransform t = getTransform(); + if (t != null && !t.isIdentity()) { + ot = g2d.getTransform(); + g2d.transform(getTransform()); + } + + Object aaHint = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + + Color oldColor = g2d.getColor(); + BasicStroke oldStroke = (BasicStroke) g2d.getStroke(); +// boolean selected = isSelected(); +// if (selected) { +// Path2D selectionPath = edge.getPath(); +// Shape selectionShape = SELECTION_STROKE.createStrokedShape(selectionPath); +// g2d.setColor(SELECTION_COLOR); +// g2d.fill(selectionShape); +// } +// + g2d.setColor(Color.BLUE); + if (stroke != null) { + if (scaleStroke && stroke instanceof BasicStroke) { + BasicStroke bs = GeometryUtils.scaleStroke(stroke, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform()))); + g2d.setStroke(bs); + } else { + g2d.setStroke(stroke); + } + } + // render + g2d.draw(edge.getPath()); + + // Reset + g2d.setStroke(oldStroke); + g2d.setColor(oldColor); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint); + + if (ot != null) + g2d.setTransform(ot); + } + + private boolean isSelected() { + return NodeUtil.isSelected(this, 1); + } + + @Override + public Rectangle2D getBoundsInLocal() { + return bounds; + } + + private void updateBounds() { + Rectangle2D oldBounds = bounds; + if (oldBounds == null) + oldBounds = new Rectangle2D.Double(); + bounds = calculateBounds(oldBounds); + } + + private Rectangle2D calculateBounds(Rectangle2D rect) { + return edge.getBounds(rect); + } + + public void setDNEdge(DistrictNetworkEdge edge) { + this.edge = edge; + updateBounds(); + } + +} diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java index 7365060b..a126ee59 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java @@ -1,54 +1,83 @@ -package org.simantics.district.network.ui.nodes; - -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; - -import org.simantics.district.network.ui.adapters.DistrictNetworkVertex; -import org.simantics.scenegraph.g2d.G2DNode; - -public class DistrictNetworkVertexNode extends G2DNode { - - private static final long serialVersionUID = -2641639101400236719L; - private DistrictNetworkVertex vertex; - - @Override - public void render(Graphics2D g2d) { - AffineTransform ot = null; - AffineTransform t = getTransform(); - if (t != null && !t.isIdentity()) { - ot = g2d.getTransform(); - g2d.transform(getTransform()); - } - - Object aaHint = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING); - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); - - Color oldColor = g2d.getColor(); - g2d.setColor(Color.RED); - // render - - Rectangle2D.Double rect = new Rectangle2D.Double(-0.5, -0.5, 1, 1); - g2d.draw(rect); - - // Reset stats - g2d.setColor(oldColor); - - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint); - - if (ot != null) - g2d.setTransform(ot); - } - - @Override - public Rectangle2D getBoundsInLocal() { - return new Rectangle2D.Double(-0.5, -0.5, 1, 1); - } - - public void setVertex(DistrictNetworkVertex vertex) { - this.vertex = vertex; - } - -} +package org.simantics.district.network.ui.nodes; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.Stroke; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; + +import org.simantics.district.network.ui.adapters.DistrictNetworkVertex; +import org.simantics.scenegraph.g2d.G2DNode; +import org.simantics.scenegraph.utils.GeometryUtils; + +public class DistrictNetworkVertexNode extends G2DNode { + + private static final long serialVersionUID = -2641639101400236719L; + private DistrictNetworkVertex vertex; + + private static final double scale = 1; + + private double left = -0.5; + private double top = -0.5; + private double width = 1; + private double height = 1; + + private Stroke stroke = new BasicStroke(2); + private boolean scaleStroke = true; + + @Override + public void init() { + setZIndex(2); + } + + @Override + public void render(Graphics2D g2d) { + AffineTransform ot = null; + AffineTransform t = getTransform(); + if (t != null && !t.isIdentity()) { + ot = g2d.getTransform(); + g2d.transform(getTransform()); + } + + Object aaHint = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + + Color oldColor = g2d.getColor(); + Stroke oldStroke = g2d.getStroke(); + + g2d.setColor(Color.RED); + if (stroke != null) { + if (scaleStroke && stroke instanceof BasicStroke) { + BasicStroke bs = GeometryUtils.scaleStroke(stroke, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform()))); + g2d.setStroke(bs); + } else { + g2d.setStroke(stroke); + } + } + // render + + Rectangle2D.Double rect = new Rectangle2D.Double(left / scale, top / scale, width / scale, height / scale); + g2d.draw(rect); + + // Reset stats + g2d.setColor(oldColor); + g2d.setStroke(oldStroke); + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint); + + if (ot != null) + g2d.setTransform(ot); + } + + @Override + public Rectangle2D getBoundsInLocal() { + return new Rectangle2D.Double(left / scale, top / scale, width / scale, height / scale); + } + + public void setVertex(DistrictNetworkVertex vertex) { + this.vertex = vertex; + } + +} diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/NetworkDrawingNode.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/NetworkDrawingNode.java index 48629427..a9c96e9b 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/NetworkDrawingNode.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/NetworkDrawingNode.java @@ -1,157 +1,188 @@ -package org.simantics.district.network.ui.nodes; - -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.geom.Path2D; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.simantics.Simantics; -import org.simantics.db.Resource; -import org.simantics.db.WriteGraph; -import org.simantics.db.common.request.WriteRequest; -import org.simantics.db.exception.DatabaseException; -import org.simantics.diagram.ui.DiagramModelHints; -import org.simantics.district.network.ui.DNEdgeBuilder; -import org.simantics.district.network.ui.NetworkDrawingParticipant; -import org.simantics.g2d.canvas.Hints; -import org.simantics.g2d.canvas.IToolMode; -import org.simantics.g2d.diagram.IDiagram; -import org.simantics.scenegraph.g2d.G2DNode; -import org.simantics.scenegraph.g2d.events.EventTypes; -import org.simantics.scenegraph.g2d.events.MouseEvent; -import org.simantics.scenegraph.g2d.events.MouseEvent.MouseClickEvent; -import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDoubleClickedEvent; -import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent; -import org.simantics.scenegraph.utils.NodeUtil; - -public class NetworkDrawingNode extends G2DNode { - - private static final long serialVersionUID = -3475301184009620573L; - - private List nodes = new ArrayList<>(); - - private Rectangle2D rect = new Rectangle2D.Double(10, 10, 10, 10); - - private Set paths = new HashSet<>(); - - private Resource diagramResource; - - private boolean committed; - - private NetworkDrawingParticipant participant; - - private IDiagram diagram; - - @Override - public void init() { - super.init(); - addEventHandler(this); - } - - public void setNetworkDrawingParticipant(NetworkDrawingParticipant participant) { - this.participant = participant; - } - - public void setDiagram(IDiagram diagram) { - if (diagram != null) { - this.diagram = diagram; - this.diagramResource = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE); - } - } - - @Override - public void render(Graphics2D g2d) { - Color old = g2d.getColor(); - g2d.setColor(Color.BLUE); - - paths.forEach(p -> { - g2d.draw(p); - }); - - g2d.setColor(old); - } - - @Override - public Rectangle2D getBoundsInLocal() { - return rect.getBounds2D(); - } - - @Override - public int getEventMask() { - return EventTypes.MouseMask; - } - - @Override - protected boolean mouseDoubleClicked(MouseDoubleClickedEvent e) { - // nodes to path2d - IToolMode mode = getToolMode(); - if (mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK)) { - Point2D start = null; - Point2D end = null; - Iterator nodeIter = nodes.iterator(); - while (nodeIter.hasNext()) { - if (end == null) { - start = nodeIter.next(); - } else { - start = end; - } - end = nodeIter.next(); - - createEdge(start, end); - } - - nodes.clear(); - committed = true; - - repaint(); - - return true; - } - return super.mouseDoubleClicked(e); - } - - private void createEdge(Point2D start, Point2D end) { - double[] startCoords = new double[] { start.getX(), start.getY() }; - double[] endCoords = new double[] { end.getX(), end.getY() }; - - DNEdgeBuilder builder = new DNEdgeBuilder(diagramResource, diagram); - Simantics.getSession().asyncRequest(new WriteRequest() { - - @Override - public void perform(WriteGraph graph) throws DatabaseException { - builder.create(graph, startCoords, endCoords); - } - }); - - } - - @Override - protected boolean mouseClicked(MouseClickEvent e) { - // check ToolMode - IToolMode mode = getToolMode(); - if (mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK)) { - if (committed) { - committed = false; - return false; - } - Point2D localPos = NodeUtil.worldToLocal(this, e.controlPosition, new Point2D.Double()); - nodes.add(new Point2D.Double(localPos.getX(), localPos.getY())); - } - return super.mouseClicked(e); - } - - private IToolMode getToolMode() { - return participant.getHint(Hints.KEY_TOOL); - } - - @Override - protected boolean mouseMoved(MouseMovedEvent e) { - return super.mouseMoved(e); - } +package org.simantics.district.network.ui.nodes; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Stroke; +import java.awt.geom.Path2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.simantics.Simantics; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.ui.DiagramModelHints; +import org.simantics.district.network.ui.DNEdgeBuilder; +import org.simantics.district.network.ui.NetworkDrawingParticipant; +import org.simantics.g2d.canvas.Hints; +import org.simantics.g2d.canvas.IToolMode; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.scenegraph.g2d.G2DNode; +import org.simantics.scenegraph.g2d.events.EventTypes; +import org.simantics.scenegraph.g2d.events.MouseEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseClickEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDoubleClickedEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent; +import org.simantics.scenegraph.utils.GeometryUtils; +import org.simantics.scenegraph.utils.NodeUtil; + +public class NetworkDrawingNode extends G2DNode { + + private static final long serialVersionUID = -3475301184009620573L; + + private List nodes = new ArrayList<>(); + + private Resource diagramResource; + + private boolean committed; + + private NetworkDrawingParticipant participant; + + private IDiagram diagram; + + private static final Stroke DASHED_STROKE = new BasicStroke(2.0f, + BasicStroke.CAP_ROUND, + BasicStroke.JOIN_ROUND, + 4.0f, new float[]{4.0f}, 0.0f); + + private static final Color BLUE_ALPHA = new Color(0, 0, 255, 100); + + private boolean scaleStroke = true; + + @Override + public void init() { + super.init(); + addEventHandler(this); + } + + public void setNetworkDrawingParticipant(NetworkDrawingParticipant participant) { + this.participant = participant; + } + + public void setDiagram(IDiagram diagram) { + if (diagram != null) { + this.diagram = diagram; + this.diagramResource = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE); + } + } + + @Override + public void render(Graphics2D g2d) { + + Path2D path = new Path2D.Double(); + Iterator nodeIter = nodes.iterator(); + if (nodeIter.hasNext()) { + Point2D node = nodeIter.next(); + path.moveTo(node.getX(), node.getY()); + } + while (nodeIter.hasNext()) { + Point2D node = nodeIter.next(); + path.lineTo(node.getX(), node.getY()); + } + + Color old = g2d.getColor(); + Stroke oldStroke = g2d.getStroke(); + + if (DASHED_STROKE != null) { + if (scaleStroke && DASHED_STROKE instanceof BasicStroke) { + BasicStroke bs = GeometryUtils.scaleStroke(DASHED_STROKE, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform()))); + g2d.setStroke(bs); + } else { + g2d.setStroke(DASHED_STROKE); + } + } + + g2d.setColor(BLUE_ALPHA); + + g2d.draw(path); + + g2d.setStroke(oldStroke); + g2d.setColor(old); + } + + @Override + public Rectangle2D getBoundsInLocal() { + return null; + } + + @Override + public int getEventMask() { + return EventTypes.MouseMask; + } + + @Override + protected boolean mouseDoubleClicked(MouseDoubleClickedEvent e) { + // nodes to path2d + IToolMode mode = getToolMode(); + if (mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK)) { + Point2D start = null; + Point2D end = null; + Iterator nodeIter = nodes.iterator(); + while (nodeIter.hasNext()) { + if (end == null) { + start = nodeIter.next(); + } else { + start = end; + } + end = nodeIter.next(); + + createEdge(start, end); + } + + nodes.clear(); + committed = true; + + repaint(); + + return true; + } + return super.mouseDoubleClicked(e); + } + + private void createEdge(Point2D start, Point2D end) { + double[] startCoords = new double[] { start.getX(), start.getY() }; + double[] endCoords = new double[] { end.getX(), end.getY() }; + + DNEdgeBuilder builder = new DNEdgeBuilder(diagramResource, diagram); + Simantics.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + builder.create(graph, startCoords, endCoords); + } + }); + + } + + @Override + protected boolean mouseClicked(MouseClickEvent e) { + // check ToolMode + IToolMode mode = getToolMode(); + if (mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK)) { + if (committed) { + committed = false; + return false; + } + Point2D localPos = NodeUtil.worldToLocal(this, e.controlPosition, new Point2D.Double()); + nodes.add(new Point2D.Double(localPos.getX(), localPos.getY())); + + repaint(); + return true; + } + return super.mouseClicked(e); + } + + private IToolMode getToolMode() { + return participant.getHint(Hints.KEY_TOOL); + } + + @Override + protected boolean mouseMoved(MouseMovedEvent e) { + return super.mouseMoved(e); + } } \ No newline at end of file diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/DNPointerInteractor.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/DNPointerInteractor.java index e8b8337b..acb0acac 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/DNPointerInteractor.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/DNPointerInteractor.java @@ -1,22 +1,56 @@ -package org.simantics.district.network.ui.participants; - -import java.awt.geom.Point2D; -import java.util.Set; - -import org.simantics.g2d.canvas.ICanvasParticipant; -import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor; -import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil.TerminalInfo; -import org.simantics.g2d.element.IElement; - -public class DNPointerInteractor extends PointerInteractor { - - @Override - protected ICanvasParticipant createConnectTool(TerminalInfo ti, int mouseId, Point2D startCanvasPos) { - return super.createConnectTool(ti, mouseId, startCanvasPos); - } - - @Override - protected ICanvasParticipant createTranslateTool(int mouseId, Point2D startCanvasPos, Point2D curCanvasPos, Set elementsToDrag) { - return new DNTranslateMode(startCanvasPos, curCanvasPos, mouseId, elementsToDrag); - } -} +package org.simantics.district.network.ui.participants; + +import java.awt.geom.Point2D; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.simantics.district.network.ui.adapters.DistrictNetworkEdgeElement; +import org.simantics.district.network.ui.adapters.DistrictNetworkVertexElement; +import org.simantics.g2d.canvas.ICanvasParticipant; +import org.simantics.g2d.diagram.handler.PickRequest.PickSorter; +import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor; +import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil.TerminalInfo; +import org.simantics.g2d.element.IElement; +import org.simantics.scenegraph.g2d.G2DNode; + +public class DNPointerInteractor extends PointerInteractor { + + private static class DNPickSorter implements PickSorter { + + @Override + public void sort(List elements) { + Collections.sort(elements, (e1, e2) -> { + G2DNode e1node = getNode(e1); + G2DNode e2node = getNode(e2); + if (e1node.getZIndex() < e2node.getZIndex()) + return -1; + else if (e1node.getZIndex() > e2node.getZIndex()) + return 1; + return 0; + }); + } + + private static G2DNode getNode(IElement element) { + G2DNode node = element.getHint(DistrictNetworkEdgeElement.KEY_DN_EDGE_NODE); + if (node == null) + node = element.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE); + return node; + } + } + + public DNPointerInteractor() { + super(new DNPickSorter()); + } + + @Override + protected ICanvasParticipant createConnectTool(TerminalInfo ti, int mouseId, Point2D startCanvasPos) { + return super.createConnectTool(ti, mouseId, startCanvasPos); + } + + @Override + protected ICanvasParticipant createTranslateTool(int mouseId, Point2D startCanvasPos, Point2D curCanvasPos, + Set elementsToDrag) { + return new DNTranslateMode(startCanvasPos, curCanvasPos, mouseId, elementsToDrag); + } +} diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/DNTranslateMode.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/DNTranslateMode.java index 74a46475..7d8af3d6 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/DNTranslateMode.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/DNTranslateMode.java @@ -1,83 +1,82 @@ -package org.simantics.district.network.ui.participants; - -import java.awt.geom.AffineTransform; -import java.awt.geom.Point2D; -import java.util.ArrayList; -import java.util.Collection; - -import org.simantics.Simantics; -import org.simantics.db.Resource; -import org.simantics.db.WriteGraph; -import org.simantics.db.common.CommentMetadata; -import org.simantics.db.common.request.WriteRequest; -import org.simantics.db.exception.DatabaseException; -import org.simantics.diagram.elements.ElementTransforms; -import org.simantics.diagram.elements.ElementTransforms.TransformedObject; -import org.simantics.diagram.stubs.DiagramResource; -import org.simantics.district.network.ontology.DistrictNetworkResource; -import org.simantics.g2d.canvas.Hints; -import org.simantics.g2d.diagram.participant.pointertool.TranslateMode; -import org.simantics.g2d.element.ElementUtils; -import org.simantics.g2d.element.IElement; -import org.simantics.g2d.element.handler.Move; - -public class DNTranslateMode extends TranslateMode { - - public DNTranslateMode(Point2D startingPoint, Point2D currentPoint, int mouseId, Collection elements) { - super(startingPoint, currentPoint, mouseId, elements); - } - - @Override - protected boolean commit() { - for (IElement el : elementsToReallyTranslate) { - Move move = el.getElementClass().getAtMostOneItemOfClass(Move.class); - if (move != null) { - Point2D oldPos = move.getPosition(el); - move.moveTo(el, oldPos.getX() + dx, oldPos.getY() + dy); - } - } - try { - Simantics.getSession().syncRequest(new WriteRequest() { - @Override - public void perform(WriteGraph graph) throws DatabaseException { - Collection transformed = new ArrayList(); - DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); - DiagramResource DIA = DiagramResource.getInstance(graph); - for (IElement e : elementsToReallyTranslate) { - Object obj = ElementUtils.getObject(e); - if (obj instanceof Resource) { - Resource res = (Resource) obj; - if (graph.isInstanceOf(res, DN.Vertex)) { - AffineTransform at = ElementUtils.getLocalTransform(e, new AffineTransform()); - transformed.add( new TransformedObject((Resource) obj, at) ); - - - // write to db - double[] coords = new double[] { at.getTranslateX(), at.getTranslateY() }; - graph.claimLiteral(res, DIA.HasLocation, coords); - } - } - } - - if (!transformed.isEmpty()) { - CommentMetadata cm = graph.getMetadata(CommentMetadata.class); - graph.addMetadata(cm.add("Translated " + transformed.size() + " " - + (transformed.size() == 1 ? "element" : "elements") - + " by (" + dx + "," + dy + ") mm.")); - graph.markUndoPoint(); - } - } - }); - } catch (DatabaseException e) { - e.printStackTrace(); - } - - for (IElement dirty : elementsToDirty) - dirty.setHint(Hints.KEY_DIRTY, Hints.VALUE_SG_DIRTY); - - setDirty(); - remove(); - return false; - } - -} +package org.simantics.district.network.ui.participants; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.Simantics; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.CommentMetadata; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.elements.ElementTransforms.TransformedObject; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.district.network.ontology.DistrictNetworkResource; +import org.simantics.g2d.canvas.Hints; +import org.simantics.g2d.diagram.participant.pointertool.TranslateMode; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.Move; + +public class DNTranslateMode extends TranslateMode { + + public DNTranslateMode(Point2D startingPoint, Point2D currentPoint, int mouseId, Collection elements) { + super(startingPoint, currentPoint, mouseId, elements); + } + + @Override + protected boolean commit() { + for (IElement el : elementsToReallyTranslate) { + Move move = el.getElementClass().getAtMostOneItemOfClass(Move.class); + if (move != null) { + Point2D oldPos = move.getPosition(el); + move.moveTo(el, oldPos.getX() + dx, oldPos.getY() + dy); + } + } + try { + Simantics.getSession().syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Collection transformed = new ArrayList(); + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + DiagramResource DIA = DiagramResource.getInstance(graph); + for (IElement e : elementsToReallyTranslate) { + Object obj = ElementUtils.getObject(e); + if (obj instanceof Resource) { + Resource res = (Resource) obj; + if (graph.isInstanceOf(res, DN.Vertex)) { + AffineTransform at = ElementUtils.getLocalTransform(e, new AffineTransform()); + transformed.add( new TransformedObject((Resource) obj, at) ); + + + // write to db + double[] coords = new double[] { at.getTranslateX(), at.getTranslateY() }; + graph.claimLiteral(res, DIA.HasLocation, coords); + } + } + } + + if (!transformed.isEmpty()) { + CommentMetadata cm = graph.getMetadata(CommentMetadata.class); + graph.addMetadata(cm.add("Translated " + transformed.size() + " " + + (transformed.size() == 1 ? "element" : "elements") + + " by (" + dx + "," + dy + ") mm.")); + graph.markUndoPoint(); + } + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + for (IElement dirty : elementsToDirty) + dirty.setHint(Hints.KEY_DIRTY, Hints.VALUE_SG_DIRTY); + + setDirty(); + remove(); + return false; + } + +} diff --git a/org.simantics.district.ui.feature/feature.xml b/org.simantics.district.ui.feature/feature.xml index 8faefe0e..8e0633e8 100644 --- a/org.simantics.district.ui.feature/feature.xml +++ b/org.simantics.district.ui.feature/feature.xml @@ -1,44 +1,51 @@ - - - - - [Enter Feature Description here.] - - - - [Enter Copyright Description here.] - - - - [Enter License Description here.] - - - - - - - - - - - + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + + + + + + + -- 2.47.1