Open the Rename Clip dialog from Clip > Rename
Clip > Rename... and Cmd+Alt+Shift+R ran clip.rename without a name, so they only put "`name` required" in the status line. They now open the Rename Clip dialog, which only the clip's right-click menu opened so far, for the selected clip (or the first clip the edit selection touches). The dialog's name field, and Rename Track's, now opens with the old name selected, so typing replaces it instead of adding to it.
This commit is contained in:
parent
3bc2d92b4e
commit
aa4f038f1a
|
|
@ -100,6 +100,11 @@ impl Dialogs {
|
|||
let s = soundcraft_engine::score::ScoreSetup::from_session(e.session());
|
||||
Dialog::ScoreSetup { title: s.title, composer: s.composer, bars_per_system: s.bars_per_system, show_track_names: s.show_track_names }
|
||||
}
|
||||
"clip.rename" => {
|
||||
let target = soundcraft_engine::cmd::clip_ids_param(e, &json!({})).first().and_then(|id| e.session().find_clip(*id));
|
||||
let Some((_, clip)) = target else { return false };
|
||||
Dialog::RenameClip { id: clip.id, name: clip.name.clone() }
|
||||
}
|
||||
_ => match path_dialog(id, &home, &name) {
|
||||
Some(d) => d,
|
||||
None => return false,
|
||||
|
|
@ -273,15 +278,13 @@ pub fn show(app: &mut SoundApp, ctx: &egui::Context) {
|
|||
}
|
||||
}
|
||||
Dialog::RenameTrack { id, name } => {
|
||||
let r = ui.text_edit_singleline(name);
|
||||
r.request_focus();
|
||||
name_field(ui, name);
|
||||
if buttons(ui, "OK", enter) {
|
||||
action = Some(("track.rename".into(), json!({"track": id.0, "name": name})));
|
||||
}
|
||||
}
|
||||
Dialog::RenameClip { id, name } => {
|
||||
let r = ui.text_edit_singleline(name);
|
||||
r.request_focus();
|
||||
name_field(ui, name);
|
||||
if buttons(ui, "OK", enter) {
|
||||
action = Some(("clip.rename".into(), json!({"clip": id.0, "name": name})));
|
||||
}
|
||||
|
|
@ -436,6 +439,17 @@ fn buttons(ui: &mut egui::Ui, ok: &str, enter: bool) -> bool {
|
|||
pressed
|
||||
}
|
||||
|
||||
/// A name field that takes the focus with its text selected, so typing replaces the old name.
|
||||
fn name_field(ui: &mut egui::Ui, name: &mut String) {
|
||||
let mut out = egui::TextEdit::singleline(name).show(ui);
|
||||
if !out.response.has_focus() {
|
||||
out.response.request_focus();
|
||||
let all = egui::text::CCursorRange::two(egui::text::CCursor::new(0), egui::text::CCursor::new(name.chars().count()));
|
||||
out.state.cursor.set_char_range(Some(all));
|
||||
out.state.store(ui.ctx(), out.response.id);
|
||||
}
|
||||
}
|
||||
|
||||
/// The command the tempo-change dialog runs on OK.
|
||||
fn tempo_change_action(at: Samples, bpm: f64) -> (String, Value) {
|
||||
("event.tempo".into(), json!({"bpm": bpm, "at": at}))
|
||||
|
|
@ -515,6 +529,18 @@ mod tests {
|
|||
assert!(matches!(d.open, Some(Dialog::ScoreSetup { bars_per_system: 4, .. })));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clip_rename_opens_the_rename_dialog_for_the_selected_clip() {
|
||||
let mut e = soundcraft_engine::demo::demo_engine();
|
||||
let mut d = Dialogs::default();
|
||||
e.execute("edit.select_none", &json!({})).unwrap();
|
||||
assert!(!d.open_for_command(&e, "clip.rename"));
|
||||
let clip = e.session().track_by_name("Kick").unwrap().clips()[0].clone();
|
||||
e.execute("edit.select", &json!({"clips": [clip.id.0]})).unwrap();
|
||||
assert!(d.open_for_command(&e, "clip.rename"));
|
||||
assert!(matches!(d.open, Some(Dialog::RenameClip { id, ref name }) if id == clip.id && *name == clip.name));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tempo_change_dialog_runs_a_real_command_at_its_position() {
|
||||
let (cmd, params) = tempo_change_action(96_000, 133.5);
|
||||
|
|
|
|||
|
|
@ -159,6 +159,7 @@ const DIALOG_COMMANDS: &[&str] = &[
|
|||
"event.quantize",
|
||||
"event.transpose",
|
||||
"edit.strip_silence",
|
||||
"clip.rename",
|
||||
];
|
||||
|
||||
/// Shared menu hierarchy for egui and native desktop hosts.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
use egui::{Event, Key, Modifiers, vec2};
|
||||
use egui_kittest::Harness;
|
||||
use serde_json::json;
|
||||
use soundcraft_ui_egui::{Services, SoundApp, menus};
|
||||
|
||||
#[test]
|
||||
fn typing_in_the_rename_clip_dialog_replaces_the_old_name() {
|
||||
let mut app = SoundApp::new(soundcraft_engine::demo::demo_engine(), None, Services::default());
|
||||
let clip = app.engine.session().track_by_name("Kick").unwrap().clips()[0].clone();
|
||||
app.run("edit.select", json!({"clips": [clip.id.0]})).unwrap();
|
||||
menus::invoke_menu(&mut app, "clip.rename", "Clip > Rename...");
|
||||
let mut h = Harness::builder().with_size(vec2(1600.0, 1000.0)).build_ui_state(
|
||||
|ui, app: &mut SoundApp| {
|
||||
let ctx = ui.ctx().clone();
|
||||
app.logic(&ctx);
|
||||
app.ui(ui);
|
||||
},
|
||||
app,
|
||||
);
|
||||
for _ in 0..3 {
|
||||
h.step();
|
||||
}
|
||||
h.input_mut().events.push(Event::Text("Intro".into()));
|
||||
h.step();
|
||||
h.input_mut().events.push(Event::Key { key: Key::Enter, physical_key: None, pressed: true, repeat: false, modifiers: Modifiers::NONE });
|
||||
h.step();
|
||||
let session = h.state().engine.session();
|
||||
let renamed = session.tracks.iter().flat_map(|t| t.clips()).find(|c| c.id == clip.id).map(|c| c.name.clone());
|
||||
assert_eq!(renamed.as_deref(), Some("Intro"));
|
||||
}
|
||||
Loading…
Reference in New Issue