class new in Git master
#include <Magnum/Ui/TextLayerAnimator.h>
TextLayerStyleAnimator Text layer style animator.
Each animation is a transition between two TextLayer styles, with individual properties interpolated with an easing function. BaseLayerStyleAnimator is a matching animator for the BaseLayer.
Setting up an animator instance
The animator doesn't have any shared state or configuration, so it's just about constructing it from a fresh AbstractUserInterface::
Ui::TextLayerStyleAnimator& animator = ui.setStyleAnimatorInstance( Containers::pointer<Ui::TextLayerStyleAnimator>(ui.createAnimator()));
After that, the animator has to be registered with a concrete layer instance. The animations make use of dynamic styles, so the text layer is expected to have at least one dynamic style enabled with TextLayer::
Ui::TextLayerGL::Shared textLayerShared{glyphCache, Ui::TextLayer::Shared::Configuration{…} … .setDynamicStyleCount(10) /* adjust as needed */ }; Ui::TextLayer& textLayer = ui.setLayerInstance( Containers::pointer<Ui::TextLayerGL>(ui.createLayer(), textLayerShared)); … textLayer.assignAnimator(animator);
Unlike builtin layers or layouters, the default UserInterface implementation doesn't implicitly provide a TextLayerStyleAnimator instance.
Creating animations
Assuming an enum is used to index the styles defined in TextLayer::
enum class TextLayerStyle { … Button, ButtonHovered, … }; Ui::DataHandle buttonText = …; animator.create(TextLayerStyle::ButtonHovered, TextLayerStyle::Button, Animation::Easing::cubicOut, now, 0.5_sec, buttonText);
Internally, once the animation starts playing, the animator allocates a new dynamic style index using TextLayer::
If the animator runs out of dynamic styles, newly started animations are switched to the source style index until a dynamic style is recycled. If no dynamic style gets recycled until the animation stops, the data gets switched directly to the target style at the animation stop with no animation. Again, in case of AnimationFlag::
The animation interpolates all properties of TextLayerStyleUniform as well as the style padding value. The font, alignment or text feature style properties cannot be animated and thus are set to properties of source style at the start (and target style for AnimationFlag::
At the moment, only animation between predefined styles is possible.
Resolving style conflicts
In case of styles transitioning in response to input events, it may often happen that a transition happens while another transition is still being animated. To avoid visual artifacts and seemingly random behavior, the animator updates the style assignment only if it didn't change since the animation started.
For example, if a different style is assigned while an animation is playing — either by a different animation or directly with TextLayer::
From the other side, if external code encounters a dynamic style being assigned to a particular data, it can query TextLayer::
The animator doesn't give any ordering guarantees for multiple style animations affecting the same data starting at the same time. Such cases should be rather rare in practice, however.
Animation lifetime and data attachment
As with all other animations, they're implicitly removed once they're played. Pass AnimationFlag::
Style animations are associated with data they animate, and thus as soon as the data or node the data is attached to is removed, the animation gets removed as well. If you want to preserve the animation when the data is removed, call attach(AnimationHandle, DataHandle) with DataHandle::
Additionally the animation is removed also if a different style is assigned to data the animation is attached to while it's playing, and the animation doesn't have AnimationFlag::
If you call create() with DataHandle::
Base classes
- class AbstractVisualLayerStyleAnimator new in Git master
- Base for AbstractVisualLayer style animators.
Constructors, destructors, conversion operators
- TextLayerStyleAnimator(AnimatorHandle handle) explicit
- Constructor.
- TextLayerStyleAnimator(const AbstractStyleAnimator&) deleted
- Copying is not allowed.
- TextLayerStyleAnimator(TextLayerStyleAnimator&&) noexcept
- Move constructor.
Public functions
- auto operator=(const TextLayerStyleAnimator&) -> TextLayerStyleAnimator& deleted
- Copying is not allowed.
- auto operator=(TextLayerStyleAnimator&&) -> TextLayerStyleAnimator& noexcept
- Move assignment.
- auto create(UnsignedInt sourceStyle, UnsignedInt targetStyle, Float(*)(Float) easing, Nanoseconds start, Nanoseconds duration, DataHandle data, UnsignedInt repeatCount = 1, AnimationFlags flags = {}) -> AnimationHandle
- Create an animation.
-
template<class StyleIndex>auto create(StyleIndex sourceStyle, StyleIndex targetStyle, Float(*)(Float) easing, Nanoseconds start, Nanoseconds duration, DataHandle data, UnsignedInt repeatCount = 1, AnimationFlags flags = {}) -> AnimationHandle
- Create an animation with a style index in a concrete enum type.
- auto create(UnsignedInt sourceStyle, UnsignedInt targetStyle, Float(*)(Float) easing, Nanoseconds start, Nanoseconds duration, DataHandle data, AnimationFlags flags) -> AnimationHandle
- Create an animation.
-
template<class StyleIndex>auto create(StyleIndex sourceStyle, StyleIndex targetStyle, Float(*)(Float) easing, Nanoseconds start, Nanoseconds duration, DataHandle data, AnimationFlags flags) -> AnimationHandle
- Create an animation with a style index in a concrete enum type.
- auto create(UnsignedInt sourceStyle, UnsignedInt targetStyle, Float(*)(Float) easing, Nanoseconds start, Nanoseconds duration, LayerDataHandle data, UnsignedInt repeatCount = 1, AnimationFlags flags = {}) -> AnimationHandle
- Create an animation assuming the data it's attached to belongs to the layer the animator is registered with.
-
template<class StyleIndex>auto create(StyleIndex sourceStyle, StyleIndex targetStyle, Float(*)(Float) easing, Nanoseconds start, Nanoseconds duration, LayerDataHandle data, UnsignedInt repeatCount = 1, AnimationFlags flags = {}) -> AnimationHandle
- Create an animation with a style index in a concrete enum type assuming the data it's attached to belongs to the layer the animator is registered with.
- auto create(UnsignedInt sourceStyle, UnsignedInt targetStyle, Float(*)(Float) easing, Nanoseconds start, Nanoseconds duration, LayerDataHandle data, AnimationFlags flags) -> AnimationHandle
- Create an animation assuming the data it's attached to belongs to the layer the animator is registered with.
-
template<class StyleIndex>auto create(StyleIndex sourceStyle, StyleIndex targetStyle, Float(*)(Float) easing, Nanoseconds start, Nanoseconds duration, LayerDataHandle data, AnimationFlags flags) -> AnimationHandle
- Create an animation with a style index in a concrete enum type assuming the data it's attached to belongs to the layer the animator is registered with.
- void remove(AnimationHandle handle)
- Remove an animation.
- void remove(AnimatorDataHandle handle)
- Remove an animation assuming it belongs to this animator.
- auto easing(AnimationHandle handle) -> auto
- Animation easing function.
- auto easing(AnimatorDataHandle handle) -> auto
- Animation easing function assuming it belongs to this animator.
-
auto advance(Nanoseconds time,
Containers::
MutableBitArrayView activeStorage, Containers:: MutableBitArrayView startedStorage, Containers:: MutableBitArrayView stoppedStorage, const Containers:: StridedArrayView1D<Float>& factorStorage, Containers:: MutableBitArrayView removeStorage, Containers:: ArrayView<TextLayerStyleUniform> dynamicStyleUniforms, Containers:: MutableBitArrayView dynamicStyleCursorStyles, Containers:: MutableBitArrayView dynamicStyleSelectionStyles, const Containers:: StridedArrayView1D<Vector4>& dynamicStylePaddings, Containers:: ArrayView<TextLayerEditingStyleUniform> dynamicEditingStyleUniforms, const Containers:: StridedArrayView1D<Vector4>& dynamicEditingStylePaddings, const Containers:: StridedArrayView1D<UnsignedInt>& dataStyles) -> TextLayerStyleAnimatorUpdates - Advance the animations.
Function documentation
Magnum:: Ui:: TextLayerStyleAnimator:: TextLayerStyleAnimator(AnimatorHandle handle) explicit
Constructor.
Parameters | |
---|---|
handle | Handle returned by AbstractUserInterface:: |
Magnum:: Ui:: TextLayerStyleAnimator:: TextLayerStyleAnimator(TextLayerStyleAnimator&&) noexcept
Move constructor.
Performs a destructive move, i.e. the original object isn't usable afterwards anymore.
AnimationHandle Magnum:: Ui:: TextLayerStyleAnimator:: create(UnsignedInt sourceStyle,
UnsignedInt targetStyle,
Float(*)(Float) easing,
Nanoseconds start,
Nanoseconds duration,
DataHandle data,
UnsignedInt repeatCount = 1,
AnimationFlags flags = {})
Create an animation.
Parameters | |
---|---|
sourceStyle | Style index to animate from |
targetStyle | Style index to animate to |
easing | Easing function between 0.0f and 1.0f , used for all style uniform values as well as the padding. Pick one from Animation:: |
start | Time at which the animation starts. Use Nanoseconds:: |
duration | Duration of a single play of the animation |
data | Data the animation is attached to. Use DataHandle:: |
repeatCount | Repeat count. Use 0 for an indefinitely repeating animation. |
flags | Flags |
Expects that TextLayer::sourceStyle
and targetStyle
are less than TextLayer::easing
is not nullptr
.
Delegates to AbstractAnimator::
The animation affects the TextLayerStyleUniform and the padding value, if it differs between the styles. The animated dynamic style is initialized from font, alignment and features from styleSrc
, if styleDst
has them different, they don't affect the animation in any way. If given style references a cursor or editing style, it affects also the corresponding TextLayerEditingStyleUniform, the editing padding value, if it differs between the editing styles, and the TextLayerStyleUniform override for selected portions of the text, if referenced.
The actually animated style values are queried from TextLayer::data
to attach to however requires a style to be set.
template<class StyleIndex>
AnimationHandle Magnum:: Ui:: TextLayerStyleAnimator:: create(StyleIndex sourceStyle,
StyleIndex targetStyle,
Float(*)(Float) easing,
Nanoseconds start,
Nanoseconds duration,
DataHandle data,
UnsignedInt repeatCount = 1,
AnimationFlags flags = {})
Create an animation with a style index in a concrete enum type.
Casts sourceStyle
and targetStyle
to UnsignedInt and delegates to create(UnsignedInt, UnsignedInt, Float(*)(Float), Nanoseconds, Nanoseconds, DataHandle, UnsignedInt, AnimationFlags).
AnimationHandle Magnum:: Ui:: TextLayerStyleAnimator:: create(UnsignedInt sourceStyle,
UnsignedInt targetStyle,
Float(*)(Float) easing,
Nanoseconds start,
Nanoseconds duration,
DataHandle data,
AnimationFlags flags)
Create an animation.
Same as calling create(UnsignedInt, UnsignedInt, Float(*)(Float), Nanoseconds, Nanoseconds, DataHandle, UnsignedInt, AnimationFlags) with repeatCount
set to 1
.
template<class StyleIndex>
AnimationHandle Magnum:: Ui:: TextLayerStyleAnimator:: create(StyleIndex sourceStyle,
StyleIndex targetStyle,
Float(*)(Float) easing,
Nanoseconds start,
Nanoseconds duration,
DataHandle data,
AnimationFlags flags)
Create an animation with a style index in a concrete enum type.
Casts sourceStyle
and targetStyle
to UnsignedInt and delegates to create(UnsignedInt, UnsignedInt, Float(*)(Float), Nanoseconds, Nanoseconds, DataHandle, AnimationFlags).
AnimationHandle Magnum:: Ui:: TextLayerStyleAnimator:: create(UnsignedInt sourceStyle,
UnsignedInt targetStyle,
Float(*)(Float) easing,
Nanoseconds start,
Nanoseconds duration,
LayerDataHandle data,
UnsignedInt repeatCount = 1,
AnimationFlags flags = {})
Create an animation assuming the data it's attached to belongs to the layer the animator is registered with.
Compared to create(UnsignedInt, UnsignedInt, Float(*)(Float), Nanoseconds, Nanoseconds, DataHandle, UnsignedInt, AnimationFlags) delegates to AbstractAnimator::
template<class StyleIndex>
AnimationHandle Magnum:: Ui:: TextLayerStyleAnimator:: create(StyleIndex sourceStyle,
StyleIndex targetStyle,
Float(*)(Float) easing,
Nanoseconds start,
Nanoseconds duration,
LayerDataHandle data,
UnsignedInt repeatCount = 1,
AnimationFlags flags = {})
Create an animation with a style index in a concrete enum type assuming the data it's attached to belongs to the layer the animator is registered with.
Casts sourceStyle
and targetStyle
to UnsignedInt and delegates to create(UnsignedInt, UnsignedInt, Float(*)(Float), Nanoseconds, Nanoseconds, LayerDataHandle, UnsignedInt, AnimationFlags).
AnimationHandle Magnum:: Ui:: TextLayerStyleAnimator:: create(UnsignedInt sourceStyle,
UnsignedInt targetStyle,
Float(*)(Float) easing,
Nanoseconds start,
Nanoseconds duration,
LayerDataHandle data,
AnimationFlags flags)
Create an animation assuming the data it's attached to belongs to the layer the animator is registered with.
Same as calling create(UnsignedInt, UnsignedInt, Float(*)(Float), Nanoseconds, Nanoseconds, LayerDataHandle, UnsignedInt, AnimationFlags) with repeatCount
set to 1
.
template<class StyleIndex>
AnimationHandle Magnum:: Ui:: TextLayerStyleAnimator:: create(StyleIndex sourceStyle,
StyleIndex targetStyle,
Float(*)(Float) easing,
Nanoseconds start,
Nanoseconds duration,
LayerDataHandle data,
AnimationFlags flags)
Create an animation with a style index in a concrete enum type assuming the data it's attached to belongs to the layer the animator is registered with.
Casts sourceStyle
and targetStyle
to UnsignedInt and delegates to create(UnsignedInt, UnsignedInt, Float(*)(Float), Nanoseconds, Nanoseconds, LayerDataHandle, UnsignedInt, AnimationFlags).
void Magnum:: Ui:: TextLayerStyleAnimator:: remove(AnimationHandle handle)
Remove an animation.
Expects that handle
is valid. Recycles a dynamic style used by given animation with TextLayer::
void Magnum:: Ui:: TextLayerStyleAnimator:: remove(AnimatorDataHandle handle)
Remove an animation assuming it belongs to this animator.
Compared to remove(AnimationHandle) delegates to AbstractAnimator::
auto Magnum:: Ui:: TextLayerStyleAnimator:: easing(AnimationHandle handle)
Animation easing function.
Expects that handle
is valid. The returned pointer is never nullptr
.
auto Magnum:: Ui:: TextLayerStyleAnimator:: easing(AnimatorDataHandle handle)
Animation easing function assuming it belongs to this animator.
Like easing(AnimationHandle) const but without checking that handle
indeed belongs to this animator. See its documentation for more information.
TextLayerStyleAnimatorUpdates Magnum:: Ui:: TextLayerStyleAnimator:: advance(Nanoseconds time,
Containers:: MutableBitArrayView activeStorage,
Containers:: MutableBitArrayView startedStorage,
Containers:: MutableBitArrayView stoppedStorage,
const Containers:: StridedArrayView1D<Float>& factorStorage,
Containers:: MutableBitArrayView removeStorage,
Containers:: ArrayView<TextLayerStyleUniform> dynamicStyleUniforms,
Containers:: MutableBitArrayView dynamicStyleCursorStyles,
Containers:: MutableBitArrayView dynamicStyleSelectionStyles,
const Containers:: StridedArrayView1D<Vector4>& dynamicStylePaddings,
Containers:: ArrayView<TextLayerEditingStyleUniform> dynamicEditingStyleUniforms,
const Containers:: StridedArrayView1D<Vector4>& dynamicEditingStylePaddings,
const Containers:: StridedArrayView1D<UnsignedInt>& dataStyles)
Advance the animations.
Parameters | |
---|---|
time in | Time to which to advance |
activeStorage in/out | Storage for the animator to put a mask of active animations into |
startedStorage in/out | Storage for the animator to put a mask of started animations into |
stoppedStorage in/out | Storage for the animator to put a mask of stopped animations into |
factorStorage in/out | Storage for the animator to put animation interpolation factors into |
removeStorage in/out | Storage for the animator to put a mask of animations to remove into |
dynamicStyleUniforms in/out | Uniforms to animate indexed by dynamic style ID or dynamic editing style text uniform ID |
dynamicStyleCursorStyles in/out | Cursor style association to animate indexed by dynamic style ID |
dynamicStyleSelectionStyles in/out | Selection style association to animate indexed by dynamic style ID |
dynamicStylePaddings in/out | Paddings to animate indexed by dynamic style ID |
dynamicEditingStyleUniforms in/out | Editing uniforms to animate indexed by dynamic editing style ID |
dynamicEditingStylePaddings in/out | Editing paddings to animate indexed by dynamic editing style ID |
dataStyles in/out | Style assignments of all layer data indexed by data ID |
Returns | Style properties that were affected by the animation |
Used internally from TextLayer::
Expects that size of activeStorage
, startedStorage
, stoppedStorage
, factorStorage
and removeStorage
matches capacity(), their contents get filled by update() internally. If the layer the animator is associated with doesn't contain editing styles, the dynamicStyleUniforms
, dynamicStyleCursorStyles
, dynamicStyleSelectionStyles
and dynamicStylePaddings
, are expected to have a size of TextLayer::dynamicEditingStyleUniforms
and dynamicEditingStylePaddings
views are expected to be empty. If the layer contains editing styles, the dynamicStyleUniforms
is expected to be three times as large as TextLayer::dynamicEditingStyleUniforms
and dynamicEditingStylePaddings
views twice as large as TextLayer::dataStyles
view should be large enough to contain any valid layer data ID. TextLayer::