-
Notifications
You must be signed in to change notification settings - Fork 1
/
iconbutton.go
132 lines (117 loc) · 3.3 KB
/
iconbutton.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package gel
import (
"image"
"github.com/cybriq/p9/pkg/gel/gio/f32"
"github.com/cybriq/p9/pkg/gel/gio/io/pointer"
l "github.com/cybriq/p9/pkg/gel/gio/layout"
"github.com/cybriq/p9/pkg/gel/gio/op/clip"
"github.com/cybriq/p9/pkg/gel/gio/unit"
"golang.org/x/exp/shiny/materialdesign/icons"
"github.com/cybriq/p9/pkg/gel/f32color"
)
type IconButton struct {
*Window
background string
// Color is the icon color.
color string
icon *Icon
// Size is the icon size.
size unit.Value
inset *Inset
button *Clickable
corners int
}
// IconButton creates an icon with a circular *optional non-round corners* background and an icon placed in the centre
func (w *Window) IconButton(button *Clickable) *IconButton {
return &IconButton{
Window: w,
background: "Primary",
color: "DocBg",
size: w.TextSize,
inset: w.Inset(0.33, nil),
button: button,
icon: w.Icon().Src(&icons.AlertError),
}
}
// Corners sets the corners that will be circular
func (b *IconButton) Corners(corners int) *IconButton {
b.corners = corners
return b
}
// Background sets the color of the circular background
func (b *IconButton) Background(color string) *IconButton {
b.background = color
return b
}
// Color sets the color of the icon
func (b *IconButton) Color(color string) *IconButton {
b.color = color
return b
}
// Icon sets the icon to display
func (b *IconButton) Icon(ic *Icon) *IconButton {
b.icon = ic
return b
}
// Scale changes the size of the icon as a ratio of the base font size
func (b *IconButton) Scale(scale float32) *IconButton {
b.size = b.Theme.TextSize.Scale(scale * 0.72)
return b
}
// ButtonInset sets the size of inset that goes in between the button background
// and the icon
func (b *IconButton) ButtonInset(inset float32) *IconButton {
b.inset = b.Inset(inset, b.button.Fn)
return b
}
// SetClick sets the function to run on click
func (b *IconButton) SetClick(fn func()) *IconButton {
b.button.SetClick(fn)
return b
}
// SetPress sets the function to run on press
func (b *IconButton) SetPress(fn func()) *IconButton {
b.button.SetPress(fn)
return b
}
// SetCancel sets the function to run on cancel (click but release outside)
func (b *IconButton) SetCancel(fn func()) *IconButton {
b.button.SetCancel(fn)
return b
}
// Fn renders the icon button
func (b *IconButton) Fn(gtx l.Context) l.Dimensions {
return b.Stack().Expanded(
func(gtx l.Context) l.Dimensions {
sizex, sizey := gtx.Constraints.Min.X, gtx.Constraints.Min.Y
sizexf, sizeyf := float32(sizex), float32(sizey)
rr := (sizexf + sizeyf) * .25
clip.RRect{
Rect: f32.Rectangle{Max: f32.Point{X: sizexf, Y: sizeyf}},
NE: ifDir(rr, b.corners&NE),
NW: ifDir(rr, b.corners&NW),
SE: ifDir(rr, b.corners&SE),
SW: ifDir(rr, b.corners&SW),
}.Add(gtx.Ops)
background := b.Theme.Colors.GetNRGBAFromName(b.background)
if gtx.Queue == nil {
background = f32color.MulAlpha(background, 150)
}
var dims l.Dimensions
if b.background != "" {
dims = Fill(gtx, background)
}
for _, c := range b.button.History() {
drawInk(gtx, c)
}
return dims
},
).Stacked(
b.inset.Embed(b.icon.Fn).Fn,
).Expanded(
func(gtx l.Context) l.Dimensions {
pointer.Ellipse(image.Rectangle{Max: gtx.Constraints.Min}).Add(gtx.Ops)
return b.button.Fn(gtx)
},
).Fn(gtx)
}