From b688a25810840c5ebf4bf2c18bbdae52c62f6b4d Mon Sep 17 00:00:00 2001 From: tcmal Date: Sun, 25 Aug 2024 17:44:22 +0100 Subject: feat(render): WIP eGUI integration --- stockton-render/src/window.rs | 124 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 120 insertions(+), 4 deletions(-) (limited to 'stockton-render/src/window.rs') diff --git a/stockton-render/src/window.rs b/stockton-render/src/window.rs index efb8030..e122dea 100644 --- a/stockton-render/src/window.rs +++ b/stockton-render/src/window.rs @@ -15,20 +15,27 @@ * with this program. If not, see . */ +use log::debug; +use std::sync::Arc; +use egui::Context; use crate::Renderer; use legion::systems::Runnable; +use egui::{RawInput, Ui, Pos2, Output, PaintJobs}; + use stockton_input::{Action as KBAction, InputManager, Mouse}; -use winit::event::{ElementState, Event as WinitEvent, WindowEvent as WinitWindowEvent}; +use winit::event::{ElementState, Event as WinitEvent, WindowEvent as WinitWindowEvent, MouseButton}; use winit::event_loop::ControlFlow; #[derive(Debug, Clone, Copy)] pub enum WindowEvent { - SizeChanged, + SizeChanged (u32, u32), CloseRequested, KeyboardAction(KBAction), + MouseAction(KBAction), MouseMoved(f32, f32), + MouseLeft } impl WindowEvent { @@ -37,7 +44,7 @@ impl WindowEvent { match winit_event { WinitEvent::WindowEvent { event, .. } => match event { WinitWindowEvent::CloseRequested => Some(WindowEvent::CloseRequested), - WinitWindowEvent::Resized(_) => Some(WindowEvent::SizeChanged), + WinitWindowEvent::Resized(size) => Some(WindowEvent::SizeChanged (size.width, size.height)), WinitWindowEvent::KeyboardInput { input, .. } => match input.state { ElementState::Pressed => Some(WindowEvent::KeyboardAction(KBAction::KeyPress( input.scancode, @@ -50,6 +57,20 @@ impl WindowEvent { position.x as f32, position.y as f32, )), + WinitWindowEvent::CursorLeft { .. } => Some(WindowEvent::MouseLeft), + WinitWindowEvent::MouseInput { button, state, .. } => { + let mb: stockton_input::MouseButton = match button { + MouseButton::Left => stockton_input::MouseButton::Left, + MouseButton::Right => stockton_input::MouseButton::Right, + MouseButton::Middle => stockton_input::MouseButton::Middle, + MouseButton::Other(x) => stockton_input::MouseButton::Other(*x) + }; + + match state { + ElementState::Pressed => Some(WindowEvent::MouseAction(KBAction::MousePress(mb))), + ElementState::Released => Some(WindowEvent::MouseAction(KBAction::MouseRelease(mb))) + } + }, _ => None, }, _ => None, @@ -57,12 +78,87 @@ impl WindowEvent { } } +pub struct UIState { + pub(crate) ctx: Arc, + pub(crate) raw_input: RawInput, + ui: Option, + + pub(crate) last_tex_ver: u64, +} + +impl UIState { + pub fn ui<'a>(&'a mut self) -> &'a mut Ui { + if self.ui.is_none() { + self.ui = Some(self.begin_frame()); + } + self.ui.as_mut().unwrap() + } + fn begin_frame(&mut self) -> Ui { + self.ctx.begin_frame(self.raw_input.take()) + } + + pub fn end_frame(&mut self) -> (Output, PaintJobs) { + self.ui = None; + self.ctx.end_frame() + } + + fn set_mouse_pos(&mut self, x: f32, y: f32) { + self.raw_input.mouse_pos = Some(Pos2 {x, y}) + } + + fn set_mouse_left(&mut self) { + self.raw_input.mouse_pos = None; + } + fn set_dimensions(&mut self, w: u32, h: u32) { + self.raw_input.screen_size = egui::math::Vec2 { + x: w as f32, + y: h as f32 + } + } + fn set_pixels_per_point(&mut self, ppp: Option) { + self.raw_input.pixels_per_point = ppp; + } + + pub fn dimensions(&self) -> egui::math::Vec2 { + self.raw_input.screen_size + } + + fn handle_action(&mut self, action: KBAction) { + // TODO + match action { + KBAction::MousePress(stockton_input::MouseButton::Left) => { + self.raw_input.mouse_down = true; + } + KBAction::MouseRelease(stockton_input::MouseButton::Right) => { + self.raw_input.mouse_down = false; + } + _ => () + } + } + + pub fn new(renderer: &Renderer) -> Self { + let mut state = UIState { + ctx: Context::new(), + raw_input: RawInput::default(), + ui: None, + last_tex_ver: 0 + }; + + let props = &renderer.context.target_chain.properties; + state.set_dimensions(props.extent.width, props.extent.height); + state.set_pixels_per_point(Some(renderer.context.pixels_per_point)); + debug!("{:?}", state.raw_input); + state + } +} + #[system] /// A system to process the window events sent to renderer by the winit event loop. pub fn _process_window_events( #[resource] renderer: &mut Renderer<'static>, #[resource] manager: &mut T, #[resource] mouse: &mut Mouse, + #[resource] ui_state: &mut UIState, #[state] actions_buf: &mut Vec, ) { let mut actions_buf_cursor = 0; @@ -70,7 +166,10 @@ pub fn _process_window_events( while let Ok(event) = renderer.window_events.try_recv() { match event { - WindowEvent::SizeChanged => renderer.resize(), + WindowEvent::SizeChanged(w, h) => { + renderer.resize(); + ui_state.set_dimensions(w, h); + }, WindowEvent::CloseRequested => { let mut flow = renderer.update_control_flow.write().unwrap(); // TODO: Let everything know this is our last frame @@ -83,10 +182,27 @@ pub fn _process_window_events( actions_buf[actions_buf_cursor] = action; } actions_buf_cursor += 1; + + ui_state.handle_action(action); } WindowEvent::MouseMoved(x, y) => { mouse_delta.x = x; mouse_delta.y = y; + + ui_state.set_mouse_pos(x, y); + }, + WindowEvent::MouseLeft => { + ui_state.set_mouse_left(); + }, + WindowEvent::MouseAction(action) => { + if actions_buf_cursor >= actions_buf.len() { + actions_buf.push(action); + } else { + actions_buf[actions_buf_cursor] = action; + } + actions_buf_cursor += 1; + + ui_state.handle_action(action); } }; } -- cgit v1.2.3