diff --git a/packages/tui/examples/tui_widgets.rs b/packages/tui/examples/tui_widgets.rs index 298685999..793057bc5 100644 --- a/packages/tui/examples/tui_widgets.rs +++ b/packages/tui/examples/tui_widgets.rs @@ -41,49 +41,53 @@ fn app(cx: Scope) -> Element { height: "10%", maxlength: "11", } - // Input{ - // oninput: |data: FormData| { - // if (data.value.parse::().unwrap() - 40.0).abs() < 5.0 { - // bg_green.set(true); - // } else{ - // bg_green.set(false); - // } - // }, - // r#type: "range", - // min: "20", - // max: "80", - // } - // Input{ - // oninput: |data: FormData| { - // if data.value == "10"{ - // bg_green.set(true); - // } else{ - // bg_green.set(false); - // } - // }, - // r#type: "number", - // maxlength: "4", - // } - // Input{ - // oninput: |data: FormData| { - // if data.value == "hello world"{ - // bg_green.set(true); - // } else{ - // bg_green.set(false); - // } - // }, - // r#type: "password", - // width: "13px", - // height: "3px", - // maxlength: "11", - // } - // Input{ - // onclick: |_: FormData| bg_green.set(true), - // r#type: "button", - // value: "green", - // height: "3px", - // width: "7px", - // } + Input{ + oninput: |data: FormData| { + if (data.value.parse::().unwrap() - 40.0).abs() < 5.0 { + bg_green.set(true); + } else{ + bg_green.set(false); + } + }, + r#type: "range", + width: "50%", + height: "10%", + min: "20", + max: "80", + } + Input{ + oninput: |data: FormData| { + if data.value == "10"{ + bg_green.set(true); + } else{ + bg_green.set(false); + } + }, + r#type: "number", + width: "50%", + height: "10%", + maxlength: "4", + } + Input{ + oninput: |data: FormData| { + if data.value == "hello world"{ + bg_green.set(true); + } else{ + bg_green.set(false); + } + }, + r#type: "password", + width: "50%", + height: "10%", + maxlength: "11", + } + Input{ + onclick: |_: FormData| bg_green.set(true), + r#type: "button", + value: "green", + width: "50%", + height: "10%", + } } }) } diff --git a/packages/tui/src/layout.rs b/packages/tui/src/layout.rs index d863f13d8..ba50b59a6 100644 --- a/packages/tui/src/layout.rs +++ b/packages/tui/src/layout.rs @@ -7,7 +7,7 @@ use dioxus_native_core::state::ChildDepState; use dioxus_native_core_macro::sorted_str_slice; use taffy::prelude::*; -use crate::screen_to_layout_space; +use crate::{screen_to_layout_space, unit_to_layout_space}; #[derive(Debug, Clone, Copy, PartialEq)] pub(crate) enum PossiblyUninitalized { @@ -105,6 +105,59 @@ impl ChildDepState for TaffyLayout { child_layout.push(l.node.unwrap()); } + fn scale_dimention(d: Dimension) -> Dimension { + match d { + Dimension::Points(p) => Dimension::Points(unit_to_layout_space(p)), + Dimension::Percent(p) => Dimension::Percent(p), + Dimension::Auto => Dimension::Auto, + Dimension::Undefined => Dimension::Undefined, + } + } + let style = Style { + position: Rect { + left: scale_dimention(style.position.left), + right: scale_dimention(style.position.right), + top: scale_dimention(style.position.top), + bottom: scale_dimention(style.position.bottom), + }, + margin: Rect { + left: scale_dimention(style.margin.left), + right: scale_dimention(style.margin.right), + top: scale_dimention(style.margin.top), + bottom: scale_dimention(style.margin.bottom), + }, + padding: Rect { + left: scale_dimention(style.padding.left), + right: scale_dimention(style.padding.right), + top: scale_dimention(style.padding.top), + bottom: scale_dimention(style.padding.bottom), + }, + border: Rect { + left: scale_dimention(style.border.left), + right: scale_dimention(style.border.right), + top: scale_dimention(style.border.top), + bottom: scale_dimention(style.border.bottom), + }, + gap: Size { + width: scale_dimention(style.gap.width), + height: scale_dimention(style.gap.height), + }, + flex_basis: scale_dimention(style.flex_basis), + size: Size { + width: scale_dimention(style.size.width), + height: scale_dimention(style.size.height), + }, + min_size: Size { + width: scale_dimention(style.min_size.width), + height: scale_dimention(style.min_size.height), + }, + max_size: Size { + width: scale_dimention(style.max_size.width), + height: scale_dimention(style.max_size.height), + }, + ..style + }; + if let PossiblyUninitalized::Initialized(n) = self.node { if self.style != style { taffy.set_style(n, style).unwrap(); diff --git a/packages/tui/src/lib.rs b/packages/tui/src/lib.rs index b3430ab0d..7b4f72ce3 100644 --- a/packages/tui/src/lib.rs +++ b/packages/tui/src/lib.rs @@ -1,5 +1,6 @@ use anyhow::Result; use crossterm::{ + cursor::{MoveTo, RestorePosition, SavePosition, Show}, event::{DisableMouseCapture, EnableMouseCapture, Event as TermEvent, KeyCode, KeyModifiers}, execute, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, @@ -45,6 +46,10 @@ pub(crate) fn screen_to_layout_space(screen: u16) -> f32 { screen as f32 * 10.0 } +pub(crate) fn unit_to_layout_space(screen: f32) -> f32 { + screen * 10.0 +} + pub(crate) fn layout_to_screen_space(layout: f32) -> f32 { layout / 10.0 } @@ -138,7 +143,13 @@ fn render_vdom( let mut terminal = (!cfg.headless).then(|| { enable_raw_mode().unwrap(); let mut stdout = std::io::stdout(); - execute!(stdout, EnterAlternateScreen, EnableMouseCapture).unwrap(); + execute!( + stdout, + EnterAlternateScreen, + EnableMouseCapture, + MoveTo(0, 1000) + ) + .unwrap(); let backend = CrosstermBackend::new(io::stdout()); Terminal::new(backend).unwrap() }); @@ -183,14 +194,16 @@ fn render_vdom( taffy.compute_layout(root_node, size).unwrap(); } if let Some(terminal) = &mut terminal { + execute!(terminal.backend_mut(), SavePosition).unwrap(); terminal.draw(|frame| { let rdom = rdom.borrow(); let mut taffy = taffy.lock().expect("taffy lock poisoned"); // size is guaranteed to not change when rendering - resize(frame.size(), &mut *taffy, &rdom); + resize(frame.size(), &mut taffy, &rdom); let root = &rdom[NodeId(0)]; - render::render_vnode(frame, &*taffy, &rdom, root, cfg, Point::ZERO); + render::render_vnode(frame, &taffy, &rdom, root, cfg, Point::ZERO); })?; + execute!(terminal.backend_mut(), RestorePosition, Show).unwrap(); } else { let rdom = rdom.borrow(); resize( diff --git a/packages/tui/src/widgets/button.rs b/packages/tui/src/widgets/button.rs index c01cb0a25..f3ebc7901 100644 --- a/packages/tui/src/widgets/button.rs +++ b/packages/tui/src/widgets/button.rs @@ -42,6 +42,9 @@ pub(crate) fn Button<'a>(cx: Scope<'a, ButtonProps>) -> Element<'a> { width: "{width}", height: "{height}", border_style: "{border_style}", + flex_direction: "row", + align_items: "center", + justify_content: "center", onclick: move |_| { update(); }, diff --git a/packages/tui/src/widgets/number.rs b/packages/tui/src/widgets/number.rs index cef829425..4478246bb 100644 --- a/packages/tui/src/widgets/number.rs +++ b/packages/tui/src/widgets/number.rs @@ -206,26 +206,6 @@ pub(crate) fn NumbericInput<'a>(cx: Scope<'a, NumbericInputProps>) -> Element<'a } "{text_after_second_cursor}" - - div{ - background_color: "rgba(255, 255, 255, 50%)", - color: "black", - Input{ - r#type: "button", - onclick: move |_| { - decrease(); - } - value: "<", - } - " " - Input{ - r#type: "button", - onclick: move |_| { - increase(); - } - value: ">", - } - } } } } diff --git a/packages/tui/src/widgets/password.rs b/packages/tui/src/widgets/password.rs index bcb1b77cc..7f8455d71 100644 --- a/packages/tui/src/widgets/password.rs +++ b/packages/tui/src/widgets/password.rs @@ -88,7 +88,6 @@ pub(crate) fn Password<'a>(cx: Scope<'a, PasswordProps>) -> Element<'a> { width: "{width}", height: "{height}", border_style: "{border}", - align_items: "left", onkeydown: move |k| { if k.key()== Key::Enter { diff --git a/packages/tui/src/widgets/textbox.rs b/packages/tui/src/widgets/textbox.rs index f3ca3e24f..8628fca29 100644 --- a/packages/tui/src/widgets/textbox.rs +++ b/packages/tui/src/widgets/textbox.rs @@ -84,9 +84,6 @@ pub(crate) fn TextBox<'a>(cx: Scope<'a, TextBoxProps>) -> Element<'a> { width: "{width}", height: "{height}", border_style: "{border}", - flex_direction: "row", - align_items: "center", - justify_content: "center", onkeydown: move |k| { if k.key() == Key::Enter {