1use std::{self, ffi::CString, sync::Arc};
9
10use crate::{overlay::Overlay, view::Cursor, view::View, Library};
11
12pub struct WindowFlags {
14 pub borderless: bool,
16 pub titled: bool,
18 pub resizable: bool,
20 pub maximizable: bool,
22 pub hidden: bool,
24}
25
26impl WindowFlags {
27 fn to_u32(&self) -> u32 {
29 let mut n = 0;
30
31 if self.borderless {
32 n |= ul_sys::ULWindowFlags_kWindowFlags_Borderless;
33 }
34 if self.titled {
35 n |= ul_sys::ULWindowFlags_kWindowFlags_Titled;
36 }
37 if self.resizable {
38 n |= ul_sys::ULWindowFlags_kWindowFlags_Resizable;
39 }
40 if self.maximizable {
41 n |= ul_sys::ULWindowFlags_kWindowFlags_Maximizable;
42 }
43 if self.hidden {
44 n |= ul_sys::ULWindowFlags_kWindowFlags_Hidden;
45 }
46
47 n
48 }
49}
50
51pub struct Window {
53 lib: Arc<Library>,
54 internal: ul_sys::ULWindow,
55 need_to_destroy: bool,
56}
57
58impl Window {
59 pub(crate) unsafe fn create(
64 lib: Arc<Library>,
65 monitor_raw: ul_sys::ULMonitor,
66 width: u32,
67 height: u32,
68 fullscreen: bool,
69 window_flags: WindowFlags,
70 ) -> Option<Self> {
71 let internal = lib.appcore().ulCreateWindow(
72 monitor_raw,
73 width,
74 height,
75 fullscreen,
76 window_flags.to_u32(),
77 );
78
79 if internal.is_null() {
80 None
81 } else {
82 Some(Self {
83 lib,
84 internal,
85 need_to_destroy: true,
86 })
87 }
88 }
89
90 pub(crate) unsafe fn from_raw(lib: Arc<Library>, raw: ul_sys::ULWindow) -> Option<Self> {
93 if raw.is_null() {
94 None
95 } else {
96 Some(Self {
97 lib,
98 internal: raw,
99 need_to_destroy: false,
100 })
101 }
102 }
103
104 pub fn screen_width(&self) -> u32 {
106 unsafe { self.lib.appcore().ulWindowGetScreenWidth(self.internal) }
107 }
108
109 pub fn width(&self) -> u32 {
111 unsafe { self.lib.appcore().ulWindowGetWidth(self.internal) }
112 }
113
114 pub fn screen_height(&self) -> u32 {
116 unsafe { self.lib.appcore().ulWindowGetScreenHeight(self.internal) }
117 }
118
119 pub fn height(&self) -> u32 {
121 unsafe { self.lib.appcore().ulWindowGetHeight(self.internal) }
122 }
123
124 pub fn move_to(&self, x: i32, y: i32) {
127 unsafe { self.lib.appcore().ulWindowMoveTo(self.internal, x, y) }
128 }
129
130 pub fn move_to_center(&self) {
132 unsafe { self.lib.appcore().ulWindowMoveToCenter(self.internal) }
133 }
134
135 pub fn x(&self) -> i32 {
138 unsafe { self.lib.appcore().ulWindowGetPositionX(self.internal) }
139 }
140
141 pub fn y(&self) -> i32 {
144 unsafe { self.lib.appcore().ulWindowGetPositionY(self.internal) }
145 }
146
147 pub fn is_fullscreen(&self) -> bool {
149 unsafe { self.lib.appcore().ulWindowIsFullscreen(self.internal) }
150 }
151
152 pub fn scale(&self) -> f64 {
154 unsafe { self.lib.appcore().ulWindowGetScale(self.internal) }
155 }
156
157 pub fn set_title(&self, title: &str) {
159 let c_string = CString::new(title).unwrap();
160 unsafe {
161 self.lib
162 .appcore()
163 .ulWindowSetTitle(self.internal, c_string.as_ptr())
164 }
165 }
166
167 pub fn set_cursor(&self, cursor: Cursor) {
169 unsafe {
170 self.lib
171 .appcore()
172 .ulWindowSetCursor(self.internal, cursor as u32)
173 }
174 }
175
176 pub fn show(&self) {
178 unsafe { self.lib.appcore().ulWindowShow(self.internal) }
179 }
180
181 pub fn hide(&self) {
183 unsafe { self.lib.appcore().ulWindowHide(self.internal) }
184 }
185
186 pub fn is_visible(&self) -> bool {
188 unsafe { self.lib.appcore().ulWindowIsVisible(self.internal) }
189 }
190
191 pub fn close(&self) {
193 unsafe { self.lib.appcore().ulWindowClose(self.internal) }
194 }
195
196 pub fn screen_to_pixels(&self, val: i32) -> i32 {
198 unsafe {
199 self.lib
200 .appcore()
201 .ulWindowScreenToPixels(self.internal, val)
202 }
203 }
204
205 pub fn pixels_to_screen(&self, val: i32) -> i32 {
207 unsafe {
208 self.lib
209 .appcore()
210 .ulWindowPixelsToScreen(self.internal, val)
211 }
212 }
213
214 set_callback! {
215 pub fn set_close_callback(&self, callback: FnMut(window: &Window)) :
220 [Window::lib.appcore()][s] ulWindowSetCloseCallback(ul_window: ul_sys::ULWindow) {
221 let window = &Window::from_raw(s.lib.clone(), ul_window).unwrap();
222 }
223 }
224
225 set_callback! {
226 pub fn set_resize_callback(&self, callback: FnMut(window: &Window, width: u32, height: u32)) :
233 [Window::lib.appcore()][s] ulWindowSetResizeCallback(ul_window: ul_sys::ULWindow, width: u32, height: u32) {
234 let window = &Window::from_raw(s.lib.clone(), ul_window).unwrap();
235 }
236 }
237
238 }
247
248impl Window {
249 pub fn create_overlay(&self, width: u32, height: u32, x: i32, y: i32) -> Option<Overlay> {
259 unsafe { Overlay::create(self.lib.clone(), self.internal, width, height, x, y) }
260 }
261
262 pub fn create_overlay_with_view(&self, view: View, x: i32, y: i32) -> Option<Overlay> {
271 unsafe { Overlay::create_with_view(self.lib.clone(), self.internal, view, x, y) }
272 }
273}
274
275impl Drop for Window {
276 fn drop(&mut self) {
277 if self.need_to_destroy {
278 unsafe { self.lib.appcore().ulDestroyWindow(self.internal) }
279 }
280 }
281}