diff --git a/examples/hello_world.rs b/examples/hello_world.rs index 3cca2e7..0f0bec7 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -10,7 +10,12 @@ fn App(cx: &Arc) -> View { rsx! { // redraw is important because the effects won't be applied 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) } diff --git a/src/component/components/flex.rs b/src/component/components/flex.rs new file mode 100644 index 0000000..897dc64 --- /dev/null +++ b/src/component/components/flex.rs @@ -0,0 +1,51 @@ +use crate::component_prelude::*; + +#[component] +pub fn FlexRow(cx: &Arc, 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, 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); + } + } + } + }) +} diff --git a/src/component/components/mod.rs b/src/component/components/mod.rs new file mode 100644 index 0000000..aaf7e40 --- /dev/null +++ b/src/component/components/mod.rs @@ -0,0 +1,3 @@ +mod flex; + +pub use flex::*; diff --git a/src/component/context.rs b/src/component/context.rs index 92fec14..7f00388 100644 --- a/src/component/context.rs +++ b/src/component/context.rs @@ -15,15 +15,15 @@ use access_cell::AccessCell; use crate::{ component::EventHandler, engine::{Command, CommandExecutor}, - render::DrawContext, hooks::{use_effect, HookDependency}, - View, + render::DrawContext, + View, ViewWrapper, }; use super::{scope::Scope, Component, ComponentImpl}; /// Context represents the runtime state and behavior of a component -/// +/// /// Each component instance has a Context that holds: /// - The component implementation /// - The current view (render result) @@ -58,7 +58,7 @@ impl Context { } /// Refreshes the component by re-rendering it - /// + /// /// Clears event handlers and calls the component to produce a new view. pub fn refresh(self: &Arc) { self.event_handlers @@ -76,7 +76,7 @@ impl Context { } /// Synchronously refreshes the component - /// + /// /// Blocks until the component has finished rendering. pub fn refresh_sync(self: &Arc) { let (tx, rx) = std::sync::mpsc::channel::<()>(); @@ -110,7 +110,7 @@ impl Context { } /// Registers an event handler for events of type T - /// + /// /// When an event of type T is emitted, the handler is called with /// the context and a reference to the event. pub fn on_event, &T) + Send + Sync + 'static>( @@ -132,7 +132,7 @@ impl Context { } /// Emits an event to this component and all descendants - /// + /// /// Calls all registered handlers for this event type, /// then propagates the event to child components. pub fn emit_event(self: &Arc, event: E) { @@ -153,7 +153,7 @@ impl Context { } /// Emits an event to this component in a spawned thread - /// + /// /// Similar to emit_event but handlers are called in spawned threads /// for concurrent execution. pub fn emit_event_threaded( @@ -216,6 +216,16 @@ impl Context { self.scopes.lock().unwrap().push(scope); } + /// Gets the children + pub fn get_children(self: &Arc) -> Vec<(Arc, Option)> { + self.scopes + .lock() + .unwrap() + .iter() + .flat_map(|s| s.children.lock().unwrap().clone()) + .collect::>() + } + /// Renders all child components to the draw context pub fn draw_children(self: &Arc, ctx: &mut DrawContext) { for scope in self.scopes.lock().unwrap().iter() { diff --git a/src/component/mod.rs b/src/component/mod.rs index e48b642..4bb0022 100644 --- a/src/component/mod.rs +++ b/src/component/mod.rs @@ -4,6 +4,7 @@ //! Components are reusable units of UI that can manage their own state //! and respond to events. +pub mod components; pub mod context; pub mod scope; diff --git a/src/lib.rs b/src/lib.rs index 3b76b8b..beb5fa5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,6 +48,12 @@ pub mod render; pub mod view_plugins; 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 pub use crate::component::{context::*, scope::*, *}; pub use crate::engine::*;