borderlayout.go 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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. var topSize, bottomSize, leftSize, rightSize fyne.Size
  22. if b.top != nil && b.top.Visible() {
  23. b.top.Resize(fyne.NewSize(size.Width, b.top.MinSize().Height))
  24. b.top.Move(fyne.NewPos(0, 0))
  25. topSize = fyne.NewSize(size.Width, b.top.MinSize().Height+theme.Padding())
  26. }
  27. if b.bottom != nil && b.bottom.Visible() {
  28. b.bottom.Resize(fyne.NewSize(size.Width, b.bottom.MinSize().Height))
  29. b.bottom.Move(fyne.NewPos(0, size.Height-b.bottom.MinSize().Height))
  30. bottomSize = fyne.NewSize(size.Width, b.bottom.MinSize().Height+theme.Padding())
  31. }
  32. if b.left != nil && b.left.Visible() {
  33. b.left.Resize(fyne.NewSize(b.left.MinSize().Width, size.Height-topSize.Height-bottomSize.Height))
  34. b.left.Move(fyne.NewPos(0, topSize.Height))
  35. leftSize = fyne.NewSize(b.left.MinSize().Width+theme.Padding(), size.Height-topSize.Height-bottomSize.Height)
  36. }
  37. if b.right != nil && b.right.Visible() {
  38. b.right.Resize(fyne.NewSize(b.right.MinSize().Width, size.Height-topSize.Height-bottomSize.Height))
  39. b.right.Move(fyne.NewPos(size.Width-b.right.MinSize().Width, topSize.Height))
  40. rightSize = fyne.NewSize(b.right.MinSize().Width+theme.Padding(), size.Height-topSize.Height-bottomSize.Height)
  41. }
  42. middleSize := fyne.NewSize(size.Width-leftSize.Width-rightSize.Width, size.Height-topSize.Height-bottomSize.Height)
  43. middlePos := fyne.NewPos(leftSize.Width, topSize.Height)
  44. for _, child := range objects {
  45. if !child.Visible() {
  46. continue
  47. }
  48. if child != b.top && child != b.bottom && child != b.left && child != b.right {
  49. child.Resize(middleSize)
  50. child.Move(middlePos)
  51. }
  52. }
  53. }
  54. // MinSize finds the smallest size that satisfies all the child objects.
  55. // For BorderLayout this is determined by the MinSize height of the top and
  56. // plus the MinSize width of the left and right, plus any padding needed.
  57. // This is then added to the union of the MinSize for any remaining content.
  58. func (b *borderLayout) MinSize(objects []fyne.CanvasObject) fyne.Size {
  59. minSize := fyne.NewSize(0, 0)
  60. for _, child := range objects {
  61. if !child.Visible() {
  62. continue
  63. }
  64. if child != b.top && child != b.bottom && child != b.left && child != b.right {
  65. minSize = minSize.Max(child.MinSize())
  66. }
  67. }
  68. if b.left != nil && b.left.Visible() {
  69. minHeight := fyne.Max(minSize.Height, b.left.MinSize().Height)
  70. minSize = fyne.NewSize(minSize.Width+b.left.MinSize().Width+theme.Padding(), minHeight)
  71. }
  72. if b.right != nil && b.right.Visible() {
  73. minHeight := fyne.Max(minSize.Height, b.right.MinSize().Height)
  74. minSize = fyne.NewSize(minSize.Width+b.right.MinSize().Width+theme.Padding(), minHeight)
  75. }
  76. if b.top != nil && b.top.Visible() {
  77. minWidth := fyne.Max(minSize.Width, b.top.MinSize().Width)
  78. minSize = fyne.NewSize(minWidth, minSize.Height+b.top.MinSize().Height+theme.Padding())
  79. }
  80. if b.bottom != nil && b.bottom.Visible() {
  81. minWidth := fyne.Max(minSize.Width, b.bottom.MinSize().Width)
  82. minSize = fyne.NewSize(minWidth, minSize.Height+b.bottom.MinSize().Height+theme.Padding())
  83. }
  84. return minSize
  85. }