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::future::Future;
use std::hash::BuildHasherDefault;
use std::pin::Pin;
pub use node_ref::NodeMask;
pub use passes::AnyMapLike;
pub use passes::{Dependancy, Pass, TypeErasedPass};
use prelude::FromAnyValue;
pub use real_dom::{NodeMut, NodeRef, RealDom};
use rustc_hash::FxHasher;
pub use tree::NodeId;
@@ -34,9 +31,3 @@ pub mod prelude {
pub type FxDashMap<K, V> = dashmap::DashMap<K, V, BuildHasherDefault<FxHasher>>;
pub type FxDashSet<K> = dashmap::DashSet<K, BuildHasherDefault<FxHasher>>;
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::{
node::{OwnedAttributeDiscription, OwnedAttributeValue, TextNode},
prelude::*,
real_dom::{ElementNodeMut, NodeImmutable, NodeTypeMut},
NodeId, Renderer,
real_dom::{NodeImmutable, NodeTypeMut},
NodeId,
};
use dioxus_tui::{self, render, Config};
use dioxus_tui::{self, render, Config, Renderer};
use rustc_hash::FxHashSet;
use std::rc::Rc;
use std::sync::{Arc, RwLock};
use std::{rc::Rc, sync::Mutex};
use taffy::Taffy;
const SIZE: usize = 10;
@@ -184,11 +183,14 @@ impl Test {
}
}
impl Renderer<Rc<EventData>> for Test {
fn render(&mut self, mut root: dioxus_native_core::NodeMut) {
impl Renderer for Test {
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() {
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 node_id = row.child_ids().unwrap()[y];
let mut node = rdom.get_mut(node_id).unwrap();
@@ -216,11 +218,14 @@ impl Renderer<Rc<EventData>> for Test {
fn handle_event(
&mut self,
node: dioxus_native_core::NodeMut<()>,
event: &str,
value: Rc<EventData>,
bubbles: bool,
rdom: &Arc<RwLock<RealDom>>,
id: NodeId,
_: &str,
_: Rc<EventData>,
_: bool,
) {
let rdom = rdom.read().unwrap();
let node = rdom.get(id).unwrap();
if let Some(parent) = node.parent() {
let child_number = parent
.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_html::EventData;
use dioxus_native_core::{
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<()>) {
launch_cfg(app, Config::default())
@@ -57,24 +61,28 @@ struct DioxusRenderer {
hot_reload_rx: tokio::sync::mpsc::UnboundedReceiver<dioxus_hot_reload::HotReloadMsg>,
}
impl Renderer<Rc<EventData>> for DioxusRenderer {
fn render(&mut self, mut root: dioxus_native_core::NodeMut<()>) {
let rdom = root.real_dom_mut();
impl Renderer for DioxusRenderer {
fn render(&mut self, rdom: &Arc<RwLock<RealDom>>) {
let muts = self.vdom.render_immediate();
self.dioxus_state
.write()
.unwrap()
.apply_mutations(rdom, muts);
{
let mut rdom = rdom.write().unwrap();
self.dioxus_state
.write()
.unwrap()
.apply_mutations(&mut rdom, muts);
}
}
fn handle_event(
&mut self,
node: dioxus_native_core::NodeMut<()>,
rdom: &Arc<RwLock<RealDom>>,
id: NodeId,
event: &str,
value: Rc<EventData>,
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
.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},
};
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 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 layout::TaffyLayout;
use prevent_default::PreventDefault;
use std::sync::{Arc, Mutex};
use std::{io, time::Duration};
use std::{
pin::Pin,
sync::{Arc, Mutex},
};
use std::{rc::Rc, sync::RwLock};
use style_attributes::StyleModifier;
use taffy::Taffy;
@@ -77,7 +80,7 @@ impl TuiContext {
}
}
pub fn render<R: Renderer<Rc<EventData>>>(
pub fn render<R: Renderer>(
cfg: Config,
create_renderer: impl FnOnce(
&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 rdom = rdom.write().unwrap();
let root_id = rdom.root_id();
renderer.render(rdom.get_mut(root_id).unwrap());
renderer.render(&rdom);
let mut any_map = SendAnyMap::new();
any_map.insert(taffy.clone());
let mut rdom = rdom.write().unwrap();
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();
} else {
let rdom = rdom.write().unwrap();
let rdom = rdom.read().unwrap();
resize(
Rect {
x: 0,
@@ -250,21 +252,22 @@ pub fn render<R: Renderer<Rc<EventData>>>(
{
{
let mut rdom = rdom.write().unwrap();
let evts = handler
.get_events(&taffy.lock().expect("taffy lock poisoned"), &mut rdom);
let evts = {
handler.get_events(
&taffy.lock().expect("taffy lock poisoned"),
&mut rdom.write().unwrap(),
)
};
updated |= handler.state().focus_state.clean();
for e in evts {
let node = rdom.get_mut(e.id).unwrap();
renderer.handle_event(node, e.name, e.data, e.bubbles);
renderer.handle_event(&rdom, e.id, e.name, e.data, e.bubbles);
}
}
let mut rdom = rdom.write().unwrap();
// updates the dom's nodes
let root_id = rdom.root_id();
renderer.render(rdom.get_mut(root_id).unwrap());
renderer.render(&rdom);
// update the style and layout
let mut rdom = rdom.write().unwrap();
let mut any_map = SendAnyMap::new();
any_map.insert(taffy.clone());
let (new_to_rerender, dirty) = rdom.update_state(any_map, false);
@@ -297,3 +300,16 @@ pub enum InputEvent {
UserInput(TermEvent),
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 {
pub fn get(&self, id: NodeId) -> ElementRef {
let rdom = self.rdom.read();
let stretch = self.stretch.lock();
ElementRef::new(
self.rdom.read().expect("rdom lock poisoned"),
self.stretch.lock().expect("taffy lock poisoned"),
rdom.expect("rdom lock poisoned"),
stretch.expect("taffy lock poisoned"),
id,
)
}