aboutsummaryrefslogtreecommitdiffstats
path: root/gui/widget/widget.go
diff options
context:
space:
mode:
Diffstat (limited to 'gui/widget/widget.go')
-rw-r--r--gui/widget/widget.go130
1 files changed, 130 insertions, 0 deletions
diff --git a/gui/widget/widget.go b/gui/widget/widget.go
new file mode 100644
index 0000000..cbc837e
--- /dev/null
+++ b/gui/widget/widget.go
@@ -0,0 +1,130 @@
+package widget
+
+import (
+ "cmp"
+ "fmt"
+
+ "image"
+ "image/color"
+ "image/draw"
+
+ "volute/gui"
+ "volute/gui/win"
+)
+
+var (
+ FOCUS_COLOR = color.RGBA{179, 217, 255, 255}
+ GREEN = color.RGBA{51, 102, 0, 255}
+ BLACK = color.Gray{0}
+ WHITE = color.Gray{255}
+)
+
+func Label(text string, r image.Rectangle, env gui.Env) {
+ redraw := func(drw draw.Image) image.Rectangle {
+ drawText([]byte(text), drw, r, BLACK, WHITE)
+ return r
+ }
+ env.Draw() <- redraw
+ for event := range env.Events() {
+ switch event := event.(type) {
+ case win.WiFocus:
+ if event.Focused {
+ env.Draw() <- redraw
+ }
+ }
+ }
+ close(env.Draw())
+}
+
+func Input(val chan<- uint, r image.Rectangle, focusChan <-chan bool, env gui.Env) {
+ redraw := func(text []byte, focus bool) func(draw.Image) image.Rectangle {
+ return func(drw draw.Image) image.Rectangle {
+ if focus {
+ drawText(text, drw, r, GREEN, FOCUS_COLOR)
+ } else {
+ drawText(text, drw, r, GREEN, WHITE)
+ }
+ return r
+ }
+ }
+ text := []byte{'0'}
+ focus := false
+
+ env.Draw() <- redraw(text, focus)
+
+ for {
+ select {
+ case focus = <-focusChan:
+ env.Draw() <- redraw(text, focus)
+ case event := <-env.Events():
+ switch event := event.(type) {
+ case win.WiFocus:
+ if event.Focused {
+ env.Draw() <- redraw(text, focus)
+ }
+ case win.KbType:
+ if focus && isDigit(event.Rune) {
+ text = fmt.Appendf(text, "%c", event.Rune)
+ env.Draw() <- redraw(text, focus)
+ val <- atoi(text)
+ }
+ case win.KbDown:
+ if focus && event.Key == win.KeyBackspace && len(text) > 0 {
+ text = text[:len(text)-1]
+ env.Draw() <- redraw(text, focus)
+ val <- atoi(text)
+ }
+ }
+ }
+ }
+ close(env.Draw())
+}
+
+func Output(val <-chan uint, r image.Rectangle, env gui.Env) {
+ redraw := func(n uint) func(draw.Image) image.Rectangle {
+ return func(drw draw.Image) image.Rectangle {
+ drawText([]byte(fmt.Sprint(n)), drw, r, BLACK, WHITE)
+ return r
+ }
+ }
+
+ var n uint = 0
+ env.Draw() <- redraw(n)
+
+Loop:
+ for {
+ select {
+ case n = <-val:
+ env.Draw() <- redraw(n)
+ case event, ok := <-env.Events():
+ if !ok { // channel closed
+ break Loop
+ }
+ if event, ok := event.(win.WiFocus); ok && event.Focused {
+ env.Draw() <- redraw(n)
+ }
+ }
+ }
+ close(env.Draw())
+}
+
+func isDigit(r rune) bool {
+ return '0' <= r && r <= '9'
+}
+
+func contains[T cmp.Ordered](slc []T, v T) bool {
+ for i := range slc {
+ if slc[i] == v {
+ return true
+ }
+ }
+ return false
+}
+
+func atoi(s []byte) uint {
+ var n uint = 0
+ for _, d := range s {
+ n = n*10 + uint(d-'0')
+ }
+ return n
+}