Flex components
This commit is contained in:
@@ -10,7 +10,12 @@ fn App(cx: &Arc<Context>) -> View {
|
|||||||
rsx! {
|
rsx! {
|
||||||
// redraw is important because the effects won't be applied
|
// redraw is important because the effects won't be applied
|
||||||
impl size_auto, center, redraw
|
impl size_auto, center, redraw
|
||||||
Card { content: "Hello World".to_string() }
|
FlexRow {
|
||||||
|
impl size_auto, redraw
|
||||||
|
Card { content: "One".to_string() }
|
||||||
|
impl size_auto, redraw
|
||||||
|
Card { content: "Two".to_string() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.view(&cx)
|
.view(&cx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
use crate::component_prelude::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn FlexRow(cx: &Arc<Context>, children: Rsx) -> View {
|
||||||
|
children.generate_children(&cx);
|
||||||
|
|
||||||
|
Arc::new({
|
||||||
|
let cx = cx.clone();
|
||||||
|
move |ctx| {
|
||||||
|
for (child, view_wrapper) in cx.get_children() {
|
||||||
|
let view = child.get_view();
|
||||||
|
|
||||||
|
if let Some(view_wrapper) = view_wrapper {
|
||||||
|
let mut ctx2 = ctx.clone();
|
||||||
|
|
||||||
|
view_wrapper(&mut ctx2, view);
|
||||||
|
|
||||||
|
ctx.drawing.append(&mut ctx2.drawing);
|
||||||
|
ctx.area.y += ctx2.allocated.height;
|
||||||
|
} else {
|
||||||
|
ctx.draw_view(ctx.area.clone(), view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn FlexColumn(cx: &Arc<Context>, children: Rsx) -> View {
|
||||||
|
children.generate_children(&cx);
|
||||||
|
|
||||||
|
Arc::new({
|
||||||
|
let cx = cx.clone();
|
||||||
|
move |ctx| {
|
||||||
|
for (child, view_wrapper) in cx.get_children() {
|
||||||
|
let view = child.get_view();
|
||||||
|
|
||||||
|
if let Some(view_wrapper) = view_wrapper {
|
||||||
|
let mut ctx2 = ctx.clone();
|
||||||
|
|
||||||
|
view_wrapper(&mut ctx2, view);
|
||||||
|
|
||||||
|
ctx.drawing.append(&mut ctx2.drawing);
|
||||||
|
ctx.area.x += ctx2.allocated.width;
|
||||||
|
} else {
|
||||||
|
ctx.draw_view(ctx.area.clone(), view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
mod flex;
|
||||||
|
|
||||||
|
pub use flex::*;
|
||||||
@@ -15,15 +15,15 @@ use access_cell::AccessCell;
|
|||||||
use crate::{
|
use crate::{
|
||||||
component::EventHandler,
|
component::EventHandler,
|
||||||
engine::{Command, CommandExecutor},
|
engine::{Command, CommandExecutor},
|
||||||
render::DrawContext,
|
|
||||||
hooks::{use_effect, HookDependency},
|
hooks::{use_effect, HookDependency},
|
||||||
View,
|
render::DrawContext,
|
||||||
|
View, ViewWrapper,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{scope::Scope, Component, ComponentImpl};
|
use super::{scope::Scope, Component, ComponentImpl};
|
||||||
|
|
||||||
/// Context represents the runtime state and behavior of a component
|
/// Context represents the runtime state and behavior of a component
|
||||||
///
|
///
|
||||||
/// Each component instance has a Context that holds:
|
/// Each component instance has a Context that holds:
|
||||||
/// - The component implementation
|
/// - The component implementation
|
||||||
/// - The current view (render result)
|
/// - The current view (render result)
|
||||||
@@ -58,7 +58,7 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Refreshes the component by re-rendering it
|
/// Refreshes the component by re-rendering it
|
||||||
///
|
///
|
||||||
/// Clears event handlers and calls the component to produce a new view.
|
/// Clears event handlers and calls the component to produce a new view.
|
||||||
pub fn refresh(self: &Arc<Self>) {
|
pub fn refresh(self: &Arc<Self>) {
|
||||||
self.event_handlers
|
self.event_handlers
|
||||||
@@ -76,7 +76,7 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Synchronously refreshes the component
|
/// Synchronously refreshes the component
|
||||||
///
|
///
|
||||||
/// Blocks until the component has finished rendering.
|
/// Blocks until the component has finished rendering.
|
||||||
pub fn refresh_sync(self: &Arc<Self>) {
|
pub fn refresh_sync(self: &Arc<Self>) {
|
||||||
let (tx, rx) = std::sync::mpsc::channel::<()>();
|
let (tx, rx) = std::sync::mpsc::channel::<()>();
|
||||||
@@ -110,7 +110,7 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Registers an event handler for events of type T
|
/// Registers an event handler for events of type T
|
||||||
///
|
///
|
||||||
/// When an event of type T is emitted, the handler is called with
|
/// When an event of type T is emitted, the handler is called with
|
||||||
/// the context and a reference to the event.
|
/// the context and a reference to the event.
|
||||||
pub fn on_event<T: Any + 'static, F: Fn(&Arc<Self>, &T) + Send + Sync + 'static>(
|
pub fn on_event<T: Any + 'static, F: Fn(&Arc<Self>, &T) + Send + Sync + 'static>(
|
||||||
@@ -132,7 +132,7 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Emits an event to this component and all descendants
|
/// Emits an event to this component and all descendants
|
||||||
///
|
///
|
||||||
/// Calls all registered handlers for this event type,
|
/// Calls all registered handlers for this event type,
|
||||||
/// then propagates the event to child components.
|
/// then propagates the event to child components.
|
||||||
pub fn emit_event<E: Send + Sync + Any + 'static>(self: &Arc<Self>, event: E) {
|
pub fn emit_event<E: Send + Sync + Any + 'static>(self: &Arc<Self>, event: E) {
|
||||||
@@ -153,7 +153,7 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Emits an event to this component in a spawned thread
|
/// Emits an event to this component in a spawned thread
|
||||||
///
|
///
|
||||||
/// Similar to emit_event but handlers are called in spawned threads
|
/// Similar to emit_event but handlers are called in spawned threads
|
||||||
/// for concurrent execution.
|
/// for concurrent execution.
|
||||||
pub fn emit_event_threaded<E: Any + Send + Sync + Clone + 'static>(
|
pub fn emit_event_threaded<E: Any + Send + Sync + Clone + 'static>(
|
||||||
@@ -216,6 +216,16 @@ impl Context {
|
|||||||
self.scopes.lock().unwrap().push(scope);
|
self.scopes.lock().unwrap().push(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the children
|
||||||
|
pub fn get_children(self: &Arc<Self>) -> Vec<(Arc<Context>, Option<ViewWrapper>)> {
|
||||||
|
self.scopes
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.iter()
|
||||||
|
.flat_map(|s| s.children.lock().unwrap().clone())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
}
|
||||||
|
|
||||||
/// Renders all child components to the draw context
|
/// Renders all child components to the draw context
|
||||||
pub fn draw_children(self: &Arc<Self>, ctx: &mut DrawContext) {
|
pub fn draw_children(self: &Arc<Self>, ctx: &mut DrawContext) {
|
||||||
for scope in self.scopes.lock().unwrap().iter() {
|
for scope in self.scopes.lock().unwrap().iter() {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
//! Components are reusable units of UI that can manage their own state
|
//! Components are reusable units of UI that can manage their own state
|
||||||
//! and respond to events.
|
//! and respond to events.
|
||||||
|
|
||||||
|
pub mod components;
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod scope;
|
pub mod scope;
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,12 @@ pub mod render;
|
|||||||
pub mod view_plugins;
|
pub mod view_plugins;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
|
//! Prelude module - Re-exports commonly used items for convenience
|
||||||
|
pub use crate::component::components::*;
|
||||||
|
pub use crate::component_prelude::*;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod component_prelude {
|
||||||
//! Prelude module - Re-exports commonly used items for convenience
|
//! Prelude module - Re-exports commonly used items for convenience
|
||||||
pub use crate::component::{context::*, scope::*, *};
|
pub use crate::component::{context::*, scope::*, *};
|
||||||
pub use crate::engine::*;
|
pub use crate::engine::*;
|
||||||
|
|||||||
Reference in New Issue
Block a user