flux-tui 0.5.0

Fast and lightweight Terminal UI drawing library
Documentation
use crossterm::event::{Event, KeyCode};
use flux_tui::canvas::Canvas;
use flux_tui::common::*;
use flux_tui::components::*;
use flux_tui::tui::Tui;
use flux_tui::window::*;
use std::cell::RefCell;
use std::rc::Rc;
use vector2d::Vector2D;

fn main() {
	let control = Rc::new(RefCell::new(Control::default()));
	let mut tui = Tui::new(control.clone()).unwrap();
	tui.render().unwrap();
	while let Ok(()) = tui.handle_next_event() {
		if !control.borrow().running {
			return;
		}
		tui.render().unwrap();
	}
}


struct Control {
	running: bool,
	uid: WindowUID,
	scrollviewer: Rc<RefCell<ScrollViewer>>,
}

impl Window for Control {
	fn render(&self, _: &mut Canvas) {}

	fn handle_event(&mut self, event: &mut WindowEvent) {
		if let Event::Key(k) = event.raw() {
			if k.code == KeyCode::Esc {
				self.running = false;
				event.handled = true;
			}
		}
	}

	fn children(&mut self, mut builder: SubWindowBuilder) -> SubWindows {
		builder.add_pair(self.scrollviewer.clone(), None).ok();
		builder.build().unwrap()
	}

	fn focus(&self) -> Option<WindowRef> {
		Some(self.scrollviewer.clone())
	}
}

impl Default for Control {
	fn default() -> Self {
		let values = [
			"Tomatoes",
			"Tofu",
			"Flatbread",
			"Olive oil",
			"Salt",
			"Oregano",
			"Butter",
		];

		let scrollviewer = WindowFactory::create::<ScrollViewer>();
		scrollviewer
			.borrow_mut()
			.set_border(BorderStyle::new(BorderKind::Solid, None, None));
		let stackpanel = WindowFactory::create::<Stackpanel>();
		for v in values {
			let cbx = WindowFactory::create::<TextCheckbox>();
			cbx.borrow_mut().set_text(v);
			stackpanel.borrow_mut().add_item(cbx);
		}
		ScrollViewer::set_content(
			&scrollviewer,
			Some(&(stackpanel as Rc<RefCell<dyn Scrollable>>)),
		);

		Self {
			uid: WindowUID::new(),
			scrollviewer,
			running: true,
		}
	}
}

impl HasWindowUID for Control {
	fn uid(&self) -> WindowUID {
		self.uid
	}
}

impl WindowLayout for Control {
	fn desired_size(&self, available_size: Vector2D<u16>) -> Vector2D<u16> {
		Vector2D::new(
			Percent::from_int(32).multiply(available_size.x),
			Percent::from_int(80).multiply(available_size.y),
		)
	}
}