blob: f83ab80840b21c0a7a68924034c5156349307d9a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.xwt.animation.internal;
import java.util.ArrayList;
import java.util.Collection;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.xwt.XWT;
import org.eclipse.xwt.XWTException;
import org.eclipse.xwt.animation.Duration;
import org.eclipse.xwt.animation.IEasingFunction;
import org.eclipse.xwt.animation.RepeatBehavior;
import org.eclipse.xwt.animation.TimeSpan;
import org.pushingpixels.trident.Timeline;
import org.pushingpixels.trident.TimelinePropertyBuilder;
import org.pushingpixels.trident.Timeline.TimelineState;
import org.pushingpixels.trident.TimelinePropertyBuilder.DefaultPropertySetter;
import org.pushingpixels.trident.TimelineScenario.TimelineScenarioActor;
import org.pushingpixels.trident.callback.TimelineCallback;
import org.pushingpixels.trident.swt.SWTRepaintCallback;
public class TridentTimeline implements ITimeline, TimelineScenarioActor {
protected Timeline tridentTimeline;
protected org.eclipse.xwt.animation.Timeline xwtTimeline;
protected Object target;
private boolean isPlayed = false;
private Collection<Runnable> stateChangedRunnables = new ArrayList<Runnable>();
public TridentTimeline(org.eclipse.xwt.animation.Timeline xwtTimeline,
Widget target) {
this.xwtTimeline = xwtTimeline;
this.target = target;
this.tridentTimeline = createTimeline(target);
tridentTimeline.addCallback(new TimelineCallback() {
public void onTimelineStateChanged(TimelineState oldState,
TimelineState newState, float durationFraction,
float timelinePosition) {
for (Runnable runnable : getStateChangedRunnables()) {
runnable.run();
}
}
public void onTimelinePulse(float durationFraction, float timelinePosition) {
}
});
}
public Collection<Runnable> getStateChangedRunnables() {
return stateChangedRunnables;
}
public void addStateChangedRunnable(Runnable stateChangedRunnable) {
if (!this.stateChangedRunnables.contains(stateChangedRunnable)) {
this.stateChangedRunnables.add(stateChangedRunnable);
}
}
public void removeStateChangedRunnable(Runnable stateChangedRunnable) {
this.stateChangedRunnables.remove(stateChangedRunnable);
}
public Object getTarget() {
return target;
}
public void play() {
if (this.isPlayed) {
this.tridentTimeline.replay();
} else {
Duration duration = this.xwtTimeline.getDuration();
if (duration != null && duration.hasTimeSpan()) {
this.tridentTimeline.setDuration(duration.getTimeSpan()
.getMilliseconds());
} else {
this.tridentTimeline.setDuration(10000);
}
RepeatBehavior behavior = xwtTimeline.getRepeatBehavior();
playLoop(behavior);
isPlayed = true;
}
}
protected void setInitialValue() {
}
protected Timeline createTimeline(Widget target) {
org.pushingpixels.trident.Timeline timeline = new org.pushingpixels.trident.Timeline(
target);
Control control = (target instanceof Control ? (Control) target
: (Control) XWT.findParent(target, Control.class));
timeline.addCallback(new SWTRepaintCallback(control));
Duration duration = this.xwtTimeline.getDuration();
if (duration != null && duration.hasTimeSpan()) {
timeline.setDuration(duration.getTimeSpan().getMilliseconds());
} else {
timeline.setDuration(10000);
}
return timeline;
}
public void playLoop(RepeatBehavior behavior) {
org.pushingpixels.trident.Timeline.RepeatBehavior loopBehavior = org.pushingpixels.trident.Timeline.RepeatBehavior.LOOP;
if (xwtTimeline.isAutoReverse()) {
loopBehavior = org.pushingpixels.trident.Timeline.RepeatBehavior.REVERSE;
}
if (behavior.getHasCount()) {
double loopCount = behavior.getCount();
if (!behavior.getHasDuration()) {
this.tridentTimeline.playLoop((int) loopCount, loopBehavior);
} else {
Duration duration = behavior.getDuration();
this.tridentTimeline.playLoopSkipping((int) loopCount,
loopBehavior, duration.getTimeSpan().getMilliseconds());
}
} else {
if (!behavior.getHasDuration()) {
this.tridentTimeline.playLoop(loopBehavior);
} else {
Duration duration = behavior.getDuration();
this.tridentTimeline.playLoopSkipping(loopBehavior, duration
.getTimeSpan().getMilliseconds());
}
}
}
public void end() {
if (this.tridentTimeline == null) {
return;
}
this.tridentTimeline.end();
}
public void cancel() {
if (this.tridentTimeline == null) {
return;
}
this.tridentTimeline.cancel();
}
public void abort() {
if (this.tridentTimeline == null) {
return;
}
this.tridentTimeline.abort();
}
public void pause() {
if (this.tridentTimeline == null) {
return;
}
this.tridentTimeline.suspend();
}
public void resume() {
if (this.tridentTimeline == null) {
return;
}
this.tridentTimeline.resume();
}
public void playReverse() {
if (this.tridentTimeline == null) {
return;
}
this.tridentTimeline.playReverse();
}
public final <T> void addPropertyToInterpolate(String propName, T from, T to) {
if (to == null) {
throw new XWTException(
"\"to\" property of Animation cannot be null.");
}
TimelinePropertyBuilder<T> builder = Timeline.<T> property(propName);
if (from == null) {
builder.fromCurrent();
} else {
builder.from(from);
}
builder.to(to);
int index = propName.indexOf('.');
PathPropertyAccessor<T> propertyAccessor = null;
if (index != -1) {
propertyAccessor = new PathPropertyAccessor<T>(propName);
builder.accessWith(propertyAccessor);
}
this.tridentTimeline.addPropertyToInterpolate(builder);
TimeSpan timeSpan = this.xwtTimeline.getBeginTime();
if (timeSpan != null && timeSpan.ticks != 0) {
this.tridentTimeline.setInitialDelay(timeSpan.getMilliseconds());
} else if (from != null) {
if (propertyAccessor != null) {
propertyAccessor.set(target, propName, from);
} else {
DefaultPropertySetter<T> propertySetter = new DefaultPropertySetter<T>(
target, propName);
propertySetter.set(target, propName, from);
}
}
}
public void setEasingFunction(IEasingFunction easingFunction) {
if (easingFunction != null) {
this.tridentTimeline.setEase(easingFunction);
}
}
public boolean isDone() {
return tridentTimeline.isDone();
}
public void resetDoneFlag() {
tridentTimeline.resetDoneFlag();
}
public boolean supportsReplay() {
return tridentTimeline.supportsReplay();
}
}