fix tui widgets

This commit is contained in:
Evan Almloff committed 2023-02-09 21:34:47 -06:00
1 parent ff408c17de
commit f6feb3f3f0
9 files changed
+56 -21

No files matched your search

+5 -1
View File
@@ -31,7 +31,11 @@ impl DioxusState {
} }
pub fn element_to_node_id(&self, element_id: ElementId) -> NodeId { pub fn element_to_node_id(&self, element_id: ElementId) -> NodeId {
self.node_id_mapping.get(element_id.0).unwrap().unwrap() self.try_element_to_node_id(element_id).unwrap()
}
pub fn try_element_to_node_id(&self, element_id: ElementId) -> Option<NodeId> {
self.node_id_mapping.get(element_id.0).copied().flatten()
} }
fn set_element_id(&mut self, mut node: NodeMut, element_id: ElementId) { fn set_element_id(&mut self, mut node: NodeMut, element_id: ElementId) {
+26 -5
View File
@@ -1,10 +1,10 @@
use std::{ops::Deref, rc::Rc}; use std::{ops::Deref, rc::Rc, sync::RwLock};
use dioxus_core::{Component, VirtualDom}; use dioxus_core::{Component, ElementId, VirtualDom};
use dioxus_html::EventData; use dioxus_html::EventData;
use dioxus_native_core::{ use dioxus_native_core::{
dioxus::{DioxusState, NodeImmutableDioxusExt}, dioxus::{DioxusState, NodeImmutableDioxusExt},
Renderer, NodeId, Renderer,
}; };
use crate::{query::Query, render, Config, TuiContext}; use crate::{query::Query, render, Config, TuiContext};
@@ -29,6 +29,10 @@ pub fn launch_cfg_with_props<Props: 'static>(app: Component<Props>, props: Props
let mut rdom = rdom.write().unwrap(); let mut rdom = rdom.write().unwrap();
let mut dioxus_state = DioxusState::create(&mut rdom); let mut dioxus_state = DioxusState::create(&mut rdom);
dioxus_state.apply_mutations(&mut rdom, muts); dioxus_state.apply_mutations(&mut rdom, muts);
let dioxus_state = Rc::new(RwLock::new(dioxus_state));
vdom = vdom.with_root_context(DioxusElementToNodeId {
mapping: dioxus_state.clone(),
});
DioxusRenderer { DioxusRenderer {
vdom, vdom,
dioxus_state, dioxus_state,
@@ -48,7 +52,7 @@ pub fn launch_cfg_with_props<Props: 'static>(app: Component<Props>, props: Props
struct DioxusRenderer { struct DioxusRenderer {
vdom: VirtualDom, vdom: VirtualDom,
dioxus_state: DioxusState, dioxus_state: Rc<RwLock<DioxusState>>,
#[cfg(all(feature = "hot-reload", debug_assertions))] #[cfg(all(feature = "hot-reload", debug_assertions))]
hot_reload_rx: tokio::sync::mpsc::UnboundedReceiver<dioxus_hot_reload::HotReloadMsg>, hot_reload_rx: tokio::sync::mpsc::UnboundedReceiver<dioxus_hot_reload::HotReloadMsg>,
} }
@@ -57,7 +61,10 @@ impl Renderer<Rc<EventData>> for DioxusRenderer {
fn render(&mut self, mut root: dioxus_native_core::NodeMut<()>) { fn render(&mut self, mut root: dioxus_native_core::NodeMut<()>) {
let rdom = root.real_dom_mut(); let rdom = root.real_dom_mut();
let muts = self.vdom.render_immediate(); let muts = self.vdom.render_immediate();
self.dioxus_state.apply_mutations(rdom, muts); self.dioxus_state
.write()
.unwrap()
.apply_mutations(rdom, muts);
} }
fn handle_event( fn handle_event(
@@ -107,3 +114,17 @@ impl Renderer<Rc<EventData>> for DioxusRenderer {
Box::pin(self.vdom.wait_for_work()) Box::pin(self.vdom.wait_for_work())
} }
} }
#[derive(Clone)]
pub struct DioxusElementToNodeId {
mapping: Rc<RwLock<DioxusState>>,
}
impl DioxusElementToNodeId {
pub fn get_node_id(&self, element_id: ElementId) -> Option<NodeId> {
self.mapping
.read()
.unwrap()
.try_element_to_node_id(element_id)
}
}
+4 -5
View File
@@ -271,12 +271,11 @@ impl FocusState {
pub(crate) fn set_focus(&mut self, rdom: &mut RealDom, id: NodeId) { pub(crate) fn set_focus(&mut self, rdom: &mut RealDom, id: NodeId) {
if let Some(old) = self.last_focused_id.replace(id) { if let Some(old) = self.last_focused_id.replace(id) {
let focused = rdom.get_state_mut_raw::<Focused>(old).unwrap(); let mut node = rdom.get_mut(old).unwrap();
*focused = Focused(false); node.insert(Focused(false));
} }
let focused = rdom.get_state_mut_raw::<Focused>(id).unwrap(); let mut node = rdom.get_mut(id).unwrap();
*focused = Focused(true); node.insert(Focused(true));
let node = rdom.get(id).unwrap();
self.focus_level = node.get::<Focus>().unwrap().level; self.focus_level = node.get::<Focus>().unwrap().level;
// reset the position to the currently focused element // reset the position to the currently focused element
while self.focus_iter.next(rdom).id() != id {} while self.focus_iter.next(rdom).id() != id {}
+7 -3
View File
@@ -24,7 +24,7 @@ use tokio::select;
use tui::{backend::CrosstermBackend, layout::Rect, Terminal}; use tui::{backend::CrosstermBackend, layout::Rect, Terminal};
mod config; mod config;
#[cfg(feature = "dioxus")] #[cfg(feature = "dioxus-bindings")]
pub mod dioxus; pub mod dioxus;
mod focus; mod focus;
mod hooks; mod hooks;
@@ -36,12 +36,16 @@ mod render;
mod style; mod style;
mod style_attributes; mod style_attributes;
mod widget; mod widget;
// mod widgets; #[cfg(feature = "dioxus-bindings")]
mod widgets;
#[cfg(feature = "dioxus")] #[cfg(feature = "dioxus-bindings")]
pub use crate::dioxus::*; pub use crate::dioxus::*;
pub use config::*; pub use config::*;
pub use hooks::*; pub use hooks::*;
pub use query::Query;
#[cfg(feature = "dioxus-bindings")]
pub use widgets::*;
// the layout space has a multiplier of 10 to minimize rounding errors // the layout space has a multiplier of 10 to minimize rounding errors
pub(crate) fn screen_to_layout_space(screen: u16) -> f32 { pub(crate) fn screen_to_layout_space(screen: u16) -> f32 {
+2 -1
View File
@@ -1 +1,2 @@
// pub use crate::widgets::*; #[cfg(feature = "dioxus-bindings")]
pub use crate::widgets::*;
+7 -3
View File
@@ -6,12 +6,16 @@ mod password;
mod slider; mod slider;
mod textbox; mod textbox;
use dioxus_core::{ElementId, RenderReturn, Scope}; use dioxus_core::{RenderReturn, Scope};
use dioxus_native_core::NodeId;
pub use input::*; pub use input::*;
pub(crate) fn get_root_id<T>(cx: Scope<T>) -> Option<ElementId> { use crate::DioxusElementToNodeId;
pub(crate) fn get_root_id<T>(cx: Scope<T>) -> Option<NodeId> {
if let RenderReturn::Ready(sync) = cx.root_node() { if let RenderReturn::Ready(sync) = cx.root_node() {
sync.root_ids.get(0) let mapping: DioxusElementToNodeId = cx.consume_context()?;
mapping.get_node_id(sync.root_ids.get(0)?)
} else { } else {
None None
} }
+1 -1
View File
@@ -113,7 +113,7 @@ pub(crate) fn NumbericInput<'a>(cx: Scope<'a, NumbericInputProps>) -> Element<'a
}; };
if is_text{ if is_text{
let mut text = text_ref.write(); let mut text = text_ref.write();
cursor.write().handle_input(&k, &mut *text, max_len); cursor.write().handle_input(&k.code(), &k.key(), &k.modifiers(), &mut *text, max_len);
update(text.clone()); update(text.clone());
let node = tui_query.get(get_root_id(cx).unwrap()); let node = tui_query.get(get_root_id(cx).unwrap());
+3 -1
View File
@@ -88,7 +88,9 @@ pub(crate) fn Password<'a>(cx: Scope<'a, PasswordProps>) -> Element<'a> {
return; return;
} }
let mut text = text_ref.write(); let mut text = text_ref.write();
cursor.write().handle_input(&k, &mut *text, max_len); cursor
.write()
.handle_input(&k.code(), &k.key(), &k.modifiers(), &mut *text, max_len);
if let Some(input_handler) = &cx.props.raw_oninput { if let Some(input_handler) = &cx.props.raw_oninput {
input_handler.call(FormData { input_handler.call(FormData {
value: text.clone(), value: text.clone(),
+1 -1
View File
@@ -90,7 +90,7 @@ pub(crate) fn TextBox<'a>(cx: Scope<'a, TextBoxProps>) -> Element<'a> {
return; return;
} }
let mut text = text_ref.write(); let mut text = text_ref.write();
cursor.write().handle_input(&k, &mut *text, max_len); cursor.write().handle_input(&k.code(), &k.key(), &k.modifiers(), &mut *text, max_len);
if let Some(input_handler) = &cx.props.raw_oninput{ if let Some(input_handler) = &cx.props.raw_oninput{
input_handler.call(FormData{ input_handler.call(FormData{
value: text.clone(), value: text.clone(),