flux-tui 0.4.5

Fast and lightweight Terminal UI drawing library
Documentation
use crossterm::event::KeyCode;

use super::*;


pub trait DataRow {
	/// Returns the data of the cell
	/// This will return None when the internal value is not set (NULL) or the column doesn't exist
	fn get(&self, column: usize) -> Option<&str>;
}

pub trait DataSource {
	/// Number of rows
	fn rows(&self) -> usize;

	/// Returns the corresponding row data
	/// This will panic if the row doesn't exist
	fn get(&self, row: usize) -> &dyn DataRow;
}

#[derive(Default)]
#[repr(packed)]
struct EmptyDataSource {}

impl DataSource for EmptyDataSource {
	fn rows(&self) -> usize {
		usize::MIN
	}

	fn get(&self, row: usize) -> &dyn DataRow {
		let _ = row;
		panic!("Data source is empty!");
	}
}


#[derive(Clone, PartialEq)]
pub struct ColumnDefiniton {
	name: String,
	width: Size,
}

/// TODO:
/// Design:
///  Row | Column1 | Column2 | Column3 \
/// ─────┼─────────┼─────────┼─────────\
///   1  |         |         |         \
///   2  |         |         |         \
///   3  |         |         |
pub struct DataGrid {
	base: WidgetBase,
	columns: Vec<ColumnDefiniton>,
	data: Box<dyn DataSource>,
	selection: (usize, usize),
}

impl Default for DataGrid {
	fn default() -> Self {
		Self::new()
	}
}

impl DataGrid {
	pub fn new() -> Self {
		Self {
			base: WidgetBase::default(),
			columns: Vec::new(),
			data: Box::new(EmptyDataSource::default()),
			selection: (usize::MIN, usize::MIN),
		}
	}

	/// Sets the internal data source
	pub fn set_data_source(&mut self, data: Box<dyn DataSource>) {
		self.data = data;
	}

	pub fn get_column_definitions(&mut self) -> &mut Vec<ColumnDefiniton> {
		&mut self.columns
	}
}

impl Window for DataGrid {
	fn render(&self, canvas: &mut crate::canvas::Canvas) {
		for def in self.columns.iter() {
			//TODO
		}

		let max = self.data.rows();
		for idx in 0..max {
			let row = self.data.get(idx);
			//TODO
		}
	}

	fn handle_event(&mut self, event: &mut WindowEvent) {
		match event.raw() {
			Event::Key(k) => match k.code {
				KeyCode::Up => {}
				KeyCode::Down => {}
				KeyCode::Left => {}
				KeyCode::Right => {}
				KeyCode::Enter => {}
				KeyCode::Char(_) => {}
				_ => {}
			},
			_ => {}
		}
	}

	fn is_enabled(&self) -> bool {
		self.base.enabled
	}
}


impl WindowLayout for DataGrid {
	fn alignment(&self) -> (HorizontalAlignment, VerticalAlignment) {
		self.base.alignment
	}

	fn size(&self) -> Vector2D<Size> {
		self.base.size
	}

	fn margin(&self) -> Thickness {
		self.base.margin
	}

	fn border(&self) -> BorderStyle {
		self.base.border
	}

	fn is_visible(&self) -> bool {
		self.base.visibility
	}
}

impl HasWindowUid for DataGrid {
	fn uid(&self) -> WindowUid {
		self.base.uid
	}
}

impl Widget for DataGrid {
	fn set_alignment(
		&mut self,
		horizontal: super::HorizontalAlignment,
		vertical: super::VerticalAlignment,
	) {
		self.base.alignment = (horizontal, vertical);
		self.evoke_changed_property(WindowProperty::Alignment);
	}

	fn set_visibility(&mut self, visibility: bool) {
		self.base.visibility = visibility;
		self.evoke_changed_property(WindowProperty::IsVisible);
	}

	fn set_width(&mut self, width: super::Size) {
		self.base.size.x = width;
		self.evoke_changed_property(WindowProperty::Size);
	}

	fn set_height(&mut self, height: super::Size) {
		self.base.size.y = height;
		self.evoke_changed_property(WindowProperty::Size);
	}

	fn set_margin(&mut self, margin: Thickness) {
		self.base.margin = margin;
		self.evoke_changed_property(WindowProperty::Margin);
	}

	fn set_border(&mut self, border: BorderStyle) {
		self.base.border = border;
		self.evoke_changed_property(WindowProperty::Border);
	}

	fn set_enabled_state(&mut self, is_enabled: bool) {
		self.base.enabled = is_enabled;
	}

	fn set_width_constraint(&mut self, width: SizeConstraint) {
		self.base.constraints.x = width;
		self.evoke_changed_property(WindowProperty::Size);
	}

	fn set_height_constraint(&mut self, height: SizeConstraint) {
		self.base.constraints.y = height;
		self.evoke_changed_property(WindowProperty::Size);
	}
}

impl WidgetColors for DataGrid{
    fn set_enabled_color(&mut self, color: Option<Color>){
        self.base.colors.enabled_color = color;
    }
    
    fn set_disabled_color(&mut self, color: Option<Color>){
        self.base.colors.disabled_color = color;
    }
    
    fn set_base_fg_color(&mut self, color: Option<Color>){
        self.base.colors.base_fg_color = color;
    }
    
    fn set_base_bg_color(&mut self, color: Option<Color>){
        self.base.colors.base_bg_color = color;
    }
}