{/* ══ LEFT COLUMN: TCP PANEL ══ */}
Kênh {/* Timeline Toolbar */}
{/* Separator */}
{/* Quick Actions (Glue, Cut, Copy, Paste) */}
{/* Snap Section */}
Snap
{/* Right Side: Time Ruler */}
{Array.from({ length: Math.ceil(maxDuration) }).map((_, i) => { const sec = i; const x = sec * zoom; return (
{formatTime(sec)}
); })}
{/* [ZONE A] Tempo Track Row */}
{/* Left Side: Tempo TCP */}
TM Tempo Track
setBpm(e.target.value)} onBlur={() => localStorage.setItem('studio_bpm', bpm)} className="w-12 bg-zinc-800 border border-zinc-700 rounded text-[10px] text-zinc-300 text-center font-mono focus:outline-none focus:border-purple-500" min="40" max="300" /> BPM
{/* Right Side: Tempo Lane */}
{/* [ZONE B] Dynamic Track List Workspace */}
{tracks.map((track, idx) => { const isSelected = selectedTrackId === track.id; return (
{/* Left Column: TCP */}
setSelectedTrackId(track.id)} className={`w-[300px] sticky left-0 z-10 p-2.5 flex flex-col justify-between bg-[#1e1e1e] border-r border-zinc-900 shrink-0 cursor-pointer border-l-4 overflow-hidden ${isSelected ? 'border-cyan-500 bg-[#252525]' : 'border-transparent hover:bg-zinc-800/20'}`} >
{(idx+1).toString().padStart(2, '0')}
{track.name}
e.stopPropagation()}> Mô phỏng:
e.stopPropagation()}>
updateTrackVolume(track.id, v)} /> Gain: {Math.round(track.volume * 100)}%
loadFileOnTrack(track.id, e.target.files[0])} />
{/* Right Column: Waveform Lane */}
e.preventDefault()} onDrop={(e) => { e.preventDefault(); if (e.dataTransfer.files[0]) { loadFileOnTrack(track.id, e.dataTransfer.files[0]); } }} onMouseEnter={() => setHoveredTrackId(track.id)} > {track.buffer && (
)}
); })} {/* Bottom Drop Zone to create new track */}
{ if (draggedClipRef.current) { const newId = addNewTrack(); setHoveredTrackId(newId); } }} onClick={addNewTrack} > Kéo clip xuống đây hoặc Click để tạo Track mới
{/* Selection Overlay - only for Global mode (LOOP_EDITOR.md §1.2: local draws on canvas per-track) */} {selectionMode !== 'local' && selLeft !== null && selRight !== null && selRight > selLeft && (
handleHandleDragStart(e, 'left')} title="Kéo giãn mốc bắt đầu">
handleHandleDragStart(e, 'right')} title="Kéo giãn mốc kết thúc">
)} {/* Playhead */}
{/* ── Footer ── */}