1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.diagram.elements;
14 import java.awt.Graphics2D;
15 import java.awt.geom.Rectangle2D;
16 import java.io.ByteArrayInputStream;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.util.HashMap;
21 import java.util.UUID;
23 import javax.script.ScriptEngine;
24 import javax.script.ScriptEngineManager;
25 import javax.script.ScriptException;
27 import org.simantics.g2d.elementclass.AnimatedNode;
28 import org.simantics.scenegraph.utils.BufferedImage;
29 import org.simantics.scenegraph.utils.G2DUtils;
30 import org.simantics.scenegraph.utils.MipMapBufferedImage;
31 import org.simantics.scenegraph.utils.MipMapVRamBufferedImage;
32 import org.simantics.scenegraph.utils.VRamBufferedImage;
34 import com.kitfox.svg.SVGCache;
35 import com.kitfox.svg.SVGElement;
36 import com.kitfox.svg.SVGException;
37 import com.kitfox.svg.SVGUniverse;
38 import com.kitfox.svg.xml.StyleAttribute;
40 public class AnimatedSVGNode extends SVGNode implements AnimatedNode {
44 private static final long serialVersionUID = 8698435757824280001L;
45 public Map<String, Object> valuezz = new HashMap<String, Object>();
47 protected String script = null;
49 @PropertySetter("VariableFilter")
51 public void setScript(String script) {
56 public void setValue(String key, Object value) {
57 valuezz.put(key, value);
61 @PropertySetter("valuezz")
63 public void setValuezz(Map<String, Object> val) {
69 public void animate() {
74 public void animate(final String script) {
78 if (dataHash == null) {
79 dataHash = parseSVG();
81 if (diagramCache == null) {
82 // Cannot execute script when SVGDiagram is not available
86 // AnimationExecutor.getInstance().animate(new IAnimation() {
88 // public void run() {
91 ScriptEngineManager manager = new ScriptEngineManager();
92 ScriptEngine engine = manager.getEngineByName("JavaScript");
94 for(String key : valuezz.keySet()) {
95 engine.put(key, valuezz.get(key));
97 engine.put("time", System.currentTimeMillis());
98 engine.put("svg", diagramCache);
99 engine.put("t", AnimatedSVGNode.this);
101 //System.out.println("ANIMATE(" + engine.get("time") + ")");
104 diagramCache.updateTime(0);
108 } catch (ScriptException e) {
109 e.printStackTrace(); // Just report the error..
110 } catch (Throwable t) {
118 protected Map<String, String> eventAnimations = new HashMap<String, String>();
121 public void registerEventAnimation(String event, String animation) {
122 eventAnimations.put(event, animation);
126 public void animateEvent(String event) {
127 if(eventAnimations.containsKey(event)) {
128 animate(eventAnimations.get(event));
136 protected String parseSVG() {
140 dataHash = UUID.randomUUID().toString();
141 // NOTE: hard-coded to assume all SVG data is encoded in UTF-8
142 InputStream is = new ByteArrayInputStream(data.getBytes("UTF-8"));
143 SVGUniverse univ = SVGCache.getSVGUniverse();
144 if (diagramCache != null)
145 univ.decRefCount(diagramCache.getXMLBase());
146 diagramCache = univ.getDiagram(SVGCache.getSVGUniverse().loadSVG(is, dataHash), false);
147 documentCache = data;
149 setBounds((Rectangle2D) diagramCache.getRoot().getBoundingBox().clone());
150 } catch (SVGException e) {
151 setBounds((Rectangle2D) diagramCache.getViewRect().clone());
153 univ.incRefCount(diagramCache.getXMLBase());
154 } catch (IOException e) {
161 @SuppressWarnings("unused")
162 private void print(SVGElement e, int indent) {
163 for(int i=0;i<indent;i++) System.err.print(" ");
164 System.err.println(e);
165 for(int i=0;i<e.getNumChildren();i++) {
166 print(e.getChild(i), indent+2);
168 for(Object o : e.getPresentationAttributes()) {
169 for(int i=0;i<indent;i++) System.err.print(" ");
170 System.err.print(" " + o);
171 System.err.print("=");
172 StyleAttribute sa = e.getPresAbsolute((String)o);
173 System.err.println(sa.getStringValue());
182 protected void initBuffer(Graphics2D g2d) {
183 if (dataHash == null) {
184 dataHash = parseSVG();
187 if (diagramCache == null) {
188 System.out.println("UNABLE TO PARSE ANIMATED SVG:\n" + data);
192 diagramCache.setIgnoringClipHeuristic(true); // FIXME
193 if (diagramCache.getViewRect().getWidth() == 0 || diagramCache.getViewRect().getHeight() == 0) {
197 if (G2DUtils.isAccelerated(g2d)) {
198 buffer = new MipMapVRamBufferedImage(diagramCache, bounds, targetSize);
200 buffer = new MipMapBufferedImage(diagramCache, bounds, targetSize);
203 // FIXME: for some reason, this code causes effects where the graphics, if rotated, will start to pixelate, translate and completely disappear in the end.
205 if (G2DUtils.isAccelerated(g2d)) {
206 buffer = new VRamBufferedImage(diagramCache, bounds, targetSize);
208 buffer = new BufferedImage(diagramCache, bounds, targetSize);
215 // public void handleEvent(AWTEvent event) {
216 // if(event.getID() == KeyEvent.KEY_PRESSED) {
217 // KeyEvent ke = (KeyEvent)event;
218 // switch(ke.getKeyCode()) {
219 // case KeyEvent.VK_LEFT:
220 // animateEvent("LEFT");
223 // case KeyEvent.VK_RIGHT:
224 // animateEvent("RIGHT");
227 // case KeyEvent.VK_UP:
228 // animateEvent("UP");
231 // case KeyEvent.VK_DOWN:
232 // animateEvent("DOWN");
239 // super.handleEvent(event);