Skip to content

AnimatedIcon

Header: winui/ui/media/AnimatedIcon.hpp. Spec: winui/ui/media/AnimatedIcon.hpp.

An icon that animates between named visual states by playing segments of an AnimatedIconSource. It draws a fallback icon when it has no source it can show.

Going from state A to B plays the source's segment between the AToB_Start and AToB_End markers. Without those it looks for an AToB or B marker, then any marker named ToB_End. A numeric state name is read as a progress value. A segment plays for duration * |to - from|, and one shorter than 20 ms jumps straight to its end. A state set while a transition plays waits or interrupts as queue_behavior() says. The icon scales the source's natural size uniformly and is centered in its slot. App code or the owning control (such as NavigationShell for its items) calls set_state(). The icon doesn't own the source.

Example:

static const ui::AnimatedFindVisualSource find; // stateless; one instance serves every icon
ui::Control<ui::AnimatedIcon> icon;

window.set_content(ui::Button{
    .width              = 75.0f,
    .accessibility      = {.name = "Search"},
    .on_pointer_entered = [&] { icon->set_state("PointerOver"); },
    .on_pointer_exited  = [&] { icon->set_state("Normal"); },
    .content            = ui::AnimatedIcon{.source   = &find,
                                          .fallback = ui::symbol_glyph(ui::Symbol::Find),
                                          .state    = std::string{"Normal"},
                                          .control  = icon},
});

// Imperative form of the same icon:
auto plain = std::make_unique<ui::AnimatedIconControl>();
plain->set_source(&find);
plain->set_state("Normal");

ui::AnimatedIcon

An icon that plays a caller-supplied AnimatedIconSource as its state changes, and draws a fallback icon when there is no source. Builds a ui::AnimatedIconControl.

Example:

static const ui::AnimatedFindVisualSource find; // stateless; one instance serves every icon
ui::Property<std::string> state{"Normal"};

window.set_content(ui::Button{
    .width              = 75.0f,
    .accessibility      = {.name = "Search"},
    .on_pointer_entered = [&] { state = "PointerOver"; },
    .on_pointer_exited  = [&] { state = "Normal"; },
    .content            = ui::AnimatedIcon{.source   = &find,
                                           .fallback = ui::symbol_glyph(ui::Symbol::Find),
                                           .state    = state},
});

Every field, in the order a designated initializer names them:

ui::AnimatedIcon{
    .source, .fallback, .state, .queue_behavior, .foreground, .style, .margin, .width, .height,
    .min_width, .min_height, .max_width, .max_height, .horizontal_alignment,
    .vertical_alignment, .visible, .tool_tip, .accessibility, .on_pointer_entered,
    .on_pointer_exited, .on_got_focus, .on_lost_focus, .on_key_down, .on_wheel, .control
}

Fields, in declaration order (designators must follow it):

Field Type Default
source ui::Binding<const ui::AnimatedIconSource*> The animation. Not owned, so it must outlive the built control. Null draws the fallback.
fallback ui::Binding<ui::IconSource> The icon drawn while there is no source: a Symbol, a glyph, a path or a picture.
state ui::Binding<std::string> The visual state, such as "Normal", "PointerOver" or "Pressed". Each change plays the source's transition segment from the old state to the new one.
queue_behavior ui::Binding<ui::AnimatedIconQueueBehavior> {ui::AnimatedIconQueueBehavior::QueueOne} What a change of .state does while a transition still plays. QueueOne by default.
foreground ui::Binding<ui::Paint> The icon's color: a fixed color or a theme resource. Unset uses the theme's text color.
on_pointer_entered ui::Action The pointer moved onto the control.
on_pointer_exited ui::Action The pointer left the control.
on_got_focus ui::Action Keyboard focus arrived on the control, or on anything inside it, from outside it. A control with nothing focusable in it never gets focus, and never raises this.
on_lost_focus ui::Action Keyboard focus left the control and everything inside it.
on_key_down ui::Callback<ui::Handling(const ui::KeyEvent&)> A key pressed while focus is on the control or inside it, before the control's own handling; ui::Handled stops it there (Element::on_key_down()).
on_wheel ui::Callback<ui::Handling(const ui::PointerEvent&)> A wheel turn over the control, before the control scrolls; ui::Handled stops it there (Element::on_wheel()).
control ui::ControlOut<ui::AnimatedIcon> Out: the handle that receives the built control.

Plus the common fields style, margin, width, height, min_width, min_height, max_width, max_height, horizontal_alignment, vertical_alignment, visible, tool_tip, accessibility every spec carries (conventions).

build

std::unique_ptr<Element> build()&&

