mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-23 12:43:08 +00:00
fix gaps in layout
This commit is contained in:
parent
6ee4f7df4f
commit
4be64cb9f0
6 changed files with 57 additions and 33 deletions
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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()
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue