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.scenegraph.g2d.nodes;
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.scenegraph.utils.BufferedImage;
28 import org.simantics.scenegraph.utils.G2DUtils;
29 import org.simantics.scenegraph.utils.MipMapBufferedImage;
30 import org.simantics.scenegraph.utils.MipMapVRamBufferedImage;
31 import org.simantics.scenegraph.utils.VRamBufferedImage;
33 import com.kitfox.svg.SVGCache;
34 import com.kitfox.svg.SVGElement;
35 import com.kitfox.svg.SVGException;
36 import com.kitfox.svg.SVGUniverse;
37 import com.kitfox.svg.xml.StyleAttribute;
39 public class AnimatedSVGNode extends SVGNode {
43 private static final long serialVersionUID = 8698435757824280001L;
44 public Map<String, Object> valuezz = new HashMap<String, Object>();
46 protected String script = null;
48 @PropertySetter("VariableFilter")
50 public void setScript(String script) {
55 public void setValue(String key, Object value) {
56 valuezz.put(key, value);
60 @PropertySetter("valuezz")
62 public void setValuezz(Map<String, Object> val) {
68 public void animate() {
73 public void animate(final String script) {
77 if (dataHash == null) {
78 dataHash = parseSVG();
80 if (diagramCache == null) {
81 // Cannot execute script when SVGDiagram is not available
85 // AnimationExecutor.getInstance().animate(new IAnimation() {
87 // public void run() {
90 ScriptEngineManager manager = new ScriptEngineManager();
91 ScriptEngine engine = manager.getEngineByName("JavaScript");
93 for(String key : valuezz.keySet()) {
94 engine.put(key, valuezz.get(key));
96 engine.put("time", System.currentTimeMillis());
97 engine.put("svg", diagramCache);
98 engine.put("t", AnimatedSVGNode.this);
100 //System.out.println("ANIMATE(" + engine.get("time") + ")");
103 diagramCache.updateTime(0);
107 } catch (ScriptException e) {
108 e.printStackTrace(); // Just report the error..
109 } catch (Throwable t) {
117 protected Map<String, String> eventAnimations = new HashMap<String, String>();
120 public void registerEventAnimation(String event, String animation) {
121 eventAnimations.put(event, animation);
125 public void animateEvent(String event) {
126 if(eventAnimations.containsKey(event)) {
127 animate(eventAnimations.get(event));
135 protected String parseSVG() {
139 dataHash = UUID.randomUUID().toString();
140 // NOTE: hard-coded to assume all SVG data is encoded in UTF-8
141 InputStream is = new ByteArrayInputStream(data.getBytes("UTF-8"));
142 SVGUniverse univ = SVGCache.getSVGUniverse();
143 if (diagramCache != null)
144 univ.decRefCount(diagramCache.getXMLBase());
145 diagramCache = univ.getDiagram(SVGCache.getSVGUniverse().loadSVG(is, dataHash), false);
146 documentCache = data;
148 setBounds((Rectangle2D) diagramCache.getRoot().getBoundingBox().clone());
149 } catch (SVGException e) {
150 setBounds((Rectangle2D) diagramCache.getViewRect().clone());
152 univ.incRefCount(diagramCache.getXMLBase());
153 } catch (IOException e) {
160 @SuppressWarnings("unused")
161 private void print(SVGElement e, int indent) {
162 for(int i=0;i<indent;i++) System.err.print(" ");
163 System.err.println(e);
164 for(int i=0;i<e.getNumChildren();i++) {
165 print(e.getChild(i), indent+2);
167 for(Object o : e.getPresentationAttributes()) {
168 for(int i=0;i<indent;i++) System.err.print(" ");
169 System.err.print(" " + o);
170 System.err.print("=");
171 StyleAttribute sa = e.getPresAbsolute((String)o);
172 System.err.println(sa.getStringValue());
181 protected void initBuffer(Graphics2D g2d) {
182 if (dataHash == null) {
183 dataHash = parseSVG();
186 if (diagramCache == null) {
187 System.out.println("UNABLE TO PARSE ANIMATED SVG:\n" + data);
191 diagramCache.setIgnoringClipHeuristic(true); // FIXME
192 if (diagramCache.getViewRect().getWidth() == 0 || diagramCache.getViewRect().getHeight() == 0) {
196 if (G2DUtils.isAccelerated(g2d)) {
197 buffer = new MipMapVRamBufferedImage(diagramCache, bounds, targetSize);
199 buffer = new MipMapBufferedImage(diagramCache, bounds, targetSize);
202 // FIXME: for some reason, this code causes effects where the graphics, if rotated, will start to pixelate, translate and completely disappear in the end.
204 if (G2DUtils.isAccelerated(g2d)) {
205 buffer = new VRamBufferedImage(diagramCache, bounds, targetSize);
207 buffer = new BufferedImage(diagramCache, bounds, targetSize);
214 // public void handleEvent(AWTEvent event) {
215 // if(event.getID() == KeyEvent.KEY_PRESSED) {
216 // KeyEvent ke = (KeyEvent)event;
217 // switch(ke.getKeyCode()) {
218 // case KeyEvent.VK_LEFT:
219 // animateEvent("LEFT");
222 // case KeyEvent.VK_RIGHT:
223 // animateEvent("RIGHT");
226 // case KeyEvent.VK_UP:
227 // animateEvent("UP");
230 // case KeyEvent.VK_DOWN:
231 // animateEvent("DOWN");
238 // super.handleEvent(event);