diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1a274d1ac..e9c786bf3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -27,7 +27,7 @@ Please only add new entries below the [Unreleased](#unreleased---releasedate) he
### Features
-- **core**: Support for modifying the theme at runtime. (#pr @M-Adoo)
+- **core**: Support for modifying the theme at runtime. (#618 @M-Adoo)
The code:
@@ -53,7 +53,7 @@ Please only add new entries below the [Unreleased](#unreleased---releasedate) he
App::run(w);
```
-- **core**: Added `Provider` widget to share data between sub-tree. (#pr @M-Adoo)
+- **core**: Added `Provider` widget to share data between sub-tree. (#618 @M-Adoo)
```rust
Provider::new(Box::new(State::value(0i32))).with_child(fn_widget! {
@SizedBox {
@@ -75,12 +75,14 @@ Please only add new entries below the [Unreleased](#unreleased---releasedate) he
});
```
-- **core**: Added `WidgetCtx::query`, `WidgetCtx::query_write`, `WidgetCtx::query_of_widget` and `WidgetCtx::query_write_of_widget`. (#pr @M-Adoo)
+- **core**: Added `Overlay::of` to allow querying the overlay in event callbacks. (#618 @M-Adoo)
+- **core**: Added `WidgetCtx::query`, `WidgetCtx::query_write`, `WidgetCtx::query_of_widget` and `WidgetCtx::query_write_of_widget`. (#618 @M-Adoo)
### Breaking
+- **core**: Removed `Overlay::new_with_handle` and `OverlayCloseHandle`. (#618 @M-Adoo)
- **core**: `GenWidget::gen_widget` no longer requires a `&mut BuildCtx` parameter. (#616 @M-Adoo)
-- **core**: Removed `FullTheme` and `InheritTheme`, now only using `Theme`. Any part of the theme, such as `Palette`, can be directly used to overwrite its corresponding theme component. (#pr @M-Adoo)
+- **core**: Removed `FullTheme` and `InheritTheme`, now only using `Theme`. Any part of the theme, such as `Palette`, can be directly used to overwrite its corresponding theme component. (#618 @M-Adoo)
## [0.4.0-alpha.5] - 2024-08-14
@@ -115,7 +117,7 @@ Please only add new entries below the [Unreleased](#unreleased---releasedate) he
### Breaking
-- Removed `WidgetCtx::query_widget_type` and `WidgetCtx::query_type` (#pr @M-Adoo)
+- Removed `WidgetCtx::query_widget_type` and `WidgetCtx::query_type` (#618 @M-Adoo)
- Removed `ChildFrom` and `FromAnother` traits (#612 @M-Adoo)
- Removed `SingleParent` and `MultiParent` traits. (#612 @M-Adoo)
- Removed `PairChild` and `PairWithChild` traits. User can use a generic type instead. (#612 @M-Adoo)
diff --git a/core/src/builtin_widgets/global_anchor.rs b/core/src/builtin_widgets/global_anchor.rs
index d551baa1c..3c723e2ed 100644
--- a/core/src/builtin_widgets/global_anchor.rs
+++ b/core/src/builtin_widgets/global_anchor.rs
@@ -86,6 +86,7 @@ impl FatObj {
/// Anchor the widget's horizontal position by placing its left edge right to
/// the left edge of the specified widget (`wid`) with the given relative
/// pixel value (`relative`).
+ // Todo: Should we control the subscription in the inner part?
pub fn left_align_to(
&mut self, wid: &LazyWidgetId, offset: f32, ctx: &BuildCtx,
) -> impl Subscription {
diff --git a/core/src/builtin_widgets/theme.rs b/core/src/builtin_widgets/theme.rs
index 92eb32e34..427fef76a 100644
--- a/core/src/builtin_widgets/theme.rs
+++ b/core/src/builtin_widgets/theme.rs
@@ -39,7 +39,7 @@ pub enum Brightness {
///
/// Every descendant widget of the theme can query it or its parts.
///
-/// ```
+/// ```no_run
/// use ribir::prelude::*;
///
/// let w = fn_widget! {
diff --git a/core/src/context/widget_ctx.rs b/core/src/context/widget_ctx.rs
index 872427b1d..b07e608a7 100644
--- a/core/src/context/widget_ctx.rs
+++ b/core/src/context/widget_ctx.rs
@@ -16,6 +16,10 @@ pub trait WidgetCtx {
fn widget_id(&self) -> WidgetId;
/// Return parent of widget of this context.
fn parent(&self) -> Option;
+ // Determine if the current widget in the context is an ancestor of `w`.
+ fn ancestor_of(&self, w: WidgetId) -> bool;
+ // Determine if the current widget in the context is an successor of `w`.
+ fn successor_of(&self, w: WidgetId) -> bool;
/// Return parent of widget `w`.
fn widget_parent(&self, w: WidgetId) -> Option;
/// Return the single child of `widget`.
@@ -98,6 +102,12 @@ impl WidgetCtx for T {
#[inline]
fn parent(&self) -> Option { self.id().parent(self.tree()) }
+ #[inline]
+ fn ancestor_of(&self, w: WidgetId) -> bool { self.id().ancestor_of(w, self.tree()) }
+
+ #[inline]
+ fn successor_of(&self, w: WidgetId) -> bool { w.ancestor_of(self.id(), self.tree()) }
+
#[inline]
fn widget_parent(&self, w: WidgetId) -> Option { w.parent(self.tree()) }
diff --git a/core/src/lib.rs b/core/src/lib.rs
index ee6d1f938..38455206a 100644
--- a/core/src/lib.rs
+++ b/core/src/lib.rs
@@ -46,7 +46,7 @@ pub mod prelude {
#[doc(no_inline)]
pub use crate::events::*;
#[doc(no_inline)]
- pub use crate::overlay::{Overlay, OverlayCloseHandle};
+ pub use crate::overlay::Overlay;
#[doc(no_inline)]
pub use crate::pipe::{BoxPipe, FinalChain, MapPipe, ModifiesPipe, Pipe};
#[doc(no_inline)]
diff --git a/core/src/overlay.rs b/core/src/overlay.rs
index bbf3cffb4..4da6cf3ea 100644
--- a/core/src/overlay.rs
+++ b/core/src/overlay.rs
@@ -1,132 +1,106 @@
-use std::{cell::RefCell, mem::replace, rc::Rc};
+use std::{
+ cell::RefCell,
+ rc::{Rc, Weak},
+};
use ribir_algo::Sc;
use crate::prelude::*;
+/// Overlay let independent the widget "float" visual elements on top of
+/// other widgets by inserting them into the root stack of the widget stack.
+///
+/// ### Example
+///
+/// ```no_run
+/// use ribir::prelude::*;
+///
+/// let w = fn_widget! {
+/// let overlay = Overlay::new(fn_widget! {
+/// @Text {
+/// on_tap: move |e| Overlay::of(&**e).unwrap().close(),
+/// h_align: HAlign::Center,
+/// v_align: VAlign::Center,
+/// text: "Click me to close overlay!"
+/// }
+/// });
+/// @FilledButton{
+/// on_tap: move |e| overlay.show(e.window()),
+/// @{ Label::new("Click me to show overlay") }
+/// }
+/// };
+/// App::run(w);
+/// ```
#[derive(Clone)]
-pub struct OverlayStyle {
- pub close_policy: ClosePolicy,
- pub mask_brush: Option,
-}
+pub struct Overlay(Sc>);
bitflags! {
#[derive(Clone, Copy)]
- pub struct ClosePolicy: u8 {
+ pub struct AutoClosePolicy: u8 {
const NONE = 0b0000;
const ESC = 0b0001;
const TAP_OUTSIDE = 0b0010;
}
}
-impl CustomStyle for OverlayStyle {
- fn default_style(_: &impl ProviderCtx) -> Self {
- Self {
- close_policy: ClosePolicy::ESC | ClosePolicy::TAP_OUTSIDE,
- mask_brush: Some(Color::from_f32_rgba(0.3, 0.3, 0.3, 0.3).into()),
- }
- }
+struct InnerOverlay {
+ gen: GenWidget,
+ auto_close_policy: AutoClosePolicy,
+ mask: Option,
+ showing: Option,
}
-/// A handle to close the overlay
-#[derive(Clone)]
-pub struct OverlayCloseHandle(OverlayState);
-impl OverlayCloseHandle {
- pub fn close(&self) { self.0.close() }
+struct ShowingInfo {
+ id: WidgetId,
+ wnd: Weak,
+ generator: GenWidget,
}
-type Builder = Box Widget<'static>>;
-struct OverlayData {
- builder: Builder,
- style: Option,
- state: OverlayState,
-}
-
-// Todo:
-// 1. The overlay should be regenerated if the window theme changes.
-// 2. We don't need to use `new_with_handle`; we can utilize the provider to
-// query the overlay to which the current widget belongs.
-
-#[derive(Clone)]
-pub struct Overlay(Sc>);
-
impl Overlay {
- /// Create overlay from Clone able widget.
- ///
- /// ### Example
- /// ``` no_run
- /// use ribir::prelude::*;
- /// let w = fn_widget! {
- /// let overlay = Overlay::new(
- /// fn_widget! {
- /// @Text {
- /// h_align: HAlign::Center,
- /// v_align: VAlign::Center,
- /// text: "Hello"
- /// }
- /// }
- /// );
- /// @FilledButton{
- /// on_tap: move |e| overlay.show(e.window()),
- /// @{ Label::new("Click to show overlay") }
- /// }
- /// };
- /// App::run(w);
- /// ```
+ /// Create overlay from a function widget that may call many times.
pub fn new(gen: impl Into) -> Self {
let gen = gen.into();
- Self::inner_new(Box::new(move |_| gen.gen_widget()))
+ Self(Sc::new(RefCell::new(InnerOverlay {
+ gen,
+ auto_close_policy: AutoClosePolicy::ESC | AutoClosePolicy::TAP_OUTSIDE,
+ mask: None,
+ showing: None,
+ })))
}
- /// Create overlay from a builder with a close_handle
- ///
- /// ### Example
- /// popup a widget of a button which will close when clicked.
- /// ``` no_run
- /// use ribir::prelude::*;
- /// let w = fn_widget! {
- /// let overlay = Overlay::new_with_handle(
- /// move |ctrl: OverlayCloseHandle| {
- /// let ctrl = ctrl.clone();
- /// fn_widget! {
- /// @FilledButton {
- /// h_align: HAlign::Center,
- /// v_align: VAlign::Center,
- /// on_tap: move |_| ctrl.close(),
- /// @{ Label::new("Click to close") }
- /// }
- /// }.into_widget()
- /// }
- /// );
- /// @FilledButton {
- /// on_tap: move |e| overlay.show(e.window()),
- /// @{ Label::new("Click to show overlay") }
- /// }
- /// };
- ///
- /// App::run(w).with_size(Size::new(200., 200.));
- /// ```
- pub fn new_with_handle(
- builder: impl FnMut(OverlayCloseHandle) -> Widget<'static> + 'static,
- ) -> Self {
- Self::inner_new(Box::new(builder))
+ /// Return the overlay that the `ctx` belongs to if it is within an overlay.
+ pub fn of(ctx: &impl WidgetCtx) -> Option {
+ let wnd = ctx.window();
+ let tree = wnd.tree();
+ let overlays = tree
+ .root()
+ .query_ref::(tree)
+ .unwrap();
+
+ overlays.showing_of(ctx)
+ }
+
+ /// Set the auto close policy of the overlay.
+ pub fn set_auto_close_policy(&self, policy: AutoClosePolicy) {
+ self.0.borrow_mut().auto_close_policy = policy
}
- /// Overlay will show with the given style, if the overlay have not been set
- /// with style, the default style will be get from the theme.
- pub fn with_style(&self, style: OverlayStyle) { self.0.borrow_mut().style = Some(style); }
+ /// Get the auto close policy of the overlay.
+ pub fn auto_close_policy(&self) -> AutoClosePolicy { self.0.borrow().auto_close_policy }
- /// the Overlay widget will be show at the top level of all widget.
- /// if the overlay is showing, nothing will happen.
+ /// Set the mask for the background of the overlay being used.
+ pub fn set_mask(&self, mask: Brush) { self.0.borrow_mut().mask = Some(mask); }
+
+ /// Get the mask of the the background of the overlay used.
+ pub fn mask(&self) -> Option { self.0.borrow().mask.clone() }
+
+ /// Show the overlay.
pub fn show(&self, wnd: Rc) {
- if self.is_show() {
+ if self.is_showing() {
return;
}
- let mut inner = self.0.borrow_mut();
- let handle = inner.state.close_handle();
- let w = (inner.builder)(handle);
- let style = inner.style.clone();
- inner.state.show(w, style, wnd);
+ let gen = self.0.borrow().gen.clone();
+ self.inner_show(gen, wnd);
}
/// User can make transform before the widget show at the top level of all
@@ -150,16 +124,15 @@ impl Overlay {
/// v_align: VAlign::Center,
/// on_tap: move |e| {
/// let wid = wid.clone();
- /// overlay.show_map(
- /// move |w, _| {
- /// let wid = wid.clone();
- /// fn_widget! {
- /// let mut w = @$w {};
- /// w.left_align_to(&wid, 0., ctx!());
- /// w
- /// }
- /// },
- /// e.window()
+ /// overlay.show_map(move |w| {
+ /// let wid = wid.clone();
+ /// fn_widget! {
+ /// let mut w = @$w {};
+ /// w.left_align_to(&wid, 0., ctx!());
+ /// w
+ /// }.into_widget()
+ /// },
+ /// e.window()
/// );
/// },
/// @{ Label::new("Click to show overlay") }
@@ -167,152 +140,141 @@ impl Overlay {
/// };
/// App::run(w);
/// ```
- pub fn show_map(&self, f: F, wnd: Rc)
+ pub fn show_map(&self, mut f: F, wnd: Rc)
where
- F: FnOnce(Widget<'static>, OverlayCloseHandle) -> O + 'static,
- O: IntoWidget<'static, FN> + 'static,
+ F: FnMut(Widget<'static>) -> Widget + 'static,
{
- if self.is_show() {
+ if self.is_showing() {
return;
}
-
- let mut inner = self.0.borrow_mut();
- let close_handle = inner.state.close_handle();
- let overlay = (inner.builder)(close_handle.clone());
- let overlay = f(overlay, close_handle);
- let style = inner.style.clone();
- inner
- .state
- .show(overlay.into_widget(), style, wnd);
+ let gen = self.0.borrow().gen.clone();
+ let gen = move |_: &mut BuildCtx| f(gen.gen_widget());
+ self.inner_show(gen.into(), wnd);
}
/// Show the widget at the give position.
/// if the overlay is showing, nothing will happen.
pub fn show_at(&self, pos: Point, wnd: Rc) {
- if self.is_show() {
+ if self.is_showing() {
return;
}
self.show_map(
- move |w, _| {
+ move |w| {
fn_widget! {
@$w { anchor: Anchor::from_point(pos) }
}
+ .into_widget()
},
wnd,
);
}
- /// return whether the overlay is show.
- pub fn is_show(&self) -> bool { self.0.borrow().state.is_show() }
+ /// return whether the overlay is showing.
+ pub fn is_showing(&self) -> bool { self.0.borrow().showing.is_some() }
- /// remove the showing overlay.
- pub fn close(&self) { self.0.borrow().state.close() }
+ /// Close the overlay; all widgets within the overlay will be removed.
+ pub fn close(&self) {
+ let showing = self.0.borrow_mut().showing.take();
+ if let Some(showing) = showing {
+ let ShowingInfo { id, wnd, .. } = showing;
+ if let Some(wnd) = wnd.upgrade() {
+ let ctx = BuildCtx::create(wnd.tree().root(), wnd.tree);
+ let showing_overlays = Provider::of::(&*ctx).unwrap();
+ showing_overlays.remove(self);
- fn inner_new(builder: Builder) -> Self {
- Self(Sc::new(RefCell::new(OverlayData {
- builder,
- style: None,
- state: OverlayState::default(),
- })))
- }
-}
-
-enum OverlayInnerState {
- ToShow(Instant, Rc),
- Showing(WidgetId, Rc),
- Hided,
-}
-
-#[derive(Clone)]
-struct OverlayState(Rc>);
-impl Default for OverlayState {
- fn default() -> Self { OverlayState(Rc::new(RefCell::new(OverlayInnerState::Hided))) }
-}
-
-impl OverlayState {
- fn close(&self) {
- let state = replace(&mut *self.0.borrow_mut(), OverlayInnerState::Hided);
- if let OverlayInnerState::Showing(wid, wnd) = state {
- let _ = AppCtx::spawn_local(async move {
let tree = wnd.tree_mut();
let root = tree.root();
- wid.dispose_subtree(tree);
+ id.dispose_subtree(tree);
tree.mark_dirty(root);
- });
+ }
}
}
- fn is_show(&self) -> bool { !matches!(*self.0.borrow(), OverlayInnerState::Hided) }
-
- fn show(&self, w: Widget<'static>, style: Option, wnd: Rc) {
- if self.is_show() {
- return;
- }
- let this = self.clone();
- let instant = Instant::now();
- *this.0.borrow_mut() = OverlayInnerState::ToShow(instant, wnd);
- let _ = AppCtx::spawn_local(async move {
- let wnd = match (instant, &*this.0.borrow()) {
- (instant, OverlayInnerState::ToShow(crate_at, wnd)) if &instant == crate_at => wnd.clone(),
- _ => return,
- };
- let mut build_ctx = BuildCtx::create(wnd.tree().root(), wnd.tree);
- let style = style.unwrap_or_else(|| OverlayStyle::of(build_ctx.deref()));
- let wid = this
- .wrap_style(w, style)
- .into_widget()
- .build(&mut build_ctx);
- *this.0.borrow_mut() = OverlayInnerState::Showing(wid, wnd.clone());
- let tree = wnd.tree_mut();
- tree.root().append(wid, tree);
- wid.on_mounted_subtree(tree);
- tree.mark_dirty(wid);
- });
- }
-
- fn wrap_style(&self, w: Widget<'static>, style: OverlayStyle) -> impl IntoWidget<'static, FN> {
- let this = self.clone();
- fn_widget! {
- let OverlayStyle { close_policy, mask_brush } = style;
- let this2 = this.clone();
+ fn inner_show(&self, content: GenWidget, wnd: Rc) {
+ let background = self.mask();
+ let gen = fn_widget! {
@Container {
size: Size::new(f32::INFINITY, f32::INFINITY),
- background: mask_brush.unwrap_or_else(|| Color::from_u32(0).into()),
+ background: background.clone(),
on_tap: move |e| {
- if close_policy.contains(ClosePolicy::TAP_OUTSIDE)
- && e.target() == e.current_target() {
- this.close();
+ if e.target() == e.current_target() {
+ if let Some(overlay) = Overlay::of(&**e)
+ .filter(|o| o.auto_close_policy().contains(AutoClosePolicy::TAP_OUTSIDE))
+ {
+ overlay.close();
+ }
}
},
on_key_down: move |e| {
- if close_policy.contains(ClosePolicy::ESC)
- && *e.key() == VirtualKey::Named(NamedKey::Escape) {
- this2.close();
+ if *e.key() == VirtualKey::Named(NamedKey::Escape) {
+ if let Some(overlay) = Overlay::of(&**e)
+ .filter(|o| o.auto_close_policy().contains(AutoClosePolicy::ESC))
+ {
+ overlay.close();
+ }
}
},
- @ { w }
+ @ { content.gen_widget() }
}
- }
+ };
+
+ let mut ctx = BuildCtx::create(wnd.tree().root(), wnd.tree);
+ let id = gen(&mut ctx).build(&mut ctx);
+ self.0.borrow_mut().showing =
+ Some(ShowingInfo { id, generator: gen.into(), wnd: Rc::downgrade(&wnd) });
+
+ let showing_overlays = Provider::of::(&*ctx).unwrap();
+ showing_overlays.add(self.clone());
+
+ let tree = wnd.tree_mut();
+ tree.root().append(id, tree);
+ id.on_mounted_subtree(tree);
+ tree.mark_dirty(id);
}
- fn close_handle(&self) -> OverlayCloseHandle { OverlayCloseHandle(self.clone()) }
+ fn showing_root(&self) -> Option { self.0.borrow().showing.as_ref().map(|s| s.id) }
}
-pub(crate) struct OverlayRoot {}
+pub(crate) struct ShowingOverlays(RefCell>);
+
+impl ShowingOverlays {
+ pub(crate) fn rebuild(&self, ctx: &mut BuildCtx) {
+ for o in self.0.borrow().iter() {
+ let mut o = o.0.borrow_mut();
+ let ShowingInfo { id, generator, .. } = o.showing.as_mut().unwrap();
-impl Render for OverlayRoot {
- fn perform_layout(&self, clamp: BoxClamp, ctx: &mut LayoutCtx) -> Size {
- let mut size = ZERO_SIZE;
- let mut layouter = ctx.first_child_layouter();
- while let Some(mut l) = layouter {
- let child_size = l.perform_widget_layout(clamp);
- size = size.max(child_size);
- layouter = l.into_next_sibling();
+ id.dispose_subtree(ctx.tree_mut());
+ *id = generator.gen_widget().build(ctx);
+ let tree = ctx.tree_mut();
+ tree.root().append(*id, tree);
+ id.on_mounted_subtree(tree);
}
- size
}
- fn paint(&self, _: &mut PaintingCtx) {}
+ fn add(&self, overlay: Overlay) {
+ assert!(overlay.showing_root().is_some());
+ self.0.borrow_mut().push(overlay)
+ }
+
+ fn remove(&self, overlay: &Overlay) {
+ assert!(overlay.showing_root().is_none());
+ self
+ .0
+ .borrow_mut()
+ .retain(|o| !Sc::ptr_eq(&o.0, &overlay.0))
+ }
+
+ fn showing_of(&self, ctx: &impl WidgetCtx) -> Option {
+ self.0.borrow().iter().find_map(|o| {
+ o.showing_root()
+ .map_or(false, |w| ctx.successor_of(w))
+ .then(|| o.clone())
+ })
+ }
+}
+
+impl Default for ShowingOverlays {
+ fn default() -> Self { Self(RefCell::new(vec![])) }
}
#[cfg(test)]
@@ -356,13 +318,11 @@ mod tests {
let root = wnd.tree().root();
assert_eq!(wnd.tree().count(root), 3);
- overlay.show(wnd.0.clone());
- overlay.close();
overlay.show_at(Point::new(50., 30.), wnd.0.clone());
wnd.draw_frame();
assert_eq!(*r_log.borrow(), &["mounted"]);
// the path [1, 0, 0, 0] is from root to anchor,
- // OverlayRoot -> BoxDecoration-> Container -> Anchor
+ // Root -> BoxDecoration-> Container -> Anchor
assert_layout_result_by_path!(wnd, {path = [1, 0, 0, 0], x == 50., y == 30.,});
overlay.close();
diff --git a/core/src/widget.rs b/core/src/widget.rs
index 42b15e67e..08b516dd9 100644
--- a/core/src/widget.rs
+++ b/core/src/widget.rs
@@ -96,6 +96,7 @@ impl<'w> LazyNode<'w> {
/// A boxed function widget that can be called multiple times to regenerate
/// widget.
+#[derive(Clone)]
pub struct GenWidget(InnerGenWidget);
type InnerGenWidget = Sc Widget<'static>>>>;
diff --git a/core/src/widget_tree.rs b/core/src/widget_tree.rs
index 8f6cfcd38..6ffb4f237 100644
--- a/core/src/widget_tree.rs
+++ b/core/src/widget_tree.rs
@@ -14,7 +14,7 @@ mod layout_info;
pub use layout_info::*;
use self::widget::widget_id::new_node;
-use crate::{overlay::OverlayRoot, prelude::*, render_helper::PureRender};
+use crate::{overlay::ShowingOverlays, prelude::*, render_helper::PureRender};
pub(crate) type DirtySet = Rc>>;
@@ -36,16 +36,15 @@ impl WidgetTree {
ctx.pre_alloc = Some(root_id);
let theme = AppCtx::app_theme().clone_writer();
- let overlays = Queryable(Overlays::default());
+ let overlays = Queryable(ShowingOverlays::default());
let id = Provider::new(Box::new(overlays))
.with_child(fn_widget! {
theme.with_child(fn_widget!{
+ let ctx = unsafe { &*(ctx!() as *mut BuildCtx) };
+ let overlays = Provider::of::(ctx).unwrap();
+ overlays.rebuild(ctx!());
@Root {
@{ content.gen_widget() }
- @{
- let overlays = Provider::of::(ctx!()).unwrap();
- overlays.rebuild()
- }
}
})
})
@@ -93,6 +92,7 @@ impl WidgetTree {
}
}
+ // todo: split layout and paint dirty.
pub(crate) fn mark_dirty(&self, id: WidgetId) { self.dirty_set.borrow_mut().insert(id); }
pub(crate) fn is_dirty(&self) -> bool { !self.dirty_set.borrow().is_empty() }
@@ -226,7 +226,7 @@ impl Default for WidgetTree {
let mut arena = TreeArena::new();
Self {
- root: new_node(&mut arena, Box::new(PureRender(OverlayRoot {}))),
+ root: new_node(&mut arena, Box::new(PureRender(Void))),
wnd: Weak::new(),
arena,
store: LayoutStore::default(),
@@ -254,19 +254,6 @@ impl Render for Root {
fn paint(&self, _: &mut PaintingCtx) {}
}
-pub(crate) struct Overlays(Stateful>);
-
-impl Overlays {
- fn rebuild(&self) -> Vec> {
- // todo: drop the old overlay subtree, create a new one for new theme
- vec![]
- }
-}
-
-impl Default for Overlays {
- fn default() -> Self { Self(Stateful::new(vec![])) }
-}
-
#[cfg(test)]
mod tests {
use super::*;
diff --git a/ribir/src/app.rs b/ribir/src/app.rs
index e5cb97bfd..462f71a72 100644
--- a/ribir/src/app.rs
+++ b/ribir/src/app.rs
@@ -145,6 +145,10 @@ impl App {
}
}
wnd.emit_events();
+
+ if wnd.need_draw() {
+ request_redraw(&wnd)
+ }
}
Event::AboutToWait => {
let run_count = AppCtx::run_until_stalled();