Added scroll container and minsize layout
This commit is contained in:
parent
18cf7858d6
commit
b9d2b680bc
93
screen/container.go
Normal file
93
screen/container.go
Normal file
@ -0,0 +1,93 @@
|
||||
package screen
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"bitbucket.org/hevanto/ui/uiwidget"
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/container"
|
||||
)
|
||||
|
||||
type Container string
|
||||
|
||||
const (
|
||||
HScroll Container = "HScroll"
|
||||
Scroll Container = "Scroll"
|
||||
VScroll Container = "VScroll"
|
||||
)
|
||||
|
||||
func (cnt Container) Build(e *Element, s ScreenHandler) (c fyne.CanvasObject, err error) {
|
||||
switch cnt {
|
||||
case HScroll:
|
||||
c, err = cnt.buildHScrollContainer(e, s)
|
||||
case Scroll:
|
||||
c, err = cnt.buildScrollContainer(e, s)
|
||||
case VScroll:
|
||||
c, err = cnt.buildVScrollContainer(e, s)
|
||||
default:
|
||||
err = errors.New("invalid container")
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if e.Decorators != nil {
|
||||
|
||||
for _, dec := range e.Decorators {
|
||||
switch dec {
|
||||
case "Border":
|
||||
c = uiwidget.NewWidgetBorder(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if e.Hidden {
|
||||
c.Hide()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ctn Container) buildHScrollContainer(e *Element, s ScreenHandler) (c fyne.CanvasObject, err error) {
|
||||
if e.Content == nil {
|
||||
err = errors.New("HScroll: no content defined")
|
||||
return
|
||||
}
|
||||
|
||||
content, err := e.Content.BuildUI(s)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("HScroll: failed to build content: %w", err)
|
||||
return
|
||||
}
|
||||
c = container.NewHScroll(content)
|
||||
return
|
||||
}
|
||||
|
||||
func (ctn Container) buildScrollContainer(e *Element, s ScreenHandler) (c fyne.CanvasObject, err error) {
|
||||
if e.Content == nil {
|
||||
err = errors.New("Scroll: no content defined")
|
||||
return
|
||||
}
|
||||
|
||||
content, err := e.Content.BuildUI(s)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Scroll: failed to build content: %w", err)
|
||||
return
|
||||
}
|
||||
c = container.NewScroll(content)
|
||||
return
|
||||
}
|
||||
|
||||
func (ctn Container) buildVScrollContainer(e *Element, s ScreenHandler) (c fyne.CanvasObject, err error) {
|
||||
if e.Content == nil {
|
||||
err = errors.New("VScroll: no content defined")
|
||||
return
|
||||
}
|
||||
|
||||
content, err := e.Content.BuildUI(s)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("VScroll: failed to build content: %w", err)
|
||||
return
|
||||
}
|
||||
c = container.NewScroll(content)
|
||||
return
|
||||
}
|
@ -15,8 +15,9 @@ type Size struct {
|
||||
type Element struct {
|
||||
ID string `yaml:"id"`
|
||||
|
||||
Layout Layout `yaml:"layout"`
|
||||
Widget Widget `yaml:"widget"`
|
||||
Container Container `yaml:"container"`
|
||||
Layout Layout `yaml:"layout"`
|
||||
Widget Widget `yaml:"widget"`
|
||||
|
||||
// Border Layout Elements
|
||||
Top *Element `yaml:"top"`
|
||||
@ -27,6 +28,7 @@ type Element struct {
|
||||
|
||||
// Other Layout Elements
|
||||
Children []*Element `yaml:"children"`
|
||||
Content *Element `yaml:"content"`
|
||||
|
||||
// Form Element
|
||||
Label *Element `yaml:"label"`
|
||||
@ -38,6 +40,9 @@ type Element struct {
|
||||
RowColumns *int `yaml:"rowColumns"`
|
||||
ElementSize *Size `yaml:"elementSize"`
|
||||
|
||||
// MinSize configuration
|
||||
MinSize *Size `yaml:"minSize"`
|
||||
|
||||
// Widget Properties
|
||||
Text string `yaml:"text"`
|
||||
Localized bool `yaml:"localized"`
|
||||
@ -81,6 +86,13 @@ func (e *Element) BuildUI(s ScreenHandler) (obj fyne.CanvasObject, err error) {
|
||||
}
|
||||
}()
|
||||
|
||||
if e.Container != "" {
|
||||
if obj, err = e.Container.Build(e, s); err != nil {
|
||||
err = fmt.Errorf("failed to build container element: %w", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
if e.Layout != "" {
|
||||
if obj, err = e.Layout.Build(e, s); err != nil {
|
||||
err = fmt.Errorf("failed to build layout element: %w", err)
|
||||
|
@ -4,6 +4,8 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"bitbucket.org/hevanto/ui/uilayout"
|
||||
"bitbucket.org/hevanto/ui/uiwidget"
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/layout"
|
||||
@ -12,15 +14,16 @@ import (
|
||||
type Layout string
|
||||
|
||||
const (
|
||||
Border Layout = "Border"
|
||||
Form Layout = "Form"
|
||||
Grid Layout = "Grid"
|
||||
HBox Layout = "HBox"
|
||||
Stack Layout = "Stack"
|
||||
VBox Layout = "VBox"
|
||||
Border Layout = "Border"
|
||||
Form Layout = "Form"
|
||||
Grid Layout = "Grid"
|
||||
HBox Layout = "HBox"
|
||||
MinSize Layout = "MinSize"
|
||||
Stack Layout = "Stack"
|
||||
VBox Layout = "VBox"
|
||||
)
|
||||
|
||||
func (l Layout) Build(e *Element, s ScreenHandler) (c *fyne.Container, err error) {
|
||||
func (l Layout) Build(e *Element, s ScreenHandler) (c fyne.CanvasObject, err error) {
|
||||
switch l {
|
||||
case Border:
|
||||
c, err = l.buildBorderLayout(e, s)
|
||||
@ -30,6 +33,8 @@ func (l Layout) Build(e *Element, s ScreenHandler) (c *fyne.Container, err error
|
||||
c, err = l.buildGridLayout(e, s)
|
||||
case HBox:
|
||||
c, err = l.buildHBoxLayout(e, s)
|
||||
case MinSize:
|
||||
c, err = l.buildMinSizeLayout(e, s)
|
||||
case Stack:
|
||||
c, err = l.buildStackLayout(e, s)
|
||||
case VBox:
|
||||
@ -41,6 +46,15 @@ func (l Layout) Build(e *Element, s ScreenHandler) (c *fyne.Container, err error
|
||||
return
|
||||
}
|
||||
|
||||
if e.Decorators != nil {
|
||||
for _, dec := range e.Decorators {
|
||||
switch dec {
|
||||
case "Border":
|
||||
c = uiwidget.NewWidgetBorder(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if e.Hidden {
|
||||
c.Hide()
|
||||
}
|
||||
@ -179,6 +193,29 @@ func (l Layout) buildHBoxLayout(e *Element, s ScreenHandler) (c *fyne.Container,
|
||||
return
|
||||
}
|
||||
|
||||
func (l Layout) buildMinSizeLayout(e *Element, s ScreenHandler) (c *fyne.Container, err error) {
|
||||
children := make([]fyne.CanvasObject, 0, len(e.Children))
|
||||
for _, child := range e.Children {
|
||||
var obj fyne.CanvasObject
|
||||
if obj, err = child.BuildUI(s); err != nil {
|
||||
err = fmt.Errorf("MinSizeLayout failed to create child element: %w", err)
|
||||
return
|
||||
}
|
||||
children = append(children, obj)
|
||||
}
|
||||
if e.MinSize == nil {
|
||||
e.MinSize = &Size{
|
||||
Width: 0,
|
||||
Height: 0,
|
||||
}
|
||||
}
|
||||
c = container.New(
|
||||
uilayout.NewMinSizeLayout(
|
||||
fyne.NewSize(e.MinSize.Width, e.MinSize.Height)),
|
||||
children...)
|
||||
return
|
||||
}
|
||||
|
||||
func (l Layout) buildStackLayout(e *Element, s ScreenHandler) (c *fyne.Container, err error) {
|
||||
children := make([]fyne.CanvasObject, 0, len(e.Children))
|
||||
for _, child := range e.Children {
|
||||
|
33
uilayout/minsize.go
Normal file
33
uilayout/minsize.go
Normal file
@ -0,0 +1,33 @@
|
||||
package uilayout
|
||||
|
||||
import "fyne.io/fyne/v2"
|
||||
|
||||
type MinSize struct {
|
||||
minSize fyne.Size
|
||||
}
|
||||
|
||||
func NewMinSizeLayout(minSize fyne.Size) *MinSize {
|
||||
return &MinSize{minSize: minSize}
|
||||
}
|
||||
|
||||
func (l *MinSize) MinSize(objects []fyne.CanvasObject) fyne.Size {
|
||||
size := l.minSize
|
||||
for _, o := range objects {
|
||||
childSize := o.MinSize()
|
||||
if size.Width < childSize.Width {
|
||||
size.Width = childSize.Width
|
||||
}
|
||||
if size.Height < childSize.Height {
|
||||
size.Height = childSize.Height
|
||||
}
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
func (l *MinSize) Layout(objects []fyne.CanvasObject, containerSize fyne.Size) {
|
||||
pos := fyne.NewPos(0, 0)
|
||||
for _, o := range objects {
|
||||
o.Resize(containerSize)
|
||||
o.Move(pos)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user