]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.diagram/src/org/simantics/diagram/elements/AnimatedSVGNode.java
Editing of texts inside SVG elements
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / elements / AnimatedSVGNode.java
diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/elements/AnimatedSVGNode.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/elements/AnimatedSVGNode.java
new file mode 100644 (file)
index 0000000..e4924d1
--- /dev/null
@@ -0,0 +1,242 @@
+/*******************************************************************************
+ * 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.elements;
+
+import java.awt.Graphics2D;
+import java.awt.geom.Rectangle2D;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+
+import org.simantics.g2d.elementclass.AnimatedNode;
+import org.simantics.scenegraph.utils.BufferedImage;
+import org.simantics.scenegraph.utils.G2DUtils;
+import org.simantics.scenegraph.utils.MipMapBufferedImage;
+import org.simantics.scenegraph.utils.MipMapVRamBufferedImage;
+import org.simantics.scenegraph.utils.VRamBufferedImage;
+
+import com.kitfox.svg.SVGCache;
+import com.kitfox.svg.SVGElement;
+import com.kitfox.svg.SVGException;
+import com.kitfox.svg.SVGUniverse;
+import com.kitfox.svg.xml.StyleAttribute;
+
+public class AnimatedSVGNode extends SVGNode implements AnimatedNode {
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 8698435757824280001L;
+    public Map<String, Object> valuezz = new HashMap<String, Object>();
+
+    protected String      script       = null;
+
+    @PropertySetter("VariableFilter")
+    @SyncField("script")
+    public void setScript(String script) {
+        this.script = script;
+    }
+
+    @SyncField("values")
+    public void setValue(String key, Object value) {
+        valuezz.put(key, value);
+        animate();
+    }
+    
+    @PropertySetter("valuezz")
+    @SyncField("valuezz")
+    public void setValuezz(Map<String, Object> val) {
+        valuezz = val;
+        animate();
+    }
+
+    @ClientSide
+    public void animate() {
+        animate(script);
+    }
+
+    @ClientSide
+    public void animate(final String script) {
+        if (script == null)
+            return;
+
+        if (dataHash == null) {
+            dataHash = parseSVG();
+        }
+        if (diagramCache == null) {
+            // Cannot execute script when SVGDiagram is not available
+            return;
+        }
+
+//        AnimationExecutor.getInstance().animate(new IAnimation() {
+//            @Override
+//            public void run() {
+        try {
+
+            ScriptEngineManager manager = new ScriptEngineManager();
+            ScriptEngine engine = manager.getEngineByName("JavaScript");
+
+            for(String key : valuezz.keySet()) {
+                engine.put(key, valuezz.get(key));
+            }
+            engine.put("time", System.currentTimeMillis());
+            engine.put("svg", diagramCache);
+            engine.put("t", AnimatedSVGNode.this);
+
+            //System.out.println("ANIMATE(" + engine.get("time") + ")");
+            engine.eval(script);
+
+            diagramCache.updateTime(0);
+
+            buffer = null;
+
+        } catch (ScriptException e) {
+            e.printStackTrace(); // Just report the error..
+        } catch (Throwable t) {
+            t.printStackTrace();
+        }
+
+//            }
+//        });
+    }
+
+    protected Map<String, String> eventAnimations = new HashMap<String, String>();
+
+    @ClientSide
+    public void registerEventAnimation(String event, String animation) {
+        eventAnimations.put(event, animation);
+    }
+
+    @ClientSide
+    public void animateEvent(String event) {
+        if(eventAnimations.containsKey(event)) {
+            animate(eventAnimations.get(event));
+        }
+    }
+
+    /**
+     * Use UUID hash
+     */
+    @Override
+    protected String parseSVG() {
+        if (data == null)
+            return null;
+        try {
+            dataHash = UUID.randomUUID().toString();
+            // NOTE: hard-coded to assume all SVG data is encoded in UTF-8
+            InputStream is = new ByteArrayInputStream(data.getBytes("UTF-8"));
+            SVGUniverse univ = SVGCache.getSVGUniverse();
+            if (diagramCache != null)
+                univ.decRefCount(diagramCache.getXMLBase());
+            diagramCache = univ.getDiagram(SVGCache.getSVGUniverse().loadSVG(is, dataHash), false);
+            documentCache = data;
+            try {
+                setBounds((Rectangle2D) diagramCache.getRoot().getBoundingBox().clone());
+            } catch (SVGException e) {
+                setBounds((Rectangle2D) diagramCache.getViewRect().clone());
+            }
+            univ.incRefCount(diagramCache.getXMLBase());
+        } catch (IOException e) {
+            diagramCache = null;
+        }
+
+        return dataHash;
+    }
+
+    @SuppressWarnings("unused")
+    private void print(SVGElement e, int indent) {
+        for(int i=0;i<indent;i++) System.err.print(" ");
+        System.err.println(e);
+        for(int i=0;i<e.getNumChildren();i++) {
+            print(e.getChild(i), indent+2);
+        }
+        for(Object o : e.getPresentationAttributes()) {
+            for(int i=0;i<indent;i++) System.err.print(" ");
+            System.err.print("  " + o);
+            System.err.print("=");
+            StyleAttribute sa = e.getPresAbsolute((String)o);
+            System.err.println(sa.getStringValue());
+
+        }
+    }
+
+    /**
+     * ..skip buffering
+     */
+    @Override
+    protected void initBuffer(Graphics2D g2d) {
+        if (dataHash == null) {
+            dataHash = parseSVG();
+        }
+
+        if (diagramCache == null) {
+            System.out.println("UNABLE TO PARSE ANIMATED SVG:\n" + data);
+            return;
+        }
+
+        diagramCache.setIgnoringClipHeuristic(true); // FIXME
+        if (diagramCache.getViewRect().getWidth() == 0 || diagramCache.getViewRect().getHeight() == 0) {
+            buffer = null;
+        } else {
+            if(useMipMap) {
+                if (G2DUtils.isAccelerated(g2d)) {
+                    buffer = new MipMapVRamBufferedImage(diagramCache, bounds, targetSize);
+                } else {
+                    buffer = new MipMapBufferedImage(diagramCache, bounds, targetSize);
+                }
+            } else {
+                // FIXME: for some reason, this code causes effects where the graphics, if rotated, will start to pixelate, translate and completely disappear in the end.
+                // See issue #2396.
+                if (G2DUtils.isAccelerated(g2d)) {
+                    buffer = new VRamBufferedImage(diagramCache, bounds, targetSize);
+                } else {
+                    buffer = new BufferedImage(diagramCache, bounds, targetSize);
+                }
+            }
+        }
+    }
+
+//    @Override
+//    public void handleEvent(AWTEvent event) {
+//        if(event.getID() == KeyEvent.KEY_PRESSED) {
+//            KeyEvent ke = (KeyEvent)event;
+//            switch(ke.getKeyCode()) {
+//                case KeyEvent.VK_LEFT:
+//                    animateEvent("LEFT");
+//                    break;
+//
+//                case KeyEvent.VK_RIGHT:
+//                    animateEvent("RIGHT");
+//                    break;
+//
+//                case KeyEvent.VK_UP:
+//                    animateEvent("UP");
+//                    break;
+//
+//                case KeyEvent.VK_DOWN:
+//                    animateEvent("DOWN");
+//                    break;
+//                default:
+//                    break;
+//            }
+//        }
+//
+//        super.handleEvent(event);
+//    }
+
+}