mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-18 07:48:02 +08:00
Add the GUI markup language spec to the docs
This commit is contained in:
151
gui/README.md
151
gui/README.md
@@ -1,4 +1,4 @@
|
||||
# GUI system
|
||||
# GUI System Explainer
|
||||
|
||||
This directory contains the XML files describing the components which make up Graphite's GUI.
|
||||
|
||||
@@ -39,3 +39,152 @@ User-defined parameters start with a colon (`:`).
|
||||
|
||||
They are created by adding attributes to a component source file:
|
||||
`:parameter="VARIABLE_NAME: (VariableType) = defaultValue"`
|
||||
|
||||
# GUI System Markup Language Specification
|
||||
|
||||
## Layouts
|
||||
|
||||
* XML files laying out interface structure with tags for layouts and primitives
|
||||
* Namespaced with folder name like `<namespace:layout-name>`
|
||||
* Inner XML content bound to the variable specified in the `children` attribute of the root element definition
|
||||
* All custom attributes are prefixed with a `:` when used as arguments and as parameters
|
||||
* Root element in each file is the layout and its accepted arguments with a bound variable and default value
|
||||
* Templating using {{mustaches}} for bound variables and computed values in the associated script
|
||||
* Each layout has a companion script (Rust or WASM) that exposes computed values for templating
|
||||
* Each layout acts as a container element used in computing layout measurements
|
||||
|
||||
## GUI layout tree data structure
|
||||
|
||||
* Stores purely the data used by the renderer and shaders
|
||||
* Updated by the layout system
|
||||
|
||||
## Primitive layouts
|
||||
|
||||
**`<box> | <box />`** Draws a box
|
||||
* **`children`** *`[xml | none = none]`*
|
||||
Inner XML stays in the document
|
||||
* **`:fill`** *`[color | none = none]`*
|
||||
Fill color for the box
|
||||
* **`:round`** *`[size | size size size size = 0px]`*
|
||||
Rounds the corners
|
||||
* **`:border-thickness`** *`[size = 0px]`*
|
||||
Thickness of the border inside the box
|
||||
* **`:border-color`** *`[color | none = none]`*
|
||||
Color of the border inside the box
|
||||
|
||||
**`<icon> | <icon />`** Draws an icon from an SVG file and optionally contains child elements
|
||||
* **`children`** *`[xml | none = none]`*
|
||||
Inner XML stays in the document
|
||||
* **`:svg`** *``[string = `missing_svg_alert.svg`]``*
|
||||
Location of the SVG file
|
||||
* **`:style`** *```[string = ``]```*
|
||||
CSS styling to be applied to the SVG, useful for applying templated variables
|
||||
|
||||
**`<text>`** Draws text
|
||||
* **`children`** *```[string = ``]```*
|
||||
The text to be drawn (eventually this could become XML for styling)
|
||||
* **`:color`** *`[color | none = [middlegray]]`*
|
||||
The color of the text
|
||||
* **`:size`** *`[size = 12px]`*
|
||||
The size of the text
|
||||
|
||||
**`<row> | <row />`** Wraps content laid out across vertically-adjacent sections, or acts as a spacer
|
||||
* **`children`** *`[xml | none = none]`*
|
||||
The elements inside the row
|
||||
|
||||
**`<col>`** Wraps content laid out across horizontally-adjacent sections, or acts as a spacer
|
||||
* **`children`** *`[xml | none = none]`*
|
||||
The elements inside the column
|
||||
|
||||
**`<if>`** Conditionally enables or disables child content if :a equals :b
|
||||
* **`children`** *`[xml | none = none]`*
|
||||
The elements to be shown if :a equals :b
|
||||
* **`:a`** *`[TypeValue = true]`*
|
||||
The first variable that must equal the second variable
|
||||
* **`:b`** *`[TypeValue = true]`*
|
||||
The second variable that must equal the first variable
|
||||
|
||||
## Layout calculation
|
||||
|
||||
**`width`** *`[Dimension = inner]`*
|
||||
Set the exact content width of the element
|
||||
|
||||
**`height`** *`[Dimension = inner]`*
|
||||
Set the exact content height of the element
|
||||
|
||||
**`x-align`** *`[Dimension::Percent = 0%]`*
|
||||
Factor from left (0%) to right (100%) to align content inside this larger element
|
||||
|
||||
**`y-align`** *`[Dimension::Percent = 0%]`*
|
||||
Factor from top (0%) to bottom (100%) to align content inside this larger element
|
||||
|
||||
**`gap`** *`[Dimension Dimension Dimension Dimension = 0px 0px 0px 0px]`*
|
||||
Collapses between neighbors, pushes/expands parent set to inner, not part of click target (negative values count against the interior dimension instead of adding to the outside of the dimension?)
|
||||
* **gap** *[Dimension → a a a a]*
|
||||
Sugar: Single value for all sides
|
||||
* **gap** *[Dimension Dimension = a b a b]*
|
||||
Sugar: Two values for top/bottom and left/right
|
||||
* **x-gap** *[Dimension = 0px a 0px a]*
|
||||
Sugar: Single value for left/right
|
||||
* **x-gap** *[Dimension Dimension = 0px a 0px b]*
|
||||
Sugar: Two values for left and right
|
||||
* **y-gap** *[Dimension = a 0px a 0px]*
|
||||
Sugar: Single value for top/bottom
|
||||
* **y-gap** *[Dimension Dimension = a 0px b 0px]*
|
||||
Sugar: Two values for top and bottom
|
||||
|
||||
**`padding`** *`[Dimension Dimension Dimension Dimension = 0]`*
|
||||
Doesn’t collapse between neighbors, pushes/expands parent set to inner, part of the click target (negative values count against the interior dimension instead of adding to the outside of the dimension?)
|
||||
* **padding** *[Dimension → a a a a]*
|
||||
Sugar: Single value for all sides
|
||||
* **padding** *[Dimension Dimension = a b a b]*
|
||||
Sugar: Two values for top/bottom and left/right
|
||||
* **x-padding** *[Dimension = 0px a 0px a]*
|
||||
Sugar: Single value for left/right
|
||||
* **x-padding** *[Dimension Dimension = 0px a 0px b]*
|
||||
Sugar: Two values for left and right
|
||||
* **y-padding** *[Dimension = a 0px a 0px]*
|
||||
Sugar: Single value for top/bottom
|
||||
* **y-padding** *[Dimension Dimension = a 0px b 0px]*
|
||||
Sugar: Two values for top and bottom
|
||||
|
||||
**`scroll`** *`[Dimension::Percent = 0%]`*
|
||||
When child elements overflow their container, keep them visible on the top/left (0%) or bottom/right (100%) while clipping on the opposite side
|
||||
|
||||
|
||||
## Variables
|
||||
|
||||
Parameter
|
||||
* Attribute: **?: (T1 | … | Tn) = ?**
|
||||
Declares a parameter with a list of possible types and a required default value
|
||||
* ```^\s*({{)\s*(\w*)\s*(:)\s*(\()\s*(\w*\s*(?:\|\s*\w*\s*?)*)\s*(\))\s*(=)\s*(\w*)\s*(}})\s*$```
|
||||
* ```{{ THE_NAME : (bool | color | inner | percent ) = none }}```
|
||||
* ```Value Type: (String, Vec<TypeName>, TypeValue)```
|
||||
|
||||
Argument
|
||||
* Attribute: {{?}}
|
||||
In an attribute, string, or between tags, evaluates to another type value via environment lookup
|
||||
* ```^\s*({{)\s*(\w*)\s*(}})\s*$```
|
||||
* ```{{THE_NAME }}```
|
||||
* ```Value Type: String```
|
||||
|
||||
## Types
|
||||
|
||||

|
||||

|
||||
|
||||
## Drawing procedure
|
||||
|
||||
Depth or breadth first traversal, shallow nodes drawn before deeper nodes
|
||||
|
||||
## Updating and damaged flag
|
||||
For any element marked damaged, it and all its children are redrawn
|
||||
Resizing panels marks all affected panel containers as damaged so the resized contents are drawn
|
||||
|
||||
## Antialiased corners
|
||||
|
||||
Pass along the parent node’s uniform, for any fragment located within a corner region, render the parent and blend antialiased GUI rectangle over it based on signed-distance function corner
|
||||
|
||||
Pixels in the corner regions must be wholly from the parent (must live within the borders of the parent, parent can’t be transparent, parent can’t have a wider overlapping border radius)
|
||||
|
||||
Requires a special case for overlapping parent and child with same border radius in same location so only the child is shown to avoid bleeding doubled antialiased edges
|
||||
|
||||
Reference in New Issue
Block a user