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
extern crate std;
use std::convert::TryFrom;
extern crate tui;
use tui::buffer::Buffer;
use tui::layout::{Alignment, Rect};
use tui::text::{Spans, Text};
use tui::widgets::{Block, Borders, Paragraph, Widget};
use crate::userinterface::widgets::{BORDERS, EMPTY_SPACES, cursor};
pub struct QuerierPopupWidget<'a> {
keyboard_instructions: Text<'a>,
value: Vec<Spans<'a>>,
cursor: (u16, bool),
}
impl<'a> QuerierPopupWidget<'a> {
pub fn new(keyboard_instructions: Text<'a>, value: Vec<Spans<'a>>,
cursor: (u16, bool)) -> QuerierPopupWidget<'a> {
QuerierPopupWidget {
keyboard_instructions,
value,
cursor,
}
}
}
impl<'a> Widget for QuerierPopupWidget<'a> {
fn render(self, area: Rect, buf: &mut Buffer) {
let (left, top, width, height) = (area.left(), area.top(),
area.right() - area.left(), area.bottom() - area.top());
let kb_height =
u16::try_from(self.keyboard_instructions.height()).unwrap();
let value_width = u16::try_from(
self.value.iter().map(|key| key.width()).max().unwrap()).unwrap();
let value_height = u16::try_from(self.value.len()).unwrap();
let keyboard_instructions_area =
Rect::new(left + 1, top + 2, width - BORDERS, height - BORDERS);
Paragraph::new(self.keyboard_instructions).alignment(Alignment::Center)
.render(keyboard_instructions_area, buf);
for (row, span) in self.value.iter().enumerate() {
let value_area = Rect::new(
left + width/2 - u16::try_from(span.width()).unwrap()/2,
top + 4 + kb_height + u16::try_from(row).unwrap(), width, 1);
Paragraph::new(span.clone()).alignment(Alignment::Left)
.render(value_area, buf);
}
let box_width = value_width + BORDERS + EMPTY_SPACES;
let value_area = Rect::new(left + width/2 - value_width/2 - 2,
top + 4 + kb_height - 1, box_width, BORDERS + value_height);
let value_block = Block::default().borders(Borders::ALL);
value_block.render(value_area, buf);
let left_cursor = left + width/2 -
u16::try_from(self.value[0].width()).unwrap()/2;
let top_cursor = top + 4 + kb_height;
let cursor_area = Rect::new(left_cursor, top_cursor, 1, 1);
cursor::CursorWidget::new(self.cursor).render(cursor_area, buf);
let window_block = Block::default().borders(Borders::ALL);
window_block.render(area, buf);
}
}