Support multiple windows, start on input UI

This commit is contained in:
2024-11-09 18:14:18 -05:00
parent 62b34ea760
commit a69247dd33
7 changed files with 824 additions and 476 deletions
+142
View File
@@ -0,0 +1,142 @@
use std::time::Instant;
use winit::{
event::{Event, WindowEvent},
event_loop::{ActiveEventLoop, EventLoopProxy},
};
use super::{
common::{ImguiState, UiExt as _, WindowState, WindowStateBuilder},
AppWindow, UserEvent,
};
pub struct InputWindow {
window: WindowState,
imgui: Option<ImguiState>,
proxy: EventLoopProxy<UserEvent>,
}
impl InputWindow {
pub fn new(event_loop: &ActiveEventLoop, proxy: EventLoopProxy<UserEvent>) -> Self {
let window = WindowStateBuilder::new(event_loop)
.with_title("Map Inputs")
.build();
Self {
window,
imgui: None,
proxy,
}
}
fn draw(&mut self) {
let window = &mut self.window;
let imgui = self.imgui.as_mut().unwrap();
let mut context = imgui.context.lock().unwrap();
let now = Instant::now();
context.io_mut().update_delta_time(now - imgui.last_frame);
imgui.last_frame = now;
let frame = match window.surface.get_current_texture() {
Ok(frame) => frame,
Err(e) => {
eprintln!("dropped frame: {e:?}");
return;
}
};
imgui
.platform
.prepare_frame(context.io_mut(), &window.window)
.expect("Failed to prepare frame");
let ui = context.new_frame();
if let Some(window) = ui.fullscreen_window() {
if let Some(table) = ui.begin_table("controls", 2) {
ui.table_next_row();
ui.table_next_column();
ui.text("Key");
ui.table_next_column();
ui.text("Value");
table.end();
}
window.end();
}
let mut encoder: wgpu::CommandEncoder = window
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
if imgui.last_cursor != ui.mouse_cursor() {
imgui.last_cursor = ui.mouse_cursor();
imgui.platform.prepare_render(ui, &window.window);
}
let view = frame
.texture
.create_view(&wgpu::TextureViewDescriptor::default());
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: None,
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: &view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(imgui.clear_color),
store: wgpu::StoreOp::Store,
},
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
});
// Draw the game
imgui
.renderer
.render(context.render(), &window.queue, &window.device, &mut rpass)
.expect("Rendering failed");
drop(rpass);
window.queue.submit(Some(encoder.finish()));
frame.present();
}
}
impl AppWindow for InputWindow {
fn id(&self) -> winit::window::WindowId {
self.window.window.id()
}
fn init(&mut self) {
self.imgui = Some(ImguiState::new(&self.window));
}
fn handle_event(&mut self, _: &ActiveEventLoop, event: &Event<UserEvent>) {
match event {
Event::WindowEvent { event, .. } => match event {
WindowEvent::Resized(size) => self.window.handle_resize(size),
WindowEvent::CloseRequested => self
.proxy
.send_event(UserEvent::CloseWindow(self.id()))
.unwrap(),
WindowEvent::RedrawRequested => self.draw(),
_ => (),
},
Event::AboutToWait => {
self.window.window.request_redraw();
}
_ => (),
}
let window = &self.window;
let Some(imgui) = self.imgui.as_mut() else {
return;
};
let mut context = imgui.context.lock().unwrap();
imgui
.platform
.handle_event(context.io_mut(), &window.window, event);
}
}