mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-29 12:37:08 -06:00
Keyboard Shortcuts: keep the OK button in view [skip ci]
The editor's content was a little taller than its dialog, so the outer scroll area clipped the OK button and its scrollbar covered the right edge. The dialog now has no outer scroll area: the command list takes whatever height is left, so the button row always fits, in small windows too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
470ea7a3af
commit
07fe9cb1dc
@@ -237,7 +237,9 @@ pub fn show(app: &mut EffectcraftApp, ctx: &egui::Context, t: &Tokens) {
|
||||
}
|
||||
}
|
||||
|
||||
super::dialogs::modal(ctx, "Keyboard Shortcuts", vec2(1000.0, 720.0), t, |ui| {
|
||||
// No outer scroll area: the command list takes the height left over, so OK stays in view.
|
||||
super::dialogs::modal_fit(ctx, "Keyboard Shortcuts", vec2(1000.0, 760.0), t, |ui, height| {
|
||||
let top = ui.cursor().top();
|
||||
// ---- preset bar
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(tr("Preset:"));
|
||||
@@ -437,42 +439,49 @@ pub fn show(app: &mut EffectcraftApp, ctx: &egui::Context, t: &Tokens) {
|
||||
q.split_whitespace().all(|w| hay.contains(w))
|
||||
})
|
||||
.collect();
|
||||
ui.allocate_ui_with_layout(vec2(ui.available_width(), 270.0), egui::Layout::left_to_right(egui::Align::Min), |ui| {
|
||||
ui.set_height(270.0);
|
||||
let footer = 6.0 + ui.spacing().interact_size.y + ui.spacing().item_spacing.y * 2.0;
|
||||
let list_h = (height - (ui.cursor().top() - top) - footer).max(140.0);
|
||||
ui.allocate_ui_with_layout(vec2(ui.available_width(), list_h), egui::Layout::left_to_right(egui::Align::Min), |ui| {
|
||||
ui.set_height(list_h);
|
||||
// Command list.
|
||||
ui.vertical(|ui| {
|
||||
ui.set_width(620.0);
|
||||
let row_h = 20.0;
|
||||
egui::ScrollArea::vertical().id_salt("sc-rows").max_height(230.0).auto_shrink([false, false]).show_rows(ui, row_h, rows.len(), |ui, range| {
|
||||
for i in range {
|
||||
let b = rows[i];
|
||||
let keys = table.keys.get(&b.key).cloned().unwrap_or_default();
|
||||
let (r, resp) = ui.allocate_exact_size(vec2(ui.available_width(), row_h), Sense::click());
|
||||
let sel = st.selected.as_deref() == Some(b.key.as_str());
|
||||
if sel {
|
||||
ui.painter().rect_filled(r, 0.0, t.row_selected);
|
||||
} else if i % 2 == 1 {
|
||||
ui.painter().rect_filled(r, 0.0, t.row_alt);
|
||||
egui::ScrollArea::vertical().id_salt("sc-rows").max_height(list_h - 40.0).auto_shrink([false, false]).show_rows(
|
||||
ui,
|
||||
row_h,
|
||||
rows.len(),
|
||||
|ui, range| {
|
||||
for i in range {
|
||||
let b = rows[i];
|
||||
let keys = table.keys.get(&b.key).cloned().unwrap_or_default();
|
||||
let (r, resp) = ui.allocate_exact_size(vec2(ui.available_width(), row_h), Sense::click());
|
||||
let sel = st.selected.as_deref() == Some(b.key.as_str());
|
||||
if sel {
|
||||
ui.painter().rect_filled(r, 0.0, t.row_selected);
|
||||
} else if i % 2 == 1 {
|
||||
ui.painter().rect_filled(r, 0.0, t.row_alt);
|
||||
}
|
||||
let pp = ui.painter();
|
||||
pp.text(pos2(r.min.x + 6.0, r.center().y), Align2::LEFT_CENTER, &b.label, Tokens::ui(11.5), t.text);
|
||||
pp.text(pos2(r.min.x + 230.0, r.center().y), Align2::LEFT_CENTER, b.path.join(" > "), Tokens::ui(10.5), t.text_faint);
|
||||
let ks: Vec<String> = keys.iter().map(|k| crate::menus::shortcut_text(k)).collect();
|
||||
let col = if b.scope == APP_SCOPE { APP_COLOR } else { PANEL_COLOR };
|
||||
pp.text(
|
||||
pos2(r.max.x - 8.0, r.center().y),
|
||||
Align2::RIGHT_CENTER,
|
||||
ks.join(", "),
|
||||
Tokens::ui(11.5),
|
||||
if keys.is_empty() { t.text_faint } else { col },
|
||||
);
|
||||
app.auto.add(&format!("shortcuts.row.{i}"), r, &b.label);
|
||||
if resp.clicked() {
|
||||
st.selected = Some(b.key.clone());
|
||||
st.pending.clear();
|
||||
}
|
||||
}
|
||||
let pp = ui.painter();
|
||||
pp.text(pos2(r.min.x + 6.0, r.center().y), Align2::LEFT_CENTER, &b.label, Tokens::ui(11.5), t.text);
|
||||
pp.text(pos2(r.min.x + 230.0, r.center().y), Align2::LEFT_CENTER, b.path.join(" > "), Tokens::ui(10.5), t.text_faint);
|
||||
let ks: Vec<String> = keys.iter().map(|k| crate::menus::shortcut_text(k)).collect();
|
||||
let col = if b.scope == APP_SCOPE { APP_COLOR } else { PANEL_COLOR };
|
||||
pp.text(
|
||||
pos2(r.max.x - 8.0, r.center().y),
|
||||
Align2::RIGHT_CENTER,
|
||||
ks.join(", "),
|
||||
Tokens::ui(11.5),
|
||||
if keys.is_empty() { t.text_faint } else { col },
|
||||
);
|
||||
app.auto.add(&format!("shortcuts.row.{i}"), r, &b.label);
|
||||
if resp.clicked() {
|
||||
st.selected = Some(b.key.clone());
|
||||
st.pending.clear();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
ui.label(RichText::new(format!("{} of {} commands", rows.len(), table.bindables.len())).color(t.text_faint));
|
||||
});
|
||||
ui.separator();
|
||||
@@ -603,6 +612,25 @@ mod tests {
|
||||
out.textures_delta.clear();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_ok_button_stays_inside_the_dialog_in_a_small_window() {
|
||||
let mut app = EffectcraftApp::new(effectcraft_engine::Session::default());
|
||||
let ctx = egui::Context::default();
|
||||
crate::theme::install(&ctx, &app.tokens, crate::i18n::language(&app));
|
||||
open(&mut app);
|
||||
for size in [vec2(1680.0, 1020.0), vec2(1280.0, 720.0)] {
|
||||
for _ in 0..3 {
|
||||
app.auto.begin_frame();
|
||||
let input = egui::RawInput { screen_rect: Some(Rect::from_min_size(pos2(0.0, 0.0), size)), ..Default::default() };
|
||||
let mut out = ctx.run_ui(input, |ui| crate::panels::dialogs::show(&mut app, ui.ctx()));
|
||||
out.textures_delta.clear();
|
||||
}
|
||||
let [_, y, _, h] = app.auto.find("shortcuts.close").expect("OK button").rect;
|
||||
// The window less the modal's margin and its frame padding.
|
||||
assert!(y + h <= size.y - 24.0 - 18.0 + 0.5, "OK ends at {} in a {size:?} window", y + h);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recording_a_shortcut_does_not_also_type_the_key_into_the_field() {
|
||||
let mut app = EffectcraftApp::new(effectcraft_engine::Session::default());
|
||||
|
||||
Reference in New Issue
Block a user