// auto-generated // **** THIS FILE IS AUTO-GENERATED, PLEASE DO NOT EDIT IT **** // package binding import ( "bytes" "fyne.io/fyne/v2" ) // BoolTree supports binding a tree of bool values. // // Since: 2.4 type BoolTree interface { DataTree Append(parent, id string, value bool) error Get() (map[string][]string, map[string]bool, error) GetValue(id string) (bool, error) Prepend(parent, id string, value bool) error Set(ids map[string][]string, values map[string]bool) error SetValue(id string, value bool) error } // ExternalBoolTree supports binding a tree of bool values from an external variable. // // Since: 2.4 type ExternalBoolTree interface { BoolTree Reload() error } // NewBoolTree returns a bindable tree of bool values. // // Since: 2.4 func NewBoolTree() BoolTree { t := &boundBoolTree{val: &map[string]bool{}} t.ids = make(map[string][]string) t.items = make(map[string]DataItem) return t } // BindBoolTree returns a bound tree of bool values, based on the contents of the passed values. // The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map. // If your code changes the content of the maps this refers to you should call Reload() to inform the bindings. // // Since: 2.4 func BindBoolTree(ids *map[string][]string, v *map[string]bool) ExternalBoolTree { if v == nil { return NewBoolTree().(ExternalBoolTree) } t := &boundBoolTree{val: v, updateExternal: true} t.ids = make(map[string][]string) t.items = make(map[string]DataItem) for parent, children := range *ids { for _, leaf := range children { t.appendItem(bindBoolTreeItem(v, leaf, t.updateExternal), leaf, parent) } } return t } type boundBoolTree struct { treeBase updateExternal bool val *map[string]bool } func (t *boundBoolTree) Append(parent, id string, val bool) error { t.lock.Lock() defer t.lock.Unlock() ids, ok := t.ids[parent] if !ok { ids = make([]string, 0) } t.ids[parent] = append(ids, id) v := *t.val v[id] = val return t.doReload() } func (t *boundBoolTree) Get() (map[string][]string, map[string]bool, error) { t.lock.RLock() defer t.lock.RUnlock() return t.ids, *t.val, nil } func (t *boundBoolTree) GetValue(id string) (bool, error) { t.lock.RLock() defer t.lock.RUnlock() if item, ok := (*t.val)[id]; ok { return item, nil } return false, errOutOfBounds } func (t *boundBoolTree) Prepend(parent, id string, val bool) error { t.lock.Lock() defer t.lock.Unlock() ids, ok := t.ids[parent] if !ok { ids = make([]string, 0) } t.ids[parent] = append([]string{id}, ids...) v := *t.val v[id] = val return t.doReload() } func (t *boundBoolTree) Reload() error { t.lock.Lock() defer t.lock.Unlock() return t.doReload() } func (t *boundBoolTree) Set(ids map[string][]string, v map[string]bool) error { t.lock.Lock() defer t.lock.Unlock() t.ids = ids *t.val = v return t.doReload() } func (t *boundBoolTree) doReload() (retErr error) { updated := []string{} fire := false for id := range *t.val { found := false for child := range t.items { if child == id { // update existing updated = append(updated, id) found = true break } } if found { continue } // append new t.appendItem(bindBoolTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids)) updated = append(updated, id) fire = true } for id := range t.items { remove := true for _, done := range updated { if done == id { remove = false break } } if remove { // remove item no longer present fire = true t.deleteItem(id, parentIDFor(id, t.ids)) } } if fire { t.trigger() } for id, item := range t.items { var err error if t.updateExternal { item.(*boundExternalBoolTreeItem).lock.Lock() err = item.(*boundExternalBoolTreeItem).setIfChanged((*t.val)[id]) item.(*boundExternalBoolTreeItem).lock.Unlock() } else { item.(*boundBoolTreeItem).lock.Lock() err = item.(*boundBoolTreeItem).doSet((*t.val)[id]) item.(*boundBoolTreeItem).lock.Unlock() } if err != nil { retErr = err } } return } func (t *boundBoolTree) SetValue(id string, v bool) error { t.lock.Lock() (*t.val)[id] = v t.lock.Unlock() item, err := t.GetItem(id) if err != nil { return err } return item.(Bool).Set(v) } func bindBoolTreeItem(v *map[string]bool, id string, external bool) Bool { if external { ret := &boundExternalBoolTreeItem{old: (*v)[id]} ret.val = v ret.id = id return ret } return &boundBoolTreeItem{id: id, val: v} } type boundBoolTreeItem struct { base val *map[string]bool id string } func (t *boundBoolTreeItem) Get() (bool, error) { t.lock.Lock() defer t.lock.Unlock() v := *t.val if item, ok := v[t.id]; ok { return item, nil } return false, errOutOfBounds } func (t *boundBoolTreeItem) Set(val bool) error { t.lock.Lock() defer t.lock.Unlock() return t.doSet(val) } func (t *boundBoolTreeItem) doSet(val bool) error { (*t.val)[t.id] = val t.trigger() return nil } type boundExternalBoolTreeItem struct { boundBoolTreeItem old bool } func (t *boundExternalBoolTreeItem) setIfChanged(val bool) error { if val == t.old { return nil } (*t.val)[t.id] = val t.old = val t.trigger() return nil } // BytesTree supports binding a tree of []byte values. // // Since: 2.4 type BytesTree interface { DataTree Append(parent, id string, value []byte) error Get() (map[string][]string, map[string][]byte, error) GetValue(id string) ([]byte, error) Prepend(parent, id string, value []byte) error Set(ids map[string][]string, values map[string][]byte) error SetValue(id string, value []byte) error } // ExternalBytesTree supports binding a tree of []byte values from an external variable. // // Since: 2.4 type ExternalBytesTree interface { BytesTree Reload() error } // NewBytesTree returns a bindable tree of []byte values. // // Since: 2.4 func NewBytesTree() BytesTree { t := &boundBytesTree{val: &map[string][]byte{}} t.ids = make(map[string][]string) t.items = make(map[string]DataItem) return t } // BindBytesTree returns a bound tree of []byte values, based on the contents of the passed values. // The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map. // If your code changes the content of the maps this refers to you should call Reload() to inform the bindings. // // Since: 2.4 func BindBytesTree(ids *map[string][]string, v *map[string][]byte) ExternalBytesTree { if v == nil { return NewBytesTree().(ExternalBytesTree) } t := &boundBytesTree{val: v, updateExternal: true} t.ids = make(map[string][]string) t.items = make(map[string]DataItem) for parent, children := range *ids { for _, leaf := range children { t.appendItem(bindBytesTreeItem(v, leaf, t.updateExternal), leaf, parent) } } return t } type boundBytesTree struct { treeBase updateExternal bool val *map[string][]byte } func (t *boundBytesTree) Append(parent, id string, val []byte) error { t.lock.Lock() defer t.lock.Unlock() ids, ok := t.ids[parent] if !ok { ids = make([]string, 0) } t.ids[parent] = append(ids, id) v := *t.val v[id] = val return t.doReload() } func (t *boundBytesTree) Get() (map[string][]string, map[string][]byte, error) { t.lock.RLock() defer t.lock.RUnlock() return t.ids, *t.val, nil } func (t *boundBytesTree) GetValue(id string) ([]byte, error) { t.lock.RLock() defer t.lock.RUnlock() if item, ok := (*t.val)[id]; ok { return item, nil } return nil, errOutOfBounds } func (t *boundBytesTree) Prepend(parent, id string, val []byte) error { t.lock.Lock() defer t.lock.Unlock() ids, ok := t.ids[parent] if !ok { ids = make([]string, 0) } t.ids[parent] = append([]string{id}, ids...) v := *t.val v[id] = val return t.doReload() } func (t *boundBytesTree) Reload() error { t.lock.Lock() defer t.lock.Unlock() return t.doReload() } func (t *boundBytesTree) Set(ids map[string][]string, v map[string][]byte) error { t.lock.Lock() defer t.lock.Unlock() t.ids = ids *t.val = v return t.doReload() } func (t *boundBytesTree) doReload() (retErr error) { updated := []string{} fire := false for id := range *t.val { found := false for child := range t.items { if child == id { // update existing updated = append(updated, id) found = true break } } if found { continue } // append new t.appendItem(bindBytesTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids)) updated = append(updated, id) fire = true } for id := range t.items { remove := true for _, done := range updated { if done == id { remove = false break } } if remove { // remove item no longer present fire = true t.deleteItem(id, parentIDFor(id, t.ids)) } } if fire { t.trigger() } for id, item := range t.items { var err error if t.updateExternal { item.(*boundExternalBytesTreeItem).lock.Lock() err = item.(*boundExternalBytesTreeItem).setIfChanged((*t.val)[id]) item.(*boundExternalBytesTreeItem).lock.Unlock() } else { item.(*boundBytesTreeItem).lock.Lock() err = item.(*boundBytesTreeItem).doSet((*t.val)[id]) item.(*boundBytesTreeItem).lock.Unlock() } if err != nil { retErr = err } } return } func (t *boundBytesTree) SetValue(id string, v []byte) error { t.lock.Lock() (*t.val)[id] = v t.lock.Unlock() item, err := t.GetItem(id) if err != nil { return err } return item.(Bytes).Set(v) } func bindBytesTreeItem(v *map[string][]byte, id string, external bool) Bytes { if external { ret := &boundExternalBytesTreeItem{old: (*v)[id]} ret.val = v ret.id = id return ret } return &boundBytesTreeItem{id: id, val: v} } type boundBytesTreeItem struct { base val *map[string][]byte id string } func (t *boundBytesTreeItem) Get() ([]byte, error) { t.lock.Lock() defer t.lock.Unlock() v := *t.val if item, ok := v[t.id]; ok { return item, nil } return nil, errOutOfBounds } func (t *boundBytesTreeItem) Set(val []byte) error { t.lock.Lock() defer t.lock.Unlock() return t.doSet(val) } func (t *boundBytesTreeItem) doSet(val []byte) error { (*t.val)[t.id] = val t.trigger() return nil } type boundExternalBytesTreeItem struct { boundBytesTreeItem old []byte } func (t *boundExternalBytesTreeItem) setIfChanged(val []byte) error { if bytes.Equal(val, t.old) { return nil } (*t.val)[t.id] = val t.old = val t.trigger() return nil } // FloatTree supports binding a tree of float64 values. // // Since: 2.4 type FloatTree interface { DataTree Append(parent, id string, value float64) error Get() (map[string][]string, map[string]float64, error) GetValue(id string) (float64, error) Prepend(parent, id string, value float64) error Set(ids map[string][]string, values map[string]float64) error SetValue(id string, value float64) error } // ExternalFloatTree supports binding a tree of float64 values from an external variable. // // Since: 2.4 type ExternalFloatTree interface { FloatTree Reload() error } // NewFloatTree returns a bindable tree of float64 values. // // Since: 2.4 func NewFloatTree() FloatTree { t := &boundFloatTree{val: &map[string]float64{}} t.ids = make(map[string][]string) t.items = make(map[string]DataItem) return t } // BindFloatTree returns a bound tree of float64 values, based on the contents of the passed values. // The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map. // If your code changes the content of the maps this refers to you should call Reload() to inform the bindings. // // Since: 2.4 func BindFloatTree(ids *map[string][]string, v *map[string]float64) ExternalFloatTree { if v == nil { return NewFloatTree().(ExternalFloatTree) } t := &boundFloatTree{val: v, updateExternal: true} t.ids = make(map[string][]string) t.items = make(map[string]DataItem) for parent, children := range *ids { for _, leaf := range children { t.appendItem(bindFloatTreeItem(v, leaf, t.updateExternal), leaf, parent) } } return t } type boundFloatTree struct { treeBase updateExternal bool val *map[string]float64 } func (t *boundFloatTree) Append(parent, id string, val float64) error { t.lock.Lock() defer t.lock.Unlock() ids, ok := t.ids[parent] if !ok { ids = make([]string, 0) } t.ids[parent] = append(ids, id) v := *t.val v[id] = val return t.doReload() } func (t *boundFloatTree) Get() (map[string][]string, map[string]float64, error) { t.lock.RLock() defer t.lock.RUnlock() return t.ids, *t.val, nil } func (t *boundFloatTree) GetValue(id string) (float64, error) { t.lock.RLock() defer t.lock.RUnlock() if item, ok := (*t.val)[id]; ok { return item, nil } return 0.0, errOutOfBounds } func (t *boundFloatTree) Prepend(parent, id string, val float64) error { t.lock.Lock() defer t.lock.Unlock() ids, ok := t.ids[parent] if !ok { ids = make([]string, 0) } t.ids[parent] = append([]string{id}, ids...) v := *t.val v[id] = val return t.doReload() } func (t *boundFloatTree) Reload() error { t.lock.Lock() defer t.lock.Unlock() return t.doReload() } func (t *boundFloatTree) Set(ids map[string][]string, v map[string]float64) error { t.lock.Lock() defer t.lock.Unlock() t.ids = ids *t.val = v return t.doReload() } func (t *boundFloatTree) doReload() (retErr error) { updated := []string{} fire := false for id := range *t.val { found := false for child := range t.items { if child == id { // update existing updated = append(updated, id) found = true break } } if found { continue } // append new t.appendItem(bindFloatTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids)) updated = append(updated, id) fire = true } for id := range t.items { remove := true for _, done := range updated { if done == id { remove = false break } } if remove { // remove item no longer present fire = true t.deleteItem(id, parentIDFor(id, t.ids)) } } if fire { t.trigger() } for id, item := range t.items { var err error if t.updateExternal { item.(*boundExternalFloatTreeItem).lock.Lock() err = item.(*boundExternalFloatTreeItem).setIfChanged((*t.val)[id]) item.(*boundExternalFloatTreeItem).lock.Unlock() } else { item.(*boundFloatTreeItem).lock.Lock() err = item.(*boundFloatTreeItem).doSet((*t.val)[id]) item.(*boundFloatTreeItem).lock.Unlock() } if err != nil { retErr = err } } return } func (t *boundFloatTree) SetValue(id string, v float64) error { t.lock.Lock() (*t.val)[id] = v t.lock.Unlock() item, err := t.GetItem(id) if err != nil { return err } return item.(Float).Set(v) } func bindFloatTreeItem(v *map[string]float64, id string, external bool) Float { if external { ret := &boundExternalFloatTreeItem{old: (*v)[id]} ret.val = v ret.id = id return ret } return &boundFloatTreeItem{id: id, val: v} } type boundFloatTreeItem struct { base val *map[string]float64 id string } func (t *boundFloatTreeItem) Get() (float64, error) { t.lock.Lock() defer t.lock.Unlock() v := *t.val if item, ok := v[t.id]; ok { return item, nil } return 0.0, errOutOfBounds } func (t *boundFloatTreeItem) Set(val float64) error { t.lock.Lock() defer t.lock.Unlock() return t.doSet(val) } func (t *boundFloatTreeItem) doSet(val float64) error { (*t.val)[t.id] = val t.trigger() return nil } type boundExternalFloatTreeItem struct { boundFloatTreeItem old float64 } func (t *boundExternalFloatTreeItem) setIfChanged(val float64) error { if val == t.old { return nil } (*t.val)[t.id] = val t.old = val t.trigger() return nil } // IntTree supports binding a tree of int values. // // Since: 2.4 type IntTree interface { DataTree Append(parent, id string, value int) error Get() (map[string][]string, map[string]int, error) GetValue(id string) (int, error) Prepend(parent, id string, value int) error Set(ids map[string][]string, values map[string]int) error SetValue(id string, value int) error } // ExternalIntTree supports binding a tree of int values from an external variable. // // Since: 2.4 type ExternalIntTree interface { IntTree Reload() error } // NewIntTree returns a bindable tree of int values. // // Since: 2.4 func NewIntTree() IntTree { t := &boundIntTree{val: &map[string]int{}} t.ids = make(map[string][]string) t.items = make(map[string]DataItem) return t } // BindIntTree returns a bound tree of int values, based on the contents of the passed values. // The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map. // If your code changes the content of the maps this refers to you should call Reload() to inform the bindings. // // Since: 2.4 func BindIntTree(ids *map[string][]string, v *map[string]int) ExternalIntTree { if v == nil { return NewIntTree().(ExternalIntTree) } t := &boundIntTree{val: v, updateExternal: true} t.ids = make(map[string][]string) t.items = make(map[string]DataItem) for parent, children := range *ids { for _, leaf := range children { t.appendItem(bindIntTreeItem(v, leaf, t.updateExternal), leaf, parent) } } return t } type boundIntTree struct { treeBase updateExternal bool val *map[string]int } func (t *boundIntTree) Append(parent, id string, val int) error { t.lock.Lock() defer t.lock.Unlock() ids, ok := t.ids[parent] if !ok { ids = make([]string, 0) } t.ids[parent] = append(ids, id) v := *t.val v[id] = val return t.doReload() } func (t *boundIntTree) Get() (map[string][]string, map[string]int, error) { t.lock.RLock() defer t.lock.RUnlock() return t.ids, *t.val, nil } func (t *boundIntTree) GetValue(id string) (int, error) { t.lock.RLock() defer t.lock.RUnlock() if item, ok := (*t.val)[id]; ok { return item, nil } return 0, errOutOfBounds } func (t *boundIntTree) Prepend(parent, id string, val int) error { t.lock.Lock() defer t.lock.Unlock() ids, ok := t.ids[parent] if !ok { ids = make([]string, 0) } t.ids[parent] = append([]string{id}, ids...) v := *t.val v[id] = val return t.doReload() } func (t *boundIntTree) Reload() error { t.lock.Lock() defer t.lock.Unlock() return t.doReload() } func (t *boundIntTree) Set(ids map[string][]string, v map[string]int) error { t.lock.Lock() defer t.lock.Unlock() t.ids = ids *t.val = v return t.doReload() } func (t *boundIntTree) doReload() (retErr error) { updated := []string{} fire := false for id := range *t.val { found := false for child := range t.items { if child == id { // update existing updated = append(updated, id) found = true break } } if found { continue } // append new t.appendItem(bindIntTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids)) updated = append(updated, id) fire = true } for id := range t.items { remove := true for _, done := range updated { if done == id { remove = false break } } if remove { // remove item no longer present fire = true t.deleteItem(id, parentIDFor(id, t.ids)) } } if fire { t.trigger() } for id, item := range t.items { var err error if t.updateExternal { item.(*boundExternalIntTreeItem).lock.Lock() err = item.(*boundExternalIntTreeItem).setIfChanged((*t.val)[id]) item.(*boundExternalIntTreeItem).lock.Unlock() } else { item.(*boundIntTreeItem).lock.Lock() err = item.(*boundIntTreeItem).doSet((*t.val)[id]) item.(*boundIntTreeItem).lock.Unlock() } if err != nil { retErr = err } } return } func (t *boundIntTree) SetValue(id string, v int) error { t.lock.Lock() (*t.val)[id] = v t.lock.Unlock() item, err := t.GetItem(id) if err != nil { return err } return item.(Int).Set(v) } func bindIntTreeItem(v *map[string]int, id string, external bool) Int { if external { ret := &boundExternalIntTreeItem{old: (*v)[id]} ret.val = v ret.id = id return ret } return &boundIntTreeItem{id: id, val: v} } type boundIntTreeItem struct { base val *map[string]int id string } func (t *boundIntTreeItem) Get() (int, error) { t.lock.Lock() defer t.lock.Unlock() v := *t.val if item, ok := v[t.id]; ok { return item, nil } return 0, errOutOfBounds } func (t *boundIntTreeItem) Set(val int) error { t.lock.Lock() defer t.lock.Unlock() return t.doSet(val) } func (t *boundIntTreeItem) doSet(val int) error { (*t.val)[t.id] = val t.trigger() return nil } type boundExternalIntTreeItem struct { boundIntTreeItem old int } func (t *boundExternalIntTreeItem) setIfChanged(val int) error { if val == t.old { return nil } (*t.val)[t.id] = val t.old = val t.trigger() return nil } // RuneTree supports binding a tree of rune values. // // Since: 2.4 type RuneTree interface { DataTree Append(parent, id string, value rune) error Get() (map[string][]string, map[string]rune, error) GetValue(id string) (rune, error) Prepend(parent, id string, value rune) error Set(ids map[string][]string, values map[string]rune) error SetValue(id string, value rune) error } // ExternalRuneTree supports binding a tree of rune values from an external variable. // // Since: 2.4 type ExternalRuneTree interface { RuneTree Reload() error } // NewRuneTree returns a bindable tree of rune values. // // Since: 2.4 func NewRuneTree() RuneTree { t := &boundRuneTree{val: &map[string]rune{}} t.ids = make(map[string][]string) t.items = make(map[string]DataItem) return t } // BindRuneTree returns a bound tree of rune values, based on the contents of the passed values. // The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map. // If your code changes the content of the maps this refers to you should call Reload() to inform the bindings. // // Since: 2.4 func BindRuneTree(ids *map[string][]string, v *map[string]rune) ExternalRuneTree { if v == nil { return NewRuneTree().(ExternalRuneTree) } t := &boundRuneTree{val: v, updateExternal: true} t.ids = make(map[string][]string) t.items = make(map[string]DataItem) for parent, children := range *ids { for _, leaf := range children { t.appendItem(bindRuneTreeItem(v, leaf, t.updateExternal), leaf, parent) } } return t } type boundRuneTree struct { treeBase updateExternal bool val *map[string]rune } func (t *boundRuneTree) Append(parent, id string, val rune) error { t.lock.Lock() defer t.lock.Unlock() ids, ok := t.ids[parent] if !ok { ids = make([]string, 0) } t.ids[parent] = append(ids, id) v := *t.val v[id] = val return t.doReload() } func (t *boundRuneTree) Get() (map[string][]string, map[string]rune, error) { t.lock.RLock() defer t.lock.RUnlock() return t.ids, *t.val, nil } func (t *boundRuneTree) GetValue(id string) (rune, error) { t.lock.RLock() defer t.lock.RUnlock() if item, ok := (*t.val)[id]; ok { return item, nil } return rune(0), errOutOfBounds } func (t *boundRuneTree) Prepend(parent, id string, val rune) error { t.lock.Lock() defer t.lock.Unlock() ids, ok := t.ids[parent] if !ok { ids = make([]string, 0) } t.ids[parent] = append([]string{id}, ids...) v := *t.val v[id] = val return t.doReload() } func (t *boundRuneTree) Reload() error { t.lock.Lock() defer t.lock.Unlock() return t.doReload() } func (t *boundRuneTree) Set(ids map[string][]string, v map[string]rune) error { t.lock.Lock() defer t.lock.Unlock() t.ids = ids *t.val = v return t.doReload() } func (t *boundRuneTree) doReload() (retErr error) { updated := []string{} fire := false for id := range *t.val { found := false for child := range t.items { if child == id { // update existing updated = append(updated, id) found = true break } } if found { continue } // append new t.appendItem(bindRuneTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids)) updated = append(updated, id) fire = true } for id := range t.items { remove := true for _, done := range updated { if done == id { remove = false break } } if remove { // remove item no longer present fire = true t.deleteItem(id, parentIDFor(id, t.ids)) } } if fire { t.trigger() } for id, item := range t.items { var err error if t.updateExternal { item.(*boundExternalRuneTreeItem).lock.Lock() err = item.(*boundExternalRuneTreeItem).setIfChanged((*t.val)[id]) item.(*boundExternalRuneTreeItem).lock.Unlock() } else { item.(*boundRuneTreeItem).lock.Lock() err = item.(*boundRuneTreeItem).doSet((*t.val)[id]) item.(*boundRuneTreeItem).lock.Unlock() } if err != nil { retErr = err } } return } func (t *boundRuneTree) SetValue(id string, v rune) error { t.lock.Lock() (*t.val)[id] = v t.lock.Unlock() item, err := t.GetItem(id) if err != nil { return err } return item.(Rune).Set(v) } func bindRuneTreeItem(v *map[string]rune, id string, external bool) Rune { if external { ret := &boundExternalRuneTreeItem{old: (*v)[id]} ret.val = v ret.id = id return ret } return &boundRuneTreeItem{id: id, val: v} } type boundRuneTreeItem struct { base val *map[string]rune id string } func (t *boundRuneTreeItem) Get() (rune, error) { t.lock.Lock() defer t.lock.Unlock() v := *t.val if item, ok := v[t.id]; ok { return item, nil } return rune(0), errOutOfBounds } func (t *boundRuneTreeItem) Set(val rune) error { t.lock.Lock() defer t.lock.Unlock() return t.doSet(val) } func (t *boundRuneTreeItem) doSet(val rune) error { (*t.val)[t.id] = val t.trigger() return nil } type boundExternalRuneTreeItem struct { boundRuneTreeItem old rune } func (t *boundExternalRuneTreeItem) setIfChanged(val rune) error { if val == t.old { return nil } (*t.val)[t.id] = val t.old = val t.trigger() return nil } // StringTree supports binding a tree of string values. // // Since: 2.4 type StringTree interface { DataTree Append(parent, id string, value string) error Get() (map[string][]string, map[string]string, error) GetValue(id string) (string, error) Prepend(parent, id string, value string) error Set(ids map[string][]string, values map[string]string) error SetValue(id string, value string) error } // ExternalStringTree supports binding a tree of string values from an external variable. // // Since: 2.4 type ExternalStringTree interface { StringTree Reload() error } // NewStringTree returns a bindable tree of string values. // // Since: 2.4 func NewStringTree() StringTree { t := &boundStringTree{val: &map[string]string{}} t.ids = make(map[string][]string) t.items = make(map[string]DataItem) return t } // BindStringTree returns a bound tree of string values, based on the contents of the passed values. // The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map. // If your code changes the content of the maps this refers to you should call Reload() to inform the bindings. // // Since: 2.4 func BindStringTree(ids *map[string][]string, v *map[string]string) ExternalStringTree { if v == nil { return NewStringTree().(ExternalStringTree) } t := &boundStringTree{val: v, updateExternal: true} t.ids = make(map[string][]string) t.items = make(map[string]DataItem) for parent, children := range *ids { for _, leaf := range children { t.appendItem(bindStringTreeItem(v, leaf, t.updateExternal), leaf, parent) } } return t } type boundStringTree struct { treeBase updateExternal bool val *map[string]string } func (t *boundStringTree) Append(parent, id string, val string) error { t.lock.Lock() defer t.lock.Unlock() ids, ok := t.ids[parent] if !ok { ids = make([]string, 0) } t.ids[parent] = append(ids, id) v := *t.val v[id] = val return t.doReload() } func (t *boundStringTree) Get() (map[string][]string, map[string]string, error) { t.lock.RLock() defer t.lock.RUnlock() return t.ids, *t.val, nil } func (t *boundStringTree) GetValue(id string) (string, error) { t.lock.RLock() defer t.lock.RUnlock() if item, ok := (*t.val)[id]; ok { return item, nil } return "", errOutOfBounds } func (t *boundStringTree) Prepend(parent, id string, val string) error { t.lock.Lock() defer t.lock.Unlock() ids, ok := t.ids[parent] if !ok { ids = make([]string, 0) } t.ids[parent] = append([]string{id}, ids...) v := *t.val v[id] = val return t.doReload() } func (t *boundStringTree) Reload() error { t.lock.Lock() defer t.lock.Unlock() return t.doReload() } func (t *boundStringTree) Set(ids map[string][]string, v map[string]string) error { t.lock.Lock() defer t.lock.Unlock() t.ids = ids *t.val = v return t.doReload() } func (t *boundStringTree) doReload() (retErr error) { updated := []string{} fire := false for id := range *t.val { found := false for child := range t.items { if child == id { // update existing updated = append(updated, id) found = true break } } if found { continue } // append new t.appendItem(bindStringTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids)) updated = append(updated, id) fire = true } for id := range t.items { remove := true for _, done := range updated { if done == id { remove = false break } } if remove { // remove item no longer present fire = true t.deleteItem(id, parentIDFor(id, t.ids)) } } if fire { t.trigger() } for id, item := range t.items { var err error if t.updateExternal { item.(*boundExternalStringTreeItem).lock.Lock() err = item.(*boundExternalStringTreeItem).setIfChanged((*t.val)[id]) item.(*boundExternalStringTreeItem).lock.Unlock() } else { item.(*boundStringTreeItem).lock.Lock() err = item.(*boundStringTreeItem).doSet((*t.val)[id]) item.(*boundStringTreeItem).lock.Unlock() } if err != nil { retErr = err } } return } func (t *boundStringTree) SetValue(id string, v string) error { t.lock.Lock() (*t.val)[id] = v t.lock.Unlock() item, err := t.GetItem(id) if err != nil { return err } return item.(String).Set(v) } func bindStringTreeItem(v *map[string]string, id string, external bool) String { if external { ret := &boundExternalStringTreeItem{old: (*v)[id]} ret.val = v ret.id = id return ret } return &boundStringTreeItem{id: id, val: v} } type boundStringTreeItem struct { base val *map[string]string id string } func (t *boundStringTreeItem) Get() (string, error) { t.lock.Lock() defer t.lock.Unlock() v := *t.val if item, ok := v[t.id]; ok { return item, nil } return "", errOutOfBounds } func (t *boundStringTreeItem) Set(val string) error { t.lock.Lock() defer t.lock.Unlock() return t.doSet(val) } func (t *boundStringTreeItem) doSet(val string) error { (*t.val)[t.id] = val t.trigger() return nil } type boundExternalStringTreeItem struct { boundStringTreeItem old string } func (t *boundExternalStringTreeItem) setIfChanged(val string) error { if val == t.old { return nil } (*t.val)[t.id] = val t.old = val t.trigger() return nil } // URITree supports binding a tree of fyne.URI values. // // Since: 2.4 type URITree interface { DataTree Append(parent, id string, value fyne.URI) error Get() (map[string][]string, map[string]fyne.URI, error) GetValue(id string) (fyne.URI, error) Prepend(parent, id string, value fyne.URI) error Set(ids map[string][]string, values map[string]fyne.URI) error SetValue(id string, value fyne.URI) error } // ExternalURITree supports binding a tree of fyne.URI values from an external variable. // // Since: 2.4 type ExternalURITree interface { URITree Reload() error } // NewURITree returns a bindable tree of fyne.URI values. // // Since: 2.4 func NewURITree() URITree { t := &boundURITree{val: &map[string]fyne.URI{}} t.ids = make(map[string][]string) t.items = make(map[string]DataItem) return t } // BindURITree returns a bound tree of fyne.URI values, based on the contents of the passed values. // The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map. // If your code changes the content of the maps this refers to you should call Reload() to inform the bindings. // // Since: 2.4 func BindURITree(ids *map[string][]string, v *map[string]fyne.URI) ExternalURITree { if v == nil { return NewURITree().(ExternalURITree) } t := &boundURITree{val: v, updateExternal: true} t.ids = make(map[string][]string) t.items = make(map[string]DataItem) for parent, children := range *ids { for _, leaf := range children { t.appendItem(bindURITreeItem(v, leaf, t.updateExternal), leaf, parent) } } return t } type boundURITree struct { treeBase updateExternal bool val *map[string]fyne.URI } func (t *boundURITree) Append(parent, id string, val fyne.URI) error { t.lock.Lock() defer t.lock.Unlock() ids, ok := t.ids[parent] if !ok { ids = make([]string, 0) } t.ids[parent] = append(ids, id) v := *t.val v[id] = val return t.doReload() } func (t *boundURITree) Get() (map[string][]string, map[string]fyne.URI, error) { t.lock.RLock() defer t.lock.RUnlock() return t.ids, *t.val, nil } func (t *boundURITree) GetValue(id string) (fyne.URI, error) { t.lock.RLock() defer t.lock.RUnlock() if item, ok := (*t.val)[id]; ok { return item, nil } return fyne.URI(nil), errOutOfBounds } func (t *boundURITree) Prepend(parent, id string, val fyne.URI) error { t.lock.Lock() defer t.lock.Unlock() ids, ok := t.ids[parent] if !ok { ids = make([]string, 0) } t.ids[parent] = append([]string{id}, ids...) v := *t.val v[id] = val return t.doReload() } func (t *boundURITree) Reload() error { t.lock.Lock() defer t.lock.Unlock() return t.doReload() } func (t *boundURITree) Set(ids map[string][]string, v map[string]fyne.URI) error { t.lock.Lock() defer t.lock.Unlock() t.ids = ids *t.val = v return t.doReload() } func (t *boundURITree) doReload() (retErr error) { updated := []string{} fire := false for id := range *t.val { found := false for child := range t.items { if child == id { // update existing updated = append(updated, id) found = true break } } if found { continue } // append new t.appendItem(bindURITreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids)) updated = append(updated, id) fire = true } for id := range t.items { remove := true for _, done := range updated { if done == id { remove = false break } } if remove { // remove item no longer present fire = true t.deleteItem(id, parentIDFor(id, t.ids)) } } if fire { t.trigger() } for id, item := range t.items { var err error if t.updateExternal { item.(*boundExternalURITreeItem).lock.Lock() err = item.(*boundExternalURITreeItem).setIfChanged((*t.val)[id]) item.(*boundExternalURITreeItem).lock.Unlock() } else { item.(*boundURITreeItem).lock.Lock() err = item.(*boundURITreeItem).doSet((*t.val)[id]) item.(*boundURITreeItem).lock.Unlock() } if err != nil { retErr = err } } return } func (t *boundURITree) SetValue(id string, v fyne.URI) error { t.lock.Lock() (*t.val)[id] = v t.lock.Unlock() item, err := t.GetItem(id) if err != nil { return err } return item.(URI).Set(v) } func bindURITreeItem(v *map[string]fyne.URI, id string, external bool) URI { if external { ret := &boundExternalURITreeItem{old: (*v)[id]} ret.val = v ret.id = id return ret } return &boundURITreeItem{id: id, val: v} } type boundURITreeItem struct { base val *map[string]fyne.URI id string } func (t *boundURITreeItem) Get() (fyne.URI, error) { t.lock.Lock() defer t.lock.Unlock() v := *t.val if item, ok := v[t.id]; ok { return item, nil } return fyne.URI(nil), errOutOfBounds } func (t *boundURITreeItem) Set(val fyne.URI) error { t.lock.Lock() defer t.lock.Unlock() return t.doSet(val) } func (t *boundURITreeItem) doSet(val fyne.URI) error { (*t.val)[t.id] = val t.trigger() return nil } type boundExternalURITreeItem struct { boundURITreeItem old fyne.URI } func (t *boundExternalURITreeItem) setIfChanged(val fyne.URI) error { if compareURI(val, t.old) { return nil } (*t.val)[t.id] = val t.old = val t.trigger() return nil }