Dalibor Votruba 16d64538cb add abstract, winform, webform, avalonia default definitions 11 месяцев назад
..
Definitions 16d64538cb add abstract, winform, webform, avalonia default definitions 11 месяцев назад
Samples 2a0b67837b initial commit in 1.1 version 11 месяцев назад
readme.md 2a0b67837b initial commit in 1.1 version 11 месяцев назад
ui-layout-def.xsd 2a0b67837b initial commit in 1.1 version 11 месяцев назад

readme.md

UI Layout Definition Format

Version: 1.1
Documentation Version: 1.1
Author: Dalibor Votruba
URL: quadarax.com/ui-layout-def

A comprehensive XML-based format for describing user interface layouts with inheritance, pattern definitions, view organization, and platform-specific extensions. This format enables cross-platform UI generation with strict validation and modular component libraries.

Table of Contents

Overview

The UI Layout Definition Format provides a standardized way to define user interfaces that can be translated to various platforms (Windows Forms, WPF, Qt, Web, Mobile). It emphasizes:

  • View-Based Organization: Logical grouping of related UI components by business function
  • Separation of Concerns: Pattern definitions separate from usage
  • Inheritance: Base wireframes and views with specific overrides
  • Validation: Strict constraints ensure consistent, valid UIs
  • Modularity: External pattern, view, and validation includes
  • Cross-Platform: Platform-specific control libraries
  • MVVM Support: Direct mapping to view models and business logic

Core Concepts

1. View-First Design (NEW in v1.1)

Views represent logical business functions (ProductView, OrderView) that group related windows and define shared data context and behaviors.

2. Patterns-First Design

All controls and structures must be defined in the <patterns> section before use in windows.

3. Inheritance Hierarchy

  • Views can inherit from other views
  • Controls can inherit from other controls
  • Windows can inherit from wireframe layouts
  • Attributes can be overridden at any level

4. Slot-Based Composition

Wireframes use slots as placeholders that windows can fill with specific content.

5. Constraint Validation

Comprehensive validation rules ensure UI consistency and platform compliance.

Document Structure

<?xml version="1.0" encoding="UTF-8"?>
<ui-layout-def xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="ui-layout-definition ui-layout-def.xsd">
  
  <!-- Optional: Validation rules with external includes -->
  <validation-rules>
    <validation-include src="..." important="true/false" />
    <rule name="...">...</rule>
  </validation-rules>
  
  <!-- Required: Pattern definitions with external includes -->
  <patterns>
    <pattern-include src="..." important="true/false" />
    <control name="...">...</control>
    <structure name="...">...</structure>
    <wireframe name="...">...</wireframe>
  </patterns>
  
  <!-- NEW: View definitions with external includes -->
  <views>
    <view-include src="..." important="true/false" />
    <view name="..." type="..." category="..." inherits="...">...</view>
  </views>
  
  <!-- Required: One or more window definitions -->
  <window name="..." title="..." wireframe="..." view="...">
    <!-- Window content -->
  </window>
  
</ui-layout-def>

View Definitions

View Concept

Views are logical containers that group related windows, dialogs, and UI components that work together for a specific business function. They provide:

  • Logical Organization: Group UI components by business purpose
  • Data Context: Shared state management within the view
  • Navigation: Centralized navigation logic
  • Dependencies: Clear relationships between views
  • Code Generation: Generate view classes with proper structure

Basic View Structure

