updates: move to stable versions
This commit is contained in:
1 parent
c884f8c1b8
commit
395558232e
13 files changed
+233
-65
No files matched your search
+4
-3
@@ -10,11 +10,12 @@ tui = { version = "0.16.0", features = ["crossterm"] }
|
||||
crossterm = "0.22.1"
|
||||
anyhow = "1.0.42"
|
||||
thiserror = "1.0.24"
|
||||
dioxus = { path = "../../dioxus" }
|
||||
# dioxus = { path = "../../dioxus" }
|
||||
dioxus = { version = "0.1.7" }
|
||||
hecs = "0.7.3"
|
||||
ctrlc = "3.2.1"
|
||||
bumpalo = { version = "3.8.0", features = ["boxed"] }
|
||||
stretch2 = { path = "../../Tinkering/stretch2" }
|
||||
# stretch2 = { path = "../../Tinkering/stretch2" }
|
||||
tokio = { version = "1.15.0", features = ["full"] }
|
||||
futures = "0.3.19"
|
||||
# stretch2 = { git = "https://github.com/elbaro/stretch2.git" }
|
||||
stretch2 = { git = "https://github.com/DioxusLabs/stretch" }
|
||||
+1
-4
@@ -1,10 +1,7 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
let mut dom = VirtualDom::new(app);
|
||||
dom.rebuild();
|
||||
|
||||
rink::render_vdom(&mut dom).unwrap();
|
||||
rink::launch(app);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
use std::cell::RefCell;
|
||||
|
||||
use crossterm::event::KeyEvent;
|
||||
use dioxus::prelude::*;
|
||||
use rink::InputHandler;
|
||||
|
||||
fn main() {
|
||||
rink::launch(app);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
let count = use_state(&cx, || 0);
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
width: "100%",
|
||||
height: "10px",
|
||||
background_color: "red",
|
||||
justify_content: "center",
|
||||
align_items: "center",
|
||||
"Hello world!",
|
||||
|
||||
// todo: enabling this will panic
|
||||
// rink::InputHandler {
|
||||
// onkeydown: move |evt: KeyEvent| {
|
||||
// use crossterm::event::KeyCode::*;
|
||||
// match evt.code {
|
||||
// Left => count += 1,
|
||||
// Right => count -= 1,
|
||||
// Up => count += 10,
|
||||
// Down => count -= 10,
|
||||
// _ => {},
|
||||
// }
|
||||
// },
|
||||
// onmousedown: move |evt| {},
|
||||
// onresize: move |dims| {
|
||||
// println!("{:?}", dims);
|
||||
// },
|
||||
// }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn app2<'a>(cx: Scope<'a>) -> Element<'a> {
|
||||
let mut count = use_state(&cx, || 0);
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
width: "100%",
|
||||
height: "10px",
|
||||
background_color: "red",
|
||||
justify_content: "center",
|
||||
align_items: "center",
|
||||
oninput: move |_| count += 1,
|
||||
"Hello world!",
|
||||
h1 {},
|
||||
}
|
||||
})
|
||||
}
|
||||
+1
-4
@@ -1,10 +1,7 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
let mut dom = VirtualDom::new(app);
|
||||
dom.rebuild();
|
||||
|
||||
rink::render_vdom(&mut dom).unwrap();
|
||||
rink::launch(app);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
|
||||
+3
-12
@@ -1,10 +1,7 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
let mut dom = VirtualDom::new(app);
|
||||
dom.rebuild();
|
||||
|
||||
rink::render_vdom(&mut dom).unwrap();
|
||||
rink::launch(app);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
@@ -16,44 +13,38 @@ fn app(cx: Scope) -> Element {
|
||||
background_color: "black",
|
||||
// margin_right: "10px",
|
||||
|
||||
|
||||
|
||||
div {
|
||||
width: "70%",
|
||||
height: "70%",
|
||||
// margin_left: "4px",
|
||||
background_color: "green",
|
||||
// margin_left: "4px",
|
||||
|
||||
div {
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
|
||||
|
||||
margin_top: "2px",
|
||||
margin_bottom: "2px",
|
||||
margin_left: "2px",
|
||||
margin_right: "2px",
|
||||
// flex_shrink: "0",
|
||||
flex_shrink: "0",
|
||||
|
||||
background_color: "red",
|
||||
justify_content: "center",
|
||||
align_items: "center",
|
||||
flex_direction: "column",
|
||||
|
||||
|
||||
// padding_top: "2px",
|
||||
// padding_bottom: "2px",
|
||||
// padding_left: "4px",
|
||||
// padding_right: "4px",
|
||||
|
||||
|
||||
"[A]"
|
||||
"[A]"
|
||||
"[A]"
|
||||
"[A]"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -1,10 +1,7 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
let mut dom = VirtualDom::new(app);
|
||||
dom.rebuild();
|
||||
|
||||
rink::render_vdom(&mut dom).unwrap();
|
||||
rink::launch(app);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
|
||||
+1
-4
@@ -1,10 +1,7 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
let mut dom = VirtualDom::new(app);
|
||||
dom.rebuild();
|
||||
|
||||
rink::render_vdom(&mut dom).unwrap();
|
||||
rink::launch(app);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
|
||||
+1
-4
@@ -1,10 +1,7 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
let mut dom = VirtualDom::new(app);
|
||||
dom.rebuild();
|
||||
|
||||
rink::render_vdom(&mut dom).unwrap();
|
||||
rink::launch(app);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
|
||||
+1
-4
@@ -1,10 +1,7 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
let mut dom = VirtualDom::new(app);
|
||||
dom.rebuild();
|
||||
|
||||
rink::render_vdom(&mut dom).unwrap();
|
||||
rink::launch(app);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
div {
|
||||
div {
|
||||
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
use anyhow::Result;
|
||||
use crossterm::{
|
||||
event::{
|
||||
DisableMouseCapture, EnableMouseCapture, Event as TermEvent, KeyCode, KeyEvent, MouseEvent,
|
||||
},
|
||||
execute,
|
||||
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
||||
};
|
||||
use dioxus::{core::exports::futures_channel::mpsc::unbounded, prelude::Props};
|
||||
use dioxus::{core::*, prelude::*};
|
||||
use futures::{channel::mpsc::UnboundedReceiver, future::Either, pin_mut, StreamExt};
|
||||
use std::{
|
||||
cell::{Cell, RefCell},
|
||||
collections::HashMap,
|
||||
io,
|
||||
rc::Rc,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use stretch2::{prelude::Size, Stretch};
|
||||
use tui::{backend::CrosstermBackend, style::Style as TuiStyle, Terminal};
|
||||
|
||||
pub struct RinkContext {
|
||||
last_event: RefCell<Option<TermEvent>>,
|
||||
receiver: Rc<Cell<Option<UnboundedReceiver<TermEvent>>>>,
|
||||
}
|
||||
|
||||
impl RinkContext {
|
||||
pub fn new(receiver: UnboundedReceiver<TermEvent>) -> Self {
|
||||
Self {
|
||||
last_event: RefCell::new(None),
|
||||
receiver: Rc::new(Cell::new(Some(receiver))),
|
||||
}
|
||||
}
|
||||
pub fn subscribe_to_events(&self, scope: ScopeId) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Props)]
|
||||
pub struct AppHandlerProps<'a> {
|
||||
// #[props(setter(strip_option), default)]
|
||||
onkeydown: EventHandler<'a, KeyEvent>,
|
||||
|
||||
// #[props(setter(strip_option), default)]
|
||||
onmousedown: EventHandler<'a, MouseEvent>,
|
||||
|
||||
#[props(setter(strip_option), default)]
|
||||
onresize: Option<EventHandler<'a, (u16, u16)>>,
|
||||
}
|
||||
|
||||
/// This component lets you handle input events
|
||||
///
|
||||
/// Once attached to the DOM, it will listen for input events from the terminal
|
||||
///
|
||||
///
|
||||
pub fn InputHandler<'a>(cx: Scope<'a, AppHandlerProps<'a>>) -> Element {
|
||||
let rcx = cx.use_hook(|_| {
|
||||
let rcx = cx
|
||||
.consume_context::<RinkContext>()
|
||||
.unwrap_or_else(|| panic!("Rink InputHandlers can only be used in Rink apps!"));
|
||||
|
||||
// our component will only re-render if new events are received ... or if the parent is updated
|
||||
// todo: if update was not caused by a new event, we should not re-render
|
||||
// perhaps add some tracking to context?
|
||||
rcx.subscribe_to_events(cx.scope_id());
|
||||
|
||||
let mut rec = rcx.receiver.take().unwrap();
|
||||
let updater = cx.schedule_update();
|
||||
let rc2 = rcx.clone();
|
||||
cx.push_future(async move {
|
||||
while let Some(evt) = rec.next().await {
|
||||
rc2.last_event.borrow_mut().replace(evt);
|
||||
println!("{:?}", evt);
|
||||
updater();
|
||||
}
|
||||
//
|
||||
});
|
||||
|
||||
rcx
|
||||
});
|
||||
|
||||
if let Some(evet) = rcx.last_event.borrow().as_ref() {
|
||||
match evet {
|
||||
TermEvent::Key(key) => {
|
||||
cx.props.onkeydown.call(key.clone());
|
||||
// let mut handler = cx.props.keydown.borrow_mut();
|
||||
// handler(*key);
|
||||
// if let Some(handler) = cx.props.onkeydown {
|
||||
// handler(*key);
|
||||
// }
|
||||
}
|
||||
TermEvent::Mouse(mouse) => {
|
||||
cx.props.onmousedown.call(mouse.clone());
|
||||
}
|
||||
TermEvent::Resize(x, y) => {
|
||||
// if let Some(handler) = cx.props.onresize {
|
||||
// handler((*x, *y));
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
+20
-3
@@ -67,7 +67,17 @@ pub fn collect_layout<'a>(
|
||||
for el in el.children {
|
||||
let ite = ElementIdIterator::new(vdom, el);
|
||||
for node in ite {
|
||||
child_layout.push(nodes[&node.mounted_id()].layout)
|
||||
match node {
|
||||
VNode::Element(_) | VNode::Text(_) => {
|
||||
//
|
||||
child_layout.push(nodes[&node.mounted_id()].layout)
|
||||
}
|
||||
VNode::Placeholder(_) => {}
|
||||
VNode::Fragment(_) => todo!(),
|
||||
VNode::Component(_) => todo!(),
|
||||
}
|
||||
|
||||
// child_layout.push(nodes[&node.mounted_id()].layout)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +96,14 @@ pub fn collect_layout<'a>(
|
||||
collect_layout(layout, nodes, vdom, child);
|
||||
}
|
||||
}
|
||||
VNode::Component(_) => todo!(),
|
||||
VNode::Placeholder(_) => todo!(),
|
||||
VNode::Component(sc) => {
|
||||
//
|
||||
let scope = vdom.get_scope(sc.scope.get().unwrap()).unwrap();
|
||||
let root = scope.root_node();
|
||||
collect_layout(layout, nodes, vdom, root);
|
||||
}
|
||||
VNode::Placeholder(_) => {
|
||||
//
|
||||
}
|
||||
};
|
||||
}
|
||||
+32
-23
@@ -4,35 +4,52 @@ use crossterm::{
|
||||
execute,
|
||||
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
||||
};
|
||||
use dioxus::core::exports::futures_channel::mpsc::unbounded;
|
||||
use dioxus::core::*;
|
||||
use futures::{future::Either, pin_mut, StreamExt};
|
||||
use dioxus::{core::exports::futures_channel::mpsc::unbounded, prelude::Props};
|
||||
use dioxus::{core::*, prelude::*};
|
||||
use futures::{
|
||||
channel::mpsc::{UnboundedReceiver, UnboundedSender},
|
||||
future::Either,
|
||||
pin_mut, StreamExt,
|
||||
};
|
||||
use std::{
|
||||
cell::Cell,
|
||||
collections::HashMap,
|
||||
io,
|
||||
rc::Rc,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use stretch2::{prelude::Size, Stretch};
|
||||
use tui::{backend::CrosstermBackend, style::Style as TuiStyle, Terminal};
|
||||
|
||||
mod attributes;
|
||||
mod hooks;
|
||||
mod layout;
|
||||
mod render;
|
||||
|
||||
pub use attributes::*;
|
||||
pub use hooks::*;
|
||||
pub use layout::*;
|
||||
pub use render::*;
|
||||
|
||||
pub fn launch(app: Component<()>) {
|
||||
let mut dom = VirtualDom::new(app);
|
||||
let (tx, rx) = unbounded();
|
||||
|
||||
dom.base_scope().provide_context(RinkContext::new(rx));
|
||||
dom.rebuild();
|
||||
|
||||
render_vdom(&mut dom, tx).unwrap();
|
||||
}
|
||||
|
||||
pub struct TuiNode<'a> {
|
||||
pub layout: stretch2::node::Node,
|
||||
pub block_style: TuiStyle,
|
||||
pub node: &'a VNode<'a>,
|
||||
}
|
||||
|
||||
pub fn render_vdom(vdom: &mut VirtualDom) -> Result<()> {
|
||||
pub fn render_vdom(vdom: &mut VirtualDom, ctx: UnboundedSender<TermEvent>) -> Result<()> {
|
||||
// Setup input handling
|
||||
let (tx, mut rx) = unbounded();
|
||||
|
||||
std::thread::spawn(move || {
|
||||
let tick_rate = Duration::from_millis(100);
|
||||
let mut last_tick = Instant::now();
|
||||
@@ -117,35 +134,27 @@ pub fn render_vdom(vdom: &mut VirtualDom) -> Result<()> {
|
||||
|
||||
match select(wait, rx.next()).await {
|
||||
Either::Left((a, b)) => {
|
||||
// println!("work");
|
||||
//
|
||||
}
|
||||
Either::Right((evt, o)) => {
|
||||
// println!("event");
|
||||
match evt.unwrap() {
|
||||
//
|
||||
match evt.as_ref().unwrap() {
|
||||
InputEvent::UserInput(event) => match event {
|
||||
TermEvent::Key(key) => {
|
||||
match key.code {
|
||||
KeyCode::Char('q') => {
|
||||
disable_raw_mode()?;
|
||||
execute!(
|
||||
terminal.backend_mut(),
|
||||
LeaveAlternateScreen,
|
||||
DisableMouseCapture
|
||||
)?;
|
||||
terminal.show_cursor()?;
|
||||
break;
|
||||
}
|
||||
KeyCode::Char('q') => break,
|
||||
_ => {} // handle event
|
||||
}
|
||||
}
|
||||
TermEvent::Mouse(_) => {}
|
||||
TermEvent::Resize(_, _) => {}
|
||||
TermEvent::Resize(_, _) | TermEvent::Mouse(_) => {}
|
||||
},
|
||||
InputEvent::Tick => {} // tick
|
||||
InputEvent::Close => {
|
||||
break;
|
||||
}
|
||||
InputEvent::Close => break,
|
||||
};
|
||||
|
||||
if let InputEvent::UserInput(evt) = evt.unwrap() {
|
||||
ctx.unbounded_send(evt).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user