-
Notifications
You must be signed in to change notification settings - Fork 21
/
clickable.go
105 lines (90 loc) · 2.72 KB
/
clickable.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
package cryptomaterial
import (
"image"
"gioui.org/layout"
"gioui.org/op/clip"
"gioui.org/op/paint"
"gioui.org/unit"
"gioui.org/widget"
"github.com/crypto-power/cryptopower/ui/values"
)
type Clickable struct {
button *widget.Clickable
style *values.ClickableStyle
Hoverable bool
Radius CornerRadius
isEnabled bool
}
func (t *Theme) NewClickable(hoverable bool) *Clickable {
return &Clickable{
button: &widget.Clickable{},
style: t.Styles.ClickableStyle,
Hoverable: hoverable,
isEnabled: true,
}
}
func (cl *Clickable) Style() values.ClickableStyle {
return *cl.style
}
func (cl *Clickable) ChangeStyle(style *values.ClickableStyle) {
cl.style = style
}
func (cl *Clickable) Clicked() bool {
return cl.button.Clicked()
}
func (cl *Clickable) IsHovered() bool {
return cl.button.Hovered()
}
// SetEnabled enables/disables the clickable.
func (cl *Clickable) SetEnabled(enable bool, gtx *layout.Context) layout.Context {
var mGtx layout.Context
if gtx != nil && !enable {
mGtx = gtx.Disabled()
}
cl.isEnabled = enable
return mGtx
}
// Return clickable enabled/disabled state.
func (cl *Clickable) Enabled() bool {
return cl.isEnabled
}
// LayoutWithInset draws a layout of a clickable and applies an hover effect if
// an hover action is detected. rightInset and bottomInset are used to restrict
// hover layout and should be supplied ONLY if a right or bottom inset/margin
// was applied to w.
func (cl *Clickable) LayoutWithInset(gtx C, w layout.Widget, rightInset, bottomInset unit.Dp) D {
return cl.button.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
return layout.Stack{}.Layout(gtx,
layout.Expanded(func(gtx layout.Context) layout.Dimensions {
// Only hover on a widget, ignore inset or margin applied.
gtx.Constraints.Min.Y = gtx.Constraints.Min.Y - gtx.Dp(bottomInset)
gtx.Constraints.Min.X = gtx.Constraints.Min.X - gtx.Dp(rightInset)
tr := gtx.Dp(unit.Dp(cl.Radius.TopRight))
tl := gtx.Dp(unit.Dp(cl.Radius.TopLeft))
br := gtx.Dp(unit.Dp(cl.Radius.BottomRight))
bl := gtx.Dp(unit.Dp(cl.Radius.BottomLeft))
defer clip.RRect{
Rect: image.Rectangle{
Max: image.Point{
X: gtx.Constraints.Min.X,
Y: gtx.Constraints.Min.Y,
},
},
NW: tl, NE: tr, SE: br, SW: bl,
}.Push(gtx.Ops).Pop()
clip.Rect{Max: gtx.Constraints.Min}.Push(gtx.Ops).Pop()
if cl.Hoverable && cl.button.Hovered() {
paint.Fill(gtx.Ops, cl.style.HoverColor)
}
for _, c := range cl.button.History() {
drawInk(gtx, c, cl.style.Color)
}
return layout.Dimensions{Size: gtx.Constraints.Min}
}),
layout.Stacked(w),
)
})
}
func (cl *Clickable) Layout(gtx C, w layout.Widget) D {
return cl.LayoutWithInset(gtx, w, 0, 0)
}