1use fltk_sys::fl;
4
5use crate::{
6 draw::{Coordinates, Rect},
7 prelude::{FltkError, FltkErrorKind},
8};
9type Coord = Coordinates<i32>; #[derive(Debug, Copy, Clone)]
16pub struct Screen {
17 pub n: i32,
19}
20
21impl Screen {
22 pub fn all_screens() -> Vec<Screen> {
26 let mut screens: Vec<Self> = vec![];
27 for n in 0..Self::count() {
28 screens.push(Self::new(n).unwrap());
29 }
30 screens
31 }
32
33 pub fn new(number: i32) -> Result<Screen, FltkError> {
37 let s = Screen { n: number };
38 if s.is_valid() {
39 Ok(s)
40 } else {
41 Err(FltkError::Internal(FltkErrorKind::ResourceNotFound))
42 }
43 }
44
45 pub fn new_at<C: Into<Coord> + Copy>(pos: C) -> Result<Screen, FltkError> {
49 let pos: Coord = pos.into();
50
51 let s = Screen {
52 n: unsafe { fl::Fl_screen_num(pos.x, pos.y) },
53 };
54
55 if Self::is_coord_inside_any_work_area(pos) {
56 Ok(s)
57 } else {
58 Err(FltkError::Internal(FltkErrorKind::ResourceNotFound))
59 }
60 }
61
62 pub fn new_inside<R: Into<Rect> + Copy>(rect: R) -> Result<Screen, FltkError> {
66 let r: Rect = rect.into();
67 let s = Screen {
68 n: unsafe { fl::Fl_screen_num_inside(r.x, r.y, r.w, r.h) },
69 };
70
71 if Self::is_rect_inside_any_work_area(r) {
72 Ok(s)
73 } else {
74 Err(FltkError::Internal(FltkErrorKind::ResourceNotFound))
75 }
76 }
77
78 pub fn scaling_supported() -> bool {
83 unsafe { fl::Fl_screen_scaling_supported() != 0 }
84 }
85
86 pub fn scaling_supported_separately() -> bool {
88 unsafe { fl::Fl_screen_scaling_supported() == 2 }
89 }
90
91 pub fn count() -> i32 {
93 unsafe { fl::Fl_screen_count() }
94 }
95
96 pub fn num_at<C: Into<Coord> + Copy>(pos: C) -> Result<i32, FltkError> {
101 let pos: Coord = pos.into();
102 if Self::is_coord_inside_any_work_area(pos) {
103 Ok(unsafe { fl::Fl_screen_num(pos.x, pos.y) })
104 } else {
105 Err(FltkError::Internal(FltkErrorKind::ResourceNotFound))
106 }
107 }
108
109 pub fn work_area_at<C: Into<Coord> + Copy>(pos: C) -> Result<Rect, FltkError> {
114 let pos: Coord = pos.into();
115 if Self::is_coord_inside_any_work_area(pos) {
116 let (mut x, mut y, mut w, mut h) = (0, 0, 0, 0);
117 unsafe { fl::Fl_screen_work_area_at(&mut x, &mut y, &mut w, &mut h, pos.x, pos.y) }
118 Ok(Rect { x, y, w, h })
119 } else {
120 Err(FltkError::Internal(FltkErrorKind::ResourceNotFound))
121 }
122 }
123
124 pub fn work_area_mouse() -> Rect {
127 let (mut x, mut y, mut w, mut h) = (0, 0, 0, 0);
128 unsafe { fl::Fl_screen_work_area_mouse(&mut x, &mut y, &mut w, &mut h) }
129 Rect { x, y, w, h }
130 }
131
132 pub fn work_area_num(number: i32) -> Result<Rect, FltkError> {
137 let s = Screen { n: number };
138 if s.is_valid() {
139 let (mut x, mut y, mut w, mut h) = (0, 0, 0, 0);
140 unsafe { fl::Fl_screen_work_area(&mut x, &mut y, &mut w, &mut h, number) }
141 Ok(Rect { x, y, w, h })
142 } else {
143 Err(FltkError::Internal(FltkErrorKind::ResourceNotFound))
144 }
145 }
146
147 pub fn xywh_at<C: Into<Coord> + Copy>(pos: C) -> Result<Rect, FltkError> {
152 let pos: Coord = pos.into();
153 if Self::is_coord_inside_any_xywh(pos) {
154 let (mut x, mut y, mut w, mut h) = (0, 0, 0, 0);
155 unsafe { fl::Fl_screen_xywh_at(&mut x, &mut y, &mut w, &mut h, pos.x, pos.y) }
156 Ok(Rect { x, y, w, h })
157 } else {
158 Err(FltkError::Internal(FltkErrorKind::ResourceNotFound))
159 }
160 }
161
162 pub fn xywh_inside<R: Into<Rect> + Copy>(rect: R) -> Result<Rect, FltkError> {
167 let r: Rect = rect.into();
168 if Self::is_rect_inside_any_xywh(r) {
169 let (mut x, mut y, mut w, mut h) = (0, 0, 0, 0);
170 unsafe { fl::Fl_screen_xywh_inside(&mut x, &mut y, &mut w, &mut h, r.x, r.y, r.w, r.h) }
171 Ok(Rect { x, y, w, h })
172 } else {
173 Err(FltkError::Internal(FltkErrorKind::ResourceNotFound))
174 }
175 }
176
177 pub fn xywh_mouse() -> Rect {
180 let (mut x, mut y, mut w, mut h) = (0, 0, 0, 0);
181 unsafe { fl::Fl_screen_xywh_mouse(&mut x, &mut y, &mut w, &mut h) }
182 Rect { x, y, w, h }
183 }
184
185 pub fn xywh_num(number: i32) -> Result<Rect, FltkError> {
190 let s = Screen { n: number };
191 if s.is_valid() {
192 let (mut x, mut y, mut w, mut h) = (0, 0, 0, 0);
193 unsafe {
194 fl::Fl_screen_xywh(&mut x, &mut y, &mut w, &mut h, number);
195 }
196 Ok(Rect { x, y, w, h })
197 } else {
198 Err(FltkError::Internal(FltkErrorKind::ResourceNotFound))
199 }
200 }
201
202 pub fn keyboard_scaling(value: bool) {
210 unsafe { fl::Fl_keyboard_screen_scaling(value.into()) }
211 }
212
213 pub fn is_valid(&self) -> bool {
218 self.n >= 0 && self.n < Self::count()
219 }
220
221 pub fn dpi(&self) -> (f32, f32) {
223 let mut h: f32 = 0.;
224 let mut v: f32 = 0.;
225 unsafe {
226 fl::Fl_screen_dpi(&mut h, &mut v, self.n);
227 }
228 (h, v)
229 }
230
231 pub fn set_scale(&self, factor: f32) {
233 unsafe { fl::Fl_set_screen_scale(self.n, factor) }
234 }
235
236 pub fn scale(&self) -> f32 {
238 unsafe { fl::Fl_screen_scale(self.n) }
239 }
240
241 pub fn work_area(&self) -> Rect {
243 let (mut x, mut y, mut w, mut h) = (0, 0, 0, 0);
244 unsafe { fl::Fl_screen_work_area(&mut x, &mut y, &mut w, &mut h, self.n) }
245 Rect { x, y, w, h }
246 }
247
248 pub fn y(&self) -> i32 {
250 self.work_area().y
251 }
252
253 pub fn x(&self) -> i32 {
255 self.work_area().x
256 }
257
258 pub fn w(&self) -> i32 {
260 self.work_area().w
261 }
262
263 pub fn h(&self) -> i32 {
265 self.work_area().h
266 }
267
268 pub fn top_left(&self) -> Coord {
270 self.work_area().top_left()
271 }
272
273 pub fn bottom_right(&self) -> Coord {
275 self.work_area().bottom_right()
276 }
277
278 fn is_coord_inside_any_work_area<C: Into<Coord> + Copy>(c: C) -> bool {
283 let c: Coord = c.into();
284 let main_wa: Rect = screen_work_area(0).into();
285 !(screen_num(c.x, c.y) == 0
287 && (c.x < main_wa.x
288 || c.y < main_wa.y
289 || c.x >= main_wa.bottom_right().x
290 || c.y >= main_wa.bottom_right().y))
291 }
292 fn is_rect_inside_any_work_area<R: Into<Rect> + Copy>(r: R) -> bool {
295 let r: Rect = r.into();
296 Self::is_coord_inside_any_work_area(r.top_left())
297 && Self::is_coord_inside_any_work_area(r.bottom_right())
298 }
299
300 fn is_coord_inside_any_xywh<C: Into<Coord> + Copy>(c: C) -> bool {
303 let c: Coord = c.into();
304 let main_xywh: Rect = screen_xywh(0).into();
305 !(screen_num(c.x, c.y) == 0
307 && (c.x < main_xywh.x
308 || c.y < main_xywh.y
309 || c.x >= main_xywh.bottom_right().x
310 || c.y >= main_xywh.bottom_right().y))
311 }
312 fn is_rect_inside_any_xywh<R: Into<Rect> + Copy>(r: R) -> bool {
315 let r: Rect = r.into();
316 Self::is_coord_inside_any_xywh(r.top_left())
317 && Self::is_coord_inside_any_xywh(r.bottom_right())
318 }
319}
320
321pub fn screen_size() -> (i32, i32) {
325 unsafe { (fl::Fl_screen_w(), fl::Fl_screen_h()) }
326}
327
328pub fn screen_coords() -> (i32, i32) {
330 unsafe { (fl::Fl_screen_x(), fl::Fl_screen_y()) }
331}
332
333pub fn set_screen_scale(n: i32, factor: f32) {
335 unsafe { fl::Fl_set_screen_scale(n, factor) }
336}
337
338pub fn screen_scale(screen_num: i32) -> f32 {
343 unsafe { fl::Fl_screen_scale(screen_num) }
344}
345
346pub fn screen_scaling_supported() -> bool {
348 unsafe { fl::Fl_screen_scaling_supported() != 0 }
349}
350
351pub fn screen_count() -> i32 {
353 unsafe { fl::Fl_screen_count() }
354}
355
356pub fn screen_num(x: i32, y: i32) -> i32 {
361 unsafe { fl::Fl_screen_num(x, y) }
362}
363
364pub fn screen_num_inside<R: Into<Rect> + Copy>(rect: R) -> i32 {
367 let r: Rect = rect.into();
368 unsafe { fl::Fl_screen_num_inside(r.x, r.y, r.w, r.h) }
369}
370
371pub fn screen_dpi(screen_num: i32) -> (f32, f32) {
376 let (mut h, mut v) = (0_f32, 0_f32);
377 unsafe {
378 fl::Fl_screen_dpi(&mut h, &mut v, screen_num);
379 }
380 (h, v)
381}
382
383pub fn screen_xywh(screen_num: i32) -> (i32, i32, i32, i32) {
388 let (mut x, mut y, mut w, mut h) = (0, 0, 0, 0);
389 unsafe {
390 fl::Fl_screen_xywh(&mut x, &mut y, &mut w, &mut h, screen_num);
391 }
392 (x, y, w, h)
393}
394
395pub fn screen_work_area(screen_num: i32) -> (i32, i32, i32, i32) {
400 let (mut x, mut y, mut w, mut h) = (0, 0, 0, 0);
401 unsafe {
402 fl::Fl_screen_work_area(&mut x, &mut y, &mut w, &mut h, screen_num);
403 }
404 (x, y, w, h)
405}
406
407pub fn keyboard_screen_scaling(value: bool) {
415 unsafe { fl::Fl_keyboard_screen_scaling(value.into()) }
416}