...
1 package etk
2
3 import (
4 "image"
5
6 "github.com/hajimehoshi/ebiten/v2"
7 )
8
9
10
11
12
13
14 type Flex struct {
15 *Box
16 vertical bool
17 childWidth, childHeight int
18 columnGap, rowGap int
19 modified bool
20 }
21
22
23 func NewFlex() *Flex {
24 return &Flex{
25 Box: NewBox(),
26 columnGap: 5,
27 rowGap: 5,
28 }
29 }
30
31
32 func (f *Flex) SetRect(r image.Rectangle) {
33 f.Lock()
34 defer f.Unlock()
35
36 f.Box.rect = r
37 f.modified = true
38 }
39
40
41 func (f *Flex) SetGaps(columnGap int, rowGap int) {
42 f.Lock()
43 defer f.Unlock()
44
45 if f.columnGap == columnGap && f.rowGap == rowGap {
46 return
47 }
48
49 f.columnGap, f.rowGap = columnGap, rowGap
50 f.modified = true
51 }
52
53
54 func (f *Flex) SetChildSize(width int, height int) {
55 f.Lock()
56 defer f.Unlock()
57
58 if f.childWidth == width && f.childHeight == height {
59 return
60 }
61
62 f.childWidth, f.childHeight = width, height
63 f.modified = true
64 }
65
66
67 func (f *Flex) SetVertical(v bool) {
68 f.Lock()
69 defer f.Unlock()
70
71 if f.vertical == v {
72 return
73 }
74
75 f.vertical = v
76 f.modified = true
77 }
78
79
80 func (f *Flex) AddChild(w ...Widget) {
81 f.Lock()
82 defer f.Unlock()
83
84 f.children = append(f.children, w...)
85 f.modified = true
86 }
87
88
89 func (f *Flex) HandleKeyboard(ebiten.Key, rune) (handled bool, err error) {
90 return false, nil
91 }
92
93
94 func (f *Flex) HandleMouse(cursor image.Point, pressed bool, clicked bool) (handled bool, err error) {
95 return false, nil
96 }
97
98
99 func (f *Flex) Draw(screen *ebiten.Image) error {
100 f.Lock()
101 defer f.Unlock()
102
103 if f.modified {
104 f.reposition()
105 f.modified = false
106 }
107
108 for _, child := range f.children {
109 err := child.Draw(screen)
110 if err != nil {
111 return err
112 }
113 }
114
115 return nil
116 }
117
118 func (f *Flex) reposition() {
119 r := f.rect
120 childWidth := f.childWidth
121 if childWidth == 0 {
122 if f.vertical {
123 childWidth = r.Dx()
124 } else if len(f.children) > 0 {
125 var gapSpace int
126 if len(f.children) > 1 {
127 gapSpace = f.columnGap * (len(f.children) - 1)
128 }
129 childWidth = (r.Dx() - gapSpace) / len(f.children)
130 }
131 }
132 childHeight := f.childHeight
133 if childHeight == 0 {
134 if f.vertical && len(f.children) > 0 {
135 var gapSpace int
136 if len(f.children) > 1 {
137 gapSpace = f.rowGap * (len(f.children) - 1)
138 }
139 childHeight = (r.Dy() - gapSpace) / len(f.children)
140 } else {
141 childHeight = r.Dy()
142 }
143 }
144
145 rects := make([]image.Rectangle, len(f.children))
146 x1, y1 := r.Min.X, r.Min.Y
147 if f.vertical {
148 for i := range f.children {
149 x2, y2 := x1+childWidth, y1+childHeight
150 if y2 > r.Max.Y {
151 return
152 }
153 rects[i] = image.Rect(x1, y1, x2, y2)
154
155 y1 += childHeight + f.rowGap
156 if y1 > r.Max.Y-childHeight {
157 rects[i].Max.Y = r.Max.Y
158 x1 += childWidth + f.columnGap
159 y1 = r.Min.Y
160 }
161 }
162 } else {
163 for i := range f.children {
164 x2, y2 := x1+childWidth, y1+childHeight
165 if x2 > r.Max.X {
166 return
167 }
168 rects[i] = image.Rect(x1, y1, x2, y2)
169
170 x1 += childWidth + f.columnGap
171 if x1 > r.Max.X-childWidth {
172 rects[i].Max.X = r.Max.X
173 y1 += childHeight + f.rowGap
174 x1 = r.Min.X
175 }
176 }
177 }
178 for i, child := range f.children {
179 child.SetRect(rects[i])
180 }
181 }
182
View as plain text