Use nested for lazy widgets
This commit is contained in:
parent
4de6ee6fa1
commit
b0205e03d8
7 changed files with 77 additions and 49 deletions
|
|
@ -47,6 +47,7 @@ pub mod clipboard;
|
|||
pub mod command;
|
||||
pub mod font;
|
||||
pub mod keyboard;
|
||||
pub mod overlay;
|
||||
pub mod program;
|
||||
pub mod system;
|
||||
pub mod user_interface;
|
||||
|
|
|
|||
4
runtime/src/overlay.rs
Normal file
4
runtime/src/overlay.rs
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
//! Overlays for user interfaces.
|
||||
mod nested;
|
||||
|
||||
pub use nested::Nested;
|
||||
|
|
@ -21,6 +21,12 @@ where
|
|||
Self { overlay: element }
|
||||
}
|
||||
|
||||
/// Returns the position of the [`Nested`] overlay.
|
||||
pub fn position(&self) -> Point {
|
||||
self.overlay.position()
|
||||
}
|
||||
|
||||
/// Returns the layout [`Node`] of the [`Nested`] overlay.
|
||||
pub fn layout(
|
||||
&mut self,
|
||||
renderer: &Renderer,
|
||||
|
|
@ -36,7 +42,7 @@ where
|
|||
where
|
||||
Renderer: renderer::Renderer,
|
||||
{
|
||||
let translation = position - Point::ORIGIN;
|
||||
let translation = position - element.position();
|
||||
|
||||
let node = element.layout(renderer, bounds, translation);
|
||||
|
||||
|
|
@ -58,6 +64,7 @@ where
|
|||
recurse(&mut self.overlay, renderer, bounds, position)
|
||||
}
|
||||
|
||||
/// Draws the [`Nested`] overlay using the associated `Renderer`.
|
||||
pub fn draw(
|
||||
&mut self,
|
||||
renderer: &mut Renderer,
|
||||
|
|
@ -127,6 +134,7 @@ where
|
|||
recurse(&mut self.overlay, layout, renderer, theme, style, cursor);
|
||||
}
|
||||
|
||||
/// Applies a [`widget::Operation`] to the [`Nested`] overlay.
|
||||
pub fn operate(
|
||||
&mut self,
|
||||
layout: Layout<'_>,
|
||||
|
|
@ -157,6 +165,7 @@ where
|
|||
recurse(&mut self.overlay, layout, renderer, operation)
|
||||
}
|
||||
|
||||
/// Processes a runtime [`Event`].
|
||||
pub fn on_event(
|
||||
&mut self,
|
||||
event: Event,
|
||||
|
|
@ -247,6 +256,7 @@ where
|
|||
status
|
||||
}
|
||||
|
||||
/// Returns the current [`mouse::Interaction`] of the [`Nested`] overlay.
|
||||
pub fn mouse_interaction(
|
||||
&mut self,
|
||||
layout: Layout<'_>,
|
||||
|
|
@ -298,6 +308,7 @@ where
|
|||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Returns true if the cursor is over the [`Nested`] overlay.
|
||||
pub fn is_over(
|
||||
&mut self,
|
||||
layout: Layout<'_>,
|
||||
|
|
@ -1,14 +1,12 @@
|
|||
//! Implement your own event loop to drive a user interface.
|
||||
mod overlay;
|
||||
|
||||
use crate::core::event::{self, Event};
|
||||
use crate::core::layout;
|
||||
use crate::core::mouse;
|
||||
use crate::core::renderer;
|
||||
use crate::core::widget;
|
||||
use crate::core::window;
|
||||
use crate::core::{Clipboard, Point, Rectangle, Size};
|
||||
use crate::core::{Element, Layout, Shell};
|
||||
use crate::core::{Clipboard, Element, Layout, Point, Rectangle, Shell, Size};
|
||||
use crate::overlay;
|
||||
|
||||
/// A set of interactive graphical elements with a specific [`Layout`].
|
||||
///
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ use crate::core::Element;
|
|||
use crate::core::{
|
||||
self, Clipboard, Hasher, Length, Point, Rectangle, Shell, Size,
|
||||
};
|
||||
use crate::runtime::overlay::Nested;
|
||||
|
||||
use ouroboros::self_referencing;
|
||||
use std::cell::RefCell;
|
||||
|
|
@ -260,14 +261,17 @@ where
|
|||
.unwrap(),
|
||||
tree: &mut tree.children[0],
|
||||
overlay_builder: |element, tree| {
|
||||
element.as_widget_mut().overlay(tree, layout, renderer)
|
||||
element
|
||||
.as_widget_mut()
|
||||
.overlay(tree, layout, renderer)
|
||||
.map(|overlay| RefCell::new(Nested::new(overlay)))
|
||||
},
|
||||
}
|
||||
.build(),
|
||||
));
|
||||
|
||||
let has_overlay = overlay
|
||||
.with_overlay_maybe(|overlay| overlay::Element::position(overlay));
|
||||
let has_overlay =
|
||||
overlay.with_overlay_maybe(|overlay| overlay.position());
|
||||
|
||||
has_overlay
|
||||
.map(|position| overlay::Element::new(position, Box::new(overlay)))
|
||||
|
|
@ -285,8 +289,8 @@ where
|
|||
tree: &'a mut Tree,
|
||||
|
||||
#[borrows(mut element, mut tree)]
|
||||
#[covariant]
|
||||
overlay: Option<overlay::Element<'this, Message, Renderer>>,
|
||||
#[not_covariant]
|
||||
overlay: Option<RefCell<Nested<'this, Message, Renderer>>>,
|
||||
}
|
||||
|
||||
struct Overlay<'a, Message, Renderer>(Option<Inner<'a, Message, Renderer>>);
|
||||
|
|
@ -301,19 +305,20 @@ impl<'a, Message, Renderer> Drop for Overlay<'a, Message, Renderer> {
|
|||
impl<'a, Message, Renderer> Overlay<'a, Message, Renderer> {
|
||||
fn with_overlay_maybe<T>(
|
||||
&self,
|
||||
f: impl FnOnce(&overlay::Element<'_, Message, Renderer>) -> T,
|
||||
f: impl FnOnce(&mut Nested<'_, Message, Renderer>) -> T,
|
||||
) -> Option<T> {
|
||||
self.0.as_ref().unwrap().borrow_overlay().as_ref().map(f)
|
||||
self.0.as_ref().unwrap().with_overlay(|overlay| {
|
||||
overlay.as_ref().map(|nested| (f)(&mut nested.borrow_mut()))
|
||||
})
|
||||
}
|
||||
|
||||
fn with_overlay_mut_maybe<T>(
|
||||
&mut self,
|
||||
f: impl FnOnce(&mut overlay::Element<'_, Message, Renderer>) -> T,
|
||||
f: impl FnOnce(&mut Nested<'_, Message, Renderer>) -> T,
|
||||
) -> Option<T> {
|
||||
self.0
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.with_overlay_mut(|overlay| overlay.as_mut().map(f))
|
||||
self.0.as_mut().unwrap().with_overlay_mut(|overlay| {
|
||||
overlay.as_mut().map(|nested| (f)(nested.get_mut()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -329,9 +334,7 @@ where
|
|||
position: Point,
|
||||
) -> layout::Node {
|
||||
self.with_overlay_maybe(|overlay| {
|
||||
let translation = position - overlay.position();
|
||||
|
||||
overlay.layout(renderer, bounds, translation)
|
||||
overlay.layout(renderer, bounds, position)
|
||||
})
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use crate::core::widget::tree::{self, Tree};
|
|||
use crate::core::{
|
||||
self, Clipboard, Element, Length, Point, Rectangle, Shell, Size, Widget,
|
||||
};
|
||||
use crate::runtime::overlay::Nested;
|
||||
|
||||
use ouroboros::self_referencing;
|
||||
use std::cell::RefCell;
|
||||
|
|
@ -455,11 +456,18 @@ where
|
|||
overlay_builder: |instance, tree| {
|
||||
instance.state.get_mut().as_mut().unwrap().with_element_mut(
|
||||
move |element| {
|
||||
element.as_mut().unwrap().as_widget_mut().overlay(
|
||||
&mut tree.children[0],
|
||||
layout,
|
||||
renderer,
|
||||
)
|
||||
element
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.as_widget_mut()
|
||||
.overlay(
|
||||
&mut tree.children[0],
|
||||
layout,
|
||||
renderer,
|
||||
)
|
||||
.map(|overlay| {
|
||||
RefCell::new(Nested::new(overlay))
|
||||
})
|
||||
},
|
||||
)
|
||||
},
|
||||
|
|
@ -468,7 +476,7 @@ where
|
|||
));
|
||||
|
||||
let has_overlay = overlay.0.as_ref().unwrap().with_overlay(|overlay| {
|
||||
overlay.as_ref().map(overlay::Element::position)
|
||||
overlay.as_ref().map(|nested| nested.borrow().position())
|
||||
});
|
||||
|
||||
has_overlay.map(|position| {
|
||||
|
|
@ -503,8 +511,8 @@ struct Inner<'a, 'b, Message, Renderer, Event, S> {
|
|||
types: PhantomData<(Message, Event, S)>,
|
||||
|
||||
#[borrows(mut instance, mut tree)]
|
||||
#[covariant]
|
||||
overlay: Option<overlay::Element<'this, Event, Renderer>>,
|
||||
#[not_covariant]
|
||||
overlay: Option<RefCell<Nested<'this, Event, Renderer>>>,
|
||||
}
|
||||
|
||||
struct OverlayInstance<'a, 'b, Message, Renderer, Event, S> {
|
||||
|
|
@ -516,7 +524,7 @@ impl<'a, 'b, Message, Renderer, Event, S>
|
|||
{
|
||||
fn with_overlay_maybe<T>(
|
||||
&self,
|
||||
f: impl FnOnce(&overlay::Element<'_, Event, Renderer>) -> T,
|
||||
f: impl FnOnce(&mut Nested<'_, Event, Renderer>) -> T,
|
||||
) -> Option<T> {
|
||||
self.overlay
|
||||
.as_ref()
|
||||
|
|
@ -524,14 +532,14 @@ impl<'a, 'b, Message, Renderer, Event, S>
|
|||
.0
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.borrow_overlay()
|
||||
.as_ref()
|
||||
.map(f)
|
||||
.with_overlay(|overlay| {
|
||||
overlay.as_ref().map(|nested| (f)(&mut nested.borrow_mut()))
|
||||
})
|
||||
}
|
||||
|
||||
fn with_overlay_mut_maybe<T>(
|
||||
&mut self,
|
||||
f: impl FnOnce(&mut overlay::Element<'_, Event, Renderer>) -> T,
|
||||
f: impl FnOnce(&mut Nested<'_, Event, Renderer>) -> T,
|
||||
) -> Option<T> {
|
||||
self.overlay
|
||||
.as_mut()
|
||||
|
|
@ -539,7 +547,9 @@ impl<'a, 'b, Message, Renderer, Event, S>
|
|||
.0
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.with_overlay_mut(|overlay| overlay.as_mut().map(f))
|
||||
.with_overlay_mut(|overlay| {
|
||||
overlay.as_mut().map(|nested| (f)(nested.get_mut()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -556,9 +566,7 @@ where
|
|||
position: Point,
|
||||
) -> layout::Node {
|
||||
self.with_overlay_maybe(|overlay| {
|
||||
let translation = position - overlay.position();
|
||||
|
||||
overlay.layout(renderer, bounds, translation)
|
||||
overlay.layout(renderer, bounds, position)
|
||||
})
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use crate::core::{
|
|||
self, Clipboard, Element, Length, Point, Rectangle, Shell, Size, Widget,
|
||||
};
|
||||
use crate::horizontal_space;
|
||||
use crate::runtime::overlay::Nested;
|
||||
|
||||
use ouroboros::self_referencing;
|
||||
use std::cell::{RefCell, RefMut};
|
||||
|
|
@ -298,13 +299,13 @@ where
|
|||
element
|
||||
.as_widget_mut()
|
||||
.overlay(tree, content_layout, renderer)
|
||||
.map(|overlay| RefCell::new(Nested::new(overlay)))
|
||||
},
|
||||
}
|
||||
.build();
|
||||
|
||||
let has_overlay = overlay.with_overlay(|overlay| {
|
||||
overlay.as_ref().map(overlay::Element::position)
|
||||
});
|
||||
let has_overlay =
|
||||
overlay.with_overlay_maybe(|overlay| overlay.position());
|
||||
|
||||
has_overlay
|
||||
.map(|position| overlay::Element::new(position, Box::new(overlay)))
|
||||
|
|
@ -329,23 +330,27 @@ struct Overlay<'a, 'b, Message, Renderer> {
|
|||
types: PhantomData<Message>,
|
||||
|
||||
#[borrows(mut content, mut tree)]
|
||||
#[covariant]
|
||||
overlay: Option<overlay::Element<'this, Message, Renderer>>,
|
||||
#[not_covariant]
|
||||
overlay: Option<RefCell<Nested<'this, Message, Renderer>>>,
|
||||
}
|
||||
|
||||
impl<'a, 'b, Message, Renderer> Overlay<'a, 'b, Message, Renderer> {
|
||||
fn with_overlay_maybe<T>(
|
||||
&self,
|
||||
f: impl FnOnce(&overlay::Element<'_, Message, Renderer>) -> T,
|
||||
f: impl FnOnce(&mut Nested<'_, Message, Renderer>) -> T,
|
||||
) -> Option<T> {
|
||||
self.borrow_overlay().as_ref().map(f)
|
||||
self.with_overlay(|overlay| {
|
||||
overlay.as_ref().map(|nested| (f)(&mut nested.borrow_mut()))
|
||||
})
|
||||
}
|
||||
|
||||
fn with_overlay_mut_maybe<T>(
|
||||
&mut self,
|
||||
f: impl FnOnce(&mut overlay::Element<'_, Message, Renderer>) -> T,
|
||||
f: impl FnOnce(&mut Nested<'_, Message, Renderer>) -> T,
|
||||
) -> Option<T> {
|
||||
self.with_overlay_mut(|overlay| overlay.as_mut().map(f))
|
||||
self.with_overlay_mut(|overlay| {
|
||||
overlay.as_mut().map(|nested| (f)(nested.get_mut()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -361,9 +366,7 @@ where
|
|||
position: Point,
|
||||
) -> layout::Node {
|
||||
self.with_overlay_maybe(|overlay| {
|
||||
let translation = position - overlay.position();
|
||||
|
||||
overlay.layout(renderer, bounds, translation)
|
||||
overlay.layout(renderer, bounds, position)
|
||||
})
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue