mirror of
https://github.com/storytold/wordcraft.git
synced 2026-10-29 12:57:09 -06:00
This commit is contained in:
@@ -14,7 +14,7 @@ mod graphics;
|
||||
mod logging;
|
||||
|
||||
use wordcraft_engine::Session;
|
||||
use wordcraft_ui_egui::{Services, UiState, WordApp, window_geometry::WindowGeometry};
|
||||
use wordcraft_ui_egui::{Services, UiState, WordApp, window_geometry::{WindowGeometry, take_rescue}};
|
||||
|
||||
/// The app, and the restored window geometry until the first frame has checked it.
|
||||
struct App(WordApp, Option<WindowGeometry>);
|
||||
@@ -24,7 +24,7 @@ impl eframe::App for App {
|
||||
self.0.logic(ctx);
|
||||
let prev = self.0.ui.window;
|
||||
self.0.ui.window = ctx.input(|i| WindowGeometry::track(prev, i.viewport(), i.viewport_rect().size()));
|
||||
if let Some(pos) = self.1.take().and_then(|g| ctx.input(|i| g.rescue_position(i.viewport()))) {
|
||||
if let Some(pos) = ctx.input(|i| take_rescue(&mut self.1, i.viewport())) {
|
||||
ctx.send_viewport_cmd(egui::ViewportCommand::OuterPosition(pos));
|
||||
}
|
||||
if self.0.quit_requested {
|
||||
|
||||
@@ -91,6 +91,14 @@ impl WindowGeometry {
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks the restored geometry in `pending` once, and only once the monitor size is known: while
|
||||
/// `info` doesn't report a usable one, `pending` is left in place for a later frame. Then it is taken
|
||||
/// and [`WindowGeometry::rescue_position`] decides where to move the window, if anywhere.
|
||||
pub fn take_rescue(pending: &mut Option<WindowGeometry>, info: &egui::ViewportInfo) -> Option<egui::Pos2> {
|
||||
info.monitor_size.filter(|s| s.is_finite() && s.x > 0.0 && s.y > 0.0)?;
|
||||
pending.take()?.rescue_position(info)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -174,6 +182,23 @@ mod tests {
|
||||
assert_eq!(saved().rescue_position(&egui::ViewportInfo::default()), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_rescue_waits_for_the_monitor_size() {
|
||||
let on = egui::Rect::from_min_size(egui::pos2(2000.0, 50.0), egui::vec2(1200.0, 800.0));
|
||||
// The first frame doesn't know the monitor yet: nothing happens and the geometry is kept.
|
||||
let mut pending = Some(saved());
|
||||
assert_eq!(take_rescue(&mut pending, &egui::ViewportInfo::default()), None);
|
||||
assert_eq!(pending, Some(saved()));
|
||||
// A later frame reports a different monitor: centred on it, and the check is done.
|
||||
assert_eq!(take_rescue(&mut pending, &info(on, egui::vec2(1600.0, 900.0))), Some(egui::pos2(200.0, 50.0)));
|
||||
assert_eq!(pending, None);
|
||||
assert_eq!(take_rescue(&mut pending, &info(on, egui::vec2(1024.0, 768.0))), None);
|
||||
// The same monitor: no move, and the check is done as well.
|
||||
let mut pending = Some(saved());
|
||||
assert_eq!(take_rescue(&mut pending, &info(on, egui::vec2(1920.0, 1080.0))), None);
|
||||
assert_eq!(pending, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn survives_the_prefs_round_trip() {
|
||||
let ui = crate::UiState { window: Some(saved()), ..Default::default() };
|
||||
|
||||
Reference in New Issue
Block a user