makepad_platform/
window.rs

1use {
2    crate::{
3        makepad_live_compiler::*,
4        makepad_live_id::*,
5        makepad_math::*,
6        makepad_error_log::*,
7        id_pool::*,
8        event::{
9            WindowGeom
10        },
11        pass::{Pass, PassId, CxPassParent},
12        cx::Cx,
13        cx_api::CxOsOp,
14        live_traits::*,
15    }
16};
17
18pub struct WindowHandle(PoolId);
19
20#[derive(Clone, Debug, PartialEq, Copy)]
21pub struct WindowId(usize, u64);
22
23impl WindowHandle {
24    pub fn window_id(&self) -> WindowId {WindowId(self.0.id, self.0.generation)}
25}
26
27#[derive(Default)]
28pub struct CxWindowPool(IdPool<CxWindow>);
29impl CxWindowPool {
30    fn alloc(&mut self) -> WindowHandle {
31        WindowHandle(self.0.alloc())
32    }
33    
34    pub fn id_zero()->WindowId{
35        WindowId(0, 0)
36    }
37}
38
39impl std::ops::Index<WindowId> for CxWindowPool {
40    type Output = CxWindow;
41    fn index(&self, index: WindowId) -> &Self::Output {
42        let d = &self.0.pool[index.0];
43        if d.generation != index.1{
44            error!("Window id generation wrong {} {} {}", index.0, d.generation, index.1)
45        }
46        &d.item
47    }
48}
49
50impl std::ops::IndexMut<WindowId> for CxWindowPool {
51    fn index_mut(&mut self, index: WindowId) -> &mut Self::Output {
52        let d = &mut self.0.pool[index.0];
53        if d.generation != index.1{
54            error!("Window id generation wrong {} {} {}", index.0, d.generation, index.1)
55        }
56        &mut d.item
57    }
58}
59
60impl LiveHook for WindowHandle {}
61impl LiveNew for WindowHandle {
62    fn new(cx: &mut Cx) -> Self {
63        let window = cx.windows.alloc();
64        let cxwindow = &mut cx.windows[window.window_id()];
65        cxwindow.is_created = false;
66        cxwindow.create_title = "Makepad".to_string();
67        cxwindow.create_inner_size = None;
68        cxwindow.create_position = None;
69        cx.platform_ops.push(CxOsOp::CreateWindow(window.window_id()));
70        window
71    }
72    
73    fn live_type_info(_cx: &mut Cx) -> LiveTypeInfo {
74        LiveTypeInfo {
75            module_id: LiveModuleId::from_str(&module_path!()).unwrap(),
76            live_type: LiveType::of::<Self>(),
77            fields: Vec::new(),
78            live_ignore: true,
79            type_name: id_lut!(Window)
80        }
81    }
82}
83impl LiveApply for WindowHandle {
84    //fn type_id(&self)->std::any::TypeId{ std::any::TypeId::of::<Self>()}
85    fn apply(&mut self, cx: &mut Cx, from: ApplyFrom, start_index: usize, nodes: &[LiveNode]) -> usize {
86        
87        if !nodes[start_index].value.is_structy_type() {
88            cx.apply_error_wrong_type_for_struct(live_error_origin!(), start_index, nodes, live_id!(View));
89            return nodes.skip_node(start_index);
90        }
91        
92        let mut index = start_index + 1;
93        loop {
94            if nodes[index].value.is_close() {
95                index += 1;
96                break;
97            }
98            match nodes[index].id {
99                live_id!(inner_size) => {
100                    let v:Vec2 = LiveNew::new_apply_mut_index(cx, from, &mut index, nodes);
101                    cx.windows[self.window_id()].create_inner_size = Some(v.into());
102                },
103                live_id!(title) => {
104                    let v = LiveNew::new_apply_mut_index(cx, from, &mut index, nodes);
105                    cx.windows[self.window_id()].create_title = v;
106                }
107                live_id!(position) => {
108                    let v:Vec2 = LiveNew::new_apply_mut_index(cx, from, &mut index, nodes);
109                    cx.windows[self.window_id()].create_position = Some(v.into());
110                }
111                live_id!(dpi_override) => {
112                    let v:f64 = LiveNew::new_apply_mut_index(cx, from, &mut index, nodes);
113                    //log!("DPI OVERRIDE {}", v);
114                    cx.windows[self.window_id()].dpi_override = Some(v);
115                }
116                _ => {
117                    cx.apply_error_no_matching_field(live_error_origin!(), index, nodes);
118                    index = nodes.skip_node(index);
119                }
120            }
121        }
122        return index;
123    }
124}
125
126
127impl WindowHandle {
128    pub fn set_pass(&self, cx: &mut Cx, pass: &Pass) {
129        cx.windows[self.window_id()].main_pass_id = Some(pass.pass_id());
130        cx.passes[pass.pass_id()].parent = CxPassParent::Window(self.window_id());
131    }
132    
133    pub fn get_inner_size(&mut self, cx: &mut Cx) -> DVec2 {
134        cx.windows[self.window_id()].get_inner_size()
135    }
136    
137    pub fn get_position(&mut self, cx: &mut Cx) -> DVec2 {
138        cx.windows[self.window_id()].get_position()
139    }
140    
141    pub fn minimize(&mut self, cx: &mut Cx) {
142        cx.push_unique_platform_op(CxOsOp::MinimizeWindow(self.window_id()));
143    }
144    
145    pub fn maximize(&mut self, cx: &mut Cx) {
146        cx.push_unique_platform_op(CxOsOp::MaximizeWindow(self.window_id()));
147    }
148    
149    pub fn fullscreen(&mut self, cx: &mut Cx) {
150        cx.push_unique_platform_op(CxOsOp::FullscreenWindow(self.window_id()));
151    }
152    
153    pub fn normal(&mut self, cx: &mut Cx) {
154        cx.push_unique_platform_op(CxOsOp::NormalizeWindow(self.window_id()));
155    }
156    
157    pub fn can_fullscreen(&mut self, cx: &mut Cx) -> bool {
158        cx.windows[self.window_id()].window_geom.can_fullscreen
159    }
160    
161    pub fn is_fullscreen(&mut self, cx: &mut Cx) -> bool {
162        cx.windows[self.window_id()].window_geom.is_fullscreen
163    }
164    
165    pub fn xr_is_presenting(&mut self, cx: &mut Cx) -> bool {
166        cx.windows[self.window_id()].window_geom.xr_is_presenting
167    }
168    
169    pub fn is_topmost(&mut self, cx: &mut Cx) -> bool {
170        cx.windows[self.window_id()].window_geom.is_topmost
171    }
172    
173    pub fn set_topmost(&mut self, cx: &mut Cx, set_topmost: bool) {
174        cx.push_unique_platform_op(CxOsOp::SetTopmost(self.window_id(), set_topmost));
175    }
176    
177    pub fn restore(&mut self, cx: &mut Cx) {
178        cx.push_unique_platform_op(CxOsOp::RestoreWindow(self.window_id()));
179    }
180    
181    pub fn close(&mut self, cx: &mut Cx) {
182        cx.push_unique_platform_op(CxOsOp::CloseWindow(self.window_id()));
183    }
184}
185
186#[derive(Clone, Default)]
187pub struct CxWindow {
188    pub create_title: String,
189    pub create_position: Option<DVec2>,
190    pub create_inner_size: Option<DVec2>,
191    pub dpi_override: Option<f64>,
192    pub is_created: bool,
193    pub window_geom: WindowGeom,
194    pub main_pass_id: Option<PassId>,
195}
196
197impl CxWindow {
198    
199    pub fn get_inner_size(&mut self) -> DVec2 {
200        if !self.is_created {
201            Default::default()
202            //panic!();
203        }
204        else {
205            self.window_geom.inner_size
206        }
207    }
208    
209    pub fn get_position(&mut self) -> DVec2 {
210        if !self.is_created {
211            panic!();
212        }
213        else {
214            self.window_geom.position
215        }
216    }
217    /*
218    pub fn get_dpi_factor(&mut self) -> Option<f32> {
219        if self.is_created {
220            Some(self.window_geom.dpi_factor)
221        }
222        else{
223            None
224        }
225    }*/
226}