feat(ui): add Drum channel toggle button on track panel

- toggleTrackDrum: sets is_percussion + soundfont_bank=128
- 🥁 button in track control panel (between Solo and Record)
- Shows 'D' badge when active, routes to MIDI channel 9
- Instrument preset list shows 🥁 prefix for bank=128 presets
This commit is contained in:
2026-07-26 17:11:42 +07:00
parent 96aa76f194
commit c2bfeb7163
+20 -1
View File
@@ -11460,6 +11460,18 @@ const App = () => {
}); });
setTimeout(() => lucide.createIcons(), 50); setTimeout(() => lucide.createIcons(), 50);
}; };
const toggleTrackDrum = trackId => {
setTracks(prev => prev.map(t => t.id === trackId ? {
...t,
is_percussion: !t.is_percussion,
soundfont_bank: !t.is_percussion ? 128 : (t._saved_sf_bank !== undefined ? t._saved_sf_bank : 0),
synth_engine: t.synth_engine ? {
...t.synth_engine,
soundfont_bank: !t.is_percussion ? 128 : 0
} : t.synth_engine
} : t));
setTimeout(() => lucide.createIcons(), 50);
};
const updateTrackVolumeDb = (trackId, val) => { const updateTrackVolumeDb = (trackId, val) => {
const beforeSnap = captureTrackSnapshot(trackId); const beforeSnap = captureTrackSnapshot(trackId);
setTracks(prev => prev.map(t => t.id === trackId ? { setTracks(prev => prev.map(t => t.id === trackId ? {
@@ -15535,6 +15547,13 @@ const App = () => {
title: "Solo", title: "Solo",
className: `px-1.5 py-0.5 text-[10px] rounded font-mono font-bold border transition flex items-center gap-0.5 ${soloedTrackId === track.id || track.solo ? 'bg-amber-950 text-amber-400 border-amber-600' : 'bg-zinc-800 text-zinc-400 border-transparent hover:text-zinc-200'}` className: `px-1.5 py-0.5 text-[10px] rounded font-mono font-bold border transition flex items-center gap-0.5 ${soloedTrackId === track.id || track.solo ? 'bg-amber-950 text-amber-400 border-amber-600' : 'bg-zinc-800 text-zinc-400 border-transparent hover:text-zinc-200'}`
}, /*#__PURE__*/React.createElement("i", { "data-lucide": soloedTrackId === track.id || track.solo ? "headphones" : "headphone-off", className: "w-3 h-3" })), /*#__PURE__*/React.createElement("button", { }, /*#__PURE__*/React.createElement("i", { "data-lucide": soloedTrackId === track.id || track.solo ? "headphones" : "headphone-off", className: "w-3 h-3" })), /*#__PURE__*/React.createElement("button", {
onClick: e => {
e.stopPropagation();
toggleTrackDrum(track.id);
},
title: track.is_percussion ? "Drum Channel (CH 10) - Click to disable" : "Toggle Drum Channel (CH 10)",
className: `px-1.5 py-0.5 text-[9px] rounded font-mono font-bold border transition flex items-center gap-0.5 ${track.is_percussion ? 'bg-rose-900 text-rose-300 border-rose-700' : 'bg-zinc-800 text-zinc-500 border-transparent hover:text-zinc-300'}`
}, /*#__PURE__*/React.createElement("span", { className: "text-[11px]" }, "🥁"), track.is_percussion ? /*#__PURE__*/React.createElement("span", { className: "text-[9px]" }, "D") : null), /*#__PURE__*/React.createElement("button", {
onClick: e => { onClick: e => {
e.stopPropagation(); e.stopPropagation();
toggleTrackArm(track.id); toggleTrackArm(track.id);
@@ -16866,7 +16885,7 @@ const App = () => {
key: i, key: i,
onClick: () => setTrackInstrumentWithProgram(instrumentSelectorTrackId, selectedSoundFontId, p.program, p.name || 'Preset ' + p.program, p.bank), onClick: () => setTrackInstrumentWithProgram(instrumentSelectorTrackId, selectedSoundFontId, p.program, p.name || 'Preset ' + p.program, p.bank),
className: "text-left px-2 py-1 text-[10px] rounded bg-zinc-800/60 hover:bg-amber-800 text-zinc-300 truncate" className: "text-left px-2 py-1 text-[10px] rounded bg-zinc-800/60 hover:bg-amber-800 text-zinc-300 truncate"
}, p.name || 'Preset ' + p.program) }, p.bank === 128 ? /*#__PURE__*/React.createElement("span", { className: "mr-1" }, "🥁") : null, p.name || 'Preset ' + p.program)
)) ))
) : ( ) : (
React.createElement("p", { className: "text-[10px] text-zinc-500 py-2" }, "No presets found.") React.createElement("p", { className: "text-[10px] text-zinc-500 py-2" }, "No presets found.")