fix gaps in layout

This commit is contained in:
Evan Almloff 2022-12-06 09:08:25 -06:00
parent 6ee4f7df4f
commit 4be64cb9f0
6 changed files with 57 additions and 33 deletions

View file

@ -125,7 +125,7 @@ impl PersistantElementIter {
/// get the next element
pub fn next<S: State>(&mut self, rdom: &RealDom<S>) -> ElementProduced {
let r = if self.stack.is_empty() {
if self.stack.is_empty() {
let id = NodeId(0);
let new = (id, NodePosition::AtNode);
self.stack.push(new);
@ -156,9 +156,7 @@ impl PersistantElementIter {
ElementProduced::Progressed(self.pop())
}
}
};
println!("next: {:?}", r);
r
}
}
/// get the previous element

View file

@ -23,7 +23,7 @@ use std::{
use taffy::geometry::{Point, Size};
use taffy::{prelude::Layout, Taffy};
use crate::FocusState;
use crate::{layout_to_screen_space, FocusState};
use crate::{TuiDom, TuiNode};
pub(crate) struct Event {
@ -243,7 +243,15 @@ impl InnerInputState {
) {
fn layout_contains_point(layout: &Layout, point: ScreenPoint) -> bool {
let Point { x, y } = layout.location;
let (x, y) = (
layout_to_screen_space(x).round(),
layout_to_screen_space(y).round(),
);
let Size { width, height } = layout.size;
let (width, height) = (
layout_to_screen_space(width).round(),
layout_to_screen_space(height).round(),
);
let layout_rect = Rect::new(Point2D::new(x, y), Size2D::new(width, height));
layout_rect.contains(point.cast())

View file

@ -7,6 +7,8 @@ use dioxus_native_core::state::ChildDepState;
use dioxus_native_core_macro::sorted_str_slice;
use taffy::prelude::*;
use crate::screen_to_layout_space;
#[derive(Debug, Clone, Copy, PartialEq)]
pub(crate) enum PossiblyUninitalized<T> {
Uninitalized,
@ -66,10 +68,10 @@ impl ChildDepState for TaffyLayout {
style = Style {
size: Size {
// characters are 1 point tall
height: Dimension::Points(1.0),
height: Dimension::Points(screen_to_layout_space(1)),
// text is as long as it is declared
width: Dimension::Points(char_len as f32),
width: Dimension::Points(screen_to_layout_space(char_len as u16)),
},
..Default::default()
};

View file

@ -35,6 +35,15 @@ pub use config::*;
pub use hooks::*;
pub(crate) use node::*;
// the layout space has a multiplier of 10 to minimize rounding errors
pub(crate)fn screen_to_layout_space(screen: u16) -> f32{
screen as f32 * 10.0
}
pub(crate)fn layout_to_screen_space(layout: f32) -> f32{
layout / 10.0
}
#[derive(Clone)]
pub struct TuiContext {
tx: UnboundedSender<InputEvent>,
@ -149,22 +158,22 @@ fn render_vdom(
if !to_rerender.is_empty() || updated {
updated = false;
fn resize(dims: Rect, taffy: &mut Taffy, rdom: &TuiDom) {
let width = dims.width;
let height = dims.height;
let width = screen_to_layout_space(dims.width );
let height = screen_to_layout_space(dims.height);
let root_node = rdom[NodeId(0)].state.layout.node.unwrap();
// the root node fills the entire area
let mut style=*taffy.style(root_node).unwrap();
style.size=Size {
width: Dimension::Points(width as f32),
height: Dimension::Points(height as f32),
width: Dimension::Points(width ),
height: Dimension::Points(height ),
};
taffy.set_style(root_node, style).unwrap();
let size =Size {
width: AvailableSpace::Definite(width as f32),
height: AvailableSpace::Definite(height as f32),
width: AvailableSpace::Definite(width),
height: AvailableSpace::Definite(height),
};
taffy
.compute_layout(
@ -195,8 +204,8 @@ fn render_vdom(
Rect {
x: 0,
y: 0,
width: 100,
height: 100,
width: 1000,
height: 1000,
},
&mut taffy.lock().expect("taffy lock poisoned"),
&rdom,

View file

@ -11,7 +11,7 @@ use taffy::{
Taffy,
};
use crate::TuiDom;
use crate::{layout_to_screen_space, TuiDom};
/// Allows querying the layout of nodes after rendering. It will only provide a correct value after a node is rendered.
/// Provided as a root context for all tui applictions.
@ -72,19 +72,28 @@ impl<'a> ElementRef<'a> {
}
pub fn size(&self) -> Option<Size<u32>> {
self.layout().map(|l| l.size.map(|v| v as u32))
self.layout().map(|l| l.size.map(|v| v.round() as u32))
}
pub fn pos(&self) -> Option<Point<u32>> {
self.layout().map(|l| Point {
x: l.location.x as u32,
y: l.location.y as u32,
x: l.location.x.round() as u32,
y: l.location.y.round() as u32,
})
}
pub fn layout(&self) -> Option<&Layout> {
self.stretch
pub fn layout(&self) -> Option<Layout> {
let layout = self
.stretch
.layout(self.inner[self.id].state.layout.node.ok()?)
.ok()
.ok();
layout.map(|layout| Layout {
order: layout.order,
size: layout.size.map(|v| layout_to_screen_space(v)),
location: Point {
x: layout_to_screen_space(layout.location.x),
y: layout_to_screen_space(layout.location.y),
},
})
}
}

View file

@ -8,6 +8,7 @@ use taffy::{
use tui::{backend::CrosstermBackend, layout::Rect, style::Color};
use crate::{
layout_to_screen_space,
style::{RinkColor, RinkStyle},
style_attributes::{BorderEdge, BorderStyle},
widget::{RinkBuffer, RinkCell, RinkWidget, WidgetWithContext},
@ -36,15 +37,12 @@ pub(crate) fn render_vnode(
location.x += parent_location.x;
location.y += parent_location.y;
let Point { mut x, mut y } = location;
x = x.floor();
y = y.floor();
let Size {
mut width,
mut height,
} = size;
width = width.ceil();
height = height.ceil();
let Point { x: fx, y: fy } = location;
let x = layout_to_screen_space(fx).round() as u16;
let y = layout_to_screen_space(fy).round() as u16;
let Size { width, height } = *size;
let width = layout_to_screen_space(fx + width).round() as u16 + x;
let height = layout_to_screen_space(fy + height).round() as u16 - y;
match &node.node_data.node_type {
NodeType::Text { text } => {
@ -69,7 +67,7 @@ pub(crate) fn render_vnode(
text,
style: node.state.style.core,
};
let area = Rect::new(x as u16, y as u16, width as u16, height as u16);
let area = Rect::new(x, y, width, height);
// the renderer will panic if a node is rendered out of range even if the size is zero
if area.width > 0 && area.height > 0 {
@ -77,7 +75,7 @@ pub(crate) fn render_vnode(
}
}
NodeType::Element { .. } => {
let area = Rect::new(x as u16, y as u16, width as u16, height as u16);
let area = Rect::new(x, y, width, height);
// the renderer will panic if a node is rendered out of range even if the size is zero
if area.width > 0 && area.height > 0 {