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) }) }) }