old school music tracker
1use winit::keyboard::{Key, NamedKey};
2
3use crate::{
4 EventQueue,
5 coordinates::{CharPosition, CharRect},
6 draw_buffer::DrawBuffer,
7};
8
9use super::{NextWidget, Widget, WidgetResponse};
10
11pub struct Button {
12 text: &'static str,
13 rect: CharRect,
14 pressed: bool,
15 next_widget: NextWidget,
16 #[cfg(feature = "accesskit")]
17 node_id: accesskit::NodeId,
18}
19
20impl Widget for Button {
21 fn draw(&self, buffer: &mut DrawBuffer, selected: bool) {
22 self.draw_overwrite_pressed(buffer, selected, false);
23 }
24
25 fn process_input(
26 &mut self,
27 modifiers: &winit::event::Modifiers,
28 key_event: &winit::event::KeyEvent,
29 _: &mut EventQueue<'_>,
30 ) -> WidgetResponse {
31 if key_event.logical_key == Key::Named(NamedKey::Space)
32 || key_event.logical_key == Key::Named(NamedKey::Enter)
33 {
34 if !key_event.repeat {
35 if key_event.state.is_pressed() {
36 self.pressed = true;
37 return WidgetResponse::None;
38 } else {
39 let pressed = self.pressed;
40 self.pressed = false;
41
42 return WidgetResponse::RequestRedraw(pressed);
43 }
44 }
45 // if focus is changed stop being pressed
46 } else {
47 return self.next_widget.process_key_event(key_event, modifiers);
48 }
49 WidgetResponse::None
50 }
51
52 #[cfg(feature = "accesskit")]
53 fn build_tree(&self, tree: &mut Vec<(accesskit::NodeId, accesskit::Node)>) {
54 use accesskit::{Node, Role};
55
56 let mut node = Node::new(Role::Button);
57 node.set_label(self.text);
58 tree.push((self.node_id, node));
59 }
60}
61
62impl Button {
63 const TOPLEFT_COLOR: u8 = 3;
64 const BOTRIGHT_COLOR: u8 = 1;
65
66 pub fn new(
67 text: &'static str,
68 rect: CharRect,
69 next_widget: NextWidget,
70 #[cfg(feature = "accesskit")] node_id: accesskit::NodeId,
71 ) -> Self {
72 // is 3 rows high, because bot and top are inclusive
73 assert!(
74 rect.bot() - rect.top() >= 2,
75 "buttons needs to be at least 3 rows high"
76 );
77 Button {
78 text,
79 rect,
80 pressed: false,
81 next_widget,
82 #[cfg(feature = "accesskit")]
83 node_id,
84 }
85 }
86
87 /// pressed = argument || self.pressed
88 pub fn draw_overwrite_pressed(&self, buffer: &mut DrawBuffer, selected: bool, pressed: bool) {
89 // let string_offset = {
90 // let half_string = self.text.len() / 2;
91 // if self.text.len() % 2 == 0 {
92 // half_string - 1
93 // } else {
94 // half_string
95 // }
96 // };
97
98 // fill behind the text
99 buffer.draw_rect(
100 DrawBuffer::BACKGROUND_COLOR,
101 CharRect::new(
102 self.rect.top() + 1,
103 self.rect.bot() - 1,
104 self.rect.left() + 1,
105 self.rect.right() - 1,
106 ),
107 );
108
109 let box_colors = match pressed || self.pressed {
110 true => (Self::BOTRIGHT_COLOR, Self::TOPLEFT_COLOR),
111 false => (Self::TOPLEFT_COLOR, Self::BOTRIGHT_COLOR),
112 };
113
114 buffer.draw_in_box(
115 self.rect,
116 DrawBuffer::BACKGROUND_COLOR,
117 box_colors.0,
118 box_colors.1,
119 1,
120 );
121
122 let text_color = match selected {
123 true => 11,
124 false => 0,
125 };
126 buffer.draw_string(
127 self.text,
128 CharPosition::new(
129 // ((self.rect.right() - self.rect.left()) / 2 + self.rect.left()) - string_offset,
130 self.rect.left() + 2,
131 (self.rect.bot() - self.rect.top()) / 2 + self.rect.top(),
132 ),
133 text_color,
134 DrawBuffer::BACKGROUND_COLOR,
135 )
136 }
137}