Render Signal
App now has a renderer object that can be retrieved to send a render signal from outside the application. This is useful for rendering based on operations taking place in other threads.
This commit is contained in:
parent
ba7703e4c2
commit
82e044a34a
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "arkham"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
edition = "2021"
|
||||
|
||||
[[example]]
|
||||
|
@ -37,6 +37,6 @@ path = "examples/paragraph.rs"
|
|||
|
||||
[dependencies]
|
||||
anyhow = "1.0.71"
|
||||
crossterm = "0.26.1"
|
||||
crossterm = "0.27"
|
||||
ctrlc = "3.3.1"
|
||||
textwrap = "0.16.0"
|
||||
|
|
45
src/app.rs
45
src/app.rs
|
@ -1,4 +1,12 @@
|
|||
use std::{any::Any, cell::RefCell, io::Write, marker::PhantomData, rc::Rc};
|
||||
use std::{
|
||||
any::Any,
|
||||
cell::RefCell,
|
||||
io::Write,
|
||||
marker::PhantomData,
|
||||
rc::Rc,
|
||||
sync::mpsc::{channel, Receiver, Sender},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use crossterm::{
|
||||
cursor,
|
||||
|
@ -14,6 +22,17 @@ use crate::{
|
|||
|
||||
use super::input::Keyboard;
|
||||
|
||||
/// A renderer that can signal a render needs to take place.
|
||||
pub struct Renderer {
|
||||
tx: Sender<()>,
|
||||
}
|
||||
|
||||
impl Renderer {
|
||||
pub fn render(&self) {
|
||||
let _ = self.tx.send(());
|
||||
}
|
||||
}
|
||||
|
||||
/// The app is the core container for the application logic, resources,
|
||||
/// state, and run loop.
|
||||
pub struct App<F, Args>
|
||||
|
@ -23,6 +42,8 @@ where
|
|||
{
|
||||
container: Rc<RefCell<Container>>,
|
||||
main_view: View,
|
||||
render_signal: Receiver<()>,
|
||||
render_tx: Sender<()>,
|
||||
root: F,
|
||||
args: PhantomData<Args>,
|
||||
}
|
||||
|
@ -39,14 +60,25 @@ where
|
|||
let container = Rc::new(RefCell::new(Container::default()));
|
||||
let size = terminal::size().unwrap();
|
||||
let main_view = View::new(size);
|
||||
let (render_tx, render_signal) = channel();
|
||||
App {
|
||||
container,
|
||||
root,
|
||||
main_view,
|
||||
render_tx,
|
||||
render_signal,
|
||||
args: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a renderer that can signal the application to rerender. This
|
||||
/// renderer can be cloned and passed between threads.
|
||||
pub fn get_renderer(&self) -> Renderer {
|
||||
Renderer {
|
||||
tx: self.render_tx.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Insert a resource which can be injected into component functions.
|
||||
///
|
||||
/// This resource can only be accessed immutably by reference.
|
||||
|
@ -146,10 +178,11 @@ where
|
|||
.unwrap()
|
||||
.reset();
|
||||
|
||||
if crossterm::event::poll(Duration::from_millis(100)).unwrap_or(false) {
|
||||
if let Ok(event) = crossterm::event::read() {
|
||||
match event {
|
||||
Event::FocusGained => todo!(),
|
||||
Event::FocusLost => todo!(),
|
||||
Event::FocusGained => self.render()?,
|
||||
Event::FocusLost => {}
|
||||
Event::Key(key_event) if key_event.code == KeyCode::Char('q') => {
|
||||
break;
|
||||
}
|
||||
|
@ -160,11 +193,15 @@ where
|
|||
}
|
||||
Event::Mouse(_) => todo!(),
|
||||
Event::Paste(_) => todo!(),
|
||||
Event::Resize(_, _) => todo!(),
|
||||
Event::Resize(_, _) => self.render()?,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
if self.render_signal.try_recv().is_ok() {
|
||||
self.render()?;
|
||||
}
|
||||
}
|
||||
self.teardown();
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use crossterm::style::Color;
|
||||
|
||||
use crate::prelude::{Callable, ToRuneExt};
|
||||
|
||||
use crossterm::style::Color;
|
||||
use std::ops::Deref;
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
pub struct Paragraph {
|
||||
content: String,
|
||||
|
@ -29,7 +27,7 @@ impl Callable<()> for Paragraph {
|
|||
let lines = textwrap::wrap(&self.content, view.width());
|
||||
let mut stack = view.vertical_stack(view.size());
|
||||
for line in lines.iter() {
|
||||
let l = line.deref().to_runes();
|
||||
let _ = line.deref().to_runes();
|
||||
|
||||
stack.insert(line);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ mod view;
|
|||
|
||||
pub mod prelude {
|
||||
pub use super::{
|
||||
app::{App, Terminal},
|
||||
app::{App, Renderer, Terminal},
|
||||
container::{Callable, FromContainer, Res, State},
|
||||
context::ViewContext,
|
||||
geometry::{Pos, Rect, Size},
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
#[allow(dead_code)]
|
||||
pub struct KeybindPlugin;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
#[cfg(any(not(windows), all(windows)))]
|
||||
mod universal {
|
||||
pub const TICK: char = '✔';
|
||||
pub const CROSS: char = '✖';
|
||||
|
@ -61,11 +60,9 @@ mod universal {
|
|||
pub const SEVEN_EIGHTHS: char = '⅞';
|
||||
}
|
||||
|
||||
#[cfg(any(not(windows), all(windows)))]
|
||||
pub use universal::*;
|
||||
|
||||
#[cfg(all(windows))]
|
||||
mod win {
|
||||
pub mod win {
|
||||
pub const TICK: char = '√';
|
||||
pub const CROSS: char = '×';
|
||||
pub const STAR: char = '*';
|
||||
|
@ -89,6 +86,3 @@ mod win {
|
|||
pub const QUESTION_MARK_PREFIX: char = '?';
|
||||
pub const ONE_HALF: char = ' ';
|
||||
}
|
||||
|
||||
#[cfg(all(windows))]
|
||||
pub use win::*;
|
||||
|
|
Loading…
Reference in New Issue