Files
SonicForgeStudio/md/29_PANEL_ARRANGE.md

333 lines
13 KiB
Markdown

# 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`):
```text
┌──────────────────────────────────────────────────────────────────────────────────┐
│ 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`), using `overflow-x: auto` and `display: 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 with `flex-shrink: 0` and 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
```html
<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
```css
: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)
```javascript
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)
```javascript
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's `localStorage`, restoring the user's custom layout configuration on app reload.