]> gerrit.simantics Code Review - simantics/district.git/commitdiff
Trying to get map background coloring to work 59/2559/2
authorjsimomaa <jani.simomaa@gmail.com>
Tue, 18 Dec 2018 06:13:00 +0000 (08:13 +0200)
committerjsimomaa <jani.simomaa@gmail.com>
Tue, 18 Dec 2018 08:03:24 +0000 (10:03 +0200)
gitlab #20

Change-Id: I6f4d3ff243784c33f8114990e27cdf83104909e3

org.simantics.district.maps/META-INF/MANIFEST.MF
org.simantics.district.maps/src/org/simantics/maps/eclipse/MapPainter.java
org.simantics.district.maps/src/org/simantics/maps/sg/MapNode.java
org.simantics.district.maps/src/org/simantics/maps/sg/commands/MapCommands.java [new file with mode: 0644]
org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictDiagramViewer.java
org.simantics.district.network.ui/src/org/simantics/district/network/ui/contributions/SetFocusableHandler.java
org.simantics.district.network/src/org/simantics/district/network/DistrictNetworkUtil.java

index 7a2b4fc0c1adc602d6954a4685076c621d7f3ac2..c7858653d4beb8c168254032804ecdc735beb92c 100644 (file)
@@ -18,6 +18,7 @@ Export-Package: org.simantics.maps,
  org.simantics.maps.debug,
  org.simantics.maps.eclipse,
  org.simantics.maps.sg,
+ org.simantics.maps.sg.commands,
  org.simantics.maps.tile,
  org.simantics.maps.wms
 Import-Package: org.simantics.scenegraph.g2d
index cdf0be15a5236d8a4826da71eb6b4b8f4e1f1cdd..853982214d933a49cf60c2348215c06bb5b5dc0b 100644 (file)
@@ -11,6 +11,7 @@
  *******************************************************************************/
 package org.simantics.maps.eclipse;
 
+import java.awt.Color;
 import java.awt.geom.AffineTransform;
 
 import org.simantics.g2d.canvas.Hints;
@@ -20,6 +21,7 @@ import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup;
 import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
 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.EventHandlerReflection.EventHandler;
 import org.simantics.scenegraph.g2d.events.command.CommandEvent;
