1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
use std::cmp::max;
use unicode_width::UnicodeWidthStr;
use tui::{
backend::Backend,
layout::{Alignment, Rect},
terminal::Frame,
widgets::{Block, Borders, Paragraph},
};
use crate::{app::App, canvas::Painter, constants};
const HELP_BASE: &str = " Help ── Esc to close ";
pub trait HelpDialog {
fn draw_help_dialog<B: Backend>(
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect,
);
}
impl HelpDialog for Painter {
fn draw_help_dialog<B: Backend>(
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect,
) {
let repeat_num = max(
0,
draw_loc.width as i32 - HELP_BASE.chars().count() as i32 - 2,
);
let help_title = format!(" Help ─{}─ Esc to close ", "─".repeat(repeat_num as usize));
if app_state.is_force_redraw {
// We must also recalculate how many lines are wrapping to properly get scrolling to work on
// small terminal sizes... oh joy.
let mut overflow_buffer = 0;
let paragraph_width = draw_loc.width - 2;
let mut prev_section_len = 0;
constants::HELP_TEXT
.iter()
.enumerate()
.for_each(|(itx, section)| {
let mut buffer = 0;
if itx == 0 {
section.iter().for_each(|text_line| {
buffer += UnicodeWidthStr::width(*text_line).saturating_sub(1) as u16
/ paragraph_width;
});
app_state.help_dialog_state.index_shortcuts[itx] = 0;
prev_section_len = section.len() as u16 + buffer;
overflow_buffer += buffer;
} else {
section.iter().for_each(|text_line| {
buffer += UnicodeWidthStr::width(*text_line).saturating_sub(1) as u16
/ paragraph_width;
});
app_state.help_dialog_state.index_shortcuts[itx] =
app_state.help_dialog_state.index_shortcuts[itx - 1]
+ 1
+ prev_section_len;
prev_section_len = section.len() as u16 + buffer;
overflow_buffer += buffer;
}
});
app_state.help_dialog_state.scroll_state.max_scroll_index =
(self.styled_help_text.len() as u16
+ (constants::HELP_TEXT.len() as u16 - 3)
+ overflow_buffer)
.saturating_sub(draw_loc.height);
// Fix if over-scrolled
if app_state
.help_dialog_state
.scroll_state
.current_scroll_index
>= app_state.help_dialog_state.scroll_state.max_scroll_index
{
app_state
.help_dialog_state
.scroll_state
.current_scroll_index = app_state
.help_dialog_state
.scroll_state
.max_scroll_index
.saturating_sub(1);
}
}
f.render_widget(
Paragraph::new(self.styled_help_text.iter())
.block(
Block::default()
.title(&help_title)
.title_style(self.colours.border_style)
.style(self.colours.border_style)
.borders(Borders::ALL)
.border_style(self.colours.border_style),
)
.style(self.colours.text_style)
.alignment(Alignment::Left)
.wrap(true)
.scroll(
app_state
.help_dialog_state
.scroll_state
.current_scroll_index,
),
draw_loc,
);
}
}
|