mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-06 03:36:42 +01:00
group tui_engine and tui_content; cargo update
This commit is contained in:
parent
877b344765
commit
71dead5150
13 changed files with 150 additions and 72 deletions
98
Cargo.lock
generated
98
Cargo.lock
generated
|
|
@ -102,12 +102,6 @@ version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06"
|
checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "byteorder"
|
|
||||||
version = "1.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cassowary"
|
name = "cassowary"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
|
@ -177,7 +171,7 @@ dependencies = [
|
||||||
"crossterm_winapi",
|
"crossterm_winapi",
|
||||||
"mio",
|
"mio",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"rustix",
|
"rustix 0.38.44",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
"signal-hook-mio",
|
"signal-hook-mio",
|
||||||
"winapi",
|
"winapi",
|
||||||
|
|
@ -229,9 +223,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.14.0"
|
version = "1.15.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b7914353092ddf589ad78f25c5c1c21b7f80b0ff8621e7c814c3485b5306da9d"
|
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encode_unicode"
|
name = "encode_unicode"
|
||||||
|
|
@ -275,9 +269,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foldhash"
|
name = "foldhash"
|
||||||
version = "0.1.4"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
|
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
|
|
@ -333,9 +327,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indoc"
|
name = "indoc"
|
||||||
version = "2.0.5"
|
version = "2.0.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
|
checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "instability"
|
name = "instability"
|
||||||
|
|
@ -370,9 +364,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.14"
|
version = "1.0.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
|
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
|
|
@ -419,9 +413,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.170"
|
version = "0.2.171"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
|
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
|
|
@ -429,6 +423,12 @@ version = "0.4.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.12"
|
version = "0.4.12"
|
||||||
|
|
@ -501,9 +501,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.20.3"
|
version = "1.21.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
|
checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "palette"
|
name = "palette"
|
||||||
|
|
@ -603,9 +603,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.20"
|
version = "0.2.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
@ -673,9 +673,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.39"
|
version = "1.0.40"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801"
|
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
@ -742,9 +742,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "raw-cpuid"
|
name = "raw-cpuid"
|
||||||
version = "11.4.0"
|
version = "11.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "529468c1335c1c03919960dfefdb1b3648858c20d7ec2d0663e728e4a717efbc"
|
checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
@ -779,15 +779,28 @@ dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys 0.4.15",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustix"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f7178faa4b75a30e269c71e61c353ce2748cf3d76f0c44c393f4e60abf49b825"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"linux-raw-sys 0.9.3",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.19"
|
version = "1.0.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
|
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rusty-fork"
|
name = "rusty-fork"
|
||||||
|
|
@ -803,9 +816,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.19"
|
version = "1.0.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
|
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
|
|
@ -891,9 +904,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.99"
|
version = "2.0.100"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2"
|
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -902,15 +915,14 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.17.1"
|
version = "3.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230"
|
checksum = "488960f40a3fd53d72c2a29a58722561dee8afdd175bd88e3db4677d7b2ba600"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
|
||||||
"fastrand",
|
"fastrand",
|
||||||
"getrandom 0.3.1",
|
"getrandom 0.3.1",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix",
|
"rustix 1.0.2",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -949,6 +961,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proptest",
|
"proptest",
|
||||||
"proptest-derive",
|
"proptest-derive",
|
||||||
|
"tengri",
|
||||||
"tengri_dsl",
|
"tengri_dsl",
|
||||||
"tengri_tui",
|
"tengri_tui",
|
||||||
]
|
]
|
||||||
|
|
@ -1014,9 +1027,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.17"
|
version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe"
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
|
|
@ -1253,19 +1266,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.7.35"
|
version = "0.8.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
|
||||||
"zerocopy-derive",
|
"zerocopy-derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy-derive"
|
name = "zerocopy-derive"
|
||||||
version = "0.7.35"
|
version = "0.8.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
||||||
36
input/src/input.rs
Normal file
36
input/src/input.rs
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
use crate::*;
|
||||||
|
use std::time::Duration;
|
||||||
|
use std::thread::JoinHandle;
|
||||||
|
|
||||||
|
/// Event source
|
||||||
|
pub trait Input: Send + Sync + Sized {
|
||||||
|
/// Type of input event
|
||||||
|
type Event;
|
||||||
|
/// Result of handling input
|
||||||
|
type Handled; // TODO: make this an Option<Box dyn Command<Self>> containing the undo
|
||||||
|
/// Currently handled event
|
||||||
|
fn event (&self) -> &Self::Event;
|
||||||
|
/// Whether component should exit
|
||||||
|
fn is_done (&self) -> bool;
|
||||||
|
/// Mark component as done
|
||||||
|
fn done (&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Input thread entrypoint.
|
||||||
|
pub trait InputRun<T> {
|
||||||
|
fn run_input (engine: T, state: Self, timer: Duration) -> JoinHandle<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handle input through a mutable reference.
|
||||||
|
pub trait Handle<E: Input>: Send + Sync {
|
||||||
|
fn handle (&mut self, _input: &E) -> Perhaps<E::Handled> {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handle input through an immutable reference (e.g. [Arc<RwLock>] or [Arc<Mutex>])
|
||||||
|
pub trait HandleRef<E: Input>: Send + Sync {
|
||||||
|
fn handle (&self, _input: &E) -> Perhaps<E::Handled> {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,5 @@
|
||||||
mod tui_buffer; pub use self::tui_buffer::*;
|
|
||||||
mod tui_color; pub use self::tui_color::*;
|
|
||||||
mod tui_content; pub use self::tui_content::*;
|
|
||||||
mod tui_engine; pub use self::tui_engine::*;
|
mod tui_engine; pub use self::tui_engine::*;
|
||||||
mod tui_file; pub use self::tui_file::*;
|
mod tui_content; pub use self::tui_content::*;
|
||||||
mod tui_input; pub use self::tui_input::*;
|
|
||||||
mod tui_output; pub use self::tui_output::*;
|
|
||||||
mod tui_perf; pub use self::tui_perf::*;
|
|
||||||
|
|
||||||
pub use ::tengri_input as input;
|
pub use ::tengri_input as input;
|
||||||
pub(crate) use ::tengri_input::*;
|
pub(crate) use ::tengri_input::*;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use crate::Color::*;
|
use crate::Color::*;
|
||||||
use ratatui::prelude::Position;
|
use ratatui::prelude::Position;
|
||||||
|
|
||||||
|
mod tui_color; pub use self::tui_color::*;
|
||||||
|
mod tui_file; pub use self::tui_file::*;
|
||||||
|
|
||||||
macro_rules! impl_content_layout_render {
|
macro_rules! impl_content_layout_render {
|
||||||
($Output:ty: |$self:ident: $Struct:ty, $to:ident| layout = $layout:expr; render = $render:expr) => {
|
($Output:ty: |$self:ident: $Struct:ty, $to:ident| layout = $layout:expr; render = $render:expr) => {
|
||||||
impl Content<$Output> for $Struct {
|
impl Content<$Output> for $Struct {
|
||||||
|
|
@ -13,19 +17,24 @@ impl_content_layout_render!(TuiOut: |self: &str, to|
|
||||||
layout = to.center_xy([self.chars().count() as u16, 1]);
|
layout = to.center_xy([self.chars().count() as u16, 1]);
|
||||||
render = {let [x, y, ..] = Content::layout(self, to.area());
|
render = {let [x, y, ..] = Content::layout(self, to.area());
|
||||||
to.blit(self, x, y, None)});
|
to.blit(self, x, y, None)});
|
||||||
|
|
||||||
impl_content_layout_render!(TuiOut: |self: String, to|
|
impl_content_layout_render!(TuiOut: |self: String, to|
|
||||||
layout = to.center_xy([self.chars().count() as u16, 1]);
|
layout = to.center_xy([self.chars().count() as u16, 1]);
|
||||||
render = {let [x, y, ..] = Content::layout(self, to.area());
|
render = {let [x, y, ..] = Content::layout(self, to.area());
|
||||||
to.blit(self, x, y, None)});
|
to.blit(self, x, y, None)});
|
||||||
|
|
||||||
impl_content_layout_render!(TuiOut: |self: std::sync::RwLock<String>, to|
|
impl_content_layout_render!(TuiOut: |self: std::sync::RwLock<String>, to|
|
||||||
layout = Content::<TuiOut>::layout(&self.read().unwrap(), to);
|
layout = Content::<TuiOut>::layout(&self.read().unwrap(), to);
|
||||||
render = Content::<TuiOut>::render(&self.read().unwrap(), to));
|
render = Content::<TuiOut>::render(&self.read().unwrap(), to));
|
||||||
|
|
||||||
impl_content_layout_render!(TuiOut: |self: std::sync::RwLockReadGuard<'_, String>, to|
|
impl_content_layout_render!(TuiOut: |self: std::sync::RwLockReadGuard<'_, String>, to|
|
||||||
layout = Content::<TuiOut>::layout(&**self, to);
|
layout = Content::<TuiOut>::layout(&**self, to);
|
||||||
render = Content::<TuiOut>::render(&**self, to));
|
render = Content::<TuiOut>::render(&**self, to));
|
||||||
|
|
||||||
impl_content_layout_render!(TuiOut: |self: Arc<str>, to|
|
impl_content_layout_render!(TuiOut: |self: Arc<str>, to|
|
||||||
layout = to.center_xy([self.chars().count() as u16, 1]);
|
layout = to.center_xy([self.chars().count() as u16, 1]);
|
||||||
render = to.blit(self, to.area.x(), to.area.y(), None));
|
render = to.blit(self, to.area.x(), to.area.y(), None));
|
||||||
|
|
||||||
impl<T: Content<TuiOut>> Content<TuiOut> for std::sync::Arc<T> {
|
impl<T: Content<TuiOut>> Content<TuiOut> for std::sync::Arc<T> {
|
||||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||||
Content::<TuiOut>::layout(&**self, to)
|
Content::<TuiOut>::layout(&**self, to)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use rand::{thread_rng, distributions::uniform::UniformSampler};
|
use rand::{thread_rng, distributions::uniform::UniformSampler};
|
||||||
|
|
||||||
impl Tui {
|
impl Tui {
|
||||||
pub const fn null () -> Color { Color::Reset }
|
pub const fn null () -> Color { Color::Reset }
|
||||||
pub const fn g (g: u8) -> Color { Color::Rgb(g, g, g) }
|
pub const fn g (g: u8) -> Color { Color::Rgb(g, g, g) }
|
||||||
|
|
@ -23,7 +24,9 @@ impl Tui {
|
||||||
//fn ti1 () -> Color { Color::Rgb(150, 160, 90) }
|
//fn ti1 () -> Color { Color::Rgb(150, 160, 90) }
|
||||||
//fn ti2 () -> Color { Color::Rgb(120, 130, 100) }
|
//fn ti2 () -> Color { Color::Rgb(120, 130, 100) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait HasColor { fn color (&self) -> ItemColor; }
|
pub trait HasColor { fn color (&self) -> ItemColor; }
|
||||||
|
|
||||||
#[macro_export] macro_rules! has_color {
|
#[macro_export] macro_rules! has_color {
|
||||||
(|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => {
|
(|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => {
|
||||||
impl $(<$($L),*$($T $(: $U)?),*>)? HasColor for $Struct $(<$($L),*$($T),*>)? {
|
impl $(<$($L),*$($T $(: $U)?),*>)? HasColor for $Struct $(<$($L),*$($T),*>)? {
|
||||||
|
|
@ -31,17 +34,22 @@ pub trait HasColor { fn color (&self) -> ItemColor; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A color in OKHSL and RGB representations.
|
/// A color in OKHSL and RGB representations.
|
||||||
#[derive(Debug, Default, Copy, Clone, PartialEq)] pub struct ItemColor {
|
#[derive(Debug, Default, Copy, Clone, PartialEq)] pub struct ItemColor {
|
||||||
pub okhsl: Okhsl<f32>,
|
pub okhsl: Okhsl<f32>,
|
||||||
pub rgb: Color,
|
pub rgb: Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
from!(|okhsl: Okhsl<f32>|ItemColor = Self { okhsl, rgb: okhsl_to_rgb(okhsl) });
|
from!(|okhsl: Okhsl<f32>|ItemColor = Self { okhsl, rgb: okhsl_to_rgb(okhsl) });
|
||||||
|
|
||||||
pub fn okhsl_to_rgb (color: Okhsl<f32>) -> Color {
|
pub fn okhsl_to_rgb (color: Okhsl<f32>) -> Color {
|
||||||
let Srgb { red, green, blue, .. }: Srgb<f32> = Srgb::from_color_unclamped(color);
|
let Srgb { red, green, blue, .. }: Srgb<f32> = Srgb::from_color_unclamped(color);
|
||||||
Color::Rgb((red * 255.0) as u8, (green * 255.0) as u8, (blue * 255.0) as u8,)
|
Color::Rgb((red * 255.0) as u8, (green * 255.0) as u8, (blue * 255.0) as u8,)
|
||||||
}
|
}
|
||||||
|
|
||||||
from!(|rgb: Color|ItemColor = Self { rgb, okhsl: rgb_to_okhsl(rgb) });
|
from!(|rgb: Color|ItemColor = Self { rgb, okhsl: rgb_to_okhsl(rgb) });
|
||||||
|
|
||||||
pub fn rgb_to_okhsl (color: Color) -> Okhsl<f32> {
|
pub fn rgb_to_okhsl (color: Color) -> Okhsl<f32> {
|
||||||
if let Color::Rgb(r, g, b) = color {
|
if let Color::Rgb(r, g, b) = color {
|
||||||
Okhsl::from_color(Srgb::new(r as f32 / 255.0, g as f32 / 255.0, b as f32 / 255.0))
|
Okhsl::from_color(Srgb::new(r as f32 / 255.0, g as f32 / 255.0, b as f32 / 255.0))
|
||||||
|
|
@ -49,6 +57,7 @@ pub fn rgb_to_okhsl (color: Color) -> Okhsl<f32> {
|
||||||
unreachable!("only Color::Rgb is supported")
|
unreachable!("only Color::Rgb is supported")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A single color within item theme parameters, in OKHSL and RGB representations.
|
// A single color within item theme parameters, in OKHSL and RGB representations.
|
||||||
impl ItemColor {
|
impl ItemColor {
|
||||||
pub const fn from_rgb (rgb: Color) -> Self {
|
pub const fn from_rgb (rgb: Color) -> Self {
|
||||||
|
|
@ -77,6 +86,7 @@ impl ItemColor {
|
||||||
self.okhsl.mix(other.okhsl, distance).into()
|
self.okhsl.mix(other.okhsl, distance).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A color in OKHSL and RGB with lighter and darker variants.
|
/// A color in OKHSL and RGB with lighter and darker variants.
|
||||||
#[derive(Debug, Default, Copy, Clone, PartialEq)] pub struct ItemPalette {
|
#[derive(Debug, Default, Copy, Clone, PartialEq)] pub struct ItemPalette {
|
||||||
pub base: ItemColor,
|
pub base: ItemColor,
|
||||||
|
|
@ -87,6 +97,7 @@ impl ItemColor {
|
||||||
pub darker: ItemColor,
|
pub darker: ItemColor,
|
||||||
pub darkest: ItemColor,
|
pub darkest: ItemColor,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ItemPalette {
|
impl ItemPalette {
|
||||||
pub const G: [Self;256] = {
|
pub const G: [Self;256] = {
|
||||||
let mut builder = konst::array::ArrayBuilder::new();
|
let mut builder = konst::array::ArrayBuilder::new();
|
||||||
|
|
@ -159,5 +170,6 @@ impl ItemPalette {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
from!(|base: Color| ItemPalette = Self::from_tui_color(base));
|
from!(|base: Color| ItemPalette = Self::from_tui_color(base));
|
||||||
from!(|base: ItemColor|ItemPalette = Self::from_item_color(base));
|
from!(|base: ItemColor|ItemPalette = Self::from_item_color(base));
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
mod tui_buffer; pub use self::tui_buffer::*;
|
||||||
|
mod tui_input; pub use self::tui_input::*;
|
||||||
|
mod tui_output; pub use self::tui_output::*;
|
||||||
|
mod tui_perf; pub use self::tui_perf::*;
|
||||||
|
|
||||||
pub struct Tui {
|
pub struct Tui {
|
||||||
pub exited: Arc<AtomicBool>,
|
pub exited: Arc<AtomicBool>,
|
||||||
pub backend: CrosstermBackend<Stdout>,
|
pub backend: CrosstermBackend<Stdout>,
|
||||||
|
|
@ -7,6 +13,31 @@ pub struct Tui {
|
||||||
pub area: [u16;4],
|
pub area: [u16;4],
|
||||||
pub perf: PerfModel,
|
pub perf: PerfModel,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait TuiRun<R: Render<TuiOut> + Handle<TuiIn> + 'static> {
|
||||||
|
/// Run an app in the main loop.
|
||||||
|
fn run (&self, state: &Arc<RwLock<R>>) -> Usually<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Render<TuiOut> + Handle<TuiIn> + 'static> TuiRun<T> for Arc<RwLock<Tui>> {
|
||||||
|
fn run (&self, state: &Arc<RwLock<T>>) -> Usually<()> {
|
||||||
|
let _input_thread = TuiIn::run_input(self, state, Duration::from_millis(100));
|
||||||
|
self.write().unwrap().setup()?;
|
||||||
|
let render_thread = TuiOut::run_output(self, state, Duration::from_millis(10));
|
||||||
|
match render_thread.join() {
|
||||||
|
Ok(result) => {
|
||||||
|
self.write().unwrap().teardown()?;
|
||||||
|
println!("\n\rRan successfully: {result:?}\n\r");
|
||||||
|
},
|
||||||
|
Err(error) => {
|
||||||
|
self.write().unwrap().teardown()?;
|
||||||
|
panic!("\n\rRender thread failed: {error:?}.\n\r")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Tui {
|
impl Tui {
|
||||||
/// Construct a new TUI engine and wrap it for shared ownership.
|
/// Construct a new TUI engine and wrap it for shared ownership.
|
||||||
pub fn new () -> Usually<Arc<RwLock<Self>>> {
|
pub fn new () -> Usually<Arc<RwLock<Self>>> {
|
||||||
|
|
@ -58,25 +89,3 @@ impl Tui {
|
||||||
disable_raw_mode().map_err(Into::into)
|
disable_raw_mode().map_err(Into::into)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub trait TuiRun<R: Render<TuiOut> + Handle<TuiIn> + 'static> {
|
|
||||||
/// Run an app in the main loop.
|
|
||||||
fn run (&self, state: &Arc<RwLock<R>>) -> Usually<()>;
|
|
||||||
}
|
|
||||||
impl<T: Render<TuiOut> + Handle<TuiIn> + 'static> TuiRun<T> for Arc<RwLock<Tui>> {
|
|
||||||
fn run (&self, state: &Arc<RwLock<T>>) -> Usually<()> {
|
|
||||||
let _input_thread = TuiIn::run_input(self, state, Duration::from_millis(100));
|
|
||||||
self.write().unwrap().setup()?;
|
|
||||||
let render_thread = TuiOut::run_output(self, state, Duration::from_millis(10));
|
|
||||||
match render_thread.join() {
|
|
||||||
Ok(result) => {
|
|
||||||
self.write().unwrap().teardown()?;
|
|
||||||
println!("\n\rRan successfully: {result:?}\n\r");
|
|
||||||
},
|
|
||||||
Err(error) => {
|
|
||||||
self.write().unwrap().teardown()?;
|
|
||||||
panic!("\n\rRender thread failed: {error:?}.\n\r")
|
|
||||||
},
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
pub fn buffer_update (buf: &mut Buffer, area: [u16;4], callback: &impl Fn(&mut Cell, u16, u16)) {
|
pub fn buffer_update (buf: &mut Buffer, area: [u16;4], callback: &impl Fn(&mut Cell, u16, u16)) {
|
||||||
for row in 0..area.h() {
|
for row in 0..area.h() {
|
||||||
let y = area.y() + row;
|
let y = area.y() + row;
|
||||||
|
|
@ -12,16 +13,19 @@ pub fn buffer_update (buf: &mut Buffer, area: [u16;4], callback: &impl Fn(&mut C
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)] pub struct BigBuffer {
|
#[derive(Default)] pub struct BigBuffer {
|
||||||
pub width: usize,
|
pub width: usize,
|
||||||
pub height: usize,
|
pub height: usize,
|
||||||
pub content: Vec<Cell>
|
pub content: Vec<Cell>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for BigBuffer {
|
impl std::fmt::Debug for BigBuffer {
|
||||||
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||||
write!(f, "[BB {}x{} ({})]", self.width, self.height, self.content.len())
|
write!(f, "[BB {}x{} ({})]", self.width, self.height, self.content.len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BigBuffer {
|
impl BigBuffer {
|
||||||
pub fn new (width: usize, height: usize) -> Self {
|
pub fn new (width: usize, height: usize) -> Self {
|
||||||
Self { width, height, content: vec![Cell::default(); width*height] }
|
Self { width, height, content: vec![Cell::default(); width*height] }
|
||||||
|
|
@ -38,4 +42,5 @@ impl BigBuffer {
|
||||||
y * self.width + x
|
y * self.width + x
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
from!(|size:(usize, usize)| BigBuffer = Self::new(size.0, size.1));
|
from!(|size:(usize, usize)| BigBuffer = Self::new(size.0, size.1));
|
||||||
|
|
@ -2,6 +2,7 @@ use crate::*;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::thread::{spawn, JoinHandle};
|
use std::thread::{spawn, JoinHandle};
|
||||||
use crossterm::event::{poll, read};
|
use crossterm::event::{poll, read};
|
||||||
|
|
||||||
#[derive(Debug, Clone)] pub struct TuiIn(pub Arc<AtomicBool>, pub Event);
|
#[derive(Debug, Clone)] pub struct TuiIn(pub Arc<AtomicBool>, pub Event);
|
||||||
impl Input for TuiIn {
|
impl Input for TuiIn {
|
||||||
type Event = Event;
|
type Event = Event;
|
||||||
Loading…
Add table
Add a link
Reference in a new issue