refactor: single automation lane with parameter dropdown and fixed-height effects panel
Phase 9 Automation Improvements: - Replaced multiple automation lanes with single lane + parameter selector - Added dropdown in automation header to switch between parameters: - Track parameters: Volume, Pan - Effect parameters: Dynamically generated from effect chain - Lanes are created on-demand when parameter is selected - Effects panel now has fixed height (280px) with scroll - Panel no longer resizes when effects are expanded - Maintains consistent UI layout Technical changes: - Track.automation.selectedParameterId: Tracks current parameter - AutomationHeader: Added parameter dropdown props - AutomationLane: Passes parameter selection to header - Track.tsx: Single lane rendering with IIFE for parameter list - Effects panel: h-[280px] with flex layout and overflow-y-auto 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,10 @@ export interface AutomationHeaderProps {
|
||||
onHeightChange?: (delta: number) => void;
|
||||
className?: string;
|
||||
formatter?: (value: number) => string;
|
||||
// Parameter selection
|
||||
availableParameters?: Array<{ id: string; name: string }>;
|
||||
selectedParameterId?: string;
|
||||
onParameterChange?: (parameterId: string) => void;
|
||||
}
|
||||
|
||||
const MODE_LABELS: Record<AutomationMode, string> = {
|
||||
@@ -44,6 +48,9 @@ export function AutomationHeader({
|
||||
onHeightChange,
|
||||
className,
|
||||
formatter,
|
||||
availableParameters,
|
||||
selectedParameterId,
|
||||
onParameterChange,
|
||||
}: AutomationHeaderProps) {
|
||||
const modes: AutomationMode[] = ['read', 'write', 'touch', 'latch'];
|
||||
const currentModeIndex = modes.indexOf(mode);
|
||||
@@ -74,10 +81,24 @@ export function AutomationHeader({
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Parameter name */}
|
||||
<span className="text-xs font-medium text-foreground flex-1 min-w-0 truncate">
|
||||
{parameterName}
|
||||
</span>
|
||||
{/* Parameter name / selector */}
|
||||
{availableParameters && availableParameters.length > 1 ? (
|
||||
<select
|
||||
value={selectedParameterId}
|
||||
onChange={(e) => onParameterChange?.(e.target.value)}
|
||||
className="text-xs font-medium text-foreground flex-1 min-w-0 bg-background/50 border border-border/30 rounded px-1.5 py-0.5 hover:bg-background/80 focus:outline-none focus:ring-1 focus:ring-primary"
|
||||
>
|
||||
{availableParameters.map((param) => (
|
||||
<option key={param.id} value={param.id}>
|
||||
{param.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
) : (
|
||||
<span className="text-xs font-medium text-foreground flex-1 min-w-0 truncate">
|
||||
{parameterName}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{/* Current value display */}
|
||||
{currentValue !== undefined && (
|
||||
|
||||
@@ -16,6 +16,10 @@ export interface AutomationLaneProps {
|
||||
onUpdatePoint?: (pointId: string, updates: Partial<AutomationPointType>) => void;
|
||||
onRemovePoint?: (pointId: string) => void;
|
||||
className?: string;
|
||||
// Parameter selection
|
||||
availableParameters?: Array<{ id: string; name: string }>;
|
||||
selectedParameterId?: string;
|
||||
onParameterChange?: (parameterId: string) => void;
|
||||
}
|
||||
|
||||
export function AutomationLane({
|
||||
@@ -28,6 +32,9 @@ export function AutomationLane({
|
||||
onUpdatePoint,
|
||||
onRemovePoint,
|
||||
className,
|
||||
availableParameters,
|
||||
selectedParameterId,
|
||||
onParameterChange,
|
||||
}: AutomationLaneProps) {
|
||||
const canvasRef = React.useRef<HTMLCanvasElement>(null);
|
||||
const containerRef = React.useRef<HTMLDivElement>(null);
|
||||
@@ -302,6 +309,9 @@ export function AutomationLane({
|
||||
onUpdateLane?.({ height: newHeight });
|
||||
}}
|
||||
formatter={lane.valueRange.formatter}
|
||||
availableParameters={availableParameters}
|
||||
selectedParameterId={selectedParameterId}
|
||||
onParameterChange={onParameterChange}
|
||||
/>
|
||||
|
||||
{/* Lane canvas area */}
|
||||
|
||||
Reference in New Issue
Block a user