ming_wm_lib/components/
toggle_button.rs

1use std::vec;
2use std::vec::Vec;
3
4use crate::components::Component;
5use crate::framebuffer_types::{ Dimensions, Point };
6use crate::themes::ThemeInfo;
7use crate::messages::WindowMessage;
8use crate::window_manager_types::DrawInstructions;
9
10pub struct ToggleButton<T> {
11  name_: String,
12  top_left: Point,
13  size: Dimensions,
14  text: String,
15  pub inverted: bool, //whether is it clicked or not
16  click_return: T,
17  unclick_return: T,
18}
19
20impl<T: Clone> Component<T> for ToggleButton<T> {
21  fn handle_message(&mut self, message: WindowMessage) -> Option<T> {
22    match message {
23      WindowMessage::FocusClick => {
24        //we know this click was for this button, otherwise window wouldn't have given us this message
25        self.inverted = !self.inverted;
26        if self.inverted {
27          Some(self.click_return.clone())
28        } else {
29          Some(self.unclick_return.clone())
30        }
31      },
32      _ => None,
33    }
34  }
35
36  fn draw(&self, theme_info: &ThemeInfo) -> Vec<DrawInstructions> {
37    //to make sure the text gets vertically centred
38    let font_height = 15;
39    vec![
40      //top and left border
41      DrawInstructions::Rect(self.top_left, [self.size[0], 2], if self.inverted { theme_info.border_right_bottom } else { theme_info.border_left_top }),
42      DrawInstructions::Rect(self.top_left, [2, self.size[1]], if self.inverted { theme_info.border_right_bottom } else { theme_info.border_left_top }),
43      //right and bottom border
44      DrawInstructions::Rect([self.top_left[0] + self.size[0] - 2, self.top_left[1]], [2, self.size[1]], if self.inverted { theme_info.border_left_top } else { theme_info.border_right_bottom }),
45      DrawInstructions::Rect([self.top_left[0], self.top_left[1] + self.size[1] - 2], [self.size[0], 2], if self.inverted { theme_info.border_left_top } else { theme_info.border_right_bottom }),
46      //the background if self.draw_bg
47      //DrawInstructions::Rect(),
48      //the text (for now, hardcoded top left)
49      DrawInstructions::Text([self.top_left[0] + 4, self.top_left[1] + (self.size[1] - font_height) / 2], vec!["nimbus-roman".to_string()], self.text.to_string(), theme_info.text, theme_info.background, None, None),
50    ]
51  }
52
53  //properties
54  fn focusable(&self) -> bool {
55    true
56  }
57
58  fn clickable(&self) -> bool {
59    true
60  }
61  
62  fn name(&self) -> &String {
63    &self.name_
64  }
65}
66
67impl<T> ToggleButton<T> {
68  pub fn new(name_: String, top_left: Point, size: Dimensions, text: String, click_return: T, unclick_return: T) -> Self {
69    Self {
70      name_,
71      top_left,
72      size,
73      text,
74      click_return,
75      unclick_return,
76      inverted: false,
77    }
78  }
79}
80