From 8ff6236f8db8c40313496cab7e2847a65803a70b Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sun, 25 Jul 2021 22:23:19 +0900 Subject: [PATCH] fix table component field names --- src/app.rs | 2 +- src/components/record_table.rs | 8 +- src/components/table.rs | 235 +++++++++++++-------------------- 3 files changed, 96 insertions(+), 149 deletions(-) diff --git a/src/app.rs b/src/app.rs index 2e38d45..a773fff 100644 --- a/src/app.rs +++ b/src/app.rs @@ -237,7 +237,7 @@ impl App { return Ok(EventState::Consumed); } - if let Some(index) = self.record_table.table.state.selected() { + if let Some(index) = self.record_table.table.selected_row.selected() { if index.saturating_add(1) % crate::utils::RECORDS_LIMIT_PER_PAGE as usize == 0 diff --git a/src/components/record_table.rs b/src/components/record_table.rs index 9ed757b..d4c2121 100644 --- a/src/components/record_table.rs +++ b/src/components/record_table.rs @@ -41,16 +41,16 @@ impl RecordTableComponent { self.table.rows = rows; self.table.headers = headers; if !self.table.rows.is_empty() { - self.table.state.select(None); - self.table.state.select(Some(0)); + self.table.selected_row.select(None); + self.table.selected_row.select(Some(0)); } } pub fn reset(&mut self) { self.table = TableComponent::default(); if !self.table.rows.is_empty() { - self.table.state.select(None); - self.table.state.select(Some(0)) + self.table.selected_row.select(None); + self.table.selected_row.select(Some(0)) } self.filter = TableFilterComponent::default(); } diff --git a/src/components/table.rs b/src/components/table.rs index a4ae13a..e953924 100644 --- a/src/components/table.rs +++ b/src/components/table.rs @@ -15,30 +15,26 @@ use tui::{ use unicode_width::UnicodeWidthStr; pub struct TableComponent { - pub state: TableState, + pub selected_row: TableState, pub headers: Vec, pub rows: Vec>, pub eod: bool, - select_state: TableState, - selected_left_column_index: usize, - selected_right_cell: Option<(usize, usize)>, + selection_area_corner: Option<(usize, usize)>, + selected_column: usize, column_page_start: std::cell::Cell, scroll: VerticalScroll, - select_entire_row: bool, } impl Default for TableComponent { fn default() -> Self { Self { - state: TableState::default(), - select_state: TableState::default(), + selected_row: TableState::default(), headers: vec![], rows: vec![], - selected_left_column_index: 0, - selected_right_cell: None, + selected_column: 0, + selection_area_corner: None, column_page_start: std::cell::Cell::new(0), scroll: VerticalScroll::new(), - select_entire_row: false, eod: false, } } @@ -46,31 +42,29 @@ impl Default for TableComponent { impl TableComponent { pub fn new(rows: Vec>, headers: Vec) -> Self { - let mut state = TableState::default(); + let mut selected_row = TableState::default(); if !rows.is_empty() { - state.select(None); - state.select(Some(0)) + selected_row.select(None); + selected_row.select(Some(0)) } Self { - state, + selected_row, headers, rows, ..Self::default() } } - pub fn reset(&mut self) { - self.select_state.select(None); - self.selected_right_cell = None; - self.select_entire_row = false; + fn reset(&mut self) { + self.selection_area_corner = None; } pub fn end(&mut self) { self.eod = true; } - pub fn next(&mut self, lines: usize) { - let i = match self.state.selected() { + fn next_row(&mut self, lines: usize) { + let i = match self.selected_row.selected() { Some(i) => { if i + lines >= self.rows.len() { Some(self.rows.len() - 1) @@ -81,25 +75,11 @@ impl TableComponent { None => None, }; self.reset(); - self.state.select(i); + self.selected_row.select(i); } - pub fn next_select(&mut self, lines: usize) { - let i = match self.select_state.selected() { - Some(i) => { - if i + lines >= self.rows.len() { - Some(self.rows.len() - 1) - } else { - Some(i + lines) - } - } - None => None, - }; - self.select_state.select(i); - } - - pub fn previous(&mut self, lines: usize) { - let i = match self.state.selected() { + fn previous_row(&mut self, lines: usize) { + let i = match self.selected_row.selected() { Some(i) => { if i <= lines { Some(0) @@ -110,70 +90,56 @@ impl TableComponent { None => None, }; self.reset(); - self.state.select(i); + self.selected_row.select(i); } - pub fn previout_select(&mut self, lines: usize) { - let i = match self.select_state.selected() { - Some(i) => { - if i <= lines { - Some(0) - } else { - Some(i - lines) - } - } - None => None, - }; - self.select_state.select(i); - } - - pub fn scroll_top(&mut self) { + fn scroll_top(&mut self) { if self.rows.is_empty() { return; } self.reset(); - self.state.select(Some(0)); + self.selected_row.select(Some(0)); } - pub fn scroll_bottom(&mut self) { + fn scroll_bottom(&mut self) { if self.rows.is_empty() { return; } self.reset(); - self.state.select(Some(self.rows.len() - 1)); + self.selected_row.select(Some(self.rows.len() - 1)); } - pub fn next_column(&mut self) { + fn next_column(&mut self) { if self.rows.is_empty() { return; } - if self.selected_left_column_index >= self.headers.len().saturating_sub(1) { + if self.selected_column >= self.headers.len().saturating_sub(1) { return; } self.reset(); - self.selected_left_column_index += 1; + self.selected_column += 1; } - pub fn previous_column(&mut self) { + fn previous_column(&mut self) { if self.rows.is_empty() { return; } - if self.selected_left_column_index == 0 { + if self.selected_column == 0 { return; } self.reset(); - self.selected_left_column_index -= 1; + self.selected_column -= 1; } - pub fn expand_selected_area_x(&mut self, positive: bool) { - if self.selected_right_cell.is_none() { - self.selected_right_cell = Some(( - self.selected_left_column_index, - self.state.selected().unwrap_or(0), + fn expand_selected_area_x(&mut self, positive: bool) { + if self.selection_area_corner.is_none() { + self.selection_area_corner = Some(( + self.selected_column, + self.selected_row.selected().unwrap_or(0), )); } - if let Some((x, y)) = self.selected_right_cell { - self.selected_right_cell = Some(( + if let Some((x, y)) = self.selection_area_corner { + self.selection_area_corner = Some(( if positive { (x + 1).min(self.headers.len().saturating_sub(1)) } else { @@ -184,25 +150,15 @@ impl TableComponent { } } - pub fn expand_selected_area_y(&mut self, positive: bool) { - if self.select_state.selected().is_none() { - self.select_state = self.state.clone(); - } - - if positive { - self.next_select(1); - } else { - self.previout_select(1); - } - - if self.selected_right_cell.is_none() { - self.selected_right_cell = Some(( - self.selected_left_column_index, - self.state.selected().unwrap_or(0), + fn expand_selected_area_y(&mut self, positive: bool) { + if self.selection_area_corner.is_none() { + self.selection_area_corner = Some(( + self.selected_column, + self.selected_row.selected().unwrap_or(0), )); } - if let Some((x, y)) = self.selected_right_cell { - self.selected_right_cell = Some(( + if let Some((x, y)) = self.selection_area_corner { + self.selection_area_corner = Some(( x, if positive { (y + 1).min(self.rows.len().saturating_sub(1)) @@ -213,50 +169,48 @@ impl TableComponent { } } - pub fn is_row_number_clumn(&self, row_index: usize, column_index: usize) -> bool { - matches!(self.state.selected(), Some(selected_row_index) if row_index == selected_row_index && 0 == column_index) + fn is_row_number_clumn(&self, row_index: usize, column_index: usize) -> bool { + matches!(self.selected_row.selected(), Some(selected_row_index) if row_index == selected_row_index && 0 == column_index) } pub fn selected_cells(&self) -> Option { - if let Some((x, y)) = self.selected_right_cell { - let selected_row_index = self.state.selected()?; + if let Some((x, y)) = self.selection_area_corner { + let selected_row_index = self.selected_row.selected()?; return Some( self.rows[y.min(selected_row_index)..y.max(selected_row_index) + 1] .iter() .map(|row| { - row[x.min(self.selected_left_column_index) - ..x.max(self.selected_left_column_index) + 1] - .join(",") + row[x.min(self.selected_column)..x.max(self.selected_column) + 1].join(",") }) .collect::>() .join("\n"), ); } self.rows - .get(self.state.selected()?)? - .get(self.selected_left_column_index) + .get(self.selected_row.selected()?)? + .get(self.selected_column) .map(|cell| cell.to_string()) } - pub fn selected_column_index(&self) -> usize { - if let Some((x, _)) = self.selected_right_cell { + fn selected_column_index(&self) -> usize { + if let Some((x, _)) = self.selection_area_corner { return x; } - self.selected_left_column_index + self.selected_column } - pub fn is_selected_cell( + fn is_selected_cell( &self, row_index: usize, column_index: usize, selected_column_index: usize, ) -> bool { - if let Some((x, y)) = self.selected_right_cell { + if let Some((x, y)) = self.selection_area_corner { let x_in_page = x .saturating_add(1) .saturating_sub(self.column_page_start.get()); return matches!( - self.state.selected(), + self.selected_row.selected(), Some(selected_row_index) if (x_in_page.min(selected_column_index).max(1)..x_in_page.max(selected_column_index) + 1) .contains(&column_index) @@ -264,16 +218,16 @@ impl TableComponent { .contains(&row_index) ); } - matches!(self.state.selected(), Some(selected_row_index) if row_index == selected_row_index && column_index == selected_column_index) + matches!(self.selected_row.selected(), Some(selected_row_index) if row_index == selected_row_index && column_index == selected_column_index) } - pub fn headers_with_number(&self, left: usize, right: usize) -> Vec { + fn headers_with_number(&self, left: usize, right: usize) -> Vec { let mut headers = self.headers.clone()[left..right].to_vec(); headers.insert(0, "".to_string()); headers } - pub fn rows_with_number(&self, left: usize, right: usize) -> Vec> { + fn rows_with_number(&self, left: usize, right: usize) -> Vec> { let rows = self .rows .iter() @@ -287,7 +241,7 @@ impl TableComponent { new_rows } - pub fn calculate_widths( + fn calculate_widths( &self, area_width: u16, ) -> (usize, Vec, Vec>, Vec) { @@ -386,14 +340,14 @@ impl TableComponent { constraints.insert(0, Constraint::Length(number_clomn_width)); self.column_page_start.set(left_column_index); ( - self.selected_right_cell + self.selection_area_corner .map_or(selected_column_index + 1, |(x, _)| { - if x > self.selected_left_column_index { + if x > self.selected_column { (selected_column_index + 1) - .saturating_sub(x.saturating_sub(self.selected_left_column_index)) + .saturating_sub(x.saturating_sub(self.selected_column)) } else { (selected_column_index + 1) - .saturating_add(self.selected_left_column_index.saturating_sub(x)) + .saturating_add(self.selected_column.saturating_sub(x)) } }), self.headers_with_number(left_column_index, right_column_index), @@ -410,7 +364,7 @@ impl DrawableComponent for TableComponent { .constraints(vec![Constraint::Length(3), Constraint::Length(5)]) .split(area); - self.state.selected().map_or_else( + self.selected_row.selected().map_or_else( || { self.scroll.reset(); }, @@ -461,24 +415,21 @@ impl DrawableComponent for TableComponent { let table = Table::new(rows) .header(header) .block(block) - .highlight_style(if self.select_entire_row { - Style::default().bg(Color::Blue) - } else { - Style::default() - }) .style(if focused { Style::default() } else { Style::default().fg(Color::DarkGray) }) .widths(&constraints); + let mut state = self.selected_row.clone(); f.render_stateful_widget( table, layout[1], - if self.select_state.selected().is_some() { - &mut self.select_state + if let Some((_, y)) = self.selection_area_corner { + state.select(Some(y)); + &mut state } else { - &mut self.state + &mut self.selected_row }, ); @@ -495,29 +446,25 @@ impl Component for TableComponent { return Ok(EventState::Consumed); } Key::Char('j') => { - self.next(1); + self.next_row(1); return Ok(EventState::NotConsumed); } Key::Ctrl('d') => { - self.next(10); + self.next_row(10); return Ok(EventState::NotConsumed); } Key::Char('k') => { - self.previous(1); + self.previous_row(1); return Ok(EventState::Consumed); } Key::Ctrl('u') => { - self.previous(10); + self.previous_row(10); return Ok(EventState::Consumed); } Key::Char('g') => { self.scroll_top(); return Ok(EventState::Consumed); } - Key::Char('r') => { - self.select_entire_row = true; - return Ok(EventState::Consumed); - } Key::Char('G') => { self.scroll_bottom(); return Ok(EventState::Consumed); @@ -591,10 +538,10 @@ mod test { vec!["a", "b", "c"].iter().map(|h| h.to_string()).collect(), vec!["d", "e", "f"].iter().map(|h| h.to_string()).collect(), ]; - component.state.select(Some(1)); - component.selected_left_column_index = 1; + component.selected_row.select(Some(1)); + component.selected_column = 1; component.expand_selected_area_x(false); - assert_eq!(component.selected_right_cell, Some((0, 1))); + assert_eq!(component.selection_area_corner, Some((0, 1))); assert_eq!(component.selected_cells(), Some("d,e".to_string())); } @@ -616,10 +563,10 @@ mod test { vec!["a", "b", "c"].iter().map(|h| h.to_string()).collect(), vec!["d", "e", "f"].iter().map(|h| h.to_string()).collect(), ]; - component.state.select(Some(1)); - component.selected_left_column_index = 1; + component.selected_row.select(Some(1)); + component.selected_column = 1; component.expand_selected_area_x(true); - assert_eq!(component.selected_right_cell, Some((2, 1))); + assert_eq!(component.selection_area_corner, Some((2, 1))); assert_eq!(component.selected_cells(), Some("e,f".to_string())); } @@ -640,10 +587,10 @@ mod test { vec!["a", "b", "c"].iter().map(|h| h.to_string()).collect(), vec!["d", "e", "f"].iter().map(|h| h.to_string()).collect(), ]; - component.state.select(Some(1)); - component.selected_left_column_index = 1; + component.selected_row.select(Some(1)); + component.selected_column = 1; component.expand_selected_area_y(false); - assert_eq!(component.selected_right_cell, Some((1, 0))); + assert_eq!(component.selection_area_corner, Some((1, 0))); assert_eq!(component.selected_cells(), Some("b\ne".to_string())); } @@ -664,10 +611,10 @@ mod test { vec!["a", "b", "c"].iter().map(|h| h.to_string()).collect(), vec!["d", "e", "f"].iter().map(|h| h.to_string()).collect(), ]; - component.state.select(Some(0)); - component.selected_left_column_index = 1; + component.selected_row.select(Some(0)); + component.selected_column = 1; component.expand_selected_area_y(true); - assert_eq!(component.selected_right_cell, Some((1, 1))); + assert_eq!(component.selection_area_corner, Some((1, 1))); assert_eq!(component.selected_cells(), Some("b\ne".to_string())); } @@ -683,7 +630,7 @@ mod test { vec!["a", "b", "c"].iter().map(|h| h.to_string()).collect(), vec!["d", "e", "f"].iter().map(|h| h.to_string()).collect(), ]; - component.state.select(Some(0)); + component.selected_row.select(Some(0)); assert_eq!(component.selected_cells(), Some("a".to_string())); } @@ -699,8 +646,8 @@ mod test { vec!["a", "b", "c"].iter().map(|h| h.to_string()).collect(), vec!["d", "e", "f"].iter().map(|h| h.to_string()).collect(), ]; - component.state.select(Some(0)); - component.selected_right_cell = Some((1, 1)); + component.selected_row.select(Some(0)); + component.selection_area_corner = Some((1, 1)); assert_eq!(component.selected_cells(), Some("a,b\nd,e".to_string())); } @@ -716,7 +663,7 @@ mod test { vec!["a", "b", "c"].iter().map(|h| h.to_string()).collect(), vec!["d", "e", "f"].iter().map(|h| h.to_string()).collect(), ]; - component.state.select(Some(0)); + component.selected_row.select(Some(0)); // a assert!(component.is_selected_cell(0, 1, 1)); // d @@ -737,8 +684,8 @@ mod test { vec!["a", "b", "c"].iter().map(|h| h.to_string()).collect(), vec!["d", "e", "f"].iter().map(|h| h.to_string()).collect(), ]; - component.state.select(Some(0)); - component.selected_right_cell = Some((1, 1)); + component.selected_row.select(Some(0)); + component.selection_area_corner = Some((1, 1)); // a assert!(component.is_selected_cell(0, 1, 1)); // b