...
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 } else if childWidth > r.Dx() {
132 childWidth = r.Dx()
133 }
134 childHeight := f.childHeight
135 if childHeight == 0 {
136 if f.vertical && len(f.children) > 0 {
137 var gapSpace int
138 if len(f.children) > 1 {
139 gapSpace = f.rowGap * (len(f.children) - 1)
140 }
141 childHeight = (r.Dy() - gapSpace) / len(f.children)
142 } else {
143 childHeight = r.Dy()
144 }
145 } else if childHeight > r.Dy() {
146 childHeight = r.Dy()
147 }
148
149 rects := make([]image.Rectangle, len(f.children))
150 x1, y1 := r.Min.X, r.Min.Y
151 if f.vertical {
152 for i := range f.children {
153 x2, y2 := x1+childWidth, y1+childHeight
154 if y2 > r.Max.Y {
155 return
156 }
157 rects[i] = image.Rect(x1, y1, x2, y2)
158
159 y1 += childHeight + f.rowGap
160 if y1 > r.Max.Y-childHeight {
161 rects[i].Max.Y = r.Max.Y
162 x1 += childWidth + f.columnGap
163 y1 = r.Min.Y
164 }
165 }
166 } else {
167 for i := range f.children {
168 x2, y2 := x1+childWidth, y1+childHeight
169 if x2 > r.Max.X {
170 return
171 }
172 rects[i] = image.Rect(x1, y1, x2, y2)
173
174 x1 += childWidth + f.columnGap
175 if x1 > r.Max.X-childWidth {
176 rects[i].Max.X = r.Max.X
177 y1 += childHeight + f.rowGap
178 x1 = r.Min.X
179 }
180 }
181 }
182 for i, child := range f.children {
183 child.SetRect(rects[i])
184 }
185 }
186
View as plain text