From ce115401230b06437247bb52fd065de6c238791b Mon Sep 17 00:00:00 2001 From: Maarten Heremans Date: Tue, 6 Aug 2024 21:30:11 +0200 Subject: [PATCH] Fix dialog layout --- dialog.go | 8 +++---- screen/element.go | 6 ++++++ screen/screen.go | 42 +++++++++++++++++++++++++++++++++++- screenhandler.go | 54 +++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 101 insertions(+), 9 deletions(-) diff --git a/dialog.go b/dialog.go index 57629c1..57e4b0b 100644 --- a/dialog.go +++ b/dialog.go @@ -100,7 +100,7 @@ func NewBaseDialogWithScreen( parent, confirm) var err error - d.ScreenHandler, err = NewScreenHandler( + d.ScreenHandler, err = NewDialogScreenHandler( filesystem, screenName, viewModel, localizer, assetLoader) if err != nil { LogWindowError(d, LoadScreen, err) @@ -148,7 +148,7 @@ func NewBaseDialogWithDataAndScreen( parent, confirm, data) var err error - d.ScreenHandler, err = NewScreenHandler( + d.ScreenHandler, err = NewDialogScreenHandler( filesystem, screenName, viewModel, localizer, assetLoader) if err != nil { LogWindowError(d, LoadScreen, err) @@ -228,7 +228,7 @@ func (d *BaseDialog) Initialize() fyne.CanvasObject { LogWindowError(d, Initialize, err) return nil } - d.CanvasObj = obj + d.CanvasObj = obj.(*screen.DialogScreen).AsContainer() } return d.CanvasObj } @@ -358,7 +358,7 @@ func (d *FormDialog) SetButtonLabels( func (d *FormDialog) Initialize() fyne.CanvasObject { if d.itemsFn == nil { - form := d.BaseDialog.Initialize().(*screen.Screen).AsContainer() + form := d.BaseDialog.Initialize().(*fyne.Container) d.itemsFn = func() []*widget.FormItem { res := make([]*widget.FormItem, 0, len(form.Objects)/2) for i := 0; i < len(form.Objects); i += 2 { diff --git a/screen/element.go b/screen/element.go index 04112b1..cec4364 100644 --- a/screen/element.go +++ b/screen/element.go @@ -47,6 +47,11 @@ func (p *Padding) HasPadding() bool { return p.Top > 0 || p.Bottom > 0 || p.Left > 0 || p.Right > 0 } +type ToolTip struct { + Content string `yaml:"content"` + Localized bool `yaml:"localized"` +} + // Element represents the yaml description of a ui element type Element struct { ID string `yaml:"id"` @@ -97,6 +102,7 @@ type Element struct { Options map[string]any `yaml:"options"` Disabled bool `yaml:"disabled"` Hidden bool `yaml:"hidden"` + ToolTip *ToolTip `yaml:"tooltip"` // Properties shared by most widgets Placeholder string `yaml:"placeholder"` diff --git a/screen/screen.go b/screen/screen.go index 3416e60..0664934 100644 --- a/screen/screen.go +++ b/screen/screen.go @@ -133,8 +133,12 @@ func (s *Screen) Resize(sz fyne.Size) { } } +func (s *Screen) MinSize() fyne.Size { + return s.CanvasObject.MinSize() +} + func (s *Screen) CreateRenderer() fyne.WidgetRenderer { - return widget.NewSimpleRenderer(s.CanvasObject) + return widget.NewSimpleRenderer(s.AsContainer()) } func (s *Screen) RegisterResizeCallback(cb func(fyne.Size)) { @@ -149,6 +153,42 @@ func (s *Screen) AsContainer() *fyne.Container { return s.CanvasObject.(*fyne.Container) } +type DialogScreen struct { + *Screen +} + +func NewDialogScreen( + filesystem embed.FS, + name string, + screenHandler ScreenHandler, +) (src *DialogScreen, err error) { + screen, err := New(filesystem, name, screenHandler) + if err != nil { + return + } + src = &DialogScreen{screen} + return +} + +func (s *DialogScreen) Initialize() (obj fyne.CanvasObject, err error) { + if s.CanvasObject, err = s.rootElement.BuildUI(s.screenHandler); err != nil { + err = fmt.Errorf("failed to build screen: %w", err) + return + } + obj = s + return +} + +func (s *DialogScreen) Move(p fyne.Position) { + c := fyne.CurrentApp().Driver().CanvasForObject(s.CanvasObject) + movePos := fyne.Position{ + X: p.X / c.Scale(), + Y: p.Y / c.Scale(), + } + s.CanvasObject.Move(movePos) + //fmt.Printf("%+v\n", s.CanvasObject.Position()); +} + type TemplateScreenHandler struct { localizer *i18n.Localizer elementsMap map[string]*UIElement diff --git a/screenhandler.go b/screenhandler.go index 96756d0..3c8d940 100644 --- a/screenhandler.go +++ b/screenhandler.go @@ -2,6 +2,7 @@ package ui import ( "embed" + "errors" "fmt" "io/fs" "log" @@ -14,6 +15,21 @@ import ( "github.com/nicksnyder/go-i18n/v2/i18n" ) +type screenType int + +const ( + stScreen screenType = iota + stDialog +) + +type ScreenDefinition interface { + fyne.Widget + Initialize() (fyne.CanvasObject, error) + RegisterResizeCallback(func(fyne.Size)) + RegisterMoveCallback(func(fyne.Position)) + AsContainer() *fyne.Container +} + // ScreenHandler represents the handler for a screen. // // It provides: @@ -24,7 +40,7 @@ import ( // - List item templates and renderers // - User interaction handlers type ScreenHandler struct { - screenDefinition *screen.Screen + screenDefinition ScreenDefinition localizer *i18n.Localizer viewModel BaseViewModel assetLoader func(string) (fs.File, error) @@ -63,18 +79,48 @@ func NewScreenHandler( viewModel BaseViewModel, localizer *i18n.Localizer, assetLoader func(string) (fs.File, error), +) (h *ScreenHandler, err error) { + return newScreenHandler( + stScreen, filesystem, screenName, viewModel, localizer, assetLoader) +} + +func NewDialogScreenHandler( + filesystem embed.FS, + screenName string, + viewModel BaseViewModel, + localizer *i18n.Localizer, + assetLoader func(string) (fs.File, error), +) (h *ScreenHandler, err error) { + return newScreenHandler( + stDialog, filesystem, screenName, viewModel, localizer, assetLoader) +} + +func newScreenHandler( + screenType screenType, + fileSystem embed.FS, + screenName string, + viewModel BaseViewModel, + localizer *i18n.Localizer, + assetLoader func(string) (fs.File, error), ) (h *ScreenHandler, err error) { h = new(ScreenHandler) h.viewModel = viewModel h.localizer = localizer - def, err := screen.New(filesystem, screenName, h) + switch screenType { + case stScreen: + h.screenDefinition, err = screen.New(fileSystem, screenName, h) + case stDialog: + h.screenDefinition, err = screen.NewDialogScreen(fileSystem, screenName, h) + default: + err = errors.New("Unsupported screen type") + } + if err != nil { err = fmt.Errorf("failure loading screen: %w", err) return } - h.screenDefinition = def h.assetLoader = assetLoader h.exportedElements = make(map[string]*screen.UIElement) @@ -93,7 +139,7 @@ func NewScreenHandler( } // ScreenDefinition returns the screen definition for the ScreenHandler. -func (h *ScreenHandler) ScreenDefinition() *screen.Screen { +func (h *ScreenHandler) ScreenDefinition() ScreenDefinition { return h.screenDefinition }