Skip to content

Commit

Permalink
Update examples
Browse files Browse the repository at this point in the history
  • Loading branch information
JD557 committed May 4, 2024
1 parent 46ae468 commit 420bb20
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 26 deletions.
4 changes: 2 additions & 2 deletions examples/snapshot/1-introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ in the end, returns the sequence of render operations that must be executed by t

Now, to the button logic:
1. Interactive components like buttons require a unique ID, which is the first parameter;
2. Then we need to specify an area where the button will be drawn;
3. We also add a label, which is the text that will be shown on the button;
2. We also add a label, which is the text that will be shown on the button;
3. Then we need to specify an area where the button will be drawn;
4. Finally, `button` returns `true` when the button is pressed, so we use that to decrement our counter.

For the text block we don't need an id, as it's just a rendering primitive with no interaction, so we just need to
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 2. Layouts
# 2. Explicit Layout

Welcome to the InterIm tutorial!

Expand All @@ -7,20 +7,19 @@ Welcome to the InterIm tutorial!
You can run the code in this file (and other tutorials) with:

```bash
scala-cli 2-layout.md example-minart-backend.scala
scala-cli 2-explicit-layout.md example-minart-backend.scala
```

Other examples can be run in a similar fashion

## Component layout in InterIm applications

In InterIm, the layout of all components is explicit: Every component receives a `Rect` with the area where it can be
rendered.
In InterIm, every component receives a `Rect` with the area where it can be rendered, so its size must be known up front.

This is very different from other systems like HTML, where elements can infer their size from their contents.

This is a typical problem of immediate mode GUIs. While there are some techniques to address that, InterIm
currently opts for the simpler design of forcing everything to be explicit.
currently opts for the simpler option.

However, explicit does not mean manual! InterIm comes with multiple helpers to automatically generate areas according
to a specified layout:
Expand All @@ -37,7 +36,7 @@ This can be quite a chore, especially since changing one area might force us to

Everything was layed out in 3 equally sized columns, so let's use the `columns` layout.

This layout returns a `Vector[Rect]`, with the 3 areas we want to use.
This layout returns a `IndexedSeq[Rect]`, with the 3 areas we want to use.

Our application now looks like:

Expand All @@ -50,18 +49,18 @@ var counter = 0
def application(inputState: InputState) =
import eu.joaocosta.interim.InterIm.*
ui(inputState, uiContext):
columns(area = Rect(x = 10, y = 10, w = 110, h = 30), numColumns = 3, padding = 10):
button(id = "minus", label = "-"):
columns(area = Rect(x = 10, y = 10, w = 110, h = 30), numColumns = 3, padding = 10): column ?=>
button(id = "minus", label = "-")(column(0)):
counter = counter - 1
text(
area = summon,
area = column(1),
color = Color(0, 0, 0),
message = counter.toString,
font = Font.default,
horizontalAlignment = centerHorizontally,
verticalAlignment = centerVertically
)
button(id = "plus", label = "+"):
button(id = "plus", label = "+")(column(2)):
counter = counter + 1
```

Expand All @@ -73,7 +72,7 @@ MinartBackend.run(application)

## Note about dynamic layouts

While `rows`, `columns` and `cells` provide a `Vector[Rect]` (or a `Vector[Vector[Rect]]`) to our body, the dynamic
While `rows`, `columns` and `cells` provide a `IndexedSeq[Rect]` (or a `IndexedSeq[IndexedSeq[Rect]]`) to our body, the dynamic
versions work a bit differently.

In those cases, a `Int => Rect` function is provided where, given a desired size, a `Rect` is returned.
Expand Down
58 changes: 58 additions & 0 deletions examples/snapshot/3-implicit-layout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# 3. Explicit Layout

Welcome to the InterIm tutorial!

## Running the examples

You can run the code in this file (and other tutorials) with:

```bash
scala-cli 3-layout.md example-minart-backend.scala
```

Other examples can be run in a similar fashion

## Implicit layouts

In the previous example, you might have noticed something odd: helpers like `columns` use a context function instead of a
regular function.

Indeed, that's because those functions introduce an implicit `LayoutAllocator`.
When there's no area defined, components will use the allocator from the current context to pick an area implicitly.

Right now, however, while primitives (such as `rectangle` and `text`) can use an allocator, that must be passed explicitly
(also in the `area` parameter).

## Using implicit layouts in the counter application

Here's the previous example but with implicit layouts:

```scala
import eu.joaocosta.interim.*

val uiContext = new UiContext()
var counter = 0

