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,
	stackpanel: Rc<RefCell<Stackpanel>>,
}

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;
			}
		}
	}

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

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

impl Default for Control {
	fn default() -> Self {
		let label = WindowFactory::create::<Label>();
		label
			.borrow_mut()
			.set_text("Please enter a valid number (x ∈ ℕ):");
		let button = WindowFactory::create::<Button>();
		button.borrow_mut().set_text("Press to increment:");
		button.borrow_mut().set_border(BorderKind::Solid.into());
		let mut cb: Combobox<u8> = Combobox::default();
		for v in [1, 2, 4] {
			cb.add_item(DisplayValue::new(v, format!("Increment by {}", v)));
		}
		let cb = Rc::new(RefCell::new(cb));
		let combobox = cb.clone();
		let numeric = WindowFactory::create::<Numeric>();
		numeric.borrow_mut().set_base(Radix::Hexadecimal);
		numeric.borrow_mut().set_min_range(8);
		numeric.borrow_mut().set_max_range(64);
		numeric.borrow_mut().set_focus_color(Some(Color::Cyan));
		let nc = numeric.clone();
		combobox
			.borrow_mut()
			.set_selection_changed_callback(move |cb| {
				let mut brw = nc.borrow_mut();
				brw.set_stepcount(*cb.get_value().unwrap().value())
			});

		let stackpanel = WindowFactory::create::<Stackpanel>();
		stackpanel.borrow_mut().set_border(BorderKind::Solid.into());
		stackpanel.borrow_mut().add_item(label);
		stackpanel.borrow_mut().add_item(numeric);
		stackpanel.borrow_mut().add_item(cb);

		Self {
			uid: WindowUID::new(),
			stackpanel,
			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),
		)
	}
}