1#![allow(unused)]
2
3pub use crate::camera::camera2d::Camera2D;
6pub use crate::camera::render_target::RenderTarget;
7use crate::draw_state::shapes::Shape;
8pub use crate::draw_state::shapes::color::*;
9pub use crate::end_frame;
10use crate::global::{PENDING_CONFIG, STATE, ctx};
11pub use crate::misc::flake_image::Image;
12use crate::misc::font::Font;
13pub use crate::misc::math::*;
14pub use crate::misc::rect::Rect;
15use crate::misc::span::RichtextSection;
16pub use crate::misc::span::Span;
17pub use crate::misc::timer::Timer;
18pub use crate::misc::*;
19use crate::model::instance::Instance;
20pub use crate::model::texture::DrawTextureParams;
21pub use crate::model::texture::FilterType;
22use crate::model::texture::{GpuTexture, Texture};
23pub use crate::runtime::next_frame::next_frame;
24pub use crate::{FlakeResult, flake};
25use arrayvec::ArrayVec;
26use image::{DynamicImage, GenericImageView, ImageBuffer, Rgb, Rgba};
27use std::borrow::Borrow;
28use std::sync::{Arc, Mutex};
29use wgpu::{CommandEncoder, Device, Queue, SurfaceConfiguration, TextureView};
30pub use winit::event::MouseButton;
31pub use winit::event::WindowEvent;
32pub use winit::keyboard::KeyCode;
33#[cfg(target_os = "windows")]
34use winit::platform::windows::WindowExtWindows;
35use winit::window::Window;
36pub use winit::window::{CursorIcon, WindowButtons, WindowLevel};
37pub fn flake_quit() {
47 ctx(|s| s.exit())
48}
49
50pub fn flake_sleep(seconds: f32) {
61 std::thread::sleep(std::time::Duration::from_secs_f32(seconds));
62}
63
64pub fn add_timer(timer: Timer) -> Timer {
76 if STATE.get().is_some() {
77 return ctx(|s| {
78 if !s.timers.contains(&timer) {
79 s.add_timer(timer.clone());
80 }
81 timer
82 });
83 }
84
85 PENDING_CONFIG.with_borrow_mut(|s| {
86 if !s.timers.contains(&timer) {
87 s.timers.push(timer.clone())
88 }
89 });
90
91 timer
92}
93
94pub fn get_window() -> Arc<Window> {
103 ctx(|s| s.get_window())
104}
105
106pub fn get_device() -> Arc<Device> {
114 ctx(|s| s.device.clone())
115}
116
117pub fn get_queue() -> Queue {
125 ctx(|s| s.queue.clone())
126}
127
128pub fn add_post_render_hook(
137 hook: impl FnMut(&Device, &Queue, &mut CommandEncoder, &TextureView, (u32, u32)) + 'static,
138) {
139 ctx(|s| s.post_render_hooks.push(Box::new(hook)));
140}
141
142pub fn get_surface_config() -> Arc<Mutex<SurfaceConfiguration>> {
150 ctx(|s| s.config.clone())
151}
152
153pub fn get_window_events() -> Vec<WindowEvent> {
161 ctx(|s| s.event_list.clone())
162}
163
164pub fn set_window_passthrough(passthrough: bool) {
166 if STATE.get().is_some() {
167 return ctx(|s| s.set_window_passthrough(passthrough));
168 }
169
170 PENDING_CONFIG.with_borrow_mut(|s| s.window_passthrough = Some(passthrough));
171}
172
173pub fn set_window_level(level: WindowLevel) {
175 if STATE.get().is_some() {
176 return ctx(|s| s.set_window_level(level));
177 }
178
179 PENDING_CONFIG.with_borrow_mut(|s| s.window_level = Some(level));
180}
181
182pub fn set_window_enabled_buttons(window_buttons: WindowButtons) {
185 ctx(|s| s.get_window().set_enabled_buttons(window_buttons));
186}
187
188pub fn set_skip_taskbar(skip: bool) {
190 if STATE.get().is_some() {
191 #[cfg(target_os = "windows")]
192 return ctx(|s| s.window.set_skip_taskbar(skip));
193 }
194
195 PENDING_CONFIG.with_borrow_mut(|s| s.skip_taskbar = Some(skip));
196}
197
198pub fn set_window_transparent(transparent: bool) {
201 if STATE.get().is_some() {
202 return get_window().set_transparent(transparent);
203 }
204
205 PENDING_CONFIG.with_borrow_mut(|s| s.window_transparent = Some(transparent));
206}
207
208pub fn set_window_decorations(enabled: bool) {
210 if STATE.get().is_some() {
211 return get_window().set_decorations(enabled);
212 }
213
214 PENDING_CONFIG.with_borrow_mut(|s| s.window_decorations = Some(enabled));
215}
216
217pub fn set_window_title(title: &str) {
227 if STATE.get().is_some() {
228 return ctx(|s| s.set_window_title(title));
229 }
230
231 PENDING_CONFIG.with_borrow_mut(|s| s.window_title = Some(title.into()));
232}
233
234pub fn set_window_visible(visible: bool) {
243 if STATE.get().is_some() {
244 return ctx(|s| s.set_window_visible(visible));
245 }
246
247 PENDING_CONFIG.with_borrow_mut(|s| s.window_visible = Some(visible));
248}
249
250pub fn set_window_icon(path: &str) {
258 let img = image::open(path)
259 .expect("image icon does not exist at path")
260 .into_rgba8();
261 let (width, height) = img.dimensions();
262 let rgba = img.into_raw();
263
264 if STATE.get().is_some() {
265 return ctx(|s| s.set_window_icon(rgba, width, height));
266 }
267
268 PENDING_CONFIG.with_borrow_mut(|s| s.window_icon = Some((rgba, width, height)));
269}
270
271pub fn set_window_icon_bytes(bytes: &[u8]) {
273 let img = image::load_from_memory(bytes)
274 .expect("image icon does not exist at path")
275 .into_rgba8();
276 let (width, height) = img.dimensions();
277 let rgba = img.into_raw();
278
279 if STATE.get().is_some() {
280 return ctx(|s| s.set_window_icon(rgba, width, height));
281 }
282
283 PENDING_CONFIG.with_borrow_mut(|s| s.window_icon = Some((rgba, width, height)));
284}
285
286pub fn set_window_x(x: i32) {
294 if STATE.get().is_some() {
295 return ctx(|s| s.set_window_x(x));
296 }
297
298 PENDING_CONFIG.with_borrow_mut(|s| s.window_x = Some(x));
299}
300
301pub fn set_window_y(y: i32) {
309 if STATE.get().is_some() {
310 return ctx(|s| s.set_window_y(y));
311 }
312
313 PENDING_CONFIG.with_borrow_mut(|s| s.window_y = Some(y));
314}
315
316pub fn set_window_position(x: i32, y: i32) {
324 set_window_x(x);
325 set_window_y(y);
326}
327
328pub fn window_width() -> f32 {
330 ctx(|s| s.window_width())
331}
332
333pub fn window_height() -> f32 {
335 ctx(|s| s.window_height())
336}
337
338pub fn window_size() -> Vector2 {
340 ctx(|s| Vector2::new(s.window_width(), s.window_height()))
341}
342
343pub fn window_position() -> (f32, f32) {
345 ctx(|s| s.window_position())
346}
347
348pub fn window_position_vec2() -> Vector2 {
350 ctx(|s| s.window_position().into())
351}
352
353pub fn window_x() -> f32 {
355 ctx(|s| s.window_x())
356}
357
358pub fn window_y() -> f32 {
360 ctx(|s| s.window_y())
361}
362
363pub fn set_window_width(w: u32) {
371 if STATE.get().is_some() {
372 return ctx(|s| s.set_window_w(w));
373 }
374
375 PENDING_CONFIG.with_borrow_mut(|s| s.window_width = Some(w));
376}
377
378pub fn set_window_height(h: u32) {
386 if STATE.get().is_some() {
387 return ctx(|s| s.set_window_h(h));
388 }
389
390 PENDING_CONFIG.with_borrow_mut(|s| s.window_height = Some(h));
391}
392
393pub fn set_window_size(w: u32, h: u32) {
401 if STATE.get().is_some() {
402 return ctx(|s| s.set_window_size(w, h));
403 }
404
405 PENDING_CONFIG.with_borrow_mut(|s| {
406 s.window_width = Some(w);
407 s.window_height = Some(h);
408 });
409}
410
411pub fn set_window_resizable(resizeable: bool) {
413 ctx(|s| s.window.set_resizable(resizeable));
414}
415
416pub fn get_fps() -> f32 {
427 ctx(|s| s.get_fps())
428}
429
430pub fn set_target_fps(fps: usize) {
438 if STATE.get().is_some() {
439 return ctx(|s| s.set_target_fps(fps));
440 }
441
442 PENDING_CONFIG.with_borrow_mut(|s| s.target_fps = Some(fps));
443}
444
445pub fn set_fps_capped(capped: bool) {
454 if STATE.get().is_some() {
455 return ctx(|s| s.set_fps_capped(capped));
456 }
457
458 PENDING_CONFIG.with_borrow_mut(|s| s.fps_capped = Some(capped));
459}
460
461pub fn get_frame_time() -> f32 {
470 ctx(|s| s.get_frame_time())
471}
472
473pub fn get_frames() -> usize {
482 ctx(|s| s.get_frames())
483}
484
485pub fn mouse_position() -> (f32, f32) {
495 ctx(|s| s.mouse_state.get_position().into())
496}
497
498pub fn mouse_position_vec2() -> Vector2 {
507 ctx(|s| s.mouse_state.get_position())
508}
509
510pub fn mouse_screen_position_vec2() -> Vector2 {
512 ctx(|s| s.mouse_state.get_screen_position())
513}
514
515pub fn mouse_screen_position() -> (f32, f32) {
517 ctx(|s| s.mouse_state.get_screen_position().into())
518}
519
520pub fn mouse_wheel() -> Vector2 {
529 ctx(|s| s.mouse_state.get_mouse_wheel())
530}
531
532pub fn set_mouse_icon(cursor_icon: CursorIcon) {
540 ctx(|s| s.window.set_cursor(cursor_icon))
541}
542pub fn focus_window() {
544 get_window().focus_window();
545}
546
547pub fn is_mouse_button_down(btn: MouseButton) -> bool {
558 ctx(|s| s.mouse_state.is_button_down(btn))
559}
560
561pub fn is_mouse_button_pressed(btn: MouseButton) -> bool {
571 ctx(|s| s.mouse_state.is_button_pressed(btn))
572}
573
574pub fn is_mouse_button_released(btn: MouseButton) -> bool {
585 ctx(|s| s.mouse_state.is_button_released(btn))
586}
587
588pub fn is_key_down(key: KeyCode) -> bool {
597 ctx(|s| s.keyboard_state.is_key_down(key))
598}
599
600pub fn is_key_pressed(key: KeyCode) -> bool {
610 ctx(|s| s.keyboard_state.is_key_pressed(key))
611}
612
613pub fn is_key_released(key: KeyCode) -> bool {
623 ctx(|s| s.keyboard_state.is_key_released(key))
624}
625
626pub fn get_axis(left: KeyCode, right: KeyCode) -> f32 {
628 ctx(|s| match (is_key_down(left), is_key_down(right)) {
629 (true, false) => -1.0,
630 (false, true) => 1.0,
631 _ => 0.0,
632 })
633}
634
635pub fn get_vector(left: KeyCode, right: KeyCode, up: KeyCode, down: KeyCode) -> Vector2 {
638 ctx(|s| {
639 Vector2::new(
640 match (is_key_down(left), is_key_down(right)) {
641 (true, false) => -1.0,
642 (false, true) => 1.0,
643 _ => 0.0,
644 },
645 match (is_key_down(up), is_key_down(down)) {
646 (true, false) => -1.0,
647 (false, true) => 1.0,
648 _ => 0.0,
649 },
650 )
651 })
652}
653
654pub fn mouse_position_global() -> (f32, f32) {
658 ctx(|s| s.mouse_state.get_position_global().into())
659}
660
661pub fn mouse_position_vec2_global() -> Vector2 {
662 ctx(|s| s.mouse_state.get_position_global())
663}
664
665pub fn mouse_screen_position_global() -> (f32, f32) {
667 ctx(|s| s.mouse_state.get_screen_position_global().into())
668}
669
670pub fn mouse_screen_position_vec2_global() -> Vector2 {
671 ctx(|s| s.mouse_state.get_screen_position_global())
672}
673
674pub fn mouse_wheel_global() -> Vector2 {
676 ctx(|s| s.mouse_state.get_mouse_wheel_global())
677}
678
679pub fn is_mouse_button_down_global(btn: MouseButton) -> bool {
680 ctx(|s| s.mouse_state.is_button_down_global(btn))
681}
682
683pub fn is_mouse_button_pressed_global(btn: MouseButton) -> bool {
684 ctx(|s| s.mouse_state.is_button_pressed_global(btn))
685}
686
687pub fn is_mouse_button_released_global(btn: MouseButton) -> bool {
688 ctx(|s| s.mouse_state.is_button_released_global(btn))
689}
690
691pub fn is_key_down_global(key: KeyCode) -> bool {
692 ctx(|s| s.keyboard_state.is_key_down_global(key))
693}
694
695pub fn is_key_pressed_global(key: KeyCode) -> bool {
696 ctx(|s| s.keyboard_state.is_key_pressed_global(key))
697}
698
699pub fn is_key_released_global(key: KeyCode) -> bool {
700 ctx(|s| s.keyboard_state.is_key_released_global(key))
701}
702
703pub fn get_axis_global(left: KeyCode, right: KeyCode) -> f32 {
705 ctx(|s| {
706 match (
707 s.keyboard_state.is_key_down_global(left),
708 s.keyboard_state.is_key_down_global(right),
709 ) {
710 (true, false) => -1.0,
711 (false, true) => 1.0,
712 _ => 0.0,
713 }
714 })
715}
716
717pub fn get_vector_global(left: KeyCode, right: KeyCode, up: KeyCode, down: KeyCode) -> Vector2 {
719 Vector2::new(get_axis_global(left, right), get_axis_global(up, down))
720}
721
722pub fn block_key(key: KeyCode) {
725 ctx(|s| s.block_key(key))
726}
727
728pub fn unblock_key(key: KeyCode) {
730 ctx(|s| s.unblock_key(key))
731}
732
733pub fn get_pressed_keys() -> impl Iterator<Item = KeyCode> {
735 ctx(|s| {
736 s.get_pressed_keys()
737 .collect::<ArrayVec<KeyCode, 32>>()
738 .into_iter()
739 })
740}
741
742pub fn get_pressed_keys_global() -> impl Iterator<Item = KeyCode> {
744 ctx(|s| {
745 s.get_pressed_keys_global()
746 .collect::<ArrayVec<KeyCode, 32>>()
747 .into_iter()
748 })
749}
750
751pub fn last_key_name() -> Option<String> {
754 ctx(|s| s.last_key_name())
755}
756
757pub fn typed_string() -> String {
760 ctx(|s| s.typed_string())
761}
762
763pub fn clear_background(color: Color) {
774 if STATE.get().is_some() {
775 return ctx(|s| {
776 s.clear_color = Some(color);
777 s.draw_state.clear();
778 });
779 }
780
781 PENDING_CONFIG.with_borrow_mut(|c| c.window_clear_color = Some(color));
782}
783
784pub fn draw_rectangle(x: f32, y: f32, w: f32, h: f32, color: Color) {
793 draw_rectangle_rounded(x, y, w, h, 0.0, color);
794}
795
796pub fn draw_rectangle_rounded(x: f32, y: f32, w: f32, h: f32, radius: f32, color: Color) {
805 draw_rectangle_rounded_ex(x, y, w, h, radius, radius, radius, radius, color)
806}
807
808pub fn draw_rectangle_rounded_ex(
823 x: f32,
824 y: f32,
825 w: f32,
826 h: f32,
827 top_left: f32,
828 top_right: f32,
829 bottom_left: f32,
830 bottom_right: f32,
831 color: Color,
832) {
833 ctx(|s| {
834 s.draw_state.draw_rectangle(
835 x,
836 y,
837 w,
838 h,
839 top_left,
840 top_right,
841 bottom_left,
842 bottom_right,
843 color,
844 )
845 });
846}
847
848pub fn draw_rectangle_from_rect(rect: Rect, color: Color) {
856 draw_rectangle(rect.x, rect.y, rect.w, rect.h, color);
857}
858
859pub fn draw_rectangle_rounded_from_rect(rect: Rect, radius: f32, color: Color) {
868 draw_rectangle_rounded(rect.x, rect.y, rect.w, rect.h, radius, color);
869}
870
871pub fn draw_rectangle_lines_rounded_from_rect(
880 rect: Rect,
881 radius: f32,
882 thickness: f32,
883 color: Color,
884) {
885 draw_rectangle_lines_rounded(rect.x, rect.y, rect.w, rect.h, radius, thickness, color);
886}
887
888pub fn draw_rectangle_lines_rounded_from_rect_ex(
897 rect: Rect,
898 top_left: f32,
899 top_right: f32,
900 bottom_left: f32,
901 bottom_right: f32,
902 thickness: f32,
903 color: Color,
904) {
905 draw_rectangle_lines_rounded_ex(
906 rect.x,
907 rect.y,
908 rect.w,
909 rect.h,
910 top_left,
911 top_right,
912 bottom_left,
913 bottom_right,
914 thickness,
915 color,
916 );
917}
918
919pub fn draw_rectangle_rounded_from_rect_ex(
933 rect: Rect,
934 top_left: f32,
935 top_right: f32,
936 bottom_left: f32,
937 bottom_right: f32,
938 color: Color,
939) {
940 draw_rectangle_rounded_ex(
941 rect.x,
942 rect.y,
943 rect.w,
944 rect.h,
945 top_left,
946 top_right,
947 bottom_left,
948 bottom_right,
949 color,
950 );
951}
952
953pub fn draw_rectangle_lines(x: f32, y: f32, w: f32, h: f32, thickness: f32, color: Color) {
961 draw_rectangle_lines_rounded(x, y, w, h, 0.0, thickness, color)
962}
963
964pub fn draw_rectangle_lines_from_rect(rect: Rect, thickness: f32, color: Color) {
972 draw_rectangle_lines(rect.x, rect.y, rect.w, rect.h, thickness, color);
973}
974
975pub fn draw_rectangle_lines_rounded(
986 x: f32,
987 y: f32,
988 w: f32,
989 h: f32,
990 radius: f32,
991 thickness: f32,
992 color: Color,
993) {
994 draw_rectangle_lines_rounded_ex(x, y, w, h, radius, radius, radius, radius, thickness, color);
995}
996
997pub fn draw_rectangle_lines_rounded_ex(
1012 x: f32,
1013 y: f32,
1014 w: f32,
1015 h: f32,
1016 top_left: f32,
1017 top_right: f32,
1018 bottom_left: f32,
1019 bottom_right: f32,
1020 thickness: f32,
1021 color: Color,
1022) {
1023 ctx(|s| {
1024 s.draw_state.draw_rectangle_lines(
1025 x,
1026 y,
1027 w,
1028 h,
1029 top_left,
1030 top_right,
1031 bottom_left,
1032 bottom_right,
1033 thickness,
1034 color,
1035 )
1036 });
1037}
1038
1039pub fn draw_rectangle_rotated(x: f32, y: f32, w: f32, h: f32, rotation: f32, color: Color) {
1048 ctx(|s| {
1049 s.draw_state
1050 .draw_rectangle_rotated(x, y, w, h, rotation, 0.0, 0.0, 0.0, 0.0, color)
1051 });
1052}
1053
1054pub fn draw_rectangle_lines_rotated(
1057 x: f32,
1058 y: f32,
1059 w: f32,
1060 h: f32,
1061 rotation: f32,
1062 thickness: f32,
1063 color: Color,
1064) {
1065 ctx(|s| {
1066 s.draw_state.draw_rectangle_lines_rotated(
1067 x, y, w, h, rotation, 0.0, 0.0, 0.0, 0.0, thickness, color,
1068 )
1069 });
1070}
1071
1072pub fn draw_rectangle_rounded_rotated(
1076 x: f32,
1077 y: f32,
1078 w: f32,
1079 h: f32,
1080 rotation: f32,
1081 radius: f32,
1082 color: Color,
1083) {
1084 draw_rectangle_rounded_rotated_ex(x, y, w, h, rotation, radius, radius, radius, radius, color);
1085}
1086
1087pub fn draw_rectangle_rounded_rotated_ex(
1088 x: f32,
1089 y: f32,
1090 w: f32,
1091 h: f32,
1092 rotation: f32,
1093 top_left: f32,
1094 top_right: f32,
1095 bottom_left: f32,
1096 bottom_right: f32,
1097 color: Color,
1098) {
1099 ctx(|s| {
1100 s.draw_state.draw_rectangle_rotated(
1101 x,
1102 y,
1103 w,
1104 h,
1105 rotation,
1106 top_left,
1107 top_right,
1108 bottom_left,
1109 bottom_right,
1110 color,
1111 )
1112 });
1113}
1114
1115pub fn draw_rectangle_lines_rounded_rotated(
1119 x: f32,
1120 y: f32,
1121 w: f32,
1122 h: f32,
1123 rotation: f32,
1124 radius: f32,
1125 thickness: f32,
1126 color: Color,
1127) {
1128 draw_rectangle_lines_rounded_rotated_ex(
1129 x, y, w, h, rotation, radius, radius, radius, radius, thickness, color,
1130 );
1131}
1132
1133pub fn draw_rectangle_lines_rounded_rotated_ex(
1137 x: f32,
1138 y: f32,
1139 w: f32,
1140 h: f32,
1141 rotation: f32,
1142 top_left: f32,
1143 top_right: f32,
1144 bottom_left: f32,
1145 bottom_right: f32,
1146 thickness: f32,
1147 color: Color,
1148) {
1149 ctx(|s| {
1150 s.draw_state.draw_rectangle_lines_rotated(
1151 x,
1152 y,
1153 w,
1154 h,
1155 rotation,
1156 top_left,
1157 top_right,
1158 bottom_left,
1159 bottom_right,
1160 thickness,
1161 color,
1162 )
1163 });
1164}
1165
1166pub fn draw_circle(x: f32, y: f32, r: f32, color: Color) {
1174 ctx(|s| s.draw_state.draw_circle(x, y, r, color));
1175}
1176
1177pub fn draw_circle_lines(x: f32, y: f32, r: f32, thickness: f32, color: Color) {
1186 ctx(|s| s.draw_state.draw_circle_lines(x, y, r, thickness, color));
1187}
1188
1189pub fn draw_triangle(x1: f32, y1: f32, x2: f32, y2: f32, x3: f32, y3: f32, color: Color) {
1198 ctx(|s| s.draw_state.draw_triangle(x1, y1, x2, y2, x3, y3, color));
1199}
1200
1201pub fn draw_triangle_lines(
1210 x1: f32,
1211 y1: f32,
1212 x2: f32,
1213 y2: f32,
1214 x3: f32,
1215 y3: f32,
1216 thickness: f32,
1217 color: Color,
1218) {
1219 ctx(|s| {
1220 s.draw_state
1221 .draw_triangle_lines(x1, y1, x2, y2, x3, y3, thickness, color)
1222 });
1223}
1224
1225pub fn draw_line(x1: f32, y1: f32, x2: f32, y2: f32, thickness: f32, color: Color) {
1234 ctx(|s| s.draw_state.draw_line(x1, y1, x2, y2, thickness, color))
1235}
1236
1237pub fn draw_poly_line(points: &[Vector2], thickness: f32, color: Color, closed: bool) {
1248 ctx(|s| {
1249 s.draw_state
1250 .draw_poly_line_miter(points, thickness, color, closed)
1251 })
1252}
1253
1254pub fn draw_poly_line_rounded(points: &[Vector2], thickness: f32, color: Color, closed: bool) {
1265 ctx(|s| {
1266 s.draw_state
1267 .draw_poly_line(points, thickness, color, closed, true)
1268 })
1269}
1270
1271pub fn draw_polygon(points: &[Vector2], color: Color) {
1284 ctx(|s| s.draw_state.draw_polygon(points, color))
1285}
1286
1287pub fn draw_polygon_concave(points: &[Vector2], color: Color) {
1301 ctx(|s| s.draw_state.draw_polygon_concave(points, color))
1302}
1303
1304pub fn draw_text(t: &str, x: f32, y: f32, size: f32, font: Option<&Font>, color: Color) {
1313 ctx(|s| s.draw_state.draw_text(&s.fonts, t, x, y, size, font, color));
1314}
1315
1316pub fn draw_rich_text<'a, I>(
1335 position: Vector2,
1336 size: f32,
1337 font: Option<&Font>,
1338 color: Color,
1339 spans: I,
1340) where
1341 I: IntoIterator,
1342 I::Item: Borrow<Span<'a>>,
1343{
1344 ctx(|s| {
1345 s.draw_state
1346 .draw_richtext(position, size, font, color, spans)
1347 })
1348}
1349
1350pub fn load_font_from_path(path: &str) -> Font {
1364 if STATE.get().is_some() {
1365 return ctx(|s| {
1366 s.load_font_from_path(path);
1367 s.fonts[s.fonts.len() - 1].clone()
1368 });
1369 }
1370
1371 PENDING_CONFIG.with_borrow_mut(|s| {
1372 let font = Font::from_path(s.fonts.len() + 1, path);
1373 s.fonts.push(font.clone());
1374 font
1375 })
1376}
1377
1378pub fn load_font_from_bytes(bytes: &[u8]) -> Font {
1392 if STATE.get().is_some() {
1393 return ctx(|s| {
1394 s.load_font_from_bytes(bytes);
1395 s.fonts[s.fonts.len() - 1].clone()
1396 });
1397 }
1398
1399 PENDING_CONFIG.with_borrow_mut(|s| {
1400 let font = Font::from_bytes(s.fonts.len() + 1, bytes);
1401 s.fonts.push(font.clone());
1402 font
1403 })
1404}
1405
1406pub fn measure_text(t: &str, size: f32, font: Option<&Font>) -> Vector2 {
1408 let (w, h) = ctx(|s| s.measure_text(t, size, font));
1409 Vector2::new(w, h)
1410}
1411
1412pub fn draw_arrow(
1415 x1: f32,
1416 y1: f32,
1417 x2: f32,
1418 y2: f32,
1419 thickness: f32,
1420 head_size: f32,
1421 color: Color,
1422) {
1423 ctx(|s| {
1424 s.draw_state
1425 .draw_arrow(x1, y1, x2, y2, thickness, head_size, color)
1426 });
1427}
1428
1429pub fn screen_size() -> Vector2 {
1431 let win = get_window();
1432 match win.current_monitor() {
1433 Some(m) => {
1434 let s = m.size();
1435 Vector2::new(s.width as f32, s.height as f32)
1436 }
1437 None => window_size(),
1438 }
1439}
1440
1441pub fn screen_width() -> f32 {
1442 screen_size().x
1443}
1444pub fn screen_height() -> f32 {
1445 screen_size().y
1446}
1447
1448pub fn create_empty_texture(width: u32, height: u32, filter_type: FilterType) -> Texture {
1452 ctx(|s| {
1453 let gpu = GpuTexture::empty(
1454 &s.device,
1455 width,
1456 height,
1457 filter_type,
1458 wgpu::TextureFormat::Rgba8UnormSrgb,
1459 )
1460 .expect("Couldn't create empty GpuTexture");
1461
1462 Texture {
1463 id: s.add_gpu_texture(gpu, false),
1464 width,
1465 height,
1466 }
1467 })
1468}
1469
1470pub fn load_texture(path: &str) -> Texture {
1472 ctx(|s| {
1473 let image = image::load_from_memory(&std::fs::read(path).unwrap()).unwrap();
1474 let width = image.width();
1475 let height = image.height();
1476
1477 Texture {
1478 id: s.add_texture(image, FilterType::Linear),
1479 width,
1480 height,
1481 }
1482 })
1483}
1484
1485pub fn load_texture_with_filter_type(path: &str, filter_type: FilterType) -> Texture {
1487 ctx(|s| {
1488 let image = image::load_from_memory(&std::fs::read(path).unwrap()).unwrap();
1489 let width = image.width();
1490 let height = image.height();
1491
1492 Texture {
1493 id: s.add_texture(image, filter_type),
1494 width,
1495 height,
1496 }
1497 })
1498}
1499
1500pub fn load_texture_from_bytes(bytes: &[u8]) -> Texture {
1502 ctx(|s| {
1503 let image = image::load_from_memory(bytes).unwrap();
1504 let (width, height) = image.dimensions();
1505
1506 Texture {
1507 id: s.add_texture(image, FilterType::Linear),
1508 width,
1509 height,
1510 }
1511 })
1512}
1513
1514pub fn load_texture_from_bytes_with_filter_type(bytes: &[u8], filter_type: FilterType) -> Texture {
1516 ctx(|s| {
1517 let image = image::load_from_memory(bytes).unwrap();
1518 let (width, height) = image.dimensions();
1519
1520 Texture {
1521 id: s.add_texture(image, filter_type),
1522 width,
1523 height,
1524 }
1525 })
1526}
1527
1528pub fn load_texture_from_data(width: u32, height: u32, data: &[f32]) -> Texture {
1530 ctx(|s| {
1531 let img_buf = ImageBuffer::<Rgba<f32>, Vec<f32>>::from_raw(width, height, data.to_vec())
1532 .expect("Buffer size mismatch");
1533
1534 let dynamic_img = DynamicImage::ImageRgba32F(img_buf);
1535
1536 Texture {
1537 id: s.add_texture(dynamic_img, FilterType::Linear),
1538 width,
1539 height,
1540 }
1541 })
1542}
1543
1544pub fn load_texture_from_data_with_filter_type(
1548 width: u32,
1549 height: u32,
1550 data: &[f32],
1551 filter_type: FilterType,
1552) -> Texture {
1553 ctx(|s| {
1554 let img_buf = ImageBuffer::<Rgba<f32>, Vec<f32>>::from_raw(width, height, data.to_vec())
1555 .expect("Buffer size mismatch");
1556
1557 let dynamic_img = DynamicImage::ImageRgba32F(img_buf);
1558
1559 Texture {
1560 id: s.add_texture(dynamic_img, filter_type),
1561 width,
1562 height,
1563 }
1564 })
1565}
1566
1567pub fn load_texture_from_image(image: &Image) -> Texture {
1569 let tex = create_empty_texture(image.width, image.height, image.filter_type);
1570 update_texture(tex, image);
1571
1572 tex
1573}
1574
1575pub fn draw_texture(texture: Texture, x: f32, y: f32, w: f32, h: f32, tint: Color) {
1578 ctx(|s| s.draw_state.draw_texture(texture, x, y, w, h, tint))
1579}
1580
1581pub fn draw_texture_ex(texture: Texture, x: f32, y: f32, p: DrawTextureParams) {
1584 ctx(|s| s.draw_state.draw_texture_ex(texture, x, y, p))
1585}
1586
1587pub fn update_texture(texture: Texture, image: &Image) {
1589 ctx(|s| s.update_texture(texture.id, image))
1590}
1591
1592pub fn render_target(width: u32, height: u32, filter_type: FilterType) -> RenderTarget {
1594 ctx(|s| s.create_render_target(width, height, filter_type))
1595}
1596
1597pub fn set_camera(cam: &Camera2D) {
1599 ctx(|s| s.set_camera(cam))
1600}
1601
1602pub fn set_default_camera() {
1604 ctx(|s| s.set_default_camera())
1605}