go-simple-ui/internal/components/icon_button.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)
})
})
}