From 123bfc76e0f85085a6abc71acce93fc2cb8717a1 Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Sun, 15 Dec 2024 16:39:54 +0000 Subject: [PATCH 1/2] Add animation to progress bar --- masonry/src/event_loop_runner.rs | 21 ++++++++ masonry/src/widget/progress_bar.rs | 77 +++++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/masonry/src/event_loop_runner.rs b/masonry/src/event_loop_runner.rs index dda6a5636..c5d3a989a 100644 --- a/masonry/src/event_loop_runner.rs +++ b/masonry/src/event_loop_runner.rs @@ -1,8 +1,11 @@ // Copyright 2024 the Xilem Authors // SPDX-License-Identifier: Apache-2.0 +use std::cmp::Reverse; +use std::collections::BinaryHeap; use std::num::NonZeroUsize; use std::sync::Arc; +use std::time::Instant; use accesskit_winit::Adapter; use tracing::{debug, info_span, warn}; @@ -81,6 +84,8 @@ pub struct MasonryState<'a> { proxy: EventLoopProxy, #[cfg(feature = "tracy")] frame: Option, + // timers as a min priority queue + timers: BinaryHeap>, // Per-Window state // In future, this will support multiple windows @@ -159,6 +164,22 @@ impl ApplicationHandler for MainState<'_> { self.masonry_state.handle_suspended(event_loop); } + fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: StartCause) { + // check if timers have elapsed and set event loop to wake at next timer deadline + let now = Instant::now(); + loop { + let Some(next_timer) = self.masonry_state.timers.peek().cloned() else { + break; + }; + let next_timer = next_timer.0; + if next_timer > now { + break; + } + // timer has elapsed - remove from heap and handle + self.masonry_state.timers.pop(); + } + } + fn window_event( &mut self, event_loop: &ActiveEventLoop, diff --git a/masonry/src/widget/progress_bar.rs b/masonry/src/widget/progress_bar.rs index 64b53b5b7..d98b07845 100644 --- a/masonry/src/widget/progress_bar.rs +++ b/masonry/src/widget/progress_bar.rs @@ -3,11 +3,14 @@ //! A progress bar widget. +use std::time::Duration; + use accesskit::{Node, Role}; use smallvec::{smallvec, SmallVec}; use tracing::{trace_span, Span}; use vello::Scene; +use crate::contexts::TimerToken; use crate::kurbo::Size; use crate::paint_scene_helpers::{fill_lin_gradient, stroke, UnitPoint}; use crate::text::ArcStr; @@ -27,6 +30,10 @@ pub struct ProgressBar { /// It is also used if an invalid float (outside of [0, 1]) is passed. progress: Option, label: WidgetPod