• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

fyne-io / fyne / 13239177181

10 Feb 2025 10:52AM UTC coverage: 62.526% (-0.03%) from 62.558%
13239177181

push

github

web-flow
Merge pull request #5507 from Jacalz/binding-cleanup-leftovers

Clean up leftovers from making bindings generic

59 of 60 new or added lines in 3 files covered. (98.33%)

4 existing lines in 1 file now uncovered.

24868 of 39772 relevant lines covered (62.53%)

827.6 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.39
/data/binding/preference.go
1
package binding
2

3
import (
4
        "sync/atomic"
5

6
        "fyne.io/fyne/v2"
7
)
8

9
// Work around Go not supporting generic methods on non-generic types:
10
type preferenceLookupSetter[T any] func(fyne.Preferences) (func(string) T, func(string, T))
11

12
const keyTypeMismatchError = "A previous preference binding exists with different type for key: "
13

14
// BindPreferenceBool returns a bindable bool value that is managed by the application preferences.
15
// Changes to this value will be saved to application storage and when the app starts the previous values will be read.
16
//
17
// Since: 2.0
18
func BindPreferenceBool(key string, p fyne.Preferences) Bool {
1✔
19
        return bindPreferenceItem(key, p,
1✔
20
                func(p fyne.Preferences) (func(string) bool, func(string, bool)) {
6✔
21
                        return p.Bool, p.SetBool
5✔
22
                })
5✔
23
}
24

25
// BindPreferenceFloat returns a bindable float64 value that is managed by the application preferences.
26
// Changes to this value will be saved to application storage and when the app starts the previous values will be read.
27
//
28
// Since: 2.0
29
func BindPreferenceFloat(key string, p fyne.Preferences) Float {
1✔
30
        return bindPreferenceItem(key, p,
1✔
31
                func(p fyne.Preferences) (func(string) float64, func(string, float64)) {
5✔
32
                        return p.Float, p.SetFloat
4✔
33
                })
4✔
34
}
35

36
// BindPreferenceInt returns a bindable int value that is managed by the application preferences.
37
// Changes to this value will be saved to application storage and when the app starts the previous values will be read.
38
//
39
// Since: 2.0
40
func BindPreferenceInt(key string, p fyne.Preferences) Int {
101✔
41
        return bindPreferenceItem(key, p,
101✔
42
                func(p fyne.Preferences) (func(string) int, func(string, int)) {
110✔
43
                        return p.Int, p.SetInt
9✔
44
                })
9✔
45
}
46

47
// BindPreferenceString returns a bindable string value that is managed by the application preferences.
48
// Changes to this value will be saved to application storage and when the app starts the previous values will be read.
49
//
50
// Since: 2.0
51
func BindPreferenceString(key string, p fyne.Preferences) String {
5✔
52
        return bindPreferenceItem(key, p,
5✔
53
                func(p fyne.Preferences) (func(string) string, func(string, string)) {
8✔
54
                        return p.String, p.SetString
3✔
55
                })
3✔
56
}
57

58
func bindPreferenceItem[T bool | float64 | int | string](key string, p fyne.Preferences, setLookup preferenceLookupSetter[T]) bindableItem[T] {
108✔
59
        if found, ok := lookupExistingBinding[T](key, p); ok {
210✔
60
                return found
102✔
61
        }
102✔
62

63
        listen := &prefBoundBase[T]{key: key, setLookup: setLookup}
6✔
64
        listen.replaceProvider(p)
6✔
65
        binds := prefBinds.ensurePreferencesAttached(p)
6✔
66
        binds.Store(key, listen)
6✔
67
        return listen
6✔
68
}
69

70
func lookupExistingBinding[T any](key string, p fyne.Preferences) (bindableItem[T], bool) {
108✔
71
        binds := prefBinds.getBindings(p)
108✔
72
        if binds == nil {
110✔
73
                return nil, false
2✔
74
        }
2✔
75

76
        if listen, ok := binds.Load(key); listen != nil && ok {
208✔
77
                if l, ok := listen.(bindableItem[T]); ok {
204✔
78
                        return l, ok
102✔
79
                }
102✔
NEW
80
                fyne.LogError(keyTypeMismatchError+key, nil)
×
81
        }
82

83
        return nil, false
4✔
84
}
85

86
type prefBoundBase[T bool | float64 | int | string] struct {
87
        base
88
        key string
89

90
        get       func(string) T
91
        set       func(string, T)
92
        setLookup preferenceLookupSetter[T]
93
        cache     atomic.Pointer[T]
94
}
95

96
func (b *prefBoundBase[T]) Get() (T, error) {
12✔
97
        cache := b.get(b.key)
12✔
98
        b.cache.Store(&cache)
12✔
99
        return cache, nil
12✔
100
}
12✔
101

102
func (b *prefBoundBase[T]) Set(v T) error {
6✔
103
        b.set(b.key, v)
6✔
104

6✔
105
        b.lock.RLock()
6✔
106
        defer b.lock.RUnlock()
6✔
107
        b.trigger()
6✔
108
        return nil
6✔
109
}
6✔
110

111
func (b *prefBoundBase[T]) checkForChange() {
17✔
112
        val := b.cache.Load()
17✔
113
        if val != nil && b.get(b.key) == *val {
21✔
114
                return
4✔
115
        }
4✔
116
        b.trigger()
13✔
117
}
118

119
func (b *prefBoundBase[T]) replaceProvider(p fyne.Preferences) {
21✔
120
        b.get, b.set = b.setLookup(p)
21✔
121
}
21✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc