mirror of
https://github.com/danbulant/mangui
synced 2026-07-08 12:20:34 +00:00
prepare for layouting
This commit is contained in:
parent
68cf25da3f
commit
8ca035e6ff
3 changed files with 88 additions and 16 deletions
23
src/main.rs
23
src/main.rs
|
|
@ -22,7 +22,7 @@ use glutin::{
|
||||||
};
|
};
|
||||||
use taffy::Taffy;
|
use taffy::Taffy;
|
||||||
use weak_table::PtrWeakKeyHashMap;
|
use weak_table::PtrWeakKeyHashMap;
|
||||||
use crate::nodes::{Node, render_recursively, RenderContext};
|
use crate::nodes::{layout_recursively, Node, render_recursively, RenderContext};
|
||||||
|
|
||||||
mod nodes;
|
mod nodes;
|
||||||
|
|
||||||
|
|
@ -48,7 +48,9 @@ fn main() {
|
||||||
taffy_map.insert(root.clone(), root_node);
|
taffy_map.insert(root.clone(), root_node);
|
||||||
|
|
||||||
let mut context = RenderContext {
|
let mut context = RenderContext {
|
||||||
canvas
|
canvas,
|
||||||
|
taffy_map,
|
||||||
|
taffy
|
||||||
};
|
};
|
||||||
|
|
||||||
event_loop.run(move |event, _target, control_flow| match event {
|
event_loop.run(move |event, _target, control_flow| match event {
|
||||||
|
|
@ -66,7 +68,16 @@ fn main() {
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
Event::RedrawRequested(_) => {
|
Event::RedrawRequested(_) => {
|
||||||
render(&buffer_context, &surface, &window, &mut context, &root, &taffy_map, &taffy);
|
layout_recursively(&root, &mut context);
|
||||||
|
let src_nodes = context.taffy_map.values().map(|v| v.to_owned()).collect::<Vec<_>>();
|
||||||
|
context.taffy_map.remove_expired();
|
||||||
|
let dst_nodes = context.taffy_map.values().map(|v| v.to_owned()).collect::<Vec<_>>();
|
||||||
|
for src_node in src_nodes {
|
||||||
|
if !dst_nodes.contains(&src_node) {
|
||||||
|
context.taffy.remove(src_node).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
render(&buffer_context, &surface, &window, &mut context, &root);
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
})
|
})
|
||||||
|
|
@ -115,9 +126,7 @@ fn render(
|
||||||
surface: &Surface<WindowSurface>,
|
surface: &Surface<WindowSurface>,
|
||||||
window: &Window,
|
window: &Window,
|
||||||
context: &mut RenderContext<OpenGl>,
|
context: &mut RenderContext<OpenGl>,
|
||||||
root_node: &Arc<GNode>,
|
root_node: &Arc<GNode>
|
||||||
taffy_map: &TaffyMap,
|
|
||||||
taffy: &Taffy
|
|
||||||
) {
|
) {
|
||||||
// Make sure the canvas has the right size:
|
// Make sure the canvas has the right size:
|
||||||
let size = window.inner_size();
|
let size = window.inner_size();
|
||||||
|
|
@ -126,7 +135,7 @@ fn render(
|
||||||
context.canvas.clear_rect(0, 0, size.width, size.height, Color::black());
|
context.canvas.clear_rect(0, 0, size.width, size.height, Color::black());
|
||||||
|
|
||||||
// Do the render passes here
|
// Do the render passes here
|
||||||
render_recursively(root_node, context, taffy_map, taffy);
|
render_recursively(root_node, context);
|
||||||
|
|
||||||
// Tell renderer to execute all drawing commands
|
// Tell renderer to execute all drawing commands
|
||||||
context.canvas.flush();
|
context.canvas.flush();
|
||||||
|
|
|
||||||
32
src/nodes/layout.rs
Normal file
32
src/nodes/layout.rs
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
use femtovg::Renderer;
|
||||||
|
use crate::nodes::{Node, NodeChildren, Overflow, RenderContext, Style};
|
||||||
|
use taffy::style::{Style as TaffyStyle};
|
||||||
|
|
||||||
|
pub struct Layout<T> {
|
||||||
|
style: Style,
|
||||||
|
children: NodeChildren<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Renderer> Layout<T> {
|
||||||
|
pub(crate) fn new() -> Layout<T> {
|
||||||
|
Layout {
|
||||||
|
style: Style {
|
||||||
|
layout: TaffyStyle::default(),
|
||||||
|
overflow: Overflow::Visible
|
||||||
|
},
|
||||||
|
children: NodeChildren::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Renderer> Node<T> for Layout<T> {
|
||||||
|
fn style(&self) -> &Style {
|
||||||
|
&self.style
|
||||||
|
}
|
||||||
|
fn children(&self) -> Option<&NodeChildren<T>> {
|
||||||
|
Some(&self.children)
|
||||||
|
}
|
||||||
|
fn render(&self, context: &mut RenderContext<T>, _layout: taffy::layout::Layout, render_children: &dyn Fn(&mut RenderContext<T>)) {
|
||||||
|
render_children(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
pub mod layout;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use femtovg::{Canvas, Color, Renderer};
|
use femtovg::{Canvas, Color, Renderer};
|
||||||
use femtovg::renderer::OpenGl;
|
use femtovg::renderer::OpenGl;
|
||||||
|
|
@ -9,7 +11,9 @@ use taffy::Taffy;
|
||||||
use crate::{GNode, TaffyMap};
|
use crate::{GNode, TaffyMap};
|
||||||
|
|
||||||
pub struct RenderContext<T: Renderer> {
|
pub struct RenderContext<T: Renderer> {
|
||||||
pub(crate) canvas: Canvas<T>,
|
pub canvas: Canvas<T>,
|
||||||
|
pub taffy_map: TaffyMap,
|
||||||
|
pub taffy: Taffy
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Default)]
|
#[derive(Copy, Clone, Default)]
|
||||||
|
|
@ -39,14 +43,41 @@ pub trait Node<T: Renderer> {
|
||||||
fn children(&self) -> Option<&NodeChildren<T>>;
|
fn children(&self) -> Option<&NodeChildren<T>>;
|
||||||
/// Render the node and its children. render_children gets ['children'] and calls this function there as well. When drawing, the canvas is translated to the node's location.
|
/// Render the node and its children. render_children gets ['children'] and calls this function there as well. When drawing, the canvas is translated to the node's location.
|
||||||
/// Canvas considers 0, 0 to be top left corner (for location after layouting happens)
|
/// Canvas considers 0, 0 to be top left corner (for location after layouting happens)
|
||||||
fn render(&self, context: &mut RenderContext<T>, layout: &Layout, render_children: &dyn Fn(&mut RenderContext<T>));
|
fn render(&self, context: &mut RenderContext<T>, layout: Layout, render_children: &dyn Fn(&mut RenderContext<T>));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_recursively(selfref: &Arc<GNode>, context: &mut RenderContext<OpenGl>, taffy_map: &TaffyMap, taffy: &Taffy) {
|
pub fn layout_recursively(node: &Arc<GNode>, context: &mut RenderContext<OpenGl>) -> taffy::node::Node {
|
||||||
let styles = selfref.style();
|
let taffy_node = context.taffy_map.get(node);
|
||||||
let node = taffy_map.get(selfref).unwrap();
|
let taffy_node = match taffy_node {
|
||||||
let layout = taffy.layout(*node).unwrap();
|
Some(taffy_node) => taffy_node,
|
||||||
let sself = selfref.clone();
|
None => {
|
||||||
|
let taffy_node = context.taffy.new_leaf(node.style().layout.to_owned()).unwrap();
|
||||||
|
context.taffy_map.insert(node.clone(), taffy_node);
|
||||||
|
context.taffy_map.get(node).unwrap()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let taffy_node = taffy_node.to_owned();
|
||||||
|
|
||||||
|
match node.children() {
|
||||||
|
None => {},
|
||||||
|
Some(children) => {
|
||||||
|
let mut t_children = Vec::with_capacity(children.len());
|
||||||
|
for child in children {
|
||||||
|
t_children.push(layout_recursively(child, context).to_owned());
|
||||||
|
}
|
||||||
|
context.taffy.set_children(taffy_node, t_children.as_slice()).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
taffy_node
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render_recursively(node: &Arc<GNode>, context: &mut RenderContext<OpenGl>) {
|
||||||
|
let styles = node.style();
|
||||||
|
let taffy_node = context.taffy_map.get(node).unwrap();
|
||||||
|
let layout = *context.taffy.layout(*taffy_node).unwrap();
|
||||||
|
let sself = node.clone();
|
||||||
context.canvas.save();
|
context.canvas.save();
|
||||||
context.canvas.translate(layout.location.x, layout.location.y);
|
context.canvas.translate(layout.location.x, layout.location.y);
|
||||||
match styles.overflow {
|
match styles.overflow {
|
||||||
|
|
@ -63,7 +94,7 @@ pub fn render_recursively(selfref: &Arc<GNode>, context: &mut RenderContext<Open
|
||||||
sself.render(context, layout, & (|context| {
|
sself.render(context, layout, & (|context| {
|
||||||
if let Some(children) = sself.children() {
|
if let Some(children) = sself.children() {
|
||||||
for child in children {
|
for child in children {
|
||||||
render_recursively(child, context, taffy_map, taffy);
|
render_recursively(child, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
@ -98,7 +129,7 @@ impl<T: Renderer> Node<T> for RedBoxDemo {
|
||||||
fn children(&self) -> Option<&NodeChildren<T>> {
|
fn children(&self) -> Option<&NodeChildren<T>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
fn render<'a>(&self, context: &mut RenderContext<T>, _layout: &Layout, _render_children: &dyn Fn(&mut RenderContext<T>)) {
|
fn render(&self, context: &mut RenderContext<T>, _layout: Layout, _render_children: &dyn Fn(&mut RenderContext<T>)) {
|
||||||
context.canvas.clear_rect(
|
context.canvas.clear_rect(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue