1use makepad_render::*;
2use crate::buttonlogic::*;
3use crate::desktopbutton::*;
4use crate::windowmenu::*;
5use crate::widgetstyle::*;
6
7#[derive(Clone)]
8pub struct DesktopWindow {
9 pub window: Window,
10 pub pass: Pass,
11 pub color_texture: Texture,
12 pub depth_texture: Texture,
13 pub caption_view: View, pub main_view: View, pub inner_view: View,
16 pub min_btn: DesktopButton,
18 pub max_btn: DesktopButton,
19 pub close_btn: DesktopButton,
20 pub vr_btn: DesktopButton,
21 pub caption_text: Text,
22 pub caption_bg: Quad,
23 pub caption_size: Vec2,
24 pub caption: String,
25
26 pub window_menu: WindowMenu,
27 pub default_menu: Menu,
28
29 pub _last_menu: Option<Menu>,
30
31 pub inner_over_chrome: bool,
33}
34
35#[derive(Clone, PartialEq)]
36pub enum DesktopWindowEvent {
37 EventForOtherWindow,
38 WindowClosed,
39 WindowGeomChange(WindowGeomChangeEvent),
40 None
41}
42
43impl DesktopWindow {
44 pub fn proto(cx: &mut Cx) -> Self {
45 Self {
46 window: Window::proto(cx),
47 pass: Pass::default(),
48 color_texture: Texture::default(),
49 depth_texture: Texture::default(),
50 main_view: View::proto(cx),
51 caption_view: View::proto(cx),
52 inner_view: View::proto(cx),
53
54 min_btn: DesktopButton::proto(cx),
55 max_btn: DesktopButton::proto(cx),
56 close_btn: DesktopButton::proto(cx),
57 vr_btn: DesktopButton::proto(cx),
58
59 window_menu: WindowMenu::proto(cx),
60 default_menu: Menu::main(vec![
61 Menu::sub("App", vec![
62 Menu::item("Quit App", Cx::command_quit()),
63 ]),
64 ]),
65 caption_text: Text::proto(cx),
66 caption_bg: Quad::proto(cx),
68 caption_size: Vec2::default(),
69 caption: "Makepad".to_string(),
70 inner_over_chrome: false,
71 _last_menu: None
72 }
73 }
74
75 pub fn text_style_window_caption() ->TextStyleId{uid!()}
76
77 pub fn style(cx:&mut Cx, _opt:&StyleOptions){
78 Self::text_style_window_caption().set(cx, Theme::text_style_unscaled().get(cx));
79 }
80
81 pub fn handle_desktop_window(&mut self, cx: &mut Cx, event: &mut Event) -> DesktopWindowEvent {
82 if let ButtonEvent::Clicked = self.vr_btn.handle_button(cx, event) {
85 if self.window.vr_is_presenting(cx) {
86 self.window.vr_stop_presenting(cx);
87 }
88 else {
89 self.window.vr_start_presenting(cx);
90 }
91 }
92 if let ButtonEvent::Clicked = self.min_btn.handle_button(cx, event) {
93 self.window.minimize_window(cx);
94 }
95 if let ButtonEvent::Clicked = self.max_btn.handle_button(cx, event) {
96 if self.window.is_fullscreen(cx) {
97 self.window.restore_window(cx);
98 }
99 else {
100 self.window.maximize_window(cx);
101 }
102 }
103 if let ButtonEvent::Clicked = self.close_btn.handle_button(cx, event) {
104 self.window.close_window(cx);
105 }
106 if let Some(window_id) = self.window.window_id {
107 let is_for_other_window = match event {
108 Event::WindowCloseRequested(ev) => ev.window_id != window_id,
109 Event::WindowClosed(ev) => {
110 if ev.window_id == window_id {
111 return DesktopWindowEvent::WindowClosed
112 }
113 true
114 }
115 Event::WindowGeomChange(ev) => {
116 if ev.window_id == window_id {
117 return DesktopWindowEvent::WindowGeomChange(ev.clone())
118 }
119 true
120 },
121 Event::WindowDragQuery(dq) => {
122 if dq.window_id == window_id {
123 if dq.abs.x < self.caption_size.x && dq.abs.y < self.caption_size.y {
124 if dq.abs.x < 50. {
125 dq.response = WindowDragQueryResponse::SysMenu;
126 }
127 else {
128 dq.response = WindowDragQueryResponse::Caption;
129 }
130 }
131 }
132 true
133 }
134 Event::FingerDown(ev) => ev.window_id != window_id,
135 Event::FingerMove(ev) => ev.window_id != window_id,
136 Event::FingerHover(ev) => ev.window_id != window_id,
137 Event::FingerUp(ev) => ev.window_id != window_id,
138 Event::FingerScroll(ev) => ev.window_id != window_id,
139 _ => false
140 };
141 if is_for_other_window {
142 DesktopWindowEvent::EventForOtherWindow
143 }
144 else {
145 DesktopWindowEvent::None
146 }
147 }
148 else {
149 DesktopWindowEvent::None
150 }
151 }
152
153 pub fn begin_desktop_window(&mut self, cx: &mut Cx, menu: Option<&Menu>) -> ViewRedraw {
154
155 if !self.main_view.view_will_redraw(cx) {
156 return Err(())
157 }
158
159 self.window.begin_window(cx);
160 self.pass.begin_pass(cx);
161 self.pass.add_color_texture(cx, &mut self.color_texture, ClearColor::ClearWith(color256(30, 30, 30)));
162 self.pass.set_depth_texture(cx, &mut self.depth_texture, ClearDepth::ClearWith(1.0));
163
164 let _ = self.main_view.begin_view(cx, Layout::default());
165
166 if self.caption_view.begin_view(cx, Layout {
167 walk:Walk::wh(Width::Fill, Height::Compute),
168 ..Layout::default()
169 }).is_ok() {
170 self.caption_text.text_style = Self::text_style_window_caption().get(cx);
171 self.caption_bg.color = Theme::color_bg_selected_over().get(cx);match cx.platform_type {
174 PlatformType::Linux | PlatformType::Windows => {
175
176 let bg_inst = self.caption_bg.begin_quad(cx, Layout {
177 align: Align::right_top(),
178 walk: Walk::wh(Width::Fill, Height::Compute),
179 ..Default::default()
180 });
181
182 if let Some(_menu) = menu {
184 }
187
188 self.min_btn.draw_desktop_button(cx, DesktopButtonType::WindowsMin);
189 if self.window.is_fullscreen(cx) {
190 self.max_btn.draw_desktop_button(cx, DesktopButtonType::WindowsMaxToggled);
191 }
192 else {
193 self.max_btn.draw_desktop_button(cx, DesktopButtonType::WindowsMax);
194 }
195 self.close_btn.draw_desktop_button(cx, DesktopButtonType::WindowsClose);
196
197 cx.change_turtle_align_x(0.5); cx.compute_turtle_height();
200 cx.change_turtle_align_y(0.5); cx.reset_turtle_pos();
202 cx.move_turtle(50., 0.);
203 self.caption_size = Vec2 {x: cx.get_width_left(), y: cx.get_height_left()};
205 self.caption_text.draw_text(cx, &self.caption);
206 self.caption_bg.end_quad(cx, &bg_inst);
207 cx.turtle_new_line();
208 },
209
210 PlatformType::OSX => { if let Some(menu) = menu {
212 cx.update_menu(menu);
213 }
214 else{
215 cx.update_menu(&self.default_menu);
216 }
217 let bg_inst = self.caption_bg.begin_quad(cx, Layout {
218 align: Align::center(),
219 walk: Walk::wh(Width::Fill, Height::Fix(22.)),
220 ..Default::default()
221 });
222 self.caption_size = Vec2 {x: cx.get_width_left(), y: cx.get_height_left()};
223 self.caption_text.draw_text(cx, &self.caption);
224 self.caption_bg.end_quad(cx, &bg_inst);
225 cx.turtle_new_line();
226 },
227 _ => {
228
229 }
230 }
231 self.caption_view.end_view(cx);
232 }
233 cx.turtle_new_line();
234
235 if self.inner_over_chrome {
236 let _ = self.inner_view.begin_view(cx, Layout {abs_origin: Some(Vec2::default()), ..Layout::default()});
237 }
238 else {
239 let _ = self.inner_view.begin_view(cx, Layout::default());
240 }
241 Ok(())
242 }
243
244 pub fn end_desktop_window(&mut self, cx: &mut Cx) {
245 self.inner_view.end_view(cx);
246 if cx.vr_can_present { cx.reset_turtle_pos();
249 cx.move_turtle(cx.get_width_total() - 50.0, 0.);
250 self.vr_btn.draw_desktop_button(cx, DesktopButtonType::VRMode);
251 }
252 self.main_view.end_view(cx);
253
254 self.pass.end_pass(cx);
255
256 self.window.end_window(cx);
257 }
258}
259