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
116
117
118
119
120
121
use crate::geometry::*;
use crate::graphics::*;
use crate::input::*;
use crate::widget::*;
use std::io;
pub struct ElementaryWidget {
pub layout: Box<Layout>,
pub elements: Vec<Box<LayoutElement>>,
}
impl ElementaryWidget {
pub fn new() -> Self {
ElementaryWidget {
layout: Box::new(FreeLayout),
elements: vec![],
}
}
pub fn set_layout<L: Layout + 'static>(&mut self, layout: L) {
self.layout = Box::new(layout);
}
pub fn add_element<E: LayoutElement + 'static, I: IntoLayoutElement<E>>(
&mut self,
item: I,
) -> &Self {
self.elements.push(Box::new(item.into_layout_element()));
self
}
fn push<F>(&mut self, mut input: Vec<GrinInput>, filter: F, output: &mut Vec<GrinInput>)
where
F: for<'r> FnMut(&'r &mut Box<dyn LayoutElement + 'static>) -> bool,
{
for mut e in self.elements.iter_mut().rev().filter(filter) {
input = e.widget_mut().consume(input);
}
output.extend(input.into_iter());
}
}
impl Widget for ElementaryWidget {
fn arrange(&mut self, window: Window) {
let size = window.size;
let total = self.elements.len();
for (element, i) in self.elements.iter_mut().zip(0..total) {
let layout = self.layout.layout(size, i, total);
let relative = element.placement().place(layout);
trace!("Relative: {:?}", relative);
let absolute = window.crop(&relative);
trace!("Absolute: {:?}", absolute);
element.state_mut().set_area(absolute);
element.widget_mut().arrange(absolute);
}
}
fn render(&self, painter: &mut Painter) -> io::Result<()> {
for element in self.elements.iter() {
let scope = element.state().get_area();
trace!("Render scope: {:?}", scope);
element.widget().render(&mut PainterScope::new(
&mut *painter,
scope,
Style::default(),
))?;
}
Ok(())
}
fn consume(&mut self, input: Vec<GrinInput>) -> Vec<GrinInput> {
let mut output: Vec<GrinInput> = vec![];
let input = input.into_iter();
for inp in input {
match inp {
GrinInput::Mouse(MouseEvent { action, position }) => {
match action {
MouseAction::WheelDown | MouseAction::WheelUp => {
self.push(
vec![GrinInput::Mouse(MouseEvent { action, position })],
|el| el.widget().captures(el.state().get_area(), position),
&mut output,
);
}
MouseAction::Drag | MouseAction::Release => {
self.push(
vec![GrinInput::Mouse(MouseEvent { action, position })],
|el| {
el.widget().captures(el.state().get_area(), position)
|| el.state().is_capturing()
},
&mut output,
);
}
MouseAction::PressLeft
| MouseAction::PressRight
| MouseAction::PressMiddle => {
for mut el in self.elements.iter_mut().rev() {
let state = el.widget().captures(el.state().get_area(), position);
el.state_mut().set_capture(state);
}
self.push(
vec![GrinInput::Mouse(MouseEvent { action, position })],
|el| el.state().is_capturing(),
&mut output,
);
}
};
}
inp => {
self.push(vec![inp], |el| el.state().is_capturing(), &mut output);
}
}
}
output
}
}