--- /dev/null
+/*******************************************************************************
+ * 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);
+// }
+
+}