<view name="ProductView" type="business-entity" category="core" inherits="BaseEntityView">
  <description>Product management functionality including listing, editing, and details</description>
  
  <!-- View metadata for code generation -->
  <metadata>
    <model-class>Product</model-class>
    <view-model-class>ProductViewModel</view-model-class>
    <controller-class>ProductController</controller-class>
    <permissions>product.read,product.write</permissions>
  </metadata>
  
  <!-- View dependencies -->
  <dependencies>
    <view-ref name="CategoryView" relationship="lookup" required="false" />
    <view-ref name="SupplierView" relationship="reference" required="false" />
    <shared-component name="FileUploadComponent" required="true" />
  </dependencies>
  
  <!-- Shared data context -->
  <data-context>
    <property name="currentProduct" type="Product" scope="view" />
    <property name="productList" type="ProductList" scope="view" />
    <property name="selectedCategory" type="Category" scope="shared" />
  </data-context>
  
  <!-- Window associations -->
  <windows>
    <window-ref name="ProductListWindow" role="main" default="true" />
    <window-ref name="ProductEditDialog" role="editor" modal="true" />
    <window-ref name="ProductDetailsWindow" role="viewer" />
  </windows>
  
  <!-- View-level navigation -->
  <navigation>
    <action name="show-list" target="ProductListWindow" />
    <action name="edit-product" target="ProductEditDialog" context="currentProduct" />
    <action name="view-details" target="ProductDetailsWindow" context="currentProduct" />
  </navigation>
  
  <!-- Shared behaviors -->
  <behaviors>
    <behavior name="refresh-data" scope="view" />
    <behavior name="validate-product" scope="view" />
    <behavior name="save-changes" scope="view" />
  </behaviors>
</view>

View Types and Categories

View Types:

  • business-entity - Product, Order, Customer management
  • process-flow - OrderProcessing, Checkout workflows
  • dashboard - MainDashboard, ReportsView
  • utility - Settings, UserPreferences
  • wizard - Setup wizards, guided processes
  • composite - Views composed of multiple sub-views
  • module - Application modules containing multiple views

Categories:

  • core - Essential business functionality
  • admin - Administrative functions
  • reporting - Reports and analytics
  • system - System-level functionality
  • framework - Base views for inheritance

View Inheritance

<!-- Base entity view -->
<view name="BaseEntityView" type="base" category="framework">
  <windows>
    <window-ref name="BaseListWindow" role="main" />
    <window-ref name="BaseEditDialog" role="editor" />
  </windows>
  
  <navigation>
    <action name="show-list" target="BaseListWindow" />
    <action name="edit-entity" target="BaseEditDialog" />
  </navigation>
  
  <behaviors>
    <behavior name="refresh-data" />
    <behavior name="save-changes" />
  </behaviors>
</view>

<!-- Inherited view -->
<view name="ProductView" inherits="BaseEntityView">
  <!-- Inherits all windows, navigation, and behaviors from BaseEntityView -->
  <!-- Can override or extend with additional functionality -->
  
  <windows>
    <!-- Additional product-specific windows -->
    <window-ref name="ProductCatalogWindow" role="catalog" />
  </windows>
  
  <navigation>
    <!-- Override base action -->
    <action name="edit-entity" target="ProductEditDialog" context="currentProduct" />
    <!-- Add new action -->
    <action name="view-catalog" target="ProductCatalogWindow" />
  </navigation>
</view>

View Dependencies and Relationships

<dependencies>
  <!-- Lookup relationship - uses other view for data selection -->
  <view-ref name="CategoryView" relationship="lookup" required="false">
    <interaction type="select-category" returns="category-id" />
  </view-ref>
  
  <!-- Master-detail relationship -->
  <view-ref name="OrderItemView" relationship="detail" required="true">
    <interaction type="manage-items" context="current-order" />
  </view-ref>
  
  <!-- Reference relationship - shows related data -->
  <view-ref name="CustomerView" relationship="reference" required="false">
    <interaction type="view-customer" context="customer-id" />
  </view-ref>
  
  <!-- Shared component dependency -->
  <shared-component name="AddressComponent" required="true" />
  <shared-component name="NotificationService" required="true" />
</dependencies>

Composite Views