@@ -45,6 +47,8 @@ public class MapPainter extends AbstractCanvasParticipant {
      */
     public static final Key KEY_MAP_ENABLED  = new KeyOf(Boolean.class);
 
+    public static final Key KEY_MAP_BACKGROUND_COLOR  = new KeyOf(Object.class);
+
     public static final double ZOOM_IN_LIMIT = 10000000.0;
 
     public static final double ZOOM_OUT_LIMIT = 10.0;
@@ -72,11 +76,13 @@ public class MapPainter extends AbstractCanvasParticipant {
     public void addedToContext(ICanvasContext ctx) {
         super.addedToContext(ctx);
         getHintStack().addKeyHintListener(getThread(), KEY_MAP_ENABLED, mapListener);
+        getHintStack().addKeyHintListener(getThread(), KEY_MAP_BACKGROUND_COLOR, mapListener);
     }
 
     @Override
     public void removedFromContext(ICanvasContext ctx) {
         getHintStack().removeKeyHintListener(getThread(), KEY_MAP_ENABLED, mapListener);
+        getHintStack().removeKeyHintListener(getThread(), KEY_MAP_BACKGROUND_COLOR, mapListener);
         super.removedFromContext(ctx);
     }
 
@@ -87,6 +93,12 @@ public class MapPainter extends AbstractCanvasParticipant {
             updateNode();
             setDirty();
             return true;
+        } else if (e.command.equals( MapCommands.MAP_BACKGROUND_COLOR_CHANGE )) {
+            ICanvasContext context = (ICanvasContext) e.getContext();
+            Color s = context.getHintStack().getHint(MapCommands.KEY_MAP_BACKGROUND_COLOR);
+            setBackgroundColor(s);
+            setDirty();
+            return true;
         } else if (e.command.equals( Commands.MAP_DISABLE )) {
             setEnabled(false);
             updateNode();
@@ -126,6 +138,7 @@ public class MapPainter extends AbstractCanvasParticipant {
 
     protected void updateNode() {
         node.setEnabled(isPaintingEnabled());
+        node.setBackgroundColor(getBackgroundColor());
     }
 
     boolean isPaintingEnabled() {
@@ -146,4 +159,12 @@ public class MapPainter extends AbstractCanvasParticipant {
     private void enablePainting() {
         setHint(Hints.KEY_DISABLE_PAINTING, false);
     }
+    
+    private void setBackgroundColor(Color backgroundColor) {
+        setHint(KEY_MAP_BACKGROUND_COLOR, backgroundColor);
+    }
+    
+    private Color getBackgroundColor() {
+        return getHint(KEY_MAP_BACKGROUND_COLOR);
+    }
 }
index 952553b0ec4cb263d75d9d2bd07524cc738f225a..f9c6abf9af2fee69d4871965ac006cec329c9d51 100644 (file)
@@ -66,6 +66,7 @@ public class MapNode extends G2DNode implements ITileListener  {
     private final int    VIEWBOX_QUIET_TIME = 500;
 
     protected Boolean enabled = true;
+    protected Color backgroundColor;
 
     enum TileState {
         NOT_LOADED,
@@ -222,11 +223,15 @@ public class MapNode extends G2DNode implements ITileListener  {
         this.enabled = enabled;
     }
 
+    @SyncField("backgroundColor")
+    public void setBackgroundColor(Color color) {
+        this.backgroundColor = color;
+    }
+
     @Override
     public void render(Graphics2D g2d) {
-        if (!enabled)
-            return;
 
+        
         AffineTransform ot = g2d.getTransform();
         g2d.transform(transform);
         
@@ -250,58 +255,68 @@ 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(viewbox == null) return; // FIXME
-
-        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;
+
+        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++;
             }
-            tileSize *= 0.5;
-            level++;
-        }
-        /*
-         *  To convert y-coordinates to map coordinates in ruler, use:
-         *    double val = (y-offsetY)/scaleY;
-         *    val = Math.toDegrees(Math.atan(Math.sinh(Math.toRadians(val))));
-         *    String str = formatValue(val);
-         */
-
-        double minx = Math.min(180, Math.max(viewbox.getMinX(), -180));
-        double maxx = Math.min(180, Math.max(viewbox.getMaxX(), -180));
-
-        double miny = Math.min(360, Math.max(viewbox.getMinY()+180, 0));
-        double maxy = Math.min(360, Math.max(viewbox.getMaxY()+180, 0));
-
-        g2d.setTransform(new AffineTransform());
-        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-
-        int levels = (1 << level);
-
-        // http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
-        int left = (int)Math.floor( (minx + 180) / 360 * (1<<level) );
-        int right = (int)Math.floor( (maxx + 180) / 360 * (1<<level) );
-        int top = (int)Math.floor(miny / 360 * (1<<level));//  (int)Math.floor( (1 - Math.log(Math.tan(Math.toRadians(miny)) + 1 / Math.cos(Math.toRadians(miny))) / Math.PI) / 2 * (1<<level) );
-        int bottom = (int)Math.floor(maxy / 360 * (1<<level));//  (int)Math.floor( (1 - Math.log(Math.tan(Math.toRadians(maxy)) + 1 / Math.cos(Math.toRadians(maxy))) / Math.PI) / 2 * (1<<level) );
-
-        double tsx = 360 / (double)levels; // Size of tile on zoom level
-        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);
+            /*
+             *  To convert y-coordinates to map coordinates in ruler, use:
+             *    double val = (y-offsetY)/scaleY;
+             *    val = Math.toDegrees(Math.atan(Math.sinh(Math.toRadians(val))));
+             *    String str = formatValue(val);
+             */
+    
+            double minx = Math.min(180, Math.max(viewbox.getMinX(), -180));
+            double maxx = Math.min(180, Math.max(viewbox.getMaxX(), -180));
+    
+            double miny = Math.min(360, Math.max(viewbox.getMinY()+180, 0));
+            double maxy = Math.min(360, Math.max(viewbox.getMaxY()+180, 0));
+    
+            g2d.setTransform(new AffineTransform());
+            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+    
+            int levels = (1 << level);
+    
+            // http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
+            int left = (int)Math.floor( (minx + 180) / 360 * (1<<level) );
+            int right = (int)Math.floor( (maxx + 180) / 360 * (1<<level) );
+            int top = (int)Math.floor(miny / 360 * (1<<level));//  (int)Math.floor( (1 - Math.log(Math.tan(Math.toRadians(miny)) + 1 / Math.cos(Math.toRadians(miny))) / Math.PI) / 2 * (1<<level) );
+            int bottom = (int)Math.floor(maxy / 360 * (1<<level));//  (int)Math.floor( (1 - Math.log(Math.tan(Math.toRadians(maxy)) + 1 / Math.cos(Math.toRadians(maxy))) / Math.PI) / 2 * (1<<level) );
+    
+            double tsx = 360 / (double)levels; // Size of tile on zoom level
+            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);
+                }
+            }
+    //        g.dispose();
+    
+            // Check if transform has changed
+            transformChanged(tr, level);
+        } else {
+            if (backgroundColor != null) {
+                g2d.setTransform(new AffineTransform());
+                Rectangle2D controlBounds = (Rectangle2D) g2d.getRenderingHint(G2DRenderingHints.KEY_CONTROL_BOUNDS);
+                Color color = g2d.getColor();
+                g2d.setColor(backgroundColor);
+                g2d.fill(controlBounds);
+                g2d.setColor(color);
             }
         }
-//        g.dispose();
-
-        // Check if transform has changed
-        transformChanged(tr, level);
-        
         g2d.setTransform(ot);
     }
 
