journey/widgets/
search_bar.rs1use saudade::{Color, Event, EventCtx, Painter, Rect, TextInput, Theme, Widget};
8
9const LABEL_W: i32 = 44;
10const PAD: i32 = 4;
11
12pub struct SearchBar {
13 bounds: Rect,
14 input: TextInput,
15 label: String,
16}
17
18impl SearchBar {
19 pub fn new(rect: Rect) -> Self {
20 let mut me = Self {
21 bounds: rect,
22 input: TextInput::new(Rect::new(0, 0, 0, 0)),
23 label: "Find:".to_string(),
24 };
25 me.relayout();
26 me
27 }
28
29 pub fn text(&self) -> String {
31 self.input.text()
32 }
33
34 pub fn clear(&mut self) {
36 self.input.set_text("");
37 }
38
39 fn relayout(&mut self) {
40 let x = self.bounds.x + LABEL_W;
41 let input_rect = Rect::new(
42 x,
43 self.bounds.y + PAD,
44 (self.bounds.right() - x - PAD).max(0),
45 (self.bounds.h - PAD * 2).max(0),
46 );
47 self.input.layout(input_rect);
48 }
49}
50
51impl Widget for SearchBar {
52 fn bounds(&self) -> Rect {
53 self.bounds
54 }
55
56 fn paint(&mut self, painter: &mut Painter, theme: &Theme) {
57 painter.fill_rect(self.bounds, theme.face);
58 let label_y = self.bounds.y + (self.bounds.h - theme.font_size as i32) / 2 - 1;
59 painter.text(
60 self.bounds.x + PAD,
61 label_y,
62 &self.label,
63 theme.font_size,
64 theme.text,
65 );
66 painter.h_line(
68 self.bounds.x,
69 self.bounds.bottom() - 1,
70 self.bounds.w,
71 Color::MID_GRAY,
72 );
73 self.input.paint(painter, theme);
74 }
75
76 fn event(&mut self, event: &Event, ctx: &mut EventCtx) {
77 self.input.event(event, ctx);
78 }
79
80 fn captures_pointer(&self) -> bool {
81 self.input.captures_pointer()
82 }
83
84 fn focusable(&self) -> bool {
85 self.input.focusable()
86 }
87
88 fn set_focused(&mut self, focused: bool) {
89 self.input.set_focused(focused);
90 }
91
92 fn focus_first(&mut self) -> bool {
93 self.input.focus_first()
94 }
95
96 fn layout(&mut self, bounds: Rect) {
97 self.bounds = bounds;
98 self.relayout();
99 }
100
101 fn wants_ticks(&self) -> bool {
102 self.input.wants_ticks()
103 }
104}