Graphical fixes
This commit is contained in:
		
							parent
							
								
									83377ff5fa
								
							
						
					
					
						commit
						9ff62af310
					
				
							
								
								
									
										44
									
								
								src/app.rs
								
								
								
								
							
							
						
						
									
										44
									
								
								src/app.rs
								
								
								
								
							| 
						 | 
					@ -2,7 +2,8 @@ use std::{collections::HashSet, num::NonZero, sync::Arc, thread};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use egui::{
 | 
					use egui::{
 | 
				
			||||||
    ahash::{HashMap, HashMapExt},
 | 
					    ahash::{HashMap, HashMapExt},
 | 
				
			||||||
    Context, TextWrapMode, ViewportBuilder, ViewportCommand, ViewportId, ViewportInfo,
 | 
					    Context, FontData, FontDefinitions, FontFamily, TextWrapMode, ViewportBuilder, ViewportCommand,
 | 
				
			||||||
 | 
					    ViewportId, ViewportInfo,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use gilrs::{EventType, Gilrs};
 | 
					use gilrs::{EventType, Gilrs};
 | 
				
			||||||
use winit::{
 | 
					use winit::{
 | 
				
			||||||
| 
						 | 
					@ -89,20 +90,37 @@ impl ApplicationHandler<UserEvent> for Application {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            _ => {}
 | 
					            _ => {}
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        let mut queue_redraw = false;
 | 
				
			||||||
 | 
					        let mut inactive_viewports = HashSet::new();
 | 
				
			||||||
        match viewport.on_window_event(event) {
 | 
					        match viewport.on_window_event(event) {
 | 
				
			||||||
            Some(Action::Redraw) => {
 | 
					            Some(Action::Redraw) => {
 | 
				
			||||||
                for viewport in self.viewports.values_mut() {
 | 
					                for viewport in self.viewports.values_mut() {
 | 
				
			||||||
                    viewport.redraw(event_loop);
 | 
					                    match viewport.redraw(event_loop) {
 | 
				
			||||||
 | 
					                        Some(Action::Redraw) => {
 | 
				
			||||||
 | 
					                            queue_redraw = true;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        Some(Action::Close) => {
 | 
				
			||||||
 | 
					                            inactive_viewports.insert(viewport.id());
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        None => {}
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Some(Action::Close) => {
 | 
					            Some(Action::Close) => {
 | 
				
			||||||
                self.viewports.remove(&viewport_id);
 | 
					                inactive_viewports.insert(viewport_id);
 | 
				
			||||||
                if viewport_id == ViewportId::ROOT {
 | 
					 | 
				
			||||||
                    event_loop.exit();
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            None => {}
 | 
					            None => {}
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        self.viewports
 | 
				
			||||||
 | 
					            .retain(|k, _| !inactive_viewports.contains(k));
 | 
				
			||||||
 | 
					        match self.viewports.get(&ViewportId::ROOT) {
 | 
				
			||||||
 | 
					            Some(viewport) => {
 | 
				
			||||||
 | 
					                if queue_redraw {
 | 
				
			||||||
 | 
					                    viewport.window.request_redraw();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            None => event_loop.exit(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn device_event(
 | 
					    fn device_event(
 | 
				
			||||||
| 
						 | 
					@ -165,6 +183,17 @@ impl Viewport {
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let ctx = Context::default();
 | 
					        let ctx = Context::default();
 | 
				
			||||||
 | 
					        let mut fonts = FontDefinitions::empty();
 | 
				
			||||||
 | 
					        fonts.font_data.insert(
 | 
				
			||||||
 | 
					            "Selawik".into(),
 | 
				
			||||||
 | 
					            FontData::from_static(include_bytes!("../assets/selawik.ttf")),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        fonts
 | 
				
			||||||
 | 
					            .families
 | 
				
			||||||
 | 
					            .get_mut(&FontFamily::Proportional)
 | 
				
			||||||
 | 
					            .unwrap()
 | 
				
			||||||
 | 
					            .insert(0, "Selawik".into());
 | 
				
			||||||
 | 
					        ctx.set_fonts(fonts);
 | 
				
			||||||
        ctx.style_mut(|s| {
 | 
					        ctx.style_mut(|s| {
 | 
				
			||||||
            s.wrap_mode = Some(TextWrapMode::Extend);
 | 
					            s.wrap_mode = Some(TextWrapMode::Extend);
 | 
				
			||||||
            s.visuals.menu_rounding = Default::default();
 | 
					            s.visuals.menu_rounding = Default::default();
 | 
				
			||||||
| 
						 | 
					@ -242,7 +271,7 @@ impl Viewport {
 | 
				
			||||||
        self.state
 | 
					        self.state
 | 
				
			||||||
            .handle_platform_output(&self.window, output.platform_output);
 | 
					            .handle_platform_output(&self.window, output.platform_output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let Some(viewport_output) = output.viewport_output.remove(&ViewportId::ROOT) else {
 | 
					        let Some(mut viewport_output) = output.viewport_output.remove(&ViewportId::ROOT) else {
 | 
				
			||||||
            return Some(Action::Close);
 | 
					            return Some(Action::Close);
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -255,6 +284,7 @@ impl Viewport {
 | 
				
			||||||
            self.state = state;
 | 
					            self.state = state;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        self.commands.append(&mut deferred_commands);
 | 
					        self.commands.append(&mut deferred_commands);
 | 
				
			||||||
 | 
					        self.commands.append(&mut viewport_output.commands);
 | 
				
			||||||
        egui_winit::process_viewport_commands(
 | 
					        egui_winit::process_viewport_commands(
 | 
				
			||||||
            &self.ctx,
 | 
					            &self.ctx,
 | 
				
			||||||
            &mut self.info,
 | 
					            &mut self.info,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,8 +3,8 @@ use crate::{
 | 
				
			||||||
    emulator::{EmulatorClient, EmulatorCommand, SimId},
 | 
					    emulator::{EmulatorClient, EmulatorCommand, SimId},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use egui::{
 | 
					use egui::{
 | 
				
			||||||
    menu, Button, CentralPanel, Color32, Context, Response, TopBottomPanel, Ui, ViewportBuilder,
 | 
					    menu, Button, CentralPanel, Color32, Context, Frame, Response, TopBottomPanel, Ui,
 | 
				
			||||||
    ViewportCommand, ViewportId, WidgetText,
 | 
					    ViewportBuilder, ViewportCommand, ViewportId, WidgetText,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use winit::event_loop::EventLoopProxy;
 | 
					use winit::event_loop::EventLoopProxy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,7 +67,7 @@ impl GameWindow {
 | 
				
			||||||
            for scale in 1..=4 {
 | 
					            for scale in 1..=4 {
 | 
				
			||||||
                let label = format!("x{scale}");
 | 
					                let label = format!("x{scale}");
 | 
				
			||||||
                let scale = scale as f32;
 | 
					                let scale = scale as f32;
 | 
				
			||||||
                let dims = (384.0 * scale, 224.0 * scale + 20.0).into();
 | 
					                let dims = (384.0 * scale, 224.0 * scale + 22.0).into();
 | 
				
			||||||
                if ui
 | 
					                if ui
 | 
				
			||||||
                    .selectable_button((current_dims - dims).length() < 1.0, label)
 | 
					                    .selectable_button((current_dims - dims).length() < 1.0, label)
 | 
				
			||||||
                    .clicked()
 | 
					                    .clicked()
 | 
				
			||||||
| 
						 | 
					@ -133,18 +133,19 @@ impl AppWindow for GameWindow {
 | 
				
			||||||
    fn initial_viewport(&self) -> ViewportBuilder {
 | 
					    fn initial_viewport(&self) -> ViewportBuilder {
 | 
				
			||||||
        ViewportBuilder::default()
 | 
					        ViewportBuilder::default()
 | 
				
			||||||
            .with_title("Shrooms VB")
 | 
					            .with_title("Shrooms VB")
 | 
				
			||||||
            .with_inner_size((384.0, 244.0))
 | 
					            .with_inner_size((384.0, 246.0))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn show(&mut self, ctx: &Context) {
 | 
					    fn show(&mut self, ctx: &Context) {
 | 
				
			||||||
        TopBottomPanel::top("menubar")
 | 
					        TopBottomPanel::top("menubar")
 | 
				
			||||||
            .exact_height(20.0)
 | 
					            .exact_height(22.0)
 | 
				
			||||||
            .show(ctx, |ui| {
 | 
					            .show(ctx, |ui| {
 | 
				
			||||||
                menu::bar(ui, |ui| {
 | 
					                menu::bar(ui, |ui| {
 | 
				
			||||||
                    self.show_menu(ctx, ui);
 | 
					                    self.show_menu(ctx, ui);
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        CentralPanel::default().show(ctx, |ui| {
 | 
					        let frame = Frame::central_panel(&ctx.style()).fill(Color32::BLACK);
 | 
				
			||||||
 | 
					        CentralPanel::default().frame(frame).show(ctx, |ui| {
 | 
				
			||||||
            if let Some(screen) = self.screen.as_ref() {
 | 
					            if let Some(screen) = self.screen.as_ref() {
 | 
				
			||||||
                ui.add(screen);
 | 
					                ui.add(screen);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -171,14 +171,24 @@ struct GameScreenCallback {
 | 
				
			||||||
impl egui_wgpu::CallbackTrait for GameScreenCallback {
 | 
					impl egui_wgpu::CallbackTrait for GameScreenCallback {
 | 
				
			||||||
    fn paint(
 | 
					    fn paint(
 | 
				
			||||||
        &self,
 | 
					        &self,
 | 
				
			||||||
        _info: egui::PaintCallbackInfo,
 | 
					        info: egui::PaintCallbackInfo,
 | 
				
			||||||
        render_pass: &mut wgpu::RenderPass<'static>,
 | 
					        render_pass: &mut wgpu::RenderPass<'static>,
 | 
				
			||||||
        callback_resources: &egui_wgpu::CallbackResources,
 | 
					        callback_resources: &egui_wgpu::CallbackResources,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        let resources: &SharedGameScreenResources = callback_resources.get().unwrap();
 | 
					        let resources: &SharedGameScreenResources = callback_resources.get().unwrap();
 | 
				
			||||||
        // TODO: maintain aspect ratio
 | 
					        let viewport = info.viewport_in_pixels();
 | 
				
			||||||
 | 
					        let left = viewport.left_px as f32;
 | 
				
			||||||
 | 
					        let top = viewport.top_px as f32;
 | 
				
			||||||
 | 
					        let width = viewport.width_px as f32;
 | 
				
			||||||
 | 
					        let height = viewport.height_px as f32;
 | 
				
			||||||
 | 
					        let aspect_ratio = 384.0 / 224.0;
 | 
				
			||||||
 | 
					        let w = width.min(height * aspect_ratio);
 | 
				
			||||||
 | 
					        let h = height.min(width / aspect_ratio);
 | 
				
			||||||
 | 
					        let x = left + (width - w) / 2.0;
 | 
				
			||||||
 | 
					        let y = top + (height - h) / 2.0;
 | 
				
			||||||
        render_pass.set_pipeline(&resources.pipeline);
 | 
					        render_pass.set_pipeline(&resources.pipeline);
 | 
				
			||||||
        render_pass.set_bind_group(0, &self.bind_group, &[]);
 | 
					        render_pass.set_bind_group(0, &self.bind_group, &[]);
 | 
				
			||||||
 | 
					        render_pass.set_viewport(x, y, w, h, 0.0, 1.0);
 | 
				
			||||||
        render_pass.draw(0..6, 0..1);
 | 
					        render_pass.draw(0..6, 0..1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue