# UI Layout Definition Draw Tool — Implementation Proposal **Version:** 0.1.0 **Platform:** Android (APK), native C++ compiled with Clang in Termux **Target Spec:** UI Layout Definition Format v1.6 --- ## 1. Project Overview A lightweight Android application for visually designing UI layouts conforming to the `ui-layout-def` XML specification (v1.6). The tool enables selecting a control set, drawing wireframes by placing controls from a toolbox, creating windows with slot overrides, editing control properties, and saving/loading/validating XML files against the XSD schemas. The app is built entirely in C++ using the Android NDK toolchain available in Termux, with no Java/Kotlin layer — pure NativeActivity + OpenGL ES or Skia for rendering. --- ## 2. Architecture ### 2.1 High-Level Component Diagram ``` ┌─────────────────────────────────────────────────────┐ │ Android APK │ │ ┌───────────────────────────────────────────────┐ │ │ │ NativeActivity (C++) │ │ │ │ ┌─────────┐ ┌──────────┐ ┌───────────────┐ │ │ │ │ │ UI Core │ │ Renderer │ │ Input Handler │ │ │ │ │ │ (ImGui) │ │(GLES 2.0)│ │ (touch/keys) │ │ │ │ │ └────┬────┘ └─────┬────┘ └───────┬───────┘ │ │ │ │ │ │ │ │ │ │ │ ┌────▼────────────▼──────────────▼───────┐ │ │ │ │ │ Application Core │ │ │ │ │ │ ┌────────────┐ ┌──────────────────┐ │ │ │ │ │ │ │ Document │ │ Control │ │ │ │ │ │ │ │ Model │ │ Registry │ │ │ │ │ │ │ │ (DOM tree) │ │ (parsed XMLs) │ │ │ │ │ │ │ └──────┬─────┘ └────────┬─────────┘ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ┌──────▼─────────────────▼──────────┐ │ │ │ │ │ │ │ XML Engine │ │ │ │ │ │ │ │ ┌──────────┐ ┌──────────────┐ │ │ │ │ │ │ │ │ │ pugixml │ │ libxml2 XSD │ │ │ │ │ │ │ │ │ │ (R/W) │ │ (validation) │ │ │ │ │ │ │ │ │ └──────────┘ └──────────────┘ │ │ │ │ │ │ │ └───────────────────────────────────┘ │ │ │ │ │ └─────────────────────────────────────────┘ │ │ │ └───────────────────────────────────────────────┘ │ │ ┌───────────────┐ │ │ │ File System │ │ │ │ (storage) │ │ │ └───────────────┘ │ └─────────────────────────────────────────────────────┘ ``` ### 2.2 Key Technology Choices | Component | Library | Rationale | |-----------|---------|-----------| | UI Framework | **Dear ImGui** (docking branch) | Immediate-mode GUI, trivial to embed in NativeActivity, excellent for toolbox/property panels, zero Java dependency | | Rendering | **OpenGL ES 2.0** via EGL | Universal Android support, ImGui has a backend for it | | XML Parsing/Writing | **pugixml** | Header-only C++, lightweight, DOM-based — perfect fit for ui-layout-def tree manipulation | | XSD Validation | **libxml2** | The only practical C library with XSD schema validation; available in Termux (`pkg install libxml2`) | | Touch/Input | **android_native_app_glue** | Standard NDK input handling for NativeActivity | | Build System | **CMake + NDK** via Termux | `pkg install android-ndk cmake` in Termux | | File Dialogs | Custom ImGui panel | Browsing `/sdcard/` for open/save since there's no native file picker in NativeActivity | ### 2.3 Why Not SDL2 / Other Frameworks? SDL2 is an option but adds an unnecessary abstraction layer. NativeActivity + `android_native_app_glue` + ImGui is more direct, smaller APK, and gives full control over the GL context lifecycle. If future versions need audio or gamepad input, SDL2 can be introduced later. --- ## 3. Data Model ### 3.1 Control Registry On startup, the app parses the control definition XML files (`abstract-controls.xml`, `avalonia-controls.xml`, `winform-controls.xml`, `webawesome-controls.xml`) using pugixml. Each parsed control becomes an entry in a `ControlRegistry`: ```cpp struct ControlDef { std::string name; // "TextBox", "Panel", "wa-button" std::string type; // "input", "container", "display" std::string category; // "basic", "avalonia-input", etc. std::string inherits; // "CommonControl" std::string platform; // "basic", "avalonia", "web" std::string description; bool is_container; std::vector allowed_parents; std::vector allowed_children; std::vector attributes; std::vector events; }; struct AttributeDef { std::string name; std::string type; // "string", "int", "bool", "enum" std::string default_val; bool required; int min, max; std::string values; // comma-separated enum values }; class ControlRegistry { std::unordered_map controls_; // Grouped by control set for toolbox display std::map> by_category_; public: void load_control_set(const std::string& xml_path); const ControlDef* find(const std::string& name) const; void resolve_inheritance(); // flatten inherited attributes }; ``` The registry resolves `inherits` chains so each `ControlDef` has the full merged attribute list from `CommonControl` down to the specific control. ### 3.2 Document Model The working document is an in-memory tree mirroring the `ui-layout-def` XML structure: ```cpp // Represents a placed control instance on the canvas struct ControlInstance { std::string id; // unique within document std::string control_name; // reference to ControlDef float x, y, w, h; // canvas position/size std::map properties; // attribute overrides std::vector children; ControlInstance* parent; }; // A wireframe definition struct WireframeDef { std::string name; std::string type; std::vector slots; // named regions ControlInstance* root_layout; // the template tree }; // A window definition struct WindowDef { std::string name; std::string title; std::string wireframe_ref; // optional wireframe name std::string view_ref; // optional view name std::string target_platform; // Either template (free-form) or slot-overrides ControlInstance* template_root; std::map slot_overrides; }; // Root document struct Document { std::string version = "1.6"; std::string target_platform = "basic"; std::vector pattern_includes; std::vector wireframes; std::vector windows; // views, validation-rules stored as raw pugixml nodes // (v0.1 focuses on patterns+windows) pugi::xml_document raw_doc; // for round-tripping unsupported sections std::string file_path; bool modified = false; }; ``` ### 3.3 Round-Trip XML Fidelity Sections the tool doesn't visually edit (views, validation-rules, state-management, etc.) are preserved as raw XML nodes via pugixml's DOM. When saving, the tool: 1. Serializes patterns (from registry selection) 2. Serializes wireframes (from canvas) 3. Serializes windows (from canvas) 4. Preserves untouched sections verbatim This guarantees no data loss when editing files created by hand or other tools. --- ## 4. Feature Implementation ### 4.1 Feature 1 — Create New UI Definition (Control Set Selection) **Flow:** 1. User taps "New" → modal dialog presents control set options: - Abstract only (basic controls) - Abstract + WinForms - Abstract + Avalonia - Abstract + Web Awesome - Custom combination (multi-select) 2. User selects target platform (`basic`, `winforms`, `avalonia`, `web`, `mixed`) 3. App creates a new `Document` with appropriate `` entries 4. Control registry loads/filters to the selected sets 5. Toolbox panel populates with available controls grouped by category **Control set files bundled in APK assets:** | File | Control Set | |------|-------------| | `abstract-controls.xml` | Always loaded — base controls | | `winform-controls.xml` | WinForms-specific controls | | `avalonia-controls.xml` | Avalonia-specific controls | | `webawesome-controls.xml` | Web Awesome components | The XSD schemas are also bundled for validation. ### 4.2 Feature 2 — Wireframe Drawing (Canvas + Toolbox) **Canvas:** - OpenGL ES 2.0 rendered surface, ImGui draw-list overlay - Pan (two-finger drag) and zoom (pinch) with transform matrix - Grid snap (configurable: 4px, 8px, 16px, 32px) - Each control renders as a labeled rectangle with type icon - Container controls show dotted border and accept children via drag-drop - Selection: tap to select, long-press for context menu - Multi-select via lasso or Shift+tap (with external keyboard) **Toolbox panel (left sidebar, collapsible):** - Accordion-style categories: Display, Input, Container, List, Navigation, etc. - Each entry shows control name + small icon - Tap a toolbox item → enters "placement mode" → tap canvas to place - Alternative: drag from toolbox to canvas (if touch precision allows) **Wireframe creation:** - User defines a wireframe via menu: "New Wireframe" → name + type - Places container controls (Panel, SplitPanel, TabControl) as layout skeleton - Marks named slots within containers (right-click → "Mark as Slot" → enter slot name) - Slot regions render with distinct dashed border + slot label **Rendering style for v0.1:** - Simple rectangles with rounded corners - Control type name rendered inside - Container nesting shown by indentation/border hierarchy - Color-coding by control type (blue=input, green=display, gray=container, orange=list) ### 4.3 Feature 3 — Window Creation (Wireframe Overrides + Standalone) **Two modes:** **A) Window with wireframe reference:** 1. User creates window → selects an existing wireframe 2. Canvas shows the wireframe layout with slot regions highlighted 3. User drags controls into slot regions → creates `` 4. Non-slot areas are read-only (inherited from wireframe) 5. Slot content is freely editable **B) Standalone window (no wireframe):** 1. User creates window → skips wireframe selection 2. Blank canvas → builds layout from scratch using `