blob: 2fe609f5cfea0abacb9bb2a5562a3caabf802219 [file] [log] [blame]
package org.eclipse.swt.animation;
import java.lang.reflect.*;
import org.eclipse.swt.*;
import org.eclipse.swt.effects.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.wpf.*;
import org.eclipse.swt.widgets.*;
public class PropertyAnimation extends Animation {
Object from, to;
long duration;
String name, property;
Object target;
Method method;
Class paramType;
int animatorHandle, customAnimation;
Object nextValue;
IInterpolator interpolator;
void create() {
if (target == null || property == null) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
if (handle == 0) {
super.create();
setParamType();
createAnimation();
register(widget);
}
updateFromToValues();
}
void createCustomAnimation() {
customAnimation = OS.gcnew_SWTAnimation(jniRef);
int children = OS.TimelineGroup_Children(handle);
OS.IList_Add(children, customAnimation);
OS.GCHandle_Free(children);
setTargetProperty (customAnimation, property);
}
void createDoubleAnimation() {
}
void createIntegerAnimation() {
}
void createRectangleAnimation() {
}
void createPointAnimation() {
}
void OnPropertyChanged(int object, int args) {
try {
if (nextValue != null) {
method.invoke(target, new Object[] {nextValue});
return;
}
if (paramType == Double.TYPE
|| paramType == Color.class
|| paramType == Transform.class) {
double newValue = OS.DependencyPropertyChangedEventArgs_NewValueDouble(args);
Object methodArg;
if (paramType == Transform.class) {
Transform transform = getTransform(newValue);
methodArg = transform;
} else if (paramType == Color.class) {
Color color = getColor(newValue);
methodArg = color;
} else {
methodArg = new Double(newValue);
}
method.invoke(target, new Object[] {methodArg});
if (paramType == Transform.class) {
((Transform)methodArg).dispose();
}
return;
}
if (paramType == Integer.TYPE) {
int newValue = OS.DependencyPropertyChangedEventArgs_NewValueInt(args);
method.invoke(target, new Object[] {new Integer(newValue)});
return;
}
throw new RuntimeException(paramType + " not supported yet");
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
Color getColor(double newValue) {
if (!(from instanceof Color && to instanceof Color)) return null;
Color colorFrom = (Color)from;
Color colorTo = (Color)to;
RGB start = colorFrom.getRGB();
RGB end = colorTo.getRGB();
int red = (int) (((end.red-start.red)*newValue) + start.red);
int green = (int) (((end.green-start.green)*newValue) + start.green);
int blue = (int) (((end.blue-start.blue)*newValue) + start.blue);
RGB current = new RGB(red, green, blue);
return new Color(colorFrom.getDevice(), current);
}
void GetCurrentValueCore(double currentTime) {
if (interpolator != null) {
try {
nextValue = interpolator.getCurrentValue(from, to, (long)currentTime, duration);
return;
} catch (RuntimeException e) {
e.printStackTrace();
}
}
nextValue = null;
}
public long getDuration() {
return duration;
}
Transform getTransform(double newValue) {
if (!(from instanceof Transform && to instanceof Transform)) return null;
float[] transformFrom = new float[6];
float[] transformTo = new float[6];
((Transform)from).getElements(transformFrom);
((Transform)to).getElements(transformTo);
Control control = (Control)target;
Transform transform = control.getTransform();
float[] f = new float[6];
for (int i = 0; i < 6; i++) {
f[i] = (float) (((transformTo[i]-transformFrom[i])*newValue) + transformFrom[i]);
}
transform.setElements(f[0], f[1], f[2], f[3], f[4], f[5]);
control.setTransform(transform);
return transform;
}
void register(Widget widget) {
if (name == null) {
int nameScope = OS.NameScope_GetNameScope(widget.handle);
count ++;
name = "SWTAnimRef" + count;
int str = createDotNetString(name);
int targetHandle = targetHandle();
OS.NameScope_RegisterName(nameScope, str, targetHandle);
OS.Storyboard_SetTargetName(handle, str);
OS.GCHandle_Free(str);
OS.GCHandle_Free(nameScope);
}
}
void release() {
super.release();
if (customAnimation != 0) OS.GCHandle_Free(customAnimation);
customAnimation = 0;
if (animatorHandle != 0) OS.GCHandle_Free(animatorHandle);
animatorHandle = 0;
}
public void setDuration(long duration) {
checkAnimation();
this.duration = duration;
}
public void setFrom(Object from) {
checkAnimation();
this.from = from;
}
// public void setInterpolator(IInterpolator interpolator) {
// checkAnimation();
// this.interpolator = interpolator;
// }
void setParamType() {
if ("alpha".equals(property) || "x".equals(property) || "y".equals(property) || "width".equals(property) || "height".equals(property)) {
paramType = Double.TYPE;
return;
}
String mName = "set" + property.substring(0, 1).toUpperCase() + property.substring(1);
Class clazz = target.getClass();
Method[] methods = clazz.getMethods();
for (int i = 0; i < methods.length; i++) {
Method m = methods[i];
if (m.getName().equals(mName)) {
Class[] parameterTypes = m.getParameterTypes();
if (parameterTypes.length == 1) {
method = m;
break;
}
}
}
// if (method == null) error?
paramType = method.getParameterTypes()[0];
}
public void setProperty(String property) {
checkAnimation();
this.property = property;
}
public void setTarget(Object target) {
checkAnimation();
this.target = target;
}
void setTargetProperty(int animation, String prop) {
int dp;
if (interpolator != null) {
dp = OS.SWTAnimator_DoubleValueProperty();
} else {
dp = Properties.getDependencyProperty(target, prop);
}
if (dp == 0) {
animatorHandle = OS.gcnew_SWTAnimator(jniRef);
if (paramType == null
|| paramType == Double.TYPE
|| paramType == Color.class
|| paramType == Transform.class) {
dp = OS.SWTAnimator_DoubleValueProperty();
} else if (paramType == Integer.TYPE) {
dp = OS.SWTAnimator_IntValueProperty();
} else {
throw new RuntimeException(paramType + " is not supported yet.");
}
}
int propertyPath = OS.gcnew_PropertyPath(dp);
OS.Storyboard_SetTargetProperty(animation, propertyPath);
OS.GCHandle_Free(propertyPath);
OS.GCHandle_Free(dp);
}
void createAnimation() {
if (interpolator != null) {
createCustomAnimation();
return;
}
if (paramType == Double.TYPE
|| paramType == Color.class
|| paramType == Transform.class) {
createDoubleAnimation();
return;
}
if (paramType == Integer.TYPE) {
createIntegerAnimation();
return;
}
if (paramType == Rectangle.class) {
createRectangleAnimation();
return;
}
if (paramType == Point.class) {
createPointAnimation();
return;
}
throw new RuntimeException(paramType + " is not supported yet.");
}
public void setTo(Object to) {
checkAnimation();
this.to = to;
}
int targetHandle() {
if (animatorHandle != 0) return animatorHandle;
if (target instanceof Widget) {
return ((Widget)target).handle;
}
if (target instanceof Effect) {
return ((Effect)target).handle;
}
return 0;
}
long updateDuration(long delay) {
if (interpolator == null) return delay;
int timeSpan = OS.TimeSpan_FromMilliseconds(duration);
int dur = OS.gcnew_Duration(timeSpan);
OS.Timeline_Duration(customAnimation, dur);
OS.GCHandle_Free(dur);
OS.GCHandle_Free(timeSpan);
//set begin time
timeSpan = OS.TimeSpan_FromMilliseconds(delay + beginTime);
OS.Timeline_BeginTime(customAnimation, timeSpan);
OS.GCHandle_Free(timeSpan);
return delay+beginTime+duration;
}
void updateFromToValues() {
OS.DoubleAnimation_From(customAnimation, 0);
OS.DoubleAnimation_To(customAnimation, 1);
}
}