352 lines
11 KiB
Go
352 lines
11 KiB
Go
|
package ui
|
||
|
|
||
|
import (
|
||
|
"embed"
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
|
||
|
"bitbucket.org/hevanto/ui/screen"
|
||
|
"fyne.io/fyne/v2"
|
||
|
"fyne.io/fyne/v2/data/binding"
|
||
|
"fyne.io/fyne/v2/theme"
|
||
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||
|
)
|
||
|
|
||
|
// ScreenHandler represents the handler for a screen.
|
||
|
//
|
||
|
// It provides:
|
||
|
// - The screen definition
|
||
|
// - The localizer
|
||
|
// - The screen controller
|
||
|
// - Exported elements
|
||
|
// - List item templates and renderers
|
||
|
// - User interaction handlers
|
||
|
type ScreenHandler struct {
|
||
|
screenDefinition *screen.Screen
|
||
|
localizer *i18n.Localizer
|
||
|
ctrl ScreenController
|
||
|
|
||
|
// Map of screen elements that got an id assigned
|
||
|
exportedElements map[string]*screen.UIElement
|
||
|
|
||
|
listItemTemplates map[string]screen.ListItemTemplateFn
|
||
|
listItemRenderers map[string]screen.ListItemRendererFn
|
||
|
listDataItemRenderers map[string]screen.ListDataItemRendererFn
|
||
|
listLengths map[string]screen.ListLengthFn
|
||
|
|
||
|
onListItemSelectedHandlers map[string]screen.ListItemHandlerFn
|
||
|
onListItemUnselectedHandlers map[string]screen.ListItemHandlerFn
|
||
|
onClickedHandlers map[string]screen.ClickHandlerFn
|
||
|
onCheckChangedHandlers map[string]screen.CheckHandlerFn
|
||
|
onDateSelectedHandlers map[string]screen.DateSelectedHandlerFn
|
||
|
onValidationChangedHandlers map[string]screen.ValidationChangedHandlerFn
|
||
|
}
|
||
|
|
||
|
// NewScreenHandler initializes a new ScreenHandler with the provided filesystem, screen name, ScreenController, and localizer.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// - filesystem: the embedded filesystem to access screen resources.
|
||
|
// - screenName: the name of the screen to load.
|
||
|
// - ctrl: the ScreenController for the screen.
|
||
|
// - localizer: the i18n.Localizer for localization.
|
||
|
//
|
||
|
// Returns:
|
||
|
// - h: the initialized ScreenHandler.
|
||
|
// - err: an error if loading the screen fails.
|
||
|
func NewScreenHandler(
|
||
|
filesystem embed.FS,
|
||
|
screenName string,
|
||
|
ctrl ScreenController,
|
||
|
localizer *i18n.Localizer,
|
||
|
) (h *ScreenHandler, err error) {
|
||
|
h = new(ScreenHandler)
|
||
|
|
||
|
h.ctrl = ctrl
|
||
|
h.localizer = localizer
|
||
|
|
||
|
def, err := screen.New(filesystem, screenName, h)
|
||
|
if err != nil {
|
||
|
err = fmt.Errorf("failure loading screen: %w", err)
|
||
|
return
|
||
|
}
|
||
|
h.screenDefinition = def
|
||
|
|
||
|
h.exportedElements = make(map[string]*screen.UIElement)
|
||
|
h.listItemTemplates = make(map[string]screen.ListItemTemplateFn)
|
||
|
h.listItemRenderers = make(map[string]screen.ListItemRendererFn)
|
||
|
h.listDataItemRenderers = make(map[string]screen.ListDataItemRendererFn)
|
||
|
h.listLengths = make(map[string]screen.ListLengthFn)
|
||
|
h.onListItemSelectedHandlers = make(map[string]screen.ListItemHandlerFn)
|
||
|
h.onListItemUnselectedHandlers = make(map[string]screen.ListItemHandlerFn)
|
||
|
h.onClickedHandlers = make(map[string]screen.ClickHandlerFn)
|
||
|
h.onCheckChangedHandlers = make(map[string]screen.CheckHandlerFn)
|
||
|
h.onDateSelectedHandlers = make(map[string]screen.DateSelectedHandlerFn)
|
||
|
h.onValidationChangedHandlers = make(map[string]screen.ValidationChangedHandlerFn)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// ScreenDefinition returns the screen definition for the ScreenHandler.
|
||
|
func (h *ScreenHandler) ScreenDefinition() *screen.Screen {
|
||
|
return h.screenDefinition
|
||
|
}
|
||
|
|
||
|
// RegisterElement registers an element with the ScreenHandler.
|
||
|
//
|
||
|
// This function is called for every element in the screen definition fow which
|
||
|
// an ID is defined.
|
||
|
func (h *ScreenHandler) RegisterElement(
|
||
|
id string,
|
||
|
elem fyne.CanvasObject,
|
||
|
decorator fyne.CanvasObject,
|
||
|
) {
|
||
|
h.exportedElements[id] = &screen.UIElement{Object: elem, Decorator: decorator}
|
||
|
}
|
||
|
|
||
|
// RegisterListItemTemplate registers a ListItemTemplate with the ScreenHandler.
|
||
|
//
|
||
|
// Use this function to register the templates for the lists used in the
|
||
|
// screen definition.
|
||
|
func (h *ScreenHandler) RegisterListItemTemplate(
|
||
|
name string,
|
||
|
fn screen.ListItemTemplateFn,
|
||
|
) {
|
||
|
h.listItemTemplates[name] = fn
|
||
|
}
|
||
|
|
||
|
// RegisterListDataItemRenderer registers a ListDataItemRenderer with the ScreenHandler.
|
||
|
//
|
||
|
// Use this function to register the renderers for the lists used in the
|
||
|
// screen definition.
|
||
|
func (h *ScreenHandler) RegisterListDataItemRenderer(
|
||
|
name string,
|
||
|
fn screen.ListDataItemRendererFn,
|
||
|
) {
|
||
|
h.listDataItemRenderers[name] = fn
|
||
|
}
|
||
|
|
||
|
// RegisterListItemRenderer registers a ListItemRenderer with the ScreenHandler.
|
||
|
//
|
||
|
// Use this function to register the renderers for the lists used in the
|
||
|
// screen definition.
|
||
|
func (h *ScreenHandler) RegisterListItemRenderer(
|
||
|
name string,
|
||
|
fn screen.ListItemRendererFn,
|
||
|
) {
|
||
|
h.listItemRenderers[name] = fn
|
||
|
}
|
||
|
|
||
|
// RegisterListLength registers a ListLength with the ScreenHandler.
|
||
|
//
|
||
|
// Use this function to register the lengths for the lists used in the
|
||
|
// screen definition.
|
||
|
func (h *ScreenHandler) RegisterListLength(
|
||
|
name string,
|
||
|
fn screen.ListLengthFn,
|
||
|
) {
|
||
|
h.listLengths[name] = fn
|
||
|
}
|
||
|
|
||
|
// RegisterOnListItemSelectedHandler registers a OnListItemSelectedHandler with the ScreenHandler.
|
||
|
//
|
||
|
// Use this function to register the handler functions used in the screen
|
||
|
// definition.
|
||
|
func (h *ScreenHandler) RegisterOnListItemSelectedHandler(
|
||
|
name string,
|
||
|
fn screen.ListItemHandlerFn,
|
||
|
) {
|
||
|
h.onListItemSelectedHandlers[name] = fn
|
||
|
}
|
||
|
|
||
|
// RegisterOnListItemUnselectedHandler registers a OnListItemUnselectedHandler with the ScreenHandler.
|
||
|
//
|
||
|
// Use this function to register the handler functions used in the screen
|
||
|
// definition.
|
||
|
func (h *ScreenHandler) RegisterOnListItemUnselectedHandler(
|
||
|
name string,
|
||
|
fn screen.ListItemHandlerFn,
|
||
|
) {
|
||
|
h.onListItemUnselectedHandlers[name] = fn
|
||
|
}
|
||
|
|
||
|
// RegisterOnClickHandler registers a OnClickHandler with the ScreenHandler.
|
||
|
//
|
||
|
// Use this function to register the handler functions used in the screen
|
||
|
// definition.
|
||
|
func (h *ScreenHandler) RegisterOnClickHandler(
|
||
|
name string,
|
||
|
fn screen.ClickHandlerFn,
|
||
|
) {
|
||
|
h.onClickedHandlers[name] = fn
|
||
|
}
|
||
|
|
||
|
// RegisterOnCheckChangedHandler registers a OnCheckChangedHandler with the ScreenHandler.
|
||
|
//
|
||
|
// Use this function to register the handler functions used in the screen
|
||
|
// definition.
|
||
|
func (h *ScreenHandler) RegisterOnCheckChangedHandler(
|
||
|
name string,
|
||
|
fn screen.CheckHandlerFn,
|
||
|
) {
|
||
|
h.onCheckChangedHandlers[name] = fn
|
||
|
}
|
||
|
|
||
|
// RegisterOnDateSelectedHandler registers a OnDateSelectedHandler with the ScreenHandler.
|
||
|
//
|
||
|
// Use this function to register the handler functions used in the screen
|
||
|
// definition.
|
||
|
func (h *ScreenHandler) RegisterOnDateSelectedHandler(
|
||
|
name string,
|
||
|
fn screen.DateSelectedHandlerFn,
|
||
|
) {
|
||
|
h.onDateSelectedHandlers[name] = fn
|
||
|
}
|
||
|
|
||
|
// RegisterOnValidationChangedHandler registers a OnValidationChangedHandler with the ScreenHandler.
|
||
|
//
|
||
|
// Use this function to register the handler functions used in the screen
|
||
|
// definition.
|
||
|
func (h *ScreenHandler) RegisterOnValidationChangedHandler(
|
||
|
name string,
|
||
|
fn screen.ValidationChangedHandlerFn,
|
||
|
) {
|
||
|
h.onValidationChangedHandlers[name] = fn
|
||
|
}
|
||
|
|
||
|
// GetBinding returns the binding with the given name.
|
||
|
//
|
||
|
// This function forwards the call to the controller. In the controller the
|
||
|
// required bindings should be mapped to the screen elements.
|
||
|
func (h *ScreenHandler) GetBinding(name string) binding.DataItem {
|
||
|
return h.ctrl.GetBinding(name)
|
||
|
}
|
||
|
|
||
|
// GetValidator returns the validator with the given name.
|
||
|
//
|
||
|
// This function forwards the call to the controller. In the controller the
|
||
|
// required validators should be mapped to the screen elements.
|
||
|
func (h *ScreenHandler) GetValidator(name string) fyne.StringValidator {
|
||
|
return h.ctrl.GetValidator(name)
|
||
|
}
|
||
|
|
||
|
// GetElement returns the UIElement with the given ID.
|
||
|
//
|
||
|
// This function allows you to retrieve the exported elements (given an ID in
|
||
|
// the screen definition). The UIElement contains the object and the decorator.
|
||
|
// Should no decorator be present, both point to the same widget. If a decorator
|
||
|
// is present it's advices to do hide and show operations on the decorator, and
|
||
|
// all other operators on the object.
|
||
|
func (h *ScreenHandler) GetElement(id string) *screen.UIElement {
|
||
|
if elem, ok := h.exportedElements[id]; ok {
|
||
|
return elem
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// GetLocalizer returns the i18n.Localizer used for localization.
|
||
|
func (h *ScreenHandler) GetLocalizer() *i18n.Localizer {
|
||
|
return h.localizer
|
||
|
}
|
||
|
|
||
|
// GetIcon returns the icon with the given name.
|
||
|
//
|
||
|
// This handler only implements the default theme icons. If you wish to support
|
||
|
// other items, wrap this ScreenHandler and implement the loading of the icons
|
||
|
// yourself.
|
||
|
func (h *ScreenHandler) 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
|
||
|
}
|
||
|
|
||
|
// GetListItemTemplate returns the ListItemTemplate with the given name.
|
||
|
func (h *ScreenHandler) GetListItemTemplate(name string) screen.ListItemTemplateFn {
|
||
|
fn, ok := h.listItemTemplates[name]
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
return fn
|
||
|
}
|
||
|
|
||
|
// GetListDataItemRenderer returns the ListDataItemRenderer with the given name.
|
||
|
func (h *ScreenHandler) GetListDataItemRenderer(name string) screen.ListDataItemRendererFn {
|
||
|
fn, ok := h.listDataItemRenderers[name]
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
return fn
|
||
|
}
|
||
|
|
||
|
// GetListItemRenderer returns the ListItemRenderer with the given name.
|
||
|
func (h *ScreenHandler) GetListItemRenderer(name string) screen.ListItemRendererFn {
|
||
|
fn, ok := h.listItemRenderers[name]
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
return fn
|
||
|
}
|
||
|
|
||
|
// GetListLength returns the ListLength with the given name.
|
||
|
func (h *ScreenHandler) GetListLength(name string) screen.ListLengthFn {
|
||
|
fn, ok := h.listLengths[name]
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
return fn
|
||
|
}
|
||
|
|
||
|
// GetOnListItemSelectedHandler returns the OnListItemSelectedHandler with the given name.
|
||
|
func (h *ScreenHandler) GetOnListItemSelectedHandler(name string) screen.ListItemHandlerFn {
|
||
|
fn, ok := h.onListItemSelectedHandlers[name]
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
return fn
|
||
|
}
|
||
|
|
||
|
// GetOnListItemUnselectedHandler returns the OnListItemUnselectedHandler with the given name.
|
||
|
func (h *ScreenHandler) GetOnListItemUnselectedHandler(name string) screen.ListItemHandlerFn {
|
||
|
fn, ok := h.onListItemUnselectedHandlers[name]
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
return fn
|
||
|
}
|
||
|
|
||
|
// GetOnClickedHandler returns the OnClickedHandler with the given name.
|
||
|
func (h *ScreenHandler) GetOnClickedHandler(name string) screen.ClickHandlerFn {
|
||
|
fn, ok := h.onClickedHandlers[name]
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
return fn
|
||
|
}
|
||
|
|
||
|
// GetOnCheckChangedHandler returns the OnCheckChangedHandler with the given name.
|
||
|
func (h *ScreenHandler) GetOnCheckChangedHandler(name string) screen.CheckHandlerFn {
|
||
|
fn, ok := h.onCheckChangedHandlers[name]
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
return fn
|
||
|
}
|
||
|
|
||
|
// GetOnDateSelectedHandler returns the OnDateSelectedHandler with the given name.
|
||
|
func (h *ScreenHandler) GetOnDateSelectedHandler(name string) screen.DateSelectedHandlerFn {
|
||
|
fn, ok := h.onDateSelectedHandlers[name]
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
return fn
|
||
|
}
|
||
|
|
||
|
// GetOnValidationChangedHandler returns the OnValidationChangedHandler with the given name.
|
||
|
func (h *ScreenHandler) GetOnValidationChangedHandler(name string) screen.ValidationChangedHandlerFn {
|
||
|
fn, ok := h.onValidationChangedHandlers[name]
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
return fn
|
||
|
}
|