mirror of
https://github.com/storytold/deckcraft.git
synced 2026-10-24 10:37:03 -06:00
Merge PR #82 from MarekSpodBiedry: Command palette: one Export… entry that opens the dialog, no path-only duplicate (#79)
This commit is contained in:
+39
-11
@@ -71,6 +71,22 @@ pub fn ui_shortcut(app: &mut SlideApp, key: egui::Key, m: Mods) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// The palette's entries for the lowercase query `q`. An engine command is hidden when a UI command has the same label: Open…, Save As…,
|
||||
/// Export… and Audio/Video from File… need a `path` the palette can't give, so the one entry left opens the dialog instead of failing.
|
||||
fn palette_items(session: &deckcraft_engine::Session, q: &str) -> Vec<(String, String, Option<&'static str>)> {
|
||||
let mut items: Vec<(String, String, Option<&'static str>)> = session
|
||||
.commands()
|
||||
.into_iter()
|
||||
.filter(|c| c.enabled && !crate::UI_COMMANDS.iter().any(|u| u.1 == c.label))
|
||||
.map(|c| (c.id.to_string(), c.label.to_string(), c.shortcut))
|
||||
.chain(crate::UI_COMMANDS.iter().map(|c| (c.0.to_string(), c.1.to_string(), c.2)))
|
||||
.filter(|(id, label, _)| q.is_empty() || label.to_lowercase().contains(q) || id.to_lowercase().contains(q))
|
||||
.collect();
|
||||
items.sort_by_key(|(_, l, _)| !l.to_lowercase().starts_with(q));
|
||||
items.truncate(60);
|
||||
items
|
||||
}
|
||||
|
||||
/// ⇧⌘P: search every command by name and run it.
|
||||
pub fn palette(app: &mut SlideApp, ctx: &egui::Context) {
|
||||
let Some((mut query, mut sel)) = app.palette.take() else { return };
|
||||
@@ -85,17 +101,7 @@ pub fn palette(app: &mut SlideApp, ctx: &egui::Context) {
|
||||
let r = ui.add(egui::TextEdit::singleline(&mut query).hint_text("Search commands…").desired_width(f32::INFINITY).font(theme::font(15.0)));
|
||||
r.request_focus();
|
||||
let q = query.to_lowercase();
|
||||
let mut items: Vec<(String, String, Option<&'static str>)> = app
|
||||
.session
|
||||
.commands()
|
||||
.into_iter()
|
||||
.filter(|c| c.enabled)
|
||||
.map(|c| (c.id.to_string(), c.label.to_string(), c.shortcut))
|
||||
.chain(crate::UI_COMMANDS.iter().map(|c| (c.0.to_string(), c.1.to_string(), c.2)))
|
||||
.filter(|(id, label, _)| q.is_empty() || label.to_lowercase().contains(&q) || id.to_lowercase().contains(&q))
|
||||
.collect();
|
||||
items.sort_by_key(|(_, l, _)| !l.to_lowercase().starts_with(&q));
|
||||
items.truncate(60);
|
||||
let items = palette_items(&app.session, &q);
|
||||
let (down, up, enter, esc) = ui.input(|i| {
|
||||
(
|
||||
i.key_pressed(egui::Key::ArrowDown),
|
||||
@@ -265,3 +271,25 @@ pub fn menu_tree() -> Vec<(&'static str, Vec<(&'static str, &'static str)>)> {
|
||||
("Help", vec![("About DeckCraft", "app.about"), ("Command Palette", "app.palette")]),
|
||||
]
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::palette_items;
|
||||
|
||||
/// #79: the palette listed two "Export…" entries and the first (`file.export`) failed with "missing `path`".
|
||||
#[test]
|
||||
fn palette_has_one_export_entry_that_opens_the_dialog() {
|
||||
let session = deckcraft_engine::Session::with_new();
|
||||
for query in ["exp", "export"] {
|
||||
let exports: Vec<_> = palette_items(&session, query).into_iter().filter(|(_, label, _)| label == "Export…").collect();
|
||||
assert_eq!(exports.len(), 1, "query {query}");
|
||||
assert_eq!(exports[0].0, "app.exportDialog");
|
||||
}
|
||||
// Open…, Save As…, Audio/Video from File… and Notes had the same duplicates: every UI command is the only entry with its label.
|
||||
for (id, label, _, _) in crate::UI_COMMANDS {
|
||||
let same: Vec<_> = palette_items(&session, &label.to_lowercase()).into_iter().filter(|(_, l, _)| l == label).collect();
|
||||
assert_eq!(same.len(), 1, "{label}");
|
||||
assert_eq!(same[0].0, *id, "{label}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user