]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/AnimatedSVGNode.java
Merge commit 'bd5bc6e45f700e755b61bd112631796631330ecb'
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / nodes / AnimatedSVGNode.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.scenegraph.g2d.nodes;\r
13 \r
14 import java.awt.Graphics2D;\r
15 import java.awt.geom.Rectangle2D;\r
16 import java.io.ByteArrayInputStream;\r
17 import java.io.IOException;\r
18 import java.io.InputStream;\r
19 import java.util.HashMap;\r
20 import java.util.Map;\r
21 import java.util.UUID;\r
22 \r
23 import javax.script.ScriptEngine;\r
24 import javax.script.ScriptEngineManager;\r
25 import javax.script.ScriptException;\r
26 \r
27 import org.simantics.scenegraph.utils.BufferedImage;\r
28 import org.simantics.scenegraph.utils.G2DUtils;\r
29 import org.simantics.scenegraph.utils.MipMapBufferedImage;\r
30 import org.simantics.scenegraph.utils.MipMapVRamBufferedImage;\r
31 import org.simantics.scenegraph.utils.VRamBufferedImage;\r
32 \r
33 import com.kitfox.svg.SVGCache;\r
34 import com.kitfox.svg.SVGElement;\r
35 import com.kitfox.svg.SVGException;\r
36 import com.kitfox.svg.SVGUniverse;\r
37 import com.kitfox.svg.xml.StyleAttribute;\r
38 \r
39 public class AnimatedSVGNode extends SVGNode {\r
40     /**\r
41      * \r
42      */\r
43     private static final long serialVersionUID = 8698435757824280001L;\r
44     public Map<String, Object> valuezz = new HashMap<String, Object>();\r
45 \r
46     protected String      script       = null;\r
47 \r
48     @PropertySetter("VariableFilter")\r
49     @SyncField("script")\r
50     public void setScript(String script) {\r
51         this.script = script;\r
52     }\r
53 \r
54     @SyncField("values")\r
55     public void setValue(String key, Object value) {\r
56         valuezz.put(key, value);\r
57         animate();\r
58     }\r
59     \r
60     @PropertySetter("valuezz")\r
61     @SyncField("valuezz")\r
62     public void setValuezz(Map<String, Object> val) {\r
63         valuezz = val;\r
64         animate();\r
65     }\r
66 \r
67     @ClientSide\r
68     public void animate() {\r
69         animate(script);\r
70     }\r
71 \r
72     @ClientSide\r
73     public void animate(final String script) {\r
74         if (script == null)\r
75             return;\r
76 \r
77         if (dataHash == null) {\r
78             dataHash = parseSVG();\r
79         }\r
80         if (diagramCache == null) {\r
81             // Cannot execute script when SVGDiagram is not available\r
82             return;\r
83         }\r
84 \r
85 //        AnimationExecutor.getInstance().animate(new IAnimation() {\r
86 //            @Override\r
87 //            public void run() {\r
88         try {\r
89 \r
90             ScriptEngineManager manager = new ScriptEngineManager();\r
91             ScriptEngine engine = manager.getEngineByName("JavaScript");\r
92 \r
93             for(String key : valuezz.keySet()) {\r
94                 engine.put(key, valuezz.get(key));\r
95             }\r
96             engine.put("time", System.currentTimeMillis());\r
97             engine.put("svg", diagramCache);\r
98             engine.put("t", AnimatedSVGNode.this);\r
99 \r
100             //System.out.println("ANIMATE(" + engine.get("time") + ")");\r
101             engine.eval(script);\r
102 \r
103             diagramCache.updateTime(0);\r
104 \r
105             buffer = null;\r
106 \r
107         } catch (ScriptException e) {\r
108             e.printStackTrace(); // Just report the error..\r
109         } catch (Throwable t) {\r
110             t.printStackTrace();\r
111         }\r
112 \r
113 //            }\r
114 //        });\r
115     }\r
116 \r
117     protected Map<String, String> eventAnimations = new HashMap<String, String>();\r
118 \r
119     @ClientSide\r
120     public void registerEventAnimation(String event, String animation) {\r
121         eventAnimations.put(event, animation);\r
122     }\r
123 \r
124     @ClientSide\r
125     public void animateEvent(String event) {\r
126         if(eventAnimations.containsKey(event)) {\r
127             animate(eventAnimations.get(event));\r
128         }\r
129     }\r
130 \r
131     /**\r
132      * Use UUID hash\r
133      */\r
134     @Override\r
135     protected String parseSVG() {\r
136         if (data == null)\r
137             return null;\r
138         try {\r
139             dataHash = UUID.randomUUID().toString();\r
140             // NOTE: hard-coded to assume all SVG data is encoded in UTF-8\r
141             InputStream is = new ByteArrayInputStream(data.getBytes("UTF-8"));\r
142             SVGUniverse univ = SVGCache.getSVGUniverse();\r
143             if (diagramCache != null)\r
144                 univ.decRefCount(diagramCache.getXMLBase());\r
145             diagramCache = univ.getDiagram(SVGCache.getSVGUniverse().loadSVG(is, dataHash), false);\r
146             documentCache = data;\r
147             try {\r
148                 setBounds((Rectangle2D) diagramCache.getRoot().getBoundingBox().clone());\r
149             } catch (SVGException e) {\r
150                 setBounds((Rectangle2D) diagramCache.getViewRect().clone());\r
151             }\r
152             univ.incRefCount(diagramCache.getXMLBase());\r
153         } catch (IOException e) {\r
154             diagramCache = null;\r
155         }\r
156 \r
157         return dataHash;\r
158     }\r
159 \r
160     @SuppressWarnings("unused")\r
161     private void print(SVGElement e, int indent) {\r
162         for(int i=0;i<indent;i++) System.err.print(" ");\r
163         System.err.println(e);\r
164         for(int i=0;i<e.getNumChildren();i++) {\r
165             print(e.getChild(i), indent+2);\r
166         }\r
167         for(Object o : e.getPresentationAttributes()) {\r
168             for(int i=0;i<indent;i++) System.err.print(" ");\r
169             System.err.print("  " + o);\r
170             System.err.print("=");\r
171             StyleAttribute sa = e.getPresAbsolute((String)o);\r
172             System.err.println(sa.getStringValue());\r
173 \r
174         }\r
175     }\r
176 \r
177     /**\r
178      * ..skip buffering\r
179      */\r
180     @Override\r
181     protected void initBuffer(Graphics2D g2d) {\r
182         if (dataHash == null) {\r
183             dataHash = parseSVG();\r
184         }\r
185 \r
186         if (diagramCache == null) {\r
187             System.out.println("UNABLE TO PARSE ANIMATED SVG:\n" + data);\r
188             return;\r
189         }\r
190 \r
191         diagramCache.setIgnoringClipHeuristic(true); // FIXME\r
192         if (diagramCache.getViewRect().getWidth() == 0 || diagramCache.getViewRect().getHeight() == 0) {\r
193             buffer = null;\r
194         } else {\r
195             if(useMipMap) {\r
196                 if (G2DUtils.isAccelerated(g2d)) {\r
197                     buffer = new MipMapVRamBufferedImage(diagramCache, bounds, targetSize);\r
198                 } else {\r
199                     buffer = new MipMapBufferedImage(diagramCache, bounds, targetSize);\r
200                 }\r
201             } else {\r
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.\r
203                 // See issue #2396.\r
204                 if (G2DUtils.isAccelerated(g2d)) {\r
205                     buffer = new VRamBufferedImage(diagramCache, bounds, targetSize);\r
206                 } else {\r
207                     buffer = new BufferedImage(diagramCache, bounds, targetSize);\r
208                 }\r
209             }\r
210         }\r
211     }\r
212 \r
213 //    @Override\r
214 //    public void handleEvent(AWTEvent event) {\r
215 //        if(event.getID() == KeyEvent.KEY_PRESSED) {\r
216 //            KeyEvent ke = (KeyEvent)event;\r
217 //            switch(ke.getKeyCode()) {\r
218 //                case KeyEvent.VK_LEFT:\r
219 //                    animateEvent("LEFT");\r
220 //                    break;\r
221 //\r
222 //                case KeyEvent.VK_RIGHT:\r
223 //                    animateEvent("RIGHT");\r
224 //                    break;\r
225 //\r
226 //                case KeyEvent.VK_UP:\r
227 //                    animateEvent("UP");\r
228 //                    break;\r
229 //\r
230 //                case KeyEvent.VK_DOWN:\r
231 //                    animateEvent("DOWN");\r
232 //                    break;\r
233 //                default:\r
234 //                    break;\r
235 //            }\r
236 //        }\r
237 //\r
238 //        super.handleEvent(event);\r
239 //    }\r
240 \r
241 }\r