# UI

## Overview

This is a small Jai library to do some basic immediate mode UI. It has a variety of widgets
and writing new ones should be relatively easy, if you follow the existing ones.

As opposed to a UI library you might find on the Internet, like Dear ImGui, this library is
sadly not platform independent. It is relatively coupled with OpenGL, so you in order to
integrate it to a project, you will need to also provide a GL context with GLFW, RGFW, SDL,
or the like.

## Architecture

The main concept behind this UI system is that as you call the ui_* functions like ui_begin/ui_end, etc.
You are implicitly building the tree that represents the UI hierarchy. That is the magic of an
immediate mode API. You take advantage of the fact that functions are called in a stack across time.
Which is implicitly a Tree. At the end of the frame you give this tree to the rendering function, which
recurses through it pre-order, drawing the panels, icons, text, etc., in the correct order.

Using this architecutre as the base places some undesirable constraints on the further design of the
system though. For example, the most useful part of this library is the auto-layout algorithm. It's not
super sophisticated, but it works. And in order to do this auto layout you need two basic pieces of
information. Where are the ui elements and how big are they. Properties that the layout algorithm can
itself change!

So, the easiest solution to this problem is to separate everything into distinct phases (or passes).
In the first pass you are declaring the tree structure of the UI as you go in a bottom up fashion,
recording the initial positions and sizes. Then after you're done you can traverse the tree from the
top down adjusting the layout. This is only possible because at this point in time you have all the
information including nodes' siblings, the size they are, they size they'd like to be, etc.

## Public API

Some functions have a begin/end pair, becuase you necesarily have to wait until things finish happening
inside of them to be able to calculate their initial size, etc. Other functions don't have this begin/end
pair, because they don't allow children, they're a leaf node, and they don't need further information to finish
their calculations.

```
ui_new_frame :: ()
```

This has to be called every frame, before calling any other UI function.

```
ui_begin :: (s: string)
```

This begins a panel, which other widgets can go inside of.

```
ui_end :: ()
```

Has to be called after a ui_begin to finish its UI Node.

```
ui_text_input :: (s: string, font_colour := Vector4.{1, 1, 1, 1})
```

This starts a text editor!

```
ui_begin_container :: (s: string, gradient := false, colour_left := Vector4.{}, colour_right := Vector4.{}, max_x: s32 = -1, max_y: s32 = -1, flags: ContainerFlags = 0)
```

Similar to a normal ui_begin, but you can have this one inside the main panel, recursively.
Very useful to change the layout direction (Left To Right vs Top to Bottom)

```
ui_end_container :: ()
```

Must be called after a ui_begin_container, to calculate sizing and finish the node in the UI Tree.

```
ui_icon :: (s: string, texture: *Texture, size: Vector2)
```

Renders an OpenGL texture.

```
ui_label :: (s: string = "", colour := Vector4.{1.0, 1.0, 1.0, 1.0})
```

Renders text.

```
ui_spacing :: (s: string)
```

Forces spacing between elements. The auto layout algorithm tries to maximize the space between
the node before the spacing and after the spacing, taking into account the max size of the parent
container.

```
ui_button :: (s: string = "", icon_texture: *Texture = null, font_colour := Vector4.{1, 1, 1, 1}, draw_frame := true) -> bool
```

Renders a panel with optional text in it and an optional OpenGL texture. When clicked it returns true.
Very useful to run conditional code like:

if ui_button(...) {
    do_something();
}

```
ui_font_icon :: (font: *Font, s: string, size: Vector2, colour: Vector4 = .{1, 1, 1, 1})
```

Renders an icon stored in a font. you have to figure out what the name of the glyph is and pray
FreeType can find it. You can look up the names using a tool like [FontDrop!](https://fontdrop.info/).

```
ui_progress_bar :: (s: string = "", progress: float, size: Vector2, background := Vector4.{1, 1, 1, 1}, foreground := Vector4.{1, 1, 1, 1})
```

Renders a progress bar.

```
ui_end_frame :: ()
```

Must be called after finishing the UI Tree. You must not call any UI Tree building functions (any of the previous ones)
after this call and before a new ui_begin_frame.

```
ui_render :: ()
```

Renders the UI with OpenGL.

## Example

Please look at main.jai for an example.
