streamdeck_oxide/view/
matrix.rs1use generic_array::{sequence::GenericSequence, ArrayLength, GenericArray};
6use std::marker::PhantomData;
7
8use super::button::Button;
9
10pub struct ButtonMatrix<W, H>
15where
16 W: ArrayLength,
17 H: ArrayLength,
18{
19 pub(crate) buttons: GenericArray<GenericArray<Button, W>, H>,
21 pub(crate) _width: PhantomData<W>,
23 pub(crate) _height: PhantomData<H>,
25}
26
27impl<W, H> Default for ButtonMatrix<W, H>
28where
29 W: ArrayLength,
30 H: ArrayLength,
31{
32 fn default() -> Self {
33 ButtonMatrix {
34 buttons: GenericArray::generate(|_| GenericArray::generate(|_| Button::default())),
35 _width: PhantomData,
36 _height: PhantomData,
37 }
38 }
39}
40
41impl<W, H> ButtonMatrix<W, H>
42where
43 W: ArrayLength,
44 H: ArrayLength,
45{
46 pub fn new() -> Self {
48 ButtonMatrix::default()
49 }
50
51 pub fn get_button_by_index(&self, index: usize) -> Option<&Button> {
56 if index < W::to_usize() * H::to_usize() {
57 let x = index % W::to_usize();
58 let y = index / W::to_usize();
59 Some(&self.buttons[y][x])
60 } else {
61 None
62 }
63 }
64
65 pub fn get_button(&self, x: usize, y: usize) -> Option<&Button> {
69 if x < W::to_usize() && y < H::to_usize() {
70 Some(&self.buttons[y][x])
71 } else {
72 None
73 }
74 }
75
76 pub fn set_button(
80 &mut self,
81 x: usize,
82 y: usize,
83 button: Button,
84 ) -> Result<(), Box<dyn std::error::Error>> {
85 if x < W::to_usize() && y < H::to_usize() {
86 self.buttons[y][x] = button;
87 Ok(())
88 } else {
89 Err(Box::new(std::io::Error::new(
90 std::io::ErrorKind::InvalidInput,
91 "Button index out of bounds",
92 )))
93 }
94 }
95
96 pub fn set_button_by_index(
101 &mut self,
102 index: usize,
103 button: Button,
104 ) -> Result<(), Box<dyn std::error::Error>> {
105 if index < W::to_usize() * H::to_usize() {
106 let x = index % W::to_usize();
107 let y = index / W::to_usize();
108 self.buttons[y][x] = button;
109 Ok(())
110 } else {
111 Err(Box::new(std::io::Error::new(
112 std::io::ErrorKind::InvalidInput,
113 "Button index out of bounds",
114 )))
115 }
116 }
117
118 pub fn width(&self) -> usize {
120 W::to_usize()
121 }
122
123 pub fn height(&self) -> usize {
125 H::to_usize()
126 }
127
128 pub fn size(&self) -> usize {
130 W::to_usize() * H::to_usize()
131 }
132}