Evan Almloff пре 2 година
родитељ
комит
f6feb3f3f0

+ 5 - 1
packages/native-core/src/dioxus.rs

@@ -31,7 +31,11 @@ impl DioxusState {
     }
 
     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) {

+ 26 - 5
packages/tui/src/dioxus.rs

@@ -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_native_core::{
     dioxus::{DioxusState, NodeImmutableDioxusExt},
-    Renderer,
+    NodeId, Renderer,
 };
 
 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 dioxus_state = DioxusState::create(&mut rdom);
         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 {
             vdom,
             dioxus_state,
@@ -48,7 +52,7 @@ pub fn launch_cfg_with_props<Props: 'static>(app: Component<Props>, props: Props
 
 struct DioxusRenderer {
     vdom: VirtualDom,
-    dioxus_state: DioxusState,
+    dioxus_state: Rc<RwLock<DioxusState>>,
     #[cfg(all(feature = "hot-reload", debug_assertions))]
     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<()>) {
         let rdom = root.real_dom_mut();
         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(
@@ -107,3 +114,17 @@ impl Renderer<Rc<EventData>> for DioxusRenderer {
         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
packages/tui/src/focus.rs

@@ -271,12 +271,11 @@ impl FocusState {
 
     pub(crate) fn set_focus(&mut self, rdom: &mut RealDom, id: NodeId) {
         if let Some(old) = self.last_focused_id.replace(id) {
-            let focused = rdom.get_state_mut_raw::<Focused>(old).unwrap();
-            *focused = Focused(false);
+            let mut node = rdom.get_mut(old).unwrap();
+            node.insert(Focused(false));
         }
-        let focused = rdom.get_state_mut_raw::<Focused>(id).unwrap();
-        *focused = Focused(true);
-        let node = rdom.get(id).unwrap();
+        let mut node = rdom.get_mut(id).unwrap();
+        node.insert(Focused(true));
         self.focus_level = node.get::<Focus>().unwrap().level;
         // reset the position to the currently focused element
         while self.focus_iter.next(rdom).id() != id {}

+ 7 - 3
packages/tui/src/lib.rs

@@ -24,7 +24,7 @@ use tokio::select;
 use tui::{backend::CrosstermBackend, layout::Rect, Terminal};
 
 mod config;
-#[cfg(feature = "dioxus")]
+#[cfg(feature = "dioxus-bindings")]
 pub mod dioxus;
 mod focus;
 mod hooks;
@@ -36,12 +36,16 @@ mod render;
 mod style;
 mod style_attributes;
 mod widget;
-// mod widgets;
+#[cfg(feature = "dioxus-bindings")]
+mod widgets;
 
-#[cfg(feature = "dioxus")]
+#[cfg(feature = "dioxus-bindings")]
 pub use crate::dioxus::*;
 pub use config::*;
 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
 pub(crate) fn screen_to_layout_space(screen: u16) -> f32 {

+ 2 - 1
packages/tui/src/prelude/mod.rs

@@ -1 +1,2 @@
-// pub use crate::widgets::*;
+#[cfg(feature = "dioxus-bindings")]
+pub use crate::widgets::*;

+ 7 - 3
packages/tui/src/widgets/mod.rs

@@ -6,12 +6,16 @@ mod password;
 mod slider;
 mod textbox;
 
-use dioxus_core::{ElementId, RenderReturn, Scope};
+use dioxus_core::{RenderReturn, Scope};
+use dioxus_native_core::NodeId;
 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() {
-        sync.root_ids.get(0)
+        let mapping: DioxusElementToNodeId = cx.consume_context()?;
+        mapping.get_node_id(sync.root_ids.get(0)?)
     } else {
         None
     }

+ 1 - 1
packages/tui/src/widgets/number.rs

@@ -113,7 +113,7 @@ pub(crate) fn NumbericInput<'a>(cx: Scope<'a, NumbericInputProps>) -> Element<'a
                 };
                 if is_text{
                     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());
 
                     let node = tui_query.get(get_root_id(cx).unwrap());

+ 3 - 1
packages/tui/src/widgets/password.rs

@@ -88,7 +88,9 @@ pub(crate) fn Password<'a>(cx: Scope<'a, PasswordProps>) -> Element<'a> {
             return;
         }
         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 {
             input_handler.call(FormData {
                 value: text.clone(),

+ 1 - 1
packages/tui/src/widgets/textbox.rs

@@ -90,7 +90,7 @@ pub(crate) fn TextBox<'a>(cx: Scope<'a, TextBoxProps>) -> Element<'a> {
                     return;
                 }
                 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{
                     input_handler.call(FormData{
                         value: text.clone(),