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