# CorgEng.UserInterface
## Contents
[toc]
## Summary
The user interface documentation for CorgEng
## Ideas
Each component is has its own render core. This will inherently add clipping to them.
To perform rendering we first need to render all children components to their frame buffers.
Then we take the frame buffer result of our children and draw them into our frame buffer.
Positions will be handled entirely by anchors. These will be relative to a parent component's side (everything will be boxes). The sides will be top, bottom, left, right.
The right side anchor can be relative to the parent's left or right side, and the top and bottom anchors can be relative to the parent's top or bottom.
A left/right anchor cannot be relative to the top/bottom of a parent element, and vice versa.
## Minimum UI Scale / UI Expansion
If the left and right or top and bottom anchors share the same relative position, they are a fixed size UI element.
The minimum UI scale is the sum of all fixed size UI elements width/height.
This is a recursive thing, a UI element cannot be smaller than 50 pixels if it contains a child element that is relative to `leftAnchor="left:0"` and `rightAnchor="left:50"`.
User interface components can be set to automatically expand to their minimum size or strictly maintain their size.
If an exclamation mark is placed after the unit in the anchor details, it will be strictly sized and any non-contained children will be culled.
```xml=
<Node leftAnchor="left:0!" rightAnchor="left:100!" topAnchor="top:0" bottomAnchor="bottom:0" />
```
Without the exclamation mark, the positions will be treated as a minimum size rather than the forced size.
Without strict scaling, the user interface element may expand.
If neither the left nor right are strict, the expansion will happen from the center and effect both sides equally.
If the left only is strict, expansion will happen on the right.
If the right only is strict, expansion will happen on the left.

If both sides are strict, the minimum scale of the UI will not expand to inlude its children.
The root element of a UI is the only element that isn't bound to the minimum UI scale. It will not automatically expand, however cannot be resized to be smaller than the minimum scale.
## Render Cores
We need a base render core that can render the sub-cores onto itself first, and then render its own stuff.
For example a text component needs a render core that renders any of its children, then draws its text on top.
## Unit Testing
When executing unit tests, we will replace the Render Cores with something that validates expected inputs.
This can be done using the dependency injection system.
## Components
### User Interface Component
The base component, renders all children and provides base functionality for other user interface components.
### Text
Renders some specified text on top of the children (if any).
### Button
Does something when pressed.
### Icon
Displays an icon specified in a text file.
### Scroll Component
Contains a scroll view that translates up and down when the scroll bar is moved.
Scroll components should use strict sizing, otherwise they will automatically fill to accomodate all their children.
### Dropdown
Hides its dropdown contents until expanded.
Dropdowns shouldn't use strict sizing, otherwise they will be pretty useless.
### Input Field
Allows text to be entered into it.
## Injecting Code into UI Elements
Using the key element in an XML file, UI components can be given a unique key. This can be used in the C# code, so that when the UI is loaded, the appropriate components can be fetched.
```xml=
<Button key="button_key" ... />
```
```csharp=
private UserInterface userInterface;
public void InjectCode()
{
//Get the button with the key 'button_key' and add some code
//to its OnClick delegate.
userInterface.GetComponent<Button>("button_key").OnClick += () => {
//Do some code here
};
}
```
## Example UI XML File
```xml=
<UserInterface>
<Button leftAnchor="left:0" rightAnchor="left:100" topAnchor="bottom:40" bottomAnchor="bottom:0">
<Text TextContent="Hello" leftAnchor="left:0" rightAnchor="right:0" topAnchor="top:0" bottomAnchor="bottom:0" />
</Button>
</UserInterface>
```
Would output something on the lines of:

The reason for using anchors over positions + scales is so that the UIs can implicitly scale well. This allows us to have buttons with a fixed width while still having well-scaling buttons all within a single system.
What if we want 2 UI components that both take up half the available space to them?
```xml=
<UserInterface>
<ExampleNode leftAnchor="left:0" rightAnchor="left:50%" bottomAnchor="bottom:0" topAnchor="top:0" />
<ExampleNode leftAnchor="right:50%" rightAnchor="right:0" bottomAnchor="bottom:0" topAnchor="top:0" />
</UserInterface>
```
Using a percentage instead of a number will use that percentage multiplied by the width/height of the parent element.
If the parent element is a button of width 200, having the right anchor be `left:50%` will cause the right anchor to be 100 pixels from the left side of that parent element.