Skip to content

Commit 0eb3fcd

Browse files
committed
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 <[email protected]>
1 parent cead928 commit 0eb3fcd

File tree

7 files changed

+64
-92
lines changed

7 files changed

+64
-92
lines changed

component/app_bar.go

+9-6
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func (a *actionGroup) setActions(actions []AppBarAction, overflows []OverflowAct
8383
a.overflowState = make([]widget.Clickable, len(a.actions)+len(a.overflow))
8484
}
8585

86-
func (a *actionGroup) layout(gtx C, th *material.Theme, overflowBtn *widget.Clickable) D {
86+
func (a *actionGroup) layout(gtx C, th *material.Theme, overflowBtn *widget.Clickable, overflowDesc string) D {
8787
overflowedActions := len(a.actions)
8888
gtx.Constraints.Min.Y = 0
8989
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
114114
if len(a.overflow)+overflowedActions > 0 {
115115
actions = append(actions, layout.Rigid(func(gtx C) D {
116116
gtx.Constraints.Min.Y = gtx.Constraints.Max.Y
117-
btn := material.IconButton(th, overflowBtn, moreIcon)
117+
btn := material.IconButton(th, overflowBtn, moreIcon, overflowDesc)
118118
btn.Size = unit.Dp(24)
119119
btn.Background = th.Palette.Bg
120120
btn.Color = th.Palette.Fg
@@ -366,8 +366,11 @@ func SwapPairs(p material.Palette) material.Palette {
366366
}
367367

368368
// Layout renders the app bar. It will span all available horizontal
369-
// space (gtx.Constraints.Max.X), but has a fixed height.
370-
func (a *AppBar) Layout(gtx layout.Context, theme *material.Theme) layout.Dimensions {
369+
// space (gtx.Constraints.Max.X), but has a fixed height. The navDesc
370+
// is an accessibility description for the navigation icon button, and
371+
// the overflowDesc is an accessibility description for the overflow
372+
// action button.
373+
func (a *AppBar) Layout(gtx layout.Context, theme *material.Theme, navDesc, overflowDesc string) layout.Dimensions {
371374
a.initialize()
372375
gtx.Constraints.Max.Y = gtx.Px(unit.Dp(56))
373376
th := *theme
@@ -403,7 +406,7 @@ func (a *AppBar) Layout(gtx layout.Context, theme *material.Theme) layout.Dimens
403406
if a.contextualAnim.Visible() {
404407
icon = cancelIcon
405408
}
406-
button := material.IconButton(&th, &a.NavigationButton, icon)
409+
button := material.IconButton(&th, &a.NavigationButton, icon, navDesc)
407410
button.Size = unit.Dp(24)
408411
button.Background = th.Palette.Bg
409412
button.Color = th.Fg
@@ -424,7 +427,7 @@ func (a *AppBar) Layout(gtx layout.Context, theme *material.Theme) layout.Dimens
424427
layout.Flexed(1, func(gtx C) D {
425428
gtx.Constraints.Min.Y = gtx.Constraints.Max.Y
426429
return layout.E.Layout(gtx, func(gtx C) D {
427-
return actionSet.layout(gtx, &th, &a.overflowMenu.Clickable)
430+
return actionSet.layout(gtx, &th, &a.overflowMenu.Clickable, overflowDesc)
428431
})
429432
}),
430433
)

component/discloser.go

+1-4
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,7 @@ func (d DiscloserStyle) Layout(gtx C, control, summary, detail layout.Widget) D
7777
}.Layout(gtx,
7878
layout.Rigid(func(gtx C) D {
7979
controlWidget := func(gtx C) D {
80-
return layout.Stack{}.Layout(gtx,
81-
layout.Stacked(control),
82-
layout.Expanded(d.Clickable.Layout),
83-
)
80+
return d.Clickable.Layout(gtx, control)
8481
}
8582
return layout.Flex{
8683
Alignment: layout.Middle,

component/scrim.go

+30-28
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,22 @@ type Scrim struct {
2020
// Layout draws the scrim using the provided animation. If the animation indicates
2121
// that the scrim is not visible, this is a no-op.
2222
func (s *Scrim) Layout(gtx layout.Context, th *material.Theme, anim *VisibilityAnimation) layout.Dimensions {
23-
if !anim.Visible() {
24-
return layout.Dimensions{}
25-
}
26-
gtx.Constraints.Min = gtx.Constraints.Max
27-
currentAlpha := s.FinalAlpha
28-
if anim.Animating() {
29-
revealed := anim.Revealed(gtx)
30-
currentAlpha = uint8(float32(s.FinalAlpha) * revealed)
31-
}
32-
color := th.Fg
33-
color.A = currentAlpha
34-
fill := WithAlpha(color, currentAlpha)
35-
paintRect(gtx, gtx.Constraints.Max, fill)
36-
s.Clickable.Layout(gtx)
37-
return layout.Dimensions{Size: gtx.Constraints.Max}
23+
return s.Clickable.Layout(gtx, func(gtx C) D {
24+
if !anim.Visible() {
25+
return layout.Dimensions{}
26+
}
27+
gtx.Constraints.Min = gtx.Constraints.Max
28+
currentAlpha := s.FinalAlpha
29+
if anim.Animating() {
30+
revealed := anim.Revealed(gtx)
31+
currentAlpha = uint8(float32(s.FinalAlpha) * revealed)
32+
}
33+
color := th.Fg
34+
color.A = currentAlpha
35+
fill := WithAlpha(color, currentAlpha)
36+
paintRect(gtx, gtx.Constraints.Max, fill)
37+
return layout.Dimensions{Size: gtx.Constraints.Max}
38+
})
3839
}
3940

4041
// ScrimState defines persistent state for a scrim.
@@ -61,17 +62,18 @@ func NewScrim(th *material.Theme, scrim *ScrimState, alpha uint8) ScrimStyle {
6162
}
6263

6364
func (scrim ScrimStyle) Layout(gtx C) D {
64-
if !scrim.Visible() {
65-
return D{}
66-
}
67-
gtx.Constraints.Min = gtx.Constraints.Max
68-
alpha := scrim.FinalAlpha
69-
if scrim.Animating() {
70-
alpha = uint8(float32(scrim.FinalAlpha) * scrim.Revealed(gtx))
71-
}
72-
defer scrim.Clickable.Layout(gtx)
73-
return Rect{
74-
Color: WithAlpha(scrim.Color, alpha),
75-
Size: gtx.Constraints.Max,
76-
}.Layout(gtx)
65+
return scrim.Clickable.Layout(gtx, func(gtx C) D {
66+
if !scrim.Visible() {
67+
return D{}
68+
}
69+
gtx.Constraints.Min = gtx.Constraints.Max
70+
alpha := scrim.FinalAlpha
71+
if scrim.Animating() {
72+
alpha = uint8(float32(scrim.FinalAlpha) * scrim.Revealed(gtx))
73+
}
74+
return Rect{
75+
Color: WithAlpha(scrim.Color, alpha),
76+
Size: gtx.Constraints.Max,
77+
}.Layout(gtx)
78+
})
7779
}

component/text_field.go

+14-52
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"time"
88

99
"gioui.org/f32"
10+
"gioui.org/gesture"
1011
"gioui.org/io/pointer"
1112
"gioui.org/layout"
1213
"gioui.org/op"
@@ -21,8 +22,9 @@ import (
2122
type TextField struct {
2223
// Editor contains the edit buffer.
2324
widget.Editor
24-
// Hoverable detects mouse hovers.
25-
Hoverable Hoverable
25+
// click detects when the mouse pointer clicks or hovers
26+
// within the textfield.
27+
click gesture.Click
2628
// Alignment specifies where to anchor the text.
2729
Alignment layout.Alignment
2830

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

116118
func (in *TextField) Update(gtx C, th *material.Theme, hint string) {
117119
disabled := gtx.Queue == nil
118-
for in.Hoverable.Clicked() {
120+
for range in.click.Events(gtx) {
121+
}
122+
if in.click.Pressed() {
119123
in.Editor.Focus()
120124
}
121125
in.state = inactive
122-
if in.Hoverable.Hovered() && !disabled {
126+
if in.click.Hovered() && !disabled {
123127
in.state = hovered
124128
}
125129
if in.Editor.Len() > 0 {
@@ -333,7 +337,12 @@ func (in *TextField) Layout(gtx C, th *material.Theme, hint string) D {
333337
)
334338
}),
335339
layout.Expanded(func(gtx C) D {
336-
return in.Hoverable.Layout(gtx)
340+
defer pointer.PassOp{}.Push(gtx.Ops).Pop()
341+
defer pointer.Rect(image.Rectangle{
342+
Max: gtx.Constraints.Min,
343+
}).Push(gtx.Ops).Pop()
344+
in.click.Add(gtx.Ops)
345+
return D{}
337346
}),
338347
)
339348
}),
@@ -401,50 +410,3 @@ func (in *TextField) Layout(gtx C, th *material.Theme, hint string) D {
401410
func lerp(start, end, progress float32) float32 {
402411
return start + (end-start)*progress
403412
}
404-
405-
// Hoverable tracks mouse hovers over some area.
406-
type Hoverable struct {
407-
widget.Clickable
408-
hovered bool
409-
}
410-
411-
// Hovered if mouse has entered the area.
412-
func (h *Hoverable) Hovered() bool {
413-
return h.hovered
414-
}
415-
416-
// Layout Hoverable according to min constraints.
417-
func (h *Hoverable) Layout(gtx C) D {
418-
{
419-
pt := pointer.PassOp{}.Push(gtx.Ops)
420-
stack := pointer.Rect(image.Rectangle{Max: gtx.Constraints.Min}).Push(gtx.Ops)
421-
h.Clickable.Layout(gtx)
422-
stack.Pop()
423-
pt.Pop()
424-
}
425-
h.update(gtx)
426-
{
427-
pt := pointer.PassOp{}.Push(gtx.Ops)
428-
stack := pointer.Rect(image.Rectangle{Max: gtx.Constraints.Min}).Push(gtx.Ops)
429-
pointer.InputOp{
430-
Tag: h,
431-
Types: pointer.Enter | pointer.Leave | pointer.Cancel,
432-
}.Add(gtx.Ops)
433-
stack.Pop()
434-
pt.Pop()
435-
}
436-
return D{Size: gtx.Constraints.Min}
437-
}
438-
439-
func (h *Hoverable) update(gtx C) {
440-
for _, event := range gtx.Events(h) {
441-
if event, ok := event.(pointer.Event); ok {
442-
switch event.Type {
443-
case pointer.Enter:
444-
h.hovered = true
445-
case pointer.Leave, pointer.Cancel:
446-
h.hovered = false
447-
}
448-
}
449-
}
450-
}

component/tooltip.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ type TipIconButtonStyle struct {
246246
// TipIconButton creates a TipIconButtonStyle.
247247
func TipIconButton(th *material.Theme, area *TipArea, button *widget.Clickable, label string, icon *widget.Icon) TipIconButtonStyle {
248248
return TipIconButtonStyle{
249-
IconButtonStyle: material.IconButton(th, button, icon),
249+
IconButtonStyle: material.IconButton(th, button, icon, label),
250250
State: area,
251251
Tooltip: PlatformTooltip(th, label),
252252
}

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module gioui.org/x
33
go 1.16
44

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

go.sum

+8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ gioui.org v0.0.0-20211026101311-1eab4b84a6d3 h1:kgz+ANJMlCF5Qd9Rqu8Xu1CKl4asi9AK
55
gioui.org v0.0.0-20211026101311-1eab4b84a6d3/go.mod h1:yoWOxPng6WkDpsud+NRmkoftmyWn3rkKsYGEcWHpjTI=
66
gioui.org v0.0.0-20211026101311-9cf7cc75f468 h1:8lKC0jESs/gMz+kYbJWzFB1bkwMdlux36LYvBB9UDtw=
77
gioui.org v0.0.0-20211026101311-9cf7cc75f468/go.mod h1:yoWOxPng6WkDpsud+NRmkoftmyWn3rkKsYGEcWHpjTI=
8+
gioui.org v0.0.0-20211130134758-67847733ac6a h1:kox8u+S7s6/8wT44rdK/LqJk2tEtfdxN/6fvoZ9WknM=
9+
gioui.org v0.0.0-20211130134758-67847733ac6a/go.mod h1:yoWOxPng6WkDpsud+NRmkoftmyWn3rkKsYGEcWHpjTI=
10+
gioui.org v0.0.0-20211130141120-dfedb065df27 h1:RCKtmko2wvGzpcxMQMniW12qPGPt2I3e0WXhkN12jc8=
11+
gioui.org v0.0.0-20211130141120-dfedb065df27/go.mod h1:yoWOxPng6WkDpsud+NRmkoftmyWn3rkKsYGEcWHpjTI=
12+
gioui.org v0.0.0-20211130163955-919827027682 h1:oVq/wQFIEPjKve5KUl7yE3Y7yNH1Wo8H9Lnk9m2eeLw=
13+
gioui.org v0.0.0-20211130163955-919827027682/go.mod h1:yoWOxPng6WkDpsud+NRmkoftmyWn3rkKsYGEcWHpjTI=
14+
gioui.org v0.0.0-20211201162354-9a5298914282 h1:AhBq0mtPYfXW7XyJ5ixFi7VA0/gwPC7HykpTTHTR9Lc=
15+
gioui.org v0.0.0-20211201162354-9a5298914282/go.mod h1:yoWOxPng6WkDpsud+NRmkoftmyWn3rkKsYGEcWHpjTI=
816
gioui.org/cpu v0.0.0-20210808092351-bfe733dd3334/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ=
917
gioui.org/cpu v0.0.0-20210817075930-8d6a761490d2 h1:AGDDxsJE1RpcXTAxPG2B4jrwVUJGFDjINIPi1jtO6pc=
1018
gioui.org/cpu v0.0.0-20210817075930-8d6a761490d2/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ=

0 commit comments

Comments
 (0)