Skip to content

Commit fd6572a

Browse files
docs, icon
1 parent 8e5b06a commit fd6572a

File tree

3 files changed

+77
-3
lines changed

3 files changed

+77
-3
lines changed

docs/concepts.md

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
Similar to **Calico**, **Swing.IO** takes its concepts from Cats Effect and FS2. This page lists some common idioms used in Swing.IO development.
44

5+
Note: Some of these docs were copied from [Calico](https://www.armanbilge.com/calico/concepts.html), as these are very similar projects with a similar basis.
6+
57
## Components and resource management
68

79
The most important idea of **Swing.IO** is that all components are represented as a `Resource[IO, Component[IO]]`.
@@ -34,4 +36,67 @@ val component: Resource[IO, Component[IO]] = box("Hello, checkbox:", checkbox())
3436
```
3537
In this example, a checkbox that does nothing composes together to create a `Resource`
3638

37-
TODO: Complete docs LATER™
39+
## Signals
40+
41+
`Signal`s are time varying values. You can always obtain the current value and subscribe to stream of update events that notify when it is updated.
42+
This is ideal for use in UI Components: they can always render immediately with the current value, and re-render only when there are updates.
43+
44+
`Signal` is a monad, enabling them to be transformed with pure functions and composed with each other.
45+
Using transformation and composition, you can derive a `Signal` that contains precisely the data you are interested in.
46+
47+
```scala
48+
import cats.syntax.all.*
49+
50+
case class S3Weapon(name: String)
51+
enum Games {
52+
case Splatoon1
53+
case Splatoon2
54+
case Splatoon3
55+
}
56+
val signals = (
57+
SignallingRef[IO].of(S3Weapon("52 Gal")),
58+
SignallingRef[IO].of(Games.Splatoon3),
59+
)
60+
61+
val weapons: Seq[S3Weapon] = Seq(???)
62+
63+
val app = signals.flatMap { (weaponSig, gameSig) => window(
64+
flow(
65+
comboBox[S3Weapon].withSelf { self => (
66+
items := weapons,
67+
renderer := { (it: S3Weapon) => it.name },
68+
onSelectionChange --> {
69+
_.foreach(_ => self.value.get.flatMap(weaponSig.set))
70+
}
71+
)},
72+
comboBox[Games].withSelf { self => (
73+
items := Seq(Games.Splatoon1, Games.Splatoon2, Games.Splatoon3),
74+
onSelectionChange --> {
75+
_.foreach(_ => self.value.get.flatMap(gameSig.set))
76+
}
77+
)}
78+
)
79+
)
80+
}
81+
```
82+
83+
There are various ways to obtain a `Signal`.
84+
85+
- Create a `SignallingRef` with an initial value.
86+
```scala
87+
SignallingRef[IO].of("initial value")
88+
```
89+
90+
- Derive a `Signal` from a `Stream`, by “holding” its latest value.
91+
```scala
92+
def stringStream: Stream[IO, String] = ???
93+
stringStream.holdResource("initial value")
94+
stringStream.holdOptionResource // use None for the intitial value
95+
```
96+
97+
## Glitch-free rendering
98+
99+
Swing forces all access to swing components to be on the Event Dispatch Thread. This ensures that rendering is glitch-free.
100+
**Swing.IO** automatically handles this by evaluating all access to swing components on the EDT, and it lets Cats Effect
101+
handle anything that doesn't touch swing components. This means you get all the benefits of multithreading your Swing app
102+
without the hassle of having to deal with the EDT.

docs/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Swing.IO is a library for the Typelevel ecosystem. It's meant to be an analog for Calico for JVM land.
33

44
## Acknowlegements
5-
**Swing.IO** is inspired by #[Calico](https://github.com/armanbilge/calico). It takes a lot of cues from it and from proposals of it.
5+
**Swing.IO** is inspired by [Calico](https://github.com/armanbilge/calico). It takes a lot of cues from it and from proposals of it.
66

7-
Thanks to @armanbilge for putting up with me in his chat and dealing with my questions.
7+
Thanks to [@armanbilge](https://github.com/armanbilge) for putting up with me in his chat and dealing with my questions.
88

swingio/src/main/scala/net/bulbyvr/swing/io/SwingProp.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,15 @@ private trait Props[F[_]](using A: Async[F]) extends LowPriorityProps[F] {
159159
lazy val onSelectionChange = eventProp["onSelectionChange", swingio.event.SelectionChanged[F]]
160160

161161
lazy val onValueChange = eventProp["onValueChange", swingio.event.ValueChanged[F]]
162+
163+
given iconProp[A, E <: swingio.WithIcon[F]]: Setter[F, E, "icon", swingio.Image[F]] =
164+
(e, v) => e.icon.set(Some(swingio.ImageIcon[F](v))).toResource
165+
given iconPropReal[A, E <: swingio.WithIcon[F], I <: swingio.Icon[F]]: Setter[F, E, "icon", swingio.Icon[F]] =
166+
(e, v) => e.icon.set(Some(v)).toResource
167+
// shenanagins ensue
168+
given iconPropNone[A, E <: swingio.WithIcon[F]]: Setter[F, E, "icon", Option[Nothing]] =
169+
(e, v) => e.icon.set(v).toResource
170+
lazy val icon = prop["icon"]
162171
}
163172

164173
private trait LowPriorityProps[F[_]] (using F: Async[F]) {

0 commit comments

Comments
 (0)