Merge pull request #1853 from storytold/fix/1629-actions-selection
Fix #1629: an action clicked in the Actions panel stays selected, so Play and Delete act on it
This commit is contained in:
commit
0ae6c288ea
|
|
@ -5,6 +5,7 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::{Value, json};
|
use serde_json::{Value, json};
|
||||||
|
|
||||||
|
use super::{pstate, set_pstate};
|
||||||
use crate::theme::Tokens;
|
use crate::theme::Tokens;
|
||||||
use crate::widgets::{self, dim_label};
|
use crate::widgets::{self, dim_label};
|
||||||
use crate::{VectorcraftApp, icons};
|
use crate::{VectorcraftApp, icons};
|
||||||
|
|
@ -52,8 +53,10 @@ pub fn play(app: &mut VectorcraftApp, set: usize, idx: usize) -> Result<Value, S
|
||||||
|
|
||||||
pub fn show(app: &mut VectorcraftApp, ui: &mut egui::Ui) {
|
pub fn show(app: &mut VectorcraftApp, ui: &mut egui::Ui) {
|
||||||
let t = Tokens::get(ui.ctx());
|
let t = Tokens::get(ui.ctx());
|
||||||
let selected_id = egui::Id::new("actions-selected");
|
// The selected action as (set, action). Read as the type it is stored as: egui keeps a
|
||||||
let mut selected: Option<(usize, usize)> = ui.data(|d| d.get_temp(selected_id));
|
// value per type, so reading the bare pair never found it and no action stayed selected (#1629).
|
||||||
|
const SELECTED: &str = "actions-selected";
|
||||||
|
let mut selected: Option<(usize, usize)> = pstate(ui.ctx(), SELECTED);
|
||||||
let mut play_req = None;
|
let mut play_req = None;
|
||||||
egui::ScrollArea::vertical().max_height(260.0).show(ui, |ui| {
|
egui::ScrollArea::vertical().max_height(260.0).show(ui, |ui| {
|
||||||
for (si, set) in app.ui.action_sets.iter().enumerate() {
|
for (si, set) in app.ui.action_sets.iter().enumerate() {
|
||||||
|
|
@ -89,7 +92,7 @@ pub fn show(app: &mut VectorcraftApp, ui: &mut egui::Ui) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ui.data_mut(|d| d.insert_temp(selected_id, selected));
|
set_pstate(ui.ctx(), SELECTED, selected);
|
||||||
widgets::divider(ui);
|
widgets::divider(ui);
|
||||||
// Bottom bar: stop, record, play, new, delete.
|
// Bottom bar: stop, record, play, new, delete.
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
|
|
@ -127,7 +130,7 @@ pub fn show(app: &mut VectorcraftApp, ui: &mut egui::Ui) {
|
||||||
&& ai < s.actions.len()
|
&& ai < s.actions.len()
|
||||||
{
|
{
|
||||||
s.actions.remove(ai);
|
s.actions.remove(ai);
|
||||||
ui.data_mut(|d| d.insert_temp::<Option<(usize, usize)>>(selected_id, None));
|
set_pstate::<Option<(usize, usize)>>(ui.ctx(), SELECTED, None);
|
||||||
}
|
}
|
||||||
if recording {
|
if recording {
|
||||||
ui.label(egui::RichText::new(tl!("● Recording")).color(egui::Color32::from_rgb(0xe0, 0x30, 0x30)));
|
ui.label(egui::RichText::new(tl!("● Recording")).color(egui::Color32::from_rgb(0xe0, 0x30, 0x30)));
|
||||||
|
|
@ -160,6 +163,36 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// #1629: a clicked action stays selected, so Play Current Selection plays it and Delete
|
||||||
|
/// Selection deletes it.
|
||||||
|
#[test]
|
||||||
|
fn a_clicked_action_stays_selected_for_play_and_delete() {
|
||||||
|
use super::super::tests_appearance::{click, frame_events, text_rect};
|
||||||
|
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||||
|
app.run("file.new", json!({"width": 200, "height": 100})).unwrap();
|
||||||
|
let id = app.run("shape.rectangle", json!({"x": 10, "y": 10, "width": 20, "height": 20})).unwrap()["id"].as_u64().unwrap();
|
||||||
|
let id = vectorcraft_doc::NodeId(id);
|
||||||
|
let ctx = egui::Context::default();
|
||||||
|
let texts = frame_events(&ctx, &mut app, vec![], show);
|
||||||
|
click(&ctx, &mut app, text_rect(&texts, "Reflect Horizontal").center(), show);
|
||||||
|
frame_events(&ctx, &mut app, vec![], show);
|
||||||
|
assert_eq!(pstate::<Option<(usize, usize)>>(&ctx, "actions-selected"), Some((0, 5)), "selected on the frames after the click");
|
||||||
|
// The bottom bar's 24-point buttons, left to right: stop, record, play, delete.
|
||||||
|
let mut bar = crate::toolbar::tests::widget_rects(&ctx, egui::vec2(24.0, 24.0));
|
||||||
|
bar.sort_by(|a, b| a.left().total_cmp(&b.left()));
|
||||||
|
let [_, _, play, delete] = bar[..] else { panic!("the bottom bar: {bar:?}") };
|
||||||
|
click(&ctx, &mut app, text_rect(&texts, "Duplicate and Offset 10 pt").center(), show);
|
||||||
|
click(&ctx, &mut app, play.center(), show);
|
||||||
|
assert_eq!(app.session.active().unwrap().selection.len(), 1);
|
||||||
|
assert_ne!(app.session.active().unwrap().selection.objects, [id], "played: the copy is selected");
|
||||||
|
let names = |app: &VectorcraftApp| app.ui.action_sets[0].actions.iter().map(|a| a.name.clone()).collect::<Vec<_>>();
|
||||||
|
let before = names(&app);
|
||||||
|
click(&ctx, &mut app, delete.center(), show);
|
||||||
|
assert_eq!(names(&app), before[1..], "the selected action is deleted");
|
||||||
|
click(&ctx, &mut app, delete.center(), show);
|
||||||
|
assert_eq!(names(&app), before[1..], "nothing selected after a delete: nothing more goes");
|
||||||
|
}
|
||||||
|
|
||||||
/// Actions recorded with Align to Artboard and Paste in Place, and the default Center on
|
/// Actions recorded with Align to Artboard and Paste in Place, and the default Center on
|
||||||
/// Artboard, play on the artboard active when they play, not on the one active when they were
|
/// Artboard, play on the artboard active when they play, not on the one active when they were
|
||||||
/// recorded.
|
/// recorded.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue