--- /dev/null
+/*******************************************************************************\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