Docs: Expand guide to ASCII UI Layout Map DSL with detailed sections

This commit is contained in:
ed
2026-06-13 16:49:09 -04:00
parent 9c650d0554
commit fd1de30c5c
+196 -108
View File
@@ -1,185 +1,273 @@
# Guide to ASCII UI Layout Maps (DSL) # Guide to ASCII UI Layout Maps (DSL)
This guide defines the syntax, visual vocabulary, and operational conventions of the **ASCII UI Layout Map DSL** used in the Manual Slop codebase. This DSL serves as a text-side design contract between the specification phase and the immediate-mode ImGui rendering implementation in `src/gui_2.py` and other UI components. This document provides a comprehensive specification and reference manual for the **ASCII UI Layout Map DSL** used in the Manual Slop application. It establishes the conventions, visual grammar, widget vocabulary, and advanced techniques required to model dear imgui interfaces in structured text.
--- ---
## 1. Rationale: Why ASCII for ImGui? ## 1. Core Paradigm: Text-Side UI Contracts
Immediate-mode graphical user interfaces (IMGUIs) like dear imgui have three properties that make them highly compatible with structured ASCII text representations: Manual Slop is built around a thread-safe, immediate-mode render pipeline in `src/gui_2.py`. In an environment where AI developer-agents operate with text-based tools and cannot directly view or interact with the runtime window, graphical user interfaces must be modeled as structured, human-auditable text contracts.
1. **Rectilinear Layouts:** IMGUI widgets are strictly rectangular, aligned horizontally or vertically, and positioned deterministically. The ASCII UI Layout Map DSL solves this problem by defining a strict visual grammar. Because Dear ImGui layouts are rectilinear, immediate-mode, and deterministic, they map directly to rectangular text blocks. By pairing a visual **ASCII Layout Map** with an operational **SSDL (Spec/Sketch Description Language)** DAG, we can fully specify both the layout structure and the logic flow of a panel before writing any Python code.
2. **Regular Grammar:** Widget patterns (collapsible trees, sliders, combos, and tables) follow standard, recurring visual cues.
3. **Information-Dense, Not Ornate:** Layout Maps focus on *what information is presented and how it is structured*, rather than pixel-perfect colors, paddings, or border-radius values.
Using ASCII Layout Maps allows developer-agents and users to share, iterate, and lock down user interface specifications directly within the text medium before committing to complex GUI implementation.
--- ---
## 2. Core Conventions & Vocabulary ## 2. Exhaustive Widget Vocabulary
The ASCII UI Layout Map DSL uses a fixed set of symbols to represent standard ImGui controls. To maintain visual clarity, the DSL maps ImGui widgets to specific text representations.
### Widget Lexicon ### 2.1 The Widget Reference Table
| Widget Class | ASCII Symbol | Example | Specification | | ImGui Widget Type | Python Code Example | ASCII Layout Representation | Notes / Alignment Rules |
|---|---|---|---| |---|---|---|---|
| **Window Container** | `=...=` | `+=== My Window ===+` | Represents a top-level OS or ImGui window wrapper. | | **Window Frame** | `imgui.begin("Title")` | `+================= Title =================+` | Top/bottom borders use double horizontal bars or thick lines. |
| **Child Panel / Pane** | `+---+` | `+----------------+` | Represents a scrollable or bounded child section (`imgui.begin_child`). | | **Child Panel** | `imgui.begin_child("id")` | `+-----------------------------------------+` | Standard single-line border mapping child boundaries. |
| **Button** | `[Label]` | `[Save]` | Bounded by square brackets; no internal padding by default. | | **Button** | `imgui.button("Save")` | `[Save]` | Square bracket boundaries. Fits text exactly. |
| **Checkbox (Unchecked)**| `[ ]` | `[ ] Word-wrap` | Interactive checkbox in the off/inactive state. | | **Checkbox (Off)** | `imgui.checkbox("A", False)` | `[ ] Option A` | Box containing a space, followed by the label. |
| **Checkbox (Checked)** | `[X]` or `[✓]` | `[X] Auto-Scroll` | Interactive checkbox in the on/active state. | | **Checkbox (On)** | `imgui.checkbox("B", True)` | `[X] Option B` or `[] Option B` | Box containing `X` or checkmark `✓`. |
| **Radio Button (Off)** | `( )` | `( ) Global` | Mutually exclusive option in the inactive state. | | **Radio Button (Off)**| `imgui.radio_button("X", False)`| `( ) Choice X` | Parentheses containing a space, followed by the label. |
| **Radio Button (On)** | `(o)` or `(•)` | `(o) Project` | Mutually exclusive option in the active state. | | **Radio Button (On)** | `imgui.radio_button("Y", True)` | `(o) Choice Y` or `() Choice Y` | Parentheses containing `o` or bullet `•`. |
| **Dropdown / Combo** | `[Value v]` | `[gemini v]` | The lowercase `v` indicates a dropdown picker. | | **Dropdown / Combo** | `imgui.combo("##c", 0, opts)` | `[Selected Value v]` | Lowercase `v` represents the dropdown arrow. |
| **Dropdown (Selected)**| `[Label: Value v]` | `[Role: AI v]` | Displays both the field name and its active selection. | | **Named Dropdown** | `imgui.combo("Role", 1, roles)`| `[Role: Selected Value v]` | Combines parameter name with current selection. |
| **Text Input (Single)**| `|Value|` | `|C:\projects\slop|`| Bounded by pipes (`\|`), representing a text input field. | | **Text Input Box** | `imgui.input_text("##t", val)`| `|Current Value_______________________|` | Bounded by pipes (`\|`), underscores denote empty space. |
| **Slider / Drag Int** | `[===-----]` | `[=====---] 62%` | Represents a slider or drag-float/int showing current progress. | | **Slider / Drag** | `imgui.slider_float("##s", v)` | `[=======----------------] 0.70` | Shows progress track, slider handle, and numerical label. |
| **Tree Node (Closed)** | `> Label` | `> file_io` | A collapsible header or directory node in the collapsed state. | | **Closed Tree Node** | `imgui.tree_node("node")` | `> Node Label` | The `>` symbol denotes a collapsed section. |
| **Tree Node (Open)** | `v Label` | `v file_io` | A collapsible header or directory node in the expanded state. | | **Open Tree Node** | `imgui.tree_node("node")` | `v Node Label` | The lowercase `v` denotes an expanded section. |
| **Table / Columns** | `\|` | `\| Name \| Size \|` | Columns separated by single pipes, indicating a tabular layout. | | **Table Grid** | `imgui.table_next_column()` | `\| Cell 1 \| Cell 2 \|` | Cell bounds delimited by pipes (`\|`). |
| **Separator** | `---` | `---` | A horizontal rule (`imgui.separator`). | | **Separator** | `imgui.separator()` | `---` | Standard horizontal dividing rule. |
| **Truncation Marker** | `...` | `...rest of 8KB...` | Indicates content or elements cropped out for layout brevity. |
--- ---
## 3. High-Resolution Challenges & Advanced Techniques ## 3. Layout Mathematics & Spacing Alignment
When a panel is highly complex, dense, or dynamically nested, a single, low-resolution ASCII map may fail to convey the necessary layout details. In these scenarios, the DSL utilizes three advanced layout techniques: **Feature Zooming**, **Grid-Based Focus**, and **State Multiplicity Annotation**. ImGui's layout calculations (such as wrapping, horizontal nesting, and right-alignment) are captured in the ASCII DSL using specific alignment conventions.
### 3.1 Feature Zooming ### 3.1 Horizontal Nesting (`imgui.same_line()`)
In ImGui, widgets stack vertically by default. To place widgets on the same horizontal line, `imgui.same_line()` is invoked. In the ASCII DSL, this is represented by placing the brackets on the same text line separated by explicit spacing.
Feature Zooming decomposes a complex interface into a parent macro-layout and multiple zoomed micro-layouts. The macro-layout uses a descriptive placeholder badge `[Zoom: Component Name]` to signal that a detailed sub-layout exists below. #### Python Code
```python
#### Macro-Layout (High-Level Grid) imgui.text("Model Parameter:")
``` imgui.same_line()
+========================= Workspace Hub =========================+ imgui.set_next_item_width(120)
| Tabs: [Discussion] [Files] [Settings] | imgui.combo("##model", active_idx, models)
+-----------------------------------------------------------------+ imgui.same_line()
| | if imgui.button("Reset"):
| [Zoom: Files Sidebar] | [Zoom: Details Editor] | reset_model()
| | |
+=================================================================+
``` ```
#### Micro-Layout: Zoom 1 (Files Sidebar) #### ASCII Layout Representation
``` ```
[Zoom: Files Sidebar] Model Parameter: [gemini-1.5-flash v] [Reset]
+--------------------------+
| Filter: |*.py| |
| v src |
| [x] gui_2.py (8KB) |
| [ ] ai_client.py (4KB) |
| > tests |
+--------------------------+
``` ```
#### Micro-Layout: Zoom 2 (Details Editor) ### 3.2 Right Alignment & Viewport Widths
To convey width ratios, the map uses proportional spacing. If a button is aligned to the right edge of a panel, it is placed at the far right of the ASCII boundary box.
#### Proportional Width Mappings
* **Fill Available:** `|Text Input Field_______________________________|` (width extends to boundary)
* **Fixed Width:** `[Close]` (width matches the label length)
* **Proportional Split:**
``` ```
[Zoom: Details Editor]
+-------------------------------------------------------------+ +-------------------------------------------------------------+
| Active: gui_2.py | | Left Column (40%) | Right Column (60%) |
| File Mode: [masked v] [Force Full] [x] Auto-Aggregate | | |Input A________________| | |Input B_____________________| |
+-------------------------------------------------------------+
```
---
## 4. Advanced High-Resolution Techniques
When laying out complex, feature-dense screens, a standard single-pane ASCII wireframe will run out of resolution. The DSL utilizes three advanced techniques to handle high-density layouts.
### 4.1 Feature Zooming (Macro/Micro Decomposition)
Feature Zooming decomposes a master interface into a parent macro-layout and multiple zoomed micro-layouts. The parent layout references zoomed sections using a target badge `[Zoom: Unique Name]`.
#### Macro-Layout (The Orchestration Dashboard)
```
+============================== Conductor Dashboard =============================+
| [Conductor Setup] [Epic Planner] |
+------------------------------------+-------------------------------------------+
| | |
| [Zoom: Conductor Track Sidebar] | [Zoom: Task Execution Pane] |
| | |
+------------------------------------+-------------------------------------------+
| [Zoom: Token Budget Footer] |
+================================================================================+
```
#### Micro-Layout: Zoom 1 (Conductor Track Sidebar)
```
[Zoom: Conductor Track Sidebar]
+----------------------------------+
| Track Browser: |
| v ACTIVE TRACKS |
| (o) mcp_refactor [======] 40%|
| ( ) type_strengths [ ] 0%|
| > COMPLETED TRACKS |
| > ARCHIVED TRACKS |
+----------------------------------+
```
#### Micro-Layout: Zoom 2 (Task Execution Pane)
```
[Zoom: Task Execution Pane]
+-------------------------------------------------------------+
| Active: mcp_refactor |
| Target Tier: [Tier 2 Tech Lead v] |
| --- | | --- |
| Fuzzy Anchor Slices: | | Ticket Queue: |
| [New Slice] | | [✓] t2_1: Extract File IO (Ready) |
| | #L12-30: class App | | | [✓] t2_2: Extract Python (Blocked) |
| +---------------------------------------------------------+ |
| | [I:ticket_details] -> [B:approve_spawn] => [B:execute] | |
| +---------------------------------------------------------+ |
| [Execute Selected] [Skip Selected] |
+-------------------------------------------------------------+ +-------------------------------------------------------------+
``` ```
--- ---
### 3.2 Grid-Based Focus Layouts ### 4.2 Grid-Based Focus Layouts
Grid-Based Focus overlays a logical coordinate system (columns `A, B, C...` and rows `1, 2, 3...`) onto the layout map. This is particularly useful for specifying precise immediate-mode alignment (`imgui.same_line()`) and relative widths under high layout density. For complex table configurations or form layouts, the DSL overlays a coordinate grid (Columns `A, B, C...` and Rows `1, 2, 3...`). This coordinates precise width constraints, alignment boundaries, and event triggers.
``` ```
Grid Focus Map: Grid Focus Map:
A B C A (30%) B (50%) C (20%)
+-----------------------+----------------------+--------------------+ +------------------------+-------------------------+--------------------+
1 | Preset: [default v] | [Save Preset] | [Delete] | 1 | Provider: [gemini v] | Model: [1.5-flash v] | Status: [Local] |
+-----------------------+----------------------+--------------------+ +------------------------+-------------------------+--------------------+
2 | Temp: [=============] | [ ] Show Advanced | 2 | Temp: [=====-----] 0.7 | Top-P: [===-------] 0.4 | [Reset Defaults] |
+-----------------------+-------------------------------------------+ +------------------------+-------------------------+--------------------+
``` ```
#### Alignment & Layout Matrix #### Grid Alignment Reference
* **Row 1:** * **Cell A1:** Combobox for provider selection. Spans exactly 30% of the table width.
* `A1`: Width 40% of viewport. Combo box selecting layout presets. * **Cell B1:** Combobox for model selection. Spans exactly 50% of the table width, aligned horizontally with A1.
* `B1`: `same_line()` called with 10px spacing. Fixed-width button. * **Cell C1:** Status badge. Right-aligned inside its column with a green success color tint.
* `C1`: `same_line()` called, right-aligned to content region edge. Fixed-width warning-tinted button. * **Cell A2/B2:** Numeric parameter sliders. Underneath Row 1, matching column boundaries.
* **Row 2:** * **Cell C2:** Action button. Right-aligned, triggers parameter resets.
* `A2`: Width 60% of viewport. Float slider for temperature.
* `B2`: `same_line()` called. Toggle checkbox spanning the remaining region.
--- ---
### 3.3 State Multiplicity Annotation ### 4.3 State Multiplicity Annotation
Immediate-mode UI layouts change shape based on state variables (e.g. read mode vs. edit mode). A Layout Map can document these variations by appending a `[State: Variable == Value]` condition block above or inline with the layout. GUI elements often mutate structure based on runtime state variables. Rather than cluttering a single ASCII sketch with multiple options, separate sketches are annotated with `[State: Condition]` expressions.
#### Read Mode Layout #### Read-Only State Layout
``` ```
[State: app.discussion_mode == "read"] [State: app.show_editing_panel == False]
+-----------------------------------------------------------------+ +-----------------------------------------------------------------+
| [Role: User] @ 12:34:56 [Edit] | | System Prompt: coding-assistant |
| | | "You are an AI coding assistant designed to solve tasks..." |
| "How does the RAG aggregation logic handle file summaries?" | | [Edit Prompt] |
+-----------------------------------------------------------------+ +-----------------------------------------------------------------+
``` ```
#### Edit Mode Layout #### Editing State Layout
``` ```
[State: app.discussion_mode == "edit"] [State: app.show_editing_panel == True]
+-----------------------------------------------------------------+ +-----------------------------------------------------------------+
| [Role: User v] @ 12:34:56 [Read] | | System Prompt: coding-assistant |
| |
| +-------------------------------------------------------------+ | | +-------------------------------------------------------------+ |
| | How does the RAG aggregation logic handle file summaries? | | | | You are an AI coding assistant designed to solve tasks... | |
| +-------------------------------------------------------------+ | | +-------------------------------------------------------------+ |
| [Save Changes] [Discard] | | [Save Changes] [Cancel] |
+-----------------------------------------------------------------+ +-----------------------------------------------------------------+
``` ```
--- ---
## 4. Integration with SSDL (DAG Context) ## 5. Integration with SSDL (Spec/Sketch Description Language)
ASCII Layout Maps must correspond to the **SSDL (Spec/Sketch Description Language)** operational flow defined in the function's docstring. SSDL maps the control flow and data mutation path through the immediate-mode graph. SSDL defines the operational control flow and data mutation path through the immediate-mode graph. Every docstring in `gui_2.py` must align its visual **ASCII Layout Map** with its functional **SSDL** flow.
### Mapping SSDL Primitives to Layout Widgets ### 5.1 SSDL Primitive Dictionary
* `[I:widget_name]` (Instruction) maps to a static widget, label, or display field. * `[I:name]` (Instruction): Represents a passive rendering unit (labels, static text, or headers).
* `[B:widget_name]` (Branch) maps to interactive elements (e.g., checkboxes, dropdowns, popups) that fork control flow or toggle visibility of subsequent blocks. * `->` (Sequential path): Represents linear vertical or horizontal flow.
* `[S:widget_name]` (Stateful Mutation) maps to input fields, sliders, or action buttons that alter values on the `App` or `Controller` state. * `=>` (Wide path): Denotes parallel branches, such as columns, tables, or tab item rendering.
* `=>` (Wide path) maps to multi-column layouts, tables, or tabs where rendering branches concurrently. * `[B:name]` (Branch): Points to conditional widgets (checkboxes, popups, or expandable trees).
* `[S:name]` (Stateful Mutation): Represents inputs, sliders, or buttons that modify data.
* `[Q:name]` (State Query): Reads parameters from the App config or state.
* `[N:name]` (Nil Sentinel): Represents safety check values to prevent rendering crashes.
#### Example Alignment ### 5.2 Side-by-Side SSDL-to-ASCII Alignment
The SSDL sequence operates as a code-path map for the corresponding layout widgets:
```python ```python
def render_example_panel(app: App) -> None: def render_example(app: App) -> None:
"""Renders a simple model parameter panel. """Renders the RAG status and rebuild control.
SSDL: `[I:header] -> [B:enable_override] -> [S:temp_slider] => [B:status_badge]` SSDL: `[Q:rag_enabled] -> [B:rag_checkbox] -> [I:status_label] => [S:rebuild_btn]`
ASCII Layout Map: ASCII Layout Map:
+---------------------------------------------------------+ +---------------------------------------------------------+
| Model Parameters | <- [I:header] | [X] Enable RAG Subsystem | <- [B:rag_checkbox] (reads [Q:rag_enabled])
| [X] Override Default Parameters | <- [B:enable_override] | Status: READY | Chunk Size: 512 | <- [I:status_label]
| Temperature: [=======---------] 0.70 | <- [S:temp_slider] (indented if enabled) | [Rebuild Vector Index] | <- [S:rebuild_btn]
| --- |
| Status: READY | <- [B:status_badge] (green if ready)
+---------------------------------------------------------+ +---------------------------------------------------------+
""" """
``` ```
--- ---
## 5. Development & Verification Loop ## 6. Step-by-Step Collaborative Design Workflow
When modifying or implementing layout panels, developers must follow a strict verification sequence to ensure that layout maps align with source code without introducing runtime bugs: To align implementations with user intent, developer-agents and human partners follow a 5-step workflow:
1. **AST Check:** Run `py_check_syntax` on the modified file immediately after editing the docstrings. ```mermaid
2. **Regression Check:** Run `pytest tests/` to confirm that docstring formatting changes have not caused runtime syntax or encoding errors. graph TD
3. **Fidelity Comparison:** Under the `Puppeteer` testing pattern, run visual simulations to capture actual ImGui viewport coordinates and ensure they correspond to the rows, columns, and zoom structures mapped in the ASCII DSL contract. A[Step 1: Pick Target Panel] --> B[Step 2: Establish Boundaries]
B --> C[Step 3: Initial ASCII Draft]
C --> D{Step 4: Critique & Iterate}
D -- Refine Sketch --> C
D -- Approved --> E[Step 5: Lock Design Contract]
```
### Collaborative Dialogue Example
1. **Step 1 (Agent):** Proposes target: "Let's update the layout for the Workspace Profile Saver."
2. **Step 2 (Human):** Establishes boundaries: "Yes, it must fit inside a popup modal, require a profile name, and have checkable scopes for Window Layout and Project Settings."
3. **Step 3 (Agent):** Drafts initial ASCII sketch:
```
+---------------------------------------------------------+
| Save Workspace Profile [X] |
+---------------------------------------------------------+
| Name: |my-profile_____________________________________| |
| Scopes: |
| [X] Window Positions & Layouts |
| [X] Active Project Settings |
| [Save Profile] [Cancel] |
+---------------------------------------------------------+
```
4. **Step 4 (Human):** Critiques: "The Save and Cancel buttons should be aligned to the right, and let's add a scope for Provider configuration."
5. **Step 4 (Agent):** Redrafts the sketch:
```
+---------------------------------------------------------+
| Save Workspace Profile [X] |
+---------------------------------------------------------+
| Name: |my-profile_____________________________________| |
| Scopes: |
| [X] Window Positions & Layouts |
| [X] Active Project Settings |
| [X] Provider Configuration |
| [Save] [Cancel] |
+---------------------------------------------------------+
```
6. **Step 5 (Human):** Approves: "This is perfect. Lock the design."
---
## 7. Verification & Audit Protocols
Once a design contract is locked and implemented, it must pass a three-tiered verification gate:
1. **AST Integrity:** Every docstring modification must pass `py_check_syntax` to ensure it doesn't break python parsing.
2. **Regression Check:** The test runner (`pytest tests/`) must be run to verify zero side-effects. Docstring additions must never alter execution logic.
3. **Puppeteer Visual Audit:** In visual simulation tests, the captured Dear ImGui layout boundaries and widget visibility flags are compared against the rows, columns, and conditional states defined in the ASCII design contract.