bugfixes, testing and refactoring
This commit is contained in:
1 parent
6adfa8805c
commit
7f4e257757
20 files changed
+3888
-739
No files matched your search
+22
-19
@@ -2,14 +2,17 @@ use crossterm::event::{
|
||||
Event as TermEvent, KeyCode as TermKeyCode, KeyModifiers, MouseButton, MouseEventKind,
|
||||
};
|
||||
use dioxus_core::*;
|
||||
use fxhash::{FxHashMap, FxHashSet};
|
||||
|
||||
use dioxus_html::{on::*, KeyCode};
|
||||
use dioxus_native_core::{layout::StretchLayout, Tree, TreeNode};
|
||||
use dioxus_native_core::{
|
||||
client_tree::{ClientTree, TreeNode},
|
||||
layout::StretchLayout,
|
||||
};
|
||||
use futures::{channel::mpsc::UnboundedReceiver, StreamExt};
|
||||
use std::{
|
||||
any::Any,
|
||||
cell::RefCell,
|
||||
collections::{HashMap, HashSet},
|
||||
rc::Rc,
|
||||
sync::Arc,
|
||||
time::{Duration, Instant},
|
||||
@@ -166,7 +169,7 @@ impl InnerInputState {
|
||||
evts: &mut Vec<EventCore>,
|
||||
resolved_events: &mut Vec<UserEvent>,
|
||||
layout: &Stretch,
|
||||
tree: &mut Tree<StretchLayout, StyleModifier>,
|
||||
tree: &mut ClientTree<StretchLayout, StyleModifier>,
|
||||
) {
|
||||
let previous_mouse = self
|
||||
.mouse
|
||||
@@ -191,7 +194,7 @@ impl InnerInputState {
|
||||
previous_mouse: Option<(MouseData, Vec<u16>)>,
|
||||
resolved_events: &mut Vec<UserEvent>,
|
||||
layout: &Stretch,
|
||||
tree: &mut Tree<StretchLayout, StyleModifier>,
|
||||
tree: &mut ClientTree<StretchLayout, StyleModifier>,
|
||||
) {
|
||||
struct Data<'b> {
|
||||
new_pos: (i32, i32),
|
||||
@@ -213,17 +216,17 @@ impl InnerInputState {
|
||||
fn try_create_event(
|
||||
name: &'static str,
|
||||
data: Arc<dyn Any + Send + Sync>,
|
||||
will_bubble: &mut HashSet<ElementId>,
|
||||
will_bubble: &mut FxHashSet<ElementId>,
|
||||
resolved_events: &mut Vec<UserEvent>,
|
||||
node: &TreeNode<StretchLayout, StyleModifier>,
|
||||
tree: &Tree<StretchLayout, StyleModifier>,
|
||||
tree: &ClientTree<StretchLayout, StyleModifier>,
|
||||
) {
|
||||
// only trigger event if the event was not triggered already by a child
|
||||
if will_bubble.insert(node.id) {
|
||||
let mut parent = node.parent;
|
||||
while let Some(parent_id) = parent {
|
||||
will_bubble.insert(parent_id);
|
||||
parent = tree.get(parent_id.0).parent;
|
||||
parent = tree[parent_id.0].parent;
|
||||
}
|
||||
resolved_events.push(UserEvent {
|
||||
scope_id: None,
|
||||
@@ -259,7 +262,7 @@ impl InnerInputState {
|
||||
|
||||
{
|
||||
// mousemove
|
||||
let mut will_bubble = HashSet::new();
|
||||
let mut will_bubble = FxHashSet::default();
|
||||
for node in tree.get_listening_sorted("mousemove") {
|
||||
let node_layout = layout.layout(node.up_state.node.unwrap()).unwrap();
|
||||
let previously_contained = data
|
||||
@@ -285,7 +288,7 @@ impl InnerInputState {
|
||||
|
||||
{
|
||||
// mouseenter
|
||||
let mut will_bubble = HashSet::new();
|
||||
let mut will_bubble = FxHashSet::default();
|
||||
for node in tree.get_listening_sorted("mouseenter") {
|
||||
let node_layout = layout.layout(node.up_state.node.unwrap()).unwrap();
|
||||
let previously_contained = data
|
||||
@@ -311,7 +314,7 @@ impl InnerInputState {
|
||||
|
||||
{
|
||||
// mouseover
|
||||
let mut will_bubble = HashSet::new();
|
||||
let mut will_bubble = FxHashSet::default();
|
||||
for node in tree.get_listening_sorted("mouseover") {
|
||||
let node_layout = layout.layout(node.up_state.node.unwrap()).unwrap();
|
||||
let previously_contained = data
|
||||
@@ -337,7 +340,7 @@ impl InnerInputState {
|
||||
|
||||
{
|
||||
// mousedown
|
||||
let mut will_bubble = HashSet::new();
|
||||
let mut will_bubble = FxHashSet::default();
|
||||
for node in tree.get_listening_sorted("mousedown") {
|
||||
let node_layout = layout.layout(node.up_state.node.unwrap()).unwrap();
|
||||
let currently_contains = layout_contains_point(node_layout, data.new_pos);
|
||||
@@ -359,7 +362,7 @@ impl InnerInputState {
|
||||
|
||||
{
|
||||
// mouseup
|
||||
let mut will_bubble = HashSet::new();
|
||||
let mut will_bubble = FxHashSet::default();
|
||||
for node in tree.get_listening_sorted("mouseup") {
|
||||
let node_layout = layout.layout(node.up_state.node.unwrap()).unwrap();
|
||||
let currently_contains = layout_contains_point(node_layout, data.new_pos);
|
||||
@@ -381,7 +384,7 @@ impl InnerInputState {
|
||||
|
||||
{
|
||||
// click
|
||||
let mut will_bubble = HashSet::new();
|
||||
let mut will_bubble = FxHashSet::default();
|
||||
for node in tree.get_listening_sorted("click") {
|
||||
let node_layout = layout.layout(node.up_state.node.unwrap()).unwrap();
|
||||
let currently_contains = layout_contains_point(node_layout, data.new_pos);
|
||||
@@ -403,7 +406,7 @@ impl InnerInputState {
|
||||
|
||||
{
|
||||
// contextmenu
|
||||
let mut will_bubble = HashSet::new();
|
||||
let mut will_bubble = FxHashSet::default();
|
||||
for node in tree.get_listening_sorted("contextmenu") {
|
||||
let node_layout = layout.layout(node.up_state.node.unwrap()).unwrap();
|
||||
let currently_contains = layout_contains_point(node_layout, data.new_pos);
|
||||
@@ -425,7 +428,7 @@ impl InnerInputState {
|
||||
|
||||
{
|
||||
// wheel
|
||||
let mut will_bubble = HashSet::new();
|
||||
let mut will_bubble = FxHashSet::default();
|
||||
for node in tree.get_listening_sorted("wheel") {
|
||||
let node_layout = layout.layout(node.up_state.node.unwrap()).unwrap();
|
||||
let currently_contains = layout_contains_point(node_layout, data.new_pos);
|
||||
@@ -449,7 +452,7 @@ impl InnerInputState {
|
||||
|
||||
{
|
||||
// mouseleave
|
||||
let mut will_bubble = HashSet::new();
|
||||
let mut will_bubble = FxHashSet::default();
|
||||
for node in tree.get_listening_sorted("mouseleave") {
|
||||
let node_layout = layout.layout(node.up_state.node.unwrap()).unwrap();
|
||||
let previously_contained = data
|
||||
@@ -473,7 +476,7 @@ impl InnerInputState {
|
||||
|
||||
{
|
||||
// mouseout
|
||||
let mut will_bubble = HashSet::new();
|
||||
let mut will_bubble = FxHashSet::default();
|
||||
for node in tree.get_listening_sorted("mouseout") {
|
||||
let node_layout = layout.layout(node.up_state.node.unwrap()).unwrap();
|
||||
let previously_contained = data
|
||||
@@ -543,7 +546,7 @@ impl RinkInputHandler {
|
||||
pub fn get_events<'a>(
|
||||
&self,
|
||||
layout: &Stretch,
|
||||
tree: &mut Tree<StretchLayout, StyleModifier>,
|
||||
tree: &mut ClientTree<StretchLayout, StyleModifier>,
|
||||
) -> Vec<UserEvent> {
|
||||
let mut resolved_events = Vec::new();
|
||||
|
||||
@@ -578,7 +581,7 @@ impl RinkInputHandler {
|
||||
.map(|evt| (evt.0, evt.1.into_any()));
|
||||
|
||||
// todo: currently resolves events in all nodes, but once the focus system is added it should filter by focus
|
||||
let mut hm: HashMap<&'static str, Vec<Arc<dyn Any + Send + Sync>>> = HashMap::new();
|
||||
let mut hm: FxHashMap<&'static str, Vec<Arc<dyn Any + Send + Sync>>> = FxHashMap::default();
|
||||
for (event, data) in events {
|
||||
if let Some(v) = hm.get_mut(event) {
|
||||
v.push(data);
|
||||
|
||||
+12
-32
@@ -9,10 +9,8 @@ use crossterm::{
|
||||
};
|
||||
use dioxus_core::exports::futures_channel::mpsc::unbounded;
|
||||
use dioxus_core::*;
|
||||
use dioxus_html::on::{KeyboardData, MouseData, PointerData, TouchData, WheelData};
|
||||
use dioxus_native_core::{layout::StretchLayout, Tree};
|
||||
use dioxus_native_core::{client_tree::ClientTree, layout::StretchLayout};
|
||||
use futures::{channel::mpsc::UnboundedSender, pin_mut, StreamExt};
|
||||
use std::collections::HashSet;
|
||||
use std::{io, time::Duration};
|
||||
use stretch2::{prelude::Size, Stretch};
|
||||
use style_attributes::StyleModifier;
|
||||
@@ -44,7 +42,7 @@ pub fn launch_cfg(app: Component<()>, cfg: Config) {
|
||||
|
||||
cx.provide_root_context(state);
|
||||
|
||||
let mut tree: Tree<StretchLayout, StyleModifier> = Tree::new();
|
||||
let mut tree: ClientTree<StretchLayout, StyleModifier> = ClientTree::new();
|
||||
let mutations = dom.rebuild();
|
||||
let to_update = tree.apply_mutations(vec![mutations]);
|
||||
let mut stretch = Stretch::new();
|
||||
@@ -60,7 +58,7 @@ pub fn render_vdom(
|
||||
ctx: UnboundedSender<TermEvent>,
|
||||
handler: RinkInputHandler,
|
||||
cfg: Config,
|
||||
mut tree: Tree<StretchLayout, StyleModifier>,
|
||||
mut tree: ClientTree<StretchLayout, StyleModifier>,
|
||||
mut stretch: Stretch,
|
||||
) -> Result<()> {
|
||||
// Setup input handling
|
||||
@@ -100,12 +98,8 @@ pub fn render_vdom(
|
||||
let mut terminal = Terminal::new(backend).unwrap();
|
||||
|
||||
terminal.clear().unwrap();
|
||||
let mut to_rerender: HashSet<usize> = tree
|
||||
.nodes
|
||||
.iter()
|
||||
.filter_map(|n| n.as_ref())
|
||||
.map(|n| n.id.0)
|
||||
.collect();
|
||||
let mut to_rerender: fxhash::FxHashSet<usize> = vec![0].into_iter().collect();
|
||||
let mut redraw = true;
|
||||
|
||||
loop {
|
||||
/*
|
||||
@@ -120,15 +114,16 @@ pub fn render_vdom(
|
||||
todo: lazy re-rendering
|
||||
*/
|
||||
|
||||
if !to_rerender.is_empty() {
|
||||
if !to_rerender.is_empty() || redraw {
|
||||
redraw = false;
|
||||
terminal.draw(|frame| {
|
||||
// size is guaranteed to not change when rendering
|
||||
let dims = frame.size();
|
||||
// println!("{dims:?}");
|
||||
let width = dims.width;
|
||||
let height = dims.height;
|
||||
let root_id = tree.root;
|
||||
let root_node = tree.get(root_id).up_state.node.unwrap();
|
||||
let root_id = tree.root_id();
|
||||
let root_node = tree[root_id].up_state.node.unwrap();
|
||||
stretch
|
||||
.compute_layout(
|
||||
root_node,
|
||||
@@ -138,7 +133,7 @@ pub fn render_vdom(
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
let root = tree.get(tree.root);
|
||||
let root = &tree[tree.root_id()];
|
||||
render::render_vnode(frame, &stretch, &tree, &root, cfg);
|
||||
})?;
|
||||
}
|
||||
@@ -146,22 +141,6 @@ pub fn render_vdom(
|
||||
// resolve events before rendering
|
||||
// todo: events do not trigger update?
|
||||
for e in handler.get_events(&stretch, &mut tree) {
|
||||
// let tname = if e.data.is::<PointerData>() {
|
||||
// "PointerData"
|
||||
// } else if e.data.is::<WheelData>() {
|
||||
// "WheelData"
|
||||
// } else if e.data.is::<MouseData>() {
|
||||
// "MouseData"
|
||||
// } else if e.data.is::<KeyboardData>() {
|
||||
// "KeyboardData"
|
||||
// } else if e.data.is::<TouchData>() {
|
||||
// "TouchData"
|
||||
// } else if e.data.is::<(u16, u16)>() {
|
||||
// "(u16, u16)"
|
||||
// } else {
|
||||
// panic!()
|
||||
// };
|
||||
// println!("{tname}: {e:?}");
|
||||
vdom.handle_message(SchedulerMsg::Event(e));
|
||||
}
|
||||
|
||||
@@ -184,7 +163,8 @@ pub fn render_vdom(
|
||||
break;
|
||||
}
|
||||
}
|
||||
TermEvent::Resize(_, _) | TermEvent::Mouse(_) => {}
|
||||
TermEvent::Resize(_, _) => redraw = true,
|
||||
TermEvent::Mouse(_) => {}
|
||||
},
|
||||
InputEvent::Tick => {} // tick
|
||||
InputEvent::Close => break,
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
use dioxus_native_core::{layout::StretchLayout, layout_attributes::UnitSystem, Tree, TreeNode};
|
||||
use dioxus_native_core::{
|
||||
client_tree::{ClientTree, TreeNode},
|
||||
layout::StretchLayout,
|
||||
layout_attributes::UnitSystem,
|
||||
};
|
||||
use std::io::Stdout;
|
||||
use stretch2::{
|
||||
geometry::Point,
|
||||
@@ -19,12 +23,14 @@ const RADIUS_MULTIPLIER: [f32; 2] = [1.0, 0.5];
|
||||
pub fn render_vnode<'a>(
|
||||
frame: &mut tui::Frame<CrosstermBackend<Stdout>>,
|
||||
layout: &Stretch,
|
||||
tree: &Tree<StretchLayout, StyleModifier>,
|
||||
tree: &ClientTree<StretchLayout, StyleModifier>,
|
||||
node: &TreeNode<StretchLayout, StyleModifier>,
|
||||
cfg: Config,
|
||||
) {
|
||||
use dioxus_native_core::client_tree::TreeNodeType;
|
||||
|
||||
match &node.node_type {
|
||||
dioxus_native_core::TreeNodeType::Placeholder => return,
|
||||
TreeNodeType::Placeholder => return,
|
||||
_ => (),
|
||||
}
|
||||
|
||||
@@ -34,7 +40,7 @@ pub fn render_vnode<'a>(
|
||||
let Size { width, height } = size;
|
||||
|
||||
match &node.node_type {
|
||||
dioxus_native_core::TreeNodeType::Text { text } => {
|
||||
TreeNodeType::Text { text } => {
|
||||
#[derive(Default)]
|
||||
struct Label<'a> {
|
||||
text: &'a str,
|
||||
@@ -64,7 +70,7 @@ pub fn render_vnode<'a>(
|
||||
frame.render_widget(WidgetWithContext::new(label, cfg), area);
|
||||
}
|
||||
}
|
||||
dioxus_native_core::TreeNodeType::Element { children, .. } => {
|
||||
TreeNodeType::Element { children, .. } => {
|
||||
let area = Rect::new(*x as u16, *y as u16, *width as u16, *height as u16);
|
||||
|
||||
// the renderer will panic if a node is rendered out of range even if the size is zero
|
||||
@@ -73,10 +79,10 @@ pub fn render_vnode<'a>(
|
||||
}
|
||||
|
||||
for c in children {
|
||||
render_vnode(frame, layout, tree, tree.get(c.0), cfg);
|
||||
render_vnode(frame, layout, tree, &tree[c.0], cfg);
|
||||
}
|
||||
}
|
||||
dioxus_native_core::TreeNodeType::Placeholder => unreachable!(),
|
||||
TreeNodeType::Placeholder => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
|
||||
use dioxus_core::{Attribute, VNode};
|
||||
use dioxus_native_core::{
|
||||
client_tree::PushedDownState,
|
||||
layout_attributes::{parse_value, UnitSystem},
|
||||
PushedDownState,
|
||||
};
|
||||
|
||||
use crate::style::{RinkColor, RinkStyle};
|
||||
@@ -48,7 +48,9 @@ impl PushedDownState for StyleModifier {
|
||||
|
||||
fn reduce(&mut self, parent: Option<&Self>, vnode: &VNode, _ctx: &mut Self::Ctx) {
|
||||
*self = StyleModifier::default();
|
||||
self.style.fg = None;
|
||||
if parent.is_some() {
|
||||
self.style.fg = None;
|
||||
}
|
||||
match vnode {
|
||||
VNode::Element(el) => {
|
||||
// handle text modifier elements
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
// use dioxus_core::{Element, ElementId, Mutations, VNode, VirtualDom, DomEdit};
|
||||
|
||||
// /// The focus system needs a iterator that can persist through changes in the [VirtualDom]. Iterate through it with [ElementIter::next], and update it with [ElementIter::update] (with data from [`VirtualDom::work_with_deadline`]).
|
||||
// pub(crate) struct ElementIter {
|
||||
// // stack of elements and fragments
|
||||
// stack: smallvec::SmallVec<[(ElementId, usize); 5]>,
|
||||
// }
|
||||
|
||||
// impl ElementIter {
|
||||
// pub(crate) fn new(initial: ElementId) -> Self {
|
||||
// ElementIter {
|
||||
// stack: smallvec::smallvec![(initial, 0)],
|
||||
// }
|
||||
// }
|
||||
// /// remove stale element refreneces
|
||||
// pub(crate) fn update(&mut self, mutations: &Mutations, vdom: &VirtualDom) {
|
||||
// let ids_removed: Vec<_> = mutations.edits.iter().filter_map(|e| if let DomEdit::Remove{root: }).collect();
|
||||
// for node in self.stack {
|
||||
|
||||
// match node.0 {
|
||||
// VNode::Fragment(f) => {
|
||||
|
||||
// }
|
||||
|
||||
// VNode::Element(_) => {}
|
||||
|
||||
// _ => unreachable!(),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// pub(crate) fn next<'a>(&mut self, vdom: &'a VirtualDom) -> Option<&'a VNode<'a>> {
|
||||
// let last = self.stack.last()?.0;
|
||||
// let node = vdom.get_element(last)?;
|
||||
// match node {
|
||||
// VNode::Fragment(f) => {
|
||||
// let mut last_mut = self.stack.last_mut()?;
|
||||
// if last_mut.1 + 1 >= f.children.len() {
|
||||
// self.stack.pop();
|
||||
// self.next(vdom)
|
||||
// } else {
|
||||
// last_mut.1 += 1;
|
||||
// let new_node = &f.children[last_mut.1];
|
||||
// if matches!(new_node, VNode::Fragment(_) | VNode::Element(_)) {
|
||||
// self.stack.push((new_node.mounted_id(), 0));
|
||||
// }
|
||||
// self.next(vdom)
|
||||
// }
|
||||
// }
|
||||
|
||||
// VNode::Component(vcomp) => {
|
||||
// let idx = vcomp.scope.get().unwrap();
|
||||
// let new_node = vdom.get_scope(idx).unwrap().root_node();
|
||||
// *self.stack.last_mut()? = (new_node.mounted_id(), 0);
|
||||
// self.next(vdom)
|
||||
// }
|
||||
|
||||
// VNode::Placeholder(_) | VNode::Text(_) => {
|
||||
// self.stack.pop();
|
||||
// self.next(vdom)
|
||||
// }
|
||||
|
||||
// VNode::Element(e) => {
|
||||
// let mut last_mut = self.stack.last_mut()?;
|
||||
// if last_mut.1 + 1 >= e.children.len() {
|
||||
// self.stack.pop();
|
||||
// self.next(vdom);
|
||||
// } else {
|
||||
// last_mut.1 += 1;
|
||||
// let new_node = &e.children[last_mut.1];
|
||||
// if matches!(new_node, VNode::Fragment(_) | VNode::Element(_)) {
|
||||
// self.stack.push((new_node.mounted_id(), 0));
|
||||
// }
|
||||
// self.next(vdom);
|
||||
// }
|
||||
// Some(node)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// pub(crate) fn peak(&self) -> Option<&ElementId> {
|
||||
// self.stack.last().map(|(e, c)| e)
|
||||
// }
|
||||
// }
|
||||
Reference in new issue
Block a user