~eliasnaur/gio-patches

widget/material: add ButtonLayout v5 PROPOSED

metaclips: 1
 widget/material: add ButtonLayout

 2 files changed, 89 insertions(+), 21 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~eliasnaur/gio-patches/patches/10041/mbox | git am -3
Learn more about email & git

[PATCH v5] widget/material: add ButtonLayout Export this patch

Add ButtonLayout for adding button behaviour and style to arbitrary content such
as a combined icon-and-text button.
Updated example/kitchen to show feature.
Fixes #43

Signed-off-by: metaclips <utimichael9@gmail.com>
---
 example/kitchen/kitchen.go | 60 +++++++++++++++++++++++++++++++++-----
 widget/material/button.go  | 50 ++++++++++++++++++++++---------
 2 files changed, 89 insertions(+), 21 deletions(-)

diff --git a/example/kitchen/kitchen.go b/example/kitchen/kitchen.go
index 7755c62..86d3f29 100644
--- a/example/kitchen/kitchen.go
+++ b/example/kitchen/kitchen.go
@@ -19,6 +19,8 @@ import (

	"gioui.org/app"
	"gioui.org/app/headless"
	"gioui.org/font"
	"gioui.org/font/gofont"
	"gioui.org/io/system"
	"gioui.org/layout"
	"gioui.org/text"
@@ -27,8 +29,6 @@ import (
	"gioui.org/widget/material"

	"golang.org/x/exp/shiny/materialdesign/icons"

	"gioui.org/font/gofont"
)

var screenshot = flag.String("screenshot", "", "save a screenshot to a file and exit")
@@ -107,11 +107,14 @@ var (
		SingleLine: true,
		Submit:     true,
	}
	button            = new(widget.Button)
	greenButton       = new(widget.Button)
	iconButton        = new(widget.Button)
	radioButtonsGroup = new(widget.Enum)
	list              = &layout.List{
	button                   = new(widget.Button)
	greenButton              = new(widget.Button)
	iconButton               = new(widget.Button)
	horizontalIconTextButton = new(widget.Button)
	buttonAxis               = layout.Horizontal
	buttonLayoutText         = "Horizontal button"
	radioButtonsGroup        = new(widget.Enum)
	list                     = &layout.List{
		Axis: layout.Vertical,
	}
	green    = true
@@ -148,6 +151,49 @@ func kitchen(gtx *layout.Context, th *material.Theme) {
						th.IconButton(icon).Layout(gtx, iconButton)
					})
				}),
				layout.Rigid(func() {
					in.Layout(gtx, func() {
						for horizontalIconTextButton.Clicked(gtx) {
							if buttonAxis == layout.Vertical {
								buttonAxis = layout.Horizontal
								buttonLayoutText = "Horizontal button"
							} else {
								buttonAxis = layout.Vertical
								buttonLayoutText = "Vertical button"
							}
						}

						btnLayout := th.ButtonLayout()
						btnLayout.Inset = layout.UniformInset(unit.Dp(10))
						btnLayout.Layout(gtx, horizontalIconTextButton, func() {
							iconAndLabel := layout.Flex{Axis: buttonAxis, Alignment: layout.Middle}

							layIcon := layout.Rigid(func() {
								layout.UniformInset(unit.Dp(5)).Layout(gtx, func() {
									size := gtx.Px(unit.Dp(56)) - 2*gtx.Px(unit.Dp(16))
									if icon != nil {
										icon.Color = btnLayout.Color
										icon.Layout(gtx, unit.Px(float32(size)))
										gtx.Dimensions = layout.Dimensions{
											Size: image.Point{X: size, Y: size},
										}
									}
								})
							})

							layLabel := layout.Rigid(func() {
								layout.UniformInset(unit.Dp(5)).Layout(gtx, func() {
									widget.Label{}.Layout(gtx, font.Default(), text.Font{}, unit.Dp(14), buttonLayoutText)
								})
							})
							if icon != nil {
								iconAndLabel.Layout(gtx, layIcon, layLabel)
							} else {
								iconAndLabel.Layout(gtx, layLabel)
							}
						})
					})
				}),
				layout.Rigid(func() {
					in.Layout(gtx, func() {
						for button.Clicked(gtx) {
diff --git a/widget/material/button.go b/widget/material/button.go
index 8cea790..81a4672 100644
--- a/widget/material/button.go
+++ b/widget/material/button.go
@@ -29,6 +29,13 @@ type Button struct {
	shaper       text.Shaper
}

type ButtonLayout struct {
	Background   color.RGBA
	Color        color.RGBA
	CornerRadius unit.Value
	Inset        layout.Inset
}

type IconButton struct {
	Background color.RGBA
	Color      color.RGBA
@@ -40,10 +47,11 @@ type IconButton struct {

func (t *Theme) Button(txt string) Button {
	return Button{
		Text:       txt,
		Color:      rgb(0xffffff),
		Background: t.Color.Primary,
		TextSize:   t.TextSize.Scale(14.0 / 16.0),
		Text:         txt,
		Color:        rgb(0xffffff),
		CornerRadius: unit.Dp(4),
		Background:   t.Color.Primary,
		TextSize:     t.TextSize.Scale(14.0 / 16.0),
		Inset: layout.Inset{
			Top: unit.Dp(10), Bottom: unit.Dp(10),
			Left: unit.Dp(12), Right: unit.Dp(12),
@@ -52,6 +60,15 @@ func (t *Theme) Button(txt string) Button {
	}
}

func (t *Theme) ButtonLayout() ButtonLayout {
	return ButtonLayout{
		Background:   t.Color.Primary,
		Color:        t.Color.InvText,
		CornerRadius: unit.Dp(4),
		Inset:        layout.UniformInset(unit.Dp(12)),
	}
}

func (t *Theme) IconButton(icon *Icon) IconButton {
	return IconButton{
		Background: t.Color.Primary,
@@ -63,13 +80,20 @@ func (t *Theme) IconButton(icon *Icon) IconButton {
}

func (b Button) Layout(gtx *layout.Context, button *widget.Button) {
	col := b.Color
	bgcol := b.Background
	hmin := gtx.Constraints.Width.Min
	vmin := gtx.Constraints.Height.Min
	ButtonLayout{
		Background:   b.Background,
		CornerRadius: b.CornerRadius,
		Color:        b.Color,
		Inset:        b.Inset,
	}.Layout(gtx, button, func() {
		widget.Label{}.Layout(gtx, b.shaper, b.Font, b.TextSize, b.Text)
	})
}

func (b ButtonLayout) Layout(gtx *layout.Context, button *widget.Button, w layout.Widget) {
	layout.Stack{Alignment: layout.Center}.Layout(gtx,
		layout.Expanded(func() {
			rr := float32(gtx.Px(unit.Dp(4)))
			rr := float32(gtx.Px(b.CornerRadius))
			clip.Rect{
				Rect: f32.Rectangle{Max: f32.Point{
					X: float32(gtx.Constraints.Width.Min),
@@ -77,18 +101,16 @@ func (b Button) Layout(gtx *layout.Context, button *widget.Button) {
				}},
				NE: rr, NW: rr, SE: rr, SW: rr,
			}.Op(gtx.Ops).Add(gtx.Ops)
			fill(gtx, bgcol)
			fill(gtx, b.Background)
			for _, c := range button.History() {
				drawInk(gtx, c)
			}
		}),
		layout.Stacked(func() {
			gtx.Constraints.Width.Min = hmin
			gtx.Constraints.Height.Min = vmin
			layout.Center.Layout(gtx, func() {
				b.Inset.Layout(gtx, func() {
					paint.ColorOp{Color: col}.Add(gtx.Ops)
					widget.Label{}.Layout(gtx, b.shaper, b.Font, b.TextSize, b.Text)
					paint.ColorOp{Color: b.Color}.Add(gtx.Ops)
					w()
				})
			})
			pointer.Rect(image.Rectangle{Max: gtx.Dimensions.Size}).Add(gtx.Ops)
-- 
2.21.1 (Apple Git-122.3)
Almost there. Can you split the kitchen example change into its own commit? If
you don't, there will be a commit where kitchen won't build.

One comment below.
View this thread in the archives