1use densa_data::{LiveTable, RowRef, View, ViewId};
2use densa_grid::{CellStyle, CellText, Color, Column, GridSource, Palette};
3
4use crate::table::{ArrowTable, CellState, TableError};
5
6#[derive(Debug, Clone)]
15pub struct LiveGrid {
16 mirror: ArrowTable,
17 table: (u64, u64),
19}
20
21impl LiveGrid {
22 pub fn new(table: &LiveTable) -> Self {
24 let mut grid = Self {
25 mirror: ArrowTable::new(table.schema().clone()),
26 table: (table.instance(), table.generation()),
27 };
28 grid.sync(table);
29 grid
30 }
31
32 pub fn columns(&self) -> Vec<Column> {
34 self.mirror.columns()
35 }
36
37 pub fn set_decimals(
42 &mut self,
43 column: usize,
44 decimals: Option<usize>,
45 ) -> Result<(), TableError> {
46 self.mirror.set_decimals(column, decimals)
47 }
48
49 pub fn set_column_chars(&mut self, column: usize, chars: usize) -> Result<(), TableError> {
54 self.mirror.set_column_chars(column, chars)
55 }
56
57 pub fn view<'a>(
60 &'a mut self,
61 table: &'a LiveTable,
62 view: ViewId,
63 first_row: usize,
64 palette: &Palette,
65 ) -> Option<LiveGridView<'a>> {
66 self.sync(table);
67 Some(LiveGridView {
68 mirror: &self.mirror,
69 rows: table.view(view)?,
70 first_row,
71 text: palette.text,
72 dim: palette.dim_text,
73 })
74 }
75
76 pub(crate) fn widths(&self) -> u64 {
78 self.mirror.widths()
79 }
80
81 pub(crate) fn is_synced(&self, table: &LiveTable) -> bool {
84 self.table == (table.instance(), table.generation())
85 && self.mirror.stored_batches() == table.batches().len()
86 }
87
88 pub(crate) fn write(&self, at: RowRef, column: usize, text: &mut CellText) -> CellState {
90 self.mirror.write_at(at.batch, at.row, column, text)
91 }
92
93 pub(crate) fn sync(&mut self, table: &LiveTable) {
96 let current = (table.instance(), table.generation());
97 if current != self.table {
98 if self.mirror.schema() != table.schema() {
99 self.mirror = ArrowTable::new(table.schema().clone());
100 }
101 self.mirror.clear_batches();
102 self.table = current;
103 }
104 let new = table
105 .batches()
106 .get(self.mirror.stored_batches()..)
107 .unwrap_or_default();
108 for batch in new {
109 if self.mirror.push(batch.clone()).is_err() {
112 self.mirror.clear_batches();
113 return;
114 }
115 }
116 }
117}
118
119#[derive(Debug, Clone, Copy)]
121pub struct LiveGridView<'a> {
122 mirror: &'a ArrowTable,
123 rows: View<'a>,
124 first_row: usize,
125 text: Color,
126 dim: Color,
127}
128
129impl GridSource for LiveGridView<'_> {
130 fn rows(&self) -> usize {
131 self.rows.len().saturating_sub(self.first_row)
132 }
133
134 fn cell(&self, row: usize, column: usize, text: &mut CellText) -> CellStyle {
135 let state = match self.rows.row(self.first_row.saturating_add(row)) {
136 Some(at) => self.mirror.write_at(at.batch, at.row, column, text),
137 None => CellState::OutOfRange,
138 };
139 let color = if state == CellState::Value {
140 self.text
141 } else {
142 self.dim
143 };
144 CellStyle::new(color)
145 }
146}