1use crate::{
2 grid::config::{ColoredConfig, SpannedConfig},
3 grid::records::{ExactRecords, Records, RecordsMut, Resizable},
4 settings::TableOption,
5};
6
7/// A horizontal/column span from 0 to a count rows.
8#[derive(Debug)]
9pub struct HorizontalPanel<S> {
10 text: S,
11 row: usize,
12}
13
14impl<S> HorizontalPanel<S> {
15 /// Creates a new horizontal panel.
16 pub fn new(row: usize, text: S) -> Self {
17 Self { row, text }
18 }
19}
20
21impl<S, R, D> TableOption<R, D, ColoredConfig> for HorizontalPanel<S>
22where
23 S: AsRef<str>,
24 R: Records + ExactRecords + Resizable + RecordsMut<String>,
25{
26 fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
27 let count_rows: usize = records.count_rows();
28 let count_cols: usize = records.count_columns();
29
30 if self.row > count_rows {
31 return;
32 }
33
34 let is_intersect_vertical_span: bool = (0..records.count_columns())
35 .any(|col: usize| cfg.is_cell_covered_by_row_span((self.row, col)));
36 if is_intersect_vertical_span {
37 return;
38 }
39
40 move_rows_aside(records, self.row);
41 move_row_spans(cfg, self.row);
42
43 let text: String = self.text.as_ref().to_owned();
44 records.set((self.row, 0), text);
45
46 cfg.set_column_span((self.row, 0), span:count_cols);
47 }
48}
49
50fn move_rows_aside<R: ExactRecords + Resizable>(records: &mut R, row: usize) {
51 records.push_row();
52
53 let count_rows: usize = records.count_rows();
54
55 let shift_count: usize = count_rows - row;
56 for i: usize in 1..shift_count {
57 let row: usize = count_rows - i;
58 records.swap_row(lhs:row, rhs:row - 1);
59 }
60}
61
62fn move_row_spans(cfg: &mut SpannedConfig, target_row: usize) {
63 for ((row: usize, col: usize), span: usize) in cfg.get_column_spans() {
64 if row < target_row {
65 continue;
66 }
67
68 cfg.set_column_span((row, col), span:1);
69 cfg.set_column_span((row + 1, col), span);
70 }
71
72 for ((row: usize, col: usize), span: usize) in cfg.get_row_spans() {
73 if row < target_row {
74 continue;
75 }
76
77 cfg.set_row_span((row, col), span:1);
78 cfg.set_row_span((row + 1, col), span);
79 }
80}
81