]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/AnimatedSVGNode.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / nodes / AnimatedSVGNode.java
diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/AnimatedSVGNode.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/AnimatedSVGNode.java
new file mode 100644 (file)
index 0000000..7e85529
--- /dev/null
@@ -0,0 +1,241 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.scenegraph.g2d.nodes;\r
+\r
+import java.awt.Graphics2D;\r
+import java.awt.geom.Rectangle2D;\r
+import java.io.ByteArrayInputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import java.util.UUID;\r
+\r
+import javax.script.ScriptEngine;\r
+import javax.script.ScriptEngineManager;\r
+import javax.script.ScriptException;\r
+\r
+import org.simantics.scenegraph.utils.BufferedImage;\r
+import org.simantics.scenegraph.utils.G2DUtils;\r
+import org.simantics.scenegraph.utils.MipMapBufferedImage;\r
+import org.simantics.scenegraph.utils.MipMapVRamBufferedImage;\r
+import org.simantics.scenegraph.utils.VRamBufferedImage;\r
+\r
+import com.kitfox.svg.SVGCache;\r
+import com.kitfox.svg.SVGElement;\r
+import com.kitfox.svg.SVGException;\r
+import com.kitfox.svg.SVGUniverse;\r
+import com.kitfox.svg.xml.StyleAttribute;\r
+\r
+public class AnimatedSVGNode extends SVGNode {\r
+    /**\r
+     * \r
+     */\r
+    private static final long serialVersionUID = 8698435757824280001L;\r
+    public Map<String, Object> valuezz = new HashMap<String, Object>();\r
+\r
+    protected String      script       = null;\r
+\r
+    @PropertySetter("VariableFilter")\r
+    @SyncField("script")\r
+    public void setScript(String script) {\r
+        this.script = script;\r
+    }\r
+\r
+    @SyncField("values")\r
+    public void setValue(String key, Object value) {\r
+        valuezz.put(key, value);\r
+        animate();\r
+    }\r
+    \r
+    @PropertySetter("valuezz")\r
+    @SyncField("valuezz")\r
+    public void setValuezz(Map<String, Object> val) {\r
+        valuezz = val;\r
+        animate();\r
+    }\r
+\r
+    @ClientSide\r
+    public void animate() {\r
+        animate(script);\r
+    }\r
+\r
+    @ClientSide\r
+    public void animate(final String script) {\r
+        if (script == null)\r
+            return;\r
+\r
+        if (dataHash == null) {\r
+            dataHash = parseSVG();\r
+        }\r
+        if (diagramCache == null) {\r
+            // Cannot execute script when SVGDiagram is not available\r
+            return;\r
+        }\r
+\r
+//        AnimationExecutor.getInstance().animate(new IAnimation() {\r
+//            @Override\r
+//            public void run() {\r
+        try {\r
+\r
+            ScriptEngineManager manager = new ScriptEngineManager();\r
+            ScriptEngine engine = manager.getEngineByName("JavaScript");\r
+\r
+            for(String key : valuezz.keySet()) {\r
+                engine.put(key, valuezz.get(key));\r
+            }\r
+            engine.put("time", System.currentTimeMillis());\r
+            engine.put("svg", diagramCache);\r
+            engine.put("t", AnimatedSVGNode.this);\r
+\r
+            //System.out.println("ANIMATE(" + engine.get("time") + ")");\r
+            engine.eval(script);\r
+\r
+            diagramCache.updateTime(0);\r
+\r
+            buffer = null;\r
+\r
+        } catch (ScriptException e) {\r
+            e.printStackTrace(); // Just report the error..\r
+        } catch (Throwable t) {\r
+            t.printStackTrace();\r
+        }\r
+\r
+//            }\r
+//        });\r
+    }\r
+\r
+    protected Map<String, String> eventAnimations = new HashMap<String, String>();\r
+\r
+    @ClientSide\r
+    public void registerEventAnimation(String event, String animation) {\r
+        eventAnimations.put(event, animation);\r
+    }\r
+\r
+    @ClientSide\r
+    public void animateEvent(String event) {\r
+        if(eventAnimations.containsKey(event)) {\r
+            animate(eventAnimations.get(event));\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Use UUID hash\r
+     */\r
+    @Override\r
+    protected String parseSVG() {\r
+        if (data == null)\r
+            return null;\r
+        try {\r
+            dataHash = UUID.randomUUID().toString();\r
+            // NOTE: hard-coded to assume all SVG data is encoded in UTF-8\r
+            InputStream is = new ByteArrayInputStream(data.getBytes("UTF-8"));\r
+            SVGUniverse univ = SVGCache.getSVGUniverse();\r
+            if (diagramCache != null)\r
+                univ.decRefCount(diagramCache.getXMLBase());\r
+            diagramCache = univ.getDiagram(SVGCache.getSVGUniverse().loadSVG(is, dataHash), false);\r
+            documentCache = data;\r
+            try {\r
+                setBounds((Rectangle2D) diagramCache.getRoot().getBoundingBox().clone());\r
+            } catch (SVGException e) {\r
+                setBounds((Rectangle2D) diagramCache.getViewRect().clone());\r
+            }\r
+            univ.incRefCount(diagramCache.getXMLBase());\r
+        } catch (IOException e) {\r
+            diagramCache = null;\r
+        }\r
+\r
+        return dataHash;\r
+    }\r
+\r
+    @SuppressWarnings("unused")\r
+    private void print(SVGElement e, int indent) {\r
+        for(int i=0;i<indent;i++) System.err.print(" ");\r
+        System.err.println(e);\r
+        for(int i=0;i<e.getNumChildren();i++) {\r
+            print(e.getChild(i), indent+2);\r
+        }\r
+        for(Object o : e.getPresentationAttributes()) {\r
+            for(int i=0;i<indent;i++) System.err.print(" ");\r
+            System.err.print("  " + o);\r
+            System.err.print("=");\r
+            StyleAttribute sa = e.getPresAbsolute((String)o);\r
+            System.err.println(sa.getStringValue());\r
+\r
+        }\r
+    }\r
+\r
+    /**\r
+     * ..skip buffering\r
+     */\r
+    @Override\r
+    protected void initBuffer(Graphics2D g2d) {\r
+        if (dataHash == null) {\r
+            dataHash = parseSVG();\r
+        }\r
+\r
+        if (diagramCache == null) {\r
+            System.out.println("UNABLE TO PARSE ANIMATED SVG:\n" + data);\r
+            return;\r
+        }\r
+\r
+        diagramCache.setIgnoringClipHeuristic(true); // FIXME\r
+        if (diagramCache.getViewRect().getWidth() == 0 || diagramCache.getViewRect().getHeight() == 0) {\r
+            buffer = null;\r
+        } else {\r
+            if(useMipMap) {\r
+                if (G2DUtils.isAccelerated(g2d)) {\r
+                    buffer = new MipMapVRamBufferedImage(diagramCache, bounds, targetSize);\r
+                } else {\r
+                    buffer = new MipMapBufferedImage(diagramCache, bounds, targetSize);\r
+                }\r
+            } else {\r
+                // FIXME: for some reason, this code causes effects where the graphics, if rotated, will start to pixelate, translate and completely disappear in the end.\r
+                // See issue #2396.\r
+                if (G2DUtils.isAccelerated(g2d)) {\r
+                    buffer = new VRamBufferedImage(diagramCache, bounds, targetSize);\r
+                } else {\r
+                    buffer = new BufferedImage(diagramCache, bounds, targetSize);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+//    @Override\r
+//    public void handleEvent(AWTEvent event) {\r
+//        if(event.getID() == KeyEvent.KEY_PRESSED) {\r
+//            KeyEvent ke = (KeyEvent)event;\r
+//            switch(ke.getKeyCode()) {\r
+//                case KeyEvent.VK_LEFT:\r
+//                    animateEvent("LEFT");\r
+//                    break;\r
+//\r
+//                case KeyEvent.VK_RIGHT:\r
+//                    animateEvent("RIGHT");\r
+//                    break;\r
+//\r
+//                case KeyEvent.VK_UP:\r
+//                    animateEvent("UP");\r
+//                    break;\r
+//\r
+//                case KeyEvent.VK_DOWN:\r
+//                    animateEvent("DOWN");\r
+//                    break;\r
+//                default:\r
+//                    break;\r
+//            }\r
+//        }\r
+//\r
+//        super.handleEvent(event);\r
+//    }\r
+\r
+}\r