AlwaysCompletePerformance, ReversePerformance
These new PerformanceView classes are transforms over PerformanceViews. The first is a cheap way to tell code that expects a performance to not animate after all, and the other is a way to replace a view of a performance going in one direction with a view of a performance going in the other direction. See also https://github.com/flutter/engine/issues/1708
This commit is contained in:
parent
86087cbb08
commit
545db87ace
@ -44,9 +44,19 @@ abstract class PerformanceView {
|
|||||||
/// Stops calling the listener every time the status of the performance changes
|
/// Stops calling the listener every time the status of the performance changes
|
||||||
void removeStatusListener(PerformanceStatusListener listener);
|
void removeStatusListener(PerformanceStatusListener listener);
|
||||||
|
|
||||||
/// The current status of this animation
|
/// The current status of this animation.
|
||||||
PerformanceStatus get status;
|
PerformanceStatus get status;
|
||||||
|
|
||||||
|
/// The current direction of the animation.
|
||||||
|
AnimationDirection get direction;
|
||||||
|
|
||||||
|
/// The direction used to select the current curve.
|
||||||
|
///
|
||||||
|
/// The curve direction is only reset when we hit the beginning or the end of
|
||||||
|
/// the timeline to avoid discontinuities in the value of any variables this
|
||||||
|
/// performance is used to animate.
|
||||||
|
AnimationDirection get curveDirection;
|
||||||
|
|
||||||
/// The current progress of this animation (a value from 0.0 to 1.0).
|
/// The current progress of this animation (a value from 0.0 to 1.0).
|
||||||
/// This is the value that is used to update any variables when using updateVariable().
|
/// This is the value that is used to update any variables when using updateVariable().
|
||||||
double get progress;
|
double get progress;
|
||||||
@ -58,6 +68,85 @@ abstract class PerformanceView {
|
|||||||
bool get isCompleted => status == PerformanceStatus.completed;
|
bool get isCompleted => status == PerformanceStatus.completed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AlwaysCompletePerformance extends PerformanceView {
|
||||||
|
const AlwaysCompletePerformance();
|
||||||
|
|
||||||
|
void updateVariable(Animatable variable) {
|
||||||
|
variable.setProgress(1.0, AnimationDirection.forward);
|
||||||
|
}
|
||||||
|
|
||||||
|
// this performance never changes state
|
||||||
|
void addListener(PerformanceListener listener) { }
|
||||||
|
void removeListener(PerformanceListener listener) { }
|
||||||
|
void addStatusListener(PerformanceStatusListener listener) { }
|
||||||
|
void removeStatusListener(PerformanceStatusListener listener) { }
|
||||||
|
PerformanceStatus get status => PerformanceStatus.completed;
|
||||||
|
AnimationDirection get direction => AnimationDirection.forward;
|
||||||
|
AnimationDirection get curveDirection => AnimationDirection.forward;
|
||||||
|
double get progress => 1.0;
|
||||||
|
}
|
||||||
|
const AlwaysCompletePerformance alwaysCompletePerformance = const AlwaysCompletePerformance();
|
||||||
|
|
||||||
|
class ReversePerformance extends PerformanceView {
|
||||||
|
ReversePerformance(this.masterPerformance) {
|
||||||
|
masterPerformance.addStatusListener(_statusChangeHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
final PerformanceView masterPerformance;
|
||||||
|
|
||||||
|
void updateVariable(Animatable variable) {
|
||||||
|
variable.setProgress(progress, curveDirection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addListener(PerformanceListener listener) {
|
||||||
|
masterPerformance.addListener(listener);
|
||||||
|
}
|
||||||
|
void removeListener(PerformanceListener listener) {
|
||||||
|
masterPerformance.removeListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<PerformanceStatusListener> _statusListeners = new List<PerformanceStatusListener>();
|
||||||
|
|
||||||
|
/// Calls listener every time the status of this performance changes
|
||||||
|
void addStatusListener(PerformanceStatusListener listener) {
|
||||||
|
_statusListeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stops calling the listener every time the status of this performance changes
|
||||||
|
void removeStatusListener(PerformanceStatusListener listener) {
|
||||||
|
_statusListeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _statusChangeHandler(PerformanceStatus status) {
|
||||||
|
status = _reverseStatus(status);
|
||||||
|
List<PerformanceStatusListener> localListeners = new List<PerformanceStatusListener>.from(_statusListeners);
|
||||||
|
for (PerformanceStatusListener listener in localListeners)
|
||||||
|
listener(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
PerformanceStatus get status => _reverseStatus(masterPerformance.status);
|
||||||
|
AnimationDirection get direction => _reverseDirection(masterPerformance.direction);
|
||||||
|
AnimationDirection get curveDirection => _reverseDirection(masterPerformance.curveDirection);
|
||||||
|
double get progress => 1.0 - masterPerformance.progress;
|
||||||
|
|
||||||
|
PerformanceStatus _reverseStatus(PerformanceStatus status) {
|
||||||
|
switch (status) {
|
||||||
|
case PerformanceStatus.forward: return PerformanceStatus.reverse;
|
||||||
|
case PerformanceStatus.reverse: return PerformanceStatus.forward;
|
||||||
|
case PerformanceStatus.completed: return PerformanceStatus.dismissed;
|
||||||
|
case PerformanceStatus.dismissed: return PerformanceStatus.completed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimationDirection _reverseDirection(AnimationDirection direction) {
|
||||||
|
switch (direction) {
|
||||||
|
case AnimationDirection.forward: return AnimationDirection.reverse;
|
||||||
|
case AnimationDirection.reverse: return AnimationDirection.forward;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// A timeline that can be reversed and used to update [Animatable]s.
|
/// A timeline that can be reversed and used to update [Animatable]s.
|
||||||
///
|
///
|
||||||
/// For example, a performance may handle an animation of a menu opening by
|
/// For example, a performance may handle an animation of a menu opening by
|
||||||
@ -86,13 +175,9 @@ class Performance extends PerformanceView {
|
|||||||
Duration duration;
|
Duration duration;
|
||||||
|
|
||||||
SimulationStepper _timeline;
|
SimulationStepper _timeline;
|
||||||
|
AnimationDirection get direction => _direction;
|
||||||
AnimationDirection _direction;
|
AnimationDirection _direction;
|
||||||
|
AnimationDirection get curveDirection => _curveDirection;
|
||||||
/// The direction used to select the current curve
|
|
||||||
///
|
|
||||||
/// Curve direction is only reset when we hit the beginning or the end of the
|
|
||||||
/// timeline to avoid discontinuities in the value of any variables this
|
|
||||||
/// performance is used to animate.
|
|
||||||
AnimationDirection _curveDirection;
|
AnimationDirection _curveDirection;
|
||||||
|
|
||||||
/// If non-null, animate with this timing instead of a linear timing
|
/// If non-null, animate with this timing instead of a linear timing
|
||||||
@ -103,7 +188,6 @@ class Performance extends PerformanceView {
|
|||||||
/// Note: Setting this value stops the current animation.
|
/// Note: Setting this value stops the current animation.
|
||||||
double get progress => _timeline.value.clamp(0.0, 1.0);
|
double get progress => _timeline.value.clamp(0.0, 1.0);
|
||||||
void set progress(double t) {
|
void set progress(double t) {
|
||||||
// TODO(mpcomplete): should this affect |direction|?
|
|
||||||
stop();
|
stop();
|
||||||
_timeline.value = t.clamp(0.0, 1.0);
|
_timeline.value = t.clamp(0.0, 1.0);
|
||||||
_checkStatusChanged();
|
_checkStatusChanged();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user