From 727197ad484d143153dae815095e34b9d30e856e Mon Sep 17 00:00:00 2001 From: dreacot Date: Mon, 16 Oct 2023 20:56:10 -0600 Subject: [PATCH] - prevent data races in segmented control - create a decorated text widget - further code cleanup --- ui/cryptomaterial/label.go | 10 ++++ ui/cryptomaterial/segmented_control.go | 65 ++++++++++++++------------ 2 files changed, 45 insertions(+), 30 deletions(-) diff --git a/ui/cryptomaterial/label.go b/ui/cryptomaterial/label.go index 817adf844..6806d8cbf 100644 --- a/ui/cryptomaterial/label.go +++ b/ui/cryptomaterial/label.go @@ -3,6 +3,9 @@ package cryptomaterial import ( + "image/color" + + "gioui.org/font" "gioui.org/unit" "gioui.org/widget/material" ) @@ -61,3 +64,10 @@ func (t *Theme) labelWithDefaultColor(l Label) Label { l.Color = t.Color.DeepBlue return l } + +func (t *Theme) DecoratedText(size unit.Sp, txt string, color color.NRGBA, weight font.Weight) Label { + label := Label{material.Label(t.Base, size, txt)} + label.Color = color + label.Font.Weight = weight + return label +} diff --git a/ui/cryptomaterial/segmented_control.go b/ui/cryptomaterial/segmented_control.go index 364faad51..23d660aeb 100644 --- a/ui/cryptomaterial/segmented_control.go +++ b/ui/cryptomaterial/segmented_control.go @@ -1,6 +1,8 @@ package cryptomaterial import ( + "sync" + "gioui.org/font" "gioui.org/layout" @@ -15,6 +17,7 @@ type SegmentedControl struct { segmentTitles []string changed bool + mu sync.Mutex } func (t *Theme) SegmentedControl(segmentTitles []string) *SegmentedControl { @@ -40,42 +43,36 @@ func (sc *SegmentedControl) Layout(gtx C) D { layout.Rigid(func(gtx C) D { return sc.list.Layout(gtx, len(sc.segmentTitles), func(gtx C, i int) D { isSelectedSegment := sc.SelectedIndex() == i - return layout.Stack{Alignment: layout.Center}.Layout(gtx, - layout.Stacked(func(gtx C) D { - return layout.Inset{}.Layout(gtx, func(gtx C) D { - return layout.Center.Layout(gtx, func(gtx C) D { - bg := sc.theme.Color.SurfaceHighlight - txt := sc.theme.Label(values.TextSize16, sc.segmentTitles[i]) - txt.Color = sc.theme.Color.GrayText1 - txt.Font.Weight = font.SemiBold - border := Border{Radius: Radius(0)} - if isSelectedSegment { - bg = sc.theme.Color.Surface - txt.Color = sc.theme.Color.Text - border = Border{Radius: Radius(8)} - } - return LinearLayout{ - Width: WrapContent, - Height: WrapContent, - Padding: layout.UniformInset(values.MarginPadding8), - Background: bg, - Margin: layout.UniformInset(values.MarginPadding5), - Border: border, - }.Layout(gtx, - layout.Rigid(func(gtx C) D { - return txt.Layout(gtx) - }), - ) - }) - }) - }), - ) + return layout.Center.Layout(gtx, func(gtx C) D { + bg := sc.theme.Color.SurfaceHighlight + txt := sc.theme.DecoratedText(values.TextSize16, sc.segmentTitles[i], sc.theme.Color.GrayText1, font.SemiBold) + border := Border{Radius: Radius(0)} + if isSelectedSegment { + bg = sc.theme.Color.Surface + txt.Color = sc.theme.Color.Text + border = Border{Radius: Radius(8)} + } + return LinearLayout{ + Width: WrapContent, + Height: WrapContent, + Padding: layout.UniformInset(values.MarginPadding8), + Background: bg, + Margin: layout.UniformInset(values.MarginPadding5), + Border: border, + }.Layout(gtx, + layout.Rigid(func(gtx C) D { + return txt.Layout(gtx) + }), + ) + }) }) }), ) } func (sc *SegmentedControl) handleEvents() { + sc.mu.Lock() + defer sc.mu.Unlock() if segmentItemClicked, clickedSegmentIndex := sc.list.ItemClicked(); segmentItemClicked { if sc.selectedIndex != clickedSegmentIndex { sc.changed = true @@ -85,19 +82,27 @@ func (sc *SegmentedControl) handleEvents() { } func (sc *SegmentedControl) SelectedIndex() int { + sc.mu.Lock() + defer sc.mu.Unlock() return sc.selectedIndex } func (sc *SegmentedControl) SelectedSegment() string { + sc.mu.Lock() + defer sc.mu.Unlock() return sc.segmentTitles[sc.selectedIndex] } func (sc *SegmentedControl) Changed() bool { + sc.mu.Lock() + defer sc.mu.Unlock() changed := sc.changed sc.changed = false return changed } func (sc *SegmentedControl) SetSelectedSegment(segment string) { + sc.mu.Lock() + defer sc.mu.Unlock() for i, item := range sc.segmentTitles { if item == segment { sc.selectedIndex = i