89 lines
2.3 KiB
Go
89 lines
2.3 KiB
Go
package components
|
|
|
|
import (
|
|
"image"
|
|
|
|
"gioui.org/layout"
|
|
"gioui.org/unit"
|
|
"gioui.org/widget"
|
|
"gioui.org/widget/material"
|
|
)
|
|
|
|
type ButtonState int
|
|
|
|
const (
|
|
NormalButton ButtonState = iota
|
|
SelectedButton
|
|
UnselectedButton
|
|
)
|
|
|
|
type iconAndTextButton struct {
|
|
theme *material.Theme
|
|
button *widget.Clickable
|
|
icon *widget.Icon
|
|
word string
|
|
axis layout.Axis
|
|
state ButtonState
|
|
}
|
|
|
|
func (b iconAndTextButton) Layout(gtx layout.Context) layout.Dimensions {
|
|
btn := material.ButtonLayout(b.theme, b.button)
|
|
switch b.state {
|
|
case NormalButton:
|
|
btn.Background = b.theme.Palette.Bg
|
|
case SelectedButton:
|
|
btn.Background = b.theme.Palette.ContrastBg
|
|
case UnselectedButton:
|
|
btn.Background = b.theme.Palette.Bg
|
|
}
|
|
|
|
return btn.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
|
return layout.UniformInset(unit.Dp(12)).Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
|
iconAndLabel := layout.Flex{Axis: b.axis, Alignment: layout.Middle}
|
|
var bottomSpacer, textIconSpacer unit.Dp
|
|
|
|
if b.axis == layout.Horizontal {
|
|
bottomSpacer = unit.Dp(0)
|
|
textIconSpacer = unit.Dp(2)
|
|
} else {
|
|
bottomSpacer = unit.Dp(2)
|
|
textIconSpacer = unit.Dp(0)
|
|
}
|
|
|
|
layIcon := layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
return layout.Inset{Bottom: bottomSpacer, Right: textIconSpacer}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
|
var d layout.Dimensions
|
|
if b.icon != nil {
|
|
size := gtx.Dp(unit.Dp(24))
|
|
|
|
if b.axis == layout.Horizontal {
|
|
size = gtx.Dp(unit.Dp(56)) - 2*gtx.Dp(unit.Dp(16))
|
|
}
|
|
|
|
gtx.Constraints = layout.Exact(image.Pt(size, size))
|
|
if b.state == SelectedButton {
|
|
d = b.icon.Layout(gtx, b.theme.Palette.ContrastFg)
|
|
} else {
|
|
d = b.icon.Layout(gtx, b.theme.Palette.Fg)
|
|
}
|
|
}
|
|
return d
|
|
})
|
|
})
|
|
|
|
layLabel := layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
return layout.Inset{Top: bottomSpacer, Right: textIconSpacer}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
|
l := material.Body1(b.theme, b.word)
|
|
if b.state == SelectedButton {
|
|
l.Color = b.theme.Palette.ContrastFg
|
|
} else {
|
|
l.Color = b.theme.Palette.Fg
|
|
}
|
|
return l.Layout(gtx)
|
|
})
|
|
})
|
|
|
|
return iconAndLabel.Layout(gtx, layIcon, layLabel)
|
|
})
|
|
})
|
|
}
|