13 KiB
13 KiB
DAW UI LAYOUT & PANEL SYSTEM ARCHITECTURE
This document details the interface layout solution (UI Layout Architecture), HTML/CSS structure, and interaction algorithms (Resizing, Scrolling) for a Hybrid DAW system, supporting responsive flexible scaling across Panels and the bottom dock strip.
1. Overall Layout Diagram (Grid Structure)
The application interface is structured around 3 main axes following an App Shell model (Viewport Locked 100vh):
┌──────────────────────────────────────────────────────────────────────────────────┐
│ Top Navigation & Transport Toolbar (Fixed Top Bar) │
├───────────────────────────────────────────────────────────┬──────────────────────┤
│ │ RIGHT COLUMN │
│ MAIN WORKSPACE │ (RIGHT SIDEBAR) │
│ ┌───────────────────────┬───────────────────────────────┐ │ ┌──────────────────┐ │
│ │ Track Control Panels │ Timeline / Audio Viewport │ │ │ Media Explorer │ │
│ │ (Track List) │ (Beat Grid & Waveforms) │ │ │ (Dynamic Height) │ │
│ │ │ │ │ ├──────────────────┤ │
│ │ │ │ │ │ AI Panel │ │
│ │ │ │ │ │ (Dynamic Height) │ │
│ └───────────────────────┴───────────────────────────────┘ │ └──────────────────┘ │
├───────────────────────────────────────────────────────────┴──────────────────────┤
│ BOTTOM DOCK PANEL STRIP - Horizontal Scroll (Overflow-X Auto) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Export Panel │ │ DSP Tools │ │ Panel 03 │ │ Panel 04... │ ──────► │
│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │
├──────────────────────────────────────────────────────────────────────────────────┤
│ Status Bar (Fixed Bottom Status) │
└──────────────────────────────────────────────────────────────────────────────────┘
2. Layout Region Details
A. Main Workspace (Center Region)
- Function: Contains the track list (Track Controls), timeline ruler (Timeline Ruler), and audio/MIDI display areas (Audio Waveform & Piano Roll Clip Grid).
- Behavior: Auto-expands (
flex-grow: 1) to fill the remaining screen space after subtracting the width of the Right Sidebar and the height of the Bottom Panel.
B. Bottom Panel Dock Strip (Bottom Row)
- Technical Specifications:
- Flexible Horizontal Scroll: The container has a fixed height (e.g.,
220px), usingoverflow-x: autoanddisplay: flex. - Sub-Panels: Houses a list of independent Card/Tile tools (Export Panel, Python DSP Tools Panel, Selection Panel, FX Panel, etc.).
- No Shrinking (
flex-shrink: 0): Each Sub-Panel is configured withflex-shrink: 0and a minimum width (min-width: 280px - 350px). When the combined width of all panels exceeds the screen width, a horizontal scrollbar appears automatically.
C. Right Resizable Sidebar (Multi-Panel Right Column)
- Technical Specifications:
- Width Resizing: The entire right column can be resized by dragging its left border (Border Left Drag Handle) to expand or collapse the visible space of the Main Workspace.
- Vertical Stacking: Houses stacked child panels (e.g., Media Explorer, AI Panel, Inspector, etc.).
- Independent Height Resizing: Horizontal splitters (Horizontal Splitter / Resizer Handle) sit between stacked child panels, allowing users to drag up/down to adjust height ratios between panels.
3. HTML & CSS Framework Implementation
HTML Core Structure
<div class="daw-app-shell">
<!-- Top Toolbar -->
<header class="daw-top-bar">...</header>
<!-- Body Middle Container -->
<div class="daw-body-container">
<!-- Main Center Viewport -->
<main class="daw-main-workspace">
<div class="track-headers-column">...</div>
<div class="timeline-canvas-viewport">...</div>
</main>
<!-- Vertical Resizer Handle (Adjusts Right Sidebar Width) -->
<div class="resizer-col-handle" id="col-resizer"></div>
<!-- Right Sidebar Container -->
<aside class="daw-right-sidebar" id="right-sidebar">
<!-- Panel 1: Media Explorer -->
<div class="sidebar-panel" id="panel-media-explorer">
<div class="panel-header">Media Explorer</div>
<div class="panel-content">...</div>
</div>
<!-- Horizontal Resizer Handle (Adjusts Panel Heights inside the Column) -->
<div class="resizer-row-handle" id="row-resizer-1"></div>
<!-- Panel 2: AI Panel -->
<div class="sidebar-panel" id="panel-ai">
<div class="panel-header">AI Panel</div>
<div class="panel-content">...</div>
</div>
</aside>
</div>
<!-- Bottom Panel Strip (Horizontal Scroll Container) -->
<footer class="daw-bottom-strip">
<div class="bottom-panel">Export Panel</div>
<div class="bottom-panel">Python DSP Tools Panel</div>
<div class="bottom-panel">Selection Panel</div>
<div class="bottom-panel">Plugin FX Rack Panel</div>
<div class="bottom-panel">MIDI Event List Panel</div>
</footer>
<!-- Status Bar -->
<div class="daw-status-bar">...</div>
</div>
CSS System Architecture
:root {
--right-sidebar-width: 320px;
--bottom-strip-height: 220px;
--top-bar-height: 80px;
--status-bar-height: 25px;
--panel-border-color: #2a2a2a;
}
/* Fullscreen Fixed App Shell */
.daw-app-shell {
display: flex;
flex-direction: column;
width: 100vw;
height: 100vh;
overflow: hidden;
background-color: #121212;
color: #e0e0e0;
}
/* Middle Section holding Main Workspace and Right Sidebar */
.daw-body-container {
display: flex;
flex: 1;
height: calc(100vh - var(--top-bar-height) - var(--bottom-strip-height) - var(--status-bar-height));
position: relative;
overflow: hidden;
}
/* Auto-expanding Main Workspace */
.daw-main-workspace {
flex: 1;
display: flex;
overflow: hidden;
}
/* Right Sidebar with Width controlled via CSS Variable */
.daw-right-sidebar {
width: var(--right-sidebar-width);
min-width: 200px;
max-width: 600px;
display: flex;
flex-direction: column;
background-color: #1a1a1a;
border-left: 1px solid var(--panel-border-color);
}
/* Vertically stacked child Panels in Right Sidebar */
.sidebar-panel {
display: flex;
flex-direction: column;
overflow: hidden;
background: #1e1e1e;
border-bottom: 1px solid var(--panel-border-color);
}
#panel-media-explorer {
height: 50%; /* Default 50/50 split */
min-height: 100px;
}
#panel-ai {
flex: 1; /* Fills remaining height */
min-height: 100px;
}
/* BOTTOM ROW: Enables Horizontal Scrolling */
.daw-bottom-strip {
height: var(--bottom-strip-height);
display: flex;
flex-direction: row;
align-items: center;
gap: 10px;
padding: 8px;
overflow-x: auto; /* Enables horizontal scroll when panels overflow */
overflow-y: hidden;
background-color: #161616;
border-top: 1px solid var(--panel-border-color);
white-space: nowrap;
}
/* Optimized custom horizontal scrollbar for DAW styling */
.daw-bottom-strip::-webkit-scrollbar {
height: 8px;
}
.daw-bottom-strip::-webkit-scrollbar-thumb {
background: #3a3a3a;
border-radius: 4px;
}
.daw-bottom-strip::-webkit-scrollbar-thumb:hover {
background: #00ffcc;
}
/* Sub-panels inside the bottom strip */
.bottom-panel {
flex: 0 0 auto; /* Prevents shrinking, locks content dimensions */
width: 320px;
height: 100%;
background-color: #222;
border: 1px solid #333;
border-radius: 6px;
box-sizing: border-box;
}
/* RESIZER HANDLES */
.resizer-col-handle {
width: 5px;
cursor: ew-resize; /* Horizontal resize cursor */
background: transparent;
transition: background 0.2s;
z-index: 10;
}
.resizer-col-handle:hover,
.resizer-col-handle:active {
background: #00ffcc;
}
.resizer-row-handle {
height: 5px;
cursor: ns-resize; /* Vertical resize cursor */
background: transparent;
transition: background 0.2s;
z-index: 10;
}
.resizer-row-handle:hover,
.resizer-row-handle:active {
background: #00ffcc;
}
4. Interaction Algorithms (JS Resizing Logic)
To handle smooth resizing without stuttering or dropped events when dragging over iframe or canvas elements, the algorithms rely on pointerdown, pointermove, and pointerup events.
A. Right Sidebar Width Resizing Algorithm (Horizontal Resizer)
const colResizer = document.getElementById('col-resizer');
const rightSidebar = document.getElementById('right-sidebar');
colResizer.addEventListener('pointerdown', (e) => {
e.preventDefault();
colResizer.setPointerCapture(e.pointerId);
const startX = e.clientX;
const startWidth = rightSidebar.getBoundingClientRect().width;
const onPointerMove = (moveEvent) => {
// Delta calculation: dragging left increases width, dragging right decreases width
const deltaX = startX - moveEvent.clientX;
const newWidth = Math.max(200, Math.min(600, startWidth + deltaX));
document.documentElement.style.setProperty('--right-sidebar-width', `${newWidth}px`);
};
const onPointerUp = (upEvent) => {
colResizer.releasePointerCapture(upEvent.pointerId);
colResizer.removeEventListener('pointermove', onPointerMove);
colResizer.removeEventListener('pointerup', onPointerUp);
};
colResizer.addEventListener('pointermove', onPointerMove);
colResizer.addEventListener('pointerup', onPointerUp);
});
B. Right Sidebar Panel Height Resizing Algorithm (Vertical Resizer)
const rowResizer = document.getElementById('row-resizer-1');
const topPanel = document.getElementById('panel-media-explorer');
rowResizer.addEventListener('pointerdown', (e) => {
e.preventDefault();
rowResizer.setPointerCapture(e.pointerId);
const startY = e.clientY;
const startHeight = topPanel.getBoundingClientRect().height;
const onPointerMove = (moveEvent) => {
const deltaY = moveEvent.clientY - startY;
const newHeight = Math.max(100, startHeight + deltaY);
topPanel.style.height = `${newHeight}px`;
topPanel.style.flex = 'none'; // Switch from flex ratio to fixed px during drag
};
const onPointerUp = (upEvent) => {
rowResizer.releasePointerCapture(upEvent.pointerId);
rowResizer.removeEventListener('pointermove', onPointerMove);
rowResizer.removeEventListener('pointerup', onPointerUp);
};
colResizer.addEventListener('pointermove', onPointerMove);
colResizer.addEventListener('pointerup', onPointerUp);
});
5. Summary of Solution Advantages
- Native Horizontal Scrolling: The bottom Dock area flexibly accommodates an unlimited number of Panels. Users can scroll horizontally (
Shift + Mouse Wheel) or use a trackpad to browse panels easily. - Smooth & Accurate Resizing: Utilizing Pointer Capture ensures drag interactions do not drop or break even when the cursor moves rapidly beyond the Resizer handle's bounds.
- Standardized CSS Variables: Enables easy persistence of layout states (
Width/Height) to the browser'slocalStorage, restoring the user's custom layout configuration on app reload.