feat: click note focuses its MIDI item in piano roll
This commit is contained in:
+31
-4
@@ -5919,6 +5919,7 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, activeTracks, onClos
|
||||
const [showGhostNotes, setShowGhostNotes] = React.useState(true);
|
||||
const [sessionSyncMode, setSessionSyncMode] = React.useState(true);
|
||||
const [activePlayTrackIds, setActivePlayTrackIds] = React.useState([]);
|
||||
const [focusItemId, setFocusItemId] = React.useState(st.target_id);
|
||||
|
||||
const allMidiItems = React.useMemo(() => {
|
||||
const result = [];
|
||||
@@ -6256,8 +6257,8 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, activeTracks, onClos
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
// Determine which MIDI item is focused (selected note → opened item; playing → item under playhead)
|
||||
var focusedItemId = st.target_id;
|
||||
// Determine which MIDI item is focused (clicked/selected note → its item; playing → item under playhead)
|
||||
var focusedItemId = focusItemId || st.target_id;
|
||||
if (selectedNoteIds && selectedNoteIds.length > 0) {
|
||||
focusedItemId = st.target_id;
|
||||
} else if (st.isPlaying && st.currentTime != null && activeTracks) {
|
||||
@@ -6382,7 +6383,7 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, activeTracks, onClos
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
}, [notes, snapValue, rollZoom, selectedNoteIds, selectionMarquee, st.currentTime, bpm, viewWidth, viewBeats, recordingState, recTempMidiNotes, showGhostNotes, sessionSyncMode, ghostLayers, renderBeatOffset, renderTick, activeTracks]);
|
||||
}, [notes, snapValue, rollZoom, selectedNoteIds, selectionMarquee, st.currentTime, bpm, viewWidth, viewBeats, recordingState, recTempMidiNotes, showGhostNotes, sessionSyncMode, ghostLayers, renderBeatOffset, renderTick, activeTracks, focusItemId]);
|
||||
|
||||
React.useLayoutEffect(() => {
|
||||
const canvas = ccCanvasRef.current;
|
||||
@@ -6463,6 +6464,11 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, activeTracks, onClos
|
||||
setSubTabs(function(prev) { return prev.map(function(s) { if (s.id !== st.id) return s; return Object.assign({}, s, { ghostPlayLayers: layers }); }); });
|
||||
}, [ghostLayers, activePlayTrackIds, sessionSyncMode, showGhostNotes, st.id, activeTracks]);
|
||||
|
||||
// Reset item focus when the opened MIDI item changes
|
||||
React.useEffect(function() {
|
||||
setFocusItemId(st.target_id);
|
||||
}, [st.id, st.target_id]);
|
||||
|
||||
const handleGridMouseDown = (e) => {
|
||||
const canvas = canvasRef.current;
|
||||
if (!canvas) return;
|
||||
@@ -6618,7 +6624,8 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, activeTracks, onClos
|
||||
}
|
||||
|
||||
if (clickedNoteIdx !== -1) {
|
||||
// Click on existing note: drag-move
|
||||
// Click on existing note: drag-move → focus its MIDI item
|
||||
setFocusItemId(st.target_id);
|
||||
const clickedNote = notes[clickedNoteIdx];
|
||||
let nextSelectedIds;
|
||||
if (!selectedNoteIds.includes(clickedNote.id)) {
|
||||
@@ -6645,6 +6652,26 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, activeTracks, onClos
|
||||
clickedOriginalStartBeat: clickedNote.start_beat
|
||||
});
|
||||
} else {
|
||||
// Click on a same-track ghost note → focus that MIDI item (no drawing)
|
||||
if (!e.ctrlKey && !e.shiftKey && !e.altKey) {
|
||||
var ghostHit = null;
|
||||
for (var gi = 0; gi < ghostLayers.length; gi++) {
|
||||
var gl = ghostLayers[gi];
|
||||
if (!gl.isSameTrack || !gl.notes) continue;
|
||||
for (var gn = 0; gn < gl.notes.length; gn++) {
|
||||
var gnote = gl.notes[gn];
|
||||
if (pitch === gnote.pitch && beat >= gnote.relative_start_beat && beat < gnote.relative_start_beat + (gnote.duration_beats || 1)) {
|
||||
ghostHit = gnote;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ghostHit) break;
|
||||
}
|
||||
if (ghostHit) {
|
||||
setFocusItemId(ghostHit.item_id || st.target_id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Click on empty space with pen tool: DRAW a new note (brush mode with visitedPitches)
|
||||
pushToUndo(notes);
|
||||
const start = getSnapBeat(beat, snapValue);
|
||||
|
||||
Reference in New Issue
Block a user