One frame for every window (frame.rs): command dialogs dock right and shrink to their content (260 to 380 px, 560 for table dialogs), floating windows are centred and capped (460 px, 760 for tables); header and footer rows right-align without stretching the dialog, long texts wrap; all windows migrated; tests: no egui::Window outside frame.rs, every command's dialog and the floating windows measured within limits
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
1 parent
74c7259825
commit
3f44110b59
16 files changed
+684
-483
No files matched your search
@@ -0,0 +1,92 @@
|
||||
//! Every command dialog and every window stays within the width limits of `frame`: started
|
||||
//! through the control channel (the toolbar's way) and measured as drawn.
|
||||
|
||||
use serde_json::json;
|
||||
use solvecraft_ui_egui::frame::{DIALOG_MAX_W, DIALOG_MIN_W, DIALOG_WIDE_MAX_W, WINDOW_WIDE_MAX_W};
|
||||
use solvecraft_ui_egui::scenario::Harness;
|
||||
|
||||
/// Widths of the windows on screen (their areas in the middle layer).
|
||||
fn window_widths(h: &Harness) -> Vec<(String, f32)> {
|
||||
h.ctx.memory(|m| {
|
||||
m.areas()
|
||||
.visible_layer_ids()
|
||||
.into_iter()
|
||||
.filter(|l| l.order == egui::Order::Middle)
|
||||
.filter_map(|l| m.area_rect(l.id).map(|r| (format!("{:?}", l.id), r.width())))
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
||||
fn fresh() -> Harness {
|
||||
let mut h = Harness::new();
|
||||
h.call("engine.execute", json!({"command": "PrimitiveBox", "params": {"length": 40, "width": 30, "height": 20}}));
|
||||
h.frames(3);
|
||||
h
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn command_dialogs_shrink_to_their_content_within_limits() {
|
||||
let mut h = fresh();
|
||||
let mut bad = Vec::new();
|
||||
// The frame border and shadow add a little to the content limits.
|
||||
let slack = 4.0;
|
||||
for spec in solvecraft_engine::command_specs() {
|
||||
h.call("ui.start", json!({"command": spec.id}));
|
||||
h.frames(4);
|
||||
let wide = h.app.dialog.as_ref().is_some_and(|d| d.is_wide());
|
||||
let max = if wide { DIALOG_WIDE_MAX_W } else { DIALOG_MAX_W };
|
||||
for (layer, w) in window_widths(&h) {
|
||||
// Floating windows a command opened (Parameters…) have their own limit.
|
||||
let limit = if h.app.dialog.is_some() { max } else { WINDOW_WIDE_MAX_W };
|
||||
if w > limit + slack {
|
||||
bad.push(format!("{} ({layer}): {w} px", spec.id));
|
||||
}
|
||||
}
|
||||
// The docked dialog shrinks to its content: most dialogs stay well under the maximum.
|
||||
if h.app.dialog.is_some() && !wide {
|
||||
for (_, w) in window_widths(&h) {
|
||||
if w < DIALOG_MIN_W - slack {
|
||||
bad.push(format!("{}: {w} px is narrower than {DIALOG_MIN_W}", spec.id));
|
||||
}
|
||||
}
|
||||
}
|
||||
h.app.dialog = None;
|
||||
h.app.params = None;
|
||||
h.app.tool = None;
|
||||
if h.app.session.active_sketch.is_some() {
|
||||
h.app.finish_sketch();
|
||||
}
|
||||
h.frames(2);
|
||||
}
|
||||
assert!(bad.is_empty(), "windows too wide or too narrow:\n{}", bad.join("\n"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn common_dialogs_are_not_stretched() {
|
||||
// Simple dialogs have room to spare: they must not be pushed out to the maximum.
|
||||
let mut h = fresh();
|
||||
for id in ["Extrude", "FusionFilletEdgesCommand", "FusionShellBodyCommand", "FusionMoveCommand", "FusionHoleCommand"] {
|
||||
h.call("ui.start", json!({"command": id}));
|
||||
h.frames(6);
|
||||
let w: f32 = window_widths(&h).iter().map(|x| x.1).fold(0.0, f32::max);
|
||||
assert!(w < DIALOG_MAX_W - 20.0, "{id} is stretched to {w} px");
|
||||
h.app.dialog = None;
|
||||
h.frames(2);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn floating_windows_stay_within_limits() {
|
||||
let mut h = fresh();
|
||||
h.app.prefs_window.open = true;
|
||||
h.app.keymap.open = true;
|
||||
h.app.help.about = true;
|
||||
h.app.ui.palette_open = true;
|
||||
solvecraft_ui_egui::params_dialog::open(&mut h.app);
|
||||
h.frames(6);
|
||||
let ws = window_widths(&h);
|
||||
assert!(ws.len() >= 4, "windows on screen: {ws:?}");
|
||||
for (layer, w) in ws {
|
||||
assert!(w <= WINDOW_WIDE_MAX_W + 4.0, "{layer} is {w} px wide");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user