1use send_wrapper::SendWrapper;
45use std::sync::{RwLock, RwLockWriteGuard};
46
47use macroquad::miniquad as mq;
48use macroquad::window::get_internal_gl;
49use yakui_miniquad::*;
50
51pub use macroquad;
52
53struct Yakui(YakuiMiniQuad, usize);
54
55static YAKUI: RwLock<Option<SendWrapper<Yakui>>> = RwLock::new(None);
57
58fn get_yakui() -> RwLockWriteGuard<'static, Option<SendWrapper<Yakui>>> {
59 match YAKUI.try_write() {
60 Ok(mut yakui) => {
61 if yakui.is_some() {
62 yakui
63 } else {
64 *yakui = Some(SendWrapper::new(Yakui::new()));
65 yakui
66 }
67 }
68 Err(_) => panic!(
69 "tried to borrow yakui mutably twice, did you accidentally nest ui or cfg calls?"
70 ),
71 }
72}
73
74impl Yakui {
75 fn new() -> Self {
76 Self(
77 YakuiMiniQuad::new(unsafe { get_internal_gl() }.quad_context),
78 macroquad::input::utils::register_input_subscriber(),
79 )
80 }
81
82 fn start(&mut self) {
83 macroquad::input::utils::repeat_all_miniquad_input(self, self.1);
84 self.0.start();
85 }
86
87 fn finish(&mut self) {
88 self.0.finish();
89 }
90
91 fn ui<F>(&mut self, f: F)
92 where
93 F: FnOnce(&mut yakui_core::Yakui),
94 {
95 macroquad::input::utils::repeat_all_miniquad_input(self, self.1);
96
97 self.0.run(f);
98 }
99
100 fn draw(&mut self) {
101 let mut gl = unsafe { get_internal_gl() };
102 gl.flush();
104 self.0.draw(gl.quad_context);
105 }
106}
107
108pub fn has_input_focus() -> bool {
110 get_yakui().as_ref().unwrap().0.has_input_focus()
111}
112
113pub fn has_keyboard_focus() -> bool {
115 get_yakui().as_ref().unwrap().0.has_keyboard_focus()
116}
117
118pub fn has_mouse_focus() -> bool {
120 get_yakui().as_ref().unwrap().0.has_mouse_focus()
121}
122
123pub fn start() {
125 get_yakui().as_mut().unwrap().start();
126}
127
128pub fn finish() {
130 get_yakui().as_mut().unwrap().finish();
131}
132
133pub fn ui<F: FnOnce(&mut yakui_core::Yakui)>(f: F) {
135 get_yakui().as_mut().unwrap().ui(|ctx| f(ctx))
136}
137
138pub fn cfg<F: FnOnce(&mut yakui_core::Yakui)>(f: F) {
140 f(get_yakui().as_mut().unwrap().0.ctx());
141}
142
143pub fn draw() {
145 get_yakui().as_mut().unwrap().draw()
146}
147
148impl mq::EventHandler for Yakui {
149 fn update(&mut self) {}
150
151 fn draw(&mut self) {}
152
153 fn mouse_motion_event(&mut self, x: f32, y: f32) {
154 self.0.mouse_motion_event(x, y);
155 }
156
157 fn mouse_wheel_event(&mut self, dx: f32, dy: f32) {
158 self.0.mouse_wheel_event(dx, dy);
159 }
160
161 fn mouse_button_down_event(&mut self, mb: mq::MouseButton, x: f32, y: f32) {
162 self.0.mouse_button_down_event(mb, x, y);
163 }
164
165 fn mouse_button_up_event(&mut self, mb: mq::MouseButton, x: f32, y: f32) {
166 self.0.mouse_button_up_event(mb, x, y);
167 }
168
169 fn char_event(&mut self, character: char, keymods: mq::KeyMods, repeat: bool) {
170 self.0.char_event(character, keymods, repeat);
171 }
172
173 fn key_down_event(&mut self, keycode: mq::KeyCode, keymods: mq::KeyMods, repeat: bool) {
174 self.0.key_down_event(keycode, keymods, repeat);
175 }
176
177 fn key_up_event(&mut self, keycode: mq::KeyCode, keymods: mq::KeyMods) {
178 self.0.key_up_event(keycode, keymods);
179 }
180}