Files
SonicForgeStudio/md/9_TRACK_UI.md
T

10 KiB

Technical Specification: Multi-Channel Layout Synchronization & Scroll Management (Unified DAW Layout & Sync Scroll)

This document analyzes and defines the structural hierarchy of the graphical user interface based on the real-world interface analysis. This specification serves to guide Frontend interface programming and porting to a Python Desktop application running inside a Docker container.


1. Structural Wireframe

Based on the visual analysis, the layout composition is split into vertically static and dynamic zones:

+───────────────────────────────────────────────────────────────────────────────+
| [ZONE A - STATIC] HEADER ZONE (Sticky - Permanently fixed when scrolling down)|
| +────────────────────+──────────────────────────────────────────────────────+ |
| | Channels & Tools   | Time Ruler Scale                                     | |
| |--------------------|------------------------------------------------------| |
| | Tempo Track Header | Tempo Grid Lane (120 BPM)                            | |
| +────────────────────+──────────────────────────────────────────────────────+ |
+───────────────────────────────────────────────────────────────────────────────+
| [ZONE B - DYNAMIC] TRACKS SCROLL WORKSPACE (Synchronized vertical scroll)     |
| +────────────────────+──────────────────────────────────────────────────────+ |
| | TCP - Track 01     | Waveform Lane - Track 01                             | |
| | TCP - Track 02     | Waveform Lane - Track 02                             | |
| | TCP - Track 03     | Waveform Lane - Track 03                             | |
| | ...                | ...                                                  | |
| +────────────────────+──────────────────────────────────────────────────────+ |
+───────────────────────────────────────────────────────────────────────────────+  ▲
                                                                                   │ [Vertical Scrollbar]
                                                                                   │ (Single unified scroll)
                                                                                   ▼


2. Layout Specifications

2.1. Fixed Header Zone (Green Border Area - Sticky Header)

  • Visual Scope: Encompasses the toolbar, the time ruler scale, and the Tempo Track Lane (indicated by the green bounding border in image_fbbd4e.png).
  • Graphical Sticky Behavior:
  • When a user adds dozens of tracks and scrolls downward, this entire zone must remain anchored to the top of the screen and is not permitted to slide out of view.
  • This ensures that users can continuously track the Ruler Seconds and the master project tempo (Tempo BPM) while editing tracks located deeper down the timeline.

2.2. Absolute Horizontal Row Alignment (Red Border Area - Row Alignment)

  • Interaction Scope: The exact matching pair consisting of the left Track Control Panel (TCP) and the right Waveform Lane of the same track (e.g., Track 4 inside the red border of image_fbbd4e.png).
  • Row Alignment Rules:
  • The corresponding TCP and Waveform Lane must have identical heights (H = 96\text{ px}).
  • These two elements must be wrapped within a single parent row container (Flex Row or Grid Row) to guarantee that during vertical scrolling, both move simultaneously along the exact same vertical axis coordinate (Y).
  • Row misalignment must be strictly avoided (e.g., situations where the Track 4 TCP sits higher or lower than the Track 4 Waveform lane).

2.3. Single Vertical Scrollbar Mandate

  • Issue to Avoid: Separating the TCP into an independent scrollable column and the Timeline into another independent scrollable column. Doing so leads to scroll-position desynchronization errors when a user drags the scrollbar.
  • Design Standard:
  • Only a single unified Vertical Scrollbar is permitted to appear on the absolute far right of the application window (as directed by the two red arrows in image_fbbd4e.png).
  • This vertical scrollbar moves the entire dynamic wrapper (Tracks Scroll Workspace), scrolling both TCPs and Waveform Lanes up or down in sync.

3. Implementation Guide

3.1. Web Frontend Integration (HTML / Tailwind CSS)

To group everything into one scrollbar while keeping the Tempo Track anchored at the top, use position: sticky and wrap the dynamic track list inside a single container:

