move edn_view into layout

This commit is contained in:
🪞👃🪞 2025-01-07 21:41:51 +01:00
parent 4d0f98acd2
commit 9a70fbc416
13 changed files with 91 additions and 89 deletions

5
Cargo.lock generated
View file

@ -1432,8 +1432,6 @@ dependencies = [
"clojure-reader",
"itertools 0.14.0",
"konst",
"tek_input",
"tek_output",
]
[[package]]
@ -1443,6 +1441,9 @@ version = "0.2.0"
[[package]]
name = "tek_output"
version = "0.2.0"
dependencies = [
"tek_edn",
]
[[package]]
name = "tek_tui"

View file

@ -27,10 +27,7 @@ wavers = "1.4.3"
#winit = { version = "0.30.4", features = [ "x11" ] }
[features]
default = ["tek_input", "tek_output", "tek_edn"]
tek_input = [ "tek_tui/tek_input" ]
tek_output = [ "tek_tui/tek_output" ]
tek_edn = [ "tek_tui/tek_edn" ]
default = []
[[bin]]
name = "tek_arranger"

View file

@ -5,7 +5,7 @@
jack::*,
tek_input::*,
tek_output::*,
tek_tui::{Tui, TuiRun, ItemPalette, ItemColor, ratatui::prelude::Color}
tek_tui::{*, ratatui::prelude::Color}
};
#[allow(unused)]

View file

@ -8,11 +8,8 @@ clojure-reader = "0.3.0"
konst = "0.3.16"
itertools = "0.14.0"
tek_input = { optional = true, path = "../input" }
tek_output = { optional = true, path = "../output" }
[features]
default = ["tek_input", "tek_output"]
default = []
[dev-dependencies]
tek_tui = { path = "../tui" }

View file

@ -1,16 +1,12 @@
#![feature(type_alias_impl_trait)]
#![feature(impl_trait_in_fn_trait_return)]
pub(crate) use std::{
fmt::{Debug, Formatter, Error as FormatError}
};
pub use ::tek_output;
pub(crate) use std::{fmt::{Debug, Formatter, Error as FormatError}};
mod edn_error; pub use self::edn_error::*;
mod edn_item; pub use self::edn_item::*;
mod edn_iter; pub use self::edn_iter::*;
mod edn_token; pub use self::edn_token::*;
mod edn_view; pub use self::edn_view::*;
#[cfg(feature = "tek_output")]
pub(crate) use ::tek_output::*;

View file

@ -1,56 +1,7 @@
# `tek_engine`
this crate provides the `Engine` trait,
which defines an application's lifecycle.
currently, there is one kind of engine implemented, `Tui`.
it uses `ratatui` to present an interactive user interface
in text mode.
at launch, the `Tui` engine spawns two threads,
a **render thread** and an **input thread**. (the
application may spawn further threads, such as a
**jack thread**.)
all threads communicate using shared ownership,
`Arc<RwLock>` and `Arc<Atomic>`. the engine and
application instances are expected to be wrapped
in `Arc<RwLock>`; internally, those synchronization
mechanisms may be used liberally.
## rendering
the **render thread** continually invokes the
`Content::render` method of the application
to redraw the display. it does this efficiently
by using ratatui's double buffering.
thus, for a type to be a valid application for engine `E`,
it must implement the trait `Content<E>`, which allows
it to display content to the engine's output.
the most important thing about the `Content` trait is that
it composes:
* you can implement `Content::content` to build
`Content`s out of other `Content`s
* and/or `Content::area` for custom positioning and sizing,
* and/or `Content::render` for custom rendering
within the given `Content`'s area.
the manner of output is determined by the
`Engine::Output` type, a mutable pointer to which
is passed to the render method, e.g. in the case of
the `Tui` engine: `fn render(&self, output: &mut TuiOut)`
you can use `TuiOut::blit` and `TuiOut::place`
to draw at specified coordinates of the display, and/or
directly modify the underlying `ratatui::Buffer` at
`output.buffer`
rendering is intended to work with read-only access
to the application state. if you really need to update
values during rendering, use interior mutability.
## input handling
the **input thread** polls for keyboard events

View file

@ -5,4 +5,6 @@ version = "0.2.0"
[dev-dependencies]
tek_tui = { path = "../tui" }
tek_engine = { path = "../engine" }
[dependencies]
tek_edn = { path = "../edn" }

View file

