embedded_graphics_simulator/window/
multi_window.rs1use std::collections::HashMap;
2
3use embedded_graphics::{pixelcolor::Rgb888, prelude::*};
4
5use crate::{
6 window::{sdl_window::SimulatorEventsIter, FpsLimiter, SdlWindow},
7 OutputImage, OutputSettings, SimulatorDisplay,
8};
9
10pub struct MultiWindow {
21 sdl_window: SdlWindow,
22 framebuffer: OutputImage<Rgb888>,
23 displays: HashMap<usize, DisplaySettings>,
24 fps_limiter: FpsLimiter,
25}
26
27impl MultiWindow {
28 pub fn new(title: &str, size: Size) -> Self {
30 let mut sdl_window = SdlWindow::new(title, size);
31
32 let framebuffer = OutputImage::new(size);
33
34 sdl_window.update(&framebuffer);
35
36 Self {
37 sdl_window: sdl_window,
38 framebuffer,
39 displays: HashMap::new(),
40 fps_limiter: FpsLimiter::new(),
41 }
42 }
43
44 pub fn add_display<C>(
46 &mut self,
47 display: &SimulatorDisplay<C>,
48 offset: Point,
49 output_settings: &OutputSettings,
50 ) {
51 self.displays.insert(
52 display.id,
53 DisplaySettings {
54 offset,
55 output_settings: output_settings.clone(),
56 },
57 );
58 }
59
60 pub fn clear(&mut self, color: Rgb888) {
65 self.framebuffer.clear(color).unwrap();
66 }
67
68 pub fn update_display<C>(&mut self, display: &SimulatorDisplay<C>)
74 where
75 C: PixelColor + Into<Rgb888> + From<Rgb888>,
76 {
77 let display_settings = self
78 .displays
79 .get(&display.id)
80 .expect("update_display called for a display that hasn't been added with add_display");
81
82 self.framebuffer.draw_display(
83 display,
84 display_settings.offset,
85 &display_settings.output_settings,
86 );
87 }
88
89 pub fn flush(&mut self) {
91 self.sdl_window.update(&self.framebuffer);
92
93 self.fps_limiter.sleep();
94 }
95
96 pub fn events(&self) -> SimulatorEventsIter<'_> {
106 self.sdl_window.events(&crate::OutputSettings::default())
107 }
108
109 pub fn translate_mouse_position<C>(
114 &self,
115 display: &SimulatorDisplay<C>,
116 position: Point,
117 ) -> Option<Point> {
118 let display_settings = self.displays.get(&display.id).expect(
119 "translate_mouse_position called for a display that hasn't been added with add_display",
120 );
121
122 let delta = position - display_settings.offset;
123 let p = display_settings.output_settings.output_to_display(delta);
124
125 display.bounding_box().contains(p).then_some(p)
126 }
127
128 pub fn set_max_fps(&mut self, max_fps: u32) {
130 self.fps_limiter.max_fps = max_fps;
131 }
132}
133
134struct DisplaySettings {
135 offset: Point,
136 output_settings: OutputSettings,
137}