Skip to content

Commit 8514602

Browse files
authored
Merge pull request fyne-io#2580 from toaster/feature/geometry_add
geometry addition helpers
2 parents 728757e + 2a32ffb commit 8514602

File tree

3 files changed

+220
-34
lines changed

3 files changed

+220
-34
lines changed

geometry.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ func (p Position) Add(v Vector2) Position {
4949
return Position{p.X + x, p.Y + y}
5050
}
5151

52+
// AddXY returns a new Position by adding x and y to the current one.
53+
func (p Position) AddXY(x, y float32) Position {
54+
return Position{p.X + x, p.Y + y}
55+
}
56+
5257
// Components returns the X and Y elements of this Position
5358
func (p Position) Components() (float32, float32) {
5459
return p.X, p.Y
@@ -66,6 +71,11 @@ func (p Position) Subtract(v Vector2) Position {
6671
return Position{p.X - x, p.Y - y}
6772
}
6873

74+
// SubtractXY returns a new Position by subtracting x and y from the current one.
75+
func (p Position) SubtractXY(x, y float32) Position {
76+
return Position{p.X - x, p.Y - y}
77+
}
78+
6979
// Size describes something with width and height.
7080
type Size struct {
7181
Width float32 // The number of units along the X axis.
@@ -84,6 +94,11 @@ func (s Size) Add(v Vector2) Size {
8494
return Size{s.Width + w, s.Height + h}
8595
}
8696

97+
// AddWidthHeight returns a new Size by adding width and height to the current one.
98+
func (s Size) AddWidthHeight(width, height float32) Size {
99+
return Size{s.Width + width, s.Height + height}
100+
}
101+
87102
// IsZero returns whether the Size has zero width and zero height.
88103
func (s Size) IsZero() bool {
89104
return s.Width == 0.0 && s.Height == 0.0
@@ -120,3 +135,8 @@ func (s Size) Subtract(v Vector2) Size {
120135
w, h := v.Components()
121136
return Size{s.Width - w, s.Height - h}
122137
}
138+
139+
// SubtractWidthHeight returns a new Size by subtracting width and height from the current one.
140+
func (s Size) SubtractWidthHeight(width, height float32) Size {
141+
return Size{s.Width - width, s.Height - height}
142+
}

geometry_benchmark_test.go

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// +build !ci
2+
3+
package fyne_test
4+
5+
import (
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
10+
"fyne.io/fyne/v2"
11+
)
12+
13+
func BenchmarkPosition_Add(b *testing.B) {
14+
b.Run("Add()", benchmarkPositionAdd)
15+
b.Run("AddXY()", benchmarkPositionAddXY)
16+
}
17+
18+
func BenchmarkPosition_Subtract(b *testing.B) {
19+
b.Run("Subtract()", benchmarkPositionSubtract)
20+
b.Run("SubtractXY()", benchmarkPositionSubtractXY)
21+
}
22+
23+
func BenchmarkSize_Add(b *testing.B) {
24+
b.Run("Add()", benchmarkSizeAdd)
25+
b.Run("AddWidthHeight()", benchmarkSizeAddWidthHeight)
26+
}
27+
28+
func BenchmarkSize_Subtract(b *testing.B) {
29+
b.Run("Subtract()", benchmarkSizeSubtract)
30+
b.Run("SubtractWidthHeight()", benchmarkSizeSubtractWidthHeight)
31+
}
32+
33+
// This test prevents Position.Add to be simplified to `return p.AddXY(v.Components())`
34+
// because this slows down the speed by factor 10.
35+
func TestPosition_Add_Speed(t *testing.T) {
36+
add := testing.Benchmark(benchmarkPositionAdd)
37+
addXY := testing.Benchmark(benchmarkPositionAddXY)
38+
assert.Less(t, add.NsPerOp()/addXY.NsPerOp(), int64(5))
39+
}
40+
41+
// This test prevents Position.Subtract to be simplified to `return p.SubtractXY(v.Components())`
42+
// because this slows down the speed by factor 10.
43+
func TestPosition_Subtract_Speed(t *testing.T) {
44+
subtract := testing.Benchmark(benchmarkPositionSubtract)
45+
subtractXY := testing.Benchmark(benchmarkPositionSubtractXY)
46+
assert.Less(t, subtract.NsPerOp()/subtractXY.NsPerOp(), int64(5))
47+
}
48+
49+
// This test prevents Size.Add to be simplified to `return s.AddWidthHeight(v.Components())`
50+
// because this slows down the speed by factor 10.
51+
func TestSize_Add_Speed(t *testing.T) {
52+
add := testing.Benchmark(benchmarkSizeAdd)
53+
addWidthHeight := testing.Benchmark(benchmarkSizeAddWidthHeight)
54+
assert.Less(t, add.NsPerOp()/addWidthHeight.NsPerOp(), int64(5))
55+
}
56+
57+
// This test prevents Size.Subtract to be simplified to `return s.SubtractWidthHeight(v.Components())`
58+
// because this slows down the speed by factor 10.
59+
func TestSize_Subtract_Speed(t *testing.T) {
60+
subtract := testing.Benchmark(benchmarkSizeSubtract)
61+
subtractWidthHeight := testing.Benchmark(benchmarkSizeSubtractWidthHeight)
62+
assert.Less(t, subtract.NsPerOp()/subtractWidthHeight.NsPerOp(), int64(5))
63+
}
64+
65+
var benchmarkResult interface{}
66+
67+
func benchmarkPositionAdd(b *testing.B) {
68+
pos := fyne.NewPos(10, 10)
69+
for n := 0; n < b.N; n++ {
70+
pos = pos.Add(fyne.NewPos(float32(n), float32(n)))
71+
}
72+
benchmarkResult = pos
73+
}
74+
75+
func benchmarkPositionAddXY(b *testing.B) {
76+
pos := fyne.NewPos(10, 10)
77+
for n := 0; n < b.N; n++ {
78+
pos = pos.AddXY(float32(n), float32(n))
79+
}
80+
benchmarkResult = pos
81+
}
82+
83+
func benchmarkPositionSubtract(b *testing.B) {
84+
pos := fyne.NewPos(10, 10)
85+
for n := 0; n < b.N; n++ {
86+
pos = pos.Subtract(fyne.NewPos(float32(n), float32(n)))
87+
}
88+
benchmarkResult = pos
89+
}
90+
91+
func benchmarkPositionSubtractXY(b *testing.B) {
92+
pos := fyne.NewPos(10, 10)
93+
for n := 0; n < b.N; n++ {
94+
pos = pos.SubtractXY(float32(n), float32(n))
95+
}
96+
benchmarkResult = pos
97+
}
98+
99+
func benchmarkSizeAdd(b *testing.B) {
100+
size := fyne.NewSize(10, 10)
101+
for n := 0; n < b.N; n++ {
102+
size = size.Add(fyne.NewPos(float32(n), float32(n)))
103+
}
104+
benchmarkResult = size
105+
}
106+
107+
func benchmarkSizeAddWidthHeight(b *testing.B) {
108+
size := fyne.NewSize(10, 10)
109+
for n := 0; n < b.N; n++ {
110+
size = size.AddWidthHeight(float32(n), float32(n))
111+
}
112+
benchmarkResult = size
113+
}
114+
115+
func benchmarkSizeSubtract(b *testing.B) {
116+
size := fyne.NewSize(10, 10)
117+
for n := 0; n < b.N; n++ {
118+
size = size.Subtract(fyne.NewSize(float32(n), float32(n)))
119+
}
120+
benchmarkResult = size
121+
}
122+
123+
func benchmarkSizeSubtractWidthHeight(b *testing.B) {
124+
size := fyne.NewSize(10, 10)
125+
for n := 0; n < b.N; n++ {
126+
size = size.SubtractWidthHeight(float32(n), float32(n))
127+
}
128+
benchmarkResult = size
129+
}

geometry_test.go

Lines changed: 71 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
package fyne
1+
package fyne_test
22

33
import (
44
"testing"
55

6+
"fyne.io/fyne/v2"
67
"github.com/stretchr/testify/assert"
78
)
89

910
func TestPosition_Add(t *testing.T) {
10-
pos1 := NewPos(10, 10)
11-
pos2 := NewPos(25, 25)
11+
pos1 := fyne.NewPos(10, 10)
12+
pos2 := fyne.NewPos(25, 25)
1213

1314
pos3 := pos1.Add(pos2)
1415

@@ -17,8 +18,8 @@ func TestPosition_Add(t *testing.T) {
1718
}
1819

1920
func TestPosition_Add_Size(t *testing.T) {
20-
pos1 := NewPos(10, 10)
21-
s := NewSize(25, 25)
21+
pos1 := fyne.NewPos(10, 10)
22+
s := fyne.NewSize(25, 25)
2223

2324
pos2 := pos1.Add(s)
2425

@@ -27,25 +28,34 @@ func TestPosition_Add_Size(t *testing.T) {
2728
}
2829

2930
func TestPosition_Add_Vector(t *testing.T) {
30-
pos1 := NewPos(10, 10)
31-
v := NewDelta(25, 25)
31+
pos1 := fyne.NewPos(10, 10)
32+
v := fyne.NewDelta(25, 25)
3233

3334
pos2 := pos1.Add(v)
3435

3536
assert.Equal(t, float32(35), pos2.X)
3637
assert.Equal(t, float32(35), pos2.Y)
3738
}
3839

40+
func TestPosition_AddXY(t *testing.T) {
41+
pos1 := fyne.NewPos(10, 10)
42+
43+
pos2 := pos1.AddXY(25, 25)
44+
45+
assert.Equal(t, float32(35), pos2.X)
46+
assert.Equal(t, float32(35), pos2.Y)
47+
}
48+
3949
func TestPosition_IsZero(t *testing.T) {
4050
for name, tt := range map[string]struct {
41-
p Position
51+
p fyne.Position
4252
want bool
4353
}{
44-
"zero value": {Position{}, true},
45-
"0,0": {NewPos(0, 0), true},
46-
"zero X": {NewPos(0, 42), false},
47-
"zero Y": {NewPos(17, 0), false},
48-
"non-zero X and Y": {NewPos(6, 9), false},
54+
"zero value": {fyne.Position{}, true},
55+
"0,0": {fyne.NewPos(0, 0), true},
56+
"zero X": {fyne.NewPos(0, 42), false},
57+
"zero Y": {fyne.NewPos(17, 0), false},
58+
"non-zero X and Y": {fyne.NewPos(6, 9), false},
4959
} {
5060
t.Run(name, func(t *testing.T) {
5161
assert.Equal(t, tt.want, tt.p.IsZero())
@@ -54,18 +64,27 @@ func TestPosition_IsZero(t *testing.T) {
5464
}
5565

5666
func TestPosition_Subtract(t *testing.T) {
57-
pos1 := NewPos(25, 25)
58-
pos2 := NewPos(10, 10)
67+
pos1 := fyne.NewPos(25, 25)
68+
pos2 := fyne.NewPos(10, 10)
5969

6070
pos3 := pos1.Subtract(pos2)
6171

6272
assert.Equal(t, float32(15), pos3.X)
6373
assert.Equal(t, float32(15), pos3.Y)
6474
}
6575

76+
func TestPosition_SubtractXY(t *testing.T) {
77+
pos1 := fyne.NewPos(25, 25)
78+
79+
pos2 := pos1.SubtractXY(10, 10)
80+
81+
assert.Equal(t, float32(15), pos2.X)
82+
assert.Equal(t, float32(15), pos2.Y)
83+
}
84+
6685
func TestSize_Add(t *testing.T) {
67-
size1 := NewSize(10, 10)
68-
size2 := NewSize(25, 25)
86+
size1 := fyne.NewSize(10, 10)
87+
size2 := fyne.NewSize(25, 25)
6988

7089
size3 := size1.Add(size2)
7190

@@ -74,8 +93,8 @@ func TestSize_Add(t *testing.T) {
7493
}
7594

7695
func TestSize_Add_Position(t *testing.T) {
77-
size1 := NewSize(10, 10)
78-
p := NewSize(25, 25)
96+
size1 := fyne.NewSize(10, 10)
97+
p := fyne.NewSize(25, 25)
7998

8099
size2 := size1.Add(p)
81100

@@ -84,25 +103,34 @@ func TestSize_Add_Position(t *testing.T) {
84103
}
85104

86105
func TestSize_Add_Vector(t *testing.T) {
87-
size1 := NewSize(10, 10)
88-
v := NewDelta(25, 25)
106+
size1 := fyne.NewSize(10, 10)
107+
v := fyne.NewDelta(25, 25)
89108

90109
size2 := size1.Add(v)
91110

92111
assert.Equal(t, float32(35), size2.Width)
93112
assert.Equal(t, float32(35), size2.Height)
94113
}
95114

115+
func TestSize_AddWidthHeight(t *testing.T) {
116+
size1 := fyne.NewSize(10, 10)
117+
118+
size2 := size1.AddWidthHeight(25, 25)
119+
120+
assert.Equal(t, float32(35), size2.Width)
121+
assert.Equal(t, float32(35), size2.Height)
122+
}
123+
96124
func TestSize_IsZero(t *testing.T) {
97125
for name, tt := range map[string]struct {
98-
s Size
126+
s fyne.Size
99127
want bool
100128
}{
101-
"zero value": {Size{}, true},
102-
"0x0": {NewSize(0, 0), true},
103-
"zero width": {NewSize(0, 42), false},
104-
"zero height": {NewSize(17, 0), false},
105-
"non-zero area": {NewSize(6, 9), false},
129+
"zero value": {fyne.Size{}, true},
130+
"0x0": {fyne.NewSize(0, 0), true},
131+
"zero width": {fyne.NewSize(0, 42), false},
132+
"zero height": {fyne.NewSize(17, 0), false},
133+
"non-zero area": {fyne.NewSize(6, 9), false},
106134
} {
107135
t.Run(name, func(t *testing.T) {
108136
assert.Equal(t, tt.want, tt.s.IsZero())
@@ -111,8 +139,8 @@ func TestSize_IsZero(t *testing.T) {
111139
}
112140

113141
func TestSize_Max(t *testing.T) {
114-
size1 := NewSize(10, 100)
115-
size2 := NewSize(100, 10)
142+
size1 := fyne.NewSize(10, 100)
143+
size2 := fyne.NewSize(100, 10)
116144

117145
size3 := size1.Max(size2)
118146

@@ -121,8 +149,8 @@ func TestSize_Max(t *testing.T) {
121149
}
122150

123151
func TestSize_Min(t *testing.T) {
124-
size1 := NewSize(10, 100)
125-
size2 := NewSize(100, 10)
152+
size1 := fyne.NewSize(10, 100)
153+
size2 := fyne.NewSize(100, 10)
126154

127155
size3 := size1.Min(size2)
128156

@@ -131,17 +159,26 @@ func TestSize_Min(t *testing.T) {
131159
}
132160

133161
func TestSize_Subtract(t *testing.T) {
134-
size1 := NewSize(25, 25)
135-
size2 := NewSize(10, 10)
162+
size1 := fyne.NewSize(25, 25)
163+
size2 := fyne.NewSize(10, 10)
136164

137165
size3 := size1.Subtract(size2)
138166

139167
assert.Equal(t, float32(15), size3.Width)
140168
assert.Equal(t, float32(15), size3.Height)
141169
}
142170

171+
func TestSize_SubtractWidthHeight(t *testing.T) {
172+
size1 := fyne.NewSize(25, 25)
173+
174+
size2 := size1.SubtractWidthHeight(10, 10)
175+
176+
assert.Equal(t, float32(15), size2.Width)
177+
assert.Equal(t, float32(15), size2.Height)
178+
}
179+
143180
func TestVector_IsZero(t *testing.T) {
144-
v := NewDelta(0, 0)
181+
v := fyne.NewDelta(0, 0)
145182

146183
assert.True(t, v.IsZero())
147184

0 commit comments

Comments
 (0)