diff --git a/org.simantics.district.maps/src/org/simantics/maps/sg/commands/MapCommands.java b/org.simantics.district.maps/src/org/simantics/maps/sg/commands/MapCommands.java
new file mode 100644 (file)
index 0000000..540eabd
--- /dev/null
@@ -0,0 +1,14 @@
+package org.simantics.maps.sg.commands;
+
+import java.awt.Color;
+
+import org.simantics.scenegraph.g2d.events.command.Command;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
+
+public final class MapCommands {
+
+    public static final Key KEY_MAP_BACKGROUND_COLOR = new KeyOf(Color.class, "MAP_BACKGROUND_COLOR");
+    public static final Command MAP_BACKGROUND_COLOR_CHANGE = new Command("changeMapBackgroundColorChange");
+
+}
index 642d02be63c575d73ea0aaedb2d8e4ab9a93b5e7..f0c76954fb954cf91c46a46c2fdd9c71ea400e2c 100644 (file)
@@ -1,9 +1,14 @@
 package org.simantics.district.network.ui;
 
+import java.awt.Color;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
 
+import org.simantics.datatypes.literal.RGB;
 import org.simantics.db.ReadGraph;
-import org.simantics.db.common.request.UniqueRead;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.UnaryRead;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.Listener;
 import org.simantics.diagram.ui.DiagramModelHints;
@@ -24,6 +29,7 @@ import org.simantics.g2d.participant.RenderingQualityInteractor;
 import org.simantics.g2d.participant.ZoomToAreaHandler;
 import org.simantics.maps.MapScalingTransform;
 import org.simantics.maps.eclipse.MapPainter;
+import org.simantics.maps.sg.commands.MapCommands;
 import org.simantics.modeling.ui.diagramEditor.DiagramViewer;
 import org.simantics.scenegraph.g2d.events.command.CommandEvent;
 import org.simantics.scenegraph.g2d.events.command.Commands;