def application(inputState: InputState) =
import eu.joaocosta.interim.InterIm.*
ui(inputState, uiContext):
columns(area = Rect(x = 10, y = 10, w = 110, h = 30), numColumns = 3, padding = 10):
button(id = "minus", label = "-"):
counter = counter - 1
text(
area = summon, // we can easily get the allocator with `summon`
color = Color(0, 0, 0),
message = counter.toString,
font = Font.default,
horizontalAlignment = centerHorizontally,
verticalAlignment = centerVertically
)
button(id = "plus", label = "+"):
counter = counter + 1
```

Now let's run it:

```scala
MinartBackend.run(application)
```
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 3. Windows
# 4. Windows

Welcome to the InterIm tutorial!

Expand All @@ -7,7 +7,7 @@ Welcome to the InterIm tutorial!
You can run the code in this file (and other tutorials) with:

```bash
scala-cli 3-windows.md example-minart-backend.scala
scala-cli 4-windows.md example-minart-backend.scala
```

Other examples can be run in a similar fashion
Expand Down
4 changes: 2 additions & 2 deletions examples/snapshot/4-refs.md → examples/snapshot/5-refs.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 4. Mutable References
# 5. Mutable References

Welcome to the InterIm tutorial!

Expand All @@ -7,7 +7,7 @@ Welcome to the InterIm tutorial!
You can run the code in this file (and other tutorials) with:

```bash
scala-cli 4-refs.md example-minart-backend.scala
scala-cli 5-refs.md example-minart-backend.scala
```

Other examples can be run in a similar fashion
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 5. Color Picker
# 6. Color Picker

Welcome to the InterIm tutorial!

Expand All @@ -7,7 +7,7 @@ Welcome to the InterIm tutorial!
You can run the code in this file (and other tutorials) with:

```bash
scala-cli 5-colorpicker.md example-minart-backend.scala
scala-cli 6-colorpicker.md example-minart-backend.scala
```

Other examples can be run in a similar fashion
Expand Down Expand Up @@ -79,18 +79,18 @@ def application(inputState: InputState, appState: AppState) =
appState.asRefs: (colorPickerArea, colorSearchArea, colorRange, resultDelta, color, query) =>
onTop:
window(id = "color picker", title = "Color Picker", closable = true, movable = true, resizable = true)(area = colorPickerArea): area =>
rows(area = area.shrink(5), numRows = 6, padding = 10): rowAlloc ?=>
rectangle(rowAlloc.nextRow(), color.get)
rows(area = area.shrink(5), numRows = 6, padding = 10):
rectangle(summon, color.get)
select(id = "range", Vector("0-255","0-100", "0x00-0xff"))(colorRange).value match
case 0 =>
val colorStr = f"R:${color.get.r}%03d G:${color.get.g}%03d B:${color.get.b}%03d"
text(rowAlloc, textColor, colorStr, Font.default, alignLeft, centerVertically)
text(summon, textColor, colorStr, Font.default, alignLeft, centerVertically)
case 1 =>
val colorStr = f"R:${color.get.r * 100 / 255}%03d G:${color.get.g * 100 / 255}%03d B:${color.get.b * 100 / 255}%03d"
text(rowAlloc, textColor, colorStr, Font.default, alignLeft, centerVertically)
text(summon, textColor, colorStr, Font.default, alignLeft, centerVertically)
case 2 =>
val colorStr = f"R:0x${color.get.r}%02x G:0x${color.get.g}%02x B:0x${color.get.b}%02x"
text(rowAlloc, textColor, colorStr, Font.default, alignLeft, centerVertically)
text(summon, textColor, colorStr, Font.default, alignLeft, centerVertically)
val r = slider("red slider", min = 0, max = 255)(color.get.r)
val g = slider("green slider", min = 0, max = 255)(color.get.g)
val b = slider("blue slider", min = 0, max = 255)(color.get.b)
Expand All @@ -108,7 +108,7 @@ def application(inputState: InputState, appState: AppState) =
val resultsHeight = results.size * buttonSize
if (resultsHeight > resultsArea.h)
slider("result scroller", min = 0, max = resultsHeight - resultsArea.h)(resultDelta)
val clipArea = newColumn(maxSize)
val clipArea = newColumn.fill()
clip(area = clipArea):
rows(area = clipArea.copy(y = clipArea.y - resultDelta.get, h = resultsHeight), numRows = results.size, padding = 10): rows ?=>
results.zip(rows).foreach:
Expand Down
2 changes: 1 addition & 1 deletion examples/snapshot/example-minart-backend.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//> using scala "3.3.3"
//> using dep "eu.joaocosta::minart::0.6.0-M3"
//> using dep "eu.joaocosta::minart::0.6.0"
//> using dep "eu.joaocosta::interim::0.1.7-SNAPSHOT"

/** This file contains a simple graphical backend written in Minart.
Expand Down

0 comments on commit 420bb20

Please sign in to comment.