<view name="OrderManagementView" type="composite" category="core">
  <description>Complete order management including orders, items, and customer details</description>
  
  <!-- Composed views -->
  <composed-views>
    <view-ref name="OrderView" role="primary" layout-slot="main-content" />
    <view-ref name="OrderItemView" role="detail" layout-slot="items-panel" />
    <view-ref name="CustomerView" role="reference" layout-slot="customer-panel" />
  </composed-views>
  
  <!-- Composite layout -->
  <layout wireframe="CompositeViewLayout">
    <slot name="main-content" view="OrderView" />
    <slot name="items-panel" view="OrderItemView" />
    <slot name="customer-panel" view="CustomerView" />
  </layout>
  
  <!-- Cross-view coordination -->
  <coordination>
    <rule when="OrderView.order-selected" then="OrderItemView.load-items" />
    <rule when="OrderView.customer-changed" then="CustomerView.load-customer" />
  </coordination>
</view>

Pattern Definitions

Control Definition

<control name="Button" type="action" category="basic">
  <constraints>
    <allowed-parents>Panel,FormField</allowed-parents>
    <allowed-children>none</allowed-children>
    <container>false</container>
  </constraints>
  
  <attributes>
    <attribute name="text" type="string" default="Button" required="true" />
    <attribute name="enabled" type="bool" default="true" />
    <attribute name="style" type="enum" values="normal,primary,danger" default="normal" />
  </attributes>
  
  <behavior>
    <event name="click" required="true" />
  </behavior>
</control>

Control Properties

  • name: Unique identifier for the control type
  • type: Control category (action, input, display, container, data, navigation)
  • category: Platform grouping (basic, windows-specific, web-specific, etc.)
  • inherits: Optional parent control to inherit from

Constraints

  • allowed-parents: List of controls that can contain this control
  • allowed-children: List of controls this control can contain
  • container: Boolean indicating if control can contain children
  • max-children: Maximum number of child controls allowed
  • requires-structure: Required structural elements

Attributes

  • name: Attribute identifier
  • type: Data type (string, int, bool, enum, color, date, etc.)
  • default: Default value
  • required: Whether attribute must be specified
  • min/max: Value constraints for numeric types
  • values: Allowed values for enum types

Structure Definition

<structure name="FormField" type="pattern" category="composite">
  <constraints>
    <allowed-parents>Panel</allowed-parents>
    <required-slots>input</required-slots>
  </constraints>
  
  <attributes>
    <attribute name="label-text" type="string" required="true" />
    <attribute name="required" type="bool" default="false" />
  </attributes>
  
  <template>
    <Panel name="fieldContainer">
      <Label name="fieldLabel" text="{label-text}" />
      <slot name="input" allowed-controls="TextBox,ComboBox" required="true" />
      <Label name="validationLabel" visible="false" color="#ff0000" />
    </Panel>
  </template>
</structure>

Wireframe Definition

<wireframe name="StandardAppLayout" type="base-layout">
  <description>Standard application layout with header, sidebar, content, footer</description>
  <template>
    <Panel name="rootContainer">
      <Panel name="headerPanel" height="60">
        <slot name="header-content" default="true">
          <Label name="appTitle" text="Application Title" />
        </slot>
      </Panel>
      
      <Panel name="mainContainer" orientation="horizontal">
        <Panel name="sidebarPanel" width="250">
          <slot name="sidebar-content" />
        </Panel>
        <Panel name="contentPanel" fill="true">
          <slot name="main-content" required="true" />
        </Panel>
      </Panel>
      
      <Panel name="footerPanel" height="30">
        <slot name="footer-content" default="true">
          <Label name="statusLabel" text="Ready" />
        </slot>
      </Panel>
    </Panel>
  </template>
</wireframe>

Wireframe Inheritance

Windows can inherit from wireframe layouts and override specific slots:

<window name="MainWindow" title="Main Application" wireframe="StandardAppLayout" view="MainView">
  <attributes>
    <attribute name="width" value="800" />
    <attribute name="height" value="600" />
  </attributes>
  
  <view-properties>
    <role>main</role>
    <default>true</default>
    <data-context-binding>mainData</data-context-binding>
  </view-properties>
  
  <slot-overrides>
    <slot name="header-content">
      <Label name="appTitle" text="My Application" />
      <Button name="settingsButton" text="Settings" />
    </slot>
    
    <slot name="main-content">
      <Panel name="dashboardPanel">
        <!-- Main content here -->
      </Panel>
    </slot>
  </slot-overrides>
