mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
wip: borrow checker battles
This commit is contained in:
parent
1d4db3c629
commit
7fbb40fad6
38 changed files with 778 additions and 708 deletions
|
|
@ -1,7 +1,7 @@
|
|||
use crate::*;
|
||||
|
||||
/// A component that may contain [Focusable] components.
|
||||
pub trait Focus <const N: usize, T, U>: Render<T, U> + Handle {
|
||||
pub trait Focus <'a, const N: usize, T, U>: Render<'a, T, U> + Handle {
|
||||
fn focus (&self) -> usize;
|
||||
fn focus_mut (&mut self) -> &mut usize;
|
||||
fn focusable (&self) -> [&dyn Focusable<T, U>;N];
|
||||
|
|
@ -33,13 +33,13 @@ pub trait Focus <const N: usize, T, U>: Render<T, U> + Handle {
|
|||
}
|
||||
|
||||
/// A component that may be focused.
|
||||
pub trait Focusable<T, U>: Render<T, U> + Handle {
|
||||
pub trait Focusable<'a, T, U>: Render<'a, T, U> + Handle {
|
||||
fn is_focused (&self) -> bool;
|
||||
fn set_focused (&mut self, focused: bool);
|
||||
}
|
||||
|
||||
impl<F: Focusable<T, U>, T, U> Focusable<T, U> for Option<F>
|
||||
where Option<F>: Render<T, U>
|
||||
impl<'a, F: Focusable<'a, T, U>, T, U> Focusable<'a, T, U> for Option<F>
|
||||
where Option<F>: Render<'a, T, U>
|
||||
{
|
||||
fn is_focused (&self) -> bool {
|
||||
match self {
|
||||
|
|
@ -59,21 +59,21 @@ impl<F: Focusable<T, U>, T, U> Focusable<T, U> for Option<F>
|
|||
($struct:ident ($focus:ident) : $count:expr => [
|
||||
$($focusable:ident),*
|
||||
]) => {
|
||||
impl Focus<$count> for $struct {
|
||||
impl Focus<$count, T, U> for $struct {
|
||||
fn focus (&self) -> usize {
|
||||
self.$focus
|
||||
}
|
||||
fn focus_mut (&mut self) -> &mut usize {
|
||||
&mut self.$focus
|
||||
}
|
||||
fn focusable (&self) -> [&dyn Focusable;$count] {
|
||||
fn focusable (&self) -> [&dyn Focusable<T, U>;$count] {
|
||||
[
|
||||
$(&self.$focusable as &dyn Focusable,)*
|
||||
$(&self.$focusable as &dyn Focusable<T, U>,)*
|
||||
]
|
||||
}
|
||||
fn focusable_mut (&mut self) -> [&mut dyn Focusable;$count] {
|
||||
fn focusable_mut (&mut self) -> [&mut dyn Focusable<T, U>;$count] {
|
||||
[
|
||||
$(&mut self.$focusable as &mut dyn Focusable,)*
|
||||
$(&mut self.$focusable as &mut dyn Focusable<T, U>,)*
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,3 +32,9 @@ pub fn handle_keymap <T> (
|
|||
] as &'static [KeyBinding<$T>]
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! key {
|
||||
($k:ident $(($char:literal))?, $m:ident, $n: literal, $d: literal, $f: expr) => {
|
||||
(KeyCode::$k $(($char))?, KeyModifiers::$m, $n, $d, &$f as &dyn Fn()->Usually<bool>)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
use crate::{*, jack::*};
|
||||
|
||||
/// A UI component that may be associated with a JACK client by the `Jack` factory.
|
||||
pub trait Device<T, U>: Render<T, U> + Handle + Process + Send + Sync {
|
||||
pub trait Device<'a, T, U>: Render<'a, T, U> + Handle + Process + Send + Sync {
|
||||
/// Perform type erasure for collecting heterogeneous devices.
|
||||
fn boxed (self) -> Box<dyn Device<T, U>> where Self: Sized + 'static {
|
||||
fn boxed (self) -> Box<dyn Device<'a, T, U>> where Self: Sized + 'static {
|
||||
Box::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// All things that implement the required traits can be treated as `Device`.
|
||||
impl<D, T, U> Device<T, U> for D where D: Render<T, U> + Handle + Process {}
|
||||
impl<'a, D, T, U> Device<'a, T, U> for D where D: Render<'a, T, U> + Handle + Process {}
|
||||
|
||||
impl<T, U> Render<T, U> for Box<dyn Device<T, U>> {
|
||||
fn render (&self, to: &mut T) -> Result<Option<U>, Box<dyn std::error::Error>> {
|
||||
impl<'a, T, U> Render<'a, T, U> for Box<dyn Device<'a, T, U>> {
|
||||
fn render (&self, to: &'a mut T) -> Result<Option<U>, Box<dyn std::error::Error>> {
|
||||
(**self).render(to)
|
||||
}
|
||||
}
|
||||
|
|
@ -143,8 +143,10 @@ impl Jack {
|
|||
)?.0,
|
||||
})
|
||||
}
|
||||
pub fn run <D, T, U> (self, state: impl FnOnce(JackPorts)->Box<D>) -> Usually<JackDevice<T, U>>
|
||||
where D: Device<T, U> + Process + Sized + 'static,
|
||||
pub fn run <'a: 'static, D, T, U> (
|
||||
self, state: impl FnOnce(JackPorts)->Box<D>
|
||||
) -> Usually<JackDevice<'a, T, U>>
|
||||
where D: Device<'a, T, U> + Process + Sized + 'static,
|
||||
T: 'static,
|
||||
U: 'static
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,31 +1,31 @@
|
|||
use crate::{*, jack::*};
|
||||
|
||||
/// A [Device] bound to a JACK client and a set of ports.
|
||||
pub struct JackDevice<T, U> {
|
||||
pub struct JackDevice<'a, T, U> {
|
||||
/// The active JACK client of this device.
|
||||
pub client: DynamicAsyncClient,
|
||||
/// The device state, encapsulated for sharing between threads.
|
||||
pub state: Arc<RwLock<Box<dyn Device<T, U>>>>,
|
||||
pub state: Arc<RwLock<Box<dyn Device<'a, T, U>>>>,
|
||||
/// Unowned copies of the device's JACK ports, for connecting to the device.
|
||||
/// The "real" readable/writable `Port`s are owned by the `state`.
|
||||
pub ports: UnownedJackPorts,
|
||||
}
|
||||
impl<T, U> std::fmt::Debug for JackDevice<T, U> {
|
||||
impl<'a, T, U> std::fmt::Debug for JackDevice<'a, T, U> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("JackDevice").field("ports", &self.ports).finish()
|
||||
}
|
||||
}
|
||||
impl<'a, T, U> Render<T, U> for JackDevice<T, U> {
|
||||
fn render (&self, to: &mut T) -> Perhaps<U> {
|
||||
impl<'a, T, U> Render<'a, T, U> for JackDevice<'a, T, U> {
|
||||
fn render (&self, to: &'a mut T) -> Perhaps<U> {
|
||||
self.state.read().unwrap().render(to)
|
||||
}
|
||||
}
|
||||
impl<T, U> Handle for JackDevice<T, U> {
|
||||
impl<'a, T, U> Handle for JackDevice<'a, T, U> {
|
||||
fn handle (&mut self, event: &AppEvent) -> Usually<bool> {
|
||||
self.state.write().unwrap().handle(event)
|
||||
}
|
||||
}
|
||||
impl<T, U> Ports for JackDevice<T, U> {
|
||||
impl<'a, T, U> Ports for JackDevice<'a, T, U> {
|
||||
fn audio_ins (&self) -> Usually<Vec<&Port<Unowned>>> {
|
||||
Ok(self.ports.audio_ins.values().collect())
|
||||
}
|
||||
|
|
@ -39,13 +39,13 @@ impl<T, U> Ports for JackDevice<T, U> {
|
|||
Ok(self.ports.midi_outs.values().collect())
|
||||
}
|
||||
}
|
||||
impl<T, U> JackDevice<T, U> {
|
||||
impl<'a, T, U> JackDevice<'a, T, U> {
|
||||
/// Returns a locked mutex of the state's contents.
|
||||
pub fn state (&self) -> LockResult<RwLockReadGuard<Box<dyn Device<T, U>>>> {
|
||||
pub fn state (&self) -> LockResult<RwLockReadGuard<Box<dyn Device<'a, T, U>>>> {
|
||||
self.state.read()
|
||||
}
|
||||
/// Returns a locked mutex of the state's contents.
|
||||
pub fn state_mut (&self) -> LockResult<RwLockWriteGuard<Box<dyn Device<T, U>>>> {
|
||||
pub fn state_mut (&self) -> LockResult<RwLockWriteGuard<Box<dyn Device<'a, T, U>>>> {
|
||||
self.state.write()
|
||||
}
|
||||
pub fn connect_midi_in (&self, index: usize, port: &Port<Unowned>) -> Usually<()> {
|
||||
|
|
|
|||
|
|
@ -54,14 +54,13 @@ submod! {
|
|||
jack_ports
|
||||
render
|
||||
render_axis
|
||||
render_border
|
||||
render_buffer
|
||||
render_collect
|
||||
render_layered
|
||||
render_split
|
||||
render_tui
|
||||
render_tui_fill
|
||||
render_tui_theme
|
||||
render_tui_border
|
||||
time_base
|
||||
time_note
|
||||
time_tick
|
||||
|
|
@ -86,28 +85,28 @@ pub type Usually<T> = Result<T, Box<dyn Error>>;
|
|||
pub type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
|
||||
|
||||
/// A UI component.
|
||||
pub trait Component<T, U>: Render<T, U> + Handle + Sync {
|
||||
pub trait Component<'a, T, U>: Render<'a, T, U> + Handle + Sync {
|
||||
/// Perform type erasure for collecting heterogeneous components.
|
||||
fn boxed (self) -> Box<dyn Component<T, U>> where Self: Sized + 'static {
|
||||
fn boxed (self) -> Box<dyn Component<'a, T, U>> where Self: Sized + 'static {
|
||||
Box::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, T, U> Component<T, U> for C where C: Render<T, U> + Handle + Sync {}
|
||||
impl<'a, C, T, U> Component<'a, T, U> for C where C: Render<'a, T, U> + Handle + Sync {}
|
||||
|
||||
/// Marker trait for [Component]s that can [Exit]
|
||||
pub trait ExitableComponent<T, U>: Exit + Component<T, U> {
|
||||
pub trait ExitableComponent<'a, T, U>: Exit + Component<'a, T, U> {
|
||||
/// Perform type erasure for collecting heterogeneous components.
|
||||
fn boxed (self) -> Box<dyn ExitableComponent<T, U>> where Self: Sized + 'static {
|
||||
fn boxed (self) -> Box<dyn ExitableComponent<'a, T, U>> where Self: Sized + 'static {
|
||||
Box::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Exit + Component<T, U>, T, U> ExitableComponent<T, U> for E {}
|
||||
impl<'a, E: Exit + Component<'a, T, U>, T, U> ExitableComponent<'a, T, U> for E {}
|
||||
|
||||
/// Run the main loop.
|
||||
pub fn run <R> (state: Arc<RwLock<R>>) -> Usually<Arc<RwLock<R>>>
|
||||
where R: for <'a> Render<TuiOutput<'a>, Rect> + Handle + Sized + 'static
|
||||
where R: for <'a> Render<'a, TuiOutput<'a>, Rect> + Handle + Sized + 'static
|
||||
{
|
||||
let exited = Arc::new(AtomicBool::new(false));
|
||||
let _input_thread = input_thread(&exited, &state);
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ use crate::*;
|
|||
pub(crate) use ratatui::prelude::CrosstermBackend;
|
||||
|
||||
/// Trait for things that are displayed to the user.
|
||||
pub trait Render<T, U>: Send + Sync {
|
||||
fn render (&self, to: &mut T) -> Perhaps<U>;
|
||||
pub trait Render<'a, T, U>: Send + Sync {
|
||||
fn render (&self, to: &'a mut T) -> Perhaps<U>;
|
||||
}
|
||||
|
||||
/// Options can be rendered optionally.
|
||||
impl<R, T, U> Render<T, U> for Option<R> where R: Render<T, U> {
|
||||
fn render (&self, to: &mut T) -> Perhaps<U> {
|
||||
impl<'a, R, T, U> Render<'a, T, U> for Option<R> where R: Render<'a, T, U> {
|
||||
fn render (&self, to: &'a mut T) -> Perhaps<U> {
|
||||
match self {
|
||||
Some(component) => component.render(to),
|
||||
None => Ok(None)
|
||||
|
|
@ -19,43 +19,43 @@ impl<R, T, U> Render<T, U> for Option<R> where R: Render<T, U> {
|
|||
}
|
||||
|
||||
/// Boxed references can be rendered.
|
||||
impl<'a, T, U> Render<T, U> for Box<dyn Render<T, U> + 'a> {
|
||||
fn render (&self, to: &mut T) -> Perhaps<U> {
|
||||
impl<'a, T, U> Render<'a, T, U> for Box<dyn Render<'a, T, U> + 'a> {
|
||||
fn render (&self, to: &'a mut T) -> Perhaps<U> {
|
||||
(**self).render(to)
|
||||
}
|
||||
}
|
||||
|
||||
/// Immutable references can be rendered.
|
||||
impl<R, T, U> Render<T, U> for &R where R: Render<T, U> {
|
||||
fn render (&self, to: &mut T) -> Perhaps<U> {
|
||||
impl<'a, R, T, U> Render<'a, T, U> for &R where R: Render<'a, T, U> {
|
||||
fn render (&self, to: &'a mut T) -> Perhaps<U> {
|
||||
(*self).render(to)
|
||||
}
|
||||
}
|
||||
|
||||
/// Mutable references can be rendered.
|
||||
impl<R, T, U> Render<T, U> for &mut R where R: Render<T, U> {
|
||||
fn render (&self, to: &mut T) -> Perhaps<U> {
|
||||
impl<'a, R, T, U> Render<'a, T, U> for &mut R where R: Render<'a, T, U> {
|
||||
fn render (&self, to: &'a mut T) -> Perhaps<U> {
|
||||
(**self).render(to)
|
||||
}
|
||||
}
|
||||
|
||||
/// Counted references can be rendered.
|
||||
impl<R, T, U> Render<T, U> for Arc<R> where R: Render<T, U> {
|
||||
fn render (&self, to: &mut T) -> Perhaps<U> {
|
||||
impl<'a, R, T, U> Render<'a, T, U> for Arc<R> where R: Render<'a, T, U> {
|
||||
fn render (&self, to: &'a mut T) -> Perhaps<U> {
|
||||
self.as_ref().render(to)
|
||||
}
|
||||
}
|
||||
|
||||
/// References behind a [Mutex] can be rendered.
|
||||
impl<R, T, U> Render<T, U> for Mutex<R> where R: Render<T, U> {
|
||||
fn render (&self, to: &mut T) -> Perhaps<U> {
|
||||
impl<'a, R, T, U> Render<'a, T, U> for Mutex<R> where R: Render<'a, T, U> {
|
||||
fn render (&self, to: &'a mut T) -> Perhaps<U> {
|
||||
self.lock().unwrap().render(to)
|
||||
}
|
||||
}
|
||||
|
||||
/// References behind a [RwLock] can be rendered.
|
||||
impl<R, T, U> Render<T, U> for RwLock<R> where R: Render<T, U> {
|
||||
fn render (&self, to: &mut T) -> Perhaps<U> {
|
||||
impl<'a, R, T, U> Render<'a, T, U> for RwLock<R> where R: Render<'a, T, U> {
|
||||
fn render (&self, to: &'a mut T) -> Perhaps<U> {
|
||||
self.read().unwrap().render(to)
|
||||
}
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ impl<R, T, U> Render<T, U> for RwLock<R> where R: Render<T, U> {
|
|||
/// Rendering unboxed closures should also be possible;
|
||||
/// but in practice implementing the trait for an unboxed
|
||||
/// `Fn` closure causes an impl conflict.
|
||||
impl<'a, T, U> Render<T, U> for Box<dyn Fn(&mut T) -> Perhaps<U> + Send + Sync + 'a> {
|
||||
impl<'a, T, U> Render<'a, T, U> for Box<dyn Fn(&mut T) -> Perhaps<U> + Send + Sync + 'a> {
|
||||
fn render (&self, to: &mut T) -> Perhaps<U> {
|
||||
(*self)(to)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
use crate::*;
|
||||
|
||||
pub enum Collected<'a, T, U> {
|
||||
Box(Box<dyn Render<T, U> + 'a>),
|
||||
Ref(&'a (dyn Render<T, U> + 'a)),
|
||||
Box(Box<dyn Render<'a, T, U> + 'a>),
|
||||
Ref(&'a (dyn Render<'a, T, U> + 'a)),
|
||||
}
|
||||
impl<'a, T, U> Render<T, U> for Collected<'a, T, U> {
|
||||
fn render (&self, to: &mut T) -> Perhaps<U> {
|
||||
impl<'a, T, U> Render<'a, T, U> for Collected<'a, T, U> {
|
||||
fn render (&self, to: &'a mut T) -> Perhaps<U> {
|
||||
match self {
|
||||
Self::Box(item) => (*item).render(to),
|
||||
Self::Ref(item) => (*item).render(to),
|
||||
|
|
@ -21,20 +21,20 @@ impl<'a, T, U> Collection<'a, T, U> {
|
|||
}
|
||||
}
|
||||
pub trait Collect<'a, T, U> {
|
||||
fn add_box (self, item: Box<dyn Render<T, U> + 'a>) -> Self;
|
||||
fn add_ref (self, item: &'a dyn Render<T, U>) -> Self;
|
||||
fn add <R: Render<T, U> + Sized + 'a> (self, item: R) -> Self
|
||||
fn add_box (self, item: Box<dyn Render<'a, T, U> + 'a>) -> Self;
|
||||
fn add_ref (self, item: &'a dyn Render<'a, T, U>) -> Self;
|
||||
fn add <R: Render<'a, T, U> + Sized + 'a> (self, item: R) -> Self
|
||||
where Self: Sized
|
||||
{
|
||||
self.add_box(Box::new(item))
|
||||
}
|
||||
}
|
||||
impl<'a, T, U> Collect<'a, T, U> for Collection<'a, T, U> {
|
||||
fn add_box (mut self, item: Box<dyn Render<T, U> + 'a>) -> Self {
|
||||
fn add_box (mut self, item: Box<dyn Render<'a, T, U> + 'a>) -> Self {
|
||||
self.0.push(Collected::Box(item));
|
||||
self
|
||||
}
|
||||
fn add_ref (mut self, item: &'a dyn Render<T, U>) -> Self {
|
||||
fn add_ref (mut self, item: &'a dyn Render<'a, T, U>) -> Self {
|
||||
self.0.push(Collected::Ref(item));
|
||||
self
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,18 +9,18 @@ impl<'a, T, U> Layered<'a, T, U> {
|
|||
}
|
||||
|
||||
impl<'a, T, U> Collect<'a, T, U> for Layered<'a, T, U> {
|
||||
fn add_box (mut self, item: Box<dyn Render<T, U> + 'a>) -> Self {
|
||||
fn add_box (mut self, item: Box<dyn Render<'a, T, U> + 'a>) -> Self {
|
||||
self.0 = self.0.add_box(item);
|
||||
self
|
||||
}
|
||||
fn add_ref (mut self, item: &'a dyn Render<T, U>) -> Self {
|
||||
fn add_ref (mut self, item: &'a dyn Render<'a, T, U>) -> Self {
|
||||
self.0 = self.0.add_ref(item);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> Render<TuiOutput<'b>, Rect> for Layered<'a, TuiOutput<'b>, Rect> {
|
||||
fn render (&self, to: &mut TuiOutput<'b>) -> Perhaps<Rect> {
|
||||
impl<'a, 'b> Render<'a, TuiOutput<'b>, Rect> for Layered<'a, TuiOutput<'b>, Rect> {
|
||||
fn render (&self, to: &'a mut TuiOutput<'b>) -> Perhaps<Rect> {
|
||||
let area = to.area;
|
||||
for layer in self.0.0.iter() {
|
||||
layer.render(to)?;
|
||||
|
|
|
|||
|
|
@ -44,17 +44,17 @@ impl<'a, T, U> Split<'a, T, U> {
|
|||
}
|
||||
|
||||
impl<'a, T, U> Collect<'a, T, U> for Split<'a, T, U> {
|
||||
fn add_box (mut self, item: Box<dyn Render<T, U> + 'a>) -> Self {
|
||||
fn add_box (mut self, item: Box<dyn Render<'a, T, U> + 'a>) -> Self {
|
||||
self.items = self.items.add_box(item);
|
||||
self
|
||||
}
|
||||
fn add_ref (mut self, item: &'a dyn Render<T, U>) -> Self {
|
||||
fn add_ref (mut self, item: &'a dyn Render<'a, T, U>) -> Self {
|
||||
self.items = self.items.add_ref(item);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Render<TuiOutput<'a>, Rect> for Split<'a, TuiOutput<'a>, Rect> {
|
||||
impl<'a> Render<'a, TuiOutput<'a>, Rect> for Split<'a, TuiOutput<'a>, Rect> {
|
||||
fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
|
||||
Ok(None)//Rect::default())//Some(self.render_areas(to)?.0))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,12 +7,17 @@ pub struct TuiOutput<'a> {
|
|||
pub buffer: &'a mut Buffer,
|
||||
pub area: Rect
|
||||
}
|
||||
impl<'a> TuiOutput<'a> {
|
||||
pub fn area (&'a mut self, area: Rect) -> Self {
|
||||
Self { buffer: self.buffer, area }
|
||||
}
|
||||
}
|
||||
|
||||
/// Main thread render loop
|
||||
pub fn tui_render_thread <T> (exited: &Arc<AtomicBool>, device: &Arc<RwLock<T>>)
|
||||
-> Usually<JoinHandle<()>>
|
||||
where
|
||||
T: for <'a> Render<TuiOutput<'a>, Rect> + 'static
|
||||
T: for <'a> Render<'a, TuiOutput<'a>, Rect> + 'static
|
||||
{
|
||||
let exited = exited.clone();
|
||||
let device = device.clone();
|
||||
|
|
@ -29,7 +34,7 @@ where
|
|||
let previous_buffer = &buffers[1 - index];
|
||||
let current_buffer = &buffers[index];
|
||||
let updates = previous_buffer.diff(current_buffer);
|
||||
backend.draw(updates.into_iter());
|
||||
backend.draw(updates.into_iter()).expect("failed to render");
|
||||
buffers[1 - index].reset();
|
||||
index = 1 - index;
|
||||
}
|
||||
|
|
@ -82,7 +87,7 @@ impl<T: AsRef<str>> Blit for T {
|
|||
}
|
||||
|
||||
/// Rendering unit struct to Ratatui returns zero-sized [Rect] at render coordinates.
|
||||
impl<'a> Render<TuiOutput<'a>, Rect> for () {
|
||||
impl<'a> Render<'a, TuiOutput<'a>, Rect> for () {
|
||||
fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
|
||||
Ok(Some(Rect { x: to.area.x, y: to.area.y, width: 0, height: 0 }))
|
||||
}
|
||||
|
|
@ -104,3 +109,53 @@ pub fn half_block (lower: bool, upper: bool) -> Option<char> {
|
|||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FillBg(pub Color);
|
||||
|
||||
impl<'a> Render<'a, TuiOutput<'a>, Rect> for FillBg {
|
||||
fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
|
||||
fill_bg(to.buffer, to.area, self.0);
|
||||
Ok(Some(to.area))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_dim (buf: &mut Buffer) {
|
||||
for cell in buf.content.iter_mut() {
|
||||
cell.bg = ratatui::style::Color::Rgb(30,30,30);
|
||||
cell.fg = ratatui::style::Color::Rgb(100,100,100);
|
||||
cell.modifier = ratatui::style::Modifier::DIM;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn buffer_update (
|
||||
buf: &mut Buffer, area: Rect, callback: &impl Fn(&mut Cell, u16, u16)
|
||||
) {
|
||||
for row in 0..area.height {
|
||||
let y = area.y + row;
|
||||
for col in 0..area.width {
|
||||
let x = area.x + col;
|
||||
if x < buf.area.width && y < buf.area.height {
|
||||
callback(buf.get_mut(x, y), col, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fill_fg (buf: &mut Buffer, area: Rect, color: Color) {
|
||||
buffer_update(buf, area, &|cell,_,_|{cell.set_fg(color);})
|
||||
}
|
||||
|
||||
pub fn fill_bg (buf: &mut Buffer, area: Rect, color: Color) {
|
||||
buffer_update(buf, area, &|cell,_,_|{cell.set_bg(color);})
|
||||
}
|
||||
|
||||
pub fn fill_ul (buf: &mut Buffer, area: Rect, color: Color) {
|
||||
buffer_update(buf, area, &|cell,_,_|{
|
||||
cell.modifier = ratatui::prelude::Modifier::UNDERLINED;
|
||||
cell.underline_color = color;
|
||||
})
|
||||
}
|
||||
|
||||
pub fn fill_char (buf: &mut Buffer, area: Rect, c: char) {
|
||||
buffer_update(buf, area, &|cell,_,_|{cell.set_char(c);})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ pub trait BorderStyle {
|
|||
const W: &'static str = "";
|
||||
|
||||
#[inline]
|
||||
fn draw (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
self.draw_horizontal(buf, area, None)?;
|
||||
self.draw_vertical(buf, area, None)?;
|
||||
self.draw_corners(buf, area, None)?;
|
||||
Ok(area)
|
||||
fn draw <'a> (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
|
||||
self.draw_horizontal(to.buffer, to.area, None)?;
|
||||
self.draw_vertical(to.buffer, to.area, None)?;
|
||||
self.draw_corners(to.buffer, to.area, None)?;
|
||||
Ok(Some(to.area))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
use crate::*;
|
||||
|
||||
pub struct FillBg(pub Color);
|
||||
|
||||
impl<'a> Render<TuiOutput<'a>, Rect> for FillBg {
|
||||
fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
|
||||
fill_bg(to.buffer, to.area, self.0);
|
||||
Ok(Some(to.area))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_dim (buf: &mut Buffer) {
|
||||
for cell in buf.content.iter_mut() {
|
||||
cell.bg = ratatui::style::Color::Rgb(30,30,30);
|
||||
cell.fg = ratatui::style::Color::Rgb(100,100,100);
|
||||
cell.modifier = ratatui::style::Modifier::DIM;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn buffer_update (
|
||||
buf: &mut Buffer, area: Rect, callback: &impl Fn(&mut Cell, u16, u16)
|
||||
) {
|
||||
for row in 0..area.height {
|
||||
let y = area.y + row;
|
||||
for col in 0..area.width {
|
||||
let x = area.x + col;
|
||||
if x < buf.area.width && y < buf.area.height {
|
||||
callback(buf.get_mut(x, y), col, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fill_fg (buf: &mut Buffer, area: Rect, color: Color) {
|
||||
buffer_update(buf, area, &|cell,_,_|{cell.set_fg(color);})
|
||||
}
|
||||
|
||||
pub fn fill_bg (buf: &mut Buffer, area: Rect, color: Color) {
|
||||
buffer_update(buf, area, &|cell,_,_|{cell.set_bg(color);})
|
||||
}
|
||||
|
||||
pub fn fill_ul (buf: &mut Buffer, area: Rect, color: Color) {
|
||||
buffer_update(buf, area, &|cell,_,_|{
|
||||
cell.modifier = ratatui::prelude::Modifier::UNDERLINED;
|
||||
cell.underline_color = color;
|
||||
})
|
||||
}
|
||||
|
||||
pub fn fill_char (buf: &mut Buffer, area: Rect, c: char) {
|
||||
buffer_update(buf, area, &|cell,_,_|{cell.set_char(c);})
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue