use std::collections::HashMap;
use embedded_graphics::{pixelcolor::Rgb888, prelude::*};
use crate::{
window::{sdl_window::SimulatorEventsIter, FpsLimiter, SdlWindow},
OutputImage, OutputSettings, SimulatorDisplay,
};
pub struct MultiWindow {
sdl_window: SdlWindow,
framebuffer: OutputImage<Rgb888>,
displays: HashMap<usize, DisplaySettings>,
fps_limiter: FpsLimiter,
}
impl MultiWindow {
pub fn new(title: &str, size: Size) -> Self {
let mut sdl_window = SdlWindow::new(title, size);
let framebuffer = OutputImage::new(size);
sdl_window.update(&framebuffer);
Self {
sdl_window: sdl_window,
framebuffer,
displays: HashMap::new(),
fps_limiter: FpsLimiter::new(),
}
}
pub fn add_display<C>(
&mut self,
display: &SimulatorDisplay<C>,
offset: Point,
output_settings: &OutputSettings,
) {
self.displays.insert(
display.id,
DisplaySettings {
offset,
output_settings: output_settings.clone(),
},
);
}
pub fn clear(&mut self, color: Rgb888) {
self.framebuffer.clear(color).unwrap();
}
pub fn update_display<C>(&mut self, display: &SimulatorDisplay<C>)
where
C: PixelColor + Into<Rgb888> + From<Rgb888>,
{
let display_settings = self
.displays
.get(&display.id)
.expect("update_display called for a display that hasn't been added with add_display");
self.framebuffer.draw_display(
display,
display_settings.offset,
&display_settings.output_settings,
);
}
pub fn flush(&mut self) {
self.sdl_window.update(&self.framebuffer);
self.fps_limiter.sleep();
}
pub fn events(&self) -> SimulatorEventsIter<'_> {
self.sdl_window.events(&crate::OutputSettings::default())
}
pub fn translate_mouse_position<C>(
&self,
display: &SimulatorDisplay<C>,
position: Point,
) -> Option<Point> {
let display_settings = self.displays.get(&display.id).expect(
"translate_mouse_position called for a display that hasn't been added with add_display",
);
let delta = position - display_settings.offset;
let p = display_settings.output_settings.output_to_display(delta);
display.bounding_box().contains(p).then_some(p)
}
pub fn set_max_fps(&mut self, max_fps: u32) {
self.fps_limiter.max_fps = max_fps;
}
}
struct DisplaySettings {
offset: Point,
output_settings: OutputSettings,
}