-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
treebinding.go
86 lines (71 loc) · 1.5 KB
/
treebinding.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package binding
// DataTreeRootID const is the value used as ID for the root of any tree binding.
const DataTreeRootID = ""
// DataTree is the base interface for all bindable data trees.
//
// Since: 2.4
type DataTree interface {
DataItem
GetItem(id string) (DataItem, error)
ChildIDs(string) []string
}
type treeBase struct {
base
ids map[string][]string
items map[string]DataItem
}
// GetItem returns the DataItem at the specified id.
func (t *treeBase) GetItem(id string) (DataItem, error) {
if item, ok := t.items[id]; ok {
return item, nil
}
return nil, errOutOfBounds
}
// ChildIDs returns the ordered IDs of items in this data tree that are children of the specified ID.
func (t *treeBase) ChildIDs(id string) []string {
if ids, ok := t.ids[id]; ok {
return ids
}
return []string{}
}
func (t *treeBase) appendItem(i DataItem, id, parent string) {
t.items[id] = i
ids, ok := t.ids[parent]
if !ok {
ids = make([]string, 0)
}
for _, in := range ids {
if in == id {
return
}
}
t.ids[parent] = append(ids, id)
}
func (t *treeBase) deleteItem(id, parent string) {
delete(t.items, id)
ids, ok := t.ids[parent]
if !ok {
return
}
off := -1
for i, id2 := range ids {
if id2 == id {
off = i
break
}
}
if off == -1 {
return
}
t.ids[parent] = append(ids[:off], ids[off+1:]...)
}
func parentIDFor(id string, ids map[string][]string) string {
for parent, list := range ids {
for _, child := range list {
if child == id {
return parent
}
}
}
return ""
}