Skip to content

Commit

Permalink
Apply atomics to insternal basewidget also
Browse files Browse the repository at this point in the history
  • Loading branch information
Jacalz committed Jan 3, 2024
1 parent 30ac9f0 commit 910eea1
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 30 deletions.
46 changes: 23 additions & 23 deletions internal/widget/base.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package widget

import (
"math"
"sync"
"sync/atomic"

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
Expand All @@ -11,8 +13,8 @@ import (
// Base provides a helper that handles basic widget behaviours.
type Base struct {
hidden bool
position fyne.Position
size fyne.Size
position atomic.Uint64
size atomic.Uint64

impl fyne.Widget
propertyLock sync.RWMutex
Expand All @@ -32,27 +34,19 @@ func (w *Base) ExtendBaseWidget(wid fyne.Widget) {

// Size gets the current size of this widget.
func (w *Base) Size() fyne.Size {
w.propertyLock.RLock()
defer w.propertyLock.RUnlock()

return w.size
return fyne.NewSize(twoFloat32FromUint64(w.size.Load()))
}

// Resize sets a new size for a widget.
// Note this should not be used if the widget is being managed by a Layout within a Container.
func (w *Base) Resize(size fyne.Size) {
w.propertyLock.RLock()
baseSize := w.size
impl := w.impl
w.propertyLock.RUnlock()
if baseSize == size {
if size == w.Size() {
return
}

w.propertyLock.Lock()
w.size = size
w.propertyLock.Unlock()
w.size.Store(uint64fromTwoFloat32(size.Width, size.Height))

impl := w.super()
if impl == nil {
return
}
Expand All @@ -61,21 +55,15 @@ func (w *Base) Resize(size fyne.Size) {

// Position gets the current position of this widget, relative to its parent.
func (w *Base) Position() fyne.Position {
w.propertyLock.RLock()
defer w.propertyLock.RUnlock()

return w.position
return fyne.NewPos(twoFloat32FromUint64(w.position.Load()))
}

// Move the widget to a new position, relative to its parent.
// Note this should not be used if the widget is being managed by a Layout within a Container.
func (w *Base) Move(pos fyne.Position) {
w.propertyLock.Lock()
w.position = pos
impl := w.impl
w.propertyLock.Unlock()
w.position.Store(uint64fromTwoFloat32(pos.X, pos.Y))

Repaint(impl)
Repaint(w.super())
}

// MinSize for the widget - it should never be resized below this value.
Expand Down Expand Up @@ -176,3 +164,15 @@ func Repaint(obj fyne.CanvasObject) {
}
}
}

func uint64fromTwoFloat32(a, b float32) uint64 {
x := uint64(math.Float32bits(a))
y := uint64(math.Float32bits(b))
return (y << 32) | x
}

func twoFloat32FromUint64(combined uint64) (float32, float32) {
x := uint32(combined & 0x00000000FFFFFFFF)
y := uint32(combined & 0xFFFFFFFF00000000 >> 32)
return math.Float32frombits(x), math.Float32frombits(y)
}
10 changes: 5 additions & 5 deletions internal/widget/scroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,15 +256,15 @@ func (r *scrollContainerRenderer) layoutBars(size fyne.Size) {
r.vertArea.Move(fyne.NewPos(r.scroll.Size().Width-r.vertArea.Size().Width, 0))
r.topShadow.Resize(fyne.NewSize(size.Width, 0))
r.bottomShadow.Resize(fyne.NewSize(size.Width, 0))
r.bottomShadow.Move(fyne.NewPos(0, r.scroll.size.Height))
r.bottomShadow.Move(fyne.NewPos(0, r.scroll.Size().Height))
}

if r.scroll.Direction == ScrollHorizontalOnly || r.scroll.Direction == ScrollBoth {
r.horizArea.Resize(fyne.NewSize(size.Width, r.horizArea.MinSize().Height))
r.horizArea.Move(fyne.NewPos(0, r.scroll.Size().Height-r.horizArea.Size().Height))
r.leftShadow.Resize(fyne.NewSize(0, size.Height))
r.rightShadow.Resize(fyne.NewSize(0, size.Height))
r.rightShadow.Move(fyne.NewPos(r.scroll.size.Width, 0))
r.rightShadow.Move(fyne.NewPos(r.scroll.Size().Width, 0))
}

r.updatePosition()
Expand Down Expand Up @@ -334,7 +334,7 @@ func (r *scrollContainerRenderer) updatePosition() {
if r.scroll.Direction == ScrollVerticalOnly || r.scroll.Direction == ScrollBoth {
r.handleAreaVisibility(contentSize.Height, scrollSize.Height, r.vertArea)
r.handleShadowVisibility(r.scroll.Offset.Y, contentSize.Height, scrollSize.Height, r.topShadow, r.bottomShadow)
cache.Renderer(r.vertArea).Layout(r.scroll.size)
cache.Renderer(r.vertArea).Layout(r.scroll.Size())
} else {
r.vertArea.Hide()
r.topShadow.Hide()
Expand All @@ -343,7 +343,7 @@ func (r *scrollContainerRenderer) updatePosition() {
if r.scroll.Direction == ScrollHorizontalOnly || r.scroll.Direction == ScrollBoth {
r.handleAreaVisibility(contentSize.Width, scrollSize.Width, r.horizArea)
r.handleShadowVisibility(r.scroll.Offset.X, contentSize.Width, scrollSize.Width, r.leftShadow, r.rightShadow)
cache.Renderer(r.horizArea).Layout(r.scroll.size)
cache.Renderer(r.horizArea).Layout(r.scroll.Size())
} else {
r.horizArea.Hide()
r.leftShadow.Hide()
Expand Down Expand Up @@ -446,7 +446,7 @@ func (s *Scroll) Refresh() {

// Resize is called when this scroller should change size. We refresh to ensure the scroll bars are updated.
func (s *Scroll) Resize(sz fyne.Size) {
if sz == s.size {
if sz == s.Size() {
return
}

Expand Down
4 changes: 2 additions & 2 deletions internal/widget/scroller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ func TestScrollContainer_ShowShadowOnRightIfContentCanScroll(t *testing.T) {
scroll.Resize(fyne.NewSize(100, 100))
r := cache.Renderer(scroll).(*scrollContainerRenderer)
assert.True(t, r.rightShadow.Visible())
assert.Equal(t, scroll.size.Width, r.rightShadow.Position().X+r.rightShadow.Size().Width)
assert.Equal(t, scroll.Size().Width, r.rightShadow.Position().X+r.rightShadow.Size().Width)

scroll.Scrolled(&fyne.ScrollEvent{Scrolled: fyne.Delta{DX: -400}})
assert.False(t, r.rightShadow.Visible())
Expand Down Expand Up @@ -428,7 +428,7 @@ func TestScrollContainer_ShowShadowOnBottomIfContentCanScroll(t *testing.T) {
scroll.Resize(fyne.NewSize(100, 100))
r := cache.Renderer(scroll).(*scrollContainerRenderer)
assert.True(t, r.bottomShadow.Visible())
assert.Equal(t, scroll.size.Height, r.bottomShadow.Position().Y+r.bottomShadow.Size().Height)
assert.Equal(t, scroll.Size().Height, r.bottomShadow.Position().Y+r.bottomShadow.Size().Height)

scroll.Scrolled(&fyne.ScrollEvent{Scrolled: fyne.Delta{DY: -400}})
assert.False(t, r.bottomShadow.Visible())
Expand Down

0 comments on commit 910eea1

Please sign in to comment.