<!-- Main Container (Entire Editor Wrapper) -->
<div class="flex flex-col h-full overflow-hidden">
  
  <!-- [ZONE A] Top Anchored Sticky Header Zone -->
  <div class="sticky top-0 z-40 bg-[#242424] border-b border-[#141414] shrink-0">
    <!-- Toolbar & Time Ruler -->
    <div class="h-8 flex">
      <div class="w-[300px] border-r border-zinc-900 px-4 flex items-center">CHANNELS</div>
      <div class="flex-1 relative h-full">...Ruler Numbers...</div>
    </div>
    <!-- Tempo Track (Green Border Area) -->
    <div class="h-[44px] flex border-t border-zinc-800 bg-[#212121]">
      <div class="w-[300px] border-r border-zinc-900 px-4 flex items-center justify-between">
        <span class="font-bold text-zinc-400">Tempo Track</span>
        <span class="bg-zinc-800 px-1.5 py-0.5 rounded text-[10px]">120 BPM</span>
      </div>
      <div class="flex-1">...Tempo Grid Lines...</div>
    </div>
  </div>

  <!-- [ZONE B] Dynamic Track Workspace (Single global vertical scrollbar on the far right) -->
  <div class="flex-1 overflow-y-auto bg-[#1a1a1a]">
    <div class="flex flex-col divide-y divide-[#141414]">
      
      <!-- Track Row Container (Absolute Horizontal Row Alignment) -->
      <div class="h-[96px] flex hover:bg-zinc-800/20 transition-colors">
        <!-- Left: TCP -->
        <div class="w-[300px] border-r border-zinc-900 p-2.5 flex-shrink-0">
          ...Controls (Mute, Solo, Volume, File Name)...
        </div>
        <!-- Right: Waveform Lane -->
        <div class="flex-1 relative overflow-hidden">
          ...Waveform Canvas...
        </div>
      </div>

      <!-- Add more track rows repeating the structure above... -->
      
    </div>
  </div>
</div>

3.2. Desktop App Integration (Python PyQt6)

When engineering this user interface using the Qt framework in Python, utilize a QScrollArea to encapsulate a QWidget managed by a layout of rows to control the single scrollbar behavior:

from PyQt6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QScrollArea, QLabel
from PyQt6.QtCore import Qt

class MasterDAWWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.main_layout = QVBoxLayout(self)
        self.main_layout.setContentsMargins(0, 0, 0, 0)
        self.main_layout.setSpacing(0)

        # 1. Initialize Fixed Header (Toolbar, Ruler, Tempo)
        self.header_widget = QWidget()
        self.header_widget.setFixedHeight(76) # 32px Ruler + 44px Tempo
        self.setup_header_ui()
        self.main_layout.addWidget(self.header_widget)

        # 2. Initialize Scroll Area for dynamic track rows
        self.scroll_area = QScrollArea()
        self.scroll_area.setWidgetResizable(True)
        # Force a single vertical scrollbar on the far right
        self.scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
        self.scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        
        # Widget container hosting the track list inside the Scroll Area
        self.tracks_container = QWidget()
        self.tracks_layout = QVBoxLayout(self.tracks_container)
        self.tracks_layout.setContentsMargins(0, 0, 0, 0)
        self.tracks_layout.setSpacing(0)
        self.tracks_layout.setAlignment(Qt.AlignmentFlag.AlignTop)

        self.scroll_area.setWidget(self.tracks_container)
        self.main_layout.addWidget(self.scroll_area)

    def add_track_row(self, track_id, track_name):
        """
        Appends a new track row. Uses QHBoxLayout to lock the TCP and Waveform Lane
        into absolute horizontal sync within the row.
        """
        row_widget = QWidget()
        row_widget.setFixedHeight(96)  # Rigid constraint for the entire row
        row_layout = QHBoxLayout(row_widget)
        row_layout.setContentsMargins(0, 0, 0, 0)
        row_layout.setSpacing(0)

        # Left: Track Control Panel (TCP)
        tcp_widget = QWidget()
        tcp_widget.setFixedWidth(300)
        # Setup TCP UI components...
        row_layout.addWidget(tcp_widget)

        # Right: Waveform Lane
        waveform_widget = QWidget()
        # Setup Waveform Canvas Painter...
        row_layout.addWidget(waveform_widget)

        self.tracks_layout.addWidget(row_widget)


4. Layout Architecture Advantages

  • Fluid User Experience: Eliminates row-stuttering or scrolling layout shifts between the control panels and audio visuals when a user scrolls through long track stacks rapidly.
  • Flawless Python Porting Compatibility: By wrapping the TCP and the Waveform Canvas inside a common row (QHBoxLayout in Qt or Flex Row in Web), the core widget tree hierarchy remains incredibly lean. This design removes the need to write custom coordinate bridging code to bind two separate scroll engines together.
  • Clean Interface Aesthetics: Safely protects the pixel rendering mapping ratios of the fixed time grids at the top, precisely matching the professional DAW interface conventions observed