mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-27 14:40:44 +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
|
/// get the next element
|
||||||
pub fn next<S: State>(&mut self, rdom: &RealDom<S>) -> ElementProduced {
|
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 id = NodeId(0);
|
||||||
let new = (id, NodePosition::AtNode);
|
let new = (id, NodePosition::AtNode);
|
||||||
self.stack.push(new);
|
self.stack.push(new);
|
||||||
|
@ -156,9 +156,7 @@ impl PersistantElementIter {
|
||||||
ElementProduced::Progressed(self.pop())
|
ElementProduced::Progressed(self.pop())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
println!("next: {:?}", r);
|
|
||||||
r
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// get the previous element
|
/// get the previous element
|
||||||
|
|
|
@ -23,7 +23,7 @@ use std::{
|
||||||
use taffy::geometry::{Point, Size};
|
use taffy::geometry::{Point, Size};
|
||||||
use taffy::{prelude::Layout, Taffy};
|
use taffy::{prelude::Layout, Taffy};
|
||||||
|
|
||||||
use crate::FocusState;
|
use crate::{layout_to_screen_space, FocusState};
|
||||||
use crate::{TuiDom, TuiNode};
|
use crate::{TuiDom, TuiNode};
|
||||||
|
|
||||||
pub(crate) struct Event {
|
pub(crate) struct Event {
|
||||||
|
@ -243,7 +243,15 @@ impl InnerInputState {
|
||||||
) {
|
) {
|
||||||
fn layout_contains_point(layout: &Layout, point: ScreenPoint) -> bool {
|
fn layout_contains_point(layout: &Layout, point: ScreenPoint) -> bool {
|
||||||
let Point { x, y } = layout.location;
|
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 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));
|
let layout_rect = Rect::new(Point2D::new(x, y), Size2D::new(width, height));
|
||||||
layout_rect.contains(point.cast())
|
layout_rect.contains(point.cast())
|
||||||
|
|
|
@ -7,6 +7,8 @@ use dioxus_native_core::state::ChildDepState;
|
||||||
use dioxus_native_core_macro::sorted_str_slice;
|
use dioxus_native_core_macro::sorted_str_slice;
|
||||||
use taffy::prelude::*;
|
use taffy::prelude::*;
|
||||||
|
|
||||||
|
use crate::screen_to_layout_space;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub(crate) enum PossiblyUninitalized<T> {
|
pub(crate) enum PossiblyUninitalized<T> {
|
||||||
Uninitalized,
|
Uninitalized,
|
||||||
|
@ -66,10 +68,10 @@ impl ChildDepState for TaffyLayout {
|
||||||
style = Style {
|
style = Style {
|
||||||
size: Size {
|
size: Size {
|
||||||
// characters are 1 point tall
|
// 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
|
// 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()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,6 +35,15 @@ pub use config::*;
|
||||||
pub use hooks::*;
|
pub use hooks::*;
|
||||||
pub(crate) use node::*;
|
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)]
|
#[derive(Clone)]
|
||||||
pub struct TuiContext {
|
pub struct TuiContext {
|
||||||
tx: UnboundedSender<InputEvent>,
|
tx: UnboundedSender<InputEvent>,
|
||||||
|
@ -149,22 +158,22 @@ fn render_vdom(
|
||||||
if !to_rerender.is_empty() || updated {
|
if !to_rerender.is_empty() || updated {
|
||||||
updated = false;
|
updated = false;
|
||||||
fn resize(dims: Rect, taffy: &mut Taffy, rdom: &TuiDom) {
|
fn resize(dims: Rect, taffy: &mut Taffy, rdom: &TuiDom) {
|
||||||
let width = dims.width;
|
let width = screen_to_layout_space(dims.width );
|
||||||
let height = dims.height;
|
let height = screen_to_layout_space(dims.height);
|
||||||
let root_node = rdom[NodeId(0)].state.layout.node.unwrap();
|
let root_node = rdom[NodeId(0)].state.layout.node.unwrap();
|
||||||
|
|
||||||
// the root node fills the entire area
|
// the root node fills the entire area
|
||||||
|
|
||||||
let mut style=*taffy.style(root_node).unwrap();
|
let mut style=*taffy.style(root_node).unwrap();
|
||||||
style.size=Size {
|
style.size=Size {
|
||||||
width: Dimension::Points(width as f32),
|
width: Dimension::Points(width ),
|
||||||
height: Dimension::Points(height as f32),
|
height: Dimension::Points(height ),
|
||||||
};
|
};
|
||||||
taffy.set_style(root_node, style).unwrap();
|
taffy.set_style(root_node, style).unwrap();
|
||||||
|
|
||||||
let size =Size {
|
let size =Size {
|
||||||
width: AvailableSpace::Definite(width as f32),
|
width: AvailableSpace::Definite(width),
|
||||||
height: AvailableSpace::Definite(height as f32),
|
height: AvailableSpace::Definite(height),
|
||||||
};
|
};
|
||||||
taffy
|
taffy
|
||||||
.compute_layout(
|
.compute_layout(
|
||||||
|
@ -195,8 +204,8 @@ fn render_vdom(
|
||||||
Rect {
|
Rect {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
width: 100,
|
width: 1000,
|
||||||
height: 100,
|
height: 1000,
|
||||||
},
|
},
|
||||||
&mut taffy.lock().expect("taffy lock poisoned"),
|
&mut taffy.lock().expect("taffy lock poisoned"),
|
||||||
&rdom,
|
&rdom,
|
||||||
|
|
|
@ -11,7 +11,7 @@ use taffy::{
|
||||||
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.
|
/// 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.
|
/// Provided as a root context for all tui applictions.
|
||||||
|
@ -72,19 +72,28 @@ impl<'a> ElementRef<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn size(&self) -> Option<Size<u32>> {
|
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>> {
|
pub fn pos(&self) -> Option<Point<u32>> {
|
||||||
self.layout().map(|l| Point {
|
self.layout().map(|l| Point {
|
||||||
x: l.location.x as u32,
|
x: l.location.x.round() as u32,
|
||||||
y: l.location.y as u32,
|
y: l.location.y.round() as u32,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layout(&self) -> Option<&Layout> {
|
pub fn layout(&self) -> Option<Layout> {
|
||||||
self.stretch
|
let layout = self
|
||||||
|
.stretch
|
||||||
.layout(self.inner[self.id].state.layout.node.ok()?)
|
.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 tui::{backend::CrosstermBackend, layout::Rect, style::Color};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
layout_to_screen_space,
|
||||||
style::{RinkColor, RinkStyle},
|
style::{RinkColor, RinkStyle},
|
||||||
style_attributes::{BorderEdge, BorderStyle},
|
style_attributes::{BorderEdge, BorderStyle},
|
||||||
widget::{RinkBuffer, RinkCell, RinkWidget, WidgetWithContext},
|
widget::{RinkBuffer, RinkCell, RinkWidget, WidgetWithContext},
|
||||||
|
@ -36,15 +37,12 @@ pub(crate) fn render_vnode(
|
||||||
location.x += parent_location.x;
|
location.x += parent_location.x;
|
||||||
location.y += parent_location.y;
|
location.y += parent_location.y;
|
||||||
|
|
||||||
let Point { mut x, mut y } = location;
|
let Point { x: fx, y: fy } = location;
|
||||||
x = x.floor();
|
let x = layout_to_screen_space(fx).round() as u16;
|
||||||
y = y.floor();
|
let y = layout_to_screen_space(fy).round() as u16;
|
||||||
let Size {
|
let Size { width, height } = *size;
|
||||||
mut width,
|
let width = layout_to_screen_space(fx + width).round() as u16 + x;
|
||||||
mut height,
|
let height = layout_to_screen_space(fy + height).round() as u16 - y;
|
||||||
} = size;
|
|
||||||
width = width.ceil();
|
|
||||||
height = height.ceil();
|
|
||||||
|
|
||||||
match &node.node_data.node_type {
|
match &node.node_data.node_type {
|
||||||
NodeType::Text { text } => {
|
NodeType::Text { text } => {
|
||||||
|
@ -69,7 +67,7 @@ pub(crate) fn render_vnode(
|
||||||
text,
|
text,
|
||||||
style: node.state.style.core,
|
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
|
// 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 {
|
if area.width > 0 && area.height > 0 {
|
||||||
|
@ -77,7 +75,7 @@ pub(crate) fn render_vnode(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NodeType::Element { .. } => {
|
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
|
// 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 {
|
if area.width > 0 && area.height > 0 {
|
||||||
|
|
Loading…
Reference in a new issue