From a5b9e41a321cfb5a2c57a07d865ace767f9023cd Mon Sep 17 00:00:00 2001 From: Reino Ruusu Date: Mon, 18 Feb 2019 13:10:43 +0200 Subject: [PATCH 01/16] Flipped coordinate axes for network diagrams in import wizard. gitlab #3 Change-Id: I36b5f67821079d91f7f75d3dc9bda79d83149c8e --- .../district/imports/ui/CSVImportWizard.java | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizard.java b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizard.java index 490c9505..54a578dd 100644 --- a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizard.java +++ b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizard.java @@ -176,6 +176,10 @@ public class CSVImportWizard extends Wizard implements IImportWizard { } else { coords = new double[] { xCoord, yCoord }; } + + // Switch to (longitude, latitude) + flipAxes(coords); + Resource vertex = DistrictNetworkUtil.createVertex(graph, model.getParentDiagram(), coords, model.getComponentMappings().get(mappingValue)); writeStringValue(graph, row, idColumn, vertex, DN.HasId); @@ -230,7 +234,11 @@ public class CSVImportWizard extends Wizard implements IImportWizard { startCoords = new double[] { startXCoord , startYCoord }; endCoords = new double[] { endXCoord , endYCoord }; } - + + // Switch to (longitude, latitude) + flipAxes(startCoords); + flipAxes(endCoords); + Resource edge = DNEdgeBuilder.create(graph, vv, model.getParentDiagram(), model.getComponentMappings().get(mappingValue), startCoords, endCoords, padding, true); writeStringValue(graph, row, idColumn, edge, DN.HasId); @@ -267,9 +275,15 @@ public class CSVImportWizard extends Wizard implements IImportWizard { return false; } } - + + private static void flipAxes(double[] coords) { + double tmp = coords[0]; + coords[0] = coords[1]; + coords[1] = tmp; + } + private static void writeValue(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation) throws DatabaseException { - if (index != -1) { + if (index != -1) { String stringValue = row.get(index); if (!stringValue.isEmpty()) { try { -- 2.45.2 From 2445ecb547cda02fa6843478a777b00a7b927c72 Mon Sep 17 00:00:00 2001 From: Reino Ruusu Date: Mon, 18 Feb 2019 18:14:53 +0200 Subject: [PATCH 02/16] Increase baseline size of vertices 10-fold to improve visibility. gitlab #27 Change-Id: Iace3eaab32a06312e094d92b449a2780867fee2f --- .../network/ui/nodes/DistrictNetworkVertexNode.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 d063d48c..10cfa905 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 @@ -77,11 +77,11 @@ public class DistrictNetworkVertexNode extends G2DParentNode implements ISelecti Color newColor = dynamicColor != null ? dynamicColor : color; boolean changeColor = !oldColor.equals(newColor); - double viewScaleRecip = 1; + double viewScaleRecip = 10; if (scaleStroke) { double scale = GeometryUtils.getScale(g2d.getTransform()); scale = Math.max(10000, Math.min(scale, 50000)); - viewScaleRecip = 1.0 / scale; + viewScaleRecip /= scale; } double scaleRecip = viewScaleRecip * nodeSize; @@ -92,7 +92,7 @@ public class DistrictNetworkVertexNode extends G2DParentNode implements ISelecti if (NodeUtil.isSelected(this, 1)) { changeColor = true; g2d.setColor(SELECTION_COLOR); - BasicStroke ss = GeometryUtils.scaleStroke(STROKE, (float) viewScaleRecip*5); + BasicStroke ss = GeometryUtils.scaleStroke(STROKE, (float) (viewScaleRecip*0.5)); g2d.setStroke(ss); g2d.draw(toDraw); } -- 2.45.2 From 131b4e3b018ad0537d38c0aa83dd3e823ebe8e95 Mon Sep 17 00:00:00 2001 From: Reino Ruusu Date: Wed, 20 Feb 2019 19:28:38 +0200 Subject: [PATCH 03/16] Generalization of mapped property accessors for other data types gitlab #27 Change-Id: Id193ae3b4840a74710c6b86e32bfefd7e3fc3a17 --- org.simantics.district.network/scl/Simantics/District.scl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/org.simantics.district.network/scl/Simantics/District.scl b/org.simantics.district.network/scl/Simantics/District.scl index 36dee397..2f46d361 100644 --- a/org.simantics.district.network/scl/Simantics/District.scl +++ b/org.simantics.district.network/scl/Simantics/District.scl @@ -112,14 +112,14 @@ possibleMappedComponentVariable r = match possibleMappedComponent r with """ """ -possibleMappedComponentPropertyValue :: String -> Resource -> Maybe Double +possibleMappedComponentPropertyValue :: Serializable a => Typeable a => String -> Resource -> Maybe a possibleMappedComponentPropertyValue propName r = match possibleMappedComponentVariable r with Nothing -> Nothing Just mv -> possiblePropertyValue mv propName """ """ -mappedComponentPropertyValue :: Double -> String -> Resource -> Double +mappedComponentPropertyValue :: Serializable a => Typeable a => a -> String -> Resource -> a mappedComponentPropertyValue def propName r = match possibleMappedComponentVariable r with Nothing -> def Just mv -> match possiblePropertyValue mv propName with -- 2.45.2 From 5ef17426c5fb415e0e536d70ea870db90938ebe6 Mon Sep 17 00:00:00 2001 From: Reino Ruusu Date: Wed, 20 Feb 2019 19:38:20 +0200 Subject: [PATCH 04/16] Value type of dynamic symbol function to Maybe String Also add caching for symbol functions. gitlab #27 Change-Id: I34ae22e6e1deae57bbf03ced6ba830c52ec74335 --- .../graph/DistrictNetworkProfiles.pgraph | 2 +- .../network/profile/VertexSymbolStyle.java | 58 ++++++++++++++++--- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/org.simantics.district.network.ontology/graph/DistrictNetworkProfiles.pgraph b/org.simantics.district.network.ontology/graph/DistrictNetworkProfiles.pgraph index d3734e63..a5c5cee5 100644 --- a/org.simantics.district.network.ontology/graph/DistrictNetworkProfiles.pgraph +++ b/org.simantics.district.network.ontology/graph/DistrictNetworkProfiles.pgraph @@ -31,4 +31,4 @@ DN.VertexSymbolStyle : DIA.Style DN.HasSymbolFunction L0.Value - ==> "Resource -> String" + ==> "Resource -> Maybe String" diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSymbolStyle.java b/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSymbolStyle.java index 98078f82..96ff4392 100644 --- a/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSymbolStyle.java +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSymbolStyle.java @@ -1,31 +1,50 @@ package org.simantics.district.network.profile; +import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; +import org.simantics.db.common.procedure.adapter.TransientCacheListener; +import org.simantics.db.common.request.ResourceRead; import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.exception.PendingVariableException; import org.simantics.district.network.ontology.DistrictNetworkResource; +import org.simantics.layer0.Layer0; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.g2d.G2DSceneGraph; import org.simantics.scenegraph.g2d.nodes.SingleElementNode; import org.simantics.scenegraph.profile.EvaluationContext; import org.simantics.scenegraph.profile.common.ProfileVariables; import org.simantics.scl.runtime.function.Function; +import org.simantics.scl.runtime.function.FunctionImpl1; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class VertexSymbolStyle extends ThrottledStyleBase { + private static final Logger LOGGER = LoggerFactory.getLogger(VertexSymbolStyle.class); + @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public String calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { - DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); - Resource symbolFunctionResource = graph.getPossibleObject(entry, DN.HasSymbolFunction); - if (symbolFunctionResource == null) - return null; - - Function symbolFunction = (Function) graph.getPossibleValue2(symbolFunctionResource, null); + + Function symbolFunction = getSymbolFunction(graph, entry); if (symbolFunction == null) return null; - return (String) symbolFunction.apply(graph, entry); + try { + return (String) Simantics.applySCLRead(graph, symbolFunction, groupItem); + } catch (PendingVariableException e) { + throw e; + } catch (Exception e) { + LOGGER.error("Getting dynamic symbol for " + groupItem + " (" + graph.getPossibleRelatedValue(groupItem, Layer0.getInstance(graph).HasName) + ") failed", e); + return null; + } + } + + @SuppressWarnings("rawtypes") + protected static Function getSymbolFunction(ReadGraph graph, Resource entry) throws DatabaseException { + // Cache function read for profile entry + return graph.syncRequest(new SymbolFunctionRequest(entry), TransientCacheListener.instance()); } @Override @@ -43,4 +62,29 @@ public class VertexSymbolStyle extends ThrottledStyleBase { ProfileVariables.claimNodeProperty(nn, "SVG", null, evaluationContext); } + @SuppressWarnings("rawtypes") + protected static final class SymbolFunctionRequest extends ResourceRead { + protected static final Function CONST_NULL = new FunctionImpl1() { + @Override + public String apply(Resource p0) { + return null; + } + }; + + public SymbolFunctionRequest(Resource entry) { + super(entry); + } + + @Override + public Function perform(ReadGraph graph) throws DatabaseException { + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + + Function symbolFunction = (Function) graph.getPossibleRelatedValue2(resource, DN.HasSymbolFunction, resource); + if (symbolFunction == null) + symbolFunction = CONST_NULL; + + return symbolFunction; + } + } + } -- 2.45.2 From db34439af303d45eb67cee78cb3f68c9b6666da4 Mon Sep 17 00:00:00 2001 From: Reino Ruusu Date: Wed, 20 Feb 2019 19:46:23 +0200 Subject: [PATCH 05/16] Added symbol rendering for edges. gitlab #27 Change-Id: I67e49bdec2f722121dd261c755ad7722469a3bc9 --- .../adapters/DistrictNetworkEdgeElement.java | 7 +++ .../ui/nodes/DistrictNetworkEdgeNode.java | 53 ++++++++++++++++++- .../ui/nodes/DistrictNetworkNodeUtils.java | 38 +++++++++++++ .../ui/nodes/DistrictNetworkVertexNode.java | 34 +++--------- 4 files changed, 105 insertions(+), 27 deletions(-) create mode 100644 org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkNodeUtils.java diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java index 9595f232..d4758007 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java @@ -28,6 +28,7 @@ import org.simantics.g2d.element.handler.impl.DefaultTransform; import org.simantics.g2d.element.handler.impl.SimpleElementLayers; import org.simantics.maps.MapScalingTransform; import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.scenegraph.g2d.nodes.SVGNode; import org.simantics.utils.datastructures.hints.IHintContext.Key; import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; import org.slf4j.Logger; @@ -37,6 +38,7 @@ public class DistrictNetworkEdgeElement { public static final Key KEY_DN_EDGE = new KeyOf(DistrictNetworkEdge.class, "DN_EDGE"); public static final Key KEY_DN_EDGE_NODE = new SceneGraphNodeKey(DistrictNetworkEdgeNode.class, "DN_EDGE_NODE"); + public static final Key KEY_DN_EDGE_SYMBOL_NODE = new SceneGraphNodeKey(DistrictNetworkEdgeNode.class, "DN_EDGE_SYMBOL_NODE"); public static final ElementClass CLASS = ElementClass.compile( @@ -66,6 +68,9 @@ public class DistrictNetworkEdgeElement { if (node == null) { node = parent.addNode(ElementUtils.generateNodeId(edgeElement), DistrictNetworkEdgeNode.class); edgeElement.setHint(KEY_DN_EDGE_NODE, node); + + SVGNode symbol = node.addNode(ElementUtils.generateNodeId(edgeElement), SVGNode.class); + edgeElement.setHint(KEY_DN_EDGE_SYMBOL_NODE, symbol); } node.setColor(ElementUtils.getAdditionalColor(edgeElement, Color.BLUE)); @@ -79,8 +84,10 @@ public class DistrictNetworkEdgeElement { @Override public void cleanup(IElement edge) { + ElementUtils.removePossibleNode(edge, KEY_DN_EDGE_SYMBOL_NODE); ElementUtils.removePossibleNode(edge, KEY_DN_EDGE_NODE); edge.removeHint(KEY_DN_EDGE_NODE); + edge.removeHint(KEY_DN_EDGE_SYMBOL_NODE); } } 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 9f8c9a23..00a1427f 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 @@ -7,16 +7,20 @@ import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.geom.Line2D; import java.awt.geom.Path2D; +import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import org.simantics.district.network.ModelledCRS; import org.simantics.district.network.ui.DistrictNetworkEdge; +import org.simantics.scenegraph.INode; import org.simantics.scenegraph.ISelectionPainterNode; import org.simantics.scenegraph.g2d.G2DNode; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.scenegraph.g2d.nodes.SVGNode; import org.simantics.scenegraph.utils.GeometryUtils; import org.simantics.scenegraph.utils.NodeUtil; -public class DistrictNetworkEdgeNode extends G2DNode implements ISelectionPainterNode { +public class DistrictNetworkEdgeNode extends G2DParentNode implements ISelectionPainterNode { private static final long serialVersionUID = 8049769475036519806L; @@ -32,6 +36,18 @@ public class DistrictNetworkEdgeNode extends G2DNode implements ISelectionPainte private Double stroke; private transient Color dynamicColor = null; + // Dimensions for shut-off valve symbol + private static final double left = -0.25; + private static final double top = -0.25; + private static final double width = 0.5; + private static final double height = 0.5; + + private static final Rectangle2D NORMAL = new Rectangle2D.Double(left, top, width, height); + + private transient Point2D centerPoint; + private transient Rectangle2D symbolRect; + private transient AffineTransform symbolTransform; + @Override public void init() { } @@ -76,12 +92,40 @@ public class DistrictNetworkEdgeNode extends G2DNode implements ISelectionPainte // Reset g2d.setStroke(oldStroke); g2d.setColor(oldColor); + + // Render SVG symbol + double viewScaleRecip = 10; + if (scaleStroke) { + double scale = GeometryUtils.getScale(g2d.getTransform()); + scale = Math.max(10000, Math.min(scale, 50000)); + viewScaleRecip /= scale; + } + + Point2D p = getCenterPoint(); + symbolRect = DistrictNetworkNodeUtils.calculateDrawnGeometry(p, NORMAL, symbolRect, viewScaleRecip); + symbolTransform = DistrictNetworkNodeUtils.getTransformToRectangle(symbolRect, symbolTransform); + + for (INode nn : getNodes()) { + G2DNode g2dNode = (G2DNode)nn; + g2dNode.setTransform(symbolTransform); + g2dNode.render(g2d); + } + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint); if (ot != null) g2d.setTransform(ot); } + private Point2D getCenterPoint() { + if (centerPoint == null) + centerPoint = new Point2D.Double(); + + Rectangle2D bounds = path.getBounds2D(); + centerPoint.setLocation(bounds.getCenterX(), bounds.getCenterY()); + return centerPoint; + } + public static Line2D calculateLine(DistrictNetworkEdge edge, Line2D result) { // Convert to screen coordinates double startX = ModelledCRS.longitudeToX(edge.getStartPoint().getX()); @@ -155,4 +199,11 @@ public class DistrictNetworkEdgeNode extends G2DNode implements ISelectionPainte this.dynamicColor = color; } + @PropertySetter(value = "SVG") + public void setSVG(String value) { + for (INode nn : this.getNodes()) + if (nn instanceof SVGNode) + ((SVGNode)nn).setData(value); + } + } diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkNodeUtils.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkNodeUtils.java new file mode 100644 index 00000000..8a369e26 --- /dev/null +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkNodeUtils.java @@ -0,0 +1,38 @@ +package org.simantics.district.network.ui.nodes; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import org.simantics.district.network.ModelledCRS; + +public class DistrictNetworkNodeUtils { + + public static Rectangle2D calculateDrawnGeometry(Point2D p, Rectangle2D margin, Rectangle2D result, double scaleRecip) { + if (result == null) + result = new Rectangle2D.Double(); + double mw = margin.getWidth(); + double mh = margin.getHeight(); + result.setFrame(p.getX() - (mw / 2 * scaleRecip), p.getY() - (mh / 2 * scaleRecip), mw * scaleRecip, mh * scaleRecip); + return result; + } + + public static Point2D calculatePoint2D(Point2D point, Point2D result) { + double x = ModelledCRS.longitudeToX(point.getX()); + double y = ModelledCRS.latitudeToY(-point.getY()); // Inverse because Simantics Diagram is inverted + if (result == null) + result = new Point2D.Double(x, y); + else + result.setLocation(x, y); + return result; + } + + public static AffineTransform getTransformToRectangle(Rectangle2D toDraw, AffineTransform transform) { + if (transform == null) + transform = new AffineTransform(); + + transform.setTransform(toDraw.getWidth(), 0.0, 0.0, toDraw.getHeight(), toDraw.getCenterX(), toDraw.getCenterY()); + return transform; + } + +} 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 10cfa905..377c7f7e 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 @@ -8,7 +8,6 @@ import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; -import org.simantics.district.network.ModelledCRS; import org.simantics.district.network.ui.adapters.DistrictNetworkVertex; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.ISelectionPainterNode; @@ -46,6 +45,7 @@ public class DistrictNetworkVertexNode extends G2DParentNode implements ISelecti private Rectangle2D bounds; private transient Point2D point; private transient Rectangle2D rect; + private transient AffineTransform symbolTransform; private double nodeSize = 1; @@ -86,8 +86,8 @@ public class DistrictNetworkVertexNode extends G2DParentNode implements ISelecti double scaleRecip = viewScaleRecip * nodeSize; // Translate lat and lon to X and Y - Point2D p = point = calculatePoint2D(vertex, point); - Rectangle2D toDraw = calculateDrawnGeometry(p, hover ? HOVERED : NORMAL, rect, scaleRecip); + Point2D p = point = DistrictNetworkNodeUtils.calculatePoint2D(vertex.getPoint(), point); + Rectangle2D toDraw = rect = DistrictNetworkNodeUtils.calculateDrawnGeometry(p, hover ? HOVERED : NORMAL, rect, scaleRecip); if (NodeUtil.isSelected(this, 1)) { changeColor = true; @@ -110,23 +110,16 @@ public class DistrictNetworkVertexNode extends G2DParentNode implements ISelecti // Render SVG symbol for (INode nn : getNodes()) { - ((G2DNode)nn).setTransform(new AffineTransform(toDraw.getWidth(), 0.0, 0.0, toDraw.getHeight(), toDraw.getCenterX(), toDraw.getCenterY())); - ((G2DNode)nn).render(g2d); + G2DNode g2dNode = (G2DNode)nn; + symbolTransform = DistrictNetworkNodeUtils.getTransformToRectangle(toDraw, symbolTransform); + g2dNode.setTransform(symbolTransform); + g2dNode.render(g2d); } if (ot != null) g2d.setTransform(ot); } - private Rectangle2D calculateDrawnGeometry(Point2D p, Rectangle2D margin, Rectangle2D result, double scaleRecip) { - if (result == null) - result = new Rectangle2D.Double(); - double mw = margin.getWidth(); - double mh = margin.getHeight(); - result.setFrame(p.getX() - (mw / 2 * scaleRecip), p.getY() - (mh / 2 * scaleRecip), mw * scaleRecip, mh * scaleRecip); - return result; - } - @Override public Rectangle2D getBounds() { return super.getBounds(); @@ -157,22 +150,11 @@ public class DistrictNetworkVertexNode extends G2DParentNode implements ISelecti } private Rectangle2D calculateBounds(Rectangle2D rect) { - Point2D calcPoint = calculatePoint2D(vertex, point); + Point2D calcPoint = DistrictNetworkNodeUtils.calculatePoint2D(vertex.getPoint(), point); AffineTransform at = getTransform(); return new Rectangle2D.Double(calcPoint.getX(), calcPoint.getY(), width / at.getScaleX(), height / at.getScaleY()).getBounds2D(); } - private static Point2D calculatePoint2D(DistrictNetworkVertex vertex, Point2D result) { - Point2D point = vertex.getPoint(); - double x = ModelledCRS.longitudeToX(point.getX()); - double y = ModelledCRS.latitudeToY(-point.getY()); // Inverse because Simantics Diagram is inverted - if (result == null) - result = new Point2D.Double(x, y); - else - result.setLocation(x, y); - return result; - } - public void setVertex(DistrictNetworkVertex vertex) { this.vertex = vertex; updateBounds(); -- 2.45.2 From 0f3520e48a9387d07b622ab5b0c20ec3bddbf2b1 Mon Sep 17 00:00:00 2001 From: Reino Ruusu Date: Fri, 22 Feb 2019 13:23:15 +0200 Subject: [PATCH 06/16] Disable throttling for now, as it doens't work. Also use setSynchronous() for diagram styles, as there is no visualization for pending results. gitlab #30 Change-Id: I53ce85ba6d81b69f41abe26930941f2bd9d610a1 --- .../network/profile/DNElementColorStyle.java | 27 ++++++++++++------- .../network/profile/EdgeThicknessStyle.java | 26 +++++++++++------- .../network/profile/ThrottledStyleBase.java | 13 ++++----- .../network/profile/VertexSizeStyle.java | 25 ++++++++++------- .../network/profile/VertexSymbolStyle.java | 27 ++++++++++--------- 5 files changed, 72 insertions(+), 46 deletions(-) diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/DNElementColorStyle.java b/org.simantics.district.network/src/org/simantics/district/network/profile/DNElementColorStyle.java index b74a6619..f8f6ba5c 100644 --- a/org.simantics.district.network/src/org/simantics/district/network/profile/DNElementColorStyle.java +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/DNElementColorStyle.java @@ -24,18 +24,25 @@ public class DNElementColorStyle extends ThrottledStyleBase { @Override public Color calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { DiagramSettings ds = graph.syncRequest(new DiagramSettingsRequest(runtimeDiagram), TransientCacheAsyncListener.instance()); - if (ds.elementColoringFunction.isPresent()) { - if (DEBUG) - System.out.print("elementColoringFunction: " + ds.elementColoringFunction + "(" + groupItem + "): "); - Double t = Simantics.applySCLRead(graph, ds.elementColoringFunction.get(), groupItem); - if (DEBUG) - System.out.print(t); - if (t != null) { - Color result = ds.coloringGradient.get(t); - //System.out.println("color(" + t + "): " + result); - return result; + // Prevent PendingVariableExceptions from coming through + boolean wasSynchronous = graph.setSynchronous(true); + try { + if (ds.elementColoringFunction.isPresent()) { + if (DEBUG) + System.out.print("elementColoringFunction: " + ds.elementColoringFunction + "(" + groupItem + "): "); + Double t = Simantics.applySCLRead(graph, ds.elementColoringFunction.get(), groupItem); + if (DEBUG) + System.out.print(t); + if (t != null) { + Color result = ds.coloringGradient.get(t); + //System.out.println("color(" + t + "): " + result); + return result; + } } } + finally { + graph.setSynchronous(wasSynchronous); + } return null; } diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/EdgeThicknessStyle.java b/org.simantics.district.network/src/org/simantics/district/network/profile/EdgeThicknessStyle.java index 06dcdf3f..b305c391 100644 --- a/org.simantics.district.network/src/org/simantics/district/network/profile/EdgeThicknessStyle.java +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/EdgeThicknessStyle.java @@ -19,17 +19,25 @@ public class EdgeThicknessStyle extends ThrottledStyleBase { @Override public Double calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { DiagramSettings ds = graph.syncRequest(new DiagramSettingsRequest(runtimeDiagram), TransientCacheAsyncListener.instance()); - Double thickness = ONE; - if (ds.edgeThicknessProperty.isPresent()) { - thickness = Simantics.applySCLRead(graph, ds.edgeThicknessProperty.get(), groupItem); -// System.out.println("read thickness: " + thickness + " : " + ds.edgeThicknessProperty); - if (thickness == null) { - thickness = ONE; - } else { - thickness = thickness * ds.edgeThicknessGain + ds.edgeThicknessBias; + // Prevent PendingVariableExceptions from coming through + boolean wasSynchronous = graph.setSynchronous(true); + try { + Double thickness = ONE; + if (ds.edgeThicknessProperty.isPresent()) { + thickness = Simantics.applySCLRead(graph, ds.edgeThicknessProperty.get(), groupItem); + // System.out.println("read thickness: " + thickness + " : " + ds.edgeThicknessProperty); + if (thickness == null) { + thickness = ONE; + } else { + thickness = thickness * ds.edgeThicknessGain + ds.edgeThicknessBias; + } } + + return thickness; + } + finally { + graph.setSynchronous(wasSynchronous); } - return thickness; } @Override diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/ThrottledStyleBase.java b/org.simantics.district.network/src/org/simantics/district/network/profile/ThrottledStyleBase.java index f8b817ae..67ca2595 100644 --- a/org.simantics.district.network/src/org/simantics/district/network/profile/ThrottledStyleBase.java +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/ThrottledStyleBase.java @@ -74,12 +74,13 @@ public abstract class ThrottledStyleBase extends StyleBase calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { - long currentTimestamp = System.currentTimeMillis(); - if (lastCalculateTimestamp > (currentTimestamp - interval.get())) { - LOGGER.debug("Throttling result calculation for {} {} {} {}", runtimeDiagram, entry, groupItem, interval.get()); - return Optional.empty(); - } - lastCalculateTimestamp = currentTimestamp; +// Needs fixing - this will result registration of listeners for nothing in the cache +// long currentTimestamp = System.currentTimeMillis(); +// if (lastCalculateTimestamp > (currentTimestamp - interval.get())) { +// LOGGER.debug("Throttling result calculation for {} {} {} {}", runtimeDiagram, entry, groupItem, interval.get()); +// return Optional.empty(); +// } +// lastCalculateTimestamp = currentTimestamp; // let's calculate return Optional.ofNullable(calculateThrottledStyle(graph, runtimeDiagram, entry, groupItem)); } diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSizeStyle.java b/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSizeStyle.java index d536bc04..b59590b6 100644 --- a/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSizeStyle.java +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSizeStyle.java @@ -20,17 +20,24 @@ public class VertexSizeStyle extends ThrottledStyleBase { public Double calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { DiagramSettings ds = graph.syncRequest(new DiagramSettingsRequest(runtimeDiagram), TransientCacheAsyncListener.instance()); Double scaling = ONE; - if (ds.vertexScaleProperty.isPresent()) { - scaling = Simantics.applySCLRead(graph, ds.vertexScaleProperty.get(), groupItem); - if (scaling == null) { - scaling = ONE; - } else { -// System.out.println("read vertex scaling: " + scaling + " : " + ds.vertexScaleProperty); - scaling = scaling * ds.vertexScaleGain + ds.vertexScaleBias; -// System.out.println("RESULT: " + scaling); + // Prevent PendingVariableExceptions from coming through + boolean wasSynchronous = graph.setSynchronous(true); + try { + if (ds.vertexScaleProperty.isPresent()) { + scaling = Simantics.applySCLRead(graph, ds.vertexScaleProperty.get(), groupItem); + if (scaling == null) { + scaling = ONE; + } else { + // System.out.println("read vertex scaling: " + scaling + " : " + ds.vertexScaleProperty); + scaling = scaling * ds.vertexScaleGain + ds.vertexScaleBias; + // System.out.println("RESULT: " + scaling); + } } + return scaling; + } + finally { + graph.setSynchronous(wasSynchronous); } - return scaling; } @Override diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSymbolStyle.java b/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSymbolStyle.java index 96ff4392..26a5564d 100644 --- a/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSymbolStyle.java +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSymbolStyle.java @@ -6,7 +6,6 @@ import org.simantics.db.Resource; import org.simantics.db.common.procedure.adapter.TransientCacheListener; import org.simantics.db.common.request.ResourceRead; import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.exception.PendingVariableException; import org.simantics.district.network.ontology.DistrictNetworkResource; import org.simantics.layer0.Layer0; import org.simantics.scenegraph.INode; @@ -26,18 +25,22 @@ public class VertexSymbolStyle extends ThrottledStyleBase { @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public String calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { - - Function symbolFunction = getSymbolFunction(graph, entry); - if (symbolFunction == null) - return null; - + // Prevent PendingVariableExceptions from coming through + boolean wasSynchronous = graph.setSynchronous(true); try { - return (String) Simantics.applySCLRead(graph, symbolFunction, groupItem); - } catch (PendingVariableException e) { - throw e; - } catch (Exception e) { - LOGGER.error("Getting dynamic symbol for " + groupItem + " (" + graph.getPossibleRelatedValue(groupItem, Layer0.getInstance(graph).HasName) + ") failed", e); - return null; + Function symbolFunction = getSymbolFunction(graph, entry); + if (symbolFunction == null) + return null; + + try { + return (String) Simantics.applySCLRead(graph, symbolFunction, groupItem); + } catch (Exception e) { + LOGGER.error("Getting dynamic symbol for " + groupItem + " (" + graph.getPossibleRelatedValue(groupItem, Layer0.getInstance(graph).HasName) + ") failed", e); + return null; + } + } + finally { + graph.setSynchronous(wasSynchronous); } } -- 2.45.2 From 09d4de70f2c30d1d788e1572d0459e4a7990fcdf Mon Sep 17 00:00:00 2001 From: Reino Ruusu Date: Fri, 22 Feb 2019 13:58:32 +0200 Subject: [PATCH 07/16] Opening of diagram element query result in diagram view. gitlab #28 Change-Id: Ibdecf9acc683bad6cd11161b50c99409581d4f46 --- .../META-INF/MANIFEST.MF | 33 ++++-- .../selection/ui/ElementSelectorTableUI.java | 103 ++++++++++-------- 2 files changed, 81 insertions(+), 55 deletions(-) diff --git a/org.simantics.district.selection.ui/META-INF/MANIFEST.MF b/org.simantics.district.selection.ui/META-INF/MANIFEST.MF index ee821144..91f61246 100644 --- a/org.simantics.district.selection.ui/META-INF/MANIFEST.MF +++ b/org.simantics.district.selection.ui/META-INF/MANIFEST.MF @@ -4,16 +4,29 @@ Bundle-SymbolicName: org.simantics.district.selection.ui;singleton:=tr ue Bundle-Name: Diagram element selection UI Bundle-Version: 1.0.0.qualifier -Require-Bundle: javax.inject,org.eclipse.osgi,org.eclipse.jface,org.ec - lipse.e4.ui.model.workbench,org.eclipse.e4.ui.di,org.eclipse.e4.ui.se - rvices,org.eclipse.e4.core.di.annotations,org.eclipse.e4.ui.workbench - ,org.slf4j.api,org.simantics,org.simantics.district.region,org.simant - ics.district.selection,org.simantics.db.common,org.simantics.ui,com.f - amfamfam.silk;bundle-version="1.3.0",org.simantics.browsing.ui.common - ,org.eclipse.e4.core.contexts,org.eclipse.e4.core.di;bundle-version=" - 1.6.100",org.simantics.district.region.ontology,org.simantics.distric - t.route.ontology,org.simantics.modeling.ontology,org.simantics.silk.o - ntology;bundle-version=1.1.0 +Require-Bundle: javax.inject, + org.eclipse.osgi, + org.eclipse.jface, + org.eclipse.e4.ui.model.workbench, + org.eclipse.e4.ui.di, + org.eclipse.e4.ui.services, + org.eclipse.e4.core.di.annotations, + org.eclipse.e4.ui.workbench, + org.slf4j.api, + org.simantics, + org.simantics.district.region, + org.simantics.district.selection, + org.simantics.db.common, + org.simantics.ui, + com.famfamfam.silk;bundle-version="1.3.0", + org.simantics.browsing.ui.common, + org.eclipse.e4.core.contexts, + org.eclipse.e4.core.di;bundle-version="1.6.100", + org.simantics.district.region.ontology, + org.simantics.district.route.ontology, + org.simantics.modeling.ontology, + org.simantics.silk.ontology;bundle-version="1.1.0", + org.simantics.district.network.ui Bundle-ManifestVersion: 2 Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-Vendor: Semantum oy diff --git a/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/ElementSelectorTableUI.java b/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/ElementSelectorTableUI.java index 0786ce53..8ed8d3e1 100644 --- a/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/ElementSelectorTableUI.java +++ b/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/ElementSelectorTableUI.java @@ -10,10 +10,8 @@ import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.jface.viewers.TreeViewer; @@ -29,15 +27,17 @@ import org.simantics.browsing.ui.common.AdaptableHintContext; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.procedure.adapter.SyncListenerAdapter; +import org.simantics.db.common.request.ResourceRead; import org.simantics.db.exception.DatabaseException; -import org.simantics.db.exception.RuntimeDatabaseException; import org.simantics.db.layer0.QueryIndexUtils; import org.simantics.db.layer0.SelectionHints; import org.simantics.db.layer0.request.ActiveModels; +import org.simantics.db.layer0.variable.Variable; import org.simantics.db.request.Read; +import org.simantics.district.network.ui.DistrictNetworkUIUtil; import org.simantics.district.selection.ElementSelectionResource; -import org.simantics.district.selection.ElementSelectionUtils; import org.simantics.district.selection.ElementSelector; +import org.simantics.district.selection.ElementSelector.DiagramGenerator; import org.simantics.layer0.Layer0; import org.simantics.scl.runtime.Lists; import org.simantics.scl.runtime.function.FunctionImpl1; @@ -63,40 +63,7 @@ public class ElementSelectorTableUI extends Composite { this.setLayout(new FillLayout()); viewer = new TreeViewer(this, SWT.FULL_SELECTION); - viewer.addDoubleClickListener(new IDoubleClickListener() { - @Override - public void doubleClick(DoubleClickEvent event) { - TreeSelection selection = (TreeSelection) viewer.getSelection(); - ElementSelector query = (ElementSelector) selection.getFirstElement(); - try { - List elements = Simantics.getSession().syncRequest(new Read>() { - @SuppressWarnings("unchecked") - @Override - public List perform(ReadGraph graph) throws DatabaseException { - Resource model = ActiveModels.getPossibleActiveModel(graph, Simantics.getProjectResource()); - if (model == null) { - LOGGER.warn("No active model"); - return Collections.emptyList(); - } - - List result = query.selectElementsFrom(graph, model); - return Lists.map(new FunctionImpl1() { - public AdaptableHintContext apply(Resource p0) { - AdaptableHintContext selectionElement = new SelectionElement(SelectionHints.STD_KEYS, graph); - selectionElement.setHint(SelectionHints.KEY_MAIN, p0); - selectionElement.setHint(SelectionHints.KEY_MODEL, model); - return selectionElement; - } - }, result); - } - }); - - selectionService.setPostSelection(new StructuredSelection(elements)); - } catch (DatabaseException e) { - LOGGER.error("Element selection query failed", e); - } - } - }); + viewer.addDoubleClickListener(new DoubleClickListener(selectionService)); viewer.setContentProvider(new ITreeContentProvider() { @Override @@ -196,12 +163,9 @@ public class ElementSelectorTableUI extends Composite { return selection != null ? (ElementSelector) selection.getFirstElement() : null; } - private final class SelectionElement extends AdaptableHintContext { - private final ReadGraph graph; - - private SelectionElement(Key[] keys, ReadGraph graph) { + private static final class SelectionElement extends AdaptableHintContext { + private SelectionElement(Key[] keys) { super(keys); - this.graph = graph; } @SuppressWarnings("unchecked") @@ -212,7 +176,11 @@ public class ElementSelectorTableUI extends Composite { } else if (contentType instanceof AnyVariable) { try { - return (T)ElementSelector.getVariableForElement(graph, element); + return (T) Simantics.getSession().syncRequest(new ResourceRead(element) { + public Variable perform(ReadGraph graph) throws DatabaseException { + return ElementSelector.getVariableForElement(graph, resource); + } + }); } catch (DatabaseException e) { return null; } @@ -222,7 +190,7 @@ public class ElementSelectorTableUI extends Composite { } } - public static class SelectionsRequest implements Read> { + public static final class SelectionsRequest implements Read> { @Override public Collection perform(ReadGraph graph) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); @@ -250,4 +218,49 @@ public class ElementSelectorTableUI extends Composite { return result; } } + + private static final class DoubleClickListener implements IDoubleClickListener { + private final ESelectionService selectionService; + private Resource model; + + private DoubleClickListener(ESelectionService selectionService) { + this.selectionService = selectionService; + } + + @Override + public void doubleClick(DoubleClickEvent event) { + TreeSelection selection = (TreeSelection) event.getViewer().getSelection(); + ElementSelector query = (ElementSelector) selection.getFirstElement(); + try { + List result = Simantics.getSession().syncRequest(new Read>() { + @Override + public List perform(ReadGraph graph) throws DatabaseException { + model = ActiveModels.getPossibleActiveModel(graph, Simantics.getProjectResource()); + if (model == null) { + LOGGER.warn("No active model"); + return Collections.emptyList(); + } + + return query.selectElementsFrom(graph, model); + } + }); + + if (query.getGenerator() instanceof DiagramGenerator) { + DistrictNetworkUIUtil.openDNDiagramWithSelection(event.getViewer().getControl().getDisplay(), result); + } + else { + selectionService.setPostSelection(new StructuredSelection(Lists.map(new FunctionImpl1() { + public AdaptableHintContext apply(Resource p0) { + AdaptableHintContext selectionElement = new SelectionElement(SelectionHints.STD_KEYS); + selectionElement.setHint(SelectionHints.KEY_MAIN, p0); + selectionElement.setHint(SelectionHints.KEY_MODEL, model); + return selectionElement; + } + }, result))); + } + } catch (DatabaseException e) { + LOGGER.error("Element selection query failed", e); + } + } + } } -- 2.45.2 From 2801a636fc48e9636283a85276130594c27979a7 Mon Sep 17 00:00:00 2001 From: Reino Ruusu Date: Fri, 22 Feb 2019 17:11:00 +0200 Subject: [PATCH 08/16] Selection queries from explicit sets of elements. gitlab #28 Change-Id: Iac2f3a51b66b37b4fbe04dc1f351327231ea00c7 --- .../META-INF/MANIFEST.MF | 4 ++- .../selection/ui/ElementSelectorTableUI.java | 3 +- .../ui/handlers/CreateNewElementSelector.java | 7 ++++- .../ui/handlers/EditElementSelector.java | 21 +++++++++++-- .../ui/parts/EditSelectorDialog.java | 31 +++++++++++++++++-- 5 files changed, 58 insertions(+), 8 deletions(-) diff --git a/org.simantics.district.selection.ui/META-INF/MANIFEST.MF b/org.simantics.district.selection.ui/META-INF/MANIFEST.MF index 91f61246..31f83e38 100644 --- a/org.simantics.district.selection.ui/META-INF/MANIFEST.MF +++ b/org.simantics.district.selection.ui/META-INF/MANIFEST.MF @@ -26,7 +26,9 @@ Require-Bundle: javax.inject, org.simantics.district.route.ontology, org.simantics.modeling.ontology, org.simantics.silk.ontology;bundle-version="1.1.0", - org.simantics.district.network.ui + org.simantics.district.network.ui, + org.simantics.structural.ontology, + org.simantics.diagram.ontology Bundle-ManifestVersion: 2 Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-Vendor: Semantum oy diff --git a/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/ElementSelectorTableUI.java b/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/ElementSelectorTableUI.java index 8ed8d3e1..09f34609 100644 --- a/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/ElementSelectorTableUI.java +++ b/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/ElementSelectorTableUI.java @@ -38,6 +38,7 @@ import org.simantics.district.network.ui.DistrictNetworkUIUtil; import org.simantics.district.selection.ElementSelectionResource; import org.simantics.district.selection.ElementSelector; import org.simantics.district.selection.ElementSelector.DiagramGenerator; +import org.simantics.district.selection.ElementSelector.ExplicitGenerator; import org.simantics.layer0.Layer0; import org.simantics.scl.runtime.Lists; import org.simantics.scl.runtime.function.FunctionImpl1; @@ -245,7 +246,7 @@ public class ElementSelectorTableUI extends Composite { } }); - if (query.getGenerator() instanceof DiagramGenerator) { + if (query.getGenerator() instanceof DiagramGenerator || query.getGenerator() instanceof ExplicitGenerator) { DistrictNetworkUIUtil.openDNDiagramWithSelection(event.getViewer().getControl().getDisplay(), result); } else { diff --git a/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/handlers/CreateNewElementSelector.java b/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/handlers/CreateNewElementSelector.java index b9df8b84..10ea9e81 100644 --- a/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/handlers/CreateNewElementSelector.java +++ b/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/handlers/CreateNewElementSelector.java @@ -3,12 +3,15 @@ package org.simantics.district.selection.ui.handlers; import org.eclipse.e4.core.contexts.IEclipseContext; import org.eclipse.e4.core.di.annotations.CanExecute; import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.services.IServiceConstants; import org.eclipse.e4.ui.workbench.IWorkbench; import org.eclipse.e4.ui.workbench.modeling.ESelectionService; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Shell; +import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; import org.simantics.district.selection.ui.parts.EditSelectorDialog; +import org.simantics.utils.ui.AdaptionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,8 +26,10 @@ public class CreateNewElementSelector { @Execute public void createNewElementSelector(IEclipseContext context, IWorkbench workbench) { + Object currentSelection = context.get(IServiceConstants.ACTIVE_SELECTION); + Shell shell = context.getActive(Shell.class); - EditSelectorDialog dialog = new EditSelectorDialog(shell, null); + EditSelectorDialog dialog = new EditSelectorDialog(shell, null, AdaptionUtils.adaptToCollection(currentSelection, Resource.class)); LOGGER.debug("Opening dialog"); int result = dialog.open(); LOGGER.debug("Dialog closed with result code " + result); diff --git a/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/handlers/EditElementSelector.java b/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/handlers/EditElementSelector.java index f914d161..69fcbccd 100644 --- a/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/handlers/EditElementSelector.java +++ b/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/handlers/EditElementSelector.java @@ -1,20 +1,26 @@ package org.simantics.district.selection.ui.handlers; +import java.util.Collection; + import javax.inject.Inject; -import org.eclipse.e4.core.contexts.ContextInjectionFactory; import org.eclipse.e4.core.contexts.IEclipseContext; import org.eclipse.e4.core.di.annotations.CanExecute; import org.eclipse.e4.core.di.annotations.Execute; import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.services.IServiceConstants; import org.eclipse.e4.ui.workbench.IWorkbench; import org.eclipse.e4.ui.workbench.modeling.EPartService; import org.eclipse.e4.ui.workbench.modeling.ESelectionService; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Shell; +import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; +import org.simantics.district.selection.ElementSelector; +import org.simantics.district.selection.ElementSelector.ExplicitGenerator; import org.simantics.district.selection.ui.parts.EditSelectorDialog; import org.simantics.district.selection.ui.parts.ElementSelectionView; +import org.simantics.utils.ui.AdaptionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,6 +46,8 @@ public class EditElementSelector { @Execute public void editElementSelector(IEclipseContext context, IWorkbench workbench) { + Object currentSelection = context.get(IServiceConstants.ACTIVE_SELECTION); + MPart part = partService.getActivePart(); if (part == null) return; @@ -49,8 +57,17 @@ public class EditElementSelector { ElementSelectionView view = (ElementSelectionView)object; + Collection selection; + ElementSelector selectedItem = view.getSelectedItem(); + if (selectedItem.getGenerator() instanceof ExplicitGenerator) { + selection = ((ExplicitGenerator)selectedItem.getGenerator()).elements; + } + else { + selection = AdaptionUtils.adaptToCollection(currentSelection, Resource.class); + } + Shell shell = context.getActive(Shell.class); - EditSelectorDialog dialog = new EditSelectorDialog(shell, view.getSelectedItem()); + EditSelectorDialog dialog = new EditSelectorDialog(shell, selectedItem, selection); LOGGER.debug("Opening dialog"); int result = dialog.open(); diff --git a/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/parts/EditSelectorDialog.java b/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/parts/EditSelectorDialog.java index 42270da9..b68c3fe1 100644 --- a/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/parts/EditSelectorDialog.java +++ b/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/parts/EditSelectorDialog.java @@ -1,6 +1,7 @@ package org.simantics.district.selection.ui.parts; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -38,8 +39,10 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.RuntimeDatabaseException; import org.simantics.db.layer0.QueryIndexUtils; import org.simantics.db.layer0.request.ActiveModels; +import org.simantics.db.layer0.util.Layer0Utils; import org.simantics.db.request.Read; import org.simantics.db.request.WriteResult; +import org.simantics.diagram.stubs.DiagramResource; import org.simantics.district.region.ontology.DiagramRegionsResource; import org.simantics.district.route.ontology.RouteResource; import org.simantics.district.selection.ElementSelectionResource; @@ -69,6 +72,9 @@ public class EditSelectorDialog extends Dialog { private static Logger LOGGER = LoggerFactory.getLogger(EditSelectorDialog.class); private ElementSelector elementSelector; + + // Currently selected elements + Collection currentSelection; // Data for comboboxes Map diagrams; @@ -106,7 +112,7 @@ public class EditSelectorDialog extends Dialog { private Composite content; @Inject - public EditSelectorDialog(Shell shell, ElementSelector elementSelector) { + public EditSelectorDialog(Shell shell, ElementSelector elementSelector, Collection currentSelection) { super(shell); this.elementSelector = elementSelector; @@ -124,6 +130,8 @@ public class EditSelectorDialog extends Dialog { } } + this.currentSelection = currentSelection; + final Map regions = new HashMap<>(); final Map routes = new HashMap<>(); @@ -229,8 +237,11 @@ public class EditSelectorDialog extends Dialog { public void perform(WriteGraph graph) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); ElementSelectionResource ES = ElementSelectionResource.getInstance(graph); + ModelingResources MOD = ModelingResources.getInstance(graph); + DiagramResource DIA = DiagramResource.getInstance(graph); graph.markUndoPoint(); + Layer0Utils.addCommentMetadata(graph, "Created new element selection"); Resource lib = ElementSelectionUtils.ensureSelectionLibrary(graph); @@ -258,12 +269,26 @@ public class EditSelectorDialog extends Dialog { break; case 1: generatorType = ES.Generator_Diagram; - Resource composite = graph.getPossibleObject(diagram, ModelingResources.getInstance(graph).DiagramToComposite); + Resource composite = graph.getPossibleObject(diagram, MOD.DiagramToComposite); graph.claim(generator, ES.Generator_HasDiagram, composite != null ? composite : diagram); break; case 2: generatorType = ES.Generator_Explicit; - // TODO: Claim relations to current selection elements + for (Resource r : currentSelection) { + // No connections + if (graph.isInstanceOf(r, DIA.Connection)) + continue; + if (!graph.isInstanceOf(r, DIA.Element)) { + if (!graph.hasStatement(r, MOD.ComponentToElement)) + continue; + + r = graph.getPossibleObject(r, MOD.ComponentToElement); + if (r == null) + continue; + } + + graph.claim(generator, ES.Generator_HasSelectedElement, r); + } break; default: throw new IllegalStateException("Invalid source index " + generatorIndex); } -- 2.45.2 From 6efcc2873091c30cbc6dbc47f5601bd62813b99f Mon Sep 17 00:00:00 2001 From: jsimomaa Date: Tue, 26 Feb 2019 23:45:19 +0200 Subject: [PATCH 09/16] Expose transform of NetworkDrawingParticipant * for programmatic vertex creation gitlab #31 Change-Id: Ia2a337fb92dab169a5b2c74f13c93a88998f4617 --- .../district/network/ui/NetworkDrawingParticipant.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/NetworkDrawingParticipant.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/NetworkDrawingParticipant.java index c020c33d..73abf31e 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/NetworkDrawingParticipant.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/NetworkDrawingParticipant.java @@ -88,4 +88,7 @@ public class NetworkDrawingParticipant extends AbstractDiagramParticipant { return changed; } + public AffineTransform getTransform() { + return transform; + } } -- 2.45.2 From 835710a4f22ec2d91c287295fb176a0af62d1186 Mon Sep 17 00:00:00 2001 From: jsimomaa Date: Thu, 28 Feb 2019 09:11:50 +0200 Subject: [PATCH 10/16] Refactoring MapNode rendering & zooming to even zoom levels (0-20) * With this change the map background bitmap-images are always sharp and not blurred on e.g. zooming level 5.42 which was previously possible gitlab #32 Change-Id: I1fd84ef25154f454efbff0b0195c447d90bd30fd --- .../simantics/maps/MapScalingTransform.java | 15 ++- .../simantics/maps/eclipse/MapPainter.java | 1 + .../src/org/simantics/maps/sg/MapNode.java | 55 ++++---- .../network/ui/DistrictDiagramViewer.java | 12 +- .../ui/DistrictPanZoomRotateHandler.java | 121 +++++++++++++++++- .../network/ui/DistrictTransformUtil.java | 75 +++++++++++ .../network/ui/NetworkDrawingParticipant.java | 2 +- .../adapters/DistrictNetworkEdgeElement.java | 2 +- .../DistrictNetworkVertexElement.java | 44 ++++++- .../ui/nodes/DistrictNetworkNodeUtils.java | 9 ++ .../ui/nodes/DistrictNetworkVertexNode.java | 26 ++-- .../network/ui/nodes/NetworkDrawingNode.java | 15 ++- .../ui/participants/DNPointerInteractor.java | 4 + .../ui/participants/MapRulerPainter.java | 4 +- 14 files changed, 333 insertions(+), 52 deletions(-) create mode 100644 org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictTransformUtil.java diff --git a/org.simantics.district.maps/src/org/simantics/maps/MapScalingTransform.java b/org.simantics.district.maps/src/org/simantics/maps/MapScalingTransform.java index f64a99f4..e29e8e55 100644 --- a/org.simantics.district.maps/src/org/simantics/maps/MapScalingTransform.java +++ b/org.simantics.district.maps/src/org/simantics/maps/MapScalingTransform.java @@ -6,8 +6,8 @@ public class MapScalingTransform { private MapScalingTransform() { } - - public static final AffineTransform INSTANCE = new AffineTransform(10000, 0, 0, 10000, 0, 0); + public static final double scale = 256.0d / 360.0d; + public static final AffineTransform INSTANCE = new AffineTransform(scale, 0, 0, scale, 0, 0); public static double getScaleX() { return INSTANCE.getScaleX(); @@ -16,4 +16,15 @@ public class MapScalingTransform { public static double getScaleY() { return INSTANCE.getScaleY(); } + + public static int zoomLevel(AffineTransform current) { + double org = INSTANCE.getScaleX(); + double cur = current.getScaleX(); + double f = cur / org; + double zoomLevel = Math.log10(f) / Math.log10(2); + if (zoomLevel < 0) { + zoomLevel = 0; + } + return (int) zoomLevel; + } } diff --git a/org.simantics.district.maps/src/org/simantics/maps/eclipse/MapPainter.java b/org.simantics.district.maps/src/org/simantics/maps/eclipse/MapPainter.java index 85398221..c519b9a5 100644 --- a/org.simantics.district.maps/src/org/simantics/maps/eclipse/MapPainter.java +++ b/org.simantics.district.maps/src/org/simantics/maps/eclipse/MapPainter.java @@ -138,6 +138,7 @@ public class MapPainter extends AbstractCanvasParticipant { protected void updateNode() { node.setEnabled(isPaintingEnabled()); + node.setEnabled(isMapEnabled()); node.setBackgroundColor(getBackgroundColor()); } diff --git a/org.simantics.district.maps/src/org/simantics/maps/sg/MapNode.java b/org.simantics.district.maps/src/org/simantics/maps/sg/MapNode.java index f9c6abf9..7ca092cf 100644 --- a/org.simantics.district.maps/src/org/simantics/maps/sg/MapNode.java +++ b/org.simantics.district.maps/src/org/simantics/maps/sg/MapNode.java @@ -36,6 +36,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import org.simantics.maps.MapScalingTransform; import org.simantics.maps.WebService; import org.simantics.maps.osm.OSMTileProvider; import org.simantics.maps.pojo.TileJobQueue; @@ -233,14 +234,16 @@ public class MapNode extends G2DNode implements ITileListener { AffineTransform ot = g2d.getTransform(); + //System.err.println("ot " + ot); g2d.transform(transform); AffineTransform tr = g2d.getTransform(); - + //System.err.println("tr " + tr); // Graphics2D g = (Graphics2D)g2d.create(); // AffineTransform tr = (AffineTransform)g.getTransform().clone(); double scaleX = Math.abs(tr.getScaleX()); + //System.err.println("scaleX : " + scaleX); double scaleY = Math.abs(tr.getScaleY()); if (scaleX <= 0 || scaleY <= 0) { // Make sure that we don't end up in an eternal loop below. @@ -255,20 +258,21 @@ public class MapNode extends G2DNode implements ITileListener { Rectangle2D b = (Rectangle2D)((Rectangle)g2d.getRenderingHint(G2DRenderingHints.KEY_CONTROL_BOUNDS)).getBounds2D(); // getClipBounds is not accurate enough, use original clipbounds and scale here Rectangle2D viewbox = new Rectangle2D.Double(offsetX/scaleX, offsetY/scaleY, b.getWidth()/sp.getWidth(), b.getHeight()/sp.getHeight()); //g.getClipBounds(); - if (enabled) { - - double smallerViewboxDimension = viewbox.getWidth() < viewbox.getHeight() ? viewbox.getWidth() * MAP_SCALE : viewbox.getHeight() * MAP_SCALE; - int level = 0; - double tileSize = 360 * MAP_SCALE*2; - while (level < MAX_TILE_LEVEL) { - double ratio = smallerViewboxDimension / tileSize; - if (ratio >= 0.85) { - break; - } - tileSize *= 0.5; - level++; - } + + int level = MapScalingTransform.zoomLevel(ot); + +// double smallerViewboxDimension = viewbox.getWidth() < viewbox.getHeight() ? viewbox.getWidth() * MAP_SCALE : viewbox.getHeight() * MAP_SCALE; +// int level = 0; +// double tileSize = 360 * MAP_SCALE*2.5; +// while (level < MAX_TILE_LEVEL) { +// double ratio = smallerViewboxDimension / tileSize; +// if (ratio >= 0.85) { +// break; +// } +// tileSize *= 0.5; +// level++; +// } /* * To convert y-coordinates to map coordinates in ruler, use: * double val = (y-offsetY)/scaleY; @@ -281,26 +285,31 @@ public class MapNode extends G2DNode implements ITileListener { double miny = Math.min(360, Math.max(viewbox.getMinY()+180, 0)); double maxy = Math.min(360, Math.max(viewbox.getMaxY()+180, 0)); - + //System.err.println("minx " + minx + " maxx " + maxx + " miny " + miny + " maxy " + maxy); g2d.setTransform(new AffineTransform()); g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); int levels = (1 << level); - + //System.err.println("level " + level); + //System.err.println("levels " + levels); // http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames int left = (int)Math.floor( (minx + 180) / 360 * (1<= levels) continue; - for(int ty = top; ty <= bottom; ty++) { - if(ty < 0 || ty >= levels) continue; + //System.err.println("tileSize " + tsx); + for (int tx = left; tx <= right; tx++) { + if (tx < 0 || tx >= levels) + continue; + for (int ty = top; ty <= bottom; ty++) { + if (ty < 0 || ty >= levels) + continue; TileKey tile = new TileKey(level, tx, ty); - double y = (double)ty - (double)levels/2; // In level 0 we have only one tile - paintTile(tileCache, g2d, tr, tile, tx*tsx-180, y*tsx, tsx); + double y = (double) ty - (double) levels / 2; // In level 0 we have only one tile + + paintTile(tileCache, g2d, tr, tile, tx * tsx - 180, y * tsx, tsx); } } // g.dispose(); 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 f0c76954..6175ace7 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,6 +1,7 @@ package org.simantics.district.network.ui; import java.awt.Color; +import java.awt.geom.AffineTransform; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Supplier; @@ -26,6 +27,7 @@ import org.simantics.g2d.participant.BackgroundPainter; import org.simantics.g2d.participant.GridPainter; import org.simantics.g2d.participant.PanZoomRotateHandler; import org.simantics.g2d.participant.RenderingQualityInteractor; +import org.simantics.g2d.participant.TransformUtil; import org.simantics.g2d.participant.ZoomToAreaHandler; import org.simantics.maps.MapScalingTransform; import org.simantics.maps.eclipse.MapPainter; @@ -48,9 +50,10 @@ public class DistrictDiagramViewer extends DiagramViewer { ctx.add(new ElementPainter()); ctx.add(new DNPointerInteractor()); - ctx.add(new MapPainter(MapScalingTransform.INSTANCE)); + AffineTransform tr = new AffineTransform(MapScalingTransform.INSTANCE); + ctx.add(new MapPainter(tr)); - ctx.add(new NetworkDrawingParticipant(MapScalingTransform.INSTANCE)); + ctx.add(new NetworkDrawingParticipant(tr)); } protected String getPopupId() { @@ -80,6 +83,11 @@ public class DistrictDiagramViewer extends DiagramViewer { } protected void addViewManipulationParticipants(CanvasContext ctx) { + // Let's replace with our special util + TransformUtil util = ctx.getAtMostOneItemOfClass(TransformUtil.class); + if (util != null) + ctx.remove(util); + ctx.add(new DistrictTransformUtil()); ctx.add(new DistrictPanZoomRotateHandler()); //ctx.add(new MousePanZoomInteractor()); //ctx.add(new MultitouchPanZoomRotateInteractor()); diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictPanZoomRotateHandler.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictPanZoomRotateHandler.java index 1a4f83d8..f9d9fccc 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictPanZoomRotateHandler.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictPanZoomRotateHandler.java @@ -1,23 +1,117 @@ package org.simantics.district.network.ui; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.util.Set; + +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; +import org.simantics.g2d.canvas.impl.DependencyReflection.Reference; +import org.simantics.g2d.diagram.participant.Selection; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.participant.CanvasBoundsParticipant; import org.simantics.g2d.participant.PanZoomRotateHandler; +import org.simantics.maps.MapScalingTransform; +import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler; import org.simantics.scenegraph.g2d.events.MouseEvent.MouseWheelMovedEvent; +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.NavigationNode; public class DistrictPanZoomRotateHandler extends PanZoomRotateHandler { + public static final int DISTRICT_TRANSLATE_AMOUNT = 2; + + @Dependency DistrictTransformUtil util; + @Reference Selection selection; + public DistrictPanZoomRotateHandler() { } + + @Override + public void addedToContext(ICanvasContext ctx) { + super.addedToContext(ctx); + setHint(KEY_TRANSLATE_AMOUNT, DISTRICT_TRANSLATE_AMOUNT); + } @Override protected Class getNavigationNodeClass() { return DistrictNavigationNode.class; } + @Override + public double getTranslateAmount() { + return 15 * super.getTranslateAmount(); + } + + @Override + public double limitScaleFactor(double scaleFactor) { + return scaleFactor; + } + + @Override + @EventHandler(priority = 1) + public boolean handleEvent(CommandEvent e) { + super.update(); + Command c = e.command; + boolean zoomDisabled = Boolean.TRUE.equals(getHint(KEY_DISABLE_ZOOM)) ? true : false; + // custom handling of zoom to fit & selection + if (Commands.ZOOM_TO_FIT.equals(c) && !zoomDisabled) { + boolean result = zoomToFit(); + if (!result) + result = zoomToPage(); + return result; + } + if (Commands.ZOOM_TO_PAGE.equals(c) && !zoomDisabled) { + return zoomToPage(); + } + if (Commands.ZOOM_TO_SELECTION.equals(c) && !zoomDisabled) { + return zoomToSelection(); + } + return super.handleEvent(e); + } + + private boolean zoomToFit() { + return false; + } + + private boolean zoomToPage() { + int currentZoomLevel = MapScalingTransform.zoomLevel(util.getTransform()); + + util.setTransform(new AffineTransform(2,0,0,2,270,270)); +// util.setTransform(new AffineTransform(MapScalingTransform.INSTANCE)); + return true; + } + + private boolean zoomToSelection() { + CanvasBoundsParticipant boundsParticipant = getContext().getAtMostOneItemOfClass(CanvasBoundsParticipant.class); + if (boundsParticipant == null) + return false; + + final Rectangle2D controlBounds = boundsParticipant.getControlBounds().getFrame(); + if (controlBounds == null || controlBounds.isEmpty()) + return false; + + Set selections = selection.getAllSelections(); + Rectangle2D diagramRect = ElementUtils.getSurroundingElementBoundsOnDiagram(selections); + + // Make sure that even empty bounds can be zoomed into. + org.simantics.scenegraph.utils.GeometryUtils.expandRectangle(diagramRect, 1); + + util.fitArea(controlBounds, diagramRect, null); + return true; + } + public static class DistrictNavigationNode extends NavigationNode { private static final long serialVersionUID = 5452897272925816875L; + public DistrictNavigationNode() { + setAdaptViewportToResizedControl(false); + } + @Override public Double getZoomInLimit() { return super.getZoomInLimit(); @@ -28,23 +122,40 @@ public class DistrictPanZoomRotateHandler extends PanZoomRotateHandler { return super.getZoomOutLimit(); } + @Override + public void setAdaptViewportToResizedControl(Boolean adapt) { + super.setAdaptViewportToResizedControl(false); + // no op + } + + @Override + public boolean getAdaptViewportToResizedControl() { + return false; + } + @Override public boolean mouseWheelMoved(MouseWheelMovedEvent me) { if (navigationEnabled && zoomEnabled) { - double scroll = Math.min(0.9, -me.wheelRotation / 20.0); - double z = 1 - scroll; + double z; + if (me.wheelRotation > 0) { + z = DISTRICT_TRANSLATE_AMOUNT; + } else { + z = 1.0d / DISTRICT_TRANSLATE_AMOUNT; + } + //double scroll = Math.min(0.9, -me.wheelRotation / 20.0); + //double z = 1 - scroll; double dx = (me.controlPosition.getX() - transform.getTranslateX()) / transform.getScaleX(); double dy = (me.controlPosition.getY() - transform.getTranslateY()) / transform.getScaleY(); dx = dx * (1 - z); dy = dy * (1 - z); - double limitedScale = limitScaleFactor(z); - if (limitedScale != 1.0) { +// double limitedScale = limitScaleFactor(z); +// if (limitedScale != 1.0) { translate(dx, dy); scale(z, z); transformChanged(); dropQuality(); repaint(); - } +// } } return false; } diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictTransformUtil.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictTransformUtil.java new file mode 100644 index 00000000..230c17cd --- /dev/null +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictTransformUtil.java @@ -0,0 +1,75 @@ +package org.simantics.district.network.ui; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; + +import org.simantics.g2d.participant.TransformUtil; +import org.simantics.scenegraph.utils.GeometryUtils; +import org.simantics.utils.page.MarginUtils; +import org.simantics.utils.page.MarginUtils.Margins; + +public class DistrictTransformUtil extends TransformUtil { + + @Override + public void fitArea(Rectangle2D controlArea, Rectangle2D diagramArea, Margins margins) { + if (margins == null) { + MarginUtils.Margin margin = MarginUtils.marginOf(40, 0, 0); + margins = new MarginUtils.Margins(margin, margin, margin, margin); + } + org.simantics.scenegraph.utils.GeometryUtils.expandRectangle(diagramArea, -1); + diagramArea = GeometryUtils.expandRectangle(diagramArea, + margins.top.diagramAbsolute, + margins.bottom.diagramAbsolute, + margins.left.diagramAbsolute, + margins.right.diagramAbsolute); + controlArea = GeometryUtils.expandRectangle(controlArea, + -margins.top.controlAbsolute - margins.top.controlRelative * controlArea.getHeight(), + -margins.bottom.controlAbsolute - margins.bottom.controlRelative * controlArea.getHeight(), + -margins.left.controlAbsolute - margins.left.controlRelative * controlArea.getWidth(), + -margins.right.controlAbsolute - margins.right.controlRelative * controlArea.getWidth()); + + double controlAspectRatio = controlArea.getWidth() / controlArea.getHeight(); + double canvasAspectRatio = diagramArea.getWidth() / diagramArea.getHeight(); + // Control is really wide => center canvas horizontally, match vertically + double scale = 1.0; + double tx = 0.0; + double ty = 0.0; + if (controlAspectRatio>canvasAspectRatio) + { + scale = controlArea.getHeight() / diagramArea.getHeight(); + tx = ( controlArea.getWidth() - diagramArea.getWidth() * scale ) / 2; + } else + // Control is really tall => center canvas vertically, match horizontally + { + scale = controlArea.getWidth() / diagramArea.getWidth(); + ty = ( controlArea.getHeight() - diagramArea.getHeight() * scale ) / 2; + } + AffineTransform current = getTransform(); + double currentX = current.getScaleX(); + double targetX = scale; + double toBeX = currentX; + if (targetX > 0) { + if (toBeX < targetX) { + while ((toBeX) < targetX) { + toBeX = toBeX * 2; + } + } else { + while ((toBeX * 0.5) > targetX) { + toBeX = toBeX * 0.5; + } + } + //tx = tx * (1 - toBeX); + //ty = ty * (1 - toBeX); + AffineTransform at = new AffineTransform(); + at.translate(tx, ty); + at.translate(controlArea.getMinX(), controlArea.getMinY()); + at.scale(toBeX, toBeX); + at.translate(-diagramArea.getMinX(), -diagramArea.getMinY()); + + setTransform(at); + } else { + // negative, how, no can do? + + } + } +} diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/NetworkDrawingParticipant.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/NetworkDrawingParticipant.java index 73abf31e..69d1f724 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/NetworkDrawingParticipant.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/NetworkDrawingParticipant.java @@ -59,7 +59,7 @@ public class NetworkDrawingParticipant extends AbstractDiagramParticipant { } public boolean pickHoveredElement(Point2D currentMousePos) { - PickRequest req = new PickRequest(currentMousePos.getX(), currentMousePos.getY()).context(getContext()); + PickRequest req = new PickRequest(currentMousePos).context(getContext()); List pickables = new ArrayList(); pick.pick(diagram, req, pickables); diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java index d4758007..ce57e0a2 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java @@ -163,7 +163,7 @@ public class DistrictNetworkEdgeElement { } private boolean pickIntersectingObjects(DistrictNetworkEdge edge, Rectangle2D bounds) { - double tolerance = (bounds.getHeight() + bounds.getHeight()) * 0.25 / MapScalingTransform.getScaleX(); + double tolerance = (bounds.getHeight() + bounds.getHeight()) * 1 / MapScalingTransform.getScaleX(); Line2D line = new Line2D.Double(edge.getStartPoint(), edge.getEndPoint()); double sx = bounds.getCenterX() / MapScalingTransform.getScaleX(); double sy = bounds.getCenterY() / MapScalingTransform.getScaleY(); diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkVertexElement.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkVertexElement.java index 7be6a14f..b3e7fda3 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkVertexElement.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkVertexElement.java @@ -1,21 +1,28 @@ package org.simantics.district.network.ui.adapters; import java.awt.Color; +import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; +import org.simantics.diagram.elements.DiagramNodeUtil; import org.simantics.district.network.ui.nodes.DistrictNetworkVertexNode; +import org.simantics.g2d.canvas.Hints; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.handler.PickRequest.PickPolicy; import org.simantics.g2d.element.ElementClass; import org.simantics.g2d.element.ElementUtils; import org.simantics.g2d.element.IElement; import org.simantics.g2d.element.SceneGraphNodeKey; import org.simantics.g2d.element.handler.InternalSize; +import org.simantics.g2d.element.handler.Pick; import org.simantics.g2d.element.handler.SceneGraph; import org.simantics.g2d.element.handler.impl.DefaultTransform; import org.simantics.g2d.element.handler.impl.SimpleElementLayers; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.g2d.G2DParentNode; import org.simantics.scenegraph.g2d.nodes.SVGNode; +import org.simantics.scenegraph.utils.GeometryUtils; import org.simantics.utils.datastructures.hints.IHintContext.Key; import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; @@ -77,7 +84,7 @@ public class DistrictNetworkVertexElement { } } - static final class DNVertexInternalSize implements InternalSize { + static final class DNVertexInternalSize implements InternalSize, Pick { public static final DNVertexInternalSize INSTANCE = new DNVertexInternalSize(); @@ -87,9 +94,42 @@ public class DistrictNetworkVertexElement { public Rectangle2D getBounds(IElement e, Rectangle2D size) { DistrictNetworkVertexNode node = e.getHint(KEY_DN_VERTEX_NODE); Rectangle2D boundsInLocal = node.getBoundsInLocal(); - size.setFrame(boundsInLocal); + ICanvasContext ctx = DiagramNodeUtil.getCanvasContext(node); + AffineTransform canvasTransform = ctx.getHintStack().getHint(Hints.KEY_CANVAS_TRANSFORM); + // for some reason PickContextImpl expands the rectangle by 0.001 (too much) - let's counter it + double counterExpansion = 0.001; + double x = boundsInLocal.getX() + counterExpansion; + double y = boundsInLocal.getY() + counterExpansion; + double scaledWidth = boundsInLocal.getWidth() / canvasTransform.getScaleX() / 10000.0; + double scaledHeight = boundsInLocal.getHeight() / canvasTransform.getScaleY() / 10000.0; + double width = scaledWidth - 2*counterExpansion; + double height = scaledHeight - 2*counterExpansion; + size.setFrame(x, y, width, height); + return size; } + + @Override + public boolean pickTest(IElement e, Shape s, PickPolicy policy) { + DistrictNetworkVertexNode node = e.getHint(KEY_DN_VERTEX_NODE); + Rectangle2D boundsInLocal = node.getBounds(); + ICanvasContext ctx = DiagramNodeUtil.getCanvasContext(node); + AffineTransform canvasTransform = ctx.getHintStack().getHint(Hints.KEY_CANVAS_TRANSFORM); + Rectangle2D scaledBounds = new Rectangle2D.Double(boundsInLocal.getX(), boundsInLocal.getY(), boundsInLocal.getWidth() / canvasTransform.getScaleX() * 2, boundsInLocal.getHeight() / canvasTransform.getScaleY() * 2); + Rectangle2D bounds = getBounds(s); + switch (policy) { + case PICK_CONTAINED_OBJECTS: + return org.simantics.g2d.utils.GeometryUtils.contains(bounds, boundsInLocal); + case PICK_INTERSECTING_OBJECTS: + return org.simantics.g2d.utils.GeometryUtils.intersects(boundsInLocal, bounds); + } + return false; + } + private Rectangle2D getBounds(Shape shape) { + if (shape instanceof Rectangle2D) + return (Rectangle2D) shape; + return shape.getBounds2D(); + } } } diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkNodeUtils.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkNodeUtils.java index 8a369e26..c48693ac 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkNodeUtils.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkNodeUtils.java @@ -5,6 +5,8 @@ import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import org.simantics.district.network.ModelledCRS; +import org.simantics.maps.MapScalingTransform; +import org.simantics.scenegraph.utils.GeometryUtils; public class DistrictNetworkNodeUtils { @@ -35,4 +37,11 @@ public class DistrictNetworkNodeUtils { return transform; } + public static double calculateScaleRecip(AffineTransform tr) { + int zoomLevel = MapScalingTransform.zoomLevel(tr); + double scale = GeometryUtils.getScale(tr); + double sqrt = Math.sqrt(scale / zoomLevel); + double viewScaleRecip = (sqrt / zoomLevel); + return viewScaleRecip; + } } 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 377c7f7e..6fb075eb 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 @@ -23,13 +23,13 @@ public class DistrictNetworkVertexNode extends G2DParentNode implements ISelecti private static final long serialVersionUID = -2641639101400236719L; - private static final BasicStroke STROKE = new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); - private static final Color SELECTION_COLOR = new Color(255, 0, 255, 96); + private static final double left = -0.00005; + private static final double top = left; + public static final double width = 0.0001; + private static final double height = width; - private static final double left = -0.25; - private static final double top = -0.25; - private static final double width = 0.5; - private static final double height = 0.5; + private static final BasicStroke STROKE = new BasicStroke((float)width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); + private static final Color SELECTION_COLOR = new Color(255, 0, 255, 96); private static final Rectangle2D NORMAL = new Rectangle2D.Double(left, top, width, height); private static final Rectangle2D HOVERED = new Rectangle2D.Double(left * 3, top * 3, width * 3, height * 3); @@ -63,7 +63,7 @@ public class DistrictNetworkVertexNode extends G2DParentNode implements ISelecti AffineTransform t = getTransform(); if (t != null && !t.isIdentity()) { ot = g2d.getTransform(); - g2d.transform(getTransform()); + g2d.transform(t); } Object oaaHint = null; @@ -77,11 +77,9 @@ public class DistrictNetworkVertexNode extends G2DParentNode implements ISelecti Color newColor = dynamicColor != null ? dynamicColor : color; boolean changeColor = !oldColor.equals(newColor); - double viewScaleRecip = 10; + double viewScaleRecip = 1; if (scaleStroke) { - double scale = GeometryUtils.getScale(g2d.getTransform()); - scale = Math.max(10000, Math.min(scale, 50000)); - viewScaleRecip /= scale; + viewScaleRecip *= DistrictNetworkNodeUtils.calculateScaleRecip(g2d.getTransform()); } double scaleRecip = viewScaleRecip * nodeSize; @@ -152,7 +150,11 @@ public class DistrictNetworkVertexNode extends G2DParentNode implements ISelecti private Rectangle2D calculateBounds(Rectangle2D rect) { Point2D calcPoint = DistrictNetworkNodeUtils.calculatePoint2D(vertex.getPoint(), point); AffineTransform at = getTransform(); - return new Rectangle2D.Double(calcPoint.getX(), calcPoint.getY(), width / at.getScaleX(), height / at.getScaleY()).getBounds2D(); + double x = calcPoint.getX(); + double y = calcPoint.getY(); + double widthh = width / at.getScaleX(); + double heighth = height / at.getScaleY(); + return new Rectangle2D.Double(x - widthh, y - heighth, widthh * 2, heighth * 2).getBounds2D(); } public void setVertex(DistrictNetworkVertex 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 71ccb781..674702b8 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 @@ -4,6 +4,7 @@ import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Stroke; +import java.awt.geom.AffineTransform; import java.awt.geom.Path2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; @@ -16,11 +17,13 @@ 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.elements.DiagramNodeUtil; import org.simantics.diagram.ui.DiagramModelHints; import org.simantics.district.network.ModelledCRS; 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.ICanvasContext; import org.simantics.g2d.canvas.IToolMode; import org.simantics.g2d.diagram.IDiagram; import org.simantics.scenegraph.g2d.G2DNode; @@ -158,8 +161,14 @@ public class NetworkDrawingNode extends G2DNode { private void createEdge(Point2D start, Point2D end) { - double padding = GeometryUtils.getScale(getTransform()); - + double currentPadding = DistrictNetworkVertexNode.width; + AffineTransform test = getTransform(); + ICanvasContext ctx = DiagramNodeUtil.getCanvasContext(this); + AffineTransform tr = ctx.getHintStack().getHint(Hints.KEY_CANVAS_TRANSFORM); + AffineTransform testing = new AffineTransform(tr); + testing.concatenate(test); + double calculateScaleRecip = DistrictNetworkNodeUtils.calculateScaleRecip(testing); + double padding = currentPadding * calculateScaleRecip; /* * To convert y-coordinates to map coordinates in ruler, use: * double val = (y-offsetY)/scaleY; @@ -184,7 +193,7 @@ public class NetworkDrawingNode extends G2DNode { @Override public void perform(WriteGraph graph) throws DatabaseException { - builder.create(graph, startCoords, endCoords, 1 / padding); + builder.create(graph, startCoords, endCoords, padding); } }); 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 c61adba9..9df6e5ef 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 @@ -81,4 +81,8 @@ public class DNPointerInteractor extends PointerInteractor { return false; } + @Override + public double getPickDistance() { + return 0.00001; + } } diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/MapRulerPainter.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/MapRulerPainter.java index ecdbf275..cdf0b530 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/MapRulerPainter.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/MapRulerPainter.java @@ -1,5 +1,7 @@ package org.simantics.district.network.ui.participants; +import java.awt.geom.AffineTransform; + import org.simantics.district.network.ui.nodes.MapRulerNode; import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit; import org.simantics.g2d.participant.RulerPainter; @@ -12,7 +14,7 @@ public class MapRulerPainter extends RulerPainter { @Override public void initSG(G2DParentNode parent) { node = parent.addNode("ruler", getNodeClass()); - node.setTransform(MapScalingTransform.INSTANCE); + node.setTransform(new AffineTransform(MapScalingTransform.INSTANCE)); node.setZIndex(PAINT_PRIORITY); updateNode(); } -- 2.45.2 From 17c52752fcc15ee30a7790b96e3976214077761b Mon Sep 17 00:00:00 2001 From: jsimomaa Date: Thu, 28 Feb 2019 11:15:13 +0200 Subject: [PATCH 11/16] Add location & zoom node for network diagram - also OSM attribution gitlab #33 Change-Id: I170d79d1af403d0dde6fb5b9ec8feb3157a1c113 --- .../simantics/maps/eclipse/MapPainter.java | 51 ++++- .../simantics/maps/sg/MapAttributionNode.java | 83 ++++++++ .../maps/sg/MapLocationZoomInfoNode.java | 182 ++++++++++++++++++ .../org/simantics/maps/sg/MapScaleNode.java | 8 +- 4 files changed, 318 insertions(+), 6 deletions(-) create mode 100644 org.simantics.district.maps/src/org/simantics/maps/sg/MapAttributionNode.java create mode 100644 org.simantics.district.maps/src/org/simantics/maps/sg/MapLocationZoomInfoNode.java diff --git a/org.simantics.district.maps/src/org/simantics/maps/eclipse/MapPainter.java b/org.simantics.district.maps/src/org/simantics/maps/eclipse/MapPainter.java index c519b9a5..ef88e1c5 100644 --- a/org.simantics.district.maps/src/org/simantics/maps/eclipse/MapPainter.java +++ b/org.simantics.district.maps/src/org/simantics/maps/eclipse/MapPainter.java @@ -13,24 +13,35 @@ package org.simantics.maps.eclipse; import java.awt.Color; import java.awt.geom.AffineTransform; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; import org.simantics.g2d.canvas.Hints; import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant; import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup; import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit; +import org.simantics.g2d.participant.MouseUtil; +import org.simantics.maps.sg.MapAttributionNode; +import org.simantics.maps.sg.MapLocationZoomInfoNode; import org.simantics.maps.sg.MapNode; import org.simantics.maps.sg.MapScaleNode; import org.simantics.maps.sg.commands.MapCommands; 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.MouseEvent.MouseMovedEvent; import org.simantics.scenegraph.g2d.events.command.CommandEvent; import org.simantics.scenegraph.g2d.events.command.Commands; import org.simantics.utils.datastructures.hints.HintListenerAdapter; -import org.simantics.utils.datastructures.hints.IHintListener; -import org.simantics.utils.datastructures.hints.IHintObservable; import org.simantics.utils.datastructures.hints.IHintContext.Key; import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; +import org.simantics.utils.datastructures.hints.IHintListener; +import org.simantics.utils.datastructures.hints.IHintObservable; +import org.simantics.utils.threads.AWTThread; +import org.simantics.utils.threads.ThreadUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * MapPainter is an ICanvasContext participant that uses the scene graph @@ -42,6 +53,8 @@ import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; */ public class MapPainter extends AbstractCanvasParticipant { + private static final Logger LOGGER = LoggerFactory.getLogger(MapPainter.class); + /** * Grid enabled status. Default value is True */ @@ -68,6 +81,10 @@ public class MapPainter extends AbstractCanvasParticipant { private AffineTransform transform; + private MapLocationZoomInfoNode locationZoomInfoNode; + + private ScheduledFuture schedule; + public MapPainter(AffineTransform transform) { this.transform = transform; } @@ -118,6 +135,24 @@ public class MapPainter extends AbstractCanvasParticipant { return false; } + @EventHandler(priority = 31) + public boolean handleEvent(Event e) { + if (e instanceof MouseMovedEvent) { + // here we should somehow re-render ? + if (locationZoomInfoNode.isEnabled()) { + if (schedule == null || schedule.isDone()) { + LOGGER.debug("current setDirty time" + System.currentTimeMillis()); + schedule = ThreadUtils.getNonBlockingWorkExecutor().schedule(() -> { + AWTThread.getThreadAccess().asyncExec(this::setDirty); + }, 100, TimeUnit.MILLISECONDS); + } else { + //LOGGER.debug("ingoring setDirty time" + System.currentTimeMillis()); + } + } + } + return false; + } + @SGInit public void initSG(G2DParentNode parent) { node = parent.addNode("map", MapNode.class); @@ -129,6 +164,18 @@ public class MapPainter extends AbstractCanvasParticipant { scaleNode.setTransform(transform); scaleNode.setEnabled(true); scaleNode.setZIndex(Integer.MAX_VALUE - 999); // Just under the grid + + locationZoomInfoNode = parent.addNode("locationZoomInfo", MapLocationZoomInfoNode.class); + locationZoomInfoNode.setTransform(transform); + locationZoomInfoNode.setEnabled(true); + MouseUtil mouseUtil = getContext().getAtMostOneItemOfClass(MouseUtil.class); + locationZoomInfoNode.setMouseUtil(mouseUtil); + locationZoomInfoNode.setZIndex(Integer.MAX_VALUE - 999); // Just under the grid + + MapAttributionNode addNode = parent.addNode("mapAttribution", MapAttributionNode.class); + addNode.setTransform(transform); + addNode.setEnabled(true); + addNode.setZIndex(Integer.MAX_VALUE - 999); } @SGCleanup diff --git a/org.simantics.district.maps/src/org/simantics/maps/sg/MapAttributionNode.java b/org.simantics.district.maps/src/org/simantics/maps/sg/MapAttributionNode.java new file mode 100644 index 00000000..66543aac --- /dev/null +++ b/org.simantics.district.maps/src/org/simantics/maps/sg/MapAttributionNode.java @@ -0,0 +1,83 @@ +package org.simantics.maps.sg; + +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; + +import org.simantics.scenegraph.g2d.G2DNode; + +public class MapAttributionNode extends G2DNode { + + private static final long serialVersionUID = 7994492218791569147L; + + private static final Color GRAY = new Color(100, 100, 100); + + protected boolean enabled = true; + + @Override + public void render(Graphics2D g2d) { + if (!enabled) + return; + + AffineTransform ot = g2d.getTransform(); + Color originalColor = g2d.getColor(); + g2d.transform(transform); + + AffineTransform tr = g2d.getTransform(); + + g2d.setTransform(new AffineTransform()); + // do the rendering magic + + Font rulerFont = new Font("Tahoma", Font.PLAIN, 9); + + //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setStroke(new BasicStroke(1)); + g2d.setColor(new Color(0.9f, 0.9f, 0.9f, 0.75f)); + + Rectangle2D bounds = g2d.getClipBounds(); + if (bounds == null) + return; // FIXME + + String str = "Map data © OpenStreetMap contributors"; + FontMetrics fm = g2d.getFontMetrics(); + Rectangle2D r = fm.getStringBounds(str, g2d); + + double pixels = r.getWidth(); + double scaleRight = bounds.getMaxX(); + double newScaleLeft = scaleRight - pixels; + double y = bounds.getMaxY(); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f)); + + + Rectangle2D vertical = new Rectangle2D.Double(newScaleLeft - 10, y - 15, pixels + 10, 15); + g2d.fill(vertical); + + g2d.setColor(GRAY); + g2d.setFont(rulerFont); + + + g2d.setColor(Color.BLACK); + g2d.drawString(str, (int)newScaleLeft - 5, (int)y - 5); + + g2d.setColor(originalColor); + g2d.setTransform(ot); + } + + @Override + public Rectangle2D getBoundsInLocal() { + return null; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } +} diff --git a/org.simantics.district.maps/src/org/simantics/maps/sg/MapLocationZoomInfoNode.java b/org.simantics.district.maps/src/org/simantics/maps/sg/MapLocationZoomInfoNode.java new file mode 100644 index 00000000..bad499e6 --- /dev/null +++ b/org.simantics.district.maps/src/org/simantics/maps/sg/MapLocationZoomInfoNode.java @@ -0,0 +1,182 @@ +package org.simantics.maps.sg; + +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.Locale; + +import org.simantics.g2d.participant.MouseUtil; +import org.simantics.g2d.participant.MouseUtil.MouseInfo; +import org.simantics.maps.MapScalingTransform; +import org.simantics.scenegraph.g2d.G2DNode; + +public class MapLocationZoomInfoNode extends G2DNode { + + private static final long serialVersionUID = 7994492218791569147L; + + private static final Color GRAY = new Color(100, 100, 100); + + protected boolean enabled = true; + + private MouseUtil util; + + @Override + public void render(Graphics2D g2d) { + if (!enabled) + return; + + AffineTransform ot = g2d.getTransform(); + Color originalColor = g2d.getColor(); + g2d.transform(transform); + + AffineTransform tr = g2d.getTransform(); + + g2d.setTransform(new AffineTransform()); + // do the rendering magic + + Font rulerFont = new Font("Tahoma", Font.PLAIN, 9); + + //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setStroke(new BasicStroke(1)); + g2d.setColor(new Color(0.9f, 0.9f, 0.9f, 0.75f)); + + Rectangle2D bounds = g2d.getClipBounds(); + if (bounds == null) + return; // FIXME + + int zoomLevel = MapScalingTransform.zoomLevel(ot); + MouseInfo mouseInfo = util.getMouseInfo(0); + + double startLat; + double startLon; + if (mouseInfo != null && mouseInfo.canvasPosition != null) { + Point2D canvasPosition = mouseInfo.canvasPosition; + double cx = canvasPosition.getX(); + double cy = canvasPosition.getY(); + + startLat = yToLatitude(-cy / transform.getScaleY()); + startLon = xToLongitude(cx / transform.getScaleX()); + } else { + startLat = 0; + startLon = 0; + } + + String str = "X: " + formatValue(startLon, MAX_DIGITS) + ", Y: " + formatValue(startLat, MAX_DIGITS) + ", Z: " + zoomLevel; + FontMetrics fm = g2d.getFontMetrics(); + Rectangle2D r = fm.getStringBounds(str, g2d); + + double pixels = r.getWidth() + 10; + double scaleRight = bounds.getMaxX() - 20; + double newScaleLeft = scaleRight - pixels; + double y = bounds.getMaxY() - 65; + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f)); + + + Rectangle2D vertical = new Rectangle2D.Double(newScaleLeft, y, pixels, 20); + g2d.fill(vertical); + + g2d.setColor(GRAY); + g2d.setFont(rulerFont); + + + g2d.setColor(Color.BLACK); + g2d.drawString(str, (int)newScaleLeft + 5, (int)y + 15); + + g2d.setColor(originalColor); + g2d.setTransform(ot); + } + + @Override + public Rectangle2D getBoundsInLocal() { + return null; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public void setMouseUtil(MouseUtil util) { + this.util = util; + } + + private static final transient int MAX_DIGITS = 7; + private static final transient double EPSILON = 0.01; + private static final transient double TRIM_THRESHOLD_MAX_VALUE = Math.pow(10, 4); + private static final transient String[] SI_UNIT_LARGE_PREFIXES = { + "k", "M", "G", "T", "P", "E", "Z", "Y" + }; + + private static String formatValue(double value, int maxDigits) { + int magnitude = (int) Math.round(Math.log10(value)); + //System.out.println("magnitude: " + magnitude + ", " + value); + int allowedDecimals = maxDigits; + allowedDecimals -= Math.abs(magnitude); + if (allowedDecimals < 0) + allowedDecimals = 0; + + String valueStr = String.format(Locale.US, "%." + allowedDecimals + "f", value); + if (allowedDecimals > 0) { + for (int trunc = valueStr.length() - 1; trunc > 0; --trunc) { + char ch = valueStr.charAt(trunc); + if (ch == '.') { + valueStr = valueStr.substring(0, trunc); + break; + } + if (valueStr.charAt(trunc) != '0') { + valueStr = valueStr.substring(0, trunc + 1); + break; + } + } + if (Math.abs(value) + EPSILON > TRIM_THRESHOLD_MAX_VALUE) { + // Cut anything beyond a possible decimal dot out since they + // should not show anyway. This is a complete hack that tries to + // circumvent floating-point inaccuracy problems. + int dotIndex = valueStr.lastIndexOf('.'); + if (dotIndex > -1) { + valueStr = valueStr.substring(0, dotIndex); + } + } + } + + double trimValue = value; + if (Math.abs(value)+EPSILON >= TRIM_THRESHOLD_MAX_VALUE) { + for (int i = 0; Math.abs(trimValue)+EPSILON >= TRIM_THRESHOLD_MAX_VALUE; ++i) { + double trim = trimValue / 1000; + if (Math.abs(trim)-EPSILON < TRIM_THRESHOLD_MAX_VALUE) { + valueStr = valueStr.substring(0, valueStr.length() - (i + 1) * 3); + valueStr += SI_UNIT_LARGE_PREFIXES[i]; + break; + } + trimValue = trim; + } + } + + if (valueStr.equals("-0")) + valueStr = "0"; + + return valueStr; + } + + // TODO: these only work with Spherical Mercator + private static double xToLongitude(double x) { + return x; + } + + private static double yToLatitude(double y) { + double rad = Math.toRadians(y); + double sinh = Math.sinh(rad); + double atan = Math.atan(sinh); + double finald = Math.toDegrees(atan); + return finald; + } +} diff --git a/org.simantics.district.maps/src/org/simantics/maps/sg/MapScaleNode.java b/org.simantics.district.maps/src/org/simantics/maps/sg/MapScaleNode.java index 793550b6..dc6b393d 100644 --- a/org.simantics.district.maps/src/org/simantics/maps/sg/MapScaleNode.java +++ b/org.simantics.district.maps/src/org/simantics/maps/sg/MapScaleNode.java @@ -58,9 +58,9 @@ public class MapScaleNode extends G2DNode { double previousText = -100; - double minY = bounds.getMaxY() - 30; + double minY = bounds.getMaxY() - 40; - double scaleRight = bounds.getMaxX() - 30; + double scaleRight = bounds.getMaxX() - 20; double meterPerPixel = getMeterPerPixel(scaleRight - offsetX, minY - offsetY, scaleX, scaleY); @@ -77,7 +77,7 @@ public class MapScaleNode extends G2DNode { double newScaleLeft = scaleRight - pixels; g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f)); - Rectangle2D vertical = new Rectangle2D.Double(newScaleLeft, bounds.getMaxY() - 30, pixels, 20); + Rectangle2D vertical = new Rectangle2D.Double(newScaleLeft, bounds.getMaxY() - 40, pixels, 20); g.fill(vertical); g.setColor(GRAY); @@ -101,9 +101,9 @@ public class MapScaleNode extends G2DNode { // Horizontal ruler double label = 0; + FontMetrics fm = g.getFontMetrics(); for(double x = newScaleLeft; x < scaleRight; x += stepX) { String str = formatValue(label * meterPerPixel); - FontMetrics fm = g.getFontMetrics(); Rectangle2D r = fm.getStringBounds(str, g); if((x - r.getWidth() / 2) > previousText) { g.setColor(Color.BLACK); -- 2.45.2 From e44d154379425df392dd983b9d6e0db82474a456 Mon Sep 17 00:00:00 2001 From: Reino Ruusu Date: Mon, 4 Mar 2019 17:33:03 +0200 Subject: [PATCH 12/16] Resolve tie situations in n lowest/highest element selection. Pick all elements that match the value of the n'th lowest/highest one. Change-Id: I066ae39a2f7db73db93a6c3d4c9531ba4300236f (cherry picked from commit 50306ed44f39142ec59265c7329e8e5930b9ff38) --- .../district/selection/ElementSelector.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/org.simantics.district.selection/src/org/simantics/district/selection/ElementSelector.java b/org.simantics.district.selection/src/org/simantics/district/selection/ElementSelector.java index 74eaa227..bf051b4c 100644 --- a/org.simantics.district.selection/src/org/simantics/district/selection/ElementSelector.java +++ b/org.simantics.district.selection/src/org/simantics/district/selection/ElementSelector.java @@ -543,13 +543,12 @@ public class ElementSelector { @SuppressWarnings("unchecked") @Override Collection select(ReadGraph graph, Collection elements) { - List result = new ArrayList<>(elements); List result2 = Lists.map(new FunctionImpl1() { @Override public Tuple2 apply(Resource r) { return new Tuple2(r, getPropertyValue(graph, r, propertyName)); } - }, result); + }, new ArrayList<>(elements)); result2 = Lists.filter(new FunctionImpl1() { @Override @@ -560,17 +559,21 @@ public class ElementSelector { result2.sort((t1, t2) -> smallest ? Double.compare((Double) t1.c1, (Double) t2.c1) : Double.compare((Double) t2.c1, (Double) t1.c1)); - if (resultCount < result2.size()) - result2 = result2.subList(0, resultCount); + if (resultCount < result2.size()) { + double limitValue = (double) result2.get(resultCount-1).c1; + + // Expand selection to contain all items with the same value as the nth one + int count = resultCount; + while (count < result2.size() && (double)result2.get(count).c1 == limitValue) count++; + result2 = result2.subList(0, count); + } - result = Lists.map(new FunctionImpl1() { + return (List) Lists.map(new FunctionImpl1() { @Override public Resource apply(Tuple2 p0) { return (Resource) p0.c0; } }, result2); - - return result; } } -- 2.45.2 From 5f2682885a16b6f23b4a80b967b56b3e086cbaef Mon Sep 17 00:00:00 2001 From: Reino Ruusu Date: Wed, 6 Mar 2019 11:45:37 +0200 Subject: [PATCH 13/16] Presentation of component-specific actions. gitlab #34 Change-Id: I9a88cbaf22c119dbf60a02fc67e7cc98f5d9148b (cherry picked from commit ee7e19e97c21555c72e1e7252eb34104d8137163) --- .../fragment.e4xmi | 1 + .../NetworkElementActionMenuContribution.java | 174 ++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/NetworkElementActionMenuContribution.java diff --git a/org.simantics.district.network.ui/fragment.e4xmi b/org.simantics.district.network.ui/fragment.e4xmi index a77581cd..fb9bde4c 100644 --- a/org.simantics.district.network.ui/fragment.e4xmi +++ b/org.simantics.district.network.ui/fragment.e4xmi @@ -18,6 +18,7 @@ + diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/NetworkElementActionMenuContribution.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/NetworkElementActionMenuContribution.java new file mode 100644 index 00000000..b3cc0891 --- /dev/null +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/NetworkElementActionMenuContribution.java @@ -0,0 +1,174 @@ +package org.simantics.district.network.ui.contributions; + +import java.util.Collections; +import java.util.List; + +import javax.inject.Named; + +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.di.AboutToHide; +import org.eclipse.e4.ui.di.AboutToShow; +import org.eclipse.e4.ui.model.application.ui.menu.MDirectMenuItem; +import org.eclipse.e4.ui.model.application.ui.menu.MMenu; +import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement; +import org.eclipse.e4.ui.model.application.ui.menu.MMenuFactory; +import org.eclipse.e4.ui.services.IServiceConstants; +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.procedure.adapter.TransientCacheListener; +import org.simantics.db.common.request.ResourceRead; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.NoSingleResultException; +import org.simantics.db.layer0.SelectionHints; +import org.simantics.db.layer0.util.Layer0Utils; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.district.network.ontology.DistrictNetworkResource; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.scl.compiler.top.ValueNotFound; +import org.simantics.scl.osgi.SCLOsgi; +import org.simantics.scl.runtime.SCLContext; +import org.simantics.scl.runtime.function.Function; +import org.simantics.scl.runtime.tuple.Tuple2; +import org.simantics.utils.ui.ISelectionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NetworkElementActionMenuContribution { + + static private Logger LOGGER = LoggerFactory.getLogger(NetworkElementActionMenuContribution.class); + + @AboutToShow + public void aboutToShow(@Named(IServiceConstants.ACTIVE_SELECTION) Object selection, List items) { + final List vertices = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class); + if (vertices.size() != 1) + return; + + Resource vertex = vertices.get(0); + + List actions; + try { + actions = Simantics.getSession().syncRequest(new ActionItemRequest(vertex), TransientCacheListener.instance()); + } catch (DatabaseException e) { + LOGGER.error("Error fetching action items for " + vertex, e); + return; + } + + items.add(MMenuFactory.INSTANCE.createMenuSeparator()); + MMenu subMenu = MMenuFactory.INSTANCE.createMenu(); + List children = subMenu.getChildren(); + subMenu.setLabel("Component Actions"); + items.add(subMenu); + + for (Tuple2 action : actions) { + String label = (String) action.c0; + @SuppressWarnings("rawtypes") + Function function = (Function) action.c1; + + Object handler = new Object() { + @CanExecute + public boolean canExecute() { + try { + return Simantics.getSession().syncRequest(new ResourceRead(vertex) { + @Override + public Boolean perform(ReadGraph graph) throws DatabaseException { + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + return graph.isInstanceOf(vertex, DN.Element) && graph.hasStatement(vertex, DN.MappedComponent); + } + }, TransientCacheListener.instance()); + } catch (DatabaseException e) { + return false; + } + } + + @Execute + public void execute() { + Simantics.getSession().asyncRequest(new WriteRequest() { + @SuppressWarnings("unchecked") + @Override + public void perform(WriteGraph graph) throws DatabaseException { + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + Resource component = graph.getPossibleObject(vertex, DN.MappedComponent); + if (component == null) + return; + + Variable v = Variables.getVariable(graph, graph.getSingleObject(component, ModelingResources.getInstance(graph).ElementToComponent)); + + graph.markUndoPoint(); + Layer0Utils.addCommentMetadata(graph, label + " for " + v.getName(graph)); + + Simantics.applySCLWrite(graph, function, v); + } + }, (DatabaseException e) -> LOGGER.error("Running command " + label + " for " + vertex + " failed", e)); + } + }; + + MDirectMenuItem dynamicItem = MMenuFactory.INSTANCE.createDirectMenuItem(); + dynamicItem.setLabel(label); + dynamicItem.setObject(handler); + children.add(dynamicItem); + } + } + + @AboutToHide + public void aboutToHide() { + } + + private static final class ActionItemRequest extends ResourceRead> { + private ActionItemRequest(Resource resource) { + super(resource); + } + + @SuppressWarnings("unchecked") + @Override + public List perform(ReadGraph graph) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + + if (!graph.isInstanceOf(resource, DN.Element)) + return Collections.emptyList(); + + Resource component = graph.getPossibleObject(resource, DN.MappedComponent); + if (component == null) + return Collections.emptyList(); + + Resource mapping = graph.getPossibleObject(resource, DN.HasMapping); + if (mapping == null) + return Collections.emptyList(); + + String name = graph.getPossibleRelatedValue(mapping, DN.Mapping_ComponentType); + if (name == null) + return Collections.emptyList(); + + Resource root = graph.getSingleObject(graph.getSingleObject(mapping, L0.PartOf), L0.PartOf); + Resource uc = Layer0Utils.getPossibleChild(graph, root, name); + if (uc == null) + return Collections.emptyList(); + + Resource actionsModule = Layer0Utils.getPossibleChild(graph, uc, "Actions"); + if (actionsModule == null) + return Collections.emptyList(); + + String uri = graph.getURI(actionsModule); + SCLContext sclContext = SCLContext.getCurrent(); + Object oldGraph = sclContext.put("graph", graph); + try { + @SuppressWarnings("rawtypes") + Function actionsFun = (Function) SCLOsgi.MODULE_REPOSITORY.getValue(uri, "actions"); + Variable variable = Variables.getPossibleVariable(graph, graph.getSingleObject(component, ModelingResources.getInstance(graph).ElementToComponent)); + return (List) actionsFun.apply(variable); + } + catch (ValueNotFound e) { + throw new NoSingleResultException("No value for " + uri + "/actions", e); + } + finally { + sclContext.put("graph", oldGraph); + } + } + } +} -- 2.45.2 From e67c653b710b4f752acaeae332a29616bfc6e408 Mon Sep 17 00:00:00 2001 From: jsimomaa Date: Wed, 6 Mar 2019 21:36:19 +0200 Subject: [PATCH 14/16] Add edge geometry for detailed rendering in closer zoom levels gitlab #35 Change-Id: I6930dc2b8225647b61beeee0dfa3408e8d1f70c6 --- .../district/imports/ui/CSVImportModel.java | 9 ++++ .../district/imports/ui/CSVImportWizard.java | 39 ++++++++++++++ .../imports/ui/CSVImportWizardPage.java | 16 ++++++ .../graph/DistrictNetwork.pgraph | 2 + .../ontology/DistrictNetworkResource.java | 6 +++ .../network/ui/DistrictNetworkEdge.java | 11 ++-- .../adapters/DistrictNetworkEdgeElement.java | 4 +- .../DistrictNetworkEdgeElementFactory.java | 25 ++++++--- .../DistrictNetworkVertexElement.java | 8 ++- .../ui/nodes/DistrictNetworkEdgeNode.java | 51 ++++++++++++------- 10 files changed, 139 insertions(+), 32 deletions(-) diff --git a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportModel.java b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportModel.java index 7c660b4c..93646ded 100644 --- a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportModel.java +++ b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportModel.java @@ -71,6 +71,7 @@ public class CSVImportModel { private int valvePositionIndx = -1; private int addressIndex; private int lengthIndex; + private int detailedGeometryIndex; // Third page @@ -491,4 +492,12 @@ public class CSVImportModel { public void setLengthIndex(int lengthIndex) { this.lengthIndex = lengthIndex; } + + public void detailedGeometryIndex(int detailedGeometryIndex) { + this.detailedGeometryIndex = detailedGeometryIndex; + } + + public int getDetailedGeometryIndex() { + return detailedGeometryIndex; + } } diff --git a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizard.java b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizard.java index 54a578dd..8c087210 100644 --- a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizard.java +++ b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizard.java @@ -108,6 +108,7 @@ public class CSVImportWizard extends Wizard implements IImportWizard { int kReturnIndex = model.getkReturnIndex(); int kSupplyIndex = model.getkSupplyIndex(); int lengthIndex = model.getLengthIndex(); + int detailedGeometryIndex = model.getDetailedGeometryIndex(); int mappingColumn = model.getComponentMappingIndex(); int idColumn = model.getIdIndex(); @@ -250,6 +251,7 @@ public class CSVImportWizard extends Wizard implements IImportWizard { writeValue(graph, row, kSupplyIndex, edge, DN.Edge_HasKSupply); writeValue(graph, row, edgeFlowAreaIndex, edge, DN.Edge_HasFlowArea); writeValue(graph, row, lengthIndex, edge, DN.Edge_HasLength); + writeDoubleArrayFromString(graph, row, detailedGeometryIndex, edge, DN.Edge_HasGeometry, actualTransform); } } catch (MismatchedDimensionException | TransformException | DatabaseException e) { throw new DatabaseException(e); @@ -307,4 +309,41 @@ public class CSVImportWizard extends Wizard implements IImportWizard { } } } + + private static void writeDoubleArrayFromString(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation, MathTransform actualTransform) throws DatabaseException, MismatchedDimensionException, TransformException { + if (index != -1) { + String stringValue = row.get(index); + if (!stringValue.isEmpty()) { + stringValue = stringValue.substring(1, stringValue.length() - 1); + String[] coordPairs = stringValue.split(";"); + ArrayList dd = new ArrayList<>(coordPairs.length * 2); + for (int i = 0; i < coordPairs.length; i++) { + String coordPair = coordPairs[i]; + String[] p = coordPair.split(" "); + double x = Double.parseDouble(p[0]); + double y = Double.parseDouble(p[1]); + if (actualTransform != null) { + DirectPosition2D targetPos = new DirectPosition2D(); + DirectPosition2D sourcePos = new DirectPosition2D(y, x); + DirectPosition res = actualTransform.transform(sourcePos, targetPos); + double[] coords = res.getCoordinate(); + x = coords[1]; + y = coords[0]; + } + dd.add(x); + dd.add(y); + } + double[] detailedGeometryCoords = new double[dd.size()]; + for (int i = 0; i < dd.size(); i++) { + double d = dd.get(i); + detailedGeometryCoords[i] = d; + } + try { + graph.claimLiteral(subject, relation, detailedGeometryCoords, Bindings.DOUBLE_ARRAY); + } catch (NumberFormatException e) { + throw new DatabaseException(e); + } + } + } + } } diff --git a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizardPage.java b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizardPage.java index b7e46475..552f7e60 100644 --- a/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizardPage.java +++ b/org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizardPage.java @@ -87,6 +87,7 @@ public class CSVImportWizardPage extends WizardPage { private DynamicComboFieldEditor endXCoordSelector; private DynamicComboFieldEditor endYCoordSelector; private DynamicComboFieldEditor endZValueSelector; + private DynamicComboFieldEditor detailedGeometrySelector; private Text edgeConnectionPadding; @@ -750,6 +751,20 @@ public class CSVImportWizardPage extends WizardPage { validatePageComplete(); } }); + detailedGeometrySelector = new DynamicComboFieldEditor("detailedGeometryValue", "Geometry", parent); + detailedGeometrySelector.addComboListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + widgetDefaultSelected(e); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + model.detailedGeometryIndex(Integer.parseInt(detailedGeometrySelector.getValue())); + validatePageComplete(); + } + }); diameterSelector = new DynamicComboFieldEditor("diameterValue", "Diameter value", parent); diameterSelector.addComboListener(new SelectionListener() { @@ -895,6 +910,7 @@ public class CSVImportWizardPage extends WizardPage { endYCoordSelector.updateCombo(namesAndValues); startZValueSelector.updateCombo(namesAndValues); endZValueSelector.updateCombo(namesAndValues); + detailedGeometrySelector.updateCombo(namesAndValues); diameterSelector.updateCombo(namesAndValues); outerDiameterSelector.updateCombo(namesAndValues); nominalMassFlowSelector.updateCombo(namesAndValues); diff --git a/org.simantics.district.network.ontology/graph/DistrictNetwork.pgraph b/org.simantics.district.network.ontology/graph/DistrictNetwork.pgraph index c5195291..d9ab6d6e 100644 --- a/org.simantics.district.network.ontology/graph/DistrictNetwork.pgraph +++ b/org.simantics.district.network.ontology/graph/DistrictNetwork.pgraph @@ -85,6 +85,8 @@ DN.Edge -- DN.Edge.HasLength @defProperty "Length" L0.Double L0.readOnly true + >-- DN.Edge.HasGeometry + @defProperty "Detailed Geometry" L0.DoubleArray >-- DN.Edge.HasDiameter @defProperty "Diameter" L0.Double >-- DN.Edge.HasOuterDiameter diff --git a/org.simantics.district.network.ontology/src/org/simantics/district/network/ontology/DistrictNetworkResource.java b/org.simantics.district.network.ontology/src/org/simantics/district/network/ontology/DistrictNetworkResource.java index e8539528..c2b15437 100644 --- a/org.simantics.district.network.ontology/src/org/simantics/district/network/ontology/DistrictNetworkResource.java +++ b/org.simantics.district.network.ontology/src/org/simantics/district/network/ontology/DistrictNetworkResource.java @@ -65,6 +65,8 @@ public class DistrictNetworkResource { public final Resource Edge_HasElevation_Inverse; public final Resource Edge_HasFlowArea; public final Resource Edge_HasFlowArea_Inverse; + public final Resource Edge_HasGeometry; + public final Resource Edge_HasGeometry_Inverse; public final Resource Edge_HasKReturn; public final Resource Edge_HasKReturn_Inverse; public final Resource Edge_HasKSupply; @@ -341,6 +343,8 @@ public class DistrictNetworkResource { public static final String Edge_HasElevation_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Edge/HasElevation/Inverse"; public static final String Edge_HasFlowArea = "http://www.simantics.org/DistrictNetwork-1.0/Edge/HasFlowArea"; public static final String Edge_HasFlowArea_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Edge/HasFlowArea/Inverse"; + public static final String Edge_HasGeometry = "http://www.simantics.org/DistrictNetwork-1.0/Edge/HasGeometry"; + public static final String Edge_HasGeometry_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Edge/HasGeometry/Inverse"; public static final String Edge_HasKReturn = "http://www.simantics.org/DistrictNetwork-1.0/Edge/HasKReturn"; public static final String Edge_HasKReturn_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Edge/HasKReturn/Inverse"; public static final String Edge_HasKSupply = "http://www.simantics.org/DistrictNetwork-1.0/Edge/HasKSupply"; @@ -627,6 +631,8 @@ public class DistrictNetworkResource { Edge_HasElevation_Inverse = getResourceOrNull(graph, URIs.Edge_HasElevation_Inverse); Edge_HasFlowArea = getResourceOrNull(graph, URIs.Edge_HasFlowArea); Edge_HasFlowArea_Inverse = getResourceOrNull(graph, URIs.Edge_HasFlowArea_Inverse); + Edge_HasGeometry = getResourceOrNull(graph, URIs.Edge_HasGeometry); + Edge_HasGeometry_Inverse = getResourceOrNull(graph, URIs.Edge_HasGeometry_Inverse); Edge_HasKReturn = getResourceOrNull(graph, URIs.Edge_HasKReturn); Edge_HasKReturn_Inverse = getResourceOrNull(graph, URIs.Edge_HasKReturn_Inverse); Edge_HasKSupply = getResourceOrNull(graph, URIs.Edge_HasKSupply); diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictNetworkEdge.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictNetworkEdge.java index 28ac1970..b9dd7250 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictNetworkEdge.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictNetworkEdge.java @@ -4,12 +4,14 @@ import java.awt.geom.Point2D; public class DistrictNetworkEdge { - private Point2D startPoint; - private Point2D endPoint; + private final Point2D startPoint; + private final Point2D endPoint; + private final double[] geometry; - public DistrictNetworkEdge(Point2D startPoint, Point2D endPoint) { + public DistrictNetworkEdge(Point2D startPoint, Point2D endPoint, double[] geometry) { this.startPoint = startPoint; this.endPoint = endPoint; + this.geometry = geometry; } public Point2D getStartPoint() { @@ -20,4 +22,7 @@ public class DistrictNetworkEdge { return endPoint; } + public double[] getGeometry() { + return geometry; + } } diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java index ce57e0a2..34424739 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java @@ -105,7 +105,7 @@ public class DistrictNetworkEdgeElement { if (size == null) size = new Rectangle2D.Double(); if (edge != null) - size.setFrame(DistrictNetworkEdgeNode.calculatePath(edge, null).getBounds2D()); + size.setFrame(DistrictNetworkEdgeNode.calculatePath(edge, null, false).getBounds2D()); else LOGGER.debug("Element {} does not have edge!", e); @@ -116,7 +116,7 @@ public class DistrictNetworkEdgeElement { public Shape getElementShape(IElement e) { DistrictNetworkEdge edge = e.getHint(KEY_DN_EDGE); if (edge != null) { - return DistrictNetworkEdgeNode.calculatePath(edge, null); + return DistrictNetworkEdgeNode.calculatePath(edge, null, false); } else { return getBounds(e, null); } diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElementFactory.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElementFactory.java index 1003a9b2..3b18dc6f 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElementFactory.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElementFactory.java @@ -2,6 +2,7 @@ package org.simantics.district.network.ui.adapters; import java.awt.geom.Point2D; +import org.simantics.databoard.Bindings; import org.simantics.db.AsyncReadGraph; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; @@ -28,7 +29,8 @@ import org.simantics.maps.MapScalingTransform; public class DistrictNetworkEdgeElementFactory extends SyncElementFactory { public static final ElementClass CLASS = DistrictNetworkEdgeElement.CLASS; - + public static final double[] EMPTY = new double[0]; + private DistrictNetworkResource DN; private DiagramResource DIA; @@ -46,19 +48,30 @@ public class DistrictNetworkEdgeElementFactory extends SyncElementFactory { protected Resource getElementClassBaseType(AsyncReadGraph graph) { return DN.Edge; } - + @Override public void load(ReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource edgeResource, IElement element) throws DatabaseException { if (!graph.hasStatement(edgeResource)) return; // already deleted + if (!graph.hasStatement(edgeResource, DN.HasStartVertex)) + return; // already deleted Resource startVertex = graph.getSingleObject(edgeResource, DN.HasStartVertex); + + if (!graph.hasStatement(edgeResource, DN.HasEndVertex)) + return; // already deleted Resource endVertex = graph.getSingleObject(edgeResource, DN.HasEndVertex); - // TODO: Find maybe a better way to apply the scaling - double[] startCoords = graph.getRelatedValue2(startVertex, DIA.HasLocation); - double[] endCoords = graph.getRelatedValue2(endVertex, DIA.HasLocation); - DistrictNetworkEdge edge = new DistrictNetworkEdge(new Point2D.Double(startCoords[0], startCoords[1]), new Point2D.Double(endCoords[0], endCoords[1])); + double[] startCoords = graph.getRelatedValue2(startVertex, DIA.HasLocation, Bindings.DOUBLE_ARRAY); + double[] endCoords = graph.getRelatedValue2(endVertex, DIA.HasLocation, Bindings.DOUBLE_ARRAY); + + double[] geometry = EMPTY; + try { + geometry = graph.getPossibleRelatedValue2(edgeResource, DN.Edge_HasGeometry, Bindings.DOUBLE_ARRAY); + } catch (Exception e) { + // most likely no geometry available + } + DistrictNetworkEdge edge = new DistrictNetworkEdge(new Point2D.Double(startCoords[0], startCoords[1]), new Point2D.Double(endCoords[0], endCoords[1]), geometry); Resource mapping = graph.getSingleObject(edgeResource, DistrictNetworkResource.getInstance(graph).HasMapping); element.setHint(DistrictNetworkAdditionalColor.KEY_DN_MAPPING_RESOURCE, mapping); diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkVertexElement.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkVertexElement.java index b3e7fda3..d873835c 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkVertexElement.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkVertexElement.java @@ -100,8 +100,12 @@ public class DistrictNetworkVertexElement { double counterExpansion = 0.001; double x = boundsInLocal.getX() + counterExpansion; double y = boundsInLocal.getY() + counterExpansion; - double scaledWidth = boundsInLocal.getWidth() / canvasTransform.getScaleX() / 10000.0; - double scaledHeight = boundsInLocal.getHeight() / canvasTransform.getScaleY() / 10000.0; + double scaledWidth = boundsInLocal.getWidth(); + double scaledHeight = boundsInLocal.getHeight(); + if (canvasTransform != null) { + scaledWidth = boundsInLocal.getWidth() / canvasTransform.getScaleX() / 10000.0; + scaledHeight= boundsInLocal.getHeight() / canvasTransform.getScaleY() / 10000.0; + } double width = scaledWidth - 2*counterExpansion; double height = scaledHeight - 2*counterExpansion; size.setFrame(x, y, width, height); 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 00a1427f..a4f348eb 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 @@ -5,13 +5,14 @@ import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; -import java.awt.geom.Line2D; import java.awt.geom.Path2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import org.simantics.district.network.ModelledCRS; import org.simantics.district.network.ui.DistrictNetworkEdge; +import org.simantics.district.network.ui.adapters.DistrictNetworkEdgeElementFactory; +import org.simantics.maps.MapScalingTransform; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.ISelectionPainterNode; import org.simantics.scenegraph.g2d.G2DNode; @@ -29,7 +30,7 @@ public class DistrictNetworkEdgeNode extends G2DParentNode implements ISelection private DistrictNetworkEdge edge; private Rectangle2D bounds; - private transient Line2D path; + private transient Path2D path; private boolean scaleStroke = true; private Color color; @@ -76,8 +77,8 @@ public class DistrictNetworkEdgeNode extends G2DParentNode implements ISelection } else { bs = STROKE; } - - path = calculateLine(edge, path); + int zoomLevel = MapScalingTransform.zoomLevel(ot); + path = calculatePath(edge, path, zoomLevel > 15); if (isSelected()) { g2d.setColor(SELECTION_COLOR); @@ -126,20 +127,20 @@ public class DistrictNetworkEdgeNode extends G2DParentNode implements ISelection return centerPoint; } - public static Line2D calculateLine(DistrictNetworkEdge edge, Line2D result) { - // Convert to screen coordinates - double startX = ModelledCRS.longitudeToX(edge.getStartPoint().getX()); - double startY = ModelledCRS.latitudeToY(-edge.getStartPoint().getY()); // Invert for Simantics - double endX = ModelledCRS.longitudeToX(edge.getEndPoint().getX()); - double endY = ModelledCRS.latitudeToY(-edge.getEndPoint().getY());// Invert for Simantics - - if (result == null) - result = new Line2D.Double(); - result.setLine(startX, startY, endX, endY); - return result; - } - - public static Path2D calculatePath(DistrictNetworkEdge edge, Path2D result) { +// public static Line2D calculateLine(DistrictNetworkEdge edge, Line2D result) { +// // Convert to screen coordinates +// double startX = ModelledCRS.longitudeToX(edge.getStartPoint().getX()); +// double startY = ModelledCRS.latitudeToY(-edge.getStartPoint().getY()); // Invert for Simantics +// double endX = ModelledCRS.longitudeToX(edge.getEndPoint().getX()); +// double endY = ModelledCRS.latitudeToY(-edge.getEndPoint().getY());// Invert for Simantics +// +// if (result == null) +// result = new Line2D.Double(); +// result.setLine(startX, startY, endX, endY); +// return result; +// } + + public static Path2D calculatePath(DistrictNetworkEdge edge, Path2D result, boolean detailed) { // Convert to screen coordinates double startX = ModelledCRS.longitudeToX(edge.getStartPoint().getX()); double startY = ModelledCRS.latitudeToY(-edge.getStartPoint().getY()); // Invert for Simantics @@ -152,6 +153,18 @@ public class DistrictNetworkEdgeNode extends G2DParentNode implements ISelection result.reset(); } result.moveTo(startX, startY); + if (detailed) { + double[] detailedGeometry = edge.getGeometry(); + if (detailedGeometry != null && !DistrictNetworkEdgeElementFactory.EMPTY.equals(detailedGeometry)) { + // ok, lets do this + + for (int i = 0; i < detailedGeometry.length; i += 2) { + double x = ModelledCRS.longitudeToX(detailedGeometry[i]); + double y = ModelledCRS.latitudeToY(-detailedGeometry[i+1]);// Invert for Simantics + result.lineTo(x, y); + } + } + } result.lineTo(endX, endY); return result; } @@ -173,7 +186,7 @@ public class DistrictNetworkEdgeNode extends G2DParentNode implements ISelection } private Rectangle2D calculateBounds(Rectangle2D rect) { - return calculatePath(edge, null).getBounds2D(); + return calculatePath(edge, null, false).getBounds2D(); } public void setDNEdge(DistrictNetworkEdge edge) { -- 2.45.2 From cb2ebef6cbe572f646082952f57bb69135f308bd Mon Sep 17 00:00:00 2001 From: jsimomaa Date: Wed, 6 Mar 2019 22:09:23 +0200 Subject: [PATCH 15/16] Add refresh to context menu in district network breakdown view Also fixes selection of single vertex gitlab #11 Change-Id: I3c8af80ccfda86be17dfdcede1269bfde0b16a40 --- .../ui/DistrictPanZoomRotateHandler.java | 77 +++++++++++---- .../network/ui/DistrictTransformUtil.java | 35 +++++-- .../DistrictNetworkVertexElement.java | 14 ++- .../DistrictNetworkBreakdownPanel.java | 29 ++++++ .../district/network/ui/breakdown/Input.java | 97 +++++++++++++++++++ 5 files changed, 214 insertions(+), 38 deletions(-) diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictPanZoomRotateHandler.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictPanZoomRotateHandler.java index f9d9fccc..fecc1754 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictPanZoomRotateHandler.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictPanZoomRotateHandler.java @@ -7,6 +7,9 @@ import java.util.Set; import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; import org.simantics.g2d.canvas.impl.DependencyReflection.Reference; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.DiagramUtils; +import org.simantics.g2d.diagram.IDiagram; import org.simantics.g2d.diagram.participant.Selection; import org.simantics.g2d.element.ElementUtils; import org.simantics.g2d.element.IElement; @@ -74,14 +77,36 @@ public class DistrictPanZoomRotateHandler extends PanZoomRotateHandler { } private boolean zoomToFit() { - return false; + CanvasBoundsParticipant boundsParticipant = getContext().getAtMostOneItemOfClass(CanvasBoundsParticipant.class); + if (boundsParticipant == null) + return false; + + final Rectangle2D controlBounds = boundsParticipant.getControlBounds().getFrame(); + if (controlBounds == null || controlBounds.isEmpty()) + return false; + + IDiagram d = getHint(DiagramHints.KEY_DIAGRAM); + if (d == null) + return false; + + Rectangle2D diagramRect = DiagramUtils.getContentRect(d); + if (diagramRect == null) + return false; + if (diagramRect.isEmpty()) + return false; + + org.simantics.scenegraph.utils.GeometryUtils.expandRectangle(diagramRect, 1); + + // System.out.println("zoomToFit(" + controlArea + ", " + diagramRect + ")"); + util.fitArea(controlBounds, diagramRect, null); + + return true; } private boolean zoomToPage() { int currentZoomLevel = MapScalingTransform.zoomLevel(util.getTransform()); util.setTransform(new AffineTransform(2,0,0,2,270,270)); -// util.setTransform(new AffineTransform(MapScalingTransform.INSTANCE)); return true; } @@ -95,6 +120,10 @@ public class DistrictPanZoomRotateHandler extends PanZoomRotateHandler { return false; Set selections = selection.getAllSelections(); + if (selections == null || selections.isEmpty()) { + // no can do, + return zoomToPage(); + } Rectangle2D diagramRect = ElementUtils.getSurroundingElementBoundsOnDiagram(selections); // Make sure that even empty bounds can be zoomed into. @@ -136,26 +165,34 @@ public class DistrictPanZoomRotateHandler extends PanZoomRotateHandler { @Override public boolean mouseWheelMoved(MouseWheelMovedEvent me) { if (navigationEnabled && zoomEnabled) { - double z; - if (me.wheelRotation > 0) { - z = DISTRICT_TRANSLATE_AMOUNT; + // check if min/max zoom already + AffineTransform transform = getTransform(); + int zoomLevel = MapScalingTransform.zoomLevel(transform); + + if (0 < zoomLevel && zoomLevel < 20 || (zoomLevel == 0 && me.wheelRotation > 0) || (zoomLevel == 20 && me.wheelRotation < 0)) { + double z; + if (me.wheelRotation > 0) { + z = DISTRICT_TRANSLATE_AMOUNT; + } else { + z = 1.0d / DISTRICT_TRANSLATE_AMOUNT; + } + //double scroll = Math.min(0.9, -me.wheelRotation / 20.0); + //double z = 1 - scroll; + double dx = (me.controlPosition.getX() - transform.getTranslateX()) / transform.getScaleX(); + double dy = (me.controlPosition.getY() - transform.getTranslateY()) / transform.getScaleY(); + dx = dx * (1 - z); + dy = dy * (1 - z); +// double limitedScale = limitScaleFactor(z); +// if (limitedScale != 1.0) { + translate(dx, dy); + scale(z, z); + transformChanged(); + dropQuality(); + repaint(); +// } } else { - z = 1.0d / DISTRICT_TRANSLATE_AMOUNT; + // max zoom level reached } - //double scroll = Math.min(0.9, -me.wheelRotation / 20.0); - //double z = 1 - scroll; - double dx = (me.controlPosition.getX() - transform.getTranslateX()) / transform.getScaleX(); - double dy = (me.controlPosition.getY() - transform.getTranslateY()) / transform.getScaleY(); - dx = dx * (1 - z); - dy = dy * (1 - z); -// double limitedScale = limitScaleFactor(z); -// if (limitedScale != 1.0) { - translate(dx, dy); - scale(z, z); - transformChanged(); - dropQuality(); - repaint(); -// } } return false; } diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictTransformUtil.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictTransformUtil.java index 230c17cd..ce28aba5 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictTransformUtil.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictTransformUtil.java @@ -4,6 +4,7 @@ import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import org.simantics.g2d.participant.TransformUtil; +import org.simantics.maps.MapScalingTransform; import org.simantics.scenegraph.utils.GeometryUtils; import org.simantics.utils.page.MarginUtils; import org.simantics.utils.page.MarginUtils.Margins; @@ -49,23 +50,37 @@ public class DistrictTransformUtil extends TransformUtil { double targetX = scale; double toBeX = currentX; if (targetX > 0) { - if (toBeX < targetX) { - while ((toBeX) < targetX) { - toBeX = toBeX * 2; - } - } else { - while ((toBeX * 0.5) > targetX) { - toBeX = toBeX * 0.5; + // let's check that targetX zoomLevel is between 0-20 + AffineTransform tar = new AffineTransform(); + tar.scale(toBeX, toBeX); + int tarZoomLevel = MapScalingTransform.zoomLevel(tar); + if (tarZoomLevel < 20 && tarZoomLevel > 0) { + if (toBeX < targetX) { + while ((toBeX * 0.5) < targetX) { + toBeX = toBeX * 2; + AffineTransform tr = new AffineTransform(); + tr.scale(toBeX, toBeX); + int zoomLevel = MapScalingTransform.zoomLevel(tr); + if (zoomLevel >= 20) { // let's not zoom too close + break; + } + } + } else { + while ((toBeX * 0.25) > targetX) { + toBeX = toBeX * 0.5; + AffineTransform tr = new AffineTransform(); + tr.scale(toBeX, toBeX); + if (MapScalingTransform.zoomLevel(tr) <= 0) { // let's not zoom too far away + break; + } + } } } - //tx = tx * (1 - toBeX); - //ty = ty * (1 - toBeX); AffineTransform at = new AffineTransform(); at.translate(tx, ty); at.translate(controlArea.getMinX(), controlArea.getMinY()); at.scale(toBeX, toBeX); at.translate(-diagramArea.getMinX(), -diagramArea.getMinY()); - setTransform(at); } else { // negative, how, no can do? diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkVertexElement.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkVertexElement.java index d873835c..a989c561 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkVertexElement.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkVertexElement.java @@ -22,7 +22,6 @@ import org.simantics.g2d.element.handler.impl.SimpleElementLayers; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.g2d.G2DParentNode; import org.simantics.scenegraph.g2d.nodes.SVGNode; -import org.simantics.scenegraph.utils.GeometryUtils; import org.simantics.utils.datastructures.hints.IHintContext.Key; import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; @@ -97,17 +96,16 @@ public class DistrictNetworkVertexElement { ICanvasContext ctx = DiagramNodeUtil.getCanvasContext(node); AffineTransform canvasTransform = ctx.getHintStack().getHint(Hints.KEY_CANVAS_TRANSFORM); // for some reason PickContextImpl expands the rectangle by 0.001 (too much) - let's counter it - double counterExpansion = 0.001; - double x = boundsInLocal.getX() + counterExpansion; - double y = boundsInLocal.getY() + counterExpansion; + double x = boundsInLocal.getX(); + double y = boundsInLocal.getY(); double scaledWidth = boundsInLocal.getWidth(); double scaledHeight = boundsInLocal.getHeight(); if (canvasTransform != null) { - scaledWidth = boundsInLocal.getWidth() / canvasTransform.getScaleX() / 10000.0; - scaledHeight= boundsInLocal.getHeight() / canvasTransform.getScaleY() / 10000.0; + scaledWidth = boundsInLocal.getWidth() / canvasTransform.getScaleX(); + scaledHeight= boundsInLocal.getHeight() / canvasTransform.getScaleY(); } - double width = scaledWidth - 2*counterExpansion; - double height = scaledHeight - 2*counterExpansion; + double width = scaledWidth; + double height = scaledHeight; size.setFrame(x, y, width, height); return size; diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/breakdown/DistrictNetworkBreakdownPanel.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/breakdown/DistrictNetworkBreakdownPanel.java index b3e6d6bb..c8db5165 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/breakdown/DistrictNetworkBreakdownPanel.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/breakdown/DistrictNetworkBreakdownPanel.java @@ -1,7 +1,9 @@ package org.simantics.district.network.ui.breakdown; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -147,6 +149,15 @@ public class DistrictNetworkBreakdownPanel extends Composite { if (sel.size() > 0 && fromSameDiagram(sel)) { manager.add(new ShowSubnetworkAction(sel)); } + Set diagrams = new HashSet<>(); + if (sel.size() > 0) { + for (Subgraph graph : sel) { + diagrams.add(graph.parent); + } + } + if (diagrams.isEmpty()) + diagrams.addAll(subgraphs.keySet()); + manager.add(new RefreshAction(diagrams)); //manager.add(new DeleteAction()); } @@ -445,6 +456,24 @@ public class DistrictNetworkBreakdownPanel extends Composite { } + private class RefreshAction extends Action { + + private Set diagram; + + public RefreshAction(Set diagrams) { + super("Refresh"); + this.diagram = diagrams; + } + + @Override + public void run() { + diagram.forEach(d -> { + subgraphs.remove(d); + tree.refresh(); + }); + } + } + private static class ShowSubnetworkAction extends Action { private final List subgraphs; diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/breakdown/Input.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/breakdown/Input.java index dd80c2a6..6d9ae8b6 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/breakdown/Input.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/breakdown/Input.java @@ -14,9 +14,35 @@ public class Input { public static class NetworkDiagrams extends Bean { public List diagrams = new ArrayList<>(); + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((diagrams == null) ? 0 : diagrams.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + NetworkDiagrams other = (NetworkDiagrams) obj; + if (diagrams == null) { + if (other.diagrams != null) + return false; + } else if (!diagrams.equals(other.diagrams)) + return false; + return true; + } } public static class NetworkDiagram extends Bean { + public String name; public Resource diagram; @@ -24,6 +50,37 @@ public class Input { this.name = name; this.diagram = diagram; } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((diagram == null) ? 0 : diagram.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + NetworkDiagram other = (NetworkDiagram) obj; + if (diagram == null) { + if (other.diagram != null) + return false; + } else if (!diagram.equals(other.diagram)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } } public static class Subgraph { @@ -38,6 +95,46 @@ public class Input { this.vertices = vertices; this.edges = edges; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((edges == null) ? 0 : edges.hashCode()); + result = prime * result + index; + result = prime * result + ((parent == null) ? 0 : parent.hashCode()); + result = prime * result + ((vertices == null) ? 0 : vertices.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Subgraph other = (Subgraph) obj; + if (edges == null) { + if (other.edges != null) + return false; + } else if (!edges.equals(other.edges)) + return false; + if (index != other.index) + return false; + if (parent == null) { + if (other.parent != null) + return false; + } else if (!parent.equals(other.parent)) + return false; + if (vertices == null) { + if (other.vertices != null) + return false; + } else if (!vertices.equals(other.vertices)) + return false; + return true; + } } } -- 2.45.2 From 474df6d53b289fca2697a700a69da110896bb98e Mon Sep 17 00:00:00 2001 From: jsimomaa Date: Wed, 6 Mar 2019 22:13:54 +0200 Subject: [PATCH 16/16] Some initial fixes for DPI in map nodes (lot's TODO still) gitlab #36 Change-Id: If7022ea127d595ea6eaa89878fce38212c81734f --- .../src/org/simantics/maps/sg/MapAttributionNode.java | 7 +++++-- .../src/org/simantics/maps/sg/MapLocationZoomInfoNode.java | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/org.simantics.district.maps/src/org/simantics/maps/sg/MapAttributionNode.java b/org.simantics.district.maps/src/org/simantics/maps/sg/MapAttributionNode.java index 66543aac..d97d22eb 100644 --- a/org.simantics.district.maps/src/org/simantics/maps/sg/MapAttributionNode.java +++ b/org.simantics.district.maps/src/org/simantics/maps/sg/MapAttributionNode.java @@ -10,6 +10,7 @@ import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import org.simantics.scenegraph.g2d.G2DNode; +import org.simantics.scenegraph.utils.DPIUtil; public class MapAttributionNode extends G2DNode { @@ -33,7 +34,7 @@ public class MapAttributionNode extends G2DNode { g2d.setTransform(new AffineTransform()); // do the rendering magic - Font rulerFont = new Font("Tahoma", Font.PLAIN, 9); + Font rulerFont = new Font("Tahoma", Font.PLAIN, DPIUtil.upscale(9)); //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setStroke(new BasicStroke(1)); @@ -43,7 +44,9 @@ public class MapAttributionNode extends G2DNode { if (bounds == null) return; // FIXME - String str = "Map data © OpenStreetMap contributors"; + String str = "Map data \u00A9 OpenStreetMap contributors"; + + g2d.setFont(rulerFont); FontMetrics fm = g2d.getFontMetrics(); Rectangle2D r = fm.getStringBounds(str, g2d); diff --git a/org.simantics.district.maps/src/org/simantics/maps/sg/MapLocationZoomInfoNode.java b/org.simantics.district.maps/src/org/simantics/maps/sg/MapLocationZoomInfoNode.java index bad499e6..9e027ecb 100644 --- a/org.simantics.district.maps/src/org/simantics/maps/sg/MapLocationZoomInfoNode.java +++ b/org.simantics.district.maps/src/org/simantics/maps/sg/MapLocationZoomInfoNode.java @@ -15,6 +15,7 @@ import org.simantics.g2d.participant.MouseUtil; import org.simantics.g2d.participant.MouseUtil.MouseInfo; import org.simantics.maps.MapScalingTransform; import org.simantics.scenegraph.g2d.G2DNode; +import org.simantics.scenegraph.utils.DPIUtil; public class MapLocationZoomInfoNode extends G2DNode { @@ -40,7 +41,7 @@ public class MapLocationZoomInfoNode extends G2DNode { g2d.setTransform(new AffineTransform()); // do the rendering magic - Font rulerFont = new Font("Tahoma", Font.PLAIN, 9); + Font rulerFont = new Font("Tahoma", Font.PLAIN, DPIUtil.upscale(9)); //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setStroke(new BasicStroke(1)); @@ -68,6 +69,7 @@ public class MapLocationZoomInfoNode extends G2DNode { } String str = "X: " + formatValue(startLon, MAX_DIGITS) + ", Y: " + formatValue(startLat, MAX_DIGITS) + ", Z: " + zoomLevel; + g2d.setFont(rulerFont); FontMetrics fm = g2d.getFontMetrics(); Rectangle2D r = fm.getStringBounds(str, g2d); -- 2.45.2