#![doc = include_str!("../readme.md")]
mod cellselection;
pub mod edit;
mod noselection;
mod rowselection;
mod rowsetselection;
mod table;
pub mod textdata;
mod util;
use crate::textdata::Row;
use ratatui_core::buffer::Buffer;
use ratatui_core::layout::{Constraint, Rect};
use ratatui_core::style::Style;
#[derive(Debug)]
pub struct TableContext {
pub focus: bool,
pub selected_cell: bool,
pub selected_row: bool,
pub selected_column: bool,
pub style: Style,
pub row_style: Option<Style>,
pub select_style: Option<Style>,
pub space_area: Rect,
pub row_area: Rect,
pub non_exhaustive: NonExhaustive,
}
pub trait TableData<'a> {
fn rows(&self) -> usize;
fn header(&self) -> Option<Row<'a>> {
None
}
fn footer(&self) -> Option<Row<'a>> {
None
}
#[allow(unused_variables)]
fn row_height(&self, row: usize) -> u16 {
1
}
#[allow(unused_variables)]
fn row_style(&self, row: usize) -> Option<Style> {
None
}
fn widths(&self) -> Vec<Constraint> {
Vec::default()
}
fn render_cell(
&self,
ctx: &TableContext,
column: usize,
row: usize,
area: Rect,
buf: &mut Buffer,
);
}
impl<'a> TableData<'a> for Box<dyn TableData<'a> + 'a> {
fn rows(&self) -> usize {
(**self).rows()
}
fn header(&self) -> Option<Row<'a>> {
(**self).header()
}
fn footer(&self) -> Option<Row<'a>> {
(**self).footer()
}
fn row_height(&self, row: usize) -> u16 {
(**self).row_height(row)
}
fn row_style(&self, row: usize) -> Option<Style> {
(**self).row_style(row)
}
fn widths(&self) -> Vec<Constraint> {
(**self).widths()
}
fn render_cell(
&self,
ctx: &TableContext,
column: usize,
row: usize,
area: Rect,
buf: &mut Buffer,
) {
(**self).render_cell(ctx, column, row, area, buf)
}
}
pub trait TableDataIter<'a> {
fn cloned(&self) -> Option<Box<dyn TableDataIter<'a> + 'a>> {
None
}
fn rows(&self) -> Option<usize>;
fn header(&self) -> Option<Row<'a>> {
None
}
fn footer(&self) -> Option<Row<'a>> {
None
}
fn nth(&mut self, n: usize) -> bool;
fn row_height(&self) -> u16 {
1
}
fn row_style(&self) -> Option<Style> {
None
}
fn widths(&self) -> Vec<Constraint> {
Vec::default()
}
fn render_cell(&self, ctx: &TableContext, column: usize, area: Rect, buf: &mut Buffer);
}
pub trait TableSelection {
fn count(&self) -> usize;
fn is_selected_row(&self, row: usize) -> bool;
fn is_selected_column(&self, column: usize) -> bool;
fn is_selected_cell(&self, column: usize, row: usize) -> bool;
fn lead_selection(&self) -> Option<(usize, usize)>;
#[allow(unused_variables)]
fn validate_rows(&mut self, rows: usize) {}
#[allow(unused_variables)]
fn validate_cols(&mut self, cols: usize) {}
#[allow(unused_variables)]
fn items_added(&mut self, pos: usize, n: usize) {}
#[allow(unused_variables)]
fn items_removed(&mut self, pos: usize, n: usize, rows: usize) {}
}
use crate::_private::NonExhaustive;
pub use table::{Table, TableState, TableStyle, handle_doubleclick_events};
pub mod selection {
pub use crate::cellselection::CellSelection;
pub mod cellselection {
pub use crate::cellselection::{handle_events, handle_mouse_events};
}
pub use crate::noselection::NoSelection;
pub mod noselection {
pub use crate::noselection::{handle_events, handle_mouse_events};
}
pub use crate::rowselection::RowSelection;
pub mod rowselection {
pub use crate::rowselection::{handle_events, handle_mouse_events};
}
pub use crate::rowsetselection::RowSetSelection;
pub mod rowsetselection {
pub use crate::rowsetselection::{handle_events, handle_mouse_events};
}
}
pub mod event {
pub use rat_event::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum TableOutcome {
Continue,
Unchanged,
Changed,
Selected,
}
impl ConsumedEvent for TableOutcome {
fn is_consumed(&self) -> bool {
*self != TableOutcome::Continue
}
}
impl From<TableOutcome> for Outcome {
fn from(value: TableOutcome) -> Self {
match value {
TableOutcome::Continue => Outcome::Continue,
TableOutcome::Unchanged => Outcome::Unchanged,
TableOutcome::Changed => Outcome::Changed,
TableOutcome::Selected => Outcome::Changed,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum DoubleClickOutcome {
Continue,
Unchanged,
Changed,
ClickClick(usize, usize),
}
impl From<DoubleClickOutcome> for Outcome {
fn from(value: DoubleClickOutcome) -> Self {
match value {
DoubleClickOutcome::Continue => Outcome::Continue,
DoubleClickOutcome::Unchanged => Outcome::Unchanged,
DoubleClickOutcome::Changed => Outcome::Changed,
DoubleClickOutcome::ClickClick(_, _) => Outcome::Changed,
}
}
}
impl From<Outcome> for DoubleClickOutcome {
fn from(value: Outcome) -> Self {
match value {
Outcome::Continue => DoubleClickOutcome::Continue,
Outcome::Unchanged => DoubleClickOutcome::Unchanged,
Outcome::Changed => DoubleClickOutcome::Changed,
}
}
}
impl ConsumedEvent for DoubleClickOutcome {
fn is_consumed(&self) -> bool {
!matches!(self, DoubleClickOutcome::Continue)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum EditOutcome {
Continue,
Unchanged,
Changed,
Cancel,
Commit,
CommitAndAppend,
CommitAndEdit,
Insert,
Remove,
Edit,
Append,
}
impl From<Outcome> for EditOutcome {
fn from(value: Outcome) -> Self {
match value {
Outcome::Continue => EditOutcome::Continue,
Outcome::Unchanged => EditOutcome::Unchanged,
Outcome::Changed => EditOutcome::Changed,
}
}
}
impl From<EditOutcome> for Outcome {
fn from(value: EditOutcome) -> Self {
match value {
EditOutcome::Continue => Outcome::Continue,
EditOutcome::Unchanged => Outcome::Unchanged,
EditOutcome::Changed => Outcome::Changed,
EditOutcome::Insert => Outcome::Unchanged,
EditOutcome::Remove => Outcome::Unchanged,
EditOutcome::Edit => Outcome::Unchanged,
EditOutcome::Append => Outcome::Unchanged,
EditOutcome::Cancel => Outcome::Unchanged,
EditOutcome::Commit => Outcome::Unchanged,
EditOutcome::CommitAndAppend => Outcome::Unchanged,
EditOutcome::CommitAndEdit => Outcome::Unchanged,
}
}
}
impl ConsumedEvent for EditOutcome {
fn is_consumed(&self) -> bool {
!matches!(self, EditOutcome::Continue)
}
}
}
mod _private {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NonExhaustive;
}