Skip to content

Commit

Permalink
- prevent data races in segmented control
Browse files Browse the repository at this point in the history
- create a decorated text widget
- further code cleanup
  • Loading branch information
dreacot committed Oct 17, 2023
1 parent be7b6af commit 727197a
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 30 deletions.
10 changes: 10 additions & 0 deletions ui/cryptomaterial/label.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
package cryptomaterial

import (
"image/color"

"gioui.org/font"
"gioui.org/unit"
"gioui.org/widget/material"
)
Expand Down Expand Up @@ -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
}
65 changes: 35 additions & 30 deletions ui/cryptomaterial/segmented_control.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cryptomaterial

import (
"sync"

"gioui.org/font"
"gioui.org/layout"

Expand All @@ -15,6 +17,7 @@ type SegmentedControl struct {
segmentTitles []string

changed bool
mu sync.Mutex
}

func (t *Theme) SegmentedControl(segmentTitles []string) *SegmentedControl {
Expand All @@ -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
Expand All @@ -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
Expand Down

0 comments on commit 727197a

Please sign in to comment.