</window>

Window Definitions

<window name="WindowName" title="Window Title" wireframe="OptionalWireframe" view="AssociatedView">
  <attributes>
    <attribute name="width" value="800" />
    <attribute name="height" value="600" />
    <attribute name="resizable" value="true" />
    <attribute name="modal" value="false" />
  </attributes>
  
  <!-- NEW: View properties -->
  <view-properties>
    <role>main</role>
    <default>true</default>
    <modal>false</modal>
    <data-context-binding>entityData</data-context-binding>
    <parent-window>ParentWindow</parent-window>
  </view-properties>
  
  <!-- For wireframe-based windows -->
  <slot-overrides>
    <slot name="content">
      <!-- Slot content -->
    </slot>
  </slot-overrides>
  
  <!-- For direct layout windows -->
  <Panel name="mainPanel">
    <!-- Direct content -->
  </Panel>
</window>

Validation System

Enhanced Validation Rules for Views

<validation-rules>
  <!-- View-specific validation rules -->
  <rule name="view-window-association">
    <description>All windows must be associated with a view</description>
    <constraint>Every window must be referenced by at least one view</constraint>
  </rule>
  
  <rule name="view-dependency-validation">
    <description>View dependencies must be valid</description>
    <constraint>Referenced views in dependencies must be defined</constraint>
  </rule>
  
  <rule name="view-inheritance-validation">
    <description>View inheritance must be valid</description>
    <constraint>Inherited views must be defined and compatible</constraint>
  </rule>
  
  <rule name="data-context-consistency">
    <description>Data context properties must be consistently typed</description>
    <constraint>Shared properties across views must have compatible types</constraint>
  </rule>
  
  <!-- Existing validation rules -->
  <rule name="control-definition-required">
    <description>All controls used in windows must be defined in patterns</description>
    <constraint>Every control element must reference a defined control or structure pattern</constraint>
  </rule>
</validation-rules>

External Includes

View Includes

<views>
  <view-include src="business-views.xml" important="true" />
  <view-include src="admin-views.xml" important="false" />
  <!-- Local view definitions -->
</views>

Pattern Includes

<patterns>
  <pattern-include src="windows-controls.xml" important="true" />
  <pattern-include src="custom-controls.xml" important="false" />
  <!-- Local pattern definitions -->
</patterns>

Validation Includes

<validation-rules>
  <validation-include src="base-validation.xml" important="true" />
  <validation-include src="view-validation.xml" important="false" />
  <!-- Local validation rules -->
</validation-rules>

Examples

Complete Application with Views

<ui-layout-def>
  <validation-rules>
    <validation-include src="base-validation.xml" important="true" />
  </validation-rules>
  
  <patterns>
    <pattern-include src="windows-controls.xml" important="true" />
    <!-- Pattern definitions... -->
  </patterns>
  
  <views>
    <!-- Product management view -->
    <view name="ProductView" type="business-entity" category="core">
      <metadata>
        <model-class>Product</model-class>
        <view-model-class>ProductViewModel</view-model-class>
      </metadata>
      
      <dependencies>
        <view-ref name="CategoryView" relationship="lookup" />
      </dependencies>
      
      <data-context>
        <property name="currentProduct" type="Product" scope="view" />
        <property name="productList" type="ProductList" scope="view" />
      </data-context>
      
      <windows>
        <window-ref name="ProductListWindow" role="main" default="true" />
        <window-ref name="ProductEditDialog" role="editor" modal="true" />
      </windows>
      
      <navigation>
        <action name="show-list" target="ProductListWindow" />
        <action name="edit-product" target="ProductEditDialog" context="currentProduct" />
      </navigation>
    </view>
    
    <!-- Category lookup view -->
    <view name="CategoryView" type="utility" category="core">
      <windows>
        <window-ref name="CategoryListDialog" role="main" modal="true" />
      </windows>
    </view>
  </views>
  
  <!-- Window definitions -->
  <window name="ProductListWindow" title="Product List" 
          wireframe="StandardAppLayout" view="ProductView">
    <view-properties>
      <role>main</role>
      <default>true</default>
      <data-context-binding>productList</data-context-binding>
    </view-properties>
    
    <slot-overrides>
      <slot name="main-content">
        <ListView name="productGrid" view-mode="details">
          <columns>
            <column name="name" text="Product Name" width="200" />
            <column name="category" text="Category" width="150" />
            <column name="price" text="Price" width="100" />
          </columns>
        </ListView>
      </slot>
    </slot-overrides>
  </window>
  
  <window name="ProductEditDialog" title="Edit Product" 
          wireframe="DialogLayout" view="ProductView">
    <view-properties>
      <role>editor</role>
      <modal>true</modal>
      <data-context-binding>currentProduct</data-context-binding>
    </view-properties>
    
    <slot-overrides>
      <slot name="dialog-body">
        <FormField name="nameField" label-text="Product Name:" required="true">
          <TextBox name="nameInput" slot="input" />
        </FormField>
        
        <FormField name="categoryField" label-text="Category:">
          <ComboBox name="categoryCombo" slot="input" />
        </FormField>
      </slot>
    </slot-overrides>
  </window>
