Move render code into Tree
This commit is contained in:
parent
ce2f986983
commit
9a25856548
4 changed files with 114 additions and 87 deletions
|
|
@ -1,8 +1,8 @@
|
||||||
pub use crate::{node::*, rect::*, render::*, vec2::*, view::*, widget::*};
|
pub use crate::{node::*, rect::*, tree::*, vec2::*, view::*, widget::*};
|
||||||
|
|
||||||
mod node;
|
mod node;
|
||||||
mod rect;
|
mod rect;
|
||||||
mod render;
|
mod tree;
|
||||||
mod vec2;
|
mod vec2;
|
||||||
mod view;
|
mod view;
|
||||||
mod widget;
|
mod widget;
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@ use taffy::{
|
||||||
AlignContent, AlignItems, AlignSelf, Dimension, Display, FlexDirection, FlexWrap, GridAutoFlow,
|
AlignContent, AlignItems, AlignSelf, Dimension, Display, FlexDirection, FlexWrap, GridAutoFlow,
|
||||||
GridPlacement, JustifyContent, LengthPercentage, LengthPercentageAuto, Line, NodeId,
|
GridPlacement, JustifyContent, LengthPercentage, LengthPercentageAuto, Line, NodeId,
|
||||||
NonRepeatedTrackSizingFunction, Overflow, Point, Position, Rect, Size, Style, TaffyResult,
|
NonRepeatedTrackSizingFunction, Overflow, Point, Position, Rect, Size, Style, TaffyResult,
|
||||||
TaffyTree, TrackSizingFunction,
|
TrackSizingFunction,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{BoxedWidget, Widget};
|
use crate::{BoxedWidget, Tree, Widget};
|
||||||
|
|
||||||
pub struct Node<C> {
|
pub struct Node<C> {
|
||||||
layout: Style,
|
layout: Style,
|
||||||
|
|
@ -32,7 +32,8 @@ impl<C> Node<C> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register(self, tree: &mut TaffyTree<BoxedWidget<C>>) -> TaffyResult<NodeId> {
|
pub fn register(self, tree: &mut Tree<C>) -> TaffyResult<NodeId> {
|
||||||
|
let tree = tree.taffy_tree();
|
||||||
let id = tree.new_with_children(self.layout, &self.children)?;
|
let id = tree.new_with_children(self.layout, &self.children)?;
|
||||||
tree.set_node_context(id, self.widget)?;
|
tree.set_node_context(id, self.widget)?;
|
||||||
Ok(id)
|
Ok(id)
|
||||||
|
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
use image::RgbImage;
|
|
||||||
use taffy::{AvailableSpace, NodeId, Point, Size, TaffyResult, TaffyTree};
|
|
||||||
|
|
||||||
use crate::{BoxedWidget, Rect, Vec2, View};
|
|
||||||
|
|
||||||
fn point_to_vec2(point: Point<f32>) -> Vec2 {
|
|
||||||
Vec2::new(point.x as i32, point.y as i32)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size_to_vec2(size: Size<f32>) -> Vec2 {
|
|
||||||
Vec2::new(size.width as i32, size.height as i32)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn layout<C>(
|
|
||||||
tree: &mut TaffyTree<BoxedWidget<C>>,
|
|
||||||
ctx: &mut C,
|
|
||||||
root: NodeId,
|
|
||||||
available: Size<AvailableSpace>,
|
|
||||||
) -> TaffyResult<()> {
|
|
||||||
tree.enable_rounding(); // Just to make sure
|
|
||||||
tree.compute_layout_with_measure(root, available, |known, available, _node, context| {
|
|
||||||
if let Some(widget) = context {
|
|
||||||
widget.size(ctx, known, available)
|
|
||||||
} else {
|
|
||||||
Size::ZERO
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_to_view<C>(
|
|
||||||
tree: &mut TaffyTree<BoxedWidget<C>>,
|
|
||||||
ctx: &mut C,
|
|
||||||
node: NodeId,
|
|
||||||
view: &mut View<'_>,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
let layout = tree.layout(node)?;
|
|
||||||
let area = Rect::from_nw(point_to_vec2(layout.location), size_to_vec2(layout.size));
|
|
||||||
let mut view = view.dup().zoom(area);
|
|
||||||
|
|
||||||
// First pass
|
|
||||||
if let Some(widget) = tree.get_node_context_mut(node) {
|
|
||||||
widget.draw_below(ctx, &mut view)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render children
|
|
||||||
let mut children = vec![];
|
|
||||||
for child in tree.children(node)? {
|
|
||||||
let order = tree.layout(child)?.order;
|
|
||||||
children.push((order, child));
|
|
||||||
}
|
|
||||||
children.sort_unstable_by_key(|(order, _)| *order);
|
|
||||||
for (_, child) in children {
|
|
||||||
render_to_view(tree, ctx, child, &mut view)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Second pass
|
|
||||||
if let Some(widget) = tree.get_node_context_mut(node) {
|
|
||||||
widget.draw_above(ctx, &mut view)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render<C>(
|
|
||||||
tree: &mut TaffyTree<BoxedWidget<C>>,
|
|
||||||
ctx: &mut C,
|
|
||||||
root: NodeId,
|
|
||||||
available: Size<AvailableSpace>,
|
|
||||||
) -> anyhow::Result<RgbImage> {
|
|
||||||
layout(tree, ctx, root, available)?;
|
|
||||||
|
|
||||||
let layout = tree.layout(root)?;
|
|
||||||
assert_eq!(layout.location.x, 0.0);
|
|
||||||
assert_eq!(layout.location.y, 0.0);
|
|
||||||
// TODO Check how taffy treats the border?
|
|
||||||
|
|
||||||
let (width, height) = size_to_vec2(layout.size).to_u32();
|
|
||||||
let mut image = RgbImage::new(width, height);
|
|
||||||
render_to_view(tree, ctx, root, &mut View::new(&mut image))?;
|
|
||||||
|
|
||||||
Ok(image)
|
|
||||||
}
|
|
||||||
108
showbits-common/src/tree.rs
Normal file
108
showbits-common/src/tree.rs
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
use image::RgbImage;
|
||||||
|
use taffy::{AvailableSpace, NodeId, Point, Size, TaffyResult, TaffyTree};
|
||||||
|
|
||||||
|
use crate::{BoxedWidget, Rect, Vec2, View};
|
||||||
|
|
||||||
|
fn point_to_vec2(point: Point<f32>) -> Vec2 {
|
||||||
|
Vec2::new(point.x as i32, point.y as i32)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_to_vec2(size: Size<f32>) -> Vec2 {
|
||||||
|
Vec2::new(size.width as i32, size.height as i32)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Tree<C> {
|
||||||
|
tree: TaffyTree<BoxedWidget<C>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C> Tree<C> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
tree: TaffyTree::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn taffy_tree(&mut self) -> &mut TaffyTree<BoxedWidget<C>> {
|
||||||
|
&mut self.tree
|
||||||
|
}
|
||||||
|
|
||||||
|
fn layout(
|
||||||
|
&mut self,
|
||||||
|
ctx: &mut C,
|
||||||
|
root: NodeId,
|
||||||
|
available: Size<AvailableSpace>,
|
||||||
|
) -> TaffyResult<()> {
|
||||||
|
self.tree.enable_rounding(); // Just to make sure
|
||||||
|
self.tree.compute_layout_with_measure(
|
||||||
|
root,
|
||||||
|
available,
|
||||||
|
|known, available, _node, context| {
|
||||||
|
if let Some(widget) = context {
|
||||||
|
widget.size(ctx, known, available)
|
||||||
|
} else {
|
||||||
|
Size::ZERO
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_to_view(
|
||||||
|
&mut self,
|
||||||
|
ctx: &mut C,
|
||||||
|
node: NodeId,
|
||||||
|
view: &mut View<'_>,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let layout = self.tree.layout(node)?;
|
||||||
|
let area = Rect::from_nw(point_to_vec2(layout.location), size_to_vec2(layout.size));
|
||||||
|
let mut view = view.dup().zoom(area);
|
||||||
|
|
||||||
|
// First pass
|
||||||
|
if let Some(widget) = self.tree.get_node_context_mut(node) {
|
||||||
|
widget.draw_below(ctx, &mut view)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render children
|
||||||
|
let mut children = vec![];
|
||||||
|
for child in self.tree.children(node)? {
|
||||||
|
let order = self.tree.layout(child)?.order;
|
||||||
|
children.push((order, child));
|
||||||
|
}
|
||||||
|
children.sort_unstable_by_key(|(order, _)| *order);
|
||||||
|
for (_, child) in children {
|
||||||
|
self.render_to_view(ctx, child, &mut view)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second pass
|
||||||
|
if let Some(widget) = self.tree.get_node_context_mut(node) {
|
||||||
|
widget.draw_above(ctx, &mut view)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render(
|
||||||
|
&mut self,
|
||||||
|
ctx: &mut C,
|
||||||
|
root: NodeId,
|
||||||
|
available: Size<AvailableSpace>,
|
||||||
|
) -> anyhow::Result<RgbImage> {
|
||||||
|
self.layout(ctx, root, available)?;
|
||||||
|
|
||||||
|
let layout = self.tree.layout(root)?;
|
||||||
|
assert_eq!(layout.location.x, 0.0);
|
||||||
|
assert_eq!(layout.location.y, 0.0);
|
||||||
|
// TODO Check how taffy treats the border?
|
||||||
|
|
||||||
|
let (width, height) = size_to_vec2(layout.size).to_u32();
|
||||||
|
let mut image = RgbImage::new(width, height);
|
||||||
|
self.render_to_view(ctx, root, &mut View::new(&mut image))?;
|
||||||
|
|
||||||
|
Ok(image)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C> Default for Tree<C> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue