/
borderlayout.go
97 lines (85 loc) · 3.74 KB
/
borderlayout.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package layout
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/theme"
)
// Declare conformity with Layout interface
var _ fyne.Layout = (*borderLayout)(nil)
type borderLayout struct {
top, bottom, left, right fyne.CanvasObject
}
// NewBorderLayout creates a new BorderLayout instance with top, bottom, left
// and right objects set. All other items in the container will fill the centre
// space
func NewBorderLayout(top, bottom, left, right fyne.CanvasObject) fyne.Layout {
return &borderLayout{top, bottom, left, right}
}
// Layout is called to pack all child objects into a specified size.
// For BorderLayout this arranges the top, bottom, left and right widgets at
// the sides and any remaining widgets are maximised in the middle space.
func (b *borderLayout) Layout(objects []fyne.CanvasObject, size fyne.Size) {
var topSize, bottomSize, leftSize, rightSize fyne.Size
if b.top != nil && b.top.Visible() {
b.top.Resize(fyne.NewSize(size.Width, b.top.MinSize().Height))
b.top.Move(fyne.NewPos(0, 0))
topSize = fyne.NewSize(size.Width, b.top.MinSize().Height+theme.Padding())
}
if b.bottom != nil && b.bottom.Visible() {
b.bottom.Resize(fyne.NewSize(size.Width, b.bottom.MinSize().Height))
b.bottom.Move(fyne.NewPos(0, size.Height-b.bottom.MinSize().Height))
bottomSize = fyne.NewSize(size.Width, b.bottom.MinSize().Height+theme.Padding())
}
if b.left != nil && b.left.Visible() {
b.left.Resize(fyne.NewSize(b.left.MinSize().Width, size.Height-topSize.Height-bottomSize.Height))
b.left.Move(fyne.NewPos(0, topSize.Height))
leftSize = fyne.NewSize(b.left.MinSize().Width+theme.Padding(), size.Height-topSize.Height-bottomSize.Height)
}
if b.right != nil && b.right.Visible() {
b.right.Resize(fyne.NewSize(b.right.MinSize().Width, size.Height-topSize.Height-bottomSize.Height))
b.right.Move(fyne.NewPos(size.Width-b.right.MinSize().Width, topSize.Height))
rightSize = fyne.NewSize(b.right.MinSize().Width+theme.Padding(), size.Height-topSize.Height-bottomSize.Height)
}
middleSize := fyne.NewSize(size.Width-leftSize.Width-rightSize.Width, size.Height-topSize.Height-bottomSize.Height)
middlePos := fyne.NewPos(leftSize.Width, topSize.Height)
for _, child := range objects {
if !child.Visible() {
continue
}
if child != b.top && child != b.bottom && child != b.left && child != b.right {
child.Resize(middleSize)
child.Move(middlePos)
}
}
}
// MinSize finds the smallest size that satisfies all the child objects.
// For BorderLayout this is determined by the MinSize height of the top and
// plus the MinSize width of the left and right, plus any padding needed.
// This is then added to the union of the MinSize for any remaining content.
func (b *borderLayout) MinSize(objects []fyne.CanvasObject) fyne.Size {
minSize := fyne.NewSize(0, 0)
for _, child := range objects {
if !child.Visible() {
continue
}
if child != b.top && child != b.bottom && child != b.left && child != b.right {
minSize = minSize.Max(child.MinSize())
}
}
if b.left != nil && b.left.Visible() {
minHeight := fyne.Max(minSize.Height, b.left.MinSize().Height)
minSize = fyne.NewSize(minSize.Width+b.left.MinSize().Width+theme.Padding(), minHeight)
}
if b.right != nil && b.right.Visible() {
minHeight := fyne.Max(minSize.Height, b.right.MinSize().Height)
minSize = fyne.NewSize(minSize.Width+b.right.MinSize().Width+theme.Padding(), minHeight)
}
if b.top != nil && b.top.Visible() {
minWidth := fyne.Max(minSize.Width, b.top.MinSize().Width)
minSize = fyne.NewSize(minWidth, minSize.Height+b.top.MinSize().Height+theme.Padding())
}
if b.bottom != nil && b.bottom.Visible() {
minWidth := fyne.Max(minSize.Width, b.bottom.MinSize().Width)
minSize = fyne.NewSize(minWidth, minSize.Height+b.bottom.MinSize().Height+theme.Padding())
}
return minSize
}