/******************************************************************************* * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) and others. * 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: * Soyatec - initial API and implementation *******************************************************************************/ package org.eclipse.papyrus.xwt.internal.core; import java.lang.reflect.Method; import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.papyrus.xwt.IDataProvider; import org.eclipse.papyrus.xwt.IXWTLoader; import org.eclipse.papyrus.xwt.XWT; import org.eclipse.papyrus.xwt.XWTException; import org.eclipse.papyrus.xwt.annotation.UIBounds; import org.eclipse.papyrus.xwt.core.IDynamicBinding; import org.eclipse.papyrus.xwt.core.IUserDataConstants; import org.eclipse.papyrus.xwt.databinding.BindingMode; import org.eclipse.papyrus.xwt.databinding.IBindingContext; import org.eclipse.papyrus.xwt.internal.utils.UserData; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Item; import org.eclipse.swt.widgets.Widget; /** * Generic Binding definition * * @author yyang (yves.yang@soyatec.com) */ public abstract class DynamicBinding implements IDynamicBinding { private Object control; private Object host; private BindingMode mode = BindingMode.TwoWay; private IXWTLoader xwtLoader; /** * The name of the {@link DataBindingContext} that we will look up in static * resources */ private IBindingContext bindingContext; /** * which used to decide binding type, not only text. */ private String type; /* * (non-Javadoc) * * @see org.eclipse.papyrus.xwt.core.IDynamicBinding#getContextName() */ public IBindingContext getBindingContext() { if(this.bindingContext == null) { Object element = (control == null ? host : control); this.bindingContext = XWT.getBindingContext(element); } return this.bindingContext; } public Object getHost() { return host; } public void setHost(Object host) { this.host = host; } /* * (non-Javadoc) * * @see * org.eclipse.papyrus.xwt.core.IDynamicBinding#setBindingContext(IBindingContext * ) */ public void setBindingContext(IBindingContext bindingContext) { this.bindingContext = bindingContext; } public void setControl(Object control) { this.control = control; } public Object getControl() { return this.control; } /** * @param type * the type to set */ public void setType(String type) { this.type = type; } /** * @return the type */ public String getType() { return type; } public BindingMode getMode() { return mode; } public void setMode(BindingMode mode) { this.mode = mode; } public void setXWTLoader(IXWTLoader xwtLoader) { this.xwtLoader = xwtLoader; } protected Object getDataContextHost() { Object control = getControl(); if(control == null) { return null; } Object data = UserData.getLocalDataContext(control); if(data == null || data == this) { if(data == null && UserData.hasLocalData(control, IUserDataConstants.XWT_DATACONTEXT_KEY)) { return control; } Widget parent = UserData.getParent(control); if(parent != null) { return UserData.getDataContextHost(parent); } return null; } return control; } protected Object getDataContext() { if(control != null) { return UserData.getDataContext(control); } return null; } protected IDataProvider getDataProvider(Object dataContext) { if(dataContext != null) { if(dataContext instanceof IDataProvider) { return (IDataProvider)dataContext; } else { return xwtLoader.findDataProvider(dataContext); } } return null; } public IDataProvider getDataProvider() { return getDataProvider(getDataContext()); } protected Rectangle getControlBounds() { Widget widget = (Widget)getControl(); if(widget instanceof Control) { Control control = (Control)widget; return control.getBounds(); } Method drawMethod = findBoundsMethod(widget.getClass()); if(drawMethod != null) { try { drawMethod.setAccessible(true); return (Rectangle)drawMethod.invoke(widget); } catch (Exception e) { throw new XWTException(e); } } Control control = findHostControl(); return control.getBounds(); } protected Control findHostControl() { Widget widget = (Widget)getControl(); Control host; if(widget instanceof Item) { Item item = (Item)widget; host = (Control)XWT.findParent(item, Control.class); } else if(widget instanceof Control) { host = (Control)widget; } else { throw new XWTException(); } return host; } private Method findBoundsMethod(Class<?> type) { for(Method method : type.getDeclaredMethods()) { if(method.getAnnotation(UIBounds.class) != null && method.getTypeParameters().length == 0 && method.getReturnType() == Rectangle.class) { return method; } } Class<?> supertype = type.getSuperclass(); if(supertype != null && supertype != Widget.class) { Method method = findBoundsMethod(supertype); if(method != null) { return method; } } for(Class<?> anInterface : type.getInterfaces()) { Method method = findBoundsMethod(anInterface); if(method != null) { return method; } } try { Method method = type.getDeclaredMethod("getBounds"); if(method.getReturnType() == Rectangle.class) { return method; } } catch (Exception e) { } return null; } }