borderlayout.go 3.8 KB

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