</ui-layout-def>

Best Practices

1. View Organization

  • Group related windows by business function
  • Use inheritance for common view patterns
  • Define clear view dependencies
  • Document view responsibilities

2. View Design Patterns

  • Single Responsibility: Each view should handle one business concept
  • Dependency Injection: Use view dependencies rather than tight coupling
  • Data Context: Define clear data scopes (view, shared, global)
  • Navigation: Centralize navigation logic within views

3. Naming Conventions

  • Use PascalCase for view names with "View" suffix
  • Use descriptive names indicating business purpose
  • Group related views with common prefixes (OrderView, OrderItemView)

4. Code Generation Strategy

  • Map views to view model classes
  • Generate navigation methods
  • Create dependency injection configuration
  • Generate view factory classes

Platform Support

Enhanced Platform Integration

Windows Forms / WPF

  • Generate view classes with proper MVVM binding
  • Create dependency injection containers
  • Generate navigation services
  • Support for Windows-specific patterns

Qt / KDE

  • Generate Qt view classes
  • Support for KDE desktop integration
  • Cross-platform Qt navigation

Web / HTML

  • Generate MVC views or React components
  • Support for SPA routing
  • Progressive web app patterns

Mobile

  • Generate platform-specific view controllers
  • Support for mobile navigation patterns
  • Responsive view layouts

Migration from Version 1.0

Backward Compatibility

Version 1.1 maintains full backward compatibility with 1.0 documents. Existing documents will work without modification, but won't benefit from view organization features.

Migration Steps

  1. Add Views Section: Introduce <views> section
  2. Group Windows: Organize related windows into views
  3. Add View Properties: Enhance windows with view properties
  4. Define Dependencies: Specify view relationships
  5. Update Validation: Add view-specific validation rules

Gradual Migration

You can migrate gradually by:

  • Adding views for new functionality
  • Keeping existing windows as-is
  • Gradually moving windows into views
  • Updating code generation templates

Code Generation

Generated View Classes (C# Example)

// Generated from ProductView definition
public class ProductView : BaseEntityView, IProductView
{
    public ProductListWindow ProductListWindow { get; private set; }
    public ProductEditDialog ProductEditDialog { get; private set; }
    
    // Data context properties
    public Product CurrentProduct { get; set; }
    public ObservableCollection<Product> ProductList { get; set; }
    
    // Dependencies
    public ICategoryView CategoryView { get; set; }
    
    // Navigation methods
    public void ShowList() => ProductListWindow.Show();
    public void EditProduct(Product product) => ProductEditDialog.ShowDialog(product);
    
    // View behaviors
    public async Task RefreshData() { /* ... */ }
    public async Task SaveChanges() { /* ... */ }
}

This format specification enables consistent, validated, cross-platform UI definitions with powerful view organization, inheritance, and modular design capabilities.