Merge pull request #906 from MarekSpodBiedry/issue-843

This commit is contained in:
Brandon Thomas
2026-10-23 17:09:50 -04:00
2 changed files with 73 additions and 4 deletions
+1
View File
@@ -139,6 +139,7 @@ app's JSON control channel (`deckcraft --control PORT`).
| 2026-10-18 | Slide thumbnails and the Slide Sorter render only the slides in view: on a deck of more than 600 slides they used to evict their own thumbnails, so the pane flashed white and never finished (#969) |
| 2026-10-18 | Resizing with the mouse snaps the edge being dragged to the slide, guides and other shapes: a fixed edge that already lined up used to take the snap and leave the dragged edge free, and a fixed edge near a line shifted the dragged one (#961) |
| 2026-10-18 | Slide show: a video or audio clip is looked up on the slide it belongs to, so slides whose shape ids repeat (the PPTX import numbers each slide afresh) no longer play each other's clips (#994) |
| 2026-10-18 | About: Contributors and Models get their own fixed-size block below the tab row, so the tab row is no longer squeezed into the credits and the tabs keep answering (#843) |
| 2026-10-17 | Opening a file caps absurd effect sizes (glow, soft edges, shadows, reflections, on shapes, text and table text) at what Format Shape allows: a glow of 10^18 pt in a .pptx made rendering ask for 34 GB and abort |
| 2026-10-17 | Opening a .deckcraft file whose shapes repeat an id gives the repeats fresh ids (groups, layouts and masters too), so the deck validates and edits by id find one shape |
| 2026-10-17 | Edit Points: turning a shape into a freeform is one undo step, so Undo brings the original shape back (it used to stay a freeform) |
+72 -4
View File
@@ -122,6 +122,21 @@ pub fn show(app: &mut SlideApp, ctx: &egui::Context) {
}
}
/// Room the About credits need for their table; the About tab keeps its compact size.
const CREDITS_SIZE: egui::Vec2 = vec2(640.0, 380.0);
/// The Contributors / Models body in a block of its own fixed size, below the tab row. Sizing the
/// dialog's `ui` instead (`set_min_size` / `set_max_height`) squeezed the tab row and the first
/// credits row together, so the text was garbled and the tabs stopped answering (#843).
fn credits_block(ui: &mut Ui, models: bool) -> Rect {
ui.allocate_ui(CREDITS_SIZE, |ui| {
ui.set_min_size(CREDITS_SIZE);
if models { crate::credits::models_ui(ui) } else { crate::credits::contributors_ui(ui) }
})
.response
.rect
}
fn buttons(ui: &mut Ui, ok_label: &str) -> (bool, bool) {
let mut ok = false;
let mut cancel = false;
@@ -2091,10 +2106,7 @@ fn body(app: &mut SlideApp, ui: &mut Ui, d: &mut Dialog) -> bool {
ui.separator();
match tab.as_str() {
"contributors" | "models" => {
// The credits need room for the table; the About tab keeps its compact size.
ui.set_min_size(vec2(640.0, 380.0));
ui.set_max_height(380.0);
if tab == "models" { crate::credits::models_ui(ui) } else { crate::credits::contributors_ui(ui) }
credits_block(ui, tab == "models");
}
_ => about(app, ui),
}
@@ -3695,3 +3707,59 @@ mod spelling_tests;
#[cfg(test)]
#[path = "paragraph_dialog_tests.rs"]
mod paragraph_dialog_tests;
#[cfg(test)]
mod about_credits_tests {
use egui_kittest::Harness;
use egui_kittest::kittest::Queryable;
use super::{CREDITS_SIZE, Dialog, credits_block};
use crate::{Services, SlideApp};
fn tab_of(h: &Harness<'_, SlideApp>) -> String {
let d = h.state().dialog.as_ref().expect("the About dialog is open");
d.fields.get("tab").cloned().unwrap_or_else(|| "about".into())
}
/// The reported symptom (#843): in the real dialog the tabs stopped answering once Contributors
/// or Models was open. Click through Contributors, Models and back to About.
#[test]
fn about_dialog_tabs_keep_responding() {
let mut app = SlideApp::new(deckcraft_engine::Session::with_new(), Services::default());
app.dialog = Some(Dialog::new("about"));
let mut h = Harness::builder().with_size(egui::vec2(1440.0, 900.0)).with_step_dt(1.0 / 60.0).build_ui_state(
|ui, app: &mut SlideApp| {
app.logic(ui.ctx());
app.ui(ui);
},
app,
);
h.run_steps(4);
assert_eq!(tab_of(&h), "about");
for label in ["Contributors", "Models", "About", "Models", "Contributors"] {
h.get_by_label(label).click();
h.run_steps(3);
assert_eq!(tab_of(&h), label.to_lowercase(), "clicking {label} switches the tab");
}
}
#[test]
fn credits_get_their_own_block_below_the_tab_row() {
for models in [false, true] {
let ctx = egui::Context::default();
let mut tabs = egui::Rect::NOTHING;
let mut block = egui::Rect::NOTHING;
let mut whole = egui::Rect::NOTHING;
let mut out = ctx.run_ui(egui::RawInput::default(), |ui| {
tabs = ui.label("About").rect;
block = credits_block(ui, models);
whole = ui.min_rect();
});
out.textures_delta.clear();
assert_eq!(block.size(), CREDITS_SIZE, "models={models}");
assert!(block.min.y >= tabs.max.y, "the credits start below the tab row (models={models})");
assert!(whole.max.y >= block.max.y, "the dialog grows to hold the block (models={models})");
assert!(whole.height() > CREDITS_SIZE.y, "the tab row is not squeezed into the credits height (models={models})");
}
}
}