fix widgets in tui

This commit is contained in:
Evan Almloff committed 2023-02-10 10:56:24 -06:00
1 parent f6feb3f3f0
commit db04550fc8
5 files changed
+73 -51

No files matched your search

-9
View File
@@ -1,12 +1,9 @@
use std::any::Any; use std::any::Any;
use std::future::Future;
use std::hash::BuildHasherDefault; use std::hash::BuildHasherDefault;
use std::pin::Pin;
pub use node_ref::NodeMask; pub use node_ref::NodeMask;
pub use passes::AnyMapLike; pub use passes::AnyMapLike;
pub use passes::{Dependancy, Pass, TypeErasedPass}; pub use passes::{Dependancy, Pass, TypeErasedPass};
use prelude::FromAnyValue;
pub use real_dom::{NodeMut, NodeRef, RealDom}; pub use real_dom::{NodeMut, NodeRef, RealDom};
use rustc_hash::FxHasher; use rustc_hash::FxHasher;
pub use tree::NodeId; pub use tree::NodeId;
@@ -34,9 +31,3 @@ pub mod prelude {
pub type FxDashMap<K, V> = dashmap::DashMap<K, V, BuildHasherDefault<FxHasher>>; pub type FxDashMap<K, V> = dashmap::DashMap<K, V, BuildHasherDefault<FxHasher>>;
pub type FxDashSet<K> = dashmap::DashSet<K, BuildHasherDefault<FxHasher>>; pub type FxDashSet<K> = dashmap::DashSet<K, BuildHasherDefault<FxHasher>>;
pub type SendAnyMap = anymap::Map<dyn Any + Send + Sync + 'static>; pub type SendAnyMap = anymap::Map<dyn Any + Send + Sync + 'static>;
pub trait Renderer<E, V: FromAnyValue + Send + Sync = ()> {
fn render(&mut self, root: NodeMut<V>);
fn handle_event(&mut self, node: NodeMut<V>, event: &str, value: E, bubbles: bool);
fn poll_async(&mut self) -> Pin<Box<dyn Future<Output = ()> + '_>>;
}
+17 -12
View File
@@ -2,14 +2,13 @@ use dioxus_html::EventData;
use dioxus_native_core::{ use dioxus_native_core::{
node::{OwnedAttributeDiscription, OwnedAttributeValue, TextNode}, node::{OwnedAttributeDiscription, OwnedAttributeValue, TextNode},
prelude::*, prelude::*,
real_dom::{ElementNodeMut, NodeImmutable, NodeTypeMut}, real_dom::{NodeImmutable, NodeTypeMut},
NodeId, Renderer, NodeId,
}; };
use dioxus_tui::{self, render, Config}; use dioxus_tui::{self, render, Config, Renderer};
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
use std::rc::Rc;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use std::{rc::Rc, sync::Mutex};
use taffy::Taffy;
const SIZE: usize = 10; const SIZE: usize = 10;
@@ -184,11 +183,14 @@ impl Test {
} }
} }
impl Renderer<Rc<EventData>> for Test { impl Renderer for Test {
fn render(&mut self, mut root: dioxus_native_core::NodeMut) { fn render(&mut self, rdom: &Arc<RwLock<RealDom>>) {
let mut rdom = rdom.write().unwrap();
let root_id = rdom.root_id();
let mut root = rdom.get_mut(root_id).unwrap();
for (x, y) in self.dirty.drain() { for (x, y) in self.dirty.drain() {
let row_id = root.child_ids().unwrap()[x]; let row_id = root.child_ids().unwrap()[x];
let mut rdom = root.real_dom_mut(); let rdom = root.real_dom_mut();
let row = rdom.get(row_id).unwrap(); let row = rdom.get(row_id).unwrap();
let node_id = row.child_ids().unwrap()[y]; let node_id = row.child_ids().unwrap()[y];
let mut node = rdom.get_mut(node_id).unwrap(); let mut node = rdom.get_mut(node_id).unwrap();
@@ -216,11 +218,14 @@ impl Renderer<Rc<EventData>> for Test {
fn handle_event( fn handle_event(
&mut self, &mut self,
node: dioxus_native_core::NodeMut<()>, rdom: &Arc<RwLock<RealDom>>,
event: &str, id: NodeId,
value: Rc<EventData>, _: &str,
bubbles: bool, _: Rc<EventData>,
_: bool,
) { ) {
let rdom = rdom.read().unwrap();
let node = rdom.get(id).unwrap();
if let Some(parent) = node.parent() { if let Some(parent) = node.parent() {
let child_number = parent let child_number = parent
.child_ids() .child_ids()
+20 -12
View File
@@ -1,13 +1,17 @@
use std::{ops::Deref, rc::Rc, sync::RwLock}; use std::{
ops::Deref,
rc::Rc,
sync::{Arc, RwLock},
};
use dioxus_core::{Component, ElementId, 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},
NodeId, Renderer, NodeId, RealDom,
}; };
use crate::{query::Query, render, Config, TuiContext}; use crate::{query::Query, render, Config, Renderer, TuiContext};
pub fn launch(app: Component<()>) { pub fn launch(app: Component<()>) {
launch_cfg(app, Config::default()) launch_cfg(app, Config::default())
@@ -57,24 +61,28 @@ struct DioxusRenderer {
hot_reload_rx: tokio::sync::mpsc::UnboundedReceiver<dioxus_hot_reload::HotReloadMsg>, hot_reload_rx: tokio::sync::mpsc::UnboundedReceiver<dioxus_hot_reload::HotReloadMsg>,
} }
impl Renderer<Rc<EventData>> for DioxusRenderer { impl Renderer for DioxusRenderer {
fn render(&mut self, mut root: dioxus_native_core::NodeMut<()>) { fn render(&mut self, rdom: &Arc<RwLock<RealDom>>) {
let rdom = root.real_dom_mut();
let muts = self.vdom.render_immediate(); let muts = self.vdom.render_immediate();
self.dioxus_state {
.write() let mut rdom = rdom.write().unwrap();
.unwrap() self.dioxus_state
.apply_mutations(rdom, muts); .write()
.unwrap()
.apply_mutations(&mut rdom, muts);
}
} }
fn handle_event( fn handle_event(
&mut self, &mut self,
node: dioxus_native_core::NodeMut<()>, rdom: &Arc<RwLock<RealDom>>,
id: NodeId,
event: &str, event: &str,
value: Rc<EventData>, value: Rc<EventData>,
bubbles: bool, bubbles: bool,
) { ) {
if let Some(id) = node.mounted_id() { let id = { rdom.read().unwrap().get(id).unwrap().mounted_id() };
if let Some(id) = id {
self.vdom self.vdom
.handle_event(event, value.deref().clone().into_any(), id, bubbles); .handle_event(event, value.deref().clone().into_any(), id, bubbles);
} }
+32 -16
View File
@@ -7,15 +7,18 @@ use crossterm::{
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
}; };
use dioxus_html::EventData; use dioxus_html::EventData;
use dioxus_native_core::{node_ref::NodeMaskBuilder, real_dom::NodeImmutable, Pass, Renderer}; use dioxus_native_core::{node_ref::NodeMaskBuilder, real_dom::NodeImmutable, Pass};
use dioxus_native_core::{real_dom::RealDom, FxDashSet, NodeId, SendAnyMap}; use dioxus_native_core::{real_dom::RealDom, FxDashSet, NodeId, SendAnyMap};
use focus::FocusState; use focus::FocusState;
use futures::{channel::mpsc::UnboundedSender, pin_mut, StreamExt}; use futures::{channel::mpsc::UnboundedSender, pin_mut, Future, StreamExt};
use futures_channel::mpsc::unbounded; use futures_channel::mpsc::unbounded;
use layout::TaffyLayout; use layout::TaffyLayout;
use prevent_default::PreventDefault; use prevent_default::PreventDefault;
use std::sync::{Arc, Mutex};
use std::{io, time::Duration}; use std::{io, time::Duration};
use std::{
pin::Pin,
sync::{Arc, Mutex},
};
use std::{rc::Rc, sync::RwLock}; use std::{rc::Rc, sync::RwLock};
use style_attributes::StyleModifier; use style_attributes::StyleModifier;
use taffy::Taffy; use taffy::Taffy;
@@ -77,7 +80,7 @@ impl TuiContext {
} }
} }
pub fn render<R: Renderer<Rc<EventData>>>( pub fn render<R: Renderer>(
cfg: Config, cfg: Config,
create_renderer: impl FnOnce( create_renderer: impl FnOnce(
&Arc<RwLock<RealDom>>, &Arc<RwLock<RealDom>>,
@@ -116,11 +119,10 @@ pub fn render<R: Renderer<Rc<EventData>>>(
let mut renderer = create_renderer(&rdom, &taffy, event_tx_clone); let mut renderer = create_renderer(&rdom, &taffy, event_tx_clone);
{ {
let mut rdom = rdom.write().unwrap(); renderer.render(&rdom);
let root_id = rdom.root_id();
renderer.render(rdom.get_mut(root_id).unwrap());
let mut any_map = SendAnyMap::new(); let mut any_map = SendAnyMap::new();
any_map.insert(taffy.clone()); any_map.insert(taffy.clone());
let mut rdom = rdom.write().unwrap();
let _ = rdom.update_state(any_map, false); let _ = rdom.update_state(any_map, false);
} }
@@ -201,7 +203,7 @@ pub fn render<R: Renderer<Rc<EventData>>>(
})?; })?;
execute!(terminal.backend_mut(), RestorePosition, Show).unwrap(); execute!(terminal.backend_mut(), RestorePosition, Show).unwrap();
} else { } else {
let rdom = rdom.write().unwrap(); let rdom = rdom.read().unwrap();
resize( resize(
Rect { Rect {
x: 0, x: 0,
@@ -250,21 +252,22 @@ pub fn render<R: Renderer<Rc<EventData>>>(
{ {
{ {
let mut rdom = rdom.write().unwrap(); let evts = {
let evts = handler handler.get_events(
.get_events(&taffy.lock().expect("taffy lock poisoned"), &mut rdom); &taffy.lock().expect("taffy lock poisoned"),
&mut rdom.write().unwrap(),
)
};
updated |= handler.state().focus_state.clean(); updated |= handler.state().focus_state.clean();
for e in evts { for e in evts {
let node = rdom.get_mut(e.id).unwrap(); renderer.handle_event(&rdom, e.id, e.name, e.data, e.bubbles);
renderer.handle_event(node, e.name, e.data, e.bubbles);
} }
} }
let mut rdom = rdom.write().unwrap();
// updates the dom's nodes // updates the dom's nodes
let root_id = rdom.root_id(); renderer.render(&rdom);
renderer.render(rdom.get_mut(root_id).unwrap());
// update the style and layout // update the style and layout
let mut rdom = rdom.write().unwrap();
let mut any_map = SendAnyMap::new(); let mut any_map = SendAnyMap::new();
any_map.insert(taffy.clone()); any_map.insert(taffy.clone());
let (new_to_rerender, dirty) = rdom.update_state(any_map, false); let (new_to_rerender, dirty) = rdom.update_state(any_map, false);
@@ -297,3 +300,16 @@ pub enum InputEvent {
UserInput(TermEvent), UserInput(TermEvent),
Close, Close,
} }
pub trait Renderer {
fn render(&mut self, rdom: &Arc<RwLock<RealDom>>);
fn handle_event(
&mut self,
rdom: &Arc<RwLock<RealDom>>,
id: NodeId,
event: &str,
value: Rc<EventData>,
bubbles: bool,
);
fn poll_async(&mut self) -> Pin<Box<dyn Future<Output = ()> + '_>>;
}
+4 -2
View File
@@ -48,9 +48,11 @@ pub struct Query {
impl Query { impl Query {
pub fn get(&self, id: NodeId) -> ElementRef { pub fn get(&self, id: NodeId) -> ElementRef {
let rdom = self.rdom.read();
let stretch = self.stretch.lock();
ElementRef::new( ElementRef::new(
self.rdom.read().expect("rdom lock poisoned"), rdom.expect("rdom lock poisoned"),
self.stretch.lock().expect("taffy lock poisoned"), stretch.expect("taffy lock poisoned"),
id, id,
) )
} }