Consumes the spec and returns the built ui::AnimatedIconControl; the caller owns it.

ui::AnimatedIconControl

Derives from ui::Element.

An icon that animates between named visual states by playing segments of an AnimatedIconSource. It draws a fallback icon when it has no source it can show.

Going from state A to B plays the source's segment between the AToB_Start and AToB_End markers. Without those it looks for an AToB or B marker, then any marker named ToB_End. A numeric state name is read as a progress value. A segment plays for duration * |to - from|, and one shorter than 20 ms jumps straight to its end. A state set while a transition plays waits or interrupts as queue_behavior() says. The icon scales the source's natural size uniformly and is centered in its slot. App code or the owning control (such as NavigationShell for its items) calls set_state(). The icon doesn't own the source.

Example:

static const ui::AnimatedFindVisualSource find; // stateless; one instance serves every icon
ui::Control<ui::AnimatedIcon> icon;

window.set_content(ui::Button{
    .width              = 75.0f,
    .accessibility      = {.name = "Search"},
    .on_pointer_entered = [&] { icon->set_state("PointerOver"); },
    .on_pointer_exited  = [&] { icon->set_state("Normal"); },
    .content            = ui::AnimatedIcon{.source   = &find,
                                          .fallback = ui::symbol_glyph(ui::Symbol::Find),
                                          .state    = std::string{"Normal"},
                                          .control  = icon},
});

// Imperative form of the same icon:
auto plain = std::make_unique<ui::AnimatedIconControl>();
plain->set_source(&find);
plain->set_state("Normal");

AnimatedIconControl

AnimatedIconControl() = default

An icon with no source and no fallback: measures to nothing and draws nothing.

source

const AnimatedIconSource* source() const

The animated source being shown, or null (then the fallback glyph is drawn, if any).

set_source

void set_source(const AnimatedIconSource* source)

Sets the animated source. The icon doesn't own it, so it must outlive the icon. The current progress carries over to the new source. Updates layout and redraws.

fallback

const IconSource& fallback() const

The icon drawn while there is no source that can be shown (none set, or its available() is false): a glyph at its own size, anything else fitted into the icon's box. Empty by default.

set_fallback

void set_fallback(IconSource icon)

Sets the fallback icon. Updates layout and redraws.

foreground

const Paint& foreground() const

The icon's color: a fixed color or a theme resource. Empty, the default, uses the theme's text color.

set_foreground

void set_foreground(Paint color)

Sets the color the source draws in. Empty goes back to the theme's text color. Redraws.

state

const std::string& state() const

The state the icon was last asked for.

set_state

void set_state(std::string state)

Moves the icon to state, playing the source's transition into it (see the class description). Setting the state it already has does nothing.

current_state

const std::string& current_state() const

The state the last transition went to, which the next one starts from.

progress

double progress() const

The source's normalized progress (0..1) currently shown.

is_playing

bool is_playing() const

True while a transition segment is animating (tick_override() advances it).

queue_behavior

AnimatedIconQueueBehavior queue_behavior() const

What a set_state() does while a transition plays. QueueOne by default.

set_queue_behavior

void set_queue_behavior(AnimatedIconQueueBehavior behavior)

Sets the queue behavior for subsequent set_state() calls.

last_segment

const std::string& last_segment() const

The segment name the last transition resolved to, for example "NormalToPointerOver". Meant for tests.

last_segment_start

const std::string& last_segment_start() const

The start marker the last transition used (empty if it had none).

last_segment_end

const std::string& last_segment_end() const

The end marker the last transition used (empty if it had none).

render_in

void render_in(Renderer& renderer, const Theme& theme, const Color& foreground) const

Draws the icon like render(), in foreground instead of its own color. For a control that owns the icon and colors it from its own visual state.

automation_role

AutomationRole automation_role() const override

Exposed to UI Automation as an image.

measure_override

Size measure_override(Size available, const MeasureContext& context) const override

Uniform-scales the source's natural size into available, or measures the fallback glyph.

render_override

void render_override(Renderer& renderer, const RenderContext& context) const override

Draws the source's current frame, or the fallback, in foreground() or the theme text color.

tick_override

void tick_override(Duration delta) override

Advances a playing segment by delta, then starts the next queued state when it ends.

Enumerations

AnimatedIconQueueBehavior

enum class AnimatedIconQueueBehavior

What a new state does while an AnimatedIcon transition is still playing.

Value
Cut a new state interrupts whatever is playing
QueueOne the default: queue it behind the running transition
SpeedUpQueueOne queue it, and play the running and queued transitions 7x faster

Tests

  • tests/test_animated_icon.cpp