@@ -86,28 +92,107 @@ public class DistrictDiagramViewer extends DiagramViewer {
         super.loadPageSettings(ctx);
         // this might be the wrong place to start such listening but at least
         // super.loadPageSettings() does async-db-operations
-        sessionContext.getSession().asyncRequest(new UniqueRead<Boolean>() {
-
-            @Override
-            public Boolean perform(ReadGraph graph) throws DatabaseException {
-                return DistrictNetworkUtil.drawMapEnabled(graph, getInputResource());
-            }
-        }, new Listener<Boolean>() {
-
-            @Override
-            public void execute(Boolean result) {
-                canvasContext.getEventQueue().queueEvent(new CommandEvent(canvasContext, System.currentTimeMillis(), result ? Commands.MAP_ENABLE : Commands.MAP_DISABLE));
-            }
-
-            @Override
-            public void exception(Throwable t) {
-                LOGGER.error("Could not listen draw map for {}", getInputResource(), t);
-            }
-
-            @Override
-            public boolean isDisposed() {
-                return DistrictDiagramViewer.this.isDisposed();
-            }
-        });
+        setupDrawMapEnabled();
+        setupBackgroundColor();
+    }
+    
+    private void setupDrawMapEnabled() {
+        sessionContext.getSession().asyncRequest(new DrawMapEnabledRequest(getInputResource()), new DrawMapEnabledListener(
+                result -> canvasContext.getEventQueue().queueEvent(new CommandEvent(canvasContext, System.currentTimeMillis(), result ? Commands.MAP_ENABLE : Commands.MAP_DISABLE)),
+                () -> DistrictDiagramViewer.this.isDisposed()));
+    }
+
+    private void setupBackgroundColor() {
+        sessionContext.getSession().asyncRequest(new MapBackgroundColorRequest(getInputResource()), new MapBackgroundColorListener(
+                result -> queueBackgroundColorChangeEvent(result),
+                () -> DistrictDiagramViewer.this.isDisposed()));
+    }
+    
+    private void queueBackgroundColorChangeEvent(RGB.Integer result) {
+        if (result != null) {
+            Color backgroundColor = new Color(result.red, result.green, result.blue);
+            canvasContext.getDefaultHintContext().setHint(MapCommands.KEY_MAP_BACKGROUND_COLOR, backgroundColor);
+            canvasContext.getEventQueue().queueEvent(new CommandEvent(canvasContext, System.currentTimeMillis(), MapCommands.MAP_BACKGROUND_COLOR_CHANGE));
+        }
+    }
+
+    private static class DrawMapEnabledRequest extends UnaryRead<Resource, Boolean> {
+
+        public DrawMapEnabledRequest(Resource diagram) {
+            super(diagram);
+        }
+
+        @Override
+        public Boolean perform(ReadGraph graph) throws DatabaseException {
+            return DistrictNetworkUtil.drawMapEnabled(graph, parameter);
+        }
+    }
+
+    private static class DrawMapEnabledListener implements Listener<Boolean> {
+
+        private static final Logger LOGGER = LoggerFactory.getLogger(DrawMapEnabledListener.class);
+
+        private Consumer<Boolean> callback;
+        private Supplier<Boolean> isDisposed;
+
+        public DrawMapEnabledListener(Consumer<Boolean> callback, Supplier<Boolean> isDisposed) {
+            this.callback = callback;
+            this.isDisposed = isDisposed;
+        }
+
+        @Override
+        public void execute(Boolean result) {
+            callback.accept(result);
+        }
+
+        @Override
+        public void exception(Throwable t) {
+            LOGGER.error("Could not listen if draw map is enabled", t);
+        }
+
+        @Override
+        public boolean isDisposed() {
+            return isDisposed.get();
+        }
+    }
+    
+    private static class MapBackgroundColorRequest extends UnaryRead<Resource, RGB.Integer> {
+
+        public MapBackgroundColorRequest(Resource diagram) {
+            super(diagram);
+        }
+
+        @Override
+        public RGB.Integer perform(ReadGraph graph) throws DatabaseException {
+            return DistrictNetworkUtil.backgroundColor(graph, parameter);
+        }
+    }
+
+    private static class MapBackgroundColorListener implements Listener<RGB.Integer> {
+
+        private static final Logger LOGGER = LoggerFactory.getLogger(DrawMapEnabledListener.class);
+
+        private Consumer<RGB.Integer> callback;
+        private Supplier<Boolean> isDisposed;
+
+        public MapBackgroundColorListener(Consumer<RGB.Integer> callback, Supplier<Boolean> isDisposed) {
+            this.callback = callback;
+            this.isDisposed = isDisposed;
+        }
+
+        @Override
+        public void execute(RGB.Integer result) {
+            callback.accept(result);
+        }
+
+        @Override
+        public void exception(Throwable t) {
+            LOGGER.error("Could not listen map background color", t);
+        }
+
+        @Override
+        public boolean isDisposed() {
+            return isDisposed.get();
+        }
     }
 }
