X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scenegraph%2Fsrc%2Forg%2Fsimantics%2Fscenegraph%2FScenegraphUtils.java;fp=bundles%2Forg.simantics.scenegraph%2Fsrc%2Forg%2Fsimantics%2Fscenegraph%2FScenegraphUtils.java;h=9b02c0f4606e1b6578acb91e4c9075126de6a880;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/ScenegraphUtils.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/ScenegraphUtils.java new file mode 100644 index 000000000..9b02c0f46 --- /dev/null +++ b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/ScenegraphUtils.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * 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 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() { + + @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 parameters(Object ... keyValuePairs) { + assert keyValuePairs.length % 2 == 0; + HashMap result = new HashMap(); + for(int i=0;i