Skip to main content

sequoia_elements/
window_controls.rs

1use std::rc::Rc;
2
3use sequoia_core::Color;
4use sequoia_view::{Row, View};
5
6use crate::Button;
7
8const BUTTON_SIZE: f32 = 46.0;
9const ICON_SIZE: f32 = 10.0;
10
11#[derive(Clone)]
12pub struct WindowControls {
13    button_size: f32,
14    icon_size: f32,
15    gap: f32,
16    minimize: bool,
17    maximize: bool,
18    close: bool,
19    close_hover: Option<Color>,
20    on_minimize: Option<Rc<dyn Fn()>>,
21    on_maximize: Option<Rc<dyn Fn()>>,
22    on_close: Option<Rc<dyn Fn()>>,
23}
24
25impl Default for WindowControls {
26    fn default() -> Self {
27        Self::new()
28    }
29}
30
31impl WindowControls {
32    pub fn new() -> Self {
33        Self {
34            button_size: BUTTON_SIZE,
35            icon_size: ICON_SIZE,
36            gap: 0.0,
37            minimize: true,
38            maximize: true,
39            close: true,
40            close_hover: None,
41            on_minimize: None,
42            on_maximize: None,
43            on_close: None,
44        }
45    }
46
47    pub fn button_size(mut self, px: f32) -> Self {
48        self.button_size = px.max(0.0);
49        self
50    }
51
52    pub fn icon_size(mut self, px: f32) -> Self {
53        self.icon_size = px.max(0.0);
54        self
55    }
56
57    pub fn gap(mut self, px: f32) -> Self {
58        self.gap = px.max(0.0);
59        self
60    }
61
62    pub fn minimize(mut self, show: bool) -> Self {
63        self.minimize = show;
64        self
65    }
66
67    pub fn maximize(mut self, show: bool) -> Self {
68        self.maximize = show;
69        self
70    }
71
72    pub fn close(mut self, show: bool) -> Self {
73        self.close = show;
74        self
75    }
76
77    pub fn close_hover(mut self, color: Color) -> Self {
78        self.close_hover = Some(color);
79        self
80    }
81
82    pub fn on_minimize(mut self, action: impl Fn() + 'static) -> Self {
83        self.on_minimize = Some(Rc::new(action));
84        self
85    }
86
87    pub fn on_maximize(mut self, action: impl Fn() + 'static) -> Self {
88        self.on_maximize = Some(Rc::new(action));
89        self
90    }
91
92    pub fn on_close(mut self, action: impl Fn() + 'static) -> Self {
93        self.on_close = Some(Rc::new(action));
94        self
95    }
96
97    fn control(&self, icon: &str, action: Option<Rc<dyn Fn()>>) -> Button {
98        let button = Button::icon(icon)
99            .width(self.button_size)
100            .height(self.button_size)
101            .icon_size(self.icon_size)
102            .padding(0.0, 0.0);
103        match action {
104            Some(action) => button.on_click(move || action()),
105            None => button,
106        }
107    }
108}
109
110impl View for WindowControls {
111    fn body(&self) -> impl View + 'static {
112        let close = self.close_hover.map_or_else(
113            || self.control("close", self.on_close.clone()),
114            |hover| self.control("close", self.on_close.clone()).hover(hover),
115        );
116
117        Row::new()
118            .height(self.button_size)
119            .gap(self.gap)
120            .child_if(self.minimize, || {
121                self.control("minimize", self.on_minimize.clone())
122            })
123            .child_if(self.maximize, || {
124                self.control("maximize", self.on_maximize.clone())
125            })
126            .child_if(self.close, || close)
127    }
128}