1extern crate glfw;
2
3use std::time::Instant;
4
5use gl::{BlendFunc, Enable, Viewport, BLEND, DEPTH_TEST, ONE_MINUS_SRC_ALPHA, SRC_ALPHA};
6use glam::{vec2, Vec2};
7use glfw::{fail_on_errors, Glfw, GlfwReceiver, PWindow, WindowEvent};
8use glfw::{Action, Context, Key};
9
10use crate::{EventHandler, Imgui};
11
12pub struct EventLoop {
13 pub event_handler: EventHandler,
14 pub window: PWindow,
15 pub ui: Imgui,
16 pub glfw: Glfw,
17 events: GlfwReceiver<(f64, WindowEvent)>,
18 pub now: Instant,
19 pub dt: f32,
20 pub time: f32,
21
22 pub timescale: f32,
23}
24
25impl EventLoop {
26 pub fn new(w: u32, h: u32) -> Self {
27 let mut glfw = glfw::init(fail_on_errors!()).unwrap();
28
29 glfw.window_hint(glfw::WindowHint::Decorated(true));
31 glfw.window_hint(glfw::WindowHint::DoubleBuffer(true));
32 glfw.window_hint(glfw::WindowHint::ContextVersionMajor(3));
33 glfw.window_hint(glfw::WindowHint::ContextVersionMinor(3));
34 let (mut window, events) = glfw.create_window(w, h, "Hello this is window", glfw::WindowMode::Windowed)
37 .expect("Failed to create GLFW window.");
38
39 let ui = Imgui::new(&mut window);
40
41 window.make_current();
42 window.set_key_polling(true);
43 window.set_cursor_pos_polling(true);
44 window.set_framebuffer_size_polling(true);
45 window.set_mouse_button_polling(true);
46 window.set_scroll_polling(true);
47 gl::load_with(|s| window.get_proc_address(s) );
50
51 unsafe {
52 BlendFunc(SRC_ALPHA, ONE_MINUS_SRC_ALPHA);
53 Enable(BLEND | DEPTH_TEST);
54 }
55
56 let mut event_handler = EventHandler::new();
57 event_handler.on_window_resize(w as i32, h as i32);
58
59 Self {
60 event_handler,
61 window,
62 ui,
63 glfw,
64 events,
65 now: std::time::Instant::now(),
66 dt: 0.0,
67 time: 0.0,
68 timescale: 1.0,
69 }
70 }
71
72 pub fn size(&self) -> Vec2 {
73 vec2(self.window.get_size().0 as f32, self.window.get_size().1 as f32)
74 }
75
76 pub fn update(&mut self) {
77 self.dt = self.now.elapsed().as_secs_f32() * self.timescale;
78 self.time += self.dt;
79 self.now = std::time::Instant::now();
80
81
82 self.window.swap_buffers();
83
84 self.glfw.poll_events();
85
86 self.event_handler.update();
87
88 for (_, event) in glfw::flush_messages(&self.events) {
89 match event {
90 glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => {
91 self.window.set_should_close(true)
92 },
93 glfw::WindowEvent::Key(key, _, Action::Press, _ ) => {
94 self.event_handler.on_key_press(key);
95 }
96 glfw::WindowEvent::Key(key, _, Action::Release, _ ) => {
97 self.event_handler.on_key_release(key);
98 }
99
100 glfw::WindowEvent::CursorPos(x, y) => {
101 self.event_handler.on_mouse_move(x, y);
102 self.ui.on_mouse_move(x as f32, y as f32);
103 }
104
105 glfw::WindowEvent::MouseButton(button, Action::Press, _) => {
106 self.ui.on_mouse_click(button, Action::Press);
107
108 match button {
112 glfw::MouseButton::Button1 => {
113 self.event_handler.on_lmb_press();
117 },
118 glfw::MouseButton::Button2 => {
119 self.event_handler.on_rmb_press();
123 },
124 _ => ()
125 }
126 }
127
128 glfw::WindowEvent::MouseButton(button, Action::Release, _) => {
129 self.ui.on_mouse_click(button, Action::Release);
130 match button {
131 glfw::MouseButton::Button1 => {
132 self.event_handler.on_lmb_release();
133 },
134 glfw::MouseButton::Button2 => {
135 self.event_handler.on_rmb_release();
136 },
137
138 _ => ()
139 }
140 }
141
142 glfw::WindowEvent::Scroll(xoff, yoff) => {
143 self.event_handler.on_scroll_change(vec2(xoff as f32, yoff as f32));
144 self.ui.on_mouse_scroll(xoff as f32, yoff as f32);
145 }
146
147 glfw::WindowEvent::FramebufferSize(w, h) => {
148 self.event_handler.on_window_resize(w, h);
149 unsafe {
150 Viewport(0, 0, w, h);
151 }
152 }
153 _ => {},
154 }
155 }
156 }
157
158 pub fn is_key_down(&self, key: Key) -> bool {
159 if self.window.get_key(key) == Action::Press {
160 true
161 } else {
162 false
163 }
164 }
165
166 pub fn is_key_up(&self, key: Key) -> bool {
167 if self.window.get_key(key) == Action::Release {
168 true
169 } else {
170 false
171 }
172 }
173
174 pub fn set_fullscreen(&mut self, fullscreen: &mut bool) {
176 if self.event_handler.key_just_pressed(Key::F11) {
177 if !*fullscreen {
178 self.glfw.with_primary_monitor(|_, monitor| {
179 let monitor = monitor.unwrap();
180 let mode = monitor.get_video_mode().unwrap();
181 self.window.set_monitor(
182 glfw::WindowMode::FullScreen(&monitor),
183 0,
184 0,
185 mode.width,
186 mode.height,
187 Some(mode.refresh_rate),
188 );
189 *fullscreen = true;
190 });
191 } else {
192 self.glfw.with_primary_monitor(|_, monitor| {
193 let monitor = monitor.unwrap();
194 let mode = monitor.get_video_mode().unwrap();
195 self.window.set_monitor(
196 glfw::WindowMode::Windowed,
197 200,
198 200,
199 800,
200 800,
201 Some(mode.refresh_rate),
202 );
203 *fullscreen = false;
204 });
205 }
206 }
207 }
208}