mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-08 11:52:10 +00:00
Actions: Playback Options plays actions accelerated, step by step or with a pause between steps
The Actions panel menu's Playback Options... sets how actions play (ui.action.playbackOptions {speed?, seconds?}). Accelerated, the default, plays every step at once as one undo step, as before. Step by Step plays one step per frame so the canvas draws each step's result, and Pause For waits 1 to 60 seconds between steps; each paced step is its own undo step. Stop Playing/Recording ends a paced playback, and another action does not play while one is paced. The setting is kept with the UI preferences. Batch... plays at full speed.
This commit is contained in:
@@ -348,6 +348,10 @@ impl VectorcraftApp {
|
||||
// The timer and heartbeat run in an idle window too.
|
||||
ctx.request_repaint_after(std::time::Duration::from_secs_f64(wait));
|
||||
}
|
||||
// An action playing at Step by Step or Pause For runs its next step when it is due.
|
||||
if let Some(wait) = crate::panels::actions::tick_playback(self, now) {
|
||||
ctx.request_repaint_after(std::time::Duration::from_secs_f64(wait));
|
||||
}
|
||||
crate::keymap::note_os(ctx);
|
||||
shortcut_editor::sync(&self.ui);
|
||||
crate::panels::actions::sync_function_keys(&self.ui);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
mod about;
|
||||
pub mod action_batch;
|
||||
pub mod action_new;
|
||||
pub mod action_playback;
|
||||
pub mod action_set_options;
|
||||
pub mod artboard_options;
|
||||
pub mod blend_options;
|
||||
@@ -365,6 +366,7 @@ registry! {
|
||||
ActionBatch: [action_batch::KIND] => action_batch::SPEC,
|
||||
ActionSetOptions: [action_set_options::KIND] => action_set_options::SPEC,
|
||||
ActionNew: [action_new::KIND] => action_new::SPEC,
|
||||
ActionPlayback: [action_playback::KIND] => action_playback::SPEC,
|
||||
SliceOptions: [slices::OPTIONS] => slices::OPTIONS_SPEC,
|
||||
DivideSlices: [slices::DIVIDE] => slices::DIVIDE_SPEC,
|
||||
EpsOptions: [eps_options::KIND] => eps_options::SPEC,
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
//! Actions panel menu › Playback Options…: the speed actions play at (`ui.action.playbackOptions`).
|
||||
//!
|
||||
//! Fields: `speed` (`accelerated`, `step` or `pause`) and `seconds`, the pause between steps with
|
||||
//! `pause`. OK sets them; an invalid value is an error, and the dialog stays open.
|
||||
|
||||
use serde_json::{Value, json};
|
||||
|
||||
use super::DialogSpec;
|
||||
use crate::state::Dialog;
|
||||
use crate::{VectorcraftApp, widgets};
|
||||
|
||||
/// The dialog kind of Playback Options.
|
||||
pub const KIND: &str = "actionPlayback";
|
||||
|
||||
pub(super) const SPEC: DialogSpec = DialogSpec { heading: |_| tl!("Playback Options").into(), body, confirm, min_width: 260.0, ..DialogSpec::FORM };
|
||||
|
||||
/// Open Playback Options with the speed and pause actions play with now.
|
||||
pub fn open(app: &mut VectorcraftApp) {
|
||||
let o = app.ui.action_playback;
|
||||
app.ui.dialog = Some(Dialog::new(KIND, json!({"speed": o.speed, "seconds": o.seconds})));
|
||||
}
|
||||
|
||||
fn body(_app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
|
||||
let speed = d.str("speed");
|
||||
for (value, label) in [("accelerated", tl!("Accelerated")), ("step", tl!("Step by Step"))] {
|
||||
if widgets::radio(ui, label, speed == value, true) {
|
||||
d.fields.insert("speed".into(), json!(value));
|
||||
}
|
||||
}
|
||||
ui.horizontal(|ui| {
|
||||
let pause = tl!("Pause For");
|
||||
if widgets::radio(ui, pause, speed == "pause", true) {
|
||||
d.fields.insert("speed".into(), json!("pause"));
|
||||
}
|
||||
let range = f64::from(*crate::panels::actions::PAUSE_SECONDS.start())..=f64::from(*crate::panels::actions::PAUSE_SECONDS.end());
|
||||
if let Some(n) = widgets::range_field_named(ui, "action-pause-seconds", Some(pause), d.f64("seconds", *range.start()), range, "s", 0, 50.0) {
|
||||
d.fields.insert("seconds".into(), json!(n as u64));
|
||||
}
|
||||
});
|
||||
false
|
||||
}
|
||||
|
||||
fn confirm(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
|
||||
let params = json!({"speed": d.str("speed"), "seconds": d.fields.get("seconds").cloned().unwrap_or(Value::Null)});
|
||||
let r = app.run(crate::panels::actions::PLAYBACK_OPTIONS, params)?;
|
||||
app.ui.dialog = None;
|
||||
Ok(r)
|
||||
}
|
||||
@@ -5502,6 +5502,9 @@ theme Appearance Външен вид
|
||||
Movie Clip Филмов клип
|
||||
@msg name is empty името е празно
|
||||
@msg an action is already recording вече се записва действие
|
||||
@msg an action is already playing вече се възпроизвежда действие
|
||||
@msg speed must be accelerated, step or pause speed трябва да е accelerated, step или pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds трябва да е цяло число от 1 до 60
|
||||
@msg no such function key няма такъв функционален клавиш
|
||||
@msg no such color няма такъв цвят
|
||||
@msg {_1} cannot be used on Windows {_1} не може да се използва в Windows
|
||||
@@ -5652,6 +5655,11 @@ axis Y Axis Y ос
|
||||
Set Options Опции на набора
|
||||
Action Options… Опции на действието…
|
||||
Action Options Опции на действието
|
||||
Playback Options… Опции за възпроизвеждане…
|
||||
Playback Options Опции за възпроизвеждане
|
||||
Accelerated Ускорено
|
||||
Step by Step Стъпка по стъпка
|
||||
Pause For Пауза за
|
||||
Rename Action Преименуване на действие
|
||||
New Action… Ново действие…
|
||||
New Action Ново действие
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5506,6 +5506,9 @@ mark-style Japanese Japanski
|
||||
Movie Clip Filmski klip
|
||||
@msg name is empty naziv je prazan
|
||||
@msg an action is already recording akcija se već snima
|
||||
@msg an action is already playing akcija se već reproducira
|
||||
@msg speed must be accelerated, step or pause speed mora biti accelerated, step ili pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds mora biti cijeli broj od 1 do 60
|
||||
@msg no such function key nema takve funkcijske tipke
|
||||
@msg no such color nema takve boje
|
||||
@msg {_1} cannot be used on Windows {_1} se ne može koristiti na Windowsu
|
||||
@@ -5675,6 +5678,11 @@ axis Y Axis Y osa
|
||||
Set Options Opcije skupa
|
||||
Action Options… Opcije akcije…
|
||||
Action Options Opcije akcije
|
||||
Playback Options… Opcije reprodukcije…
|
||||
Playback Options Opcije reprodukcije
|
||||
Accelerated Ubrzano
|
||||
Step by Step Korak po korak
|
||||
Pause For Pauza od
|
||||
Rename Action Preimenuj akciju
|
||||
New Action… Nova akcija…
|
||||
New Action Nova akcija
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3791,6 +3791,11 @@ digits Malayalam Malaiàlam
|
||||
Set Options Defineix les opcions
|
||||
Action Options… Opcions de l’acció…
|
||||
Action Options Opcions de l’acció
|
||||
Playback Options… Opcions de reproducció…
|
||||
Playback Options Opcions de reproducció
|
||||
Accelerated Accelerada
|
||||
Step by Step Pas a pas
|
||||
Pause For Pausa de
|
||||
Rename Action Canvia el nom de l’acció
|
||||
New Action… Acció nova…
|
||||
New Action Acció nova
|
||||
@@ -5187,6 +5192,9 @@ digits Malayalam Malaiàlam
|
||||
@msg Multichannel PSD files can't be read: save it in RGB, CMYK or Grayscale mode Els fitxers PSD multicanal no es poden llegir: deseu-los en mode RGB, CMYK o escala de grisos
|
||||
@msg name is empty el nom és buit
|
||||
@msg an action is already recording ja s’està enregistrant una acció
|
||||
@msg an action is already playing ja s’està reproduint una acció
|
||||
@msg speed must be accelerated, step or pause speed ha de ser accelerated, step o pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds ha de ser un nombre enter de l’1 al 60
|
||||
@msg no such function key no existeix aquesta tecla de funció
|
||||
@msg no such color no existeix aquest color
|
||||
@msg {_1} cannot be used on Windows {_1} no es pot fer servir al Windows
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5592,6 +5592,9 @@ mark-style Japanese Japonské
|
||||
Movie Clip Filmový klip
|
||||
@msg name is empty název je prázdný
|
||||
@msg an action is already recording akce se už zaznamenává
|
||||
@msg an action is already playing akce se už přehrává
|
||||
@msg speed must be accelerated, step or pause speed musí být accelerated, step nebo pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds musí být celé číslo od 1 do 60
|
||||
@msg no such function key taková funkční klávesa neexistuje
|
||||
@msg no such color taková barva neexistuje
|
||||
@msg {_1} cannot be used on Windows Zkratku {_1} nelze ve Windows použít
|
||||
@@ -5766,6 +5769,11 @@ axis Y Axis osa Y
|
||||
Set Options Možnosti sady
|
||||
Action Options… Možnosti akce…
|
||||
Action Options Možnosti akce
|
||||
Playback Options… Možnosti přehrávání…
|
||||
Playback Options Možnosti přehrávání
|
||||
Accelerated Zrychleně
|
||||
Step by Step Krok za krokem
|
||||
Pause For Pozastavit na
|
||||
Rename Action Přejmenovat akci
|
||||
New Action… Nová akce…
|
||||
New Action Nová akce
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5387,6 +5387,9 @@ swatch Bright Violet Kraftig violet
|
||||
Movie Clip Filmklip
|
||||
@msg name is empty navnet er tomt
|
||||
@msg an action is already recording en handling optages allerede
|
||||
@msg an action is already playing en handling afspilles allerede
|
||||
@msg speed must be accelerated, step or pause speed skal være accelerated, step eller pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds skal være et heltal fra 1 til 60
|
||||
@msg no such function key ingen sådan funktionstast
|
||||
@msg no such color ingen sådan farve
|
||||
@msg {_1} cannot be used on Windows {_1} kan ikke bruges i Windows
|
||||
@@ -5669,6 +5672,11 @@ axis Y Axis Y-akse
|
||||
Set Options Indstillinger for sæt
|
||||
Action Options… Indstillinger for handling…
|
||||
Action Options Indstillinger for handling
|
||||
Playback Options… Afspilningsindstillinger…
|
||||
Playback Options Afspilningsindstillinger
|
||||
Accelerated Accelereret
|
||||
Step by Step Trin for trin
|
||||
Pause For Pause på
|
||||
Rename Action Omdøb handling
|
||||
New Action… Ny handling…
|
||||
New Action Ny handling
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5170,6 +5170,9 @@ effect Soft Weich
|
||||
Movie Clip Movieclip
|
||||
@msg name is empty Name ist leer
|
||||
@msg an action is already recording eine Aktion wird bereits aufgezeichnet
|
||||
@msg an action is already playing eine Aktion wird bereits abgespielt
|
||||
@msg speed must be accelerated, step or pause speed muss accelerated, step oder pause sein
|
||||
@msg seconds must be a whole number from 1 to 60 seconds muss eine ganze Zahl von 1 bis 60 sein
|
||||
@msg no such function key keine solche Funktionstaste
|
||||
@msg no such color keine solche Farbe
|
||||
@msg {_1} cannot be used on Windows {_1} kann unter Windows nicht verwendet werden
|
||||
@@ -5348,6 +5351,11 @@ axis Y Axis Y-Achse
|
||||
Set Options Satzoptionen
|
||||
Action Options… Aktionsoptionen…
|
||||
Action Options Aktionsoptionen
|
||||
Playback Options… Wiedergabeoptionen…
|
||||
Playback Options Wiedergabeoptionen
|
||||
Accelerated Beschleunigt
|
||||
Step by Step Schrittweise
|
||||
Pause For Pause von
|
||||
Rename Action Aktion umbenennen
|
||||
New Action… Neue Aktion…
|
||||
New Action Neue Aktion
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5543,6 +5543,9 @@ effect Points Σημεία
|
||||
Movie Clip Κλιπ ταινίας
|
||||
@msg name is empty το όνομα είναι κενό
|
||||
@msg an action is already recording μια ενέργεια καταγράφεται ήδη
|
||||
@msg an action is already playing μια ενέργεια αναπαράγεται ήδη
|
||||
@msg speed must be accelerated, step or pause το speed πρέπει να είναι accelerated, step ή pause
|
||||
@msg seconds must be a whole number from 1 to 60 το seconds πρέπει να είναι ακέραιος από 1 έως 60
|
||||
@msg no such function key δεν υπάρχει τέτοιο πλήκτρο λειτουργίας
|
||||
@msg no such color δεν υπάρχει τέτοιο χρώμα
|
||||
@msg {_1} cannot be used on Windows Το {_1} δεν μπορεί να χρησιμοποιηθεί στα Windows
|
||||
@@ -5717,6 +5720,11 @@ axis Y Axis Άξονας Y
|
||||
Set Options Επιλογές συνόλου
|
||||
Action Options… Επιλογές ενέργειας…
|
||||
Action Options Επιλογές ενέργειας
|
||||
Playback Options… Επιλογές αναπαραγωγής…
|
||||
Playback Options Επιλογές αναπαραγωγής
|
||||
Accelerated Επιταχυμένα
|
||||
Step by Step Βήμα προς βήμα
|
||||
Pause For Παύση για
|
||||
Rename Action Μετονομασία ενέργειας
|
||||
New Action… Νέα ενέργεια…
|
||||
New Action Νέα ενέργεια
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 163 and column 5.
|
@@ -5533,6 +5533,9 @@ mark-style Japanese Japonesas
|
||||
Movie Clip Clip de película
|
||||
@msg name is empty el nombre está vacío
|
||||
@msg an action is already recording ya se está grabando una acción
|
||||
@msg an action is already playing ya se está reproduciendo una acción
|
||||
@msg speed must be accelerated, step or pause speed debe ser accelerated, step o pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds debe ser un número entero de 1 a 60
|
||||
@msg no such function key no existe esa tecla de función
|
||||
@msg no such color no existe ese color
|
||||
@msg {_1} cannot be used on Windows {_1} no se puede usar en Windows
|
||||
@@ -5707,6 +5710,11 @@ axis Y Axis Eje Y
|
||||
Set Options Opciones de conjunto
|
||||
Action Options… Opciones de acción…
|
||||
Action Options Opciones de acción
|
||||
Playback Options… Opciones de reproducción…
|
||||
Playback Options Opciones de reproducción
|
||||
Accelerated Acelerada
|
||||
Step by Step Paso a paso
|
||||
Pause For Pausa de
|
||||
Rename Action Cambiar nombre de acción
|
||||
New Action… Nueva acción…
|
||||
New Action Nueva acción
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5555,6 +5555,9 @@ mark-style Japanese Japanilainen
|
||||
Movie Clip Elokuvaleike
|
||||
@msg name is empty nimi on tyhjä
|
||||
@msg an action is already recording toimintoa nauhoitetaan jo
|
||||
@msg an action is already playing toimintoa toistetaan jo
|
||||
@msg speed must be accelerated, step or pause speed on oltava accelerated, step tai pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds on oltava kokonaisluku 1:stä 60:een
|
||||
@msg no such function key toimintonäppäintä ei ole
|
||||
@msg no such color väriä ei ole
|
||||
@msg {_1} cannot be used on Windows {_1} ei ole käytettävissä Windowsissa
|
||||
@@ -5796,6 +5799,11 @@ axis Y Axis Y-akseli
|
||||
Set Options Sarjan asetukset
|
||||
Action Options… Toiminnon asetukset…
|
||||
Action Options Toiminnon asetukset
|
||||
Playback Options… Toistoasetukset…
|
||||
Playback Options Toistoasetukset
|
||||
Accelerated Nopeutettu
|
||||
Step by Step Vaihe kerrallaan
|
||||
Pause For Tauko
|
||||
Rename Action Nimeä toiminto uudelleen
|
||||
New Action… Uusi toiminto…
|
||||
New Action Uusi toiminto
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5587,6 +5587,9 @@ theme Appearance Apparence
|
||||
Movie Clip Clip
|
||||
@msg name is empty le nom est vide
|
||||
@msg an action is already recording un script est déjà en cours d’enregistrement
|
||||
@msg an action is already playing un script est déjà en cours d’exécution
|
||||
@msg speed must be accelerated, step or pause speed doit valoir accelerated, step ou pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds doit être un nombre entier de 1 à 60
|
||||
@msg no such function key touche de fonction inexistante
|
||||
@msg no such color couleur inexistante
|
||||
@msg {_1} cannot be used on Windows {_1} ne peut pas être utilisé sous Windows
|
||||
@@ -5761,6 +5764,11 @@ axis Y Axis Axe Y
|
||||
Set Options Options du jeu
|
||||
Action Options… Options de script…
|
||||
Action Options Options de script
|
||||
Playback Options… Options d’exécution…
|
||||
Playback Options Options d’exécution
|
||||
Accelerated Accélérée
|
||||
Step by Step Pas à pas
|
||||
Pause For Pause de
|
||||
Rename Action Renommer le script
|
||||
New Action… Nouveau script…
|
||||
New Action Nouveau script
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5575,6 +5575,9 @@ imageTrace Outline Körvonal
|
||||
Movie Clip Mozgóklip
|
||||
@msg name is empty a név üres
|
||||
@msg an action is already recording már folyik egy művelet felvétele
|
||||
@msg an action is already playing már folyik egy művelet lejátszása
|
||||
@msg speed must be accelerated, step or pause a speed értéke accelerated, step vagy pause lehet
|
||||
@msg seconds must be a whole number from 1 to 60 a seconds értéke 1 és 60 közötti egész szám lehet
|
||||
@msg no such function key nincs ilyen funkcióbillentyű
|
||||
@msg no such color nincs ilyen szín
|
||||
@msg {_1} cannot be used on Windows A(z) {_1} nem használható Windows rendszeren
|
||||
@@ -5749,6 +5752,11 @@ axis Y Axis Y tengely
|
||||
Set Options Készlet beállításai
|
||||
Action Options… Művelet beállításai…
|
||||
Action Options Művelet beállításai
|
||||
Playback Options… Lejátszási beállítások…
|
||||
Playback Options Lejátszási beállítások
|
||||
Accelerated Gyorsított
|
||||
Step by Step Lépésenként
|
||||
Pause For Szünet
|
||||
Rename Action Művelet átnevezése
|
||||
New Action… Új művelet…
|
||||
New Action Új művelet
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5387,6 +5387,9 @@ swatch Bright Violet Violet cerah
|
||||
Movie Clip Klip film
|
||||
@msg name is empty nama kosong
|
||||
@msg an action is already recording sebuah tindakan sedang direkam
|
||||
@msg an action is already playing sebuah tindakan sedang diputar
|
||||
@msg speed must be accelerated, step or pause speed harus accelerated, step, atau pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds harus bilangan bulat dari 1 sampai 60
|
||||
@msg no such function key tidak ada tombol fungsi seperti itu
|
||||
@msg no such color tidak ada warna seperti itu
|
||||
@msg {_1} cannot be used on Windows {_1} tidak dapat digunakan di Windows
|
||||
@@ -5669,6 +5672,11 @@ axis Y Axis Sumbu Y
|
||||
Set Options Opsi set
|
||||
Action Options… Opsi tindakan…
|
||||
Action Options Opsi tindakan
|
||||
Playback Options… Opsi pemutaran…
|
||||
Playback Options Opsi pemutaran
|
||||
Accelerated Dipercepat
|
||||
Step by Step Langkah demi langkah
|
||||
Pause For Jeda selama
|
||||
Rename Action Ganti nama tindakan
|
||||
New Action… Tindakan baru…
|
||||
New Action Tindakan baru
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2230 and column 5.
|
@@ -5205,6 +5205,9 @@ lighting Light Luce
|
||||
Movie Clip Clip filmato
|
||||
@msg name is empty il nome è vuoto
|
||||
@msg an action is already recording è già in corso la registrazione di un’azione
|
||||
@msg an action is already playing è già in corso la riproduzione di un’azione
|
||||
@msg speed must be accelerated, step or pause speed deve essere accelerated, step o pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds deve essere un numero intero da 1 a 60
|
||||
@msg no such function key tasto funzione inesistente
|
||||
@msg no such color colore inesistente
|
||||
@msg {_1} cannot be used on Windows {_1} non può essere usato su Windows
|
||||
@@ -5382,6 +5385,11 @@ axis Y Axis Asse Y
|
||||
Set Options Opzioni set
|
||||
Action Options… Opzioni azione…
|
||||
Action Options Opzioni azione
|
||||
Playback Options… Opzioni di riproduzione…
|
||||
Playback Options Opzioni di riproduzione
|
||||
Accelerated Accelerata
|
||||
Step by Step Passo per passo
|
||||
Pause For Pausa di
|
||||
Rename Action Rinomina azione
|
||||
New Action… Nuova azione…
|
||||
New Action Nuova azione
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5248,6 +5248,9 @@ lighting Light ライト
|
||||
Movie Clip ムービークリップ
|
||||
@msg name is empty 名前が空です
|
||||
@msg an action is already recording すでにアクションを記録中です
|
||||
@msg an action is already playing すでにアクションを再生中です
|
||||
@msg speed must be accelerated, step or pause speed には accelerated、step または pause を指定してください
|
||||
@msg seconds must be a whole number from 1 to 60 seconds には 1 から 60 までの整数を指定してください
|
||||
@msg no such function key 指定されたファンクションキーが見つかりません
|
||||
@msg no such color 指定されたカラーが見つかりません
|
||||
@msg {_1} cannot be used on Windows {_1} は Windows では使用できません
|
||||
@@ -5447,6 +5450,11 @@ axis Y Axis Y 軸
|
||||
Set Options セットオプション
|
||||
Action Options… アクションオプション…
|
||||
Action Options アクションオプション
|
||||
Playback Options… 再生オプション…
|
||||
Playback Options 再生オプション
|
||||
Accelerated 高速
|
||||
Step by Step ステップ実行
|
||||
Pause For 一時停止
|
||||
Rename Action アクション名を変更
|
||||
New Action… 新規アクション…
|
||||
New Action 新規アクション
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5300,6 +5300,9 @@ imageTrace Outline კონტური
|
||||
Movie Clip ანიმაციური კლიპი
|
||||
@msg name is empty სახელი ცარიელია
|
||||
@msg an action is already recording მოქმედება უკვე იწერება
|
||||
@msg an action is already playing მოქმედება უკვე სრულდება
|
||||
@msg speed must be accelerated, step or pause speed უნდა იყოს accelerated, step ან pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds უნდა იყოს მთელი რიცხვი 1-დან 60-მდე
|
||||
@msg no such function key ასეთი ფუნქციური კლავიში არ არის
|
||||
@msg no such color ასეთი ფერი არ არის
|
||||
@msg {_1} cannot be used on Windows {_1} ვერ გამოიყენება Windows-ში
|
||||
@@ -5688,6 +5691,11 @@ axis Y Axis Y ღერძი
|
||||
Set Options ნაკრების პარამეტრები
|
||||
Action Options… მოქმედების პარამეტრები…
|
||||
Action Options მოქმედების პარამეტრები
|
||||
Playback Options… შესრულების პარამეტრები…
|
||||
Playback Options შესრულების პარამეტრები
|
||||
Accelerated დაჩქარებული
|
||||
Step by Step ნაბიჯ-ნაბიჯ
|
||||
Pause For პაუზა
|
||||
Rename Action მოქმედების სახელის შეცვლა
|
||||
New Action… ახალი მოქმედება…
|
||||
New Action ახალი მოქმედება
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -5166,6 +5166,9 @@ lighting Light 광원
|
||||
Movie Clip 무비 클립
|
||||
@msg name is empty 이름이 비어 있습니다
|
||||
@msg an action is already recording 이미 액션을 기록하고 있습니다
|
||||
@msg an action is already playing 이미 액션을 재생하고 있습니다
|
||||
@msg speed must be accelerated, step or pause speed는 accelerated, step 또는 pause여야 합니다
|
||||
@msg seconds must be a whole number from 1 to 60 seconds는 1에서 60 사이의 정수여야 합니다
|
||||
@msg no such function key 해당 기능 키가 없습니다
|
||||
@msg no such color 해당 색상이 없습니다
|
||||
@msg {_1} cannot be used on Windows {_1}은(는) Windows에서 사용할 수 없습니다
|
||||
@@ -5343,6 +5346,11 @@ axis Y Axis Y축
|
||||
Set Options 세트 옵션
|
||||
Action Options… 액션 옵션…
|
||||
Action Options 액션 옵션
|
||||
Playback Options… 재생 옵션…
|
||||
Playback Options 재생 옵션
|
||||
Accelerated 가속
|
||||
Step by Step 단계별
|
||||
Pause For 일시 정지
|
||||
Rename Action 액션 이름 바꾸기
|
||||
New Action… 새 액션…
|
||||
New Action 새 액션
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5395,6 +5395,9 @@ swatch Bright Violet Felviolet
|
||||
Movie Clip Filmclip
|
||||
@msg name is empty naam is leeg
|
||||
@msg an action is already recording er wordt al een actie opgenomen
|
||||
@msg an action is already playing er wordt al een actie afgespeeld
|
||||
@msg speed must be accelerated, step or pause speed moet accelerated, step of pause zijn
|
||||
@msg seconds must be a whole number from 1 to 60 seconds moet een geheel getal van 1 tot 60 zijn
|
||||
@msg no such function key functietoets bestaat niet
|
||||
@msg no such color kleur bestaat niet
|
||||
@msg {_1} cannot be used on Windows {_1} kan niet worden gebruikt in Windows
|
||||
@@ -5713,6 +5716,11 @@ axis Y Axis Y-as
|
||||
Set Options Setopties
|
||||
Action Options… Actieopties…
|
||||
Action Options Actieopties
|
||||
Playback Options… Afspeelopties…
|
||||
Playback Options Afspeelopties
|
||||
Accelerated Versneld
|
||||
Step by Step Stap voor stap
|
||||
Pause For Pauzeren
|
||||
Rename Action Actie hernoemen
|
||||
New Action… Nieuwe actie…
|
||||
New Action Nieuwe actie
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5445,6 +5445,9 @@ mark-style Japanese Japońskie
|
||||
Movie Clip Klip filmowy
|
||||
@msg name is empty nazwa jest pusta
|
||||
@msg an action is already recording operacja jest już nagrywana
|
||||
@msg an action is already playing operacja jest już odtwarzana
|
||||
@msg speed must be accelerated, step or pause speed musi mieć wartość accelerated, step lub pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds musi być liczbą całkowitą od 1 do 60
|
||||
@msg no such function key brak takiego klawisza funkcyjnego
|
||||
@msg no such color brak takiego koloru
|
||||
@msg {_1} cannot be used on Windows Skrótu {_1} nie można używać w systemie Windows
|
||||
@@ -5619,6 +5622,11 @@ axis Y Axis Oś Y
|
||||
Set Options Opcje zestawu
|
||||
Action Options… Opcje operacji…
|
||||
Action Options Opcje operacji
|
||||
Playback Options… Opcje odtwarzania…
|
||||
Playback Options Opcje odtwarzania
|
||||
Accelerated Przyspieszone
|
||||
Step by Step Krok po kroku
|
||||
Pause For Pauza
|
||||
Rename Action Zmień nazwę operacji
|
||||
New Action… Nowa operacja…
|
||||
New Action Nowa operacja
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5507,6 +5507,9 @@ mark-style Japanese Japonesas
|
||||
# Symbol Options › Export Type
|
||||
@msg name is empty o nome está vazio
|
||||
@msg an action is already recording uma ação já está sendo gravada
|
||||
@msg an action is already playing uma ação já está sendo reproduzida
|
||||
@msg speed must be accelerated, step or pause speed deve ser accelerated, step ou pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds deve ser um número inteiro de 1 a 60
|
||||
@msg no such function key tecla de função inexistente
|
||||
@msg no such color cor inexistente
|
||||
@msg {_1} cannot be used on Windows {_1} não pode ser usado no Windows
|
||||
@@ -5681,6 +5684,11 @@ axis Y Axis Eixo Y
|
||||
Set Options Opções do Conjunto
|
||||
Action Options… Opções da Ação…
|
||||
Action Options Opções da Ação
|
||||
Playback Options… Opções de Reprodução…
|
||||
Playback Options Opções de Reprodução
|
||||
Accelerated Acelerada
|
||||
Step by Step Passo a Passo
|
||||
Pause For Pausar Por
|
||||
Rename Action Renomear Ação
|
||||
New Action… Nova Ação…
|
||||
New Action Nova Ação
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -5200,6 +5200,9 @@ lighting Light Свет
|
||||
Movie Clip Видеоклип
|
||||
@msg name is empty имя пустое
|
||||
@msg an action is already recording действие уже записывается
|
||||
@msg an action is already playing действие уже воспроизводится
|
||||
@msg speed must be accelerated, step or pause speed должен быть accelerated, step или pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds должно быть целым числом от 1 до 60
|
||||
@msg no such function key такой функциональной клавиши нет
|
||||
@msg no such color такого цвета нет
|
||||
@msg {_1} cannot be used on Windows Сочетание {_1} нельзя использовать в Windows
|
||||
@@ -5377,6 +5380,11 @@ axis Y Axis Ось Y
|
||||
Set Options Параметры набора
|
||||
Action Options… Параметры действия…
|
||||
Action Options Параметры действия
|
||||
Playback Options… Параметры воспроизведения…
|
||||
Playback Options Параметры воспроизведения
|
||||
Accelerated Ускоренно
|
||||
Step by Step Пошагово
|
||||
Pause For Пауза
|
||||
Rename Action Переименовать действие
|
||||
New Action… Новое действие…
|
||||
New Action Новое действие
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5547,6 +5547,9 @@ theme Appearance Utseende
|
||||
Movie Clip Filmklipp
|
||||
@msg name is empty namnet är tomt
|
||||
@msg an action is already recording en åtgärd spelas redan in
|
||||
@msg an action is already playing en åtgärd spelas redan upp
|
||||
@msg speed must be accelerated, step or pause speed måste vara accelerated, step eller pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds måste vara ett heltal från 1 till 60
|
||||
@msg no such function key funktionstangenten finns inte
|
||||
@msg no such color färgen finns inte
|
||||
@msg {_1} cannot be used on Windows {_1} kan inte användas i Windows
|
||||
@@ -5789,6 +5792,11 @@ axis Y Axis Y-axel
|
||||
Set Options Alternativ för uppsättning
|
||||
Action Options… Alternativ för åtgärd…
|
||||
Action Options Alternativ för åtgärd
|
||||
Playback Options… Uppspelningsalternativ…
|
||||
Playback Options Uppspelningsalternativ
|
||||
Accelerated Accelererad
|
||||
Step by Step Steg för steg
|
||||
Pause For Paus i
|
||||
Rename Action Byt namn på åtgärd
|
||||
New Action… Ny åtgärd…
|
||||
New Action Ny åtgärd
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -5256,6 +5256,9 @@ theme Appearance Görünüm
|
||||
Movie Clip Film Klibi
|
||||
@msg name is empty isim boş
|
||||
@msg an action is already recording zaten bir eylem kaydediliyor
|
||||
@msg an action is already playing zaten bir eylem oynatılıyor
|
||||
@msg speed must be accelerated, step or pause speed accelerated, step veya pause olmalıdır
|
||||
@msg seconds must be a whole number from 1 to 60 seconds 1 ile 60 arasında bir tam sayı olmalıdır
|
||||
@msg no such function key öyle bir işlev tuşu yok
|
||||
@msg no such color öyle bir renk yok
|
||||
@msg {_1} cannot be used on Windows {_1} Windows'ta kullanılamaz
|
||||
@@ -5723,6 +5726,11 @@ axis Y Axis Y ekseni
|
||||
Set Options Set Seçenekleri
|
||||
Action Options… Eylem Seçenekleri…
|
||||
Action Options Eylem Seçenekleri
|
||||
Playback Options… Oynatma Seçenekleri…
|
||||
Playback Options Oynatma Seçenekleri
|
||||
Accelerated Hızlandırılmış
|
||||
Step by Step Adım Adım
|
||||
Pause For Duraklat
|
||||
Rename Action Eylemi Yeniden Adlandır
|
||||
New Action… Yeni Eylem…
|
||||
New Action Yeni Eylem
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -5185,6 +5185,9 @@ lighting Light Світло
|
||||
Movie Clip Кліп
|
||||
@msg name is empty ім’я порожнє
|
||||
@msg an action is already recording дія вже записується
|
||||
@msg an action is already playing дія вже відтворюється
|
||||
@msg speed must be accelerated, step or pause speed має бути accelerated, step або pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds має бути цілим числом від 1 до 60
|
||||
@msg no such function key такої функціональної клавіші немає
|
||||
@msg no such color такого кольору немає
|
||||
@msg {_1} cannot be used on Windows Сполучення {_1} не можна використовувати у Windows
|
||||
@@ -5362,6 +5365,11 @@ axis Y Axis Вісь Y
|
||||
Set Options Параметри набору
|
||||
Action Options… Параметри дії…
|
||||
Action Options Параметри дії
|
||||
Playback Options… Параметри відтворення…
|
||||
Playback Options Параметри відтворення
|
||||
Accelerated Прискорено
|
||||
Step by Step Покроково
|
||||
Pause For Пауза
|
||||
Rename Action Перейменувати дію
|
||||
New Action… Нова дія…
|
||||
New Action Нова дія
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 177 and column 5.
|
@@ -5186,6 +5186,9 @@ theme Appearance Giao diện
|
||||
Movie Clip Clip phim
|
||||
@msg name is empty tên trống
|
||||
@msg an action is already recording đang ghi một hành động
|
||||
@msg an action is already playing đang phát một hành động
|
||||
@msg speed must be accelerated, step or pause speed phải là accelerated, step hoặc pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds phải là số nguyên từ 1 đến 60
|
||||
@msg no such function key không có phím chức năng như vậy
|
||||
@msg no such color không có màu như vậy
|
||||
@msg {_1} cannot be used on Windows không thể dùng {_1} trên Windows
|
||||
@@ -5363,6 +5366,11 @@ axis Y Axis Trục Y
|
||||
Set Options Tùy chọn bộ
|
||||
Action Options… Tùy chọn hành động…
|
||||
Action Options Tùy chọn hành động
|
||||
Playback Options… Tùy chọn phát lại…
|
||||
Playback Options Tùy chọn phát lại
|
||||
Accelerated Tăng tốc
|
||||
Step by Step Từng bước
|
||||
Pause For Tạm dừng
|
||||
Rename Action Đổi tên hành động
|
||||
New Action… Hành động mới…
|
||||
New Action Hành động mới
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 199 and column 5.
|
@@ -5425,6 +5425,9 @@ lighting Light 光源
|
||||
Movie Clip 影片剪辑
|
||||
@msg name is empty 名称为空
|
||||
@msg an action is already recording 已在记录动作
|
||||
@msg an action is already playing 已在播放动作
|
||||
@msg speed must be accelerated, step or pause speed 必须为 accelerated、step 或 pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds 必须为 1 到 60 之间的整数
|
||||
@msg no such function key 没有此功能键
|
||||
@msg no such color 没有此颜色
|
||||
@msg {_1} cannot be used on Windows {_1} 在 Windows 上不能使用
|
||||
@@ -5604,6 +5607,11 @@ axis Y Axis Y 轴
|
||||
Set Options 组选项
|
||||
Action Options… 动作选项…
|
||||
Action Options 动作选项
|
||||
Playback Options… 播放选项…
|
||||
Playback Options 播放选项
|
||||
Accelerated 加速
|
||||
Step by Step 逐步
|
||||
Pause For 暂停
|
||||
Rename Action 重命名动作
|
||||
New Action… 新建动作…
|
||||
New Action 新建动作
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5243,6 +5243,9 @@ lighting Light 光源
|
||||
Movie Clip 影片片段
|
||||
@msg name is empty 名稱為空
|
||||
@msg an action is already recording 已在錄製動作
|
||||
@msg an action is already playing 已在播放動作
|
||||
@msg speed must be accelerated, step or pause speed 必須為 accelerated、step 或 pause
|
||||
@msg seconds must be a whole number from 1 to 60 seconds 必須為 1 到 60 之間的整數
|
||||
@msg no such function key 沒有這個功能鍵
|
||||
@msg no such color 沒有這個顏色
|
||||
@msg {_1} cannot be used on Windows {_1} 無法在 Windows 上使用
|
||||
@@ -5400,6 +5403,11 @@ axis Y Axis Y 軸
|
||||
Set Options 組選項
|
||||
Action Options… 動作選項…
|
||||
Action Options 動作選項
|
||||
Playback Options… 播放選項…
|
||||
Playback Options 播放選項
|
||||
Accelerated 加速
|
||||
Step by Step 逐步
|
||||
Pause For 暫停
|
||||
Rename Action 重新命名動作
|
||||
New Action… 新增動作…
|
||||
New Action 新增動作
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -826,6 +826,7 @@ fn run_ui_part11(app: &mut VectorcraftApp, id: &str, p: &Value) -> Option<Result
|
||||
crate::panels::actions::NEW_ACTION => crate::panels::actions::new_action(app, p),
|
||||
crate::panels::actions::ACTION_OPTIONS => crate::panels::actions::action_options(app, p),
|
||||
crate::panels::actions::PLAY_ACTION => crate::panels::actions::play_action(app, p),
|
||||
crate::panels::actions::PLAYBACK_OPTIONS => crate::panels::actions::playback_options(app, p),
|
||||
crate::panels::actions::START_RECORDING => crate::panels::actions::record(app, p),
|
||||
crate::panels::actions::STOP_RECORDING => crate::panels::actions::stop(app, p),
|
||||
"ui.batchDialog" => {
|
||||
|
||||
@@ -1239,7 +1239,13 @@ pub const UI_COMMANDS: &[(&str, &str, &str, &str)] = &[
|
||||
crate::panels::actions::PLAY_ACTION,
|
||||
"Play Action",
|
||||
"",
|
||||
"{action: name, set?: name} play the Actions panel's action named action as one undoable batch; set names the set to look in (default: every set). A name no action has, or one that more than one action in the sets looked in has, is an error and nothing plays → what command.batch returns",
|
||||
"{action: name, set?: name} play the Actions panel's action named action at the speed ui.action.playbackOptions sets; set names the set to look in (default: every set). Accelerated plays it as one undoable batch → what command.batch returns. Step by Step and Pause For play its first step now and the others one at a time, each its own undo step, until the last or ui.action.stop → {results: [the first step's result], pending: the steps left}. A name no action has, or one that more than one action in the sets looked in has, or an action played while another is still playing step by step or with pauses, is an error and nothing plays",
|
||||
),
|
||||
(
|
||||
crate::panels::actions::PLAYBACK_OPTIONS,
|
||||
"Playback Options",
|
||||
"",
|
||||
"{speed?: accelerated|step|pause, seconds?: 1-60} set how the Actions panel plays actions: accelerated (the default) plays every step at once, step plays one step at a time and draws the window after each, and pause waits seconds (a whole number, 1 to 60, VectorCraft's own range) between steps. A param left out keeps its value; the setting is kept with the UI preferences. Any other speed or seconds is an error and changes nothing. The panel menu's Playback Options… (dialog `actionPlayback` with speed and seconds) runs this on OK → {speed, seconds}",
|
||||
),
|
||||
(
|
||||
crate::panels::actions::START_RECORDING,
|
||||
@@ -1251,7 +1257,7 @@ pub const UI_COMMANDS: &[(&str, &str, &str, &str)] = &[
|
||||
crate::panels::actions::STOP_RECORDING,
|
||||
"Stop Playing/Recording",
|
||||
"",
|
||||
"{} end the Actions panel's recording and keep its steps, in the action ui.action.new made for it, else in a new action after the last action of its set, as the panel's Stop Playing/Recording button does. With nothing recording it changes nothing → {stopped}",
|
||||
"{} end the Actions panel's recording and keep its steps, in the action ui.action.new made for it, else in a new action after the last action of its set, as the panel's Stop Playing/Recording button does. It also ends an action playing step by step or with pauses: the steps played stay and the rest do not run. With nothing recording or playing it changes nothing → {stopped}",
|
||||
),
|
||||
(
|
||||
"ui.batchDialog",
|
||||
|
||||
@@ -203,14 +203,154 @@ pub fn default_sets() -> Vec<ActionSet> {
|
||||
)]
|
||||
}
|
||||
|
||||
/// Run an action as a single undoable batch.
|
||||
/// Plays an action at the speed [`UiState::action_playback`](crate::UiState::action_playback) sets.
|
||||
/// Accelerated runs every included step at once as a single undoable batch → what `command.batch`
|
||||
/// returns. Step by Step and Pause For run the first step now, each as its own undo step, and leave
|
||||
/// the rest to [`tick_playback`] → {results: [the first step's result], pending: the steps left}.
|
||||
/// While a paced playback is in progress, another action does not play.
|
||||
pub fn play(app: &mut VectorcraftApp, set: usize, idx: usize) -> Result<Value, String> {
|
||||
let Some(a) = app.ui.action_sets.get(set).and_then(|s| s.actions.get(idx)).cloned() else { return Err("no such action".into()) };
|
||||
let commands = a.included_commands();
|
||||
if commands.is_empty() {
|
||||
return Err("the action has no included steps".into());
|
||||
}
|
||||
app.run("command.batch", json!({"label": a.name, "commands": commands}))
|
||||
if app.ui.action_playing.is_some() {
|
||||
return Err("an action is already playing".into());
|
||||
}
|
||||
let options = app.ui.action_playback;
|
||||
if options.speed == PlaybackSpeed::Accelerated {
|
||||
return app.run("command.batch", json!({"label": a.name, "commands": commands}));
|
||||
}
|
||||
let mut steps: std::collections::VecDeque<Value> = commands.into();
|
||||
let Some(first) = steps.pop_front() else { return Err("the action has no included steps".into()) };
|
||||
let result = play_step(app, &a.name, first)?;
|
||||
let pending = steps.len();
|
||||
if pending > 0 {
|
||||
app.ui.action_playing = Some(Playing { label: a.name, steps, options, next_at: None });
|
||||
if let Some(ctx) = &app.ui_ctx {
|
||||
ctx.request_repaint();
|
||||
}
|
||||
}
|
||||
Ok(json!({"results": [result], "pending": pending}))
|
||||
}
|
||||
|
||||
/// Runs one step of a paced playback as its own undo step, named `label` → the step's result.
|
||||
fn play_step(app: &mut VectorcraftApp, label: &str, step: Value) -> Result<Value, String> {
|
||||
let r = app.run("command.batch", json!({"label": label, "commands": [step]}))?;
|
||||
Ok(r.get("results").and_then(|r| r.get(0)).cloned().unwrap_or(Value::Null))
|
||||
}
|
||||
|
||||
/// The speed actions play at (Actions panel menu › Playback Options…).
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum PlaybackSpeed {
|
||||
/// Every included step at once.
|
||||
#[default]
|
||||
Accelerated,
|
||||
/// One step per frame, so the window draws each step's result before the next step runs.
|
||||
Step,
|
||||
/// [`PlaybackOptions::seconds`] between steps.
|
||||
Pause,
|
||||
}
|
||||
|
||||
/// The pause between steps that Pause For takes, in whole seconds: VectorCraft's own range.
|
||||
pub const PAUSE_SECONDS: std::ops::RangeInclusive<u32> = 1..=60;
|
||||
|
||||
/// How actions play, kept with the UI preferences.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct PlaybackOptions {
|
||||
pub speed: PlaybackSpeed,
|
||||
/// The pause between steps with [`PlaybackSpeed::Pause`], within [`PAUSE_SECONDS`]. It is kept
|
||||
/// while another speed is chosen.
|
||||
pub seconds: u32,
|
||||
}
|
||||
|
||||
impl Default for PlaybackOptions {
|
||||
fn default() -> Self {
|
||||
Self { speed: PlaybackSpeed::Accelerated, seconds: *PAUSE_SECONDS.start() }
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads saved [`PlaybackOptions`]: a value that is not a valid one loads as the default.
|
||||
pub fn deserialize_playback<'de, D: serde::Deserializer<'de>>(d: D) -> Result<PlaybackOptions, D::Error> {
|
||||
let v = <Value as serde::Deserialize>::deserialize(d)?;
|
||||
Ok(serde_json::from_value::<PlaybackOptions>(v).ok().filter(|o| PAUSE_SECONDS.contains(&o.seconds)).unwrap_or_default())
|
||||
}
|
||||
|
||||
/// A paced playback in progress: the steps still to run.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Playing {
|
||||
/// The action's name, which names each step's undo step.
|
||||
label: String,
|
||||
steps: std::collections::VecDeque<Value>,
|
||||
/// The options the action started playing with.
|
||||
options: PlaybackOptions,
|
||||
/// With Pause For, when the next step runs (seconds on the app's clock); none until the frame
|
||||
/// after the first step, which starts the first pause.
|
||||
next_at: Option<f64>,
|
||||
}
|
||||
|
||||
/// Runs the next step of the paced playback in progress when it is due at `now` (seconds on the
|
||||
/// app's clock): with Step by Step at each call, so each frame runs one step; with Pause For once
|
||||
/// the pause after the step before has passed. A step that fails ends the playback and shows its
|
||||
/// error. → the seconds until the window should draw again while playback goes on
|
||||
pub fn tick_playback(app: &mut VectorcraftApp, now: f64) -> Option<f64> {
|
||||
let playing = app.ui.action_playing.as_mut()?;
|
||||
let pause = f64::from(playing.options.seconds);
|
||||
if playing.options.speed == PlaybackSpeed::Pause {
|
||||
let due = *playing.next_at.get_or_insert(now + pause);
|
||||
if now < due {
|
||||
return Some(due - now);
|
||||
}
|
||||
// The next pause starts when this step runs.
|
||||
playing.next_at = Some(now + pause);
|
||||
}
|
||||
let Some(step) = playing.steps.pop_front() else {
|
||||
app.ui.action_playing = None;
|
||||
return None;
|
||||
};
|
||||
let label = playing.label.clone();
|
||||
if playing.steps.is_empty() {
|
||||
app.ui.action_playing = None;
|
||||
}
|
||||
if let Err(e) = play_step(app, &label, step) {
|
||||
app.ui.action_playing = None;
|
||||
app.status(e);
|
||||
return None;
|
||||
}
|
||||
let playing = app.ui.action_playing.as_ref()?;
|
||||
Some(if playing.options.speed == PlaybackSpeed::Pause { pause } else { 0.0 })
|
||||
}
|
||||
|
||||
/// The command behind Playback Options… ([`playback_options`]).
|
||||
pub const PLAYBACK_OPTIONS: &str = "ui.action.playbackOptions";
|
||||
|
||||
/// `ui.action.playbackOptions {speed?, seconds?}`: sets how actions play. `speed` is
|
||||
/// `accelerated` (every step at once, the default), `step` (one step at a time, the window drawn
|
||||
/// after each) or `pause` (`seconds` between steps); `seconds` is a whole number in
|
||||
/// [`PAUSE_SECONDS`]. A param left out keeps its value. Any other value is an error, and then
|
||||
/// nothing changes. An action already playing keeps its speed. → {speed, seconds}
|
||||
pub fn playback_options(app: &mut VectorcraftApp, p: &Value) -> Result<Value, String> {
|
||||
let current = app.ui.action_playback;
|
||||
let speed = match p.get("speed") {
|
||||
None => current.speed,
|
||||
Some(v) => match v.as_str() {
|
||||
Some("accelerated") => PlaybackSpeed::Accelerated,
|
||||
Some("step") => PlaybackSpeed::Step,
|
||||
Some("pause") => PlaybackSpeed::Pause,
|
||||
_ => return Err("speed must be accelerated, step or pause".into()),
|
||||
},
|
||||
};
|
||||
let seconds = match p.get("seconds") {
|
||||
None => current.seconds,
|
||||
Some(v) => v
|
||||
.as_u64()
|
||||
.and_then(|s| u32::try_from(s).ok())
|
||||
.filter(|s| PAUSE_SECONDS.contains(s))
|
||||
.ok_or("seconds must be a whole number from 1 to 60")?,
|
||||
};
|
||||
app.ui.action_playback = PlaybackOptions { speed, seconds };
|
||||
Ok(json!({"speed": speed, "seconds": seconds}))
|
||||
}
|
||||
|
||||
/// The command behind the Actions panel's set, action and step checkmarks.
|
||||
@@ -444,11 +584,14 @@ pub fn record(app: &mut VectorcraftApp, p: &Value) -> Result<Value, String> {
|
||||
|
||||
/// `ui.action.stop {}`: ends the recording in progress and keeps its steps, in the action New
|
||||
/// Action made for it, else in a new action after the last action of its set, as the bottom bar's
|
||||
/// Stop Playing/Recording does. With nothing recording it changes nothing. → {stopped}
|
||||
/// Stop Playing/Recording does. It also ends a playback at Step by Step or Pause For: the steps
|
||||
/// already played stay, and the rest do not run. With nothing recording or playing it changes
|
||||
/// nothing. → {stopped}
|
||||
pub fn stop(app: &mut VectorcraftApp, _: &Value) -> Result<Value, String> {
|
||||
let stopped = app.ui.recording.is_some();
|
||||
let playing = app.ui.action_playing.take().is_some();
|
||||
let recording = app.ui.recording.is_some();
|
||||
stop_recording(app);
|
||||
Ok(json!({ "stopped": stopped }))
|
||||
Ok(json!({ "stopped": recording || playing }))
|
||||
}
|
||||
|
||||
/// The command that `chord` runs under `km`, pressed once or pressed twice.
|
||||
@@ -801,6 +944,9 @@ pub fn menu(app: &mut VectorcraftApp, ui: &mut egui::Ui) {
|
||||
{
|
||||
crate::dialogs::action_set_options::open_action(app, s, a);
|
||||
}
|
||||
if widgets::menu_item(ui, tl!("Playback Options…"), true, false) {
|
||||
crate::dialogs::action_playback::open(app);
|
||||
}
|
||||
ui.separator();
|
||||
// As commands, so a file dialog shown off the UI thread saves or loads when it answers.
|
||||
// Save Actions… names the current set by its id, so a file dialog that answers later saves that set.
|
||||
@@ -2662,4 +2808,145 @@ mod tests {
|
||||
"the command keeps its shortcut"
|
||||
);
|
||||
}
|
||||
|
||||
/// A document with one rectangle selected and the set "Moves" with one action that moves it
|
||||
/// right three times, by 1, 2 and 4 pt → (the app, the rectangle's left edge as it moves).
|
||||
fn app_with_three_moves() -> (VectorcraftApp, impl Fn(&VectorcraftApp) -> f64) {
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.run("file.new", json!({"width": 200, "height": 100})).unwrap();
|
||||
let id = vectorcraft_doc::NodeId(
|
||||
app.run("shape.rectangle", json!({"x": 10, "y": 10, "width": 20, "height": 20})).unwrap()["id"].as_u64().unwrap(),
|
||||
);
|
||||
app.run("select.set", json!({"ids": [id.0]})).unwrap();
|
||||
let step = |dx: u32| ("object.move".to_string(), json!({"dx": dx, "dy": 0}));
|
||||
app.ui.action_sets = vec![ActionSet::new("Moves", vec![Action::new("Three Moves", vec![step(1), step(2), step(4)])])];
|
||||
let x = move |app: &VectorcraftApp| app.session.active().unwrap().doc.node(id).unwrap().geometric_bounds().unwrap().x0 - 10.0;
|
||||
(app, x)
|
||||
}
|
||||
|
||||
fn undo_steps(app: &VectorcraftApp) -> usize {
|
||||
app.session.active().unwrap().history.undo.len()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn playback_options_sets_each_speed_and_refuses_bad_values() {
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
assert_eq!(app.ui.action_playback, PlaybackOptions { speed: PlaybackSpeed::Accelerated, seconds: 1 }, "Accelerated is the default");
|
||||
assert_eq!(app.run(PLAYBACK_OPTIONS, json!({"speed": "step"})).unwrap(), json!({"speed": "step", "seconds": 1}));
|
||||
assert_eq!(app.run(PLAYBACK_OPTIONS, json!({"speed": "pause", "seconds": 2})).unwrap(), json!({"speed": "pause", "seconds": 2}));
|
||||
assert_eq!(
|
||||
app.run(PLAYBACK_OPTIONS, json!({"speed": "accelerated"})).unwrap(),
|
||||
json!({"speed": "accelerated", "seconds": 2}),
|
||||
"seconds kept"
|
||||
);
|
||||
assert_eq!(app.run(PLAYBACK_OPTIONS, json!({"seconds": 60})).unwrap(), json!({"speed": "accelerated", "seconds": 60}), "speed kept");
|
||||
let kept = app.ui.action_playback;
|
||||
for bad in [json!({"speed": "fast"}), json!({"speed": null}), json!({"speed": 1})] {
|
||||
assert_eq!(app.run(PLAYBACK_OPTIONS, bad.clone()).unwrap_err(), "speed must be accelerated, step or pause", "{bad}");
|
||||
}
|
||||
for bad in [json!(0), json!(61), json!(2.5), json!(-1), json!("2"), json!(null)] {
|
||||
let p = json!({"speed": "pause", "seconds": bad});
|
||||
assert_eq!(app.run(PLAYBACK_OPTIONS, p).unwrap_err(), "seconds must be a whole number from 1 to 60", "{bad}");
|
||||
}
|
||||
assert_eq!(app.ui.action_playback, kept, "a refused value changes nothing");
|
||||
// Kept with the UI preferences; a saved value that is not valid loads as the default.
|
||||
app.run(PLAYBACK_OPTIONS, json!({"speed": "pause", "seconds": 5})).unwrap();
|
||||
let mut saved = serde_json::to_value(&app.ui).unwrap();
|
||||
let ui = serde_json::from_value::<crate::UiState>(saved.clone()).unwrap();
|
||||
assert_eq!(ui.action_playback, PlaybackOptions { speed: PlaybackSpeed::Pause, seconds: 5 });
|
||||
for bad in [json!({"speed": "pause", "seconds": 0}), json!({"speed": "slow", "seconds": 5}), json!("step")] {
|
||||
saved["action_playback"] = bad;
|
||||
assert_eq!(serde_json::from_value::<crate::UiState>(saved.clone()).unwrap().action_playback, PlaybackOptions::default());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_playback_options_dialog_sets_the_speed_and_pause() {
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.run(PLAYBACK_OPTIONS, json!({"speed": "step", "seconds": 3})).unwrap();
|
||||
crate::dialogs::action_playback::open(&mut app);
|
||||
let d = app.ui.dialog.as_mut().unwrap();
|
||||
assert_eq!((d.kind.as_str(), d.str("speed"), d.fields["seconds"].clone()), ("actionPlayback", "step".to_string(), json!(3)));
|
||||
d.fields.insert("speed".into(), json!("pause"));
|
||||
d.fields.insert("seconds".into(), json!(4));
|
||||
crate::dialogs::confirm(&mut app).unwrap();
|
||||
assert!(app.ui.dialog.is_none());
|
||||
assert_eq!(app.ui.action_playback, PlaybackOptions { speed: PlaybackSpeed::Pause, seconds: 4 });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn accelerated_playback_plays_every_step_as_one_undo_step() {
|
||||
let (mut app, x) = app_with_three_moves();
|
||||
let before = undo_steps(&app);
|
||||
play(&mut app, 0, 0).unwrap();
|
||||
assert_eq!(x(&app), 7.0);
|
||||
assert_eq!(undo_steps(&app), before + 1);
|
||||
assert!(app.ui.action_playing.is_none());
|
||||
assert_eq!(tick_playback(&mut app, 0.0), None, "nothing waits for a frame");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn step_by_step_plays_one_step_per_frame_and_redraws_between_steps() {
|
||||
let (mut app, x) = app_with_three_moves();
|
||||
app.run(PLAYBACK_OPTIONS, json!({"speed": "step"})).unwrap();
|
||||
let before = undo_steps(&app);
|
||||
assert_eq!(play(&mut app, 0, 0).unwrap()["pending"], json!(2));
|
||||
assert_eq!(x(&app), 1.0, "the first step runs at once");
|
||||
assert_eq!(tick_playback(&mut app, 0.0), Some(0.0), "the window draws again before the next step");
|
||||
assert_eq!(x(&app), 3.0, "one more step in this frame");
|
||||
assert_eq!(tick_playback(&mut app, 0.0), None, "the last step ends the playback");
|
||||
assert_eq!(x(&app), 7.0);
|
||||
assert!(app.ui.action_playing.is_none());
|
||||
assert_eq!(tick_playback(&mut app, 0.0), None);
|
||||
assert_eq!(x(&app), 7.0);
|
||||
assert_eq!(undo_steps(&app), before + 3, "each step is its own undo step");
|
||||
assert_eq!(app.session.active().unwrap().history.undo.last().unwrap().label, "Three Moves");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pause_for_waits_the_seconds_between_steps() {
|
||||
let (mut app, x) = app_with_three_moves();
|
||||
app.run(PLAYBACK_OPTIONS, json!({"speed": "pause", "seconds": 2})).unwrap();
|
||||
play(&mut app, 0, 0).unwrap();
|
||||
assert_eq!(x(&app), 1.0);
|
||||
assert_eq!(tick_playback(&mut app, 10.0), Some(2.0), "the pause starts in the frame after the first step");
|
||||
assert_eq!(tick_playback(&mut app, 11.5), Some(0.5));
|
||||
assert_eq!(x(&app), 1.0, "nothing runs before the pause has passed");
|
||||
assert_eq!(tick_playback(&mut app, 12.0), Some(2.0));
|
||||
assert_eq!(x(&app), 3.0, "the second step runs after 2 s");
|
||||
assert!(tick_playback(&mut app, 13.9).is_some_and(|wait| (wait - 0.1).abs() < 1e-9));
|
||||
assert_eq!(x(&app), 3.0);
|
||||
assert_eq!(tick_playback(&mut app, 14.0), None);
|
||||
assert_eq!(x(&app), 7.0, "the third step runs 2 s after the second");
|
||||
assert!(app.ui.action_playing.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stop_ends_a_paced_playback_and_another_action_waits_for_it() {
|
||||
let (mut app, x) = app_with_three_moves();
|
||||
app.run(PLAYBACK_OPTIONS, json!({"speed": "pause", "seconds": 1})).unwrap();
|
||||
play(&mut app, 0, 0).unwrap();
|
||||
assert_eq!(play(&mut app, 0, 0).unwrap_err(), "an action is already playing");
|
||||
assert_eq!(app.run(PLAY_ACTION, json!({"action": "Three Moves"})).unwrap_err(), "an action is already playing");
|
||||
assert_eq!(x(&app), 1.0);
|
||||
assert_eq!(app.run(STOP_RECORDING, json!({})).unwrap(), json!({"stopped": true}));
|
||||
assert_eq!(tick_playback(&mut app, 100.0), None);
|
||||
assert_eq!(x(&app), 1.0, "the steps after Stop do not run; the one played stays");
|
||||
assert_eq!(app.run(STOP_RECORDING, json!({})).unwrap(), json!({"stopped": false}));
|
||||
play(&mut app, 0, 0).unwrap();
|
||||
assert_eq!(x(&app), 2.0, "an action plays again after Stop");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_failing_step_ends_a_paced_playback_with_its_error() {
|
||||
let (mut app, x) = app_with_three_moves();
|
||||
app.run(PLAYBACK_OPTIONS, json!({"speed": "step"})).unwrap();
|
||||
app.ui.action_sets[0].actions[0].steps[1] = ("no.such.command".into(), json!({}));
|
||||
play(&mut app, 0, 0).unwrap();
|
||||
assert_eq!(tick_playback(&mut app, 0.0), None);
|
||||
assert!(app.ui.action_playing.is_none());
|
||||
assert!(!app.ui.status.is_empty(), "the step's error shows");
|
||||
assert_eq!(tick_playback(&mut app, 0.0), None);
|
||||
assert_eq!(x(&app), 1.0, "the step after the failing one does not run");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,6 +496,12 @@ pub struct UiState {
|
||||
/// adds a new action, as after Begin Recording.
|
||||
#[serde(skip)]
|
||||
pub recording_into: Option<u64>,
|
||||
/// How actions play (Actions panel menu › Playback Options…), kept with the UI preferences.
|
||||
#[serde(default, deserialize_with = "crate::panels::actions::deserialize_playback")]
|
||||
pub action_playback: crate::panels::actions::PlaybackOptions,
|
||||
/// The playback at Step by Step or Pause For in progress, if any. Not saved.
|
||||
#[serde(skip)]
|
||||
pub action_playing: Option<crate::panels::actions::Playing>,
|
||||
/// Keyboard shortcut overrides: command id, `tool:<id>` or `panel:<id>` → chord ("" = none),
|
||||
/// stored in the form every earlier version reads.
|
||||
#[serde(default, with = "crate::keymap::stored")]
|
||||
@@ -970,6 +976,8 @@ impl Default for UiState {
|
||||
action_sets_selected: vec![],
|
||||
recording: None,
|
||||
recording_into: None,
|
||||
action_playback: Default::default(),
|
||||
action_playing: None,
|
||||
shortcut_overrides: Default::default(),
|
||||
shortcut_set: default_shortcut_set(),
|
||||
workspace: default_workspace(),
|
||||
|
||||
+17
-5
@@ -1848,12 +1848,24 @@ already walks Image Trace. Short agent entry points:
|
||||
a text field has the keyboard, or while a tool is busy. Editing command shortcuts (`shortcuts.set`, Keyboard Shortcuts), loading preferences and
|
||||
`ui.actionSet.load` preserve action function keys. When several actions have the same key, the first in panel order
|
||||
plays. A stored key reserved on the current platform does not play an action.
|
||||
- Actions: `ui.action.play {action, set?}` plays the action named `action` as one undoable batch; `set` names the set
|
||||
to look in (default: every set), and a `set` that is not a string is an error. A name that no action has, or that
|
||||
more than one action in the sets looked in has, or whose every step is excluded, is an error, and then nothing plays.
|
||||
- Actions: `ui.action.play {action, set?}` plays the action named `action` at the speed `ui.action.playbackOptions`
|
||||
sets; `set` names the set to look in (default: every set), and a `set` that is not a string is an error. At
|
||||
Accelerated it plays the action as one undoable batch and returns what `command.batch` returns. At Step by Step and
|
||||
Pause For it plays the first step at once and returns `{results: [the first step's result], pending}`, where
|
||||
`pending` counts the steps still to play; the app plays them one at a time, each as its own undo step. A name that no
|
||||
action has, or that more than one action in the sets looked in has, or whose every step is excluded, is an error, and
|
||||
then nothing plays. So is an action played while another is still playing at Step by Step or Pause For.
|
||||
- Actions: `ui.action.playbackOptions {speed?, seconds?}` sets how the Actions panel plays actions and returns
|
||||
`{speed, seconds}`. `speed` is `accelerated` (the default: every step at once), `step` (one step at a time, with the
|
||||
window drawn after each step before the next runs) or `pause` (a pause of `seconds` between steps). `seconds` is a
|
||||
whole number from 1 to 60, VectorCraft's own range, and stays set while another speed is chosen. A param left out
|
||||
keeps its value. Any other `speed` or `seconds` is an error, and then nothing changes. The setting is kept with the UI
|
||||
preferences. The panel menu's Playback Options… opens the `actionPlayback` dialog (`speed`, `seconds`), whose OK runs
|
||||
this. Batch… (`action.batch`) plays every step at once whatever the setting.
|
||||
- Actions: `ui.action.stop {}` ends the recording in progress and keeps its steps, in the action `ui.action.new` made
|
||||
for it, else in a new action after the last action of its set, and returns `{stopped}`. With nothing recording it
|
||||
changes nothing. The panel's Stop Playing/Recording button runs this.
|
||||
for it, else in a new action after the last action of its set, and returns `{stopped}`. It also ends an action
|
||||
playing at Step by Step or Pause For: the steps already played stay, and the rest do not play. With nothing
|
||||
recording or playing it changes nothing. The panel's Stop Playing/Recording button runs this.
|
||||
- Action sets: `ui.actionSet.delete {sets?: [index], ids?: [id]}` deletes the Actions panel's sets at these indexes
|
||||
(0 is the top set) with their actions, by default the current set, and returns `{deleted}`. An index past the last
|
||||
set is an error, and then no set is deleted. `ids` holds the panel's own set ids, which its question passes: the
|
||||
|
||||
@@ -581,6 +581,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
- Actions panel (record/playback, persisted), generic parameter dialogs for every "…" command.
|
||||
- Actions panel: the current set is kept with the UI preferences, so after a restart a recording goes into the set that was current, not into the first set. With no set current, Begin Recording records into the first set and makes it current.
|
||||
- Actions panel: expand an action to show its recorded steps, then clear a step's checkmark to keep it in the action but skip it during playback. The action and set checkmarks include or exclude all their steps; a mixed checkmark includes all. Alt/Option-clicking a step checkmark keeps that step as it was and applies the opposite inclusion state to the other steps in its action. This follows the public [Exclude commands from an action](https://helpx.adobe.com/illustrator/desktop/automate-visualize-data/automate-actions/exclude-commands-from-actions.html) guide; the scope of the mixed-state and Alt-click behavior is VectorCraft's design. The exclusion survives UI restart, action duplication, and `.vcactions` save/load. Existing version 1 action set files load with every step included.
|
||||
- Actions panel: the panel menu's Playback Options… sets how actions play: Accelerated (the default) plays every step at once, Step by Step plays one step at a time with the canvas drawn after each, and Pause For waits the given number of seconds between steps ([Specify playback speed](https://helpx.adobe.com/illustrator/desktop/automate-visualize-data/automate-actions/specify-playback-speed.html); `ui.action.playbackOptions`). VectorCraft's own rules, which the page does not cover: the pause is a whole number of seconds from 1 to 60, the setting is kept with the UI preferences, Stop Playing/Recording ends a paced playback, each step of a paced playback is its own undo step, and Batch… plays at full speed.
|
||||
- Actions panel: Delete Selection deletes the selected action set with its actions and keeps the other sets ([Actions panel overview](https://helpx.adobe.com/illustrator/desktop/automate-visualize-data/automate-actions/actions-panel-overview.html); `ui.actionSet.delete`). VectorCraft's own rules, which the overview does not cover: deleting a set asks first, Shift-click on a set's name selects a range of sets to delete together, the panel menu's Delete does the same, and Default Actions and the last set can be deleted. Undo does not bring a deleted set back.
|
||||
- Actions panel: the panel menu's Duplicate copies the selected action, else the current action set with all its actions ([Actions panel overview](https://helpx.adobe.com/illustrator/desktop/automate-visualize-data/automate-actions/actions-panel-overview.html); `ui.actionSet.duplicate`). VectorCraft's own rules, which the overview does not cover: the copy goes right after the original, is named after it with " copy" added and is selected.
|
||||
- Batch… over data sets names each file after the document and the data set (`action.batch`). It writes `/`, `\`, `:`, `<`, `>`, `"`, `|`, `?`, `*` and control characters in the data set's name as `-`, and adds `-2`, `-3`… to a name an earlier data set used.
|
||||
|
||||
@@ -320,6 +320,7 @@ next unit in the order a right-click on a ruler lists them, from Feet back to Po
|
||||
| Toolbar without group labels by default, one or two columns; All Tools drawer by flyout group with shortcuts, its menu (Reset, Basic, Advanced) and Show section | done | #1751; a preference brings the labels back; `toolbar.show` sets the Fill/Stroke, Coloring, Draw Mode and Screen Mode controls |
|
||||
| Actions panel: ≡ › Save Actions… saves the current set with all its actions to a file and ≡ › Load Actions… adds a saved set ([Manage a set of actions](https://helpx.adobe.com/illustrator/desktop/automate-visualize-data/automate-actions/manage-a-set-of-actions.html)) | partial | `ui.actionSet.save`, `ui.actionSet.load`; `panels/actions.rs` tests. The file is VectorCraft's own `.vcactions` JSON; the reference app's `.aia` files and Reset, Clear and Replace Actions remain |
|
||||
| Actions panel: ≡ › Action Options… renames the selected action and sets its function key and color ([Actions panel overview](https://helpx.adobe.com/illustrator/desktop/automate-visualize-data/automate-actions/actions-panel-overview.html)) | partial | `ui.action.options`; `panels/actions.rs` tests (part of #1629). The color shows nowhere until Button Mode exists |
|
||||
| Actions panel: ≡ › Playback Options… plays actions Accelerated, Step by Step or with a pause between steps ([Specify playback speed](https://helpx.adobe.com/illustrator/desktop/automate-visualize-data/automate-actions/specify-playback-speed.html)) | done | `ui.action.playbackOptions`; `panels/actions.rs` tests. The pause is a whole number of seconds from 1 to 60 (VectorCraft's own range); Batch… plays at full speed |
|
||||
| Actions panel: a clicked action stays selected for Play Current Selection and Delete Selection | partial | #1853 (part of #1629); editing actions and action shortcuts remain |
|
||||
| Actions panel: Create New Set (bottom bar, ≡ › New Set…) names a new set and Set Options… renames the current one; a click on a set's name makes it current and a recording goes into the current set ([helpx: Automation with actions](https://helpx.adobe.com/illustrator/using/automation-actions.html)); the current set is kept with the UI preferences, and with no set current a recording goes into the first set, which becomes current | partial | #3712; dragging actions between sets remains |
|
||||
| Actions panel: Create New Action (bottom bar, ≡ › New Action…) asks for the name, set, function key and color, and Record adds the action and records into it ([Create new actions](https://helpx.adobe.com/illustrator/desktop/automate-visualize-data/automate-actions/record-actions.html)) | partial | `ui.action.new`, `ui.action.play`; `panels/actions.rs` tests. A function key plays its action, even when a command has the same shortcut, and the command keeps it. Button Mode, which shows the color, remains |
|
||||
|
||||
Reference in New Issue
Block a user