makepad_render/
cx_desktop.rs

1use crate::cx::*;
2use std::io::prelude::*;
3use std::fs::File;
4use std::io;
5use std::net::TcpStream;
6//use time::precise_time_ns;
7
8#[derive(Clone)]
9pub struct CxDesktop {
10    pub repaint_via_scroll_event: bool,
11    pub file_read_id: u64,
12    pub file_reads: Vec<FileRead>,
13    pub profiler_start: Option<u64>,
14}
15
16impl Default for CxDesktop {
17    fn default() -> CxDesktop {
18        CxDesktop {
19            repaint_via_scroll_event: false,
20            file_read_id: 1,
21            file_reads: Vec::new(),
22            profiler_start: None,
23        }
24    }
25}
26
27impl Cx {
28    
29    pub fn get_default_window_size(&self) -> Vec2 {
30        return Vec2 {x: 800., y: 600.}
31    }
32    
33    pub fn file_read(&mut self, path: &str) -> FileRead {
34        let desktop = &mut self.platform.desktop;
35        desktop.file_read_id += 1;
36        let read_id = desktop.file_read_id;
37        let file_read = FileRead {
38            read_id: read_id,
39            path: path.to_string()
40        };
41        desktop.file_reads.push(file_read.clone());
42        file_read
43    }
44    
45    pub fn file_write(&mut self, path: &str, data: &[u8]) -> u64 {
46        // just write it right now
47        if let Ok(mut file) = File::create(path) {
48            if let Ok(_) = file.write_all(&data) {
49            }
50            else {
51                println!("ERROR WRITING FILE {}", path);
52            }
53        }
54        else {
55            println!("ERROR WRITING FILE {}", path);
56        }
57        0
58    }
59    
60    pub fn process_desktop_pre_event<F>(&mut self, event: &mut Event, mut event_handler: F)
61    where F: FnMut(&mut Cx, &mut Event)
62    {
63        match event {
64            Event::FingerHover(_fe) => {
65                self.finger_over_last_area = Area::Empty;
66                //self.hover_mouse_cursor = None;
67            },
68            Event::FingerUp(_fe) => {
69                self.down_mouse_cursor = None;
70            },
71            Event::WindowCloseRequested(_cr) => {
72            },
73            Event::FingerDown(fe) => {
74                // lets set the finger tap count
75                fe.tap_count = self.process_tap_count(fe.digit, fe.abs, fe.time);
76            },
77            Event::KeyDown(ke) => {
78                self.process_key_down(ke.clone());
79                if ke.key_code == KeyCode::PrintScreen {
80                    if ke.modifiers.control {
81                        self.panic_redraw = true;
82                    }
83                    else {
84                        self.panic_now = true;
85                    }
86                }
87            },
88            Event::KeyUp(ke) => {
89                self.process_key_up(&ke);
90            },
91            Event::AppFocusLost => {
92                self.call_all_keys_up(&mut event_handler);
93            },
94            _ => ()
95        };
96    }
97    
98    pub fn process_desktop_post_event(&mut self, event: &mut Event) -> bool {
99        match event {
100            Event::FingerUp(fe) => { // decapture automatically
101                self.captured_fingers[fe.digit] = Area::Empty;
102            },
103            Event::FingerHover(_fe) => { // new last area finger over
104                self._finger_over_last_area = self.finger_over_last_area;
105                //if fe.hover_state == HoverState::Out{
106                //    self.hover_mouse_cursor = None;
107                //}
108            },
109            Event::FingerScroll(_) => {
110                // check for anything being paint or dra dirty
111                if self.redraw_child_areas.len()>0 || self.redraw_parent_areas.len()>0 {
112                    self.platform.desktop.repaint_via_scroll_event = true;
113                }
114            }
115            _ => {}
116        }
117        false
118    }
119    
120    pub fn process_desktop_paint_callbacks<F>(&mut self, time: f64, mut event_handler: F) -> bool
121    where F: FnMut(&mut Cx, &mut Event)
122    {
123        if self.playing_anim_areas.len() != 0 {
124            self.call_animation_event(&mut event_handler, time);
125        }
126        
127        let mut vsync = false; //self.platform.desktop.repaint_via_scroll_event;
128        self.platform.desktop.repaint_via_scroll_event = false;
129        if self.frame_callbacks.len() != 0 {
130            self.call_frame_event(&mut event_handler, time);
131            if self.frame_callbacks.len() != 0 {
132                vsync = true;
133            }
134        }
135        
136        self.call_signals(&mut event_handler);
137        
138        // call redraw event
139        if self.redraw_child_areas.len()>0 || self.redraw_parent_areas.len()>0 {
140            self.call_draw_event(&mut event_handler);
141        }
142        if self.redraw_child_areas.len()>0 || self.redraw_parent_areas.len()>0 {
143            vsync = true;
144        }
145        
146        self.process_desktop_file_reads(&mut event_handler);
147        
148        self.call_signals(&mut event_handler);
149        
150        vsync
151    }
152    
153    
154    pub fn process_desktop_file_reads<F>(&mut self, mut event_handler: F)
155    where F: FnMut(&mut Cx, &mut Event)
156    {
157        if self.platform.desktop.file_reads.len() == 0 {
158            return
159        }
160        
161        let file_read_requests = self.platform.desktop.file_reads.clone();
162        self.platform.desktop.file_reads.truncate(0);
163        
164        for read_req in file_read_requests {
165            let file_result = File::open(&read_req.path);
166            if let Ok(mut file) = file_result {
167                let mut buffer = Vec::new();
168                // read the whole file
169                if file.read_to_end(&mut buffer).is_ok() {
170                    event_handler(self, &mut Event::FileRead(FileReadEvent {
171                        read_id: read_req.read_id,
172                        data: Ok(buffer)
173                    }))
174                }
175                else {
176                    event_handler(self, &mut Event::FileRead(FileReadEvent {
177                        read_id: read_req.read_id,
178                        data: Err(format!("Failed to read {}", read_req.path))
179                    }))
180                }
181            }
182            else {
183                event_handler(self, &mut Event::FileRead(FileReadEvent {
184                    read_id: read_req.read_id,
185                    data: Err(format!("Failed to open {}", read_req.path))
186                }))
187            }
188        }
189        
190        if self.platform.desktop.file_reads.len() != 0 {
191            self.process_desktop_file_reads(event_handler);
192        }
193    }
194    
195    pub fn process_to_wasm<F>(&mut self, _msg: u32, mut _event_handler: F) -> u32
196    where F: FnMut(&mut Cx, &mut Event)
197    {
198        0
199    }
200    
201    pub fn load_theme_fonts(&mut self) {
202        // lets load all fonts that aren't loaded yet
203        for cxfont in &mut self.fonts {
204            let path = cxfont.path.clone();
205            if cxfont.font_loaded.is_none() {
206                // load it
207                let file_result = File::open(&path);
208                if let Ok(mut file) = file_result {
209                    let mut buffer = Vec::<u8>::new();
210                    // read the whole file
211                    if file.read_to_end(&mut buffer).is_ok() {
212                        let mut font = CxFont::default();
213                        if font.load_from_ttf_bytes(&buffer).is_err() {
214                            println!("Error loading font {} ", path);
215                        }
216                        else {
217                            font.path = path.clone();
218                            *cxfont = font;
219                        }
220                    }
221                }
222                else {
223                    println!("Error loading font {} ", path);
224                }
225                
226            }
227        }
228    }
229    
230    /*pub fn log(&mut self, val:&str){
231        let mut stdout = io::stdout();
232        let _e = stdout.write(val.as_bytes());
233        let _e = stdout.flush();
234    }*/
235    
236    pub fn write_log(data: &str) {
237        let _ = io::stdout().write(data.as_bytes());
238        let _ = io::stdout().flush();
239    }
240    
241    pub fn http_send(&self, verb: &str, path: &str, _proto:&str, domain: &str, port: u16, content_type: &str, body: &[u8], signal: Signal) {
242        
243        fn write_bytes_to_tcp_stream(tcp_stream: &mut TcpStream, bytes: &[u8]) -> bool {
244            let bytes_total = bytes.len();
245            let mut bytes_left = bytes_total;
246            while bytes_left > 0 {
247                let buf = &bytes[(bytes_total - bytes_left)..bytes_total];
248                if let Ok(bytes_written) = tcp_stream.write(buf) {
249                    if bytes_written == 0 {
250                        return false
251                    }
252                    bytes_left -= bytes_written;
253                }
254                else {
255                    return true
256                }
257            }
258            return false
259        }
260        
261        // start a thread, connect, and report back.
262        let data = body.to_vec();
263        let byte_len = data.len();
264        let header = format!(
265            "{} {} HTTP/1.1\r\nHost: {}\r\nConnect: close\r\nContent-Type:{}\r\nContent-Length:{}\r\n\r\n",
266            verb,
267            path,
268            domain,
269            content_type,
270            byte_len
271        );
272        let host = format!("{}:{}", domain, port);
273        let _connect_thread = {
274            std::thread::spawn(move || {
275                let stream = TcpStream::connect(&host);
276                if let Ok(mut stream) = stream {
277                    if !write_bytes_to_tcp_stream(&mut stream, header.as_bytes())
278                        && !write_bytes_to_tcp_stream(&mut stream, &data) {
279                        Cx::post_signal(signal, Cx::status_http_send_ok());
280                        return
281                    }
282                }
283                Cx::post_signal(signal, Cx::status_http_send_fail());
284            })
285        };
286    }
287    /*
288    
289    pub fn profile(&mut self) {
290        if let Some(start) = self.platform.desktop.profiler_start {
291            let delta = mach_absolute_time() - start;
292            println!("Profile time:{} usec", delta / 1_000);
293            self.platform.desktop.profiler_start = None
294        }
295        else {
296            self.platform.desktop.profiler_start = Some(precise_time_ns())
297        }
298    }*/
299}