Explorar el Código

refactor prevent-default

Evan Almloff hace 3 años
padre
commit
acfde71d7e
Se han modificado 3 ficheros con 96 adiciones y 27 borrados
  1. 3 7
      packages/tui/src/focus.rs
  2. 2 20
      packages/tui/src/lib.rs
  3. 91 0
      packages/tui/src/node.rs

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

@@ -1,4 +1,4 @@
-use crate::Dom;
+use crate::{node::PreventDefault, Dom};
 
 use dioxus_core::ElementId;
 use dioxus_native_core::utils::{ElementProduced, PersistantElementIter};
@@ -59,7 +59,6 @@ impl Default for FocusLevel {
 
 #[derive(Clone, PartialEq, Debug, Default)]
 pub(crate) struct Focus {
-    pub pass_focus: bool,
     pub level: FocusLevel,
 }
 
@@ -71,9 +70,6 @@ impl NodeDepState for Focus {
 
     fn reduce(&mut self, node: NodeView<'_>, _sibling: &Self::DepState, _: &Self::Ctx) -> bool {
         let new = Focus {
-            pass_focus: !node
-                .attributes()
-                .any(|a| a.name == "dioxus-prevent-default" && a.value.trim() == "keydown"),
             level: if let Some(a) = node.attributes().find(|a| a.name == "tabindex") {
                 if let Ok(index) = a.value.parse::<i32>() {
                     match index.cmp(&0) {
@@ -106,7 +102,7 @@ impl NodeDepState for Focus {
 }
 
 const FOCUS_EVENTS: &[&str] = &sorted_str_slice!(["keydown", "keypress", "keyup"]);
-const FOCUS_ATTRIBUTES: &[&str] = &sorted_str_slice!(["dioxus-prevent-default", "tabindex"]);
+const FOCUS_ATTRIBUTES: &[&str] = &sorted_str_slice!(["tabindex"]);
 
 #[derive(Default)]
 pub(crate) struct FocusState {
@@ -120,7 +116,7 @@ impl FocusState {
     /// Returns true if the focus has changed.
     pub fn progress(&mut self, rdom: &mut Dom, forward: bool) -> bool {
         if let Some(last) = self.last_focused_id {
-            if !rdom[last].state.focus.pass_focus {
+            if rdom[last].state.prevent_default == PreventDefault::KeyDown {
                 return false;
             }
         }

+ 2 - 20
packages/tui/src/lib.rs

@@ -8,26 +8,22 @@ use crossterm::{
 use dioxus_core::exports::futures_channel::mpsc::unbounded;
 use dioxus_core::*;
 use dioxus_native_core::real_dom::RealDom;
-use dioxus_native_core::state::*;
-use dioxus_native_core_macro::State;
-use focus::Focus;
 use focus::FocusState;
 use futures::{
     channel::mpsc::{UnboundedReceiver, UnboundedSender},
     pin_mut, StreamExt,
 };
-use layout::StretchLayout;
 use std::cell::RefCell;
 use std::rc::Rc;
 use std::{io, time::Duration};
 use stretch2::{prelude::Size, Stretch};
-use style_attributes::StyleModifier;
 use tui::{backend::CrosstermBackend, layout::Rect, Terminal};
 
 mod config;
 mod focus;
 mod hooks;
 mod layout;
+mod node;
 mod render;
 mod style;
 mod style_attributes;
@@ -35,21 +31,7 @@ mod widget;
 
 pub use config::*;
 pub use hooks::*;
-
-type Dom = RealDom<NodeState>;
-type Node = dioxus_native_core::real_dom::Node<NodeState>;
-
-#[derive(Debug, Clone, State, Default)]
-struct NodeState {
-    #[child_dep_state(layout, RefCell<Stretch>)]
-    layout: StretchLayout,
-    // depends on attributes, the C component of it's parent and a u8 context
-    #[parent_dep_state(style)]
-    style: StyleModifier,
-    #[node_dep_state()]
-    focus: Focus,
-    focused: bool,
-}
+pub(crate) use node::*;
 
 #[derive(Clone)]
 pub struct TuiContext {

+ 91 - 0
packages/tui/src/node.rs

@@ -0,0 +1,91 @@
+use crate::focus::Focus;
+use crate::layout::StretchLayout;
+use crate::style_attributes::StyleModifier;
+use dioxus_native_core::{real_dom::RealDom, state::*};
+use dioxus_native_core_macro::State;
+
+pub(crate) type Dom = RealDom<NodeState>;
+pub(crate) type Node = dioxus_native_core::real_dom::Node<NodeState>;
+
+#[derive(Debug, Clone, State, Default)]
+pub(crate) struct NodeState {
+    #[child_dep_state(layout, RefCell<Stretch>)]
+    pub layout: StretchLayout,
+    // depends on attributes, the C component of it's parent and a u8 context
+    #[parent_dep_state(style)]
+    pub style: StyleModifier,
+    #[node_dep_state()]
+    pub prevent_default: PreventDefault,
+    #[node_dep_state()]
+    pub focus: Focus,
+    pub focused: bool,
+}
+
+#[derive(PartialEq, Debug, Clone)]
+pub(crate) enum PreventDefault {
+    Focus,
+    KeyPress,
+    KeyRelease,
+    KeyDown,
+    KeyUp,
+    MouseDown,
+    Click,
+    MouseEnter,
+    MouseLeave,
+    MouseOut,
+    Unknown,
+    MouseOver,
+    ContextMenu,
+    Wheel,
+    MouseUp,
+}
+
+impl Default for PreventDefault {
+    fn default() -> Self {
+        PreventDefault::Unknown
+    }
+}
+
+impl NodeDepState for PreventDefault {
+    type Ctx = ();
+
+    type DepState = ();
+
+    const NODE_MASK: dioxus_native_core::node_ref::NodeMask =
+        dioxus_native_core::node_ref::NodeMask::NONE;
+
+    fn reduce(
+        &mut self,
+        node: dioxus_native_core::node_ref::NodeView,
+        _sibling: &Self::DepState,
+        _ctx: &Self::Ctx,
+    ) -> bool {
+        let new = match node
+            .attributes()
+            .find(|a| a.name == "dioxus-prevent-default")
+            .map(|a| a.value)
+        {
+            Some("focus") => PreventDefault::Focus,
+            Some("keypress") => PreventDefault::KeyPress,
+            Some("keyrelease") => PreventDefault::KeyRelease,
+            Some("keydown") => PreventDefault::KeyDown,
+            Some("keyup") => PreventDefault::KeyUp,
+            Some("click") => PreventDefault::Click,
+            Some("mousedown") => PreventDefault::MouseDown,
+            Some("mouseup") => PreventDefault::MouseUp,
+            Some("mouseenter") => PreventDefault::MouseEnter,
+            Some("mouseover") => PreventDefault::MouseOver,
+            Some("mouseleave") => PreventDefault::MouseLeave,
+            Some("mouseout") => PreventDefault::MouseOut,
+            Some("wheel") => PreventDefault::Wheel,
+            Some("contextmenu") => PreventDefault::ContextMenu,
+            _ => return false,
+        };
+        if new == *self {
+            false
+        } else {
+            *self = new;
+            true
+        }
+    }
+}