added Iterator
This commit is contained in:
@@ -78,6 +78,12 @@ impl Element for FlexRow {
|
||||
element.inject(|w| w.component(NoRenderRoot));
|
||||
}
|
||||
|
||||
fn undraw_child(&mut self, element: &Arc<Widget>) {
|
||||
if let Some(i) = self.children.iter().position(|v| Arc::ptr_eq(v, element)) {
|
||||
self.children.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
fn is_ghost(&mut self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
+65
-1
@@ -25,6 +25,12 @@ pub enum RsxElement {
|
||||
Vec<Box<dyn DependencyHandler>>,
|
||||
Rsx,
|
||||
),
|
||||
|
||||
/// A dynamic iteration of widgets, keeping track of their state.
|
||||
Iter(
|
||||
Box<dyn FnMut() -> Rsx + Send + Sync>,
|
||||
Box<dyn DependencyHandler>,
|
||||
),
|
||||
}
|
||||
|
||||
/// A container representing a group of RSX elements.
|
||||
@@ -42,7 +48,13 @@ impl Rsx {
|
||||
/// Recursively draws the RSX tree with an optional parent widget.
|
||||
///
|
||||
/// Used internally to establish parent-child widget relationships.
|
||||
pub fn draw_parent(self, screen: &Arc<Screen>, parent: Option<Arc<Widget>>) {
|
||||
pub fn draw_parent(
|
||||
self,
|
||||
screen: &Arc<Screen>,
|
||||
parent: Option<Arc<Widget>>,
|
||||
) -> Option<Arc<Widget>> {
|
||||
let mut first_widget = None;
|
||||
|
||||
for rsx_elem in self.0 {
|
||||
match rsx_elem {
|
||||
RsxElement::DynElement(f, dep, child) => {
|
||||
@@ -57,6 +69,9 @@ impl Rsx {
|
||||
}
|
||||
|
||||
child.draw_parent(screen, Some(w.clone()));
|
||||
if first_widget.is_none() {
|
||||
first_widget = Some(w)
|
||||
}
|
||||
}
|
||||
|
||||
RsxElement::Element(ws, child) => {
|
||||
@@ -68,9 +83,49 @@ impl Rsx {
|
||||
}
|
||||
|
||||
child.draw_parent(screen, Some(w.clone()));
|
||||
if first_widget.is_none() {
|
||||
first_widget = Some(w)
|
||||
}
|
||||
}
|
||||
|
||||
RsxElement::Iter(mut rsx, dep) => {
|
||||
#[allow(unused)]
|
||||
let mut rsx_len = 0;
|
||||
let mut fw = {
|
||||
let r = rsx();
|
||||
rsx_len = r.0.len();
|
||||
r.draw_parent(screen, parent.clone())
|
||||
};
|
||||
let parent = parent.clone();
|
||||
let s = screen.clone();
|
||||
|
||||
screen.add_dependency(vec![dep], move || {
|
||||
if let Some(fww) = &fw {
|
||||
{
|
||||
let mut widgets = s.widgets.lock().unwrap();
|
||||
if let Some(i) = widgets.iter().position(|v| Arc::ptr_eq(v, fww)) {
|
||||
for v in (i..(i + rsx_len)).rev() {
|
||||
if let Some(w) = widgets.get(v) {
|
||||
if let Some(p) = &parent {
|
||||
p.get_elem().undraw_child(w);
|
||||
}
|
||||
widgets.remove(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fw = {
|
||||
let r = rsx();
|
||||
rsx_len = r.0.len();
|
||||
r.draw_parent(&s, parent.clone())
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
first_widget
|
||||
}
|
||||
|
||||
/// Adds a dynamically constructed element to the RSX tree.
|
||||
@@ -96,6 +151,15 @@ impl Rsx {
|
||||
self.0.push(RsxElement::Element(element, children));
|
||||
}
|
||||
|
||||
/// Adds a statically defined element to the RSX tree with its children.
|
||||
pub fn iter<F: FnMut() -> Rsx + Send + Sync + 'static>(
|
||||
&mut self,
|
||||
rsx: F,
|
||||
dependency: Box<dyn DependencyHandler>,
|
||||
) {
|
||||
self.0.push(RsxElement::Iter(Box::new(rsx), dependency));
|
||||
}
|
||||
|
||||
/// Appends the elements from another `Rsx` tree into this one.
|
||||
pub fn expand(&mut self, other: &mut Rsx) {
|
||||
self.0.append(&mut other.0);
|
||||
|
||||
+34
@@ -35,6 +35,7 @@ use crate::{
|
||||
extensions::Extension,
|
||||
prelude::{Context, ElementRenderer},
|
||||
render_scope::RenderScope,
|
||||
state::DependencyHandler,
|
||||
widget::{BoxedElement, DynWidget, Element, StaticWidget, Widget, WidgetLoad},
|
||||
};
|
||||
|
||||
@@ -78,6 +79,13 @@ pub struct Screen {
|
||||
extensions: Mutex<Vec<Arc<Mutex<Box<dyn Extension + Send + Sync>>>>>,
|
||||
/// If it's still running
|
||||
running: Mutex<bool>,
|
||||
/// If it's still running
|
||||
dependencies: Mutex<
|
||||
Vec<(
|
||||
Vec<Box<dyn DependencyHandler>>,
|
||||
Box<dyn FnMut() + Send + Sync>,
|
||||
)>,
|
||||
>,
|
||||
}
|
||||
|
||||
event!(RenderWrapperEvent(*mut RenderScope));
|
||||
@@ -104,6 +112,7 @@ impl Screen {
|
||||
widgets: Mutex::new(Vec::new()),
|
||||
extensions: Mutex::new(Vec::new()),
|
||||
running: Mutex::new(true),
|
||||
dependencies: Mutex::new(Vec::new()),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -194,6 +203,14 @@ impl Screen {
|
||||
|
||||
scope.render_widget(&mut renderer, ctx, widget);
|
||||
}
|
||||
for d in self.dependencies.lock().unwrap().iter_mut() {
|
||||
for dh in &d.0 {
|
||||
if dh.check() {
|
||||
(d.1)();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -208,6 +225,23 @@ impl Screen {
|
||||
}
|
||||
}
|
||||
|
||||
impl Screen {
|
||||
pub fn add_dependency<F: FnMut() + Send + Sync + 'static>(
|
||||
self: &Arc<Self>,
|
||||
dependencies: Vec<Box<dyn DependencyHandler>>,
|
||||
handler: F,
|
||||
) {
|
||||
for d in &dependencies {
|
||||
d.add();
|
||||
}
|
||||
|
||||
self.dependencies
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push((dependencies, Box::new(handler)));
|
||||
}
|
||||
}
|
||||
|
||||
struct ScreenRenderer;
|
||||
|
||||
impl ElementRenderer for ScreenRenderer {}
|
||||
|
||||
@@ -51,6 +51,10 @@ pub trait Element: Send + Sync {
|
||||
#[allow(unused)]
|
||||
fn draw_child(&mut self, element: &Arc<Widget>) {}
|
||||
|
||||
/// Called to undraw child widgets, if any.
|
||||
#[allow(unused)]
|
||||
fn undraw_child(&mut self, element: &Arc<Widget>) {}
|
||||
|
||||
#[allow(unused)]
|
||||
fn event(&mut self, event: &dyn Event) {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user