extern crate embedded_graphics;
extern crate embedded_graphics_simulator;
use embedded_graphics::{
geometry::AnchorPoint,
mono_font::{ascii::FONT_10X20, MonoTextStyle},
pixelcolor::{BinaryColor, Rgb565, Rgb888},
prelude::*,
primitives::{Circle, PrimitiveStyle, PrimitiveStyleBuilder, Rectangle, StrokeAlignment},
text::{Alignment, Baseline, Text, TextStyle, TextStyleBuilder},
};
use embedded_graphics_simulator::{
sdl2::MouseButton, BinaryColorTheme, MultiWindow, OutputSettings, OutputSettingsBuilder,
SimulatorDisplay, SimulatorEvent,
};
const OLED_TEXT: MonoTextStyle<BinaryColor> = MonoTextStyle::new(&FONT_10X20, BinaryColor::On);
const TFT_TEXT: MonoTextStyle<Rgb565> =
MonoTextStyle::new(&FONT_10X20, Rgb565::CSS_LIGHT_SLATE_GRAY);
const CENTERED: TextStyle = TextStyleBuilder::new()
.alignment(Alignment::Center)
.baseline(Baseline::Middle)
.build();
fn display_offset(window_size: Size, display_size: Size, anchor_point: AnchorPoint) -> Point {
let layout_rect = Rectangle::new(Point::zero(), window_size).offset(-20);
layout_rect.resized(display_size, anchor_point).top_left
}
fn main() -> Result<(), core::convert::Infallible> {
let mut oled_displays = Vec::new();
for i in 0..3 {
let mut oled: SimulatorDisplay<BinaryColor> = SimulatorDisplay::new(Size::new(128, 64));
Text::with_text_style(
&format!("Display {i}"),
oled.bounding_box().center(),
OLED_TEXT,
CENTERED,
)
.draw(&mut oled)
.unwrap();
oled_displays.push(oled);
}
let mut tft: SimulatorDisplay<Rgb565> = SimulatorDisplay::new(Size::new(320, 240));
tft.clear(Rgb565::new(5, 10, 5)).unwrap();
Text::with_text_style(
&format!("Draw here"),
tft.bounding_box().center(),
TFT_TEXT,
CENTERED,
)
.draw(&mut tft)
.unwrap();
let window_size = Size::new(1300, 500);
let mut window = MultiWindow::new("Multiple displays example", window_size);
window.clear(Rgb888::CSS_DIM_GRAY);
let oled_settings = OutputSettingsBuilder::new()
.theme(BinaryColorTheme::OledBlue)
.scale(2)
.build();
let oled_size = oled_displays[0].output_size(&oled_settings);
for (oled, anchor) in oled_displays.iter().zip(
[
AnchorPoint::TopLeft,
AnchorPoint::TopCenter,
AnchorPoint::TopRight,
]
.into_iter(),
) {
let offset = display_offset(window_size, oled_size, anchor);
window.add_display(&oled, offset, &oled_settings);
}
let tft_settings = OutputSettings::default();
let tft_size = tft.output_size(&tft_settings);
let tft_offset = display_offset(window_size, tft_size, AnchorPoint::BottomCenter);
window.add_display(&tft, tft_offset, &tft_settings);
let border_style = PrimitiveStyleBuilder::new()
.stroke_width(5)
.stroke_alignment(StrokeAlignment::Inside)
.build();
let mut mouse_down = false;
'running: loop {
for oled in &oled_displays {
window.update_display(oled);
}
window.update_display(&tft);
window.flush();
for event in window.events() {
match event {
SimulatorEvent::MouseMove { point } => {
for oled in &mut oled_displays {
let is_inside = window.translate_mouse_position(oled, point).is_some();
let style = PrimitiveStyleBuilder::from(&border_style)
.stroke_color(BinaryColor::from(is_inside))
.build();
oled.bounding_box().into_styled(style).draw(oled).unwrap();
}
if mouse_down {
if let Some(point) = window.translate_mouse_position(&tft, point) {
Circle::with_center(point, 10)
.into_styled(PrimitiveStyle::with_fill(Rgb565::CSS_DODGER_BLUE))
.draw(&mut tft)
.unwrap();
}
}
}
SimulatorEvent::MouseButtonDown {
mouse_btn: MouseButton::Left,
..
} => {
mouse_down = true;
}
SimulatorEvent::MouseButtonUp {
mouse_btn: MouseButton::Left,
..
} => {
mouse_down = false;
}
SimulatorEvent::Quit => break 'running,
_ => {}
}
}
}
Ok(())
}