ui/screen/screen.go
Maarten Heremans 864255113c Initial Commit
2024-03-30 17:45:07 +01:00

170 lines
4.0 KiB
Go

package screen
import (
"embed"
"fmt"
"io"
"io/fs"
"strings"
"time"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/data/binding"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
"github.com/nicksnyder/go-i18n/v2/i18n"
"gopkg.in/yaml.v2"
)
type ScreenHandler interface {
RegisterElement(string, fyne.CanvasObject)
GetLocalizer() *i18n.Localizer
GetIcon(string) fyne.Resource
GetBinding(string) binding.DataItem
GetListItemTemplate(string) func() fyne.CanvasObject
GetListDataItemRenderer(string) func(binding.DataItem, fyne.CanvasObject)
GetListItemRenderer(string) func(int, fyne.CanvasObject)
GetListLength(string) func() int
GetOnSelectedHandler(string) func(widget.ListItemID)
GetOnUnselectedHandler(string) func(widget.ListItemID)
GetClickedHandler(string) func()
GetCheckChangedHandler(string) func(bool)
GetDateSelectedHandler(string) func(time.Time)
}
type Screen struct {
rootElement *Element
screenHandler ScreenHandler
}
func New(
filesystem embed.FS,
name string,
screenHandler ScreenHandler,
) (scr *Screen, err error) {
var bytes []byte
var fh fs.File
if fh, err = filesystem.Open(name); err != nil {
err = fmt.Errorf("no screen definition found: %w", err)
return
}
if bytes, err = io.ReadAll(fh); err != nil {
err = fmt.Errorf("unable to read screen definition: %w", err)
return
}
root := &Element{}
if err = yaml.Unmarshal(bytes, root); err != nil {
err = fmt.Errorf("failure parsing screen definition: %w", err)
return
}
scr = &Screen{
rootElement: root,
screenHandler: screenHandler,
}
return
}
func NewTemplate(
filesystem embed.FS,
name string,
localizer *i18n.Localizer,
) (
scr *Screen,
handler *TemplateScreenHandler,
err error,
) {
handler = NewDummyScreenHandler(localizer)
scr, err = New(filesystem, name, handler)
return
}
func (s *Screen) Initialize() (obj fyne.CanvasObject, err error) {
if obj, err = s.rootElement.BuildUI(s.screenHandler); err != nil {
err = fmt.Errorf("failed to build screen: %w", err)
return
}
return
}
type TemplateScreenHandler struct {
localizer *i18n.Localizer
elementsMap map[string]fyne.CanvasObject
}
func NewDummyScreenHandler(localizer *i18n.Localizer) *TemplateScreenHandler {
return &TemplateScreenHandler{
localizer: localizer,
elementsMap: make(map[string]fyne.CanvasObject),
}
}
func (d *TemplateScreenHandler) RegisterElement(name string, element fyne.CanvasObject) {
d.elementsMap[name] = element
}
func (d *TemplateScreenHandler) GetElement(name string) fyne.CanvasObject {
elem, ok := d.elementsMap[name]
if !ok {
return nil
}
return elem
}
func (d *TemplateScreenHandler) GetLocalizer() *i18n.Localizer {
return d.localizer
}
func (d *TemplateScreenHandler) GetIcon(iconName string) fyne.Resource {
if strings.HasPrefix(iconName, "theme.") {
iconName := strings.SplitN(iconName, ".", 2)[1]
return theme.DefaultTheme().Icon(fyne.ThemeIconName(iconName))
}
return nil
}
func (*TemplateScreenHandler) GetBinding(string) binding.DataItem {
return nil
}
func (*TemplateScreenHandler) GetListItemTemplate(string) func() fyne.CanvasObject {
return func() fyne.CanvasObject { return nil }
}
func (*TemplateScreenHandler) GetListDataItemRenderer(string) func(binding.DataItem, fyne.CanvasObject) {
return func(binding.DataItem, fyne.CanvasObject) {}
}
func (*TemplateScreenHandler) GetListItemRenderer(string) func(int, fyne.CanvasObject) {
return func(int, fyne.CanvasObject) {}
}
func (*TemplateScreenHandler) GetListLength(string) func() int {
return func() int { return 0 }
}
func (*TemplateScreenHandler) GetOnSelectedHandler(string) func(widget.ListItemID) {
return func(widget.ListItemID) {}
}
func (*TemplateScreenHandler) GetOnUnselectedHandler(string) func(widget.ListItemID) {
return func(widget.ListItemID) {}
}
func (*TemplateScreenHandler) GetClickedHandler(string) func() {
return func() {}
}
func (*TemplateScreenHandler) GetCheckChangedHandler(string) func(bool) {
return func(bool) {}
}
func (*TemplateScreenHandler) GetDateSelectedHandler(string) func(time.Time) {
return func(time.Time) {}
}