-/*******************************************************************************\r
- * Copyright (c) 2012 Association for Decentralized Information Management in\r
- * 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;\r
-\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.Rectangle2D;\r
-import java.io.StringReader;\r
-import java.lang.reflect.Method;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-import java.util.UUID;\r
-\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.binding.Binding;\r
-import org.simantics.databoard.binding.error.BindingException;\r
-import org.simantics.databoard.binding.mutable.Variant;\r
-import org.simantics.scenegraph.utils.BufferedImage;\r
-import org.simantics.scl.runtime.function.Function1;\r
-import org.simantics.scl.runtime.function.FunctionImpl1;\r
-import org.simantics.utils.threads.IThreadWorkQueue;\r
-import org.simantics.utils.threads.ThreadUtils;\r
-\r
-import com.kitfox.svg.SVGDiagram;\r
-import com.kitfox.svg.SVGException;\r
-import com.kitfox.svg.SVGUniverse;\r
-\r
-public class ScenegraphUtils {\r
- \r
- final static protected void dispatch(IThreadWorkQueue queue, final Runnable runnable) {\r
- if(queue == null) runnable.run();\r
- else if(queue.currentThreadAccess()) runnable.run();\r
- else {\r
- ThreadUtils.asyncExec(queue, new Runnable() {\r
- @Override\r
- public void run() {\r
- runnable.run();\r
- }\r
- });\r
- }\r
- }\r
- \r
- private static Class<?> getPropertyType(Method method) {\r
- return (Class<?>)method.getGenericParameterTypes()[0]; \r
- }\r
- \r
- private static Binding getPropertyBinding(Method method) {\r
- try {\r
- return Bindings.getBindingUnchecked(getPropertyType(method));\r
- } catch (Throwable t) {\r
- return null;\r
- }\r
- }\r
- \r
- private static Binding getGenericPropertyBinding(Method method) {\r
- try {\r
- Binding specific = getPropertyBinding(method);\r
- return Bindings.getBinding(specific.type());\r
- } catch (Throwable t) {\r
- return null;\r
- }\r
- }\r
-\r
- private static Method getSynchronizeMethod(Object node, String propertyName) {\r
- try {\r
- String methodName = "synchronize" + propertyName.substring(0,1).toUpperCase() + propertyName.substring(1);\r
- for(Method method : node.getClass().getMethods()) {\r
- if(method.getName().equals(methodName)) return method;\r
- }\r
- } catch (SecurityException e) {\r
- e.printStackTrace();\r
- }\r
- return null;\r
- }\r
- \r
- public static Function1<Object, Boolean> getMethodPropertyFunction(final IThreadWorkQueue queue, final Object node, final String propertyName) {\r
- \r
- final Method synchronizeMethod = getSynchronizeMethod(node, propertyName);\r
- if(synchronizeMethod == null) throw new NodeException("Did not find synchronize method for property '" + propertyName + "'");\r
- final Class<?> type = getPropertyType(synchronizeMethod);\r
- final Binding binding = getPropertyBinding(synchronizeMethod);\r
- final Binding genericBinding = getGenericPropertyBinding(synchronizeMethod);\r
-\r
- return new FunctionImpl1<Object, Boolean>() {\r
-\r
- @Override\r
- public Boolean apply(final Object value) {\r
- \r
- dispatch(queue, new Runnable() {\r
-\r
- @Override\r
- public void run() {\r
- \r
- try {\r
- if(type.isPrimitive()) {\r
- synchronizeMethod.invoke(node, value);\r
- } else if (value == null) {\r
- synchronizeMethod.invoke(node, value);\r
- } else if(type.isInstance(value)) {\r
- synchronizeMethod.invoke(node, value);\r
- } else if (type.isArray()) {\r
- synchronizeMethod.invoke(node, value);\r
- } else {\r
- Object instance = binding.createDefaultUnchecked();\r
- binding.readFrom(genericBinding, value, instance);\r
- synchronizeMethod.invoke(node, instance);\r
- }\r
- } catch (IllegalArgumentException e1) {\r
- e1.printStackTrace();\r
- } catch (IllegalAccessException e1) {\r
- e1.printStackTrace();\r
- } catch (BindingException e) {\r
- e.printStackTrace();\r
- } catch (Throwable t) {\r
- t.printStackTrace();\r
- }\r
- }\r
- \r
- });\r
- return false;\r
- }\r
-\r
- };\r
- \r
- }\r
-\r
- public static SVGDiagram loadSVGDiagram(SVGUniverse univ, String text) throws SVGException {\r
- SVGDiagram diagram = univ.getDiagram(univ.loadSVG(new StringReader(text), UUID.randomUUID().toString()), false);\r
- diagram.setIgnoringClipHeuristic(true);\r
- return diagram;\r
- }\r
-\r
- public static java.awt.image.BufferedImage loadSVG(SVGUniverse univ, String text, double scale) throws SVGException {\r
- SVGDiagram diagram = loadSVGDiagram(univ, text);\r
- return paintSVG(diagram, scale);\r
- }\r
-\r
- public static java.awt.image.BufferedImage paintSVG(SVGDiagram diagram, double scale) throws SVGException {\r
- BufferedImage bi = new BufferedImage(diagram);\r
- bi.paintToBuffer(AffineTransform.getScaleInstance(scale, scale), 0);\r
- return bi.getBuffer();\r
- }\r
-\r
- public static java.awt.image.BufferedImage paintSVG(SVGDiagram diagram, AffineTransform transform, float margin) throws SVGException {\r
- BufferedImage bi = new BufferedImage(diagram);\r
- bi.paintToBuffer(transform, margin);\r
- return bi.getBuffer();\r
- }\r
-\r
- /*\r
- * NOTE! This is not re-entrant\r
- */\r
- public static synchronized java.awt.image.BufferedImage loadSVG(SVGUniverse univ, String text, int maxDimension) throws SVGException {\r
- SVGDiagram diagram = univ.getDiagram(univ.loadSVG(new StringReader(text), UUID.randomUUID().toString()), false);\r
- diagram.setIgnoringClipHeuristic(true);\r
- BufferedImage bi = new BufferedImage(diagram);\r
- Rectangle2D bounds = diagram.getViewRect();\r
- double xScale = (double)maxDimension / bounds.getWidth();\r
- double yScale = (double)maxDimension / bounds.getHeight();\r
- double scale = Math.min(xScale, yScale);\r
- bi.paintToBuffer(AffineTransform.getScaleInstance(scale, scale), 0);\r
- return bi.getBuffer();\r
- }\r
- \r
- private static Variant extractVariant(Object value) {\r
- if(value instanceof Variant) return (Variant)value;\r
- else return Variant.ofInstance(value);\r
- }\r
- \r
- public static Map<String, Variant> parameters(Object ... keyValuePairs) {\r
- assert keyValuePairs.length % 2 == 0;\r
- HashMap<String, Variant> result = new HashMap<String, Variant>();\r
- for(int i=0;i<keyValuePairs.length;i+=2) {\r
- String key = (String)keyValuePairs[i];\r
- Variant value = extractVariant(keyValuePairs[i+1]);\r
- result.put(key, value);\r
- }\r
- return result;\r
- }\r
- \r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012 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.scenegraph;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.io.StringReader;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.binding.error.BindingException;
+import org.simantics.databoard.binding.mutable.Variant;
+import org.simantics.scenegraph.utils.BufferedImage;
+import org.simantics.scl.runtime.function.Function1;
+import org.simantics.scl.runtime.function.FunctionImpl1;
+import org.simantics.utils.threads.IThreadWorkQueue;
+import org.simantics.utils.threads.ThreadUtils;
+
+import com.kitfox.svg.SVGDiagram;
+import com.kitfox.svg.SVGException;
+import com.kitfox.svg.SVGUniverse;
+
+public class ScenegraphUtils {
+
+ final static protected void dispatch(IThreadWorkQueue queue, final Runnable runnable) {
+ if(queue == null) runnable.run();
+ else if(queue.currentThreadAccess()) runnable.run();
+ else {
+ ThreadUtils.asyncExec(queue, new Runnable() {
+ @Override
+ public void run() {
+ runnable.run();
+ }
+ });
+ }
+ }
+
+ private static Class<?> getPropertyType(Method method) {
+ return (Class<?>)method.getGenericParameterTypes()[0];
+ }
+
+ private static Binding getPropertyBinding(Method method) {
+ try {
+ return Bindings.getBindingUnchecked(getPropertyType(method));
+ } catch (Throwable t) {
+ return null;
+ }
+ }
+
+ private static Binding getGenericPropertyBinding(Method method) {
+ try {
+ Binding specific = getPropertyBinding(method);
+ return Bindings.getBinding(specific.type());
+ } catch (Throwable t) {
+ return null;
+ }
+ }
+
+ private static Method getSynchronizeMethod(Object node, String propertyName) {
+ try {
+ String methodName = "synchronize" + propertyName.substring(0,1).toUpperCase() + propertyName.substring(1);
+ for(Method method : node.getClass().getMethods()) {
+ if(method.getName().equals(methodName)) return method;
+ }
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static Function1<Object, Boolean> getMethodPropertyFunction(final IThreadWorkQueue queue, final Object node, final String propertyName) {
+
+ final Method synchronizeMethod = getSynchronizeMethod(node, propertyName);
+ if(synchronizeMethod == null) throw new NodeException("Did not find synchronize method for property '" + propertyName + "'");
+ final Class<?> type = getPropertyType(synchronizeMethod);
+ final Binding binding = getPropertyBinding(synchronizeMethod);
+ final Binding genericBinding = getGenericPropertyBinding(synchronizeMethod);
+
+ return new FunctionImpl1<Object, Boolean>() {
+
+ @Override
+ public Boolean apply(final Object value) {
+
+ dispatch(queue, new Runnable() {
+
+ @Override
+ public void run() {
+
+ try {
+ if(type.isPrimitive()) {
+ synchronizeMethod.invoke(node, value);
+ } else if (value == null) {
+ synchronizeMethod.invoke(node, value);
+ } else if(type.isInstance(value)) {
+ synchronizeMethod.invoke(node, value);
+ } else if (type.isArray()) {
+ synchronizeMethod.invoke(node, value);
+ } else {
+ Object instance = binding.createDefaultUnchecked();
+ binding.readFrom(genericBinding, value, instance);
+ synchronizeMethod.invoke(node, instance);
+ }
+ } catch (IllegalArgumentException e1) {
+ e1.printStackTrace();
+ } catch (IllegalAccessException e1) {
+ e1.printStackTrace();
+ } catch (BindingException e) {
+ e.printStackTrace();
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ });
+ return false;
+ }
+
+ };
+
+ }
+
+ public static SVGDiagram loadSVGDiagram(SVGUniverse univ, String text) throws SVGException {
+ SVGDiagram diagram = univ.getDiagram(univ.loadSVG(new StringReader(text), UUID.randomUUID().toString()), false);
+ diagram.setIgnoringClipHeuristic(true);
+ return diagram;
+ }
+
+ public static java.awt.image.BufferedImage loadSVG(SVGUniverse univ, String text, double scale) throws SVGException {
+ SVGDiagram diagram = loadSVGDiagram(univ, text);
+ return paintSVG(diagram, scale);
+ }
+
+ public static java.awt.image.BufferedImage paintSVG(SVGDiagram diagram, double scale) throws SVGException {
+ BufferedImage bi = new BufferedImage(diagram);
+ bi.paintToBuffer(AffineTransform.getScaleInstance(scale, scale), 0);
+ return bi.getBuffer();
+ }
+
+ public static java.awt.image.BufferedImage paintSVG(SVGDiagram diagram, AffineTransform transform, float margin) throws SVGException {
+ BufferedImage bi = new BufferedImage(diagram);
+ bi.paintToBuffer(transform, margin);
+ return bi.getBuffer();
+ }
+
+ /*
+ * NOTE! This is not re-entrant
+ */
+ public static synchronized java.awt.image.BufferedImage loadSVG(SVGUniverse univ, String text, int maxDimension) throws SVGException {
+ SVGDiagram diagram = univ.getDiagram(univ.loadSVG(new StringReader(text), UUID.randomUUID().toString()), false);
+ diagram.setIgnoringClipHeuristic(true);
+ BufferedImage bi = new BufferedImage(diagram);
+ Rectangle2D bounds = diagram.getViewRect();
+ double xScale = (double)maxDimension / bounds.getWidth();
+ double yScale = (double)maxDimension / bounds.getHeight();
+ double scale = Math.min(xScale, yScale);
+ bi.paintToBuffer(AffineTransform.getScaleInstance(scale, scale), 0);
+ return bi.getBuffer();
+ }
+
+ private static Variant extractVariant(Object value) {
+ if(value instanceof Variant) return (Variant)value;
+ else return Variant.ofInstance(value);
+ }
+
+ public static Map<String, Variant> parameters(Object ... keyValuePairs) {
+ assert keyValuePairs.length % 2 == 0;
+ HashMap<String, Variant> result = new HashMap<String, Variant>();
+ for(int i=0;i<keyValuePairs.length;i+=2) {
+ String key = (String)keyValuePairs[i];
+ Variant value = extractVariant(keyValuePairs[i+1]);
+ result.put(key, value);
+ }
+ return result;
+ }
+
+}