From 0234054e0ae5a7b35c81702ddb2cf69baa1738ae Mon Sep 17 00:00:00 2001 From: Adoo Date: Sun, 8 Sep 2024 01:58:02 +0800 Subject: [PATCH] =?UTF-8?q?feat(core):=20=F0=9F=8E=B8=20support=20`WindowF?= =?UTF-8?q?lags`=20to=20control=20the=20window=20behavior?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + core/src/animation/animate.rs | 14 ++++++++++++-- core/src/test_helper.rs | 7 ++++++- core/src/window.rs | 19 +++++++++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3569282f..81971edd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ Please only add new entries below the [Unreleased](#unreleased---releasedate) he - **core**: The built-in widget `Class` has been added to enable the sharing of consistent styles across multiple elements and to allow widgets to have different actions and styles in different themes. (#pr, @M-Adoo) - **core**: The widget `ConstrainedBox` has been added as a built-in widget; now `clamp` can be used as a built-in field. (#pr @M-Adoo) +- **core**: Added `WindowFlags` to regulate the window behavior, with the option of utilizing `WindowFlags::ANIMATIONS` to toggle animations on or off. (#pr @M-Adoo) - **theme/material**: Define the constant variables of motion. (#pr, @M-Adoo) - **dev_helper**: Refine the widget test macros. (#pr, @M-Adoo) diff --git a/core/src/animation/animate.rs b/core/src/animation/animate.rs index dfa925ff6..5d2ad4bba 100644 --- a/core/src/animation/animate.rs +++ b/core/src/animation/animate.rs @@ -1,4 +1,8 @@ -use crate::{prelude::*, ticker::FrameMsg, window::WindowId}; +use crate::{ + prelude::*, + ticker::FrameMsg, + window::{WindowFlags, WindowId}, +}; #[simple_declare] pub struct Animate where @@ -35,6 +39,12 @@ where let mut animate_ref = self.write(); let this = &mut *animate_ref; let wnd_id = this.window_id; + let Some(wnd) = AppCtx::get_window(this.window_id) else { return }; + + if !wnd.flags().contains(WindowFlags::ANIMATIONS) { + return; + } + let new_to = this.state.get(); if let Some(AnimateInfo { from, to, last_progress, .. }) = &mut this.running_info { @@ -42,7 +52,7 @@ where .state .calc_lerp_value(from, to, last_progress.value()); *to = new_to; - } else if let Some(wnd) = AppCtx::get_window(wnd_id) { + } else { drop(animate_ref); let animate = self.clone_writer(); diff --git a/core/src/test_helper.rs b/core/src/test_helper.rs index 63dc63cff..60276f4e4 100644 --- a/core/src/test_helper.rs +++ b/core/src/test_helper.rs @@ -14,7 +14,7 @@ wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); pub use crate::timer::Timer; use crate::{ prelude::*, - window::{ShellWindow, WindowId}, + window::{ShellWindow, WindowFlags, WindowId}, }; pub struct Frame { @@ -28,6 +28,8 @@ pub fn split_value(v: T) -> (Watcher>, Stateful) { (src.clone_watcher(), src.clone_writer()) } +/// The Window assists in writing unit tests; animations are disabled by +/// default. #[derive(Clone)] pub struct TestWindow(pub Rc); @@ -56,6 +58,9 @@ impl TestWindow { fn new_wnd(root: impl Into, size: Option) -> Self { let _ = NEW_TIMER_FN.set(Timer::new_timer_future); let wnd = AppCtx::new_window(Box::new(TestShellWindow::new(size)), root.into()); + let mut flags = wnd.flags(); + flags.remove(WindowFlags::ANIMATIONS); + wnd.set_flags(flags); wnd.run_frame_tasks(); Self(wnd) } diff --git a/core/src/window.rs b/core/src/window.rs index e8e46c6f5..288162b8e 100644 --- a/core/src/window.rs +++ b/core/src/window.rs @@ -52,6 +52,20 @@ pub struct Window { /// /// This widgets it's detached from its parent, but still need to paint. delay_drop_widgets: RefCell, WidgetId)>>, + + flags: Cell, +} + +bitflags! { + #[derive(Clone, Copy)] + #[doc="A set of flags to control the window behavior."] + pub struct WindowFlags: u32 { + #[doc="If this window enables animation, set this flag to true to \ + activate all animations; if this flag is not marked, all animations\ + will not run."] + const ANIMATIONS = 1 << 0; + const DEFAULT = Self::ANIMATIONS.bits(); + } } #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Hash)] @@ -277,6 +291,7 @@ impl Window { priority_task_queue: PriorityTaskQueue::default(), shell_wnd: RefCell::new(shell_wnd), delay_drop_widgets: <_>::default(), + flags: Cell::new(WindowFlags::DEFAULT), }; let window = Rc::new(window); window.dispatcher.borrow_mut().init(&window); @@ -292,6 +307,10 @@ impl Window { pub fn shell_wnd(&self) -> &RefCell> { &self.shell_wnd } + pub fn flags(&self) -> WindowFlags { self.flags.get() } + + pub fn set_flags(&self, flags: WindowFlags) { self.flags.set(flags) } + pub(crate) fn add_focus_node(&self, wid: WidgetId, auto_focus: bool, focus_type: FocusType) { self .focus_mgr