X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=bundles%2Forg.simantics.views.swt.client%2Fsrc%2Forg%2Fsimantics%2Fviews%2Fswt%2Fclient%2Fbase%2FSingleSWTViewNode.java;h=69594b5dd0c99be05f1fa9d21077ee9e5c7c09a2;hb=refs%2Fchanges%2F38%2F238%2F2;hp=55ac799d3ba9509630e54c64c9c36f7ec4d1ef2f;hpb=24e2b34260f219f0d1644ca7a138894980e25b14;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/base/SingleSWTViewNode.java b/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/base/SingleSWTViewNode.java index 55ac799d3..69594b5dd 100644 --- a/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/base/SingleSWTViewNode.java +++ b/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/base/SingleSWTViewNode.java @@ -1,299 +1,299 @@ -package org.simantics.views.swt.client.base; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.jface.resource.ColorDescriptor; -import org.eclipse.jface.resource.FontDescriptor; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.swt.widgets.Control; -import org.simantics.databoard.Bindings; -import org.simantics.databoard.binding.ArrayBinding; -import org.simantics.databoard.binding.Binding; -import org.simantics.databoard.binding.error.BindingConstructionException; -import org.simantics.databoard.binding.error.BindingException; -import org.simantics.databoard.binding.reflection.BindingRequest; -import org.simantics.datatypes.literal.Font; -import org.simantics.datatypes.literal.RGB; -import org.simantics.scenegraph.LoaderNode; -import org.simantics.scenegraph.loader.ScenegraphLoaderUtils; -import org.simantics.scl.runtime.function.Function1; -import org.simantics.scl.runtime.function.Function2; -import org.simantics.scl.runtime.function.FunctionImpl1; -import org.simantics.ui.colors.Colors; -import org.simantics.ui.fonts.Fonts; -import org.simantics.utils.threads.IThreadWorkQueue; -import org.simantics.utils.threads.SWTThread; -import org.simantics.views.ViewUtils.LayoutDataBean; - -abstract public class SingleSWTViewNode extends SWTParentNode implements LoaderNode { - - private static final long serialVersionUID = -5810308021930769003L; - - private Map genericProperties = new HashMap(); - - public Function2 propertyCallback; - public LayoutDataBean layoutData; - public int style; - public String text; - public RGB.Integer background; - public RGB.Integer foreground; - public Font font; - protected transient ColorDescriptor backgroundDesc; - protected transient ColorDescriptor foregroundDesc; - protected transient FontDescriptor fontDesc; - - protected T control; - - @Override - public Control getControl() { - return control; - } - - @Override - public void reset() { - control = null; - } - - final protected boolean isDisposed() { - Control c = getControl(); - return c == null ? false : c.isDisposed(); - } - - final protected void dispatch(final Runnable runnable) { - if(isNodeDisposed()) return; - IThreadWorkQueue thread = SWTThread.getThreadAccess(); - if(thread.currentThreadAccess()) runnable.run(); - else thread.asyncExec(new Runnable() { - - @Override - public void run() { - if(isDisposed()) return; - Control c = control; - if(c == null || c.isDisposed()) return; - runnable.run(); - } - - }); - } - - private Field getPropertyField(String propertyName) { - assert(!isNodeDisposed()); - return ScenegraphLoaderUtils.getPropertyField(this, propertyName); - } - - private Class getPropertyType(Field field) { - return field.getType(); - } - - private Binding getPropertyBinding(Field field) { - try { - Binding b = Bindings.getBinding( BindingRequest.create( field ) ); - - // Safety checks for unusable bindings. - if (b instanceof ArrayBinding && ((ArrayBinding) b).type().componentType() == null) - return null; - - return b; - } catch (BindingConstructionException e) { - return null; - } catch (Throwable t) { - return null; - } - } - - /** - * Convert binding to generic binding - * @param binding - * @return - */ - private Binding getGenericPropertyBinding(Binding binding) { - if (binding == null) return null; - return Bindings.getBinding(binding.type()); - } - - @Override - public Function1 getPropertyFunction(final String propertyName) { - - if(isNodeDisposed()) return null; - -// assert(!isNodeDisposed()); - - final Field field = getPropertyField(propertyName); - if(field != null) { - - return new FunctionImpl1() { - - final Method method = ScenegraphLoaderUtils.getSynchronizeMethod(SingleSWTViewNode.this, propertyName); - final Class type = getPropertyType(field); - final Binding binding = getPropertyBinding(field); - final Binding genericBinding = getGenericPropertyBinding(binding); - - private Object setField(Object value) { - - try { - if(type.isPrimitive() || (value == null) || type.isInstance(value) || type.isArray()) { - field.set(SingleSWTViewNode.this, value); - return value; - } else { - Object instance = binding.createDefaultUnchecked(); - binding.readFrom(genericBinding, value, instance); - field.set(SingleSWTViewNode.this, instance); - return instance; - } - } catch (IllegalArgumentException e1) { - e1.printStackTrace(); - } catch (IllegalAccessException e1) { - e1.printStackTrace(); - } catch (BindingException e) { - e.printStackTrace(); - } catch (Throwable t) { - t.printStackTrace(); - } - - return null; - - } - - @Override - public Boolean apply(Object value) { - - if(isNodeDisposed()) return true; - - final Object translated = setField(value); - - if(method != null) { - dispatch(new Runnable() { - - @Override - public void run() { - - try { - method.invoke(SingleSWTViewNode.this, translated); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.getCause().printStackTrace(); - } - } - - }); - } - return isDisposed(); - } - - }; - - } else { - - return new FunctionImpl1() { - - @Override - public Boolean apply(Object p0) { - assert(!isNodeDisposed()); - genericProperties.put(propertyName, p0); - return isDisposed(); - } - - }; - - } - - } - - @Override - public void setPropertyCallback(Function2 callback) { - this.propertyCallback = callback; - } - - @SuppressWarnings("unchecked") - @Override - public T2 getProperty(String propertyName) { - - Method m = ScenegraphLoaderUtils.getReadMethod(this, propertyName); - if(m != null) { - - try { - return (T2)m.invoke(this); - } catch (IllegalArgumentException e) { - throw new RuntimeException("Failed to get property '" + propertyName + "' for " + getClass().getName(), e); - } catch (IllegalAccessException e) { - throw new RuntimeException("Failed to get property '" + propertyName + "' for " + getClass().getName(), e); - } catch (InvocationTargetException e) { - throw new RuntimeException("Failed to get property '" + propertyName + "' for " + getClass().getName(), e.getCause()); - } - - } else { - return (T2)genericProperties.get(propertyName); - } - - } - - protected void setProperties() { - for(Method m : getClass().getMethods()) { - if(m.getName().startsWith("synchronize")) { - String upperFieldName = m.getName().substring("synchronize".length()); - String fieldName = upperFieldName.substring(0,1).toLowerCase() + upperFieldName.substring(1); - Field f = ScenegraphLoaderUtils.getPropertyField(this, fieldName); - try { - m.invoke(this, f.get(this)); - } catch (IllegalArgumentException e) { - throw new RuntimeException("Failed to set property '" + fieldName + "' for " + getClass().getName(), e); - } catch (IllegalAccessException e) { - throw new RuntimeException("Failed to set property '" + fieldName + "' for " + getClass().getName(), e); - } catch (InvocationTargetException e) { - throw new RuntimeException("Failed to set property '" + fieldName + "' for " + getClass().getName(), e.getCause()); - } - } - } - } - - public void synchronizeText(String text) { - } - - final public void synchronizeFont(Font font) { - if (font == null && fontDesc == null) - return; - ResourceManager rm = getResourceManager(); - FontDescriptor oldDesc = fontDesc; - if (font != null) - control.setFont( getResourceManager().createFont( fontDesc = Fonts.swt(font) ) ); - if (oldDesc != null) - rm.destroy(oldDesc); - } - - final public void synchronizeForeground(RGB.Integer foreground) { - if (foreground == null && foregroundDesc == null) - return; - ResourceManager rm = getResourceManager(); - ColorDescriptor oldDesc = foregroundDesc; - if (foreground != null) - control.setForeground( getResourceManager().createColor( foregroundDesc = Colors.swt(foreground) ) ); - if (oldDesc != null) - rm.destroy(oldDesc); - } - - final public void synchronizeBackground(RGB.Integer background) { - if (background == null && backgroundDesc == null) - return; - ResourceManager rm = getResourceManager(); - ColorDescriptor oldDesc = backgroundDesc; - if (background != null) - control.setBackground( getResourceManager().createColor( backgroundDesc = Colors.swt(background) ) ); - if (oldDesc != null) - rm.destroy(oldDesc); - } - - final public void synchronizeStyle(int style) { - } - - final public void synchronizeLayoutData(LayoutDataBean layoutData) { - if(layoutData != null) control.setLayoutData(SWTViewUtils.toLayoutData(layoutData)); - } - -} +package org.simantics.views.swt.client.base; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jface.resource.ColorDescriptor; +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.swt.widgets.Control; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.binding.ArrayBinding; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.error.BindingConstructionException; +import org.simantics.databoard.binding.error.BindingException; +import org.simantics.databoard.binding.reflection.BindingRequest; +import org.simantics.datatypes.literal.Font; +import org.simantics.datatypes.literal.RGB; +import org.simantics.scenegraph.LoaderNode; +import org.simantics.scenegraph.loader.ScenegraphLoaderUtils; +import org.simantics.scl.runtime.function.Function1; +import org.simantics.scl.runtime.function.Function2; +import org.simantics.scl.runtime.function.FunctionImpl1; +import org.simantics.ui.colors.Colors; +import org.simantics.ui.fonts.Fonts; +import org.simantics.utils.threads.IThreadWorkQueue; +import org.simantics.utils.threads.SWTThread; +import org.simantics.views.ViewUtils.LayoutDataBean; + +abstract public class SingleSWTViewNode extends SWTParentNode implements LoaderNode { + + private static final long serialVersionUID = -5810308021930769003L; + + private Map genericProperties = new HashMap(); + + public Function2 propertyCallback; + public LayoutDataBean layoutData; + public int style; + public String text; + public RGB.Integer background; + public RGB.Integer foreground; + public Font font; + protected transient ColorDescriptor backgroundDesc; + protected transient ColorDescriptor foregroundDesc; + protected transient FontDescriptor fontDesc; + + protected T control; + + @Override + public Control getControl() { + return control; + } + + @Override + public void reset() { + control = null; + } + + final protected boolean isDisposed() { + Control c = getControl(); + return c == null ? false : c.isDisposed(); + } + + final protected void dispatch(final Runnable runnable) { + if(isNodeDisposed()) return; + IThreadWorkQueue thread = SWTThread.getThreadAccess(); + if(thread.currentThreadAccess()) runnable.run(); + else thread.asyncExec(new Runnable() { + + @Override + public void run() { + if(isDisposed()) return; + Control c = control; + if(c == null || c.isDisposed()) return; + runnable.run(); + } + + }); + } + + private Field getPropertyField(String propertyName) { + assert(!isNodeDisposed()); + return ScenegraphLoaderUtils.getPropertyField(this, propertyName); + } + + private Class getPropertyType(Field field) { + return field.getType(); + } + + private Binding getPropertyBinding(Field field) { + try { + Binding b = Bindings.getBinding( BindingRequest.create( field ) ); + + // Safety checks for unusable bindings. + if (b instanceof ArrayBinding && ((ArrayBinding) b).type().componentType() == null) + return null; + + return b; + } catch (BindingConstructionException e) { + return null; + } catch (Throwable t) { + return null; + } + } + + /** + * Convert binding to generic binding + * @param binding + * @return + */ + private Binding getGenericPropertyBinding(Binding binding) { + if (binding == null) return null; + return Bindings.getBinding(binding.type()); + } + + @Override + public Function1 getPropertyFunction(final String propertyName) { + + if(isNodeDisposed()) return null; + +// assert(!isNodeDisposed()); + + final Field field = getPropertyField(propertyName); + if(field != null) { + + return new FunctionImpl1() { + + final Method method = ScenegraphLoaderUtils.getSynchronizeMethod(SingleSWTViewNode.this, propertyName); + final Class type = getPropertyType(field); + final Binding binding = getPropertyBinding(field); + final Binding genericBinding = getGenericPropertyBinding(binding); + + private Object setField(Object value) { + + try { + if(type.isPrimitive() || (value == null) || type.isInstance(value) || type.isArray()) { + field.set(SingleSWTViewNode.this, value); + return value; + } else { + Object instance = binding.createDefaultUnchecked(); + binding.readFrom(genericBinding, value, instance); + field.set(SingleSWTViewNode.this, instance); + return instance; + } + } catch (IllegalArgumentException e1) { + e1.printStackTrace(); + } catch (IllegalAccessException e1) { + e1.printStackTrace(); + } catch (BindingException e) { + e.printStackTrace(); + } catch (Throwable t) { + t.printStackTrace(); + } + + return null; + + } + + @Override + public Boolean apply(Object value) { + + if(isNodeDisposed()) return true; + + final Object translated = setField(value); + + if(method != null) { + dispatch(new Runnable() { + + @Override + public void run() { + + try { + method.invoke(SingleSWTViewNode.this, translated); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.getCause().printStackTrace(); + } + } + + }); + } + return isDisposed(); + } + + }; + + } else { + + return new FunctionImpl1() { + + @Override + public Boolean apply(Object p0) { + assert(!isNodeDisposed()); + genericProperties.put(propertyName, p0); + return isDisposed(); + } + + }; + + } + + } + + @Override + public void setPropertyCallback(Function2 callback) { + this.propertyCallback = callback; + } + + @SuppressWarnings("unchecked") + @Override + public T2 getProperty(String propertyName) { + + Method m = ScenegraphLoaderUtils.getReadMethod(this, propertyName); + if(m != null) { + + try { + return (T2)m.invoke(this); + } catch (IllegalArgumentException e) { + throw new RuntimeException("Failed to get property '" + propertyName + "' for " + getClass().getName(), e); + } catch (IllegalAccessException e) { + throw new RuntimeException("Failed to get property '" + propertyName + "' for " + getClass().getName(), e); + } catch (InvocationTargetException e) { + throw new RuntimeException("Failed to get property '" + propertyName + "' for " + getClass().getName(), e.getCause()); + } + + } else { + return (T2)genericProperties.get(propertyName); + } + + } + + protected void setProperties() { + for(Method m : getClass().getMethods()) { + if(m.getName().startsWith("synchronize")) { + String upperFieldName = m.getName().substring("synchronize".length()); + String fieldName = upperFieldName.substring(0,1).toLowerCase() + upperFieldName.substring(1); + Field f = ScenegraphLoaderUtils.getPropertyField(this, fieldName); + try { + m.invoke(this, f.get(this)); + } catch (IllegalArgumentException e) { + throw new RuntimeException("Failed to set property '" + fieldName + "' for " + getClass().getName(), e); + } catch (IllegalAccessException e) { + throw new RuntimeException("Failed to set property '" + fieldName + "' for " + getClass().getName(), e); + } catch (InvocationTargetException e) { + throw new RuntimeException("Failed to set property '" + fieldName + "' for " + getClass().getName(), e.getCause()); + } + } + } + } + + public void synchronizeText(String text) { + } + + final public void synchronizeFont(Font font) { + if (font == null && fontDesc == null) + return; + ResourceManager rm = getResourceManager(); + FontDescriptor oldDesc = fontDesc; + if (font != null) + control.setFont( getResourceManager().createFont( fontDesc = Fonts.swt(font) ) ); + if (oldDesc != null) + rm.destroy(oldDesc); + } + + final public void synchronizeForeground(RGB.Integer foreground) { + if (foreground == null && foregroundDesc == null) + return; + ResourceManager rm = getResourceManager(); + ColorDescriptor oldDesc = foregroundDesc; + if (foreground != null) + control.setForeground( getResourceManager().createColor( foregroundDesc = Colors.swt(foreground) ) ); + if (oldDesc != null) + rm.destroy(oldDesc); + } + + final public void synchronizeBackground(RGB.Integer background) { + if (background == null && backgroundDesc == null) + return; + ResourceManager rm = getResourceManager(); + ColorDescriptor oldDesc = backgroundDesc; + if (background != null) + control.setBackground( getResourceManager().createColor( backgroundDesc = Colors.swt(background) ) ); + if (oldDesc != null) + rm.destroy(oldDesc); + } + + final public void synchronizeStyle(int style) { + } + + final public void synchronizeLayoutData(LayoutDataBean layoutData) { + if(layoutData != null) control.setLayoutData(SWTViewUtils.toLayoutData(layoutData)); + } + +}