/******************************************************************************* * Copyright (c) 2008 Hallvard Traetteberg. * 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: * Hallvard Traetteberg - initial API and implementation ******************************************************************************/ package org.eclipse.e4.tm.builder.swt; import java.util.Iterator; import java.util.StringTokenizer; import org.eclipse.e4.tm.builder.IBinderContext; import org.eclipse.e4.tm.styles.Style; import org.eclipse.e4.tm.styles.StyleItem; import org.eclipse.e4.tm.styles.StyleSelector; import org.eclipse.e4.tm.styles.Styled; import org.eclipse.e4.tm.widgets.AbstractComposite; import org.eclipse.e4.tm.widgets.Composite; import org.eclipse.e4.tm.widgets.Control; import org.eclipse.e4.tm.widgets.WidgetsPackage; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Widget; public class ControlBinder extends SwtBinder implements Listener { public <T> T adapt(Object value, Class<T> c) { if (value instanceof Widget) { Widget widget = (Widget)value; for (Class<?> sc = c; sc != null && sc != Object.class; sc = sc.getSuperclass()) { Object o = widget.getData(sc.getName()); if (c.isInstance(o)) { return (T)o; } } } return super.adapt(value, c); } private final static String VIEWER_CONTROL_DATA_KEY = "viewer"; public void dispose(EObject eObject, Object object, IBinderContext context) { if (object instanceof org.eclipse.swt.widgets.Control) { org.eclipse.swt.widgets.Control swtControl = (org.eclipse.swt.widgets.Control)object; swtControl.dispose(); } super.dispose(eObject, object, context); } private final static Class<?>[] constructorParameterTypes = new Class[]{org.eclipse.swt.widgets.Composite.class, int.class}; protected int getSwtStyle(String styleString) { int style = SWT.NONE; StringTokenizer styles = SwtBuilder.getSeparatedTokens(styleString); while (styles.hasMoreTokens()) { style |= SwtBuilder.getStaticField(SWT.class, styles.nextToken(), Integer.class, SWT.NONE); } return style; } protected int getSwtStyle(EObject control) { String styleString = getClassAnnotation(control); return getSwtStyle(styleString); } // protected boolean shouldntHandleFeature(EStructuralFeature feature) { // if (feature == StylesPackage.eINSTANCE.getStyled_Style()) { // return true; // } // return super.shouldntHandleFeature(feature); // } protected void update(EObject control, EStructuralFeature feature, Object object, boolean isInit) { super.update(control, feature, object, isInit); if (control instanceof AbstractComposite && feature == WidgetsPackage.eINSTANCE.getAbstractComposite_Controls()) { org.eclipse.swt.widgets.Composite swtComposite = context.getObject(control, org.eclipse.swt.widgets.Composite.class); if (swtComposite != null) { swtComposite.layout(); } } if (isInit) { updateStyle(control, object, context); } } protected void invalidateFeature(EObject eObject, EStructuralFeature feature, Object object, boolean isEvent) { if (eObject instanceof AbstractComposite && feature == WidgetsPackage.eINSTANCE.getAbstractComposite_Controls()) { AbstractComposite<? extends Control> composite = (AbstractComposite<? extends Control>)eObject; org.eclipse.swt.widgets.Composite swtComposite = context.getObject(composite, org.eclipse.swt.widgets.Composite.class); if (swtComposite != null) { org.eclipse.swt.widgets.Control[] swtControls = swtComposite.getChildren(); for (int i = 0; i < swtControls.length; i++) { swtControls[i].dispose(); } } for (Iterator<? extends Control> it = composite.getControls().iterator(); it.hasNext();) { Control control = it.next(); context.dispose(control); } } super.invalidateFeature(eObject, feature, object, isEvent); } public final static String CONTROL_DATA_URI_KEY = "modelUri"; protected Object create(EObject control) { int style = getSwtStyle(control); Class<?> swtClass = getToolkitClass(control, true); org.eclipse.swt.widgets.Composite swtComposite = getParent(control, org.eclipse.swt.widgets.Composite.class); if (swtComposite != null && swtComposite.getLayout() == null) { setDefaultLayout(swtComposite); } Object swtObject = null; try { Object[] constructorArguments = new Object[]{swtComposite, style}; swtObject = swtClass.getConstructor(ControlBinder.constructorParameterTypes).newInstance(constructorArguments); if (swtObject instanceof org.eclipse.swt.widgets.Control) { org.eclipse.swt.widgets.Control swtControl = (org.eclipse.swt.widgets.Control)swtObject; swtControl.setData(CONTROL_DATA_URI_KEY, EcoreUtil.getURI(control)); } } catch (Exception e) { System.err.println("Exception when creating widget for " + this + ": " + e); } return swtObject; } protected void handleEventFeature(final EObject control, final EStructuralFeature feature, Object object) { if (! (object instanceof org.eclipse.swt.widgets.Control)) { return; } org.eclipse.swt.widgets.Control swtControl = (org.eclipse.swt.widgets.Control)object; String name = getRealName(feature); int eventType = SwtBuilder.getStaticField(SWT.class, name, Integer.class, SWT.NONE); swtControl.addListener(eventType, this); // new Listener() { // public void handleEvent(Event event) { // // System.out.println("Event: " + event); // control.eSet(feature, event); // } // }); } public void handleEvent(Event event) { EObject control = context.getEObject(event.widget); if (control == null) { return; } // find out which feature this event is for for (Iterator<EAttribute> it = control.eClass().getEAllAttributes().iterator(); it.hasNext();) { EStructuralFeature feature = it.next(); if ("event".equals(getAccessMethod(feature, control.eClass()))) { String name = getRealName(feature); if (event.type == SwtBuilder.getStaticField(SWT.class, name, Integer.class, SWT.NONE)) { control.eSet(feature, event); } } } } public boolean validateFeature(EObject eObject, Object object, String featureName, IBinderContext context) { if ("Style".equals(featureName) && eObject instanceof Styled) { updateStyle(eObject, object, context); return true; } return super.validateFeature(eObject, object, featureName, context); } public void updateStyle(EObject eObject, Object object, IBinderContext context) { if (eObject instanceof Styled && object instanceof org.eclipse.swt.widgets.Control) { updateStyle((Styled)eObject, ((org.eclipse.swt.widgets.Control)object), context); } } protected void updateStyle(Styled control, org.eclipse.swt.widgets.Control swtControl, IBinderContext context) { Style style = control.getStyle(); if (style != null) { for (StyleSelector styleSelector: style.getStyleSelectors()) { applyStyleSelector(style, styleSelector, swtControl); } } if (control instanceof Composite) { for (Control child : ((Composite)control).getControls()) { context.updateStyle(child); } } } private void applyStyleSelector(Style style, StyleSelector styleSelector, org.eclipse.swt.widgets.Control object) { String property = styleSelector.getProperty(); String selector = styleSelector.getSelector(); Object value = getStyleValue(style.eContainer(), selector); try { context.setProperty(object, property, value); } catch (Exception e) { } } private Object getStyleValue(EObject eObject, String selector) { while (eObject != null) { if (eObject instanceof Styled) { Style style = ((Styled)eObject).getStyle(); if (style != null) { Object value = getStyleValue(style, selector); if (value != null) { return value; } } } eObject = eObject.eContainer(); } return null; } private Object getStyleValue(Style style, String selector) { for (StyleItem styleItem: style.getStyleItems()) { if (selector.equals(styleItem.getName())) { Class c = getToolkitClass(styleItem, true); Object value = context.getObject(styleItem, c); if (value == null) { try { value = context.convert(styleItem.getSource(), c); context.putObject(styleItem, value); } catch (Exception e) { } } if (value != null) { return value; } } } return null; } }