Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Timed Events

Events can be scheduled to emit at a specific point in time, allowing you to implement delays, timeouts, and delayed actions without needing separate timers.

Scheduling events

Use cx.schedule_emit() to send an event at a later time:

use vizia::prelude::*;
use web_time::{Instant, Duration};

pub enum AppEvent {
    Delayed,
}

let delay = Duration::from_secs(2);
let when = Instant::now() + delay;
cx.schedule_emit(AppEvent::Delayed, when);

The method returns a TimedEventHandle that can be used to cancel the scheduled event before it sends.

Targeting scheduled events

Like regular events, you can schedule events to a specific target using cx.schedule_emit_to():

let target: Entity = some_entity;
let when = Instant::now() + Duration::from_secs(1);
cx.schedule_emit_to(target, AppEvent::Delayed, when);

Custom propagation for scheduled events

For precise control over how a scheduled event propagates, use cx.schedule_emit_custom():

let custom = Event::new(AppEvent::Delayed)
    .target(target)
    .origin(cx.current)
    .propagate(Propagation::Subtree);

let when = Instant::now() + Duration::from_secs(1);
cx.schedule_emit_custom(custom, when);

Canceling scheduled events

Keep the returned TimedEventHandle to cancel a scheduled event before it emits:

let handle = cx.schedule_emit(AppEvent::Delayed, Instant::now() + Duration::from_secs(5));

// ... later, if you want to prevent the event from sending:
cx.cancel_scheduled(handle);

Practical example: Delayed notification

Here’s a complete example showing a button that triggers a delayed event:

use vizia::prelude::*;
use web_time::{Instant, Duration};

pub struct AppData {
    message: Signal<String>,
}

pub enum AppEvent {
    ShowMessage(String),
}

impl Model for AppData {
    fn event(&mut self, _cx: &mut EventContext, event: &mut Event) {
        event.map(|app_event, _| match app_event {
            AppEvent::ShowMessage(msg) => {
                self.message.set(msg.clone());
            }
        });
    }
}

fn main() -> Result<(), ApplicationError> {
    Application::new(|cx| {
        let message = Signal::new(String::new());
        AppData { message }.build(cx);

        VStack::new(cx, |cx| {
            Label::new(cx, message);
            
            Button::new(cx, |cx| Label::new(cx, "Notify in 2s"))
                .on_press(|cx| {
                    let when = Instant::now() + Duration::from_secs(2);
                    cx.schedule_emit(
                        AppEvent::ShowMessage(String::from("Notification!")),
                        when
                    );
                });
        });
    })
    .inner_size((400, 100))
    .run()
}

When the button is pressed, the ShowMessage event is scheduled to emit after 2 seconds, updating the label with the notification message.