X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.diagram%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Fparticipant%2FDiagramModelActivityTracker.java;h=e2787743886058aaf4a5ab0b5e4fde0984ca2c99;hb=a96e5125d72579c43abd70eb5c23de835324eaad;hp=a12043f10375dd7c781c402e531c18e200772e01;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git
diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/DiagramModelActivityTracker.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/DiagramModelActivityTracker.java
index a12043f10..e27877438 100644
--- a/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/DiagramModelActivityTracker.java
+++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/DiagramModelActivityTracker.java
@@ -1,245 +1,272 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
- * in Industry THTH ry.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * VTT Technical Research Centre of Finland - initial API and implementation
- *******************************************************************************/
-package org.simantics.diagram.participant;
-
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-
-import org.simantics.Simantics;
-import org.simantics.db.ReadGraph;
-import org.simantics.db.Resource;
-import org.simantics.db.common.request.PossibleIndexRoot;
-import org.simantics.db.common.request.UnaryRead;
-import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.layer0.adapter.Instances;
-import org.simantics.db.layer0.request.IsActive;
-import org.simantics.db.layer0.util.Layer0Utils;
-import org.simantics.db.procedure.Listener;
-import org.simantics.diagram.elements.TextNode;
-import org.simantics.diagram.stubs.DiagramResource;
-import org.simantics.g2d.canvas.Hints;
-import org.simantics.g2d.canvas.ICanvasContext;
-import org.simantics.g2d.canvas.SGDesignation;
-import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;
-import org.simantics.g2d.canvas.impl.HintReflection.HintListener;
-import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup;
-import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
-import org.simantics.g2d.utils.Alignment;
-import org.simantics.layer0.Layer0;
-import org.simantics.modeling.ModelingResources;
-import org.simantics.scenegraph.g2d.G2DParentNode;
-import org.simantics.structural.stubs.StructuralResource2;
-import org.simantics.utils.datastructures.hints.IHintContext;
-import org.simantics.utils.datastructures.hints.IHintContext.Key;
-import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
-import org.simantics.utils.datastructures.hints.IHintObservable;
-import org.simantics.utils.ui.ErrorLogger;
-
-/**
- * DiagramModelActivityTracker tracks whether or not the specified input
- * resource is part of the diagram model or not and modifies the canvas
- * background color accordingly. If the diagram is not in an active model, an
- * INACTIVE MODEL banner is also shown in the background using
- * {@link TextNode}.
- *
- * @author Tuukka Lehtonen
- */
-public class DiagramModelActivityTracker extends AbstractCanvasParticipant {
-
- public static final Key KEY_IN_ACTIVE_MODEL = new KeyOf(String.class, "IN_ACTIVE_MODEL");
- public static final Key KEY_ACTIVE_BACKGROUND = new KeyOf(Color.class, "ACTIVE_BACKGROUND");
- public static final Key KEY_INACTIVE_BACKGROUND = new KeyOf(Color.class, "INACTIVE_BACKGROUND");
-
- private static final Color DEFAULT_ACTIVE_BACKGROUND = Color.WHITE;
- private static final Color DEFAULT_INACTIVE_BACKGROUND = new Color(242, 242, 242);
-
- Resource input;
- IsInActiveModelListener listener;
- TextNode bannerNode;
-
- public DiagramModelActivityTracker(Resource input) {
- if (input == null)
- throw new NullPointerException("null input");
- this.input = input;
- }
-
- @HintListener(Class=Hints.class, Field="KEY_CONTROL_BOUNDS")
- public void controlBoundsChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
- if (bannerNode == null)
- return;
- if (newValue != null) {
- Rectangle2D bounds = (Rectangle2D) newValue;
- AffineTransform at = new AffineTransform();
- at.translate(5,5);
-// at.translate(bounds.getWidth() / 2, bounds.getHeight() / 2);
-// at.scale(2, 2);
-// at.rotate(-Math.PI/6);
-// at.translate(bounds.getWidth() - 150, bounds.getHeight() - 30);
-// at.scale(1, 1);
- bannerNode.setTransform(at);
- } else {
- // Disable rendering
- bannerNode.setColor(null);
- }
- }
-
- @HintListener(Class=DiagramModelActivityTracker.class, Field="KEY_IN_ACTIVE_MODEL")
- public void containingModelActivityChanged(IHintObservable sender, Key key, Object oldValue, Object _newValue) {
- String newValue = (String)_newValue;
- if (bannerNode == null)
- return;
- if (newValue == null) {
- bannerNode.setText("");
- } else {
- bannerNode.setText(newValue);
- //bannerNode.setColor(new Color(192, 32, 32, 128));
- //bannerNode.setColor(new Color(192, 32, 32, 32));
- }
- }
-
- @Override
- public void addedToContext(ICanvasContext ctx) {
- super.addedToContext(ctx);
-
- listener = new IsInActiveModelListener(ctx);
- Simantics.getSession().async(new IsActiveDiagram(input), listener);
-
- if (!ctx.getHintStack().containsHint(KEY_ACTIVE_BACKGROUND))
- ctx.getDefaultHintContext().setHint(KEY_ACTIVE_BACKGROUND, DEFAULT_ACTIVE_BACKGROUND);
- if (!ctx.getHintStack().containsHint(KEY_INACTIVE_BACKGROUND))
- ctx.getDefaultHintContext().setHint(KEY_INACTIVE_BACKGROUND, DEFAULT_INACTIVE_BACKGROUND);
- }
-
- @Override
- public void removedFromContext(ICanvasContext ctx) {
- if (listener != null) {
- listener.dispose();
- listener = null;
- }
- super.removedFromContext(ctx);
- }
-
- @SGInit(designation = SGDesignation.CONTROL)
- public void initSG(G2DParentNode parent) {
- bannerNode = parent.addNode("inactivity-banner", TextNode.class);
- bannerNode.setZIndex(Integer.MIN_VALUE / 4);
- //bannerNode.setZIndex(Integer.MAX_VALUE / 4);
- bannerNode.setHorizontalAlignment((byte) Alignment.LEADING.ordinal());
- bannerNode.setVerticalAlignment((byte) Alignment.LEADING.ordinal());
- //bannerNode.setText("Model is not active.");
- bannerNode.setText("");
- bannerNode.setFont(Font.decode("Arial 16"));
- //bannerNode.setBackgroundColor(new Color(192, 192, 192, 128));
- bannerNode.setPadding(10, 10);
- bannerNode.setBorderColor(Color.GRAY);
- bannerNode.setBorderWidth(0);
- bannerNode.setEditable(false);
- }
-
- @SGCleanup
- public void cleanupSG() {
- if (bannerNode != null) {
- bannerNode.remove();
- bannerNode = null;
- }
- }
-
- static class IsActiveDiagram extends UnaryRead {
- public IsActiveDiagram(Resource parameter) {
- super(parameter);
- }
- @Override
- public String perform(ReadGraph graph) throws DatabaseException {
-
- Resource indexRoot = graph.syncRequest( new PossibleIndexRoot(parameter) );
- if (indexRoot == null) {
- return "This diagram is not part of any model or shared library";
- }
- Layer0 L0 = Layer0.getInstance(graph);
- StructuralResource2 STR = StructuralResource2.getInstance(graph);
- ModelingResources MOD = ModelingResources.getInstance(graph);
- Resource composite = graph.getPossibleObject(parameter, MOD.DiagramToComposite);
- if(composite == null)
- return "This diagram does not have a corresponding configuration";
-
- Resource componentType = graph.getPossibleObject(composite, STR.Defines);
- if(componentType != null) {
- // This is a component type
- boolean published = Layer0Utils.isPublished(graph, componentType);
- if(published)
- return "This diagram defines a published (read-only) user component";
- }
-
- if(graph.isInstanceOf(indexRoot, L0.SharedOntology)) {
- return "";
- }
-
- boolean activeModel = graph.syncRequest( new IsActive(indexRoot) );
- if(!activeModel)
- return "The model of this diagram is not active";
-
- DiagramResource DIA = DiagramResource.getInstance(graph);
- Instances query = graph.adapt(DIA.DiagramActivityCondition, Instances.class);
-
- for(Resource condition : query.find(graph, indexRoot)) {
- String value = Simantics.tryInvokeSCL(graph, condition, DIA.DiagramActivityCondition_test, parameter);
- if(value != null && !value.isEmpty()) return value;
- }
-
- return "";
-
- }
- }
-
- static class IsInActiveModelListener implements Listener {
- ICanvasContext context;
- public IsInActiveModelListener(ICanvasContext context) {
- this.context = context;
- }
- @Override
- public void execute(final String result) {
- final Color color = (result.isEmpty())
- ? context.getHintStack().getHint(KEY_ACTIVE_BACKGROUND)
- : context.getHintStack().getHint(KEY_INACTIVE_BACKGROUND);
-
- context.getThreadAccess().asyncExec(new Runnable() {
- @Override
- public void run() {
- ICanvasContext ctx = context;
- if (ctx == null)
- return;
- if (ctx.isDisposed())
- return;
- IHintContext hints = ctx.getDefaultHintContext();
- if (color != null)
- hints.setHint(Hints.KEY_BACKGROUND_COLOR, color);
- hints.setHint(KEY_IN_ACTIVE_MODEL, result);
- }
- });
- }
- public void dispose() {
- context = null;
- }
- @Override
- public boolean isDisposed() {
- ICanvasContext context = this.context;
- return context == null || context.isDisposed();
- }
- @Override
- public void exception(Throwable t) {
- ErrorLogger.defaultLogError(t);
- }
- }
-
-}
+/*******************************************************************************
+ * Copyright (c) 2007, 2018 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.diagram.participant;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.PossibleIndexRoot;
+import org.simantics.db.common.request.UnaryRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.adapter.Instances;
+import org.simantics.db.layer0.request.IsActive;
+import org.simantics.db.layer0.util.Layer0Utils;
+import org.simantics.db.procedure.Listener;
+import org.simantics.diagram.elements.TextNode;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.g2d.canvas.Hints;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.canvas.SGDesignation;
+import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;
+import org.simantics.g2d.canvas.impl.HintReflection.HintListener;
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup;
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
+import org.simantics.g2d.participant.RulerPainter;
+import org.simantics.g2d.utils.Alignment;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.scenegraph.g2d.G2DParentNode;
+import org.simantics.scenegraph.utils.DPIUtil;
+import org.simantics.structural.stubs.StructuralResource2;
+import org.simantics.utils.datastructures.hints.IHintContext;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
+import org.simantics.utils.datastructures.hints.IHintObservable;
+import org.simantics.utils.ui.ErrorLogger;
+
+/**
+ * DiagramModelActivityTracker tracks whether or not the specified input
+ * resource is part of the diagram model or not and modifies the canvas
+ * background color accordingly. If the diagram is not in an active model, an
+ * INACTIVE MODEL banner is also shown in the background using
+ * {@link TextNode}.
+ *
+ * @author Tuukka Lehtonen
+ */
+public class DiagramModelActivityTracker extends AbstractCanvasParticipant {
+
+ public static final Key KEY_IN_ACTIVE_MODEL = new KeyOf(String.class, "IN_ACTIVE_MODEL");
+ public static final Key KEY_ACTIVE_BACKGROUND = new KeyOf(Color.class, "ACTIVE_BACKGROUND");
+ public static final Key KEY_INACTIVE_BACKGROUND = new KeyOf(Color.class, "INACTIVE_BACKGROUND");
+
+ private static final Color DEFAULT_ACTIVE_BACKGROUND = Color.WHITE;
+ private static final Color DEFAULT_INACTIVE_BACKGROUND = new Color(242, 242, 242);
+
+ Resource input;
+ IsInActiveModelListener listener;
+ TextNode bannerNode;
+ Rectangle2D bounds;
+ boolean rulerVisible = false;
+ double rulerSize = 0;
+
+ public DiagramModelActivityTracker(Resource input) {
+ if (input == null)
+ throw new NullPointerException("null input");
+ this.input = input;
+ }
+
+ @HintListener(Class=Hints.class, Field="KEY_CONTROL_BOUNDS")
+ public void controlBoundsChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
+ bounds = (Rectangle2D) newValue;
+ resetBannerNode(bounds, rulerVisible, rulerSize);
+ }
+
+ @HintListener(Class=RulerPainter.class, Field="KEY_RULER_ENABLED")
+ public void rulerToggled(IHintObservable sender, Key key, Object oldValue, Object newValue) {
+ rulerVisible = Boolean.TRUE.equals(newValue);
+ resetBannerNode(bounds, rulerVisible, rulerSize);
+ }
+
+ @HintListener(Class=RulerPainter.class, Field="KEY_RULER_SIZE")
+ public void rulerSizeChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
+ rulerSize = newValue != null ? (Double) newValue : 0.0;
+ resetBannerNode(bounds, rulerVisible, rulerSize);
+ }
+
+ private void resetBannerNode(Rectangle2D bounds, boolean rulerVisible, double rulerSize) {
+ if (bannerNode == null)
+ return;
+ if (bounds != null) {
+ AffineTransform at = new AffineTransform();
+ at.translate(5,5);
+ if (rulerVisible) {
+ double s = DPIUtil.upscale(rulerSize);
+ at.translate(s, s);
+ }
+ bannerNode.setTransform(at);
+ bannerNode.setColor(Color.BLACK);
+ } else {
+ // Disable rendering
+ bannerNode.setColor(null);
+ }
+ }
+
+ @HintListener(Class=DiagramModelActivityTracker.class, Field="KEY_IN_ACTIVE_MODEL")
+ public void containingModelActivityChanged(IHintObservable sender, Key key, Object oldValue, Object _newValue) {
+ String newValue = (String)_newValue;
+ if (bannerNode == null)
+ return;
+ if (newValue == null) {
+ bannerNode.setText("");
+ } else {
+ bannerNode.setText(newValue);
+ //bannerNode.setColor(new Color(192, 32, 32, 128));
+ //bannerNode.setColor(new Color(192, 32, 32, 32));
+ }
+ }
+
+ @Override
+ public void addedToContext(ICanvasContext ctx) {
+ super.addedToContext(ctx);
+
+ rulerVisible = Boolean.TRUE.equals(getHint(RulerPainter.KEY_RULER_ENABLED));
+ Double rs = getHint(RulerPainter.KEY_RULER_SIZE);
+ rulerSize = rs != null ? rs : 0;
+
+ listener = new IsInActiveModelListener(ctx);
+ Simantics.getSession().async(new IsActiveDiagram(input), listener);
+
+ if (!ctx.getHintStack().containsHint(KEY_ACTIVE_BACKGROUND))
+ ctx.getDefaultHintContext().setHint(KEY_ACTIVE_BACKGROUND, DEFAULT_ACTIVE_BACKGROUND);
+ if (!ctx.getHintStack().containsHint(KEY_INACTIVE_BACKGROUND))
+ ctx.getDefaultHintContext().setHint(KEY_INACTIVE_BACKGROUND, DEFAULT_INACTIVE_BACKGROUND);
+ }
+
+ @Override
+ public void removedFromContext(ICanvasContext ctx) {
+ if (listener != null) {
+ listener.dispose();
+ listener = null;
+ }
+ super.removedFromContext(ctx);
+ }
+
+ @SGInit(designation = SGDesignation.CONTROL)
+ public void initSG(G2DParentNode parent) {
+ bannerNode = parent.addNode("inactivity-banner", TextNode.class);
+ bannerNode.setZIndex(Integer.MIN_VALUE / 4);
+ //bannerNode.setZIndex(Integer.MAX_VALUE / 4);
+ bannerNode.setHorizontalAlignment((byte) Alignment.LEADING.ordinal());
+ bannerNode.setVerticalAlignment((byte) Alignment.LEADING.ordinal());
+ //bannerNode.setText("Model is not active.");
+ bannerNode.setText("");
+ int fontSize = DPIUtil.upscale(16);
+ bannerNode.setFont(new Font("Tahoma", Font.PLAIN, fontSize));
+ //bannerNode.setBackgroundColor(new Color(192, 192, 192, 128));
+ bannerNode.setPadding(10, 10);
+ bannerNode.setBorderColor(Color.GRAY);
+ bannerNode.setBorderWidth(0);
+ bannerNode.setEditable(false);
+ bannerNode.setColor(Color.BLACK);
+ }
+
+ @SGCleanup
+ public void cleanupSG() {
+ if (bannerNode != null) {
+ bannerNode.remove();
+ bannerNode = null;
+ }
+ }
+
+ static class IsActiveDiagram extends UnaryRead {
+ public IsActiveDiagram(Resource parameter) {
+ super(parameter);
+ }
+ @Override
+ public String perform(ReadGraph graph) throws DatabaseException {
+
+ Resource indexRoot = graph.syncRequest( new PossibleIndexRoot(parameter) );
+ if (indexRoot == null) {
+ return "This diagram is not part of any model or shared library";
+ }
+ Layer0 L0 = Layer0.getInstance(graph);
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+ ModelingResources MOD = ModelingResources.getInstance(graph);
+ Resource composite = graph.getPossibleObject(parameter, MOD.DiagramToComposite);
+ if(composite == null)
+ return "This diagram does not have a corresponding configuration";
+
+ Resource componentType = graph.getPossibleObject(composite, STR.Defines);
+ if(componentType != null) {
+ // This is a component type
+ boolean published = Layer0Utils.isPublished(graph, componentType);
+ if(published)
+ return "This diagram defines a published (read-only) user component";
+ }
+
+ if(graph.isInstanceOf(indexRoot, L0.SharedOntology)) {
+ return "";
+ }
+
+ boolean activeModel = graph.syncRequest( new IsActive(indexRoot) );
+ if(!activeModel)
+ return "The model of this diagram is not active";
+
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+ Instances query = graph.adapt(DIA.DiagramActivityCondition, Instances.class);
+
+ for(Resource condition : query.find(graph, indexRoot)) {
+ String value = Simantics.tryInvokeSCL(graph, condition, DIA.DiagramActivityCondition_test, parameter);
+ if(value != null && !value.isEmpty()) return value;
+ }
+
+ return "";
+
+ }
+ }
+
+ static class IsInActiveModelListener implements Listener {
+ ICanvasContext context;
+ public IsInActiveModelListener(ICanvasContext context) {
+ this.context = context;
+ }
+ @Override
+ public void execute(final String result) {
+ final Color color = (result.isEmpty())
+ ? context.getHintStack().getHint(KEY_ACTIVE_BACKGROUND)
+ : context.getHintStack().getHint(KEY_INACTIVE_BACKGROUND);
+
+ context.getThreadAccess().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ ICanvasContext ctx = context;
+ if (ctx == null)
+ return;
+ if (ctx.isDisposed())
+ return;
+ IHintContext hints = ctx.getDefaultHintContext();
+ if (color != null)
+ hints.setHint(Hints.KEY_BACKGROUND_COLOR, color);
+ hints.setHint(KEY_IN_ACTIVE_MODEL, result);
+ }
+ });
+ }
+ public void dispose() {
+ context = null;
+ }
+ @Override
+ public boolean isDisposed() {
+ ICanvasContext context = this.context;
+ return context == null || context.isDisposed();
+ }
+ @Override
+ public void exception(Throwable t) {
+ ErrorLogger.defaultLogError(t);
+ }
+ }
+
+}