~whereswaldon/gio-x

0eb3fcddb9ec3fceaa3ceb00151cf2358d1f934e — Chris Waldon 2 years ago cead928 a11y
deps,component: update to support new a11y APIs

This commit adds rudimentary support for the new accessibility
capabilities offered by the io/semantic package and the updated
widget{,/material} packages.

Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
M component/app_bar.go => component/app_bar.go +9 -6
@@ 83,7 83,7 @@ func (a *actionGroup) setActions(actions []AppBarAction, overflows []OverflowAct
	a.overflowState = make([]widget.Clickable, len(a.actions)+len(a.overflow))
}

func (a *actionGroup) layout(gtx C, th *material.Theme, overflowBtn *widget.Clickable) D {
func (a *actionGroup) layout(gtx C, th *material.Theme, overflowBtn *widget.Clickable, overflowDesc string) D {
	overflowedActions := len(a.actions)
	gtx.Constraints.Min.Y = 0
	widthDp := float32(gtx.Constraints.Max.X) / gtx.Metric.PxPerDp


@@ 114,7 114,7 @@ func (a *actionGroup) layout(gtx C, th *material.Theme, overflowBtn *widget.Clic
	if len(a.overflow)+overflowedActions > 0 {
		actions = append(actions, layout.Rigid(func(gtx C) D {
			gtx.Constraints.Min.Y = gtx.Constraints.Max.Y
			btn := material.IconButton(th, overflowBtn, moreIcon)
			btn := material.IconButton(th, overflowBtn, moreIcon, overflowDesc)
			btn.Size = unit.Dp(24)
			btn.Background = th.Palette.Bg
			btn.Color = th.Palette.Fg


@@ 366,8 366,11 @@ func SwapPairs(p material.Palette) material.Palette {
}

// Layout renders the app bar. It will span all available horizontal
// space (gtx.Constraints.Max.X), but has a fixed height.
func (a *AppBar) Layout(gtx layout.Context, theme *material.Theme) layout.Dimensions {
// space (gtx.Constraints.Max.X), but has a fixed height. The navDesc
// is an accessibility description for the navigation icon button, and
// the overflowDesc is an accessibility description for the overflow
// action button.
func (a *AppBar) Layout(gtx layout.Context, theme *material.Theme, navDesc, overflowDesc string) layout.Dimensions {
	a.initialize()
	gtx.Constraints.Max.Y = gtx.Px(unit.Dp(56))
	th := *theme


@@ 403,7 406,7 @@ func (a *AppBar) Layout(gtx layout.Context, theme *material.Theme) layout.Dimens
			if a.contextualAnim.Visible() {
				icon = cancelIcon
			}
			button := material.IconButton(&th, &a.NavigationButton, icon)
			button := material.IconButton(&th, &a.NavigationButton, icon, navDesc)
			button.Size = unit.Dp(24)
			button.Background = th.Palette.Bg
			button.Color = th.Fg


@@ 424,7 427,7 @@ func (a *AppBar) Layout(gtx layout.Context, theme *material.Theme) layout.Dimens
		layout.Flexed(1, func(gtx C) D {
			gtx.Constraints.Min.Y = gtx.Constraints.Max.Y
			return layout.E.Layout(gtx, func(gtx C) D {
				return actionSet.layout(gtx, &th, &a.overflowMenu.Clickable)
				return actionSet.layout(gtx, &th, &a.overflowMenu.Clickable, overflowDesc)
			})
		}),
	)

M component/discloser.go => component/discloser.go +1 -4
@@ 77,10 77,7 @@ func (d DiscloserStyle) Layout(gtx C, control, summary, detail layout.Widget) D 
	}.Layout(gtx,
		layout.Rigid(func(gtx C) D {
			controlWidget := func(gtx C) D {
				return layout.Stack{}.Layout(gtx,
					layout.Stacked(control),
					layout.Expanded(d.Clickable.Layout),
				)
				return d.Clickable.Layout(gtx, control)
			}
			return layout.Flex{
				Alignment: layout.Middle,

M component/scrim.go => component/scrim.go +30 -28
@@ 20,21 20,22 @@ type Scrim struct {
// Layout draws the scrim using the provided animation. If the animation indicates
// that the scrim is not visible, this is a no-op.
func (s *Scrim) Layout(gtx layout.Context, th *material.Theme, anim *VisibilityAnimation) layout.Dimensions {
	if !anim.Visible() {
		return layout.Dimensions{}
	}
	gtx.Constraints.Min = gtx.Constraints.Max
	currentAlpha := s.FinalAlpha
	if anim.Animating() {
		revealed := anim.Revealed(gtx)
		currentAlpha = uint8(float32(s.FinalAlpha) * revealed)
	}
	color := th.Fg
	color.A = currentAlpha
	fill := WithAlpha(color, currentAlpha)
	paintRect(gtx, gtx.Constraints.Max, fill)
	s.Clickable.Layout(gtx)
	return layout.Dimensions{Size: gtx.Constraints.Max}
	return s.Clickable.Layout(gtx, func(gtx C) D {
		if !anim.Visible() {
			return layout.Dimensions{}
		}
		gtx.Constraints.Min = gtx.Constraints.Max
		currentAlpha := s.FinalAlpha
		if anim.Animating() {
			revealed := anim.Revealed(gtx)
			currentAlpha = uint8(float32(s.FinalAlpha) * revealed)
		}
		color := th.Fg
		color.A = currentAlpha
		fill := WithAlpha(color, currentAlpha)
		paintRect(gtx, gtx.Constraints.Max, fill)
		return layout.Dimensions{Size: gtx.Constraints.Max}
	})
}

// ScrimState defines persistent state for a scrim.


@@ 61,17 62,18 @@ func NewScrim(th *material.Theme, scrim *ScrimState, alpha uint8) ScrimStyle {
}

func (scrim ScrimStyle) Layout(gtx C) D {
	if !scrim.Visible() {
		return D{}
	}
	gtx.Constraints.Min = gtx.Constraints.Max
	alpha := scrim.FinalAlpha
	if scrim.Animating() {
		alpha = uint8(float32(scrim.FinalAlpha) * scrim.Revealed(gtx))
	}
	defer scrim.Clickable.Layout(gtx)
	return Rect{
		Color: WithAlpha(scrim.Color, alpha),
		Size:  gtx.Constraints.Max,
	}.Layout(gtx)
	return scrim.Clickable.Layout(gtx, func(gtx C) D {
		if !scrim.Visible() {
			return D{}
		}
		gtx.Constraints.Min = gtx.Constraints.Max
		alpha := scrim.FinalAlpha
		if scrim.Animating() {
			alpha = uint8(float32(scrim.FinalAlpha) * scrim.Revealed(gtx))
		}
		return Rect{
			Color: WithAlpha(scrim.Color, alpha),
			Size:  gtx.Constraints.Max,
		}.Layout(gtx)
	})
}

M component/text_field.go => component/text_field.go +14 -52
@@ 7,6 7,7 @@ import (
	"time"

	"gioui.org/f32"
	"gioui.org/gesture"
	"gioui.org/io/pointer"
	"gioui.org/layout"
	"gioui.org/op"


@@ 21,8 22,9 @@ import (
type TextField struct {
	// Editor contains the edit buffer.
	widget.Editor
	// Hoverable detects mouse hovers.
	Hoverable Hoverable
	// click detects when the mouse pointer clicks or hovers
	// within the textfield.
	click gesture.Click
	// Alignment specifies where to anchor the text.
	Alignment layout.Alignment



@@ 115,11 117,13 @@ func (in *TextField) TextTooLong() bool {

func (in *TextField) Update(gtx C, th *material.Theme, hint string) {
	disabled := gtx.Queue == nil
	for in.Hoverable.Clicked() {
	for range in.click.Events(gtx) {
	}
	if in.click.Pressed() {
		in.Editor.Focus()
	}
	in.state = inactive
	if in.Hoverable.Hovered() && !disabled {
	if in.click.Hovered() && !disabled {
		in.state = hovered
	}
	if in.Editor.Len() > 0 {


@@ 333,7 337,12 @@ func (in *TextField) Layout(gtx C, th *material.Theme, hint string) D {
					)
				}),
				layout.Expanded(func(gtx C) D {
					return in.Hoverable.Layout(gtx)
					defer pointer.PassOp{}.Push(gtx.Ops).Pop()
					defer pointer.Rect(image.Rectangle{
						Max: gtx.Constraints.Min,
					}).Push(gtx.Ops).Pop()
					in.click.Add(gtx.Ops)
					return D{}
				}),
			)
		}),


@@ 401,50 410,3 @@ func (in *TextField) Layout(gtx C, th *material.Theme, hint string) D {
func lerp(start, end, progress float32) float32 {
	return start + (end-start)*progress
}

// Hoverable tracks mouse hovers over some area.
type Hoverable struct {
	widget.Clickable
	hovered bool
}

// Hovered if mouse has entered the area.
func (h *Hoverable) Hovered() bool {
	return h.hovered
}

// Layout Hoverable according to min constraints.
func (h *Hoverable) Layout(gtx C) D {
	{
		pt := pointer.PassOp{}.Push(gtx.Ops)
		stack := pointer.Rect(image.Rectangle{Max: gtx.Constraints.Min}).Push(gtx.Ops)
		h.Clickable.Layout(gtx)
		stack.Pop()
		pt.Pop()
	}
	h.update(gtx)
	{
		pt := pointer.PassOp{}.Push(gtx.Ops)
		stack := pointer.Rect(image.Rectangle{Max: gtx.Constraints.Min}).Push(gtx.Ops)
		pointer.InputOp{
			Tag:   h,
			Types: pointer.Enter | pointer.Leave | pointer.Cancel,
		}.Add(gtx.Ops)
		stack.Pop()
		pt.Pop()
	}
	return D{Size: gtx.Constraints.Min}
}

func (h *Hoverable) update(gtx C) {
	for _, event := range gtx.Events(h) {
		if event, ok := event.(pointer.Event); ok {
			switch event.Type {
			case pointer.Enter:
				h.hovered = true
			case pointer.Leave, pointer.Cancel:
				h.hovered = false
			}
		}
	}
}

M component/tooltip.go => component/tooltip.go +1 -1
@@ 246,7 246,7 @@ type TipIconButtonStyle struct {
// TipIconButton creates a TipIconButtonStyle.
func TipIconButton(th *material.Theme, area *TipArea, button *widget.Clickable, label string, icon *widget.Icon) TipIconButtonStyle {
	return TipIconButtonStyle{
		IconButtonStyle: material.IconButton(th, button, icon),
		IconButtonStyle: material.IconButton(th, button, icon, label),
		State:           area,
		Tooltip:         PlatformTooltip(th, label),
	}

M go.mod => go.mod +1 -1
@@ 3,7 3,7 @@ module gioui.org/x
go 1.16

require (
	gioui.org v0.0.0-20211026101311-1eab4b84a6d3
	gioui.org v0.0.0-20211201162354-9a5298914282
	github.com/yuin/goldmark v1.4.0
	golang.org/x/exp v0.0.0-20210722180016-6781d3edade3
	golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d

M go.sum => go.sum +8 -0
@@ 5,6 5,14 @@ gioui.org v0.0.0-20211026101311-1eab4b84a6d3 h1:kgz+ANJMlCF5Qd9Rqu8Xu1CKl4asi9AK
gioui.org v0.0.0-20211026101311-1eab4b84a6d3/go.mod h1:yoWOxPng6WkDpsud+NRmkoftmyWn3rkKsYGEcWHpjTI=
gioui.org v0.0.0-20211026101311-9cf7cc75f468 h1:8lKC0jESs/gMz+kYbJWzFB1bkwMdlux36LYvBB9UDtw=
gioui.org v0.0.0-20211026101311-9cf7cc75f468/go.mod h1:yoWOxPng6WkDpsud+NRmkoftmyWn3rkKsYGEcWHpjTI=
gioui.org v0.0.0-20211130134758-67847733ac6a h1:kox8u+S7s6/8wT44rdK/LqJk2tEtfdxN/6fvoZ9WknM=
gioui.org v0.0.0-20211130134758-67847733ac6a/go.mod h1:yoWOxPng6WkDpsud+NRmkoftmyWn3rkKsYGEcWHpjTI=
gioui.org v0.0.0-20211130141120-dfedb065df27 h1:RCKtmko2wvGzpcxMQMniW12qPGPt2I3e0WXhkN12jc8=
gioui.org v0.0.0-20211130141120-dfedb065df27/go.mod h1:yoWOxPng6WkDpsud+NRmkoftmyWn3rkKsYGEcWHpjTI=
gioui.org v0.0.0-20211130163955-919827027682 h1:oVq/wQFIEPjKve5KUl7yE3Y7yNH1Wo8H9Lnk9m2eeLw=
gioui.org v0.0.0-20211130163955-919827027682/go.mod h1:yoWOxPng6WkDpsud+NRmkoftmyWn3rkKsYGEcWHpjTI=
gioui.org v0.0.0-20211201162354-9a5298914282 h1:AhBq0mtPYfXW7XyJ5ixFi7VA0/gwPC7HykpTTHTR9Lc=
gioui.org v0.0.0-20211201162354-9a5298914282/go.mod h1:yoWOxPng6WkDpsud+NRmkoftmyWn3rkKsYGEcWHpjTI=
gioui.org/cpu v0.0.0-20210808092351-bfe733dd3334/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ=
gioui.org/cpu v0.0.0-20210817075930-8d6a761490d2 h1:AGDDxsJE1RpcXTAxPG2B4jrwVUJGFDjINIPi1jtO6pc=
gioui.org/cpu v0.0.0-20210817075930-8d6a761490d2/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ=