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
|
use crate::interactive::{
widgets::{Entries, Footer, Header, HelpPane, ListState},
AppState, DisplayOptions, FocussedPane,
};
use dua::traverse::Traversal;
use tui::style::{Color, Style};
use tui::{
buffer::Buffer,
layout::{Constraint, Direction, Layout, Rect},
style::Modifier,
widgets::Widget,
};
/// The state that can be mutated while drawing
/// This is easiest compared to alternatives, but at least it's restricted to a subset of the state
#[derive(Default)]
pub struct DrawState {
entries_list: ListState,
pub help_scroll: u16,
}
pub struct MainWindow<'a, 'b, 'c> {
pub traversal: &'a Traversal,
pub display: DisplayOptions,
pub state: &'b AppState,
pub draw_state: &'c mut DrawState,
}
impl<'a, 'b, 'c> Widget for MainWindow<'a, 'b, 'c> {
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
let Self {
traversal:
Traversal {
tree,
entries_traversed,
total_bytes,
..
},
display,
state,
ref mut draw_state,
} = self;
let regions = Layout::default()
.direction(Direction::Vertical)
.constraints(
[
Constraint::Length(1),
Constraint::Max(256),
Constraint::Length(1),
]
.as_ref(),
)
.split(area);
let (header_area, entries_area, footer_area) = (regions[0], regions[1], regions[2]);
let (entries_area, help_area_state) = match state.help_pane {
Some(state) => {
let regions = Layout::default()
.direction(Direction::Horizontal)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
.split(entries_area);
(regions[0], Some((regions[1], state)))
}
None => (entries_area, None),
};
let grey = Style {
fg: Color::DarkGray,
bg: Color::Reset,
modifier: Modifier::empty(),
};
let white = Style {
fg: Color::White,
..grey
};
let (entries_style, help_style) = match state.focussed {
FocussedPane::Main => (white, grey),
FocussedPane::Help => (grey, white),
};
Header.draw(header_area, buf);
Entries {
tree: &tree,
root: state.root,
display: *display,
sorting: state.sorting,
selected: state.selected,
border_style: entries_style,
list: &mut draw_state.entries_list,
is_focussed: if let FocussedPane::Main = state.focussed {
true
} else {
false
},
}
.draw(entries_area, buf);
if let Some((help_area, state)) = help_area_state {
let mut pane = HelpPane {
scroll: draw_state.help_scroll,
state,
border_style: help_style,
};
pane.draw(help_area, buf);
draw_state.help_scroll = pane.scroll;
}
Footer {
total_bytes: *total_bytes,
entries_traversed: *entries_traversed,
format: display.byte_format,
message: state.message.clone(),
}
.draw(footer_area, buf);
}
}
|