Added scroll container and minsize layout
This commit is contained in:
		
							
								
								
									
										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,6 +15,7 @@ type Size struct { | ||||
| type Element struct { | ||||
| 	ID string `yaml:"id"` | ||||
|  | ||||
| 	Container Container `yaml:"container"` | ||||
| 	Layout    Layout    `yaml:"layout"` | ||||
| 	Widget    Widget    `yaml:"widget"` | ||||
|  | ||||
| @@ -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" | ||||
| @@ -16,11 +18,12 @@ const ( | ||||
| 	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) | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Maarten Heremans
					Maarten Heremans