-
Notifications
You must be signed in to change notification settings - Fork 0
/
grid.go
93 lines (83 loc) · 2.59 KB
/
grid.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
package main
import (
"github.com/AllenDang/giu"
"github.com/AllenDang/imgui-go"
"image"
"image/color"
)
type GridState struct {
itemWidth float32
itemHeight float32
}
func (s *GridState) Dispose() {
// Nothing to do here.
}
// GridBuilder Arrange widgets from given array of Samples in a grid layout where all grid items share equal size
// The selected item will be highlighted by a border.
func GridBuilder[T any](id string, columns int, rows int, values []T, selected int, onClicked func(i int), builder func(i int, selected bool, item T) giu.Widget) giu.Layout {
var layout giu.Layout
layout = append(layout, giu.Custom(func() {
imgui.PushID(id)
w, h := giu.GetAvailableRegion()
spacingX, spacingY := giu.GetItemSpacing()
itemWidth := (w - spacingX*float32(columns-1)) / float32(columns)
itemHeight := (h - spacingY*float32(rows-1)) / float32(rows)
var state *GridState
if s := giu.Context.GetState(id); s == nil {
state = &GridState{itemWidth: itemWidth, itemHeight: itemHeight}
giu.Context.SetState(id, state)
} else {
state = s.(*GridState)
state.itemWidth = itemWidth
state.itemHeight = itemHeight
}
}))
if len(values) > 0 && builder != nil {
for i, v := range values {
itemIdx := i
itemColumns := columns
if i >= columns*rows {
break
}
valueRef := v
layout = append(layout, giu.Custom(func() {
_ = itemIdx
_ = itemColumns
if itemIdx%itemColumns > 0 {
giu.SameLine()
}
if s := giu.Context.GetState(id); s != nil {
state := s.(*GridState)
isSelected := itemIdx == selected
giu.Child().Border(true).Size(state.itemWidth, state.itemHeight).Flags(giu.WindowFlagsNoScrollbar|giu.WindowFlagsNoScrollWithMouse).Layout(
giu.Custom(func() {
if !isSelected {
return
}
style := imgui.CurrentStyle()
availWidth, availHeight := giu.GetAvailableRegion()
canvas := giu.GetCanvas()
topLeftPos := giu.GetCursorScreenPos().Sub(image.Pt(int(style.FramePadding().X), int(2*style.FramePadding().Y)))
canvas.AddRect(
topLeftPos,
topLeftPos.Add(image.Pt(int(availWidth+2*style.FramePadding().X), int(availHeight+4*style.FramePadding().Y))),
color.RGBA{R: 255, G: 255, B: 255, A: 255},
6.,
giu.DrawFlagsRoundCornersAll,
2.,
)
}),
builder(itemIdx, isSelected, valueRef),
).Build()
giu.Event().OnClick(giu.MouseButtonLeft, func() {
if onClicked != nil {
onClicked(itemIdx)
}
}).Build()
}
}))
}
}
layout = append(layout, giu.Custom(func() { imgui.PopID() }))
return layout
}