wip: add an image
This commit is contained in:
1 parent
dc34805ee6
commit
7b29fbbad0
8 files changed
+331
-174
No files matched your search
@@ -12,15 +12,21 @@ You can use html-esque semantics with stylesheets, inline styles, tree hierarchy
|
|||||||
|
|
||||||
static App: FC<()> = |cx| {
|
static App: FC<()> = |cx| {
|
||||||
cx.render(rsx!{
|
cx.render(rsx!{
|
||||||
div { width: "100%", height: "3px", border_style: "solid",
|
div {
|
||||||
h1 { "Hello world!" }
|
width: "100%",
|
||||||
p { "This is a paragraph." }
|
height: "10px",
|
||||||
|
background_color: "red",
|
||||||
|
justify_content: "center",
|
||||||
|
align_items: "center",
|
||||||
|
|
||||||
|
|
||||||
|
"Hello world!"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
an image should go here
|

|
||||||
|
|
||||||
|
|
||||||
Rink is basically a port of [Ink]() but for Rust and Dioxus. Rink doesn't depend on Node.js or any other JavaScript runtime, so your binaries are portable and beautiful.
|
Rink is basically a port of [Ink]() but for Rust and Dioxus. Rink doesn't depend on Node.js or any other JavaScript runtime, so your binaries are portable and beautiful.
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 105 KiB |
@@ -0,0 +1,59 @@
|
|||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut dom = VirtualDom::new(app);
|
||||||
|
dom.rebuild();
|
||||||
|
|
||||||
|
rink::render_vdom(&dom).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn app(cx: Scope) -> Element {
|
||||||
|
cx.render(rsx! {
|
||||||
|
div {
|
||||||
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
flex_direction: "column",
|
||||||
|
background_color: "black",
|
||||||
|
// margin_right: "10px",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
div {
|
||||||
|
width: "70%",
|
||||||
|
height: "70%",
|
||||||
|
// margin_left: "4px",
|
||||||
|
background_color: "green",
|
||||||
|
|
||||||
|
div {
|
||||||
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
|
||||||
|
|
||||||
|
margin_top: "2px",
|
||||||
|
margin_bottom: "2px",
|
||||||
|
margin_left: "2px",
|
||||||
|
margin_right: "2px",
|
||||||
|
// 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]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut dom = VirtualDom::new(app);
|
||||||
|
dom.rebuild();
|
||||||
|
|
||||||
|
rink::render_vdom(&dom).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn app(cx: Scope) -> Element {
|
||||||
|
cx.render(rsx! {
|
||||||
|
div {
|
||||||
|
width: "100%",
|
||||||
|
height: "10px",
|
||||||
|
background_color: "red",
|
||||||
|
justify_content: "center",
|
||||||
|
align_items: "center",
|
||||||
|
|
||||||
|
"Hello world!"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
+106
-61
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
- [ ] pub display: Display,
|
- [ ] pub display: Display,
|
||||||
- [ ] pub position_type: PositionType,
|
- [x] pub position_type: PositionType, --> kinda, stretch doesnt support everything
|
||||||
- [ ] pub direction: Direction,
|
- [ ] pub direction: Direction,
|
||||||
|
|
||||||
- [x] pub flex_direction: FlexDirection,
|
- [x] pub flex_direction: FlexDirection,
|
||||||
@@ -9,26 +9,27 @@
|
|||||||
- [x] pub flex_shrink: f32,
|
- [x] pub flex_shrink: f32,
|
||||||
- [x] pub flex_basis: Dimension,
|
- [x] pub flex_basis: Dimension,
|
||||||
|
|
||||||
- [ ] pub overflow: Overflow,
|
- [x] pub overflow: Overflow, ---> kinda implemented... stretch doesnt have support for directional overflow
|
||||||
|
|
||||||
- [x] pub align_items: AlignItems,
|
- [x] pub align_items: AlignItems,
|
||||||
- [x] pub align_self: AlignSelf,
|
- [x] pub align_self: AlignSelf,
|
||||||
- [x] pub align_content: AlignContent,
|
- [x] pub align_content: AlignContent,
|
||||||
|
|
||||||
- [ ] pub margin: Rect<Dimension>,
|
- [x] pub margin: Rect<Dimension>,
|
||||||
- [ ] pub padding: Rect<Dimension>,
|
- [x] pub padding: Rect<Dimension>,
|
||||||
|
|
||||||
- [x] pub justify_content: JustifyContent,
|
- [x] pub justify_content: JustifyContent,
|
||||||
- [ ] pub position: Rect<Dimension>,
|
- [ ] pub position: Rect<Dimension>,
|
||||||
- [ ] pub border: Rect<Dimension>,
|
- [ ] pub border: Rect<Dimension>,
|
||||||
- [ ] pub size: Size<Dimension>,
|
|
||||||
|
|
||||||
|
- [ ] pub size: Size<Dimension>, ----> ??? seems to only be relevant for input?
|
||||||
- [ ] pub min_size: Size<Dimension>,
|
- [ ] pub min_size: Size<Dimension>,
|
||||||
- [ ] pub max_size: Size<Dimension>,
|
- [ ] pub max_size: Size<Dimension>,
|
||||||
|
|
||||||
- [ ] pub aspect_ratio: Number,
|
- [ ] pub aspect_ratio: Number,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use stretch2::{prelude::*, style::Style};
|
use stretch2::{prelude::*, style::PositionType, style::Style};
|
||||||
use tui::style::Style as TuiStyle;
|
use tui::style::Style as TuiStyle;
|
||||||
|
|
||||||
pub struct StyleModifer {
|
pub struct StyleModifer {
|
||||||
@@ -137,7 +138,13 @@ pub fn apply_attributes(
|
|||||||
"counter-reset" => {}
|
"counter-reset" => {}
|
||||||
|
|
||||||
"cursor" => {}
|
"cursor" => {}
|
||||||
"direction" => {}
|
"direction" => {
|
||||||
|
match value {
|
||||||
|
"ltr" => style.style.direction = Direction::LTR,
|
||||||
|
"rtl" => style.style.direction = Direction::RTL,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
"display" => apply_display(name, value, style),
|
"display" => apply_display(name, value, style),
|
||||||
|
|
||||||
@@ -231,8 +238,20 @@ pub fn apply_attributes(
|
|||||||
"perspective"
|
"perspective"
|
||||||
| "perspective-origin" => {}
|
| "perspective-origin" => {}
|
||||||
|
|
||||||
"position" => {}
|
"position" => {
|
||||||
|
match value {
|
||||||
|
"static" => {}
|
||||||
|
"relative" => style.style.position_type = PositionType::Relative,
|
||||||
|
"fixed" => {}
|
||||||
|
"absolute" => style.style.position_type = PositionType::Absolute,
|
||||||
|
"sticky" => {}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
"pointer-events" => {}
|
"pointer-events" => {}
|
||||||
|
|
||||||
"quotes" => {}
|
"quotes" => {}
|
||||||
"resize" => {}
|
"resize" => {}
|
||||||
"right" => {}
|
"right" => {}
|
||||||
@@ -285,6 +304,29 @@ pub fn apply_attributes(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum UnitSystem {
|
||||||
|
Percent(f32),
|
||||||
|
Point(f32),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_value(value: &str) -> Option<UnitSystem> {
|
||||||
|
if value.ends_with("px") {
|
||||||
|
if let Ok(px) = value.trim_end_matches("px").parse::<f32>() {
|
||||||
|
Some(UnitSystem::Point(px))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else if value.ends_with("%") {
|
||||||
|
if let Ok(pct) = value.trim_end_matches("%").parse::<f32>() {
|
||||||
|
Some(UnitSystem::Percent(pct))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn apply_overflow(name: &str, value: &str, style: &mut StyleModifer) {
|
fn apply_overflow(name: &str, value: &str, style: &mut StyleModifer) {
|
||||||
match name {
|
match name {
|
||||||
// todo: add more overflow support to stretch2
|
// todo: add more overflow support to stretch2
|
||||||
@@ -491,54 +533,35 @@ fn apply_font(name: &str, value: &str, style: &mut StyleModifer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn apply_padding(name: &str, value: &str, style: &mut StyleModifer) {
|
fn apply_padding(name: &str, value: &str, style: &mut StyleModifer) {
|
||||||
// // left
|
match parse_value(value) {
|
||||||
// start: stretch::style::Dimension::Points(10f32),
|
Some(UnitSystem::Percent(v)) => match name {
|
||||||
|
"padding" => {
|
||||||
// // right?
|
let v = Dimension::Percent(v / 100.0);
|
||||||
// end: stretch::style::Dimension::Points(10f32),
|
style.style.padding.top = v;
|
||||||
|
style.style.padding.bottom = v;
|
||||||
// // top?
|
style.style.padding.start = v;
|
||||||
// // top: stretch::style::Dimension::Points(10f32),
|
style.style.padding.end = v;
|
||||||
|
|
||||||
// // bottom?
|
|
||||||
// // bottom: stretch::style::Dimension::Points(10f32),
|
|
||||||
|
|
||||||
match name {
|
|
||||||
"padding" => {
|
|
||||||
if name.ends_with("px") {
|
|
||||||
if let Ok(px) = value.trim_end_matches("px").parse::<f32>() {
|
|
||||||
style.style.padding.bottom = Dimension::Points(px);
|
|
||||||
style.style.padding.top = Dimension::Points(px);
|
|
||||||
style.style.padding.start = Dimension::Points(px);
|
|
||||||
style.style.padding.end = Dimension::Points(px);
|
|
||||||
}
|
|
||||||
} else if name.ends_with("%") {
|
|
||||||
if let Ok(pct) = value.trim_end_matches("%").parse::<f32>() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
"padding-bottom" => style.style.padding.bottom = Dimension::Percent(v / 100.0),
|
||||||
"padding-bottom" => {
|
"padding-left" => style.style.padding.start = Dimension::Percent(v / 100.0),
|
||||||
if let Ok(px) = value.trim_end_matches("px").parse::<f32>() {
|
"padding-right" => style.style.padding.end = Dimension::Percent(v / 100.0),
|
||||||
style.style.padding.bottom = Dimension::Points(px);
|
"padding-top" => style.style.padding.top = Dimension::Percent(v / 100.0),
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
Some(UnitSystem::Point(v)) => match name {
|
||||||
|
"padding" => {
|
||||||
|
style.style.padding.top = Dimension::Points(v);
|
||||||
|
style.style.padding.bottom = Dimension::Points(v);
|
||||||
|
style.style.padding.start = Dimension::Points(v);
|
||||||
|
style.style.padding.end = Dimension::Points(v);
|
||||||
}
|
}
|
||||||
}
|
"padding-bottom" => style.style.padding.bottom = Dimension::Points(v),
|
||||||
"padding-left" => {
|
"padding-left" => style.style.padding.start = Dimension::Points(v),
|
||||||
if let Ok(px) = value.trim_end_matches("px").parse::<f32>() {
|
"padding-right" => style.style.padding.end = Dimension::Points(v),
|
||||||
style.style.padding.start = Dimension::Points(px);
|
"padding-top" => style.style.padding.top = Dimension::Points(v),
|
||||||
}
|
_ => {}
|
||||||
}
|
},
|
||||||
"padding-right" => {
|
None => {}
|
||||||
if let Ok(px) = value.trim_end_matches("px").parse::<f32>() {
|
|
||||||
style.style.padding.end = Dimension::Points(px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"padding-top" => {
|
|
||||||
if let Ok(px) = value.trim_end_matches("px").parse::<f32>() {
|
|
||||||
style.style.padding.top = Dimension::Points(px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,12 +622,34 @@ pub fn apply_size(name: &str, value: &str, style: &mut StyleModifer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_margin(name: &str, value: &str, style: &mut StyleModifer) {
|
pub fn apply_margin(name: &str, value: &str, style: &mut StyleModifer) {
|
||||||
match name {
|
match parse_value(value) {
|
||||||
"margin" => {}
|
Some(UnitSystem::Percent(v)) => match name {
|
||||||
"margin-bottom" => {}
|
"margin" => {
|
||||||
"margin-left" => {}
|
let v = Dimension::Percent(v / 100.0);
|
||||||
"margin-right" => {}
|
style.style.margin.top = v;
|
||||||
"margin-top" => {}
|
style.style.margin.bottom = v;
|
||||||
_ => {}
|
style.style.margin.start = v;
|
||||||
|
style.style.margin.end = v;
|
||||||
|
}
|
||||||
|
"margin-top" => style.style.margin.top = Dimension::Percent(v / 100.0),
|
||||||
|
"margin-bottom" => style.style.margin.bottom = Dimension::Percent(v / 100.0),
|
||||||
|
"margin-left" => style.style.margin.start = Dimension::Percent(v / 100.0),
|
||||||
|
"margin-right" => style.style.margin.end = Dimension::Percent(v / 100.0),
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
Some(UnitSystem::Point(v)) => match name {
|
||||||
|
"margin" => {
|
||||||
|
style.style.margin.top = Dimension::Points(v);
|
||||||
|
style.style.margin.bottom = Dimension::Points(v);
|
||||||
|
style.style.margin.start = Dimension::Points(v);
|
||||||
|
style.style.margin.end = Dimension::Points(v);
|
||||||
|
}
|
||||||
|
"margin-top" => style.style.margin.top = Dimension::Points(v),
|
||||||
|
"margin-bottom" => style.style.margin.bottom = Dimension::Points(v),
|
||||||
|
"margin-left" => style.style.margin.start = Dimension::Points(v),
|
||||||
|
"margin-right" => style.style.margin.end = Dimension::Points(v),
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+6
-2
@@ -7,6 +7,12 @@ use crate::{
|
|||||||
TuiNode,
|
TuiNode,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
The layout system uses the lineheight as one point.
|
||||||
|
|
||||||
|
stretch uses fractional points, so we can rasterize if we need too, but not with characters
|
||||||
|
this means anything thats "1px" is 1 lineheight. Unfortunately, text cannot be smaller or bigger
|
||||||
|
*/
|
||||||
pub fn collect_layout<'a>(
|
pub fn collect_layout<'a>(
|
||||||
layout: &mut stretch2::Stretch,
|
layout: &mut stretch2::Stretch,
|
||||||
nodes: &mut HashMap<ElementId, TuiNode<'a>>,
|
nodes: &mut HashMap<ElementId, TuiNode<'a>>,
|
||||||
@@ -17,7 +23,6 @@ pub fn collect_layout<'a>(
|
|||||||
|
|
||||||
match node {
|
match node {
|
||||||
VNode::Text(t) => {
|
VNode::Text(t) => {
|
||||||
//
|
|
||||||
let id = t.id.get().unwrap();
|
let id = t.id.get().unwrap();
|
||||||
let char_len = t.text.chars().count();
|
let char_len = t.text.chars().count();
|
||||||
|
|
||||||
@@ -29,7 +34,6 @@ pub fn collect_layout<'a>(
|
|||||||
// text is as long as it is declared
|
// text is as long as it is declared
|
||||||
width: Dimension::Points(char_len as f32),
|
width: Dimension::Points(char_len as f32),
|
||||||
},
|
},
|
||||||
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+93
-100
@@ -1,11 +1,16 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use crossterm::{
|
use crossterm::{
|
||||||
event::{DisableMouseCapture, EnableMouseCapture},
|
event::{self, DisableMouseCapture, EnableMouseCapture, Event as TermEvent, KeyCode, KeyEvent},
|
||||||
execute,
|
execute,
|
||||||
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
||||||
};
|
};
|
||||||
use dioxus::core::*;
|
use dioxus::core::*;
|
||||||
use std::{collections::HashMap, io};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
io,
|
||||||
|
sync::mpsc,
|
||||||
|
time::{Duration, Instant},
|
||||||
|
};
|
||||||
use stretch2::{prelude::Size, Stretch};
|
use stretch2::{prelude::Size, Stretch};
|
||||||
use tui::{backend::CrosstermBackend, style::Style as TuiStyle, Terminal};
|
use tui::{backend::CrosstermBackend, style::Style as TuiStyle, Terminal};
|
||||||
|
|
||||||
@@ -24,21 +29,6 @@ pub struct TuiNode<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_vdom(vdom: &VirtualDom) -> Result<()> {
|
pub fn render_vdom(vdom: &VirtualDom) -> Result<()> {
|
||||||
/*
|
|
||||||
-> collect all the nodes with their layout
|
|
||||||
-> solve their layout
|
|
||||||
-> render the nodes in the right place with tui/crosstream
|
|
||||||
-> while rendering, apply styling
|
|
||||||
|
|
||||||
use simd to compare lines for diffing?
|
|
||||||
|
|
||||||
*/
|
|
||||||
let mut layout = Stretch::new();
|
|
||||||
let mut nodes = HashMap::new();
|
|
||||||
|
|
||||||
let root_node = vdom.base_scope().root_node();
|
|
||||||
layout::collect_layout(&mut layout, &mut nodes, vdom, root_node);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get the terminal to calcualte the layout from
|
Get the terminal to calcualte the layout from
|
||||||
*/
|
*/
|
||||||
@@ -52,30 +42,90 @@ pub fn render_vdom(vdom: &VirtualDom) -> Result<()> {
|
|||||||
let backend = CrosstermBackend::new(io::stdout());
|
let backend = CrosstermBackend::new(io::stdout());
|
||||||
let mut terminal = Terminal::new(backend).unwrap();
|
let mut terminal = Terminal::new(backend).unwrap();
|
||||||
|
|
||||||
let dims = terminal.size().unwrap();
|
// Setup input handling
|
||||||
let width = dims.width;
|
let (tx, rx) = mpsc::channel();
|
||||||
let height = dims.height;
|
std::thread::spawn(move || {
|
||||||
|
let tick_rate = Duration::from_millis(100);
|
||||||
|
let mut last_tick = Instant::now();
|
||||||
|
loop {
|
||||||
|
// poll for tick rate duration, if no events, sent tick event.
|
||||||
|
let timeout = tick_rate
|
||||||
|
.checked_sub(last_tick.elapsed())
|
||||||
|
.unwrap_or_else(|| Duration::from_secs(0));
|
||||||
|
|
||||||
/*
|
if event::poll(timeout).unwrap() {
|
||||||
Compute the layout given th terminal size
|
if let TermEvent::Key(key) = event::read().unwrap() {
|
||||||
*/
|
tx.send(InputEvent::UserInput(key)).unwrap();
|
||||||
let node_id = root_node.try_mounted_id().unwrap();
|
}
|
||||||
let root_layout = nodes[&node_id].layout;
|
}
|
||||||
layout.compute_layout(
|
|
||||||
root_layout,
|
|
||||||
Size {
|
|
||||||
width: stretch2::prelude::Number::Defined(width as f32),
|
|
||||||
height: stretch2::prelude::Number::Defined(height as f32),
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
|
|
||||||
terminal.draw(|frame| {
|
if last_tick.elapsed() >= tick_rate {
|
||||||
//
|
tx.send(InputEvent::Tick).unwrap();
|
||||||
render::render_vnode(frame, &layout, &mut nodes, vdom, root_node);
|
last_tick = Instant::now();
|
||||||
assert!(nodes.is_empty());
|
}
|
||||||
})?;
|
}
|
||||||
|
});
|
||||||
|
|
||||||
std::thread::sleep(std::time::Duration::from_millis(5000));
|
terminal.clear().unwrap();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let dims = terminal.size().unwrap();
|
||||||
|
let width = dims.width;
|
||||||
|
let height = dims.height;
|
||||||
|
|
||||||
|
/*
|
||||||
|
-> collect all the nodes with their layout
|
||||||
|
-> solve their layout
|
||||||
|
-> render the nodes in the right place with tui/crosstream
|
||||||
|
-> while rendering, apply styling
|
||||||
|
|
||||||
|
use simd to compare lines for diffing?
|
||||||
|
|
||||||
|
*/
|
||||||
|
let mut layout = Stretch::new();
|
||||||
|
let mut nodes = HashMap::new();
|
||||||
|
|
||||||
|
let root_node = vdom.base_scope().root_node();
|
||||||
|
layout::collect_layout(&mut layout, &mut nodes, vdom, root_node);
|
||||||
|
/*
|
||||||
|
Compute the layout given th terminal size
|
||||||
|
*/
|
||||||
|
let node_id = root_node.try_mounted_id().unwrap();
|
||||||
|
let root_layout = nodes[&node_id].layout;
|
||||||
|
layout.compute_layout(
|
||||||
|
root_layout,
|
||||||
|
Size {
|
||||||
|
width: stretch2::prelude::Number::Defined(width as f32),
|
||||||
|
height: stretch2::prelude::Number::Defined(height as f32),
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
terminal.draw(|frame| {
|
||||||
|
//
|
||||||
|
render::render_vnode(frame, &layout, &mut nodes, vdom, root_node);
|
||||||
|
assert!(nodes.is_empty());
|
||||||
|
})?;
|
||||||
|
|
||||||
|
match rx.recv()? {
|
||||||
|
InputEvent::UserInput(event) => match event.code {
|
||||||
|
KeyCode::Char('q') => {
|
||||||
|
disable_raw_mode()?;
|
||||||
|
execute!(
|
||||||
|
terminal.backend_mut(),
|
||||||
|
LeaveAlternateScreen,
|
||||||
|
DisableMouseCapture
|
||||||
|
)?;
|
||||||
|
terminal.show_cursor()?;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_ => {} // handle event
|
||||||
|
},
|
||||||
|
InputEvent::Tick => {} // tick
|
||||||
|
InputEvent::Close => {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
disable_raw_mode()?;
|
disable_raw_mode()?;
|
||||||
execute!(
|
execute!(
|
||||||
@@ -88,65 +138,8 @@ pub fn render_vdom(vdom: &VirtualDom) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// enum InputEvent {
|
enum InputEvent {
|
||||||
// UserInput(KeyEvent),
|
UserInput(KeyEvent),
|
||||||
// Close,
|
Close,
|
||||||
// Tick,
|
Tick,
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // Setup input handling
|
|
||||||
// let (tx, rx) = mpsc::channel();
|
|
||||||
// let tick_rate = Duration::from_millis(100);
|
|
||||||
// thread::spawn(move || {
|
|
||||||
// let mut last_tick = Instant::now();
|
|
||||||
// loop {
|
|
||||||
// // poll for tick rate duration, if no events, sent tick event.
|
|
||||||
// let timeout = tick_rate
|
|
||||||
// .checked_sub(last_tick.elapsed())
|
|
||||||
// .unwrap_or_else(|| Duration::from_secs(0));
|
|
||||||
|
|
||||||
// if event::poll(timeout).unwrap() {
|
|
||||||
// if let TermEvent::Key(key) = event::read().unwrap() {
|
|
||||||
// tx.send(InputEvent::UserInput(key)).unwrap();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // if last_tick.elapsed() >= tick_rate {
|
|
||||||
// // tx.send(InputEvent::Tick).unwrap();
|
|
||||||
// // last_tick = Instant::now();
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// terminal.clear()?;
|
|
||||||
|
|
||||||
// // loop {
|
|
||||||
// terminal.draw(|frame| {
|
|
||||||
// // draw the frame
|
|
||||||
// let size = frame.size();
|
|
||||||
// let root_node = vdom.base_scope().root_node();
|
|
||||||
// let block = render_vnode(frame, vdom, root_node);
|
|
||||||
|
|
||||||
// frame.render_widget(block, size);
|
|
||||||
// })?;
|
|
||||||
|
|
||||||
// // // terminal.draw(|f| ui::draw(f, &mut app))?;
|
|
||||||
// match rx.recv()? {
|
|
||||||
// InputEvent::UserInput(event) => match event.code {
|
|
||||||
// KeyCode::Char('q') => {
|
|
||||||
// disable_raw_mode()?;
|
|
||||||
// execute!(
|
|
||||||
// terminal.backend_mut(),
|
|
||||||
// LeaveAlternateScreen,
|
|
||||||
// DisableMouseCapture
|
|
||||||
// )?;
|
|
||||||
// terminal.show_cursor()?;
|
|
||||||
// // break;
|
|
||||||
// }
|
|
||||||
// _ => {} // handle event
|
|
||||||
// },
|
|
||||||
// InputEvent::Tick => {} // tick
|
|
||||||
// InputEvent::Close => {
|
|
||||||
// // break;
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
@@ -14,32 +14,60 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
background-color: black;
|
||||||
align-items: center;
|
/* justify-content: center;
|
||||||
|
align-items: center; */
|
||||||
/* margin: auto; */
|
/* margin: auto; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.smaller {
|
.smaller {
|
||||||
height: 50%;
|
height: 70%;
|
||||||
|
width: 70%;
|
||||||
|
background-color: green;
|
||||||
|
/* justify-content: center; */
|
||||||
|
/* align-items: center; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.superinner {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
/* display: flex; */
|
||||||
|
/* */
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-right: 20px;
|
||||||
|
/* */
|
||||||
|
background-color: red;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: violet;
|
flex-direction: column;
|
||||||
|
/* margin: 20px; */
|
||||||
|
/* margin: 20px; */
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
<div class="smaller">
|
||||||
|
<div class="superinner">
|
||||||
|
<h1>Hello World</h1>
|
||||||
|
<p>This is a test</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="container">
|
||||||
<div class="smaller">
|
<div class="smaller">
|
||||||
hello world
|
hello world
|
||||||
<div style="color: red;">
|
<div style="color: green; margin: 40px;">
|
||||||
goodbye
|
goodbye
|
||||||
<div>
|
<div style="color:red;">
|
||||||
asdasdasd
|
asdasdasd
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
Reference in new issue
Block a user