diff --git a/neothesia/src/scene/playing_scene/top_bar/widget/speed_pill.rs b/neothesia/src/scene/playing_scene/top_bar/widget/speed_pill.rs index 5cd93c6..607facd 100644 --- a/neothesia/src/scene/playing_scene/top_bar/widget/speed_pill.rs +++ b/neothesia/src/scene/playing_scene/top_bar/widget/speed_pill.rs @@ -117,7 +117,7 @@ impl Widget for SpeedPill { tree: &Tree, ctx: &RenderCtx, ) { - self.render_default(renderer, layout, tree, ctx); + nuon::default_render(self, renderer, layout, tree, ctx); let pad = 2.0; diff --git a/nuon/src/lib.rs b/nuon/src/lib.rs index 3b5a795..ea5e108 100644 --- a/nuon/src/lib.rs +++ b/nuon/src/lib.rs @@ -190,37 +190,7 @@ pub trait Widget { } fn layout(&self, tree: &mut Tree, parent: &ParentLayout, ctx: &LayoutCtx) -> Node { - let widgets = self.children(); - let mut children = Vec::with_capacity(widgets.len()); - - for (ch, tree) in widgets.iter().zip(tree.children.iter_mut()) { - children.push(ch.as_widget().layout(tree, parent, ctx)); - } - - Node { - x: parent.x, - y: parent.y, - w: parent.w, - h: parent.h, - children, - } - } - - fn render_default( - &self, - renderer: &mut dyn Renderer, - layout: &Node, - tree: &Tree, - ctx: &RenderCtx, - ) { - for ((ch, layout), tree) in self - .children() - .iter() - .zip(layout.children.iter()) - .zip(tree.children.iter()) - { - ch.as_widget().render(renderer, layout, tree, ctx); - } + widget::stack::stack_layout(self, tree, parent, ctx) } fn render( @@ -230,39 +200,60 @@ pub trait Widget { tree: &Tree, ctx: &RenderCtx, ) { - self.render_default(renderer, layout, tree, ctx) + default_render(self, renderer, layout, tree, ctx) } - fn update_default( + fn update( &mut self, event: input::Event, layout: &Node, tree: &mut Tree, ctx: &mut UpdateCtx, ) { - for ((ch, layout), tree) in self - .children_mut() - .iter_mut() - .zip(layout.children.iter()) - .zip(tree.children.iter_mut()) - .rev() - { - ch.as_widget_mut().update(event.clone(), layout, tree, ctx); - - if ctx.is_event_captured() { - return; - } - } + default_update(self, event, layout, tree, ctx) } +} - fn update( - &mut self, - event: input::Event, - layout: &Node, - tree: &mut Tree, - ctx: &mut UpdateCtx, - ) { - self.update_default(event, layout, tree, ctx) +pub use widget::column::column_layout; +pub use widget::row::row_layout; +pub use widget::stack::stack_layout; + +pub fn default_render + ?Sized>( + this: &W, + renderer: &mut dyn Renderer, + layout: &Node, + tree: &Tree, + ctx: &RenderCtx, +) { + for ((ch, layout), tree) in this + .children() + .iter() + .zip(layout.children.iter()) + .zip(tree.children.iter()) + { + ch.as_widget().render(renderer, layout, tree, ctx); + } +} + +pub fn default_update + ?Sized>( + this: &mut W, + event: input::Event, + layout: &Node, + tree: &mut Tree, + ctx: &mut UpdateCtx, +) { + for ((ch, layout), tree) in this + .children_mut() + .iter_mut() + .zip(layout.children.iter()) + .zip(tree.children.iter_mut()) + .rev() + { + ch.as_widget_mut().update(event.clone(), layout, tree, ctx); + + if ctx.is_event_captured() { + return; + } } } diff --git a/nuon/src/widget/column.rs b/nuon/src/widget/column.rs index 95cc5cc..9e5c30b 100644 --- a/nuon/src/widget/column.rs +++ b/nuon/src/widget/column.rs @@ -52,42 +52,52 @@ impl Widget for Column { } fn layout(&self, tree: &mut Tree, parent: &ParentLayout, ctx: &LayoutCtx) -> Node { - let mut children = Vec::with_capacity(self.children.len()); + column_layout(self, tree, parent, ctx, self.gap) + } +} - let mut item_layout = ParentLayout { - x: parent.x, - y: parent.y, - w: parent.w, - h: parent.h, - }; +pub fn column_layout + ?Sized>( + this: &W, + tree: &mut Tree, + parent: &ParentLayout, + ctx: &LayoutCtx, + gap: f32, +) -> Node { + let mut children = Vec::with_capacity(this.children().len()); - let mut total_height = 0.0; + let mut item_layout = ParentLayout { + x: parent.x, + y: parent.y, + w: parent.w, + h: parent.h, + }; - for (ch, tree) in self.children.iter().zip(tree.children.iter_mut()) { - let node = ch.as_widget().layout(tree, &item_layout, ctx); + let mut total_height = 0.0; - item_layout.y += node.h; - item_layout.h -= node.h; + for (ch, tree) in this.children().iter().zip(tree.children.iter_mut()) { + let node = ch.as_widget().layout(tree, &item_layout, ctx); - item_layout.y += self.gap; - item_layout.h -= self.gap; + item_layout.y += node.h; + item_layout.h -= node.h; - total_height += node.h; - total_height += self.gap; + item_layout.y += gap; + item_layout.h -= gap; - children.push(node); - } + total_height += node.h; + total_height += gap; - total_height -= self.gap; - total_height = total_height.max(0.0); + children.push(node); + } - Node { - x: parent.x, - y: parent.y, - w: parent.w, - h: total_height, - children, - } + total_height -= gap; + total_height = total_height.max(0.0); + + Node { + x: parent.x, + y: parent.y, + w: parent.w, + h: total_height, + children, } } diff --git a/nuon/src/widget/container.rs b/nuon/src/widget/container.rs index c1d1529..9a5c17c 100644 --- a/nuon/src/widget/container.rs +++ b/nuon/src/widget/container.rs @@ -110,7 +110,7 @@ impl Widget for Container { if let Some(bg) = self.background { renderer.quad(layout.x, layout.y, layout.w, layout.h, bg); } - self.render_default(renderer, layout, tree, ctx); + crate::default_render(self, renderer, layout, tree, ctx); } } diff --git a/nuon/src/widget/row.rs b/nuon/src/widget/row.rs index 993395f..edf7a07 100644 --- a/nuon/src/widget/row.rs +++ b/nuon/src/widget/row.rs @@ -52,42 +52,52 @@ impl Widget for Row { } fn layout(&self, tree: &mut Tree, parent: &ParentLayout, ctx: &LayoutCtx) -> Node { - let mut children = Vec::with_capacity(self.children.len()); + row_layout(self, tree, parent, ctx, self.gap) + } +} - let mut item_layout = ParentLayout { - x: parent.x, - y: parent.y, - w: parent.w, - h: parent.h, - }; +pub fn row_layout + ?Sized>( + this: &W, + tree: &mut Tree, + parent: &ParentLayout, + ctx: &LayoutCtx, + gap: f32, +) -> Node { + let mut children = Vec::with_capacity(this.children().len()); - let mut total_width = 0.0; + let mut item_layout = ParentLayout { + x: parent.x, + y: parent.y, + w: parent.w, + h: parent.h, + }; - for (ch, tree) in self.children.iter().zip(tree.children.iter_mut()) { - let node = ch.as_widget().layout(tree, &item_layout, ctx); + let mut total_width = 0.0; - item_layout.x += node.w; - item_layout.w -= node.w; + for (ch, tree) in this.children().iter().zip(tree.children.iter_mut()) { + let node = ch.as_widget().layout(tree, &item_layout, ctx); - item_layout.x += self.gap; - item_layout.w -= self.gap; + item_layout.x += node.w; + item_layout.w -= node.w; - total_width += node.w; - total_width += self.gap; + item_layout.x += gap; + item_layout.w -= gap; - children.push(node); - } + total_width += node.w; + total_width += gap; - total_width -= self.gap; - total_width = total_width.max(0.0); + children.push(node); + } - Node { - x: parent.x, - y: parent.y, - w: total_width, - h: parent.h, - children, - } + total_width -= gap; + total_width = total_width.max(0.0); + + Node { + x: parent.x, + y: parent.y, + w: total_width, + h: parent.h, + children, } } diff --git a/nuon/src/widget/stack.rs b/nuon/src/widget/stack.rs index 46df78b..a1b1e1a 100644 --- a/nuon/src/widget/stack.rs +++ b/nuon/src/widget/stack.rs @@ -1,6 +1,6 @@ use smallvec::SmallVec; -use crate::{Element, Widget}; +use crate::{Element, LayoutCtx, Node, ParentLayout, Tree, Widget}; pub struct Stack { children: SmallVec<[Element; 4]>, @@ -43,6 +43,32 @@ impl Widget for Stack { fn children_mut(&mut self) -> &mut [Element] { &mut self.children } + + fn layout(&self, tree: &mut Tree, parent: &ParentLayout, ctx: &LayoutCtx) -> Node { + stack_layout(self, tree, parent, ctx) + } +} + +pub fn stack_layout + ?Sized>( + this: &W, + tree: &mut Tree, + parent: &ParentLayout, + ctx: &LayoutCtx, +) -> Node { + let widgets = this.children(); + let mut children = Vec::with_capacity(widgets.len()); + + for (ch, tree) in widgets.iter().zip(tree.children.iter_mut()) { + children.push(ch.as_widget().layout(tree, parent, ctx)); + } + + Node { + x: parent.x, + y: parent.y, + w: parent.w, + h: parent.h, + children, + } } impl From> for Element {