pref_helper.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package binding
  2. import (
  3. "sync"
  4. "fyne.io/fyne/v2"
  5. )
  6. type preferenceItem interface {
  7. checkForChange()
  8. }
  9. type preferenceBindings struct {
  10. items sync.Map // map[string]preferenceItem
  11. }
  12. func (b *preferenceBindings) getItem(key string) preferenceItem {
  13. val, loaded := b.items.Load(key)
  14. if !loaded {
  15. return nil
  16. }
  17. return val.(preferenceItem)
  18. }
  19. func (b *preferenceBindings) list() []preferenceItem {
  20. ret := []preferenceItem{}
  21. b.items.Range(func(_, val interface{}) bool {
  22. ret = append(ret, val.(preferenceItem))
  23. return true
  24. })
  25. return ret
  26. }
  27. func (b *preferenceBindings) setItem(key string, item preferenceItem) {
  28. b.items.Store(key, item)
  29. }
  30. type preferencesMap struct {
  31. prefs sync.Map // map[fyne.Preferences]*preferenceBindings
  32. appPrefs fyne.Preferences // the main application prefs, to check if it changed...
  33. }
  34. func newPreferencesMap() *preferencesMap {
  35. return &preferencesMap{}
  36. }
  37. func (m *preferencesMap) ensurePreferencesAttached(p fyne.Preferences) *preferenceBindings {
  38. binds, loaded := m.prefs.LoadOrStore(p, &preferenceBindings{})
  39. if loaded {
  40. return binds.(*preferenceBindings)
  41. }
  42. p.AddChangeListener(func() { m.preferencesChanged(fyne.CurrentApp().Preferences()) })
  43. return binds.(*preferenceBindings)
  44. }
  45. func (m *preferencesMap) getBindings(p fyne.Preferences) *preferenceBindings {
  46. if p == fyne.CurrentApp().Preferences() {
  47. if m.appPrefs == nil {
  48. m.appPrefs = p
  49. } else if m.appPrefs != p {
  50. m.migratePreferences(m.appPrefs, p)
  51. }
  52. }
  53. binds, loaded := m.prefs.Load(p)
  54. if !loaded {
  55. return nil
  56. }
  57. return binds.(*preferenceBindings)
  58. }
  59. func (m *preferencesMap) preferencesChanged(p fyne.Preferences) {
  60. binds := m.getBindings(p)
  61. if binds == nil {
  62. return
  63. }
  64. for _, item := range binds.list() {
  65. item.checkForChange()
  66. }
  67. }
  68. func (m *preferencesMap) migratePreferences(src, dst fyne.Preferences) {
  69. old, loaded := m.prefs.Load(src)
  70. if !loaded {
  71. return
  72. }
  73. m.prefs.Store(dst, old)
  74. m.prefs.Delete(src)
  75. m.appPrefs = dst
  76. binds := m.getBindings(dst)
  77. if binds == nil {
  78. return
  79. }
  80. for _, b := range binds.list() {
  81. if backed, ok := b.(interface{ replaceProvider(fyne.Preferences) }); ok {
  82. backed.replaceProvider(dst)
  83. }
  84. }
  85. m.preferencesChanged(dst)
  86. }