176 lines
5.3 KiB
Go
176 lines
5.3 KiB
Go
|
// +build !nogui
|
||
|
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
|
||
|
"fyne.io/fyne/v2"
|
||
|
"fyne.io/fyne/v2/app"
|
||
|
"fyne.io/fyne/v2/container"
|
||
|
"fyne.io/fyne/v2/widget"
|
||
|
)
|
||
|
|
||
|
type GUI struct {
|
||
|
gui fyne.App
|
||
|
windows map[string]fyne.Window
|
||
|
}
|
||
|
|
||
|
func (g GUI) String() string {
|
||
|
return "GUI"
|
||
|
}
|
||
|
|
||
|
type guiWidget fyne.Widget
|
||
|
type guiContainer fyne.Container
|
||
|
|
||
|
var guiLib = vars{
|
||
|
"gui-create": func(a ...expression) expression {
|
||
|
return &GUI{app.New(), make(map[string]fyne.Window)}
|
||
|
},
|
||
|
"gui-add-window": func(a ...expression) expression {
|
||
|
if len(a) < 2 {
|
||
|
return exception("'gui-add-window' expects a GUI and a string as arguments, too few arguments were given")
|
||
|
}
|
||
|
g, ok := a[0].(*GUI)
|
||
|
if !ok {
|
||
|
return exception("'gui-add-window' was given a non-GUI value as its first argument")
|
||
|
}
|
||
|
s := String(a[1], false)
|
||
|
g.windows[s] = g.gui.NewWindow(s)
|
||
|
return true
|
||
|
},
|
||
|
"gui-list-windows": func(a ...expression) expression {
|
||
|
if len(a) == 0 {
|
||
|
return exception("'gui-list-windows' expects a GUI as an argument, no arguments were given")
|
||
|
}
|
||
|
g, ok := a[0].(*GUI)
|
||
|
if !ok {
|
||
|
return exception("'gui-list-windows' was given a non-GUI argument")
|
||
|
}
|
||
|
out := make([]expression, 0, len(g.windows))
|
||
|
for k := range g.windows {
|
||
|
out = append(out, k)
|
||
|
}
|
||
|
return out
|
||
|
},
|
||
|
"window-set-content": func(a ...expression) expression {
|
||
|
// (window-set-content window-id content...)
|
||
|
if len(a) < 3 {
|
||
|
return exception("'window-set-content' expects a GUI and a string as arguments, too few arguments were given")
|
||
|
}
|
||
|
g, ok := a[0].(*GUI)
|
||
|
if !ok {
|
||
|
return exception("'window-set-content' was given a non-GUI value as its first argument")
|
||
|
}
|
||
|
s := String(a[1], false)
|
||
|
w, ok := g.windows[s]
|
||
|
if !ok {
|
||
|
return exception("'window-show-and-run' was given a window ID that does not exist: " + s)
|
||
|
}
|
||
|
w.SetContent(a[2].(fyne.CanvasObject))
|
||
|
|
||
|
return true
|
||
|
},
|
||
|
"window-show-and-run": func(a ...expression) expression {
|
||
|
// (window-show-and-run window-id)
|
||
|
if len(a) < 2 {
|
||
|
return exception("'window-show-and-run' expects a GUI and a string as arguments, too few arguments were given")
|
||
|
}
|
||
|
g, ok := a[0].(*GUI)
|
||
|
if !ok {
|
||
|
return exception("'window-show-and-run' was given a non-GUI value as its first argument")
|
||
|
}
|
||
|
s := String(a[1], false)
|
||
|
w, ok := g.windows[s]
|
||
|
if !ok {
|
||
|
return exception("'window-show-and-run' was given a window ID that does not exist: " + s)
|
||
|
}
|
||
|
w.ShowAndRun()
|
||
|
return true
|
||
|
},
|
||
|
"widget-label": func(a ...expression) expression {
|
||
|
// (widget-label text:string alignment:number wrap:bool)
|
||
|
if len(a) == 0 {
|
||
|
return exception("'widget-label' expects at least one argument, a string representing the text of the label, no arguments were given")
|
||
|
}
|
||
|
var l guiWidget = widget.NewLabel(String(a[0], false))
|
||
|
if len(a) >= 2 {
|
||
|
align, ok := a[1].(number)
|
||
|
if !ok {
|
||
|
return exception("'widget-label' expects a number (-1, 0, or 1) as its optional second argument (alignment), a non-number value was given")
|
||
|
}
|
||
|
switch int(align) {
|
||
|
case -1:
|
||
|
l.(*widget.Label).Alignment = fyne.TextAlignLeading
|
||
|
case 0:
|
||
|
l.(*widget.Label).Alignment = fyne.TextAlignCenter
|
||
|
case 1:
|
||
|
l.(*widget.Label).Alignment = fyne.TextAlignTrailing
|
||
|
default:
|
||
|
return exception("'widget-label' expects a number (-1, 0, or 1) as its optional second argument (alignment), a number outside of the range was given")
|
||
|
}
|
||
|
}
|
||
|
if len(a) >= 3 {
|
||
|
wrap, ok := a[2].(bool)
|
||
|
if !ok {
|
||
|
return exception("'widget-label' expects a bool as its optional third argument (wrap), a non-bool value was given")
|
||
|
}
|
||
|
if wrap {
|
||
|
l.(*widget.Label).Wrapping = fyne.TextWrapWord
|
||
|
}
|
||
|
}
|
||
|
return l
|
||
|
},
|
||
|
"widget-button": func(a ...expression) expression {
|
||
|
// (widget-label text:string alignment:number wrap:bool)
|
||
|
if len(a) < 2 {
|
||
|
return exception("'widget-button' expects at least one argument, a string representing the text of the label, no arguments were given")
|
||
|
}
|
||
|
var b guiWidget
|
||
|
switch f := a[1].(type) {
|
||
|
case func(...expression) expression:
|
||
|
b = widget.NewButton(String(a[0], false), func() { f() })
|
||
|
case Callback:
|
||
|
b = widget.NewButton(String(a[0], false), func() { apply(f.p, []expression{}) })
|
||
|
default:
|
||
|
return exception("'widget-button' was given a non-procedure value as its second argument")
|
||
|
}
|
||
|
if len(a) >= 3 {
|
||
|
align, ok := a[2].(number)
|
||
|
if !ok {
|
||
|
return exception("'widget-label' expects a number (-1, 0, or 1) as its optional third argument (alignment), a non-number value was given")
|
||
|
}
|
||
|
switch int(align) {
|
||
|
case -1:
|
||
|
b.(*widget.Button).Alignment = widget.ButtonAlignLeading
|
||
|
case 0:
|
||
|
b.(*widget.Button).Alignment = widget.ButtonAlignCenter
|
||
|
case 1:
|
||
|
b.(*widget.Button).Alignment = widget.ButtonAlignTrailing
|
||
|
default:
|
||
|
return exception("'widget-button' expects a number (-1, 0, or 1) as its optional third argument (alignment), a number outside of the range was given")
|
||
|
}
|
||
|
}
|
||
|
return b
|
||
|
},
|
||
|
"container-vertical-box": func(a ...expression) expression {
|
||
|
list, err := ExpToCanvasObjectList(a)
|
||
|
if err != nil {
|
||
|
return exception("'container-vertical-box' was given a list that contained a non widget value")
|
||
|
}
|
||
|
return container.NewVBox(list...)
|
||
|
},
|
||
|
}
|
||
|
|
||
|
func ExpToCanvasObjectList(e []expression) ([]fyne.CanvasObject, error) {
|
||
|
out := make([]fyne.CanvasObject, len(e))
|
||
|
for i, v := range e {
|
||
|
wid, ok := v.(guiWidget)
|
||
|
if !ok {
|
||
|
return out, fmt.Errorf("Invalid list")
|
||
|
}
|
||
|
out[i] = wid.(fyne.Widget).(fyne.CanvasObject)
|
||
|
}
|
||
|
return out, nil
|
||
|
}
|