ui/screen/screen.go

201 lines
4.8 KiB
Go
Raw Normal View History

2024-03-30 17:45:07 +01:00
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"
)
2024-04-03 16:07:24 +02:00
type ListItemTemplateFn func() fyne.CanvasObject
type ListDataItemRendererFn func(binding.DataItem, fyne.CanvasObject)
type ListItemRendererFn func(int, fyne.CanvasObject)
type ListLengthFn func() int
type ListItemHandlerFn func(widget.ListItemID)
type ClickHandlerFn func()
type CheckHandlerFn func(bool)
type DateSelectedHandlerFn func(time.Time)
type ValidationChangedHandlerFn func(error)
type UIElement struct {
Object fyne.CanvasObject
Decorator fyne.CanvasObject
}
2024-03-30 17:45:07 +01:00
type ScreenHandler interface {
2024-04-03 16:07:24 +02:00
RegisterElement(string, fyne.CanvasObject, fyne.CanvasObject)
2024-03-30 17:45:07 +01:00
GetLocalizer() *i18n.Localizer
GetIcon(string) fyne.Resource
GetBinding(string) binding.DataItem
2024-04-03 16:07:24 +02:00
GetValidator(string) fyne.StringValidator
GetListItemTemplate(string) ListItemTemplateFn
GetListDataItemRenderer(string) ListDataItemRendererFn
GetListItemRenderer(string) ListItemRendererFn
GetListLength(string) ListLengthFn
2024-03-30 17:45:07 +01:00
2024-04-03 16:07:24 +02:00
GetOnListItemSelectedHandler(string) ListItemHandlerFn
GetOnListItemUnselectedHandler(string) ListItemHandlerFn
GetOnClickedHandler(string) ClickHandlerFn
GetOnCheckChangedHandler(string) CheckHandlerFn
GetOnDateSelectedHandler(string) DateSelectedHandlerFn
GetOnValidationChangedHandler(string) ValidationChangedHandlerFn
2024-03-30 17:45:07 +01:00
}
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,
) {
2024-04-03 16:07:24 +02:00
handler = NewTemplateScreenHandler(localizer)
2024-03-30 17:45:07 +01:00
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
2024-04-03 16:07:24 +02:00
elementsMap map[string]*UIElement
2024-03-30 17:45:07 +01:00
}
2024-04-03 16:07:24 +02:00
func NewTemplateScreenHandler(
localizer *i18n.Localizer,
) *TemplateScreenHandler {
2024-03-30 17:45:07 +01:00
return &TemplateScreenHandler{
localizer: localizer,
2024-04-03 16:07:24 +02:00
elementsMap: make(map[string]*UIElement),
2024-03-30 17:45:07 +01:00
}
}
2024-04-03 16:07:24 +02:00
func (d *TemplateScreenHandler) RegisterElement(
name string,
element fyne.CanvasObject,
decorator fyne.CanvasObject,
) {
d.elementsMap[name] = &UIElement{element, decorator}
2024-03-30 17:45:07 +01:00
}
2024-04-03 16:07:24 +02:00
func (d *TemplateScreenHandler) GetElement(name string) *UIElement {
2024-03-30 17:45:07 +01:00
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
}
2024-04-03 16:07:24 +02:00
func (*TemplateScreenHandler) GetValidator(string) fyne.StringValidator {
return nil
}
func (*TemplateScreenHandler) GetListItemTemplate(string) ListItemTemplateFn {
2024-03-30 17:45:07 +01:00
return func() fyne.CanvasObject { return nil }
}
2024-04-03 16:07:24 +02:00
func (*TemplateScreenHandler) GetListDataItemRenderer(string) ListDataItemRendererFn {
2024-03-30 17:45:07 +01:00
return func(binding.DataItem, fyne.CanvasObject) {}
}
2024-04-03 16:07:24 +02:00
func (*TemplateScreenHandler) GetListItemRenderer(string) ListItemRendererFn {
2024-03-30 17:45:07 +01:00
return func(int, fyne.CanvasObject) {}
}
2024-04-03 16:07:24 +02:00
func (*TemplateScreenHandler) GetListLength(string) ListLengthFn {
2024-03-30 17:45:07 +01:00
return func() int { return 0 }
}
2024-04-03 16:07:24 +02:00
func (*TemplateScreenHandler) GetOnListItemSelectedHandler(string) ListItemHandlerFn {
2024-03-30 17:45:07 +01:00
return func(widget.ListItemID) {}
}
2024-04-03 16:07:24 +02:00
func (*TemplateScreenHandler) GetOnListItemUnselectedHandler(string) ListItemHandlerFn {
2024-03-30 17:45:07 +01:00
return func(widget.ListItemID) {}
}
2024-04-03 16:07:24 +02:00
func (*TemplateScreenHandler) GetOnClickedHandler(string) ClickHandlerFn {
2024-03-30 17:45:07 +01:00
return func() {}
}
2024-04-03 16:07:24 +02:00
func (*TemplateScreenHandler) GetOnCheckChangedHandler(string) CheckHandlerFn {
2024-03-30 17:45:07 +01:00
return func(bool) {}
}
2024-04-03 16:07:24 +02:00
func (*TemplateScreenHandler) GetOnDateSelectedHandler(string) DateSelectedHandlerFn {
2024-03-30 17:45:07 +01:00
return func(time.Time) {}
}
2024-04-03 16:07:24 +02:00
func (*TemplateScreenHandler) GetOnValidationChangedHandler(string) ValidationChangedHandlerFn {
return func(error) {}
}