98 lines
1.9 KiB
Go
98 lines
1.9 KiB
Go
package binding
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/internal/async"
|
|
)
|
|
|
|
type preferenceItem interface {
|
|
checkForChange()
|
|
}
|
|
|
|
type preferenceBindings struct {
|
|
async.Map[string, preferenceItem]
|
|
}
|
|
|
|
func (b *preferenceBindings) list() []preferenceItem {
|
|
ret := []preferenceItem{}
|
|
b.Range(func(_ string, item preferenceItem) bool {
|
|
ret = append(ret, item)
|
|
return true
|
|
})
|
|
return ret
|
|
}
|
|
|
|
type preferencesMap struct {
|
|
prefs async.Map[fyne.Preferences, *preferenceBindings]
|
|
|
|
appPrefs fyne.Preferences // the main application prefs, to check if it changed...
|
|
appLock sync.Mutex
|
|
}
|
|
|
|
func newPreferencesMap() *preferencesMap {
|
|
return &preferencesMap{}
|
|
}
|
|
|
|
func (m *preferencesMap) ensurePreferencesAttached(p fyne.Preferences) *preferenceBindings {
|
|
binds, loaded := m.prefs.LoadOrStore(p, &preferenceBindings{})
|
|
if loaded {
|
|
return binds
|
|
}
|
|
|
|
p.AddChangeListener(func() { m.preferencesChanged(p) })
|
|
return binds
|
|
}
|
|
|
|
func (m *preferencesMap) getBindings(p fyne.Preferences) *preferenceBindings {
|
|
if p == fyne.CurrentApp().Preferences() {
|
|
m.appLock.Lock()
|
|
prefs := m.appPrefs
|
|
if m.appPrefs == nil {
|
|
m.appPrefs = p
|
|
}
|
|
m.appLock.Unlock()
|
|
if prefs != p {
|
|
m.migratePreferences(prefs, p)
|
|
}
|
|
}
|
|
binds, _ := m.prefs.Load(p)
|
|
return binds
|
|
}
|
|
|
|
func (m *preferencesMap) preferencesChanged(p fyne.Preferences) {
|
|
binds := m.getBindings(p)
|
|
if binds == nil {
|
|
return
|
|
}
|
|
for _, item := range binds.list() {
|
|
item.checkForChange()
|
|
}
|
|
}
|
|
|
|
func (m *preferencesMap) migratePreferences(src, dst fyne.Preferences) {
|
|
old, loaded := m.prefs.Load(src)
|
|
if !loaded {
|
|
return
|
|
}
|
|
|
|
m.prefs.Store(dst, old)
|
|
m.prefs.Delete(src)
|
|
m.appLock.Lock()
|
|
m.appPrefs = dst
|
|
m.appLock.Unlock()
|
|
|
|
binds := m.getBindings(dst)
|
|
if binds == nil {
|
|
return
|
|
}
|
|
for _, b := range binds.list() {
|
|
if backed, ok := b.(interface{ replaceProvider(fyne.Preferences) }); ok {
|
|
backed.replaceProvider(dst)
|
|
}
|
|
}
|
|
|
|
m.preferencesChanged(dst)
|
|
}
|