@ -1,4 +1,6 @@
# `tek_layout`
# `tek_output`
## free floating layout primitives
this crate exposes several layout operators
which work entirely in unsigned coordinates
@ -39,3 +41,36 @@ are not dependent on rendering framework.
**todo:**
* sensible `Margin`/`Padding`
* `Reduce`
## example rendering loop
the **render thread** continually invokes the
`Content::render` method of the application
to redraw the display. it does this efficiently
by using ratatui's double buffering.
thus, for a type to be a valid application for engine `E`,
it must implement the trait `Content<E>`, which allows
it to display content to the engine's output.
the most important thing about the `Content` trait is that
it composes:
* you can implement `Content::content` to build
`Content`s out of other `Content`s
* and/or `Content::area` for custom positioning and sizing,
* and/or `Content::render` for custom rendering
within the given `Content`'s area.
the manner of output is determined by the
`Engine::Output` type, a mutable pointer to which
is passed to the render method, e.g. in the case of
the `Tui` engine: `fn render(&self, output: &mut TuiOut)`
you can use `TuiOut::blit` and `TuiOut::place`
to draw at specified coordinates of the display, and/or
directly modify the underlying `ratatui::Buffer` at
`output.buffer`
rendering is intended to work with read-only access
to the application state. if you really need to update
values during rendering, use interior mutability.

View file

@ -1,6 +1,5 @@
use crate::*;
use std::marker::PhantomData;
use ::tek_output::*;
use EdnItem::*;
pub type EdnCallback<'a, Output, State> =
@ -99,3 +98,4 @@ impl<E: Output, T: EdnViewData<E> + Send + Sync> Content<E> for EdnView<E, T> {
}
}

View file

@ -21,24 +21,18 @@ mod measure; pub use self::measure::*;
mod transform_xy; pub use self::transform_xy::*;
mod transform_xy_unit; pub use self::transform_xy_unit::*;
mod edn_view;
pub use self::edn_view::*;
pub(crate) use ::tek_edn::*;
pub(crate) use std::marker::PhantomData;
pub(crate) use std::error::Error;
/// Standard result type.
pub type Usually<T> = Result<T, Box<dyn Error>>;
pub(crate) type Usually<T> = Result<T, Box<dyn Error>>;
/// Standard optional result type.
pub type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
/// Prototypal case of implementor macro.
/// Saves 4loc per data pats.
#[macro_export] macro_rules! from {
($(<$($lt:lifetime),+>)?|$state:ident:$Source:ty|$Target:ty=$cb:expr) => {
impl $(<$($lt),+>)? From<$Source> for $Target {
fn from ($state:$Source) -> Self { $cb }
}
};
}
pub(crate) type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
#[cfg(test)] #[test] fn test_layout () -> Usually<()> {
use ::tek_tui::Tui;

View file

@ -10,9 +10,6 @@ crossterm = "0.28.1"
ratatui = { version = "0.29.0", features = [ "unstable-widget-ref", "underline-color" ] }
better-panic = "0.3.0"
tek_edn = { optional = true, path = "../edn" }
tek_input = { optional = true, path = "../input" }
tek_output = { optional = true, path = "../output" }
[features]
default = ["tek_input", "tek_output", "tek_edn"]
tek_edn = { path = "../edn" }
tek_input = { path = "../input" }
tek_output = { path = "../output" }

View file

@ -1,3 +1,15 @@
# `tek_tui`
tui utilities.
the `Tui` struct (the *engine*) implements the
`tek_input::Input` and `tek_output::Output` traits.
at launch, the `Tui` engine spawns two threads,
a **render thread** and an **input thread**. (the
application may spawn further threads, such as a
**jack thread**.)
all threads communicate using shared ownership,
`Arc<RwLock>` and `Arc<Atomic>`. the engine and
application instances are expected to be wrapped
in `Arc<RwLock>`; internally, those synchronization
mechanisms may be used liberally.

View file

@ -1,9 +1,12 @@
pub use ::tek_input;
pub use ::tek_output;
pub use ::tek_edn;
pub(crate) use tek_input::*;
pub use ::tek_output;
pub(crate) use tek_output::*;
pub use ::tek_edn;
pub(crate) use ::tek_edn::*;
mod tui_engine; pub use self::tui_engine::*;
mod tui_content; pub use self::tui_content::*;
mod tui_input; pub use self::tui_input::*;
@ -17,6 +20,23 @@ mod tui_border; pub use self::tui_border::*;
pub(crate) use std::sync::{Arc, RwLock, atomic::{AtomicBool, Ordering::*}};
pub(crate) use std::io::{stdout, Stdout};
pub(crate) use std::error::Error;
/// Standard result type.
pub type Usually<T> = Result<T, Box<dyn Error>>;
/// Standard optional result type.
pub type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
/// Prototypal case of implementor macro.
/// Saves 4loc per data pats.
#[macro_export] macro_rules! from {
($(<$($lt:lifetime),+>)?|$state:ident:$Source:ty|$Target:ty=$cb:expr) => {
impl $(<$($lt),+>)? From<$Source> for $Target {
fn from ($state:$Source) -> Self { $cb }
}
};
}
pub use ::better_panic; pub(crate) use better_panic::{Settings, Verbosity};
pub use ::palette; pub(crate) use ::palette::{*, convert::*, okhsl::*};