sequoia_elements/
window_controls.rs1use 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}