index b0cfad3c0cb3fc6bfbdf08cf3568420489819c2a..e6049b5953f9587070df5ac77bc87bf836f3c186 100644 (file)
@@ -26,7 +26,7 @@ public class SetFocusableHandler {
     public boolean canExecute(IEclipseContext popupContext, @Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) {
         @SuppressWarnings("unchecked")
         Collection<IElement> elements = (Collection<IElement>) popupContext.get(SetFocusableDynamicMenuContribution.FOCUSABLE_ELEMENTS);
-        return !elements.isEmpty();
+        return elements != null && !elements.isEmpty();
     }
     
     @Execute
index 550553f1b88083249877ed8f20c41073adf3efc3..fd72a67378b62609f3061284aca2528723a78512 100644 (file)
@@ -41,7 +41,7 @@ public class DistrictNetworkUtil {
         Resource edge = graph.newResource();
         graph.claim(edge, L0.InstanceOf, DN.Edge);
         
-        graph.claim(edge, DN.HasMapping, mapping);
+        graph.claim(edge, DN.HasMapping, null, mapping);
         
         OrderedSetUtils.addFirst(graph, composite, edge);
         graph.claim(composite, L0.ConsistsOf, L0.PartOf, edge);
@@ -74,7 +74,7 @@ public class DistrictNetworkUtil {
         graph.claim(vertex, L0.InstanceOf, DN.Vertex);
         graph.claimLiteral(vertex, DIA.HasLocation, coords);
         
-        graph.claim(vertex, DN.HasMapping, mapping);
+        graph.claim(vertex, DN.HasMapping, null, mapping);
         
         OrderedSetUtils.add(graph, composite, vertex);
         graph.claim(composite, L0.ConsistsOf, L0.PartOf, vertex);
@@ -223,13 +223,23 @@ public class DistrictNetworkUtil {
         return current != null ? current : true;
     }
 
-    public static void changeMapBackgroundColor(WriteGraph graph, Resource resource, Integer integer) throws DatabaseException {
+    public static void changeMapBackgroundColor(WriteGraph graph, Resource diagram, Integer integer) throws DatabaseException {
         DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
-        graph.claimLiteral(resource, DN.Diagram_backgroundColor, integer, Bindings.getBindingUnchecked(RGB.Integer.class));
+        graph.claimLiteral(diagram, DN.Diagram_backgroundColor, integer, Bindings.getBindingUnchecked(RGB.Integer.class));
     }
     
     public static Boolean trackChangesEnabled(ReadGraph graph, Resource diagram) throws DatabaseException {
-        return Boolean.TRUE.equals(graph.getPossibleRelatedValue(diagram,
+        if (diagram != null && graph.hasStatement(diagram)) {
+            return Boolean.TRUE.equals(graph.getPossibleRelatedValue(diagram,
                 DistrictNetworkResource.getInstance(graph).Diagram_trackChangesEnabled));
+        } else {
+            return false;
+        }
+    }
+
+    public static RGB.Integer backgroundColor(ReadGraph graph, Resource diagram) throws DatabaseException {
+        return graph.getPossibleRelatedValue(diagram,
+                DistrictNetworkResource.getInstance(graph).Diagram_backgroundColor,
+                Bindings.getBindingUnchecked(RGB.Integer.class));
     }
 }