Actions: the panel menu reads the selected action only in the current set

The panel menu read the stored (set, action) pair without checking that
its set is still the current one, as the panel and Delete Selection do.
After `ui.actionSet.delete` removed a set above it, the pair pointed at
another set's action, and Action Options…, Batch… and Play Current
Selection acted on that action. They are now off until an action of the
current set is selected.
This commit is contained in:
dotCooCoo
2026-11-02 14:32:51 +07:00
committed by bflatastic
parent 0212c2b00e
commit b2c62c398e
+23 -1
View File
@@ -275,7 +275,9 @@ pub fn duplicate(app: &mut VectorcraftApp, p: &Value) -> Result<Value, String> {
/// The panel's (≡) menu.
pub fn menu(app: &mut VectorcraftApp, ui: &mut egui::Ui) {
let selected: Option<(usize, usize)> = pstate(ui.ctx(), "actions-selected");
// A selected action counts only while its set is the current one, as the panel shows it: a set
// deleted since leaves the stored pair pointing at another set's action.
let selected = pstate::<Option<(usize, usize)>>(ui.ctx(), "actions-selected").filter(|&(s, _)| app.ui.action_set == Some(s));
let has = selected.and_then(|(s, a)| app.ui.action_sets.get(s).and_then(|set| set.actions.get(a))).is_some();
if widgets::menu_item(ui, tl!("New Set…"), true, false) {
crate::dialogs::action_set_options::open_new(app);
@@ -633,6 +635,26 @@ mod tests {
}
}
/// After `ui.actionSet.delete` removes a set above the selected action's set, the panel menu's
/// Action Options… is off: it does not open for the action that moved to the stored position.
#[test]
fn action_options_is_off_after_a_set_above_the_selection_is_deleted() {
use super::super::tests_appearance::{click, frame_events};
let mut app = app_with_sets();
let action = |name: &str| Action { name: name.into(), steps: vec![] };
app.ui.action_sets[2].actions.push(action("Spin"));
app.ui.action_sets.push(ActionSet::new("Last", vec![action("Wrong")]));
let ctx = egui::Context::default();
app.ui.action_set = Some(2);
set_pstate::<Option<(usize, usize)>>(&ctx, "actions-selected", Some((2, 0)));
app.run(DELETE_SETS, json!({"sets": [1]})).unwrap();
assert_eq!(app.ui.action_set, Some(1), "Other is still current");
let texts = frame_events(&ctx, &mut app, vec![], menu);
let item = texts.iter().find(|(s, _)| s.trim() == "Action Options…").map(|(_, r)| *r).expect("Action Options… in the menu");
click(&ctx, &mut app, item.center(), menu);
assert!(app.ui.dialog.is_none(), "Action Options… does not open for Last's action");
}
/// An app with the default set and the sets Mine (two actions) and Other.
fn app_with_sets() -> VectorcraftApp {
let mut app = VectorcraftApp::new(Session::new(), Default::default());