56 lines
1.5 KiB
Rust
56 lines
1.5 KiB
Rust
use std::{cell::RefCell, rc::Rc};
|
|
|
|
use crate::{
|
|
container::Container,
|
|
prelude::{Callable, Pos, Runes, Size, ViewContext},
|
|
view::View,
|
|
};
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub enum StackDirection {
|
|
Vertical,
|
|
Horizontal,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct Stack {
|
|
pub(crate) direction: StackDirection,
|
|
pub(crate) container: Rc<RefCell<Container>>,
|
|
pub(crate) view: View,
|
|
pub(crate) position: Pos,
|
|
}
|
|
|
|
impl Stack {
|
|
pub fn component<F, Args, S>(&mut self, size: S, f: F)
|
|
where
|
|
F: crate::prelude::Callable<Args>,
|
|
Args: crate::prelude::FromContainer,
|
|
S: Into<Size>,
|
|
{
|
|
let size = size.into();
|
|
let mut context = ViewContext::new(self.container.clone(), size);
|
|
f.call(&mut context, Args::from_container(&self.container.borrow()));
|
|
self.view.apply(self.position, &context.view);
|
|
self.position += match self.direction {
|
|
StackDirection::Vertical => Pos::new(0, size.height),
|
|
StackDirection::Horizontal => Pos::new(size.width, 0),
|
|
};
|
|
}
|
|
|
|
pub fn insert<R: Into<Runes>>(&mut self, value: R) {
|
|
let runes: Runes = value.into();
|
|
let l = runes.len();
|
|
self.view.insert(self.position, runes);
|
|
self.position += match self.direction {
|
|
StackDirection::Vertical => Pos::new(0, 1),
|
|
StackDirection::Horizontal => Pos::new(l, 0),
|
|
};
|
|
}
|
|
}
|
|
|
|
impl Callable<()> for Stack {
|
|
fn call(&self, ctx: &mut ViewContext, _args: ()) {
|
|
ctx.apply((0, 0), &self.view);
|
|
}
|
|
}
|