@ -83,7 +83,114 @@ by downloading everything, OSX already has most things, and Linux is...well...Li
## Using LEL
## Using LEL
Coming soon..
To use LEL with GUECS you first initialize a `guecs::UI` class with its position and size. Here's
an example taken from the `demos/calc.cpp` example:
```cpp
$gui.position(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
```
Then you configure a layout with the LEL formatting language:
```cpp
$gui.layout(
"[*%(400)stack|_|_|_]"
"[*%(400)readout|_|_|_]"
"[push|pop|clear|eq]"
"[add|sub|mul|div]"
"[btn7|btn8|btn9]"
"[btn4|btn5|btn6]"
"[btn1|btn2|btn3]"
"[neg|btn0|_]");
```
This creates a simple RPN calculator UI with buttons for numbers, readouts for the results and stack, and basic math operators. For people from other languages, this is actually one big string, but C++ (like C) allows you to "concatenate" strings together that are next to each other, so I just put them on separate lines so they look more like the grid they represent.
Once you have that you can give your panel a background and render a debug layout:
```cpp
void render(sf::RenderWindow& window) {
$gui.render(window);
$gui.debug_layout(window);
}
```
Since this first version works with SFML this render only takes a `sf::RenderWindow` and renders the
gui to it. With these two calls you'll get red lines showing you the grid specified in `layout()`.
This lets you refine the layout grid without requiring any components. Keep working the LEL layout until the grid looks good, then add some rectangles and labels:
```cpp
for(auto& [name, cell] : $gui.cells()) {
auto id = $gui.entity(name);
$gui.set<Rectangle>(id, {});
$gui.set<Label>(id, { guecs::to_wstring(name) });
}
```
You'll notice I have `guecs::to_wstring(name)` which uses the forbidden unicode conversion `codecvt`
from C++. Don't tell Microsoft. They'll be really angry and that one manager that's trying to get
Unicode removed from C++ won't get the bonus he needs to buy that houseboat.
With that working you can now use the components in `sfml/components.hpp` to add shader `Effect`,
`Clickable` interactions, `Sound`, and other things. You can also easily write your own. Look in
`sfml/components.cpp` to see how I do it. They're very simple.
The LEL language has quite a few features in a small package, so study the grammar below and try
working on a layout in different ways to learn it.
### LEL Full Grammar
`[`
: _startrow_ -- Starts a new row.
`]`
: _endrow_ -- Ends the row.
`|`
: _column_ -- Separates (starts a new) columns.
`^` or `.`
: _valign_ -- Simple vertical alignment. `^` aligns to the top and `.` aligns to the bottom. This is only useful if you use `()` to change the size so the cell is smaller than it normally is. Then use this to move it up/down.
`<` or `>`
: _halign_ -- Simple horizontal alignment. Again, only useful if you change the size so that it's _less_ than its default size.
`*`
: _expand_ -- This causes a cell to "break" out of its default cell and expand into neighbors. This is mostly used with `_` (empty) cells next to it for larger components, but you can also use this to create layered cells for special effects.
`=`
: _center_ -- Centers the cell inside its default cell. Again this is only useful if you use `()` to make it smaller than its default.
`%`
: _percent_ -- Normally the numbers inside `()` are actual pixel sizes, but adding this before will turn them into percentages as whole numbers. This means "10 percent" is given as `10` and "150 percent" is given as `150`. _DO NOT_ write `0.1` or `10%`. For example, if you want a cell to be 2 cells wide and 4 cells tall then write `*%(200, 400)`. You need `*` (expand) when expanding it.
`digit+`
: _numbers_ -- Anywhere in the grammar when you can type a number, these are them. They're numbers. Why am I explaining numbers?
`(number (, number)?)`
: _setw_ -- Sets the width (or height) of the cell. The `(, number)?` means that the second term is optional, and if it's missing it's assumed you want to only specify the width. So `(200)` is 200 pixels wide while `(200, 340)` is 200 wide and 340 tall. Combine with `*` (expand) and `%` (percent) to make the cell expand into other cells (which can be empty using `_`).
: _modifiers_ -- In the grammar modifiers are all of these things before the cell ID (name). So if I want a cell named `launch_rocket` that is 250% wider, 130% taller, I would write `*%(250, 130)launch_rocket`. For this to make sense you'd need to set the neighbor cells to `_` so they're empty like this: `[*%(250, 130)launch_rocket|_][_|_]`.
`((alpha | '_')+ (alnum | '_')*)`
: _id_ -- This is the cell id format, and it's basically what you get with most programming language: It can start with any alpha character or `_`, and contain any alphanumeric character or `_`. You can also just have `_` on its own which will mean "empty" and be left as empty space.
`modifiers* id`
: _cell_ -- A cell is any of the above modifiers (or none) followed by a cell _id_.
`[ cell (| cell )* ]`
: _row_ -- A row starts with `[`, contains any number of _cells_ separated by `|` (column) and terminated with a `]`.
### LEL Examples
### LEL Tricks
1. You can use `_` to create an empty cell, then use `*%(200)` to expand the previous cell into it.
2. You can also do this to rows below a cell to make them expand down. Simply set the cells below to `_` and use `*%(X,Y)` to expand by X=width and Y=height percentage.
3. You can use the names of cells to set an initial character as the event trigger. Just make each cell start (or end) with a unique relevant character, then grab it to create a number for that event.