mirror of
https://github.com/storytold/soundcraft.git
synced 2026-10-13 23:08:25 +00:00
Merge pull request #407 from vbasky/fix/midi-editor-tool-insertion
Require the Pencil tool to insert MIDI notes
This commit is contained in:
2 files changed
+35
-3
No files matched your search
@@ -4,7 +4,7 @@ use crate::SoundApp;
|
||||
use crate::theme::{Tokens, bold, regular};
|
||||
use egui::{Align2, Color32, Rect, Sense, Stroke, StrokeKind, Ui, pos2, vec2};
|
||||
use serde_json::json;
|
||||
use soundcraft_model::{ClipContent, ClipId};
|
||||
use soundcraft_model::{ClipContent, ClipId, Tool};
|
||||
use soundcraft_time::TICKS_PER_QUARTER;
|
||||
|
||||
const KEY_W: f32 = 48.0;
|
||||
@@ -93,7 +93,7 @@ pub fn show(app: &mut SoundApp, ui: &mut Ui) {
|
||||
pos2(header.min.x + 110.0, header.center().y),
|
||||
Align2::LEFT_CENTER,
|
||||
format!(
|
||||
"{} · {} notes · {} selected · click: add · drag: move/select · arrows: move · Delete: remove",
|
||||
"{} · {} notes · {} selected · Pencil: add · drag: move/select · arrows: move · Delete: remove",
|
||||
clip.name,
|
||||
sequence.notes.len(),
|
||||
app.midi.selected.len()
|
||||
@@ -303,7 +303,7 @@ pub fn show(app: &mut SoundApp, ui: &mut Ui) {
|
||||
}
|
||||
// Audition on the instrument would go here (needs a live MIDI input path).
|
||||
}
|
||||
None => {
|
||||
None if s.edit.tool == Tool::Pencil => {
|
||||
let pitch = pitch_at(p.y).clamp(0, 127);
|
||||
let start = (((p.x - roll.min.x) / px_per_tick) as i64 / grid_ticks) * grid_ticks;
|
||||
let _ = app.run(
|
||||
@@ -312,6 +312,7 @@ pub fn show(app: &mut SoundApp, ui: &mut Ui) {
|
||||
);
|
||||
app.midi.selected.clear();
|
||||
}
|
||||
None => app.midi.selected.clear(),
|
||||
}
|
||||
}
|
||||
// Keyboard: Cmd+A select all; arrows transpose (Shift = octave) and move by the grid.
|
||||
|
||||
@@ -170,3 +170,34 @@ fn a_selected_video_clip_is_not_a_midi_target() {
|
||||
let (_, clip) = app.engine.session().find_clip(midi).unwrap();
|
||||
assert!(matches!(clip.content, ClipContent::Midi { .. }));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn only_pencil_inserts_notes_in_the_midi_roll() {
|
||||
use soundcraft_model::{ClipContent, Tool};
|
||||
|
||||
let mut app = SoundApp::new(soundcraft_engine::demo::demo_engine(), None, Services::default());
|
||||
app.ui.show_midi_editor = true;
|
||||
let created = app.run("midi.new_clip", json!({"track": "Keys", "start": 0, "length": 96000})).unwrap();
|
||||
let clip = created["clip"].as_u64().unwrap();
|
||||
app.run("edit.select", json!({"clips": [clip]})).unwrap();
|
||||
let ctx = egui::Context::default();
|
||||
for _ in 0..6 {
|
||||
frame(&ctx, &mut app, vec![]);
|
||||
}
|
||||
let body = panel(&ctx);
|
||||
let point = pos2(body.left() + 200.0, body.top() + 60.0);
|
||||
for tool in Tool::ALL.into_iter().filter(|tool| *tool != Tool::Pencil).chain([Tool::Pencil]) {
|
||||
app.run("edit.tool", json!({"tool": tool.id()})).unwrap();
|
||||
let before = app.engine.session().clone();
|
||||
frame(&ctx, &mut app, vec![Event::PointerMoved(point)]);
|
||||
frame(&ctx, &mut app, vec![button(point, true)]);
|
||||
frame(&ctx, &mut app, vec![button(point, false)]);
|
||||
let (_, edited) = app.engine.session().find_clip(soundcraft_model::ClipId(clip)).unwrap();
|
||||
let ClipContent::Midi { sequence } = &edited.content else { panic!("MIDI clip required") };
|
||||
if tool == Tool::Pencil {
|
||||
assert_eq!(sequence.notes.len(), 1);
|
||||
app.run("edit.undo", json!({})).unwrap();
|
||||
}
|
||||
assert!(*app.engine.session() == before, "{tool:?} click must not change the session");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user