bindtrees.go 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816
  1. // auto-generated
  2. // **** THIS FILE IS AUTO-GENERATED, PLEASE DO NOT EDIT IT **** //
  3. package binding
  4. import (
  5. "bytes"
  6. "fyne.io/fyne/v2"
  7. )
  8. // BoolTree supports binding a tree of bool values.
  9. //
  10. // Since: 2.4
  11. type BoolTree interface {
  12. DataTree
  13. Append(parent, id string, value bool) error
  14. Get() (map[string][]string, map[string]bool, error)
  15. GetValue(id string) (bool, error)
  16. Prepend(parent, id string, value bool) error
  17. Set(ids map[string][]string, values map[string]bool) error
  18. SetValue(id string, value bool) error
  19. }
  20. // ExternalBoolTree supports binding a tree of bool values from an external variable.
  21. //
  22. // Since: 2.4
  23. type ExternalBoolTree interface {
  24. BoolTree
  25. Reload() error
  26. }
  27. // NewBoolTree returns a bindable tree of bool values.
  28. //
  29. // Since: 2.4
  30. func NewBoolTree() BoolTree {
  31. t := &boundBoolTree{val: &map[string]bool{}}
  32. t.ids = make(map[string][]string)
  33. t.items = make(map[string]DataItem)
  34. return t
  35. }
  36. // BindBoolTree returns a bound tree of bool values, based on the contents of the passed values.
  37. // The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map.
  38. // If your code changes the content of the maps this refers to you should call Reload() to inform the bindings.
  39. //
  40. // Since: 2.4
  41. func BindBoolTree(ids *map[string][]string, v *map[string]bool) ExternalBoolTree {
  42. if v == nil {
  43. return NewBoolTree().(ExternalBoolTree)
  44. }
  45. t := &boundBoolTree{val: v, updateExternal: true}
  46. t.ids = make(map[string][]string)
  47. t.items = make(map[string]DataItem)
  48. for parent, children := range *ids {
  49. for _, leaf := range children {
  50. t.appendItem(bindBoolTreeItem(v, leaf, t.updateExternal), leaf, parent)
  51. }
  52. }
  53. return t
  54. }
  55. type boundBoolTree struct {
  56. treeBase
  57. updateExternal bool
  58. val *map[string]bool
  59. }
  60. func (t *boundBoolTree) Append(parent, id string, val bool) error {
  61. t.lock.Lock()
  62. defer t.lock.Unlock()
  63. ids, ok := t.ids[parent]
  64. if !ok {
  65. ids = make([]string, 0)
  66. }
  67. t.ids[parent] = append(ids, id)
  68. v := *t.val
  69. v[id] = val
  70. return t.doReload()
  71. }
  72. func (t *boundBoolTree) Get() (map[string][]string, map[string]bool, error) {
  73. t.lock.RLock()
  74. defer t.lock.RUnlock()
  75. return t.ids, *t.val, nil
  76. }
  77. func (t *boundBoolTree) GetValue(id string) (bool, error) {
  78. t.lock.RLock()
  79. defer t.lock.RUnlock()
  80. if item, ok := (*t.val)[id]; ok {
  81. return item, nil
  82. }
  83. return false, errOutOfBounds
  84. }
  85. func (t *boundBoolTree) Prepend(parent, id string, val bool) error {
  86. t.lock.Lock()
  87. defer t.lock.Unlock()
  88. ids, ok := t.ids[parent]
  89. if !ok {
  90. ids = make([]string, 0)
  91. }
  92. t.ids[parent] = append([]string{id}, ids...)
  93. v := *t.val
  94. v[id] = val
  95. return t.doReload()
  96. }
  97. func (t *boundBoolTree) Reload() error {
  98. t.lock.Lock()
  99. defer t.lock.Unlock()
  100. return t.doReload()
  101. }
  102. func (t *boundBoolTree) Set(ids map[string][]string, v map[string]bool) error {
  103. t.lock.Lock()
  104. defer t.lock.Unlock()
  105. t.ids = ids
  106. *t.val = v
  107. return t.doReload()
  108. }
  109. func (t *boundBoolTree) doReload() (retErr error) {
  110. updated := []string{}
  111. fire := false
  112. for id := range *t.val {
  113. found := false
  114. for child := range t.items {
  115. if child == id { // update existing
  116. updated = append(updated, id)
  117. found = true
  118. break
  119. }
  120. }
  121. if found {
  122. continue
  123. }
  124. // append new
  125. t.appendItem(bindBoolTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids))
  126. updated = append(updated, id)
  127. fire = true
  128. }
  129. for id := range t.items {
  130. remove := true
  131. for _, done := range updated {
  132. if done == id {
  133. remove = false
  134. break
  135. }
  136. }
  137. if remove { // remove item no longer present
  138. fire = true
  139. t.deleteItem(id, parentIDFor(id, t.ids))
  140. }
  141. }
  142. if fire {
  143. t.trigger()
  144. }
  145. for id, item := range t.items {
  146. var err error
  147. if t.updateExternal {
  148. item.(*boundExternalBoolTreeItem).lock.Lock()
  149. err = item.(*boundExternalBoolTreeItem).setIfChanged((*t.val)[id])
  150. item.(*boundExternalBoolTreeItem).lock.Unlock()
  151. } else {
  152. item.(*boundBoolTreeItem).lock.Lock()
  153. err = item.(*boundBoolTreeItem).doSet((*t.val)[id])
  154. item.(*boundBoolTreeItem).lock.Unlock()
  155. }
  156. if err != nil {
  157. retErr = err
  158. }
  159. }
  160. return
  161. }
  162. func (t *boundBoolTree) SetValue(id string, v bool) error {
  163. t.lock.Lock()
  164. (*t.val)[id] = v
  165. t.lock.Unlock()
  166. item, err := t.GetItem(id)
  167. if err != nil {
  168. return err
  169. }
  170. return item.(Bool).Set(v)
  171. }
  172. func bindBoolTreeItem(v *map[string]bool, id string, external bool) Bool {
  173. if external {
  174. ret := &boundExternalBoolTreeItem{old: (*v)[id]}
  175. ret.val = v
  176. ret.id = id
  177. return ret
  178. }
  179. return &boundBoolTreeItem{id: id, val: v}
  180. }
  181. type boundBoolTreeItem struct {
  182. base
  183. val *map[string]bool
  184. id string
  185. }
  186. func (t *boundBoolTreeItem) Get() (bool, error) {
  187. t.lock.Lock()
  188. defer t.lock.Unlock()
  189. v := *t.val
  190. if item, ok := v[t.id]; ok {
  191. return item, nil
  192. }
  193. return false, errOutOfBounds
  194. }
  195. func (t *boundBoolTreeItem) Set(val bool) error {
  196. t.lock.Lock()
  197. defer t.lock.Unlock()
  198. return t.doSet(val)
  199. }
  200. func (t *boundBoolTreeItem) doSet(val bool) error {
  201. (*t.val)[t.id] = val
  202. t.trigger()
  203. return nil
  204. }
  205. type boundExternalBoolTreeItem struct {
  206. boundBoolTreeItem
  207. old bool
  208. }
  209. func (t *boundExternalBoolTreeItem) setIfChanged(val bool) error {
  210. if val == t.old {
  211. return nil
  212. }
  213. (*t.val)[t.id] = val
  214. t.old = val
  215. t.trigger()
  216. return nil
  217. }
  218. // BytesTree supports binding a tree of []byte values.
  219. //
  220. // Since: 2.4
  221. type BytesTree interface {
  222. DataTree
  223. Append(parent, id string, value []byte) error
  224. Get() (map[string][]string, map[string][]byte, error)
  225. GetValue(id string) ([]byte, error)
  226. Prepend(parent, id string, value []byte) error
  227. Set(ids map[string][]string, values map[string][]byte) error
  228. SetValue(id string, value []byte) error
  229. }
  230. // ExternalBytesTree supports binding a tree of []byte values from an external variable.
  231. //
  232. // Since: 2.4
  233. type ExternalBytesTree interface {
  234. BytesTree
  235. Reload() error
  236. }
  237. // NewBytesTree returns a bindable tree of []byte values.
  238. //
  239. // Since: 2.4
  240. func NewBytesTree() BytesTree {
  241. t := &boundBytesTree{val: &map[string][]byte{}}
  242. t.ids = make(map[string][]string)
  243. t.items = make(map[string]DataItem)
  244. return t
  245. }
  246. // BindBytesTree returns a bound tree of []byte values, based on the contents of the passed values.
  247. // The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map.
  248. // If your code changes the content of the maps this refers to you should call Reload() to inform the bindings.
  249. //
  250. // Since: 2.4
  251. func BindBytesTree(ids *map[string][]string, v *map[string][]byte) ExternalBytesTree {
  252. if v == nil {
  253. return NewBytesTree().(ExternalBytesTree)
  254. }
  255. t := &boundBytesTree{val: v, updateExternal: true}
  256. t.ids = make(map[string][]string)
  257. t.items = make(map[string]DataItem)
  258. for parent, children := range *ids {
  259. for _, leaf := range children {
  260. t.appendItem(bindBytesTreeItem(v, leaf, t.updateExternal), leaf, parent)
  261. }
  262. }
  263. return t
  264. }
  265. type boundBytesTree struct {
  266. treeBase
  267. updateExternal bool
  268. val *map[string][]byte
  269. }
  270. func (t *boundBytesTree) Append(parent, id string, val []byte) error {
  271. t.lock.Lock()
  272. defer t.lock.Unlock()
  273. ids, ok := t.ids[parent]
  274. if !ok {
  275. ids = make([]string, 0)
  276. }
  277. t.ids[parent] = append(ids, id)
  278. v := *t.val
  279. v[id] = val
  280. return t.doReload()
  281. }
  282. func (t *boundBytesTree) Get() (map[string][]string, map[string][]byte, error) {
  283. t.lock.RLock()
  284. defer t.lock.RUnlock()
  285. return t.ids, *t.val, nil
  286. }
  287. func (t *boundBytesTree) GetValue(id string) ([]byte, error) {
  288. t.lock.RLock()
  289. defer t.lock.RUnlock()
  290. if item, ok := (*t.val)[id]; ok {
  291. return item, nil
  292. }
  293. return nil, errOutOfBounds
  294. }
  295. func (t *boundBytesTree) Prepend(parent, id string, val []byte) error {
  296. t.lock.Lock()
  297. defer t.lock.Unlock()
  298. ids, ok := t.ids[parent]
  299. if !ok {
  300. ids = make([]string, 0)
  301. }
  302. t.ids[parent] = append([]string{id}, ids...)
  303. v := *t.val
  304. v[id] = val
  305. return t.doReload()
  306. }
  307. func (t *boundBytesTree) Reload() error {
  308. t.lock.Lock()
  309. defer t.lock.Unlock()
  310. return t.doReload()
  311. }
  312. func (t *boundBytesTree) Set(ids map[string][]string, v map[string][]byte) error {
  313. t.lock.Lock()
  314. defer t.lock.Unlock()
  315. t.ids = ids
  316. *t.val = v
  317. return t.doReload()
  318. }
  319. func (t *boundBytesTree) doReload() (retErr error) {
  320. updated := []string{}
  321. fire := false
  322. for id := range *t.val {
  323. found := false
  324. for child := range t.items {
  325. if child == id { // update existing
  326. updated = append(updated, id)
  327. found = true
  328. break
  329. }
  330. }
  331. if found {
  332. continue
  333. }
  334. // append new
  335. t.appendItem(bindBytesTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids))
  336. updated = append(updated, id)
  337. fire = true
  338. }
  339. for id := range t.items {
  340. remove := true
  341. for _, done := range updated {
  342. if done == id {
  343. remove = false
  344. break
  345. }
  346. }
  347. if remove { // remove item no longer present
  348. fire = true
  349. t.deleteItem(id, parentIDFor(id, t.ids))
  350. }
  351. }
  352. if fire {
  353. t.trigger()
  354. }
  355. for id, item := range t.items {
  356. var err error
  357. if t.updateExternal {
  358. item.(*boundExternalBytesTreeItem).lock.Lock()
  359. err = item.(*boundExternalBytesTreeItem).setIfChanged((*t.val)[id])
  360. item.(*boundExternalBytesTreeItem).lock.Unlock()
  361. } else {
  362. item.(*boundBytesTreeItem).lock.Lock()
  363. err = item.(*boundBytesTreeItem).doSet((*t.val)[id])
  364. item.(*boundBytesTreeItem).lock.Unlock()
  365. }
  366. if err != nil {
  367. retErr = err
  368. }
  369. }
  370. return
  371. }
  372. func (t *boundBytesTree) SetValue(id string, v []byte) error {
  373. t.lock.Lock()
  374. (*t.val)[id] = v
  375. t.lock.Unlock()
  376. item, err := t.GetItem(id)
  377. if err != nil {
  378. return err
  379. }
  380. return item.(Bytes).Set(v)
  381. }
  382. func bindBytesTreeItem(v *map[string][]byte, id string, external bool) Bytes {
  383. if external {
  384. ret := &boundExternalBytesTreeItem{old: (*v)[id]}
  385. ret.val = v
  386. ret.id = id
  387. return ret
  388. }
  389. return &boundBytesTreeItem{id: id, val: v}
  390. }
  391. type boundBytesTreeItem struct {
  392. base
  393. val *map[string][]byte
  394. id string
  395. }
  396. func (t *boundBytesTreeItem) Get() ([]byte, error) {
  397. t.lock.Lock()
  398. defer t.lock.Unlock()
  399. v := *t.val
  400. if item, ok := v[t.id]; ok {
  401. return item, nil
  402. }
  403. return nil, errOutOfBounds
  404. }
  405. func (t *boundBytesTreeItem) Set(val []byte) error {
  406. t.lock.Lock()
  407. defer t.lock.Unlock()
  408. return t.doSet(val)
  409. }
  410. func (t *boundBytesTreeItem) doSet(val []byte) error {
  411. (*t.val)[t.id] = val
  412. t.trigger()
  413. return nil
  414. }
  415. type boundExternalBytesTreeItem struct {
  416. boundBytesTreeItem
  417. old []byte
  418. }
  419. func (t *boundExternalBytesTreeItem) setIfChanged(val []byte) error {
  420. if bytes.Equal(val, t.old) {
  421. return nil
  422. }
  423. (*t.val)[t.id] = val
  424. t.old = val
  425. t.trigger()
  426. return nil
  427. }
  428. // FloatTree supports binding a tree of float64 values.
  429. //
  430. // Since: 2.4
  431. type FloatTree interface {
  432. DataTree
  433. Append(parent, id string, value float64) error
  434. Get() (map[string][]string, map[string]float64, error)
  435. GetValue(id string) (float64, error)
  436. Prepend(parent, id string, value float64) error
  437. Set(ids map[string][]string, values map[string]float64) error
  438. SetValue(id string, value float64) error
  439. }
  440. // ExternalFloatTree supports binding a tree of float64 values from an external variable.
  441. //
  442. // Since: 2.4
  443. type ExternalFloatTree interface {
  444. FloatTree
  445. Reload() error
  446. }
  447. // NewFloatTree returns a bindable tree of float64 values.
  448. //
  449. // Since: 2.4
  450. func NewFloatTree() FloatTree {
  451. t := &boundFloatTree{val: &map[string]float64{}}
  452. t.ids = make(map[string][]string)
  453. t.items = make(map[string]DataItem)
  454. return t
  455. }
  456. // BindFloatTree returns a bound tree of float64 values, based on the contents of the passed values.
  457. // The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map.
  458. // If your code changes the content of the maps this refers to you should call Reload() to inform the bindings.
  459. //
  460. // Since: 2.4
  461. func BindFloatTree(ids *map[string][]string, v *map[string]float64) ExternalFloatTree {
  462. if v == nil {
  463. return NewFloatTree().(ExternalFloatTree)
  464. }
  465. t := &boundFloatTree{val: v, updateExternal: true}
  466. t.ids = make(map[string][]string)
  467. t.items = make(map[string]DataItem)
  468. for parent, children := range *ids {
  469. for _, leaf := range children {
  470. t.appendItem(bindFloatTreeItem(v, leaf, t.updateExternal), leaf, parent)
  471. }
  472. }
  473. return t
  474. }
  475. type boundFloatTree struct {
  476. treeBase
  477. updateExternal bool
  478. val *map[string]float64
  479. }
  480. func (t *boundFloatTree) Append(parent, id string, val float64) error {
  481. t.lock.Lock()
  482. defer t.lock.Unlock()
  483. ids, ok := t.ids[parent]
  484. if !ok {
  485. ids = make([]string, 0)
  486. }
  487. t.ids[parent] = append(ids, id)
  488. v := *t.val
  489. v[id] = val
  490. return t.doReload()
  491. }
  492. func (t *boundFloatTree) Get() (map[string][]string, map[string]float64, error) {
  493. t.lock.RLock()
  494. defer t.lock.RUnlock()
  495. return t.ids, *t.val, nil
  496. }
  497. func (t *boundFloatTree) GetValue(id string) (float64, error) {
  498. t.lock.RLock()
  499. defer t.lock.RUnlock()
  500. if item, ok := (*t.val)[id]; ok {
  501. return item, nil
  502. }
  503. return 0.0, errOutOfBounds
  504. }
  505. func (t *boundFloatTree) Prepend(parent, id string, val float64) error {
  506. t.lock.Lock()
  507. defer t.lock.Unlock()
  508. ids, ok := t.ids[parent]
  509. if !ok {
  510. ids = make([]string, 0)
  511. }
  512. t.ids[parent] = append([]string{id}, ids...)
  513. v := *t.val
  514. v[id] = val
  515. return t.doReload()
  516. }
  517. func (t *boundFloatTree) Reload() error {
  518. t.lock.Lock()
  519. defer t.lock.Unlock()
  520. return t.doReload()
  521. }
  522. func (t *boundFloatTree) Set(ids map[string][]string, v map[string]float64) error {
  523. t.lock.Lock()
  524. defer t.lock.Unlock()
  525. t.ids = ids
  526. *t.val = v
  527. return t.doReload()
  528. }
  529. func (t *boundFloatTree) doReload() (retErr error) {
  530. updated := []string{}
  531. fire := false
  532. for id := range *t.val {
  533. found := false
  534. for child := range t.items {
  535. if child == id { // update existing
  536. updated = append(updated, id)
  537. found = true
  538. break
  539. }
  540. }
  541. if found {
  542. continue
  543. }
  544. // append new
  545. t.appendItem(bindFloatTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids))
  546. updated = append(updated, id)
  547. fire = true
  548. }
  549. for id := range t.items {
  550. remove := true
  551. for _, done := range updated {
  552. if done == id {
  553. remove = false
  554. break
  555. }
  556. }
  557. if remove { // remove item no longer present
  558. fire = true
  559. t.deleteItem(id, parentIDFor(id, t.ids))
  560. }
  561. }
  562. if fire {
  563. t.trigger()
  564. }
  565. for id, item := range t.items {
  566. var err error
  567. if t.updateExternal {
  568. item.(*boundExternalFloatTreeItem).lock.Lock()
  569. err = item.(*boundExternalFloatTreeItem).setIfChanged((*t.val)[id])
  570. item.(*boundExternalFloatTreeItem).lock.Unlock()
  571. } else {
  572. item.(*boundFloatTreeItem).lock.Lock()
  573. err = item.(*boundFloatTreeItem).doSet((*t.val)[id])
  574. item.(*boundFloatTreeItem).lock.Unlock()
  575. }
  576. if err != nil {
  577. retErr = err
  578. }
  579. }
  580. return
  581. }
  582. func (t *boundFloatTree) SetValue(id string, v float64) error {
  583. t.lock.Lock()
  584. (*t.val)[id] = v
  585. t.lock.Unlock()
  586. item, err := t.GetItem(id)
  587. if err != nil {
  588. return err
  589. }
  590. return item.(Float).Set(v)
  591. }
  592. func bindFloatTreeItem(v *map[string]float64, id string, external bool) Float {
  593. if external {
  594. ret := &boundExternalFloatTreeItem{old: (*v)[id]}
  595. ret.val = v
  596. ret.id = id
  597. return ret
  598. }
  599. return &boundFloatTreeItem{id: id, val: v}
  600. }
  601. type boundFloatTreeItem struct {
  602. base
  603. val *map[string]float64
  604. id string
  605. }
  606. func (t *boundFloatTreeItem) Get() (float64, error) {
  607. t.lock.Lock()
  608. defer t.lock.Unlock()
  609. v := *t.val
  610. if item, ok := v[t.id]; ok {
  611. return item, nil
  612. }
  613. return 0.0, errOutOfBounds
  614. }
  615. func (t *boundFloatTreeItem) Set(val float64) error {
  616. t.lock.Lock()
  617. defer t.lock.Unlock()
  618. return t.doSet(val)
  619. }
  620. func (t *boundFloatTreeItem) doSet(val float64) error {
  621. (*t.val)[t.id] = val
  622. t.trigger()
  623. return nil
  624. }
  625. type boundExternalFloatTreeItem struct {
  626. boundFloatTreeItem
  627. old float64
  628. }
  629. func (t *boundExternalFloatTreeItem) setIfChanged(val float64) error {
  630. if val == t.old {
  631. return nil
  632. }
  633. (*t.val)[t.id] = val
  634. t.old = val
  635. t.trigger()
  636. return nil
  637. }
  638. // IntTree supports binding a tree of int values.
  639. //
  640. // Since: 2.4
  641. type IntTree interface {
  642. DataTree
  643. Append(parent, id string, value int) error
  644. Get() (map[string][]string, map[string]int, error)
  645. GetValue(id string) (int, error)
  646. Prepend(parent, id string, value int) error
  647. Set(ids map[string][]string, values map[string]int) error
  648. SetValue(id string, value int) error
  649. }
  650. // ExternalIntTree supports binding a tree of int values from an external variable.
  651. //
  652. // Since: 2.4
  653. type ExternalIntTree interface {
  654. IntTree
  655. Reload() error
  656. }
  657. // NewIntTree returns a bindable tree of int values.
  658. //
  659. // Since: 2.4
  660. func NewIntTree() IntTree {
  661. t := &boundIntTree{val: &map[string]int{}}
  662. t.ids = make(map[string][]string)
  663. t.items = make(map[string]DataItem)
  664. return t
  665. }
  666. // BindIntTree returns a bound tree of int values, based on the contents of the passed values.
  667. // The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map.
  668. // If your code changes the content of the maps this refers to you should call Reload() to inform the bindings.
  669. //
  670. // Since: 2.4
  671. func BindIntTree(ids *map[string][]string, v *map[string]int) ExternalIntTree {
  672. if v == nil {
  673. return NewIntTree().(ExternalIntTree)
  674. }
  675. t := &boundIntTree{val: v, updateExternal: true}
  676. t.ids = make(map[string][]string)
  677. t.items = make(map[string]DataItem)
  678. for parent, children := range *ids {
  679. for _, leaf := range children {
  680. t.appendItem(bindIntTreeItem(v, leaf, t.updateExternal), leaf, parent)
  681. }
  682. }
  683. return t
  684. }
  685. type boundIntTree struct {
  686. treeBase
  687. updateExternal bool
  688. val *map[string]int
  689. }
  690. func (t *boundIntTree) Append(parent, id string, val int) error {
  691. t.lock.Lock()
  692. defer t.lock.Unlock()
  693. ids, ok := t.ids[parent]
  694. if !ok {
  695. ids = make([]string, 0)
  696. }
  697. t.ids[parent] = append(ids, id)
  698. v := *t.val
  699. v[id] = val
  700. return t.doReload()
  701. }
  702. func (t *boundIntTree) Get() (map[string][]string, map[string]int, error) {
  703. t.lock.RLock()
  704. defer t.lock.RUnlock()
  705. return t.ids, *t.val, nil
  706. }
  707. func (t *boundIntTree) GetValue(id string) (int, error) {
  708. t.lock.RLock()
  709. defer t.lock.RUnlock()
  710. if item, ok := (*t.val)[id]; ok {
  711. return item, nil
  712. }
  713. return 0, errOutOfBounds
  714. }
  715. func (t *boundIntTree) Prepend(parent, id string, val int) error {
  716. t.lock.Lock()
  717. defer t.lock.Unlock()
  718. ids, ok := t.ids[parent]
  719. if !ok {
  720. ids = make([]string, 0)
  721. }
  722. t.ids[parent] = append([]string{id}, ids...)
  723. v := *t.val
  724. v[id] = val
  725. return t.doReload()
  726. }
  727. func (t *boundIntTree) Reload() error {
  728. t.lock.Lock()
  729. defer t.lock.Unlock()
  730. return t.doReload()
  731. }
  732. func (t *boundIntTree) Set(ids map[string][]string, v map[string]int) error {
  733. t.lock.Lock()
  734. defer t.lock.Unlock()
  735. t.ids = ids
  736. *t.val = v
  737. return t.doReload()
  738. }
  739. func (t *boundIntTree) doReload() (retErr error) {
  740. updated := []string{}
  741. fire := false
  742. for id := range *t.val {
  743. found := false
  744. for child := range t.items {
  745. if child == id { // update existing
  746. updated = append(updated, id)
  747. found = true
  748. break
  749. }
  750. }
  751. if found {
  752. continue
  753. }
  754. // append new
  755. t.appendItem(bindIntTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids))
  756. updated = append(updated, id)
  757. fire = true
  758. }
  759. for id := range t.items {
  760. remove := true
  761. for _, done := range updated {
  762. if done == id {
  763. remove = false
  764. break
  765. }
  766. }
  767. if remove { // remove item no longer present
  768. fire = true
  769. t.deleteItem(id, parentIDFor(id, t.ids))
  770. }
  771. }
  772. if fire {
  773. t.trigger()
  774. }
  775. for id, item := range t.items {
  776. var err error
  777. if t.updateExternal {
  778. item.(*boundExternalIntTreeItem).lock.Lock()
  779. err = item.(*boundExternalIntTreeItem).setIfChanged((*t.val)[id])
  780. item.(*boundExternalIntTreeItem).lock.Unlock()
  781. } else {
  782. item.(*boundIntTreeItem).lock.Lock()
  783. err = item.(*boundIntTreeItem).doSet((*t.val)[id])
  784. item.(*boundIntTreeItem).lock.Unlock()
  785. }
  786. if err != nil {
  787. retErr = err
  788. }
  789. }
  790. return
  791. }
  792. func (t *boundIntTree) SetValue(id string, v int) error {
  793. t.lock.Lock()
  794. (*t.val)[id] = v
  795. t.lock.Unlock()
  796. item, err := t.GetItem(id)
  797. if err != nil {
  798. return err
  799. }
  800. return item.(Int).Set(v)
  801. }
  802. func bindIntTreeItem(v *map[string]int, id string, external bool) Int {
  803. if external {
  804. ret := &boundExternalIntTreeItem{old: (*v)[id]}
  805. ret.val = v
  806. ret.id = id
  807. return ret
  808. }
  809. return &boundIntTreeItem{id: id, val: v}
  810. }
  811. type boundIntTreeItem struct {
  812. base
  813. val *map[string]int
  814. id string
  815. }
  816. func (t *boundIntTreeItem) Get() (int, error) {
  817. t.lock.Lock()
  818. defer t.lock.Unlock()
  819. v := *t.val
  820. if item, ok := v[t.id]; ok {
  821. return item, nil
  822. }
  823. return 0, errOutOfBounds
  824. }
  825. func (t *boundIntTreeItem) Set(val int) error {
  826. t.lock.Lock()
  827. defer t.lock.Unlock()
  828. return t.doSet(val)
  829. }
  830. func (t *boundIntTreeItem) doSet(val int) error {
  831. (*t.val)[t.id] = val
  832. t.trigger()
  833. return nil
  834. }
  835. type boundExternalIntTreeItem struct {
  836. boundIntTreeItem
  837. old int
  838. }
  839. func (t *boundExternalIntTreeItem) setIfChanged(val int) error {
  840. if val == t.old {
  841. return nil
  842. }
  843. (*t.val)[t.id] = val
  844. t.old = val
  845. t.trigger()
  846. return nil
  847. }
  848. // RuneTree supports binding a tree of rune values.
  849. //
  850. // Since: 2.4
  851. type RuneTree interface {
  852. DataTree
  853. Append(parent, id string, value rune) error
  854. Get() (map[string][]string, map[string]rune, error)
  855. GetValue(id string) (rune, error)
  856. Prepend(parent, id string, value rune) error
  857. Set(ids map[string][]string, values map[string]rune) error
  858. SetValue(id string, value rune) error
  859. }
  860. // ExternalRuneTree supports binding a tree of rune values from an external variable.
  861. //
  862. // Since: 2.4
  863. type ExternalRuneTree interface {
  864. RuneTree
  865. Reload() error
  866. }
  867. // NewRuneTree returns a bindable tree of rune values.
  868. //
  869. // Since: 2.4
  870. func NewRuneTree() RuneTree {
  871. t := &boundRuneTree{val: &map[string]rune{}}
  872. t.ids = make(map[string][]string)
  873. t.items = make(map[string]DataItem)
  874. return t
  875. }
  876. // BindRuneTree returns a bound tree of rune values, based on the contents of the passed values.
  877. // The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map.
  878. // If your code changes the content of the maps this refers to you should call Reload() to inform the bindings.
  879. //
  880. // Since: 2.4
  881. func BindRuneTree(ids *map[string][]string, v *map[string]rune) ExternalRuneTree {
  882. if v == nil {
  883. return NewRuneTree().(ExternalRuneTree)
  884. }
  885. t := &boundRuneTree{val: v, updateExternal: true}
  886. t.ids = make(map[string][]string)
  887. t.items = make(map[string]DataItem)
  888. for parent, children := range *ids {
  889. for _, leaf := range children {
  890. t.appendItem(bindRuneTreeItem(v, leaf, t.updateExternal), leaf, parent)
  891. }
  892. }
  893. return t
  894. }
  895. type boundRuneTree struct {
  896. treeBase
  897. updateExternal bool
  898. val *map[string]rune
  899. }
  900. func (t *boundRuneTree) Append(parent, id string, val rune) error {
  901. t.lock.Lock()
  902. defer t.lock.Unlock()
  903. ids, ok := t.ids[parent]
  904. if !ok {
  905. ids = make([]string, 0)
  906. }
  907. t.ids[parent] = append(ids, id)
  908. v := *t.val
  909. v[id] = val
  910. return t.doReload()
  911. }
  912. func (t *boundRuneTree) Get() (map[string][]string, map[string]rune, error) {
  913. t.lock.RLock()
  914. defer t.lock.RUnlock()
  915. return t.ids, *t.val, nil
  916. }
  917. func (t *boundRuneTree) GetValue(id string) (rune, error) {
  918. t.lock.RLock()
  919. defer t.lock.RUnlock()
  920. if item, ok := (*t.val)[id]; ok {
  921. return item, nil
  922. }
  923. return rune(0), errOutOfBounds
  924. }
  925. func (t *boundRuneTree) Prepend(parent, id string, val rune) error {
  926. t.lock.Lock()
  927. defer t.lock.Unlock()
  928. ids, ok := t.ids[parent]
  929. if !ok {
  930. ids = make([]string, 0)
  931. }
  932. t.ids[parent] = append([]string{id}, ids...)
  933. v := *t.val
  934. v[id] = val
  935. return t.doReload()
  936. }
  937. func (t *boundRuneTree) Reload() error {
  938. t.lock.Lock()
  939. defer t.lock.Unlock()
  940. return t.doReload()
  941. }
  942. func (t *boundRuneTree) Set(ids map[string][]string, v map[string]rune) error {
  943. t.lock.Lock()
  944. defer t.lock.Unlock()
  945. t.ids = ids
  946. *t.val = v
  947. return t.doReload()
  948. }
  949. func (t *boundRuneTree) doReload() (retErr error) {
  950. updated := []string{}
  951. fire := false
  952. for id := range *t.val {
  953. found := false
  954. for child := range t.items {
  955. if child == id { // update existing
  956. updated = append(updated, id)
  957. found = true
  958. break
  959. }
  960. }
  961. if found {
  962. continue
  963. }
  964. // append new
  965. t.appendItem(bindRuneTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids))
  966. updated = append(updated, id)
  967. fire = true
  968. }
  969. for id := range t.items {
  970. remove := true
  971. for _, done := range updated {
  972. if done == id {
  973. remove = false
  974. break
  975. }
  976. }
  977. if remove { // remove item no longer present
  978. fire = true
  979. t.deleteItem(id, parentIDFor(id, t.ids))
  980. }
  981. }
  982. if fire {
  983. t.trigger()
  984. }
  985. for id, item := range t.items {
  986. var err error
  987. if t.updateExternal {
  988. item.(*boundExternalRuneTreeItem).lock.Lock()
  989. err = item.(*boundExternalRuneTreeItem).setIfChanged((*t.val)[id])
  990. item.(*boundExternalRuneTreeItem).lock.Unlock()
  991. } else {
  992. item.(*boundRuneTreeItem).lock.Lock()
  993. err = item.(*boundRuneTreeItem).doSet((*t.val)[id])
  994. item.(*boundRuneTreeItem).lock.Unlock()
  995. }
  996. if err != nil {
  997. retErr = err
  998. }
  999. }
  1000. return
  1001. }
  1002. func (t *boundRuneTree) SetValue(id string, v rune) error {
  1003. t.lock.Lock()
  1004. (*t.val)[id] = v
  1005. t.lock.Unlock()
  1006. item, err := t.GetItem(id)
  1007. if err != nil {
  1008. return err
  1009. }
  1010. return item.(Rune).Set(v)
  1011. }
  1012. func bindRuneTreeItem(v *map[string]rune, id string, external bool) Rune {
  1013. if external {
  1014. ret := &boundExternalRuneTreeItem{old: (*v)[id]}
  1015. ret.val = v
  1016. ret.id = id
  1017. return ret
  1018. }
  1019. return &boundRuneTreeItem{id: id, val: v}
  1020. }
  1021. type boundRuneTreeItem struct {
  1022. base
  1023. val *map[string]rune
  1024. id string
  1025. }
  1026. func (t *boundRuneTreeItem) Get() (rune, error) {
  1027. t.lock.Lock()
  1028. defer t.lock.Unlock()
  1029. v := *t.val
  1030. if item, ok := v[t.id]; ok {
  1031. return item, nil
  1032. }
  1033. return rune(0), errOutOfBounds
  1034. }
  1035. func (t *boundRuneTreeItem) Set(val rune) error {
  1036. t.lock.Lock()
  1037. defer t.lock.Unlock()
  1038. return t.doSet(val)
  1039. }
  1040. func (t *boundRuneTreeItem) doSet(val rune) error {
  1041. (*t.val)[t.id] = val
  1042. t.trigger()
  1043. return nil
  1044. }
  1045. type boundExternalRuneTreeItem struct {
  1046. boundRuneTreeItem
  1047. old rune
  1048. }
  1049. func (t *boundExternalRuneTreeItem) setIfChanged(val rune) error {
  1050. if val == t.old {
  1051. return nil
  1052. }
  1053. (*t.val)[t.id] = val
  1054. t.old = val
  1055. t.trigger()
  1056. return nil
  1057. }
  1058. // StringTree supports binding a tree of string values.
  1059. //
  1060. // Since: 2.4
  1061. type StringTree interface {
  1062. DataTree
  1063. Append(parent, id string, value string) error
  1064. Get() (map[string][]string, map[string]string, error)
  1065. GetValue(id string) (string, error)
  1066. Prepend(parent, id string, value string) error
  1067. Set(ids map[string][]string, values map[string]string) error
  1068. SetValue(id string, value string) error
  1069. }
  1070. // ExternalStringTree supports binding a tree of string values from an external variable.
  1071. //
  1072. // Since: 2.4
  1073. type ExternalStringTree interface {
  1074. StringTree
  1075. Reload() error
  1076. }
  1077. // NewStringTree returns a bindable tree of string values.
  1078. //
  1079. // Since: 2.4
  1080. func NewStringTree() StringTree {
  1081. t := &boundStringTree{val: &map[string]string{}}
  1082. t.ids = make(map[string][]string)
  1083. t.items = make(map[string]DataItem)
  1084. return t
  1085. }
  1086. // BindStringTree returns a bound tree of string values, based on the contents of the passed values.
  1087. // The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map.
  1088. // If your code changes the content of the maps this refers to you should call Reload() to inform the bindings.
  1089. //
  1090. // Since: 2.4
  1091. func BindStringTree(ids *map[string][]string, v *map[string]string) ExternalStringTree {
  1092. if v == nil {
  1093. return NewStringTree().(ExternalStringTree)
  1094. }
  1095. t := &boundStringTree{val: v, updateExternal: true}
  1096. t.ids = make(map[string][]string)
  1097. t.items = make(map[string]DataItem)
  1098. for parent, children := range *ids {
  1099. for _, leaf := range children {
  1100. t.appendItem(bindStringTreeItem(v, leaf, t.updateExternal), leaf, parent)
  1101. }
  1102. }
  1103. return t
  1104. }
  1105. type boundStringTree struct {
  1106. treeBase
  1107. updateExternal bool
  1108. val *map[string]string
  1109. }
  1110. func (t *boundStringTree) Append(parent, id string, val string) error {
  1111. t.lock.Lock()
  1112. defer t.lock.Unlock()
  1113. ids, ok := t.ids[parent]
  1114. if !ok {
  1115. ids = make([]string, 0)
  1116. }
  1117. t.ids[parent] = append(ids, id)
  1118. v := *t.val
  1119. v[id] = val
  1120. return t.doReload()
  1121. }
  1122. func (t *boundStringTree) Get() (map[string][]string, map[string]string, error) {
  1123. t.lock.RLock()
  1124. defer t.lock.RUnlock()
  1125. return t.ids, *t.val, nil
  1126. }
  1127. func (t *boundStringTree) GetValue(id string) (string, error) {
  1128. t.lock.RLock()
  1129. defer t.lock.RUnlock()
  1130. if item, ok := (*t.val)[id]; ok {
  1131. return item, nil
  1132. }
  1133. return "", errOutOfBounds
  1134. }
  1135. func (t *boundStringTree) Prepend(parent, id string, val string) error {
  1136. t.lock.Lock()
  1137. defer t.lock.Unlock()
  1138. ids, ok := t.ids[parent]
  1139. if !ok {
  1140. ids = make([]string, 0)
  1141. }
  1142. t.ids[parent] = append([]string{id}, ids...)
  1143. v := *t.val
  1144. v[id] = val
  1145. return t.doReload()
  1146. }
  1147. func (t *boundStringTree) Reload() error {
  1148. t.lock.Lock()
  1149. defer t.lock.Unlock()
  1150. return t.doReload()
  1151. }
  1152. func (t *boundStringTree) Set(ids map[string][]string, v map[string]string) error {
  1153. t.lock.Lock()
  1154. defer t.lock.Unlock()
  1155. t.ids = ids
  1156. *t.val = v
  1157. return t.doReload()
  1158. }
  1159. func (t *boundStringTree) doReload() (retErr error) {
  1160. updated := []string{}
  1161. fire := false
  1162. for id := range *t.val {
  1163. found := false
  1164. for child := range t.items {
  1165. if child == id { // update existing
  1166. updated = append(updated, id)
  1167. found = true
  1168. break
  1169. }
  1170. }
  1171. if found {
  1172. continue
  1173. }
  1174. // append new
  1175. t.appendItem(bindStringTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids))
  1176. updated = append(updated, id)
  1177. fire = true
  1178. }
  1179. for id := range t.items {
  1180. remove := true
  1181. for _, done := range updated {
  1182. if done == id {
  1183. remove = false
  1184. break
  1185. }
  1186. }
  1187. if remove { // remove item no longer present
  1188. fire = true
  1189. t.deleteItem(id, parentIDFor(id, t.ids))
  1190. }
  1191. }
  1192. if fire {
  1193. t.trigger()
  1194. }
  1195. for id, item := range t.items {
  1196. var err error
  1197. if t.updateExternal {
  1198. item.(*boundExternalStringTreeItem).lock.Lock()
  1199. err = item.(*boundExternalStringTreeItem).setIfChanged((*t.val)[id])
  1200. item.(*boundExternalStringTreeItem).lock.Unlock()
  1201. } else {
  1202. item.(*boundStringTreeItem).lock.Lock()
  1203. err = item.(*boundStringTreeItem).doSet((*t.val)[id])
  1204. item.(*boundStringTreeItem).lock.Unlock()
  1205. }
  1206. if err != nil {
  1207. retErr = err
  1208. }
  1209. }
  1210. return
  1211. }
  1212. func (t *boundStringTree) SetValue(id string, v string) error {
  1213. t.lock.Lock()
  1214. (*t.val)[id] = v
  1215. t.lock.Unlock()
  1216. item, err := t.GetItem(id)
  1217. if err != nil {
  1218. return err
  1219. }
  1220. return item.(String).Set(v)
  1221. }
  1222. func bindStringTreeItem(v *map[string]string, id string, external bool) String {
  1223. if external {
  1224. ret := &boundExternalStringTreeItem{old: (*v)[id]}
  1225. ret.val = v
  1226. ret.id = id
  1227. return ret
  1228. }
  1229. return &boundStringTreeItem{id: id, val: v}
  1230. }
  1231. type boundStringTreeItem struct {
  1232. base
  1233. val *map[string]string
  1234. id string
  1235. }
  1236. func (t *boundStringTreeItem) Get() (string, error) {
  1237. t.lock.Lock()
  1238. defer t.lock.Unlock()
  1239. v := *t.val
  1240. if item, ok := v[t.id]; ok {
  1241. return item, nil
  1242. }
  1243. return "", errOutOfBounds
  1244. }
  1245. func (t *boundStringTreeItem) Set(val string) error {
  1246. t.lock.Lock()
  1247. defer t.lock.Unlock()
  1248. return t.doSet(val)
  1249. }
  1250. func (t *boundStringTreeItem) doSet(val string) error {
  1251. (*t.val)[t.id] = val
  1252. t.trigger()
  1253. return nil
  1254. }
  1255. type boundExternalStringTreeItem struct {
  1256. boundStringTreeItem
  1257. old string
  1258. }
  1259. func (t *boundExternalStringTreeItem) setIfChanged(val string) error {
  1260. if val == t.old {
  1261. return nil
  1262. }
  1263. (*t.val)[t.id] = val
  1264. t.old = val
  1265. t.trigger()
  1266. return nil
  1267. }
  1268. // URITree supports binding a tree of fyne.URI values.
  1269. //
  1270. // Since: 2.4
  1271. type URITree interface {
  1272. DataTree
  1273. Append(parent, id string, value fyne.URI) error
  1274. Get() (map[string][]string, map[string]fyne.URI, error)
  1275. GetValue(id string) (fyne.URI, error)
  1276. Prepend(parent, id string, value fyne.URI) error
  1277. Set(ids map[string][]string, values map[string]fyne.URI) error
  1278. SetValue(id string, value fyne.URI) error
  1279. }
  1280. // ExternalURITree supports binding a tree of fyne.URI values from an external variable.
  1281. //
  1282. // Since: 2.4
  1283. type ExternalURITree interface {
  1284. URITree
  1285. Reload() error
  1286. }
  1287. // NewURITree returns a bindable tree of fyne.URI values.
  1288. //
  1289. // Since: 2.4
  1290. func NewURITree() URITree {
  1291. t := &boundURITree{val: &map[string]fyne.URI{}}
  1292. t.ids = make(map[string][]string)
  1293. t.items = make(map[string]DataItem)
  1294. return t
  1295. }
  1296. // BindURITree returns a bound tree of fyne.URI values, based on the contents of the passed values.
  1297. // The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map.
  1298. // If your code changes the content of the maps this refers to you should call Reload() to inform the bindings.
  1299. //
  1300. // Since: 2.4
  1301. func BindURITree(ids *map[string][]string, v *map[string]fyne.URI) ExternalURITree {
  1302. if v == nil {
  1303. return NewURITree().(ExternalURITree)
  1304. }
  1305. t := &boundURITree{val: v, updateExternal: true}
  1306. t.ids = make(map[string][]string)
  1307. t.items = make(map[string]DataItem)
  1308. for parent, children := range *ids {
  1309. for _, leaf := range children {
  1310. t.appendItem(bindURITreeItem(v, leaf, t.updateExternal), leaf, parent)
  1311. }
  1312. }
  1313. return t
  1314. }
  1315. type boundURITree struct {
  1316. treeBase
  1317. updateExternal bool
  1318. val *map[string]fyne.URI
  1319. }
  1320. func (t *boundURITree) Append(parent, id string, val fyne.URI) error {
  1321. t.lock.Lock()
  1322. defer t.lock.Unlock()
  1323. ids, ok := t.ids[parent]
  1324. if !ok {
  1325. ids = make([]string, 0)
  1326. }
  1327. t.ids[parent] = append(ids, id)
  1328. v := *t.val
  1329. v[id] = val
  1330. return t.doReload()
  1331. }
  1332. func (t *boundURITree) Get() (map[string][]string, map[string]fyne.URI, error) {
  1333. t.lock.RLock()
  1334. defer t.lock.RUnlock()
  1335. return t.ids, *t.val, nil
  1336. }
  1337. func (t *boundURITree) GetValue(id string) (fyne.URI, error) {
  1338. t.lock.RLock()
  1339. defer t.lock.RUnlock()
  1340. if item, ok := (*t.val)[id]; ok {
  1341. return item, nil
  1342. }
  1343. return fyne.URI(nil), errOutOfBounds
  1344. }
  1345. func (t *boundURITree) Prepend(parent, id string, val fyne.URI) error {
  1346. t.lock.Lock()
  1347. defer t.lock.Unlock()
  1348. ids, ok := t.ids[parent]
  1349. if !ok {
  1350. ids = make([]string, 0)
  1351. }
  1352. t.ids[parent] = append([]string{id}, ids...)
  1353. v := *t.val
  1354. v[id] = val
  1355. return t.doReload()
  1356. }
  1357. func (t *boundURITree) Reload() error {
  1358. t.lock.Lock()
  1359. defer t.lock.Unlock()
  1360. return t.doReload()
  1361. }
  1362. func (t *boundURITree) Set(ids map[string][]string, v map[string]fyne.URI) error {
  1363. t.lock.Lock()
  1364. defer t.lock.Unlock()
  1365. t.ids = ids
  1366. *t.val = v
  1367. return t.doReload()
  1368. }
  1369. func (t *boundURITree) doReload() (retErr error) {
  1370. updated := []string{}
  1371. fire := false
  1372. for id := range *t.val {
  1373. found := false
  1374. for child := range t.items {
  1375. if child == id { // update existing
  1376. updated = append(updated, id)
  1377. found = true
  1378. break
  1379. }
  1380. }
  1381. if found {
  1382. continue
  1383. }
  1384. // append new
  1385. t.appendItem(bindURITreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids))
  1386. updated = append(updated, id)
  1387. fire = true
  1388. }
  1389. for id := range t.items {
  1390. remove := true
  1391. for _, done := range updated {
  1392. if done == id {
  1393. remove = false
  1394. break
  1395. }
  1396. }
  1397. if remove { // remove item no longer present
  1398. fire = true
  1399. t.deleteItem(id, parentIDFor(id, t.ids))
  1400. }
  1401. }
  1402. if fire {
  1403. t.trigger()
  1404. }
  1405. for id, item := range t.items {
  1406. var err error
  1407. if t.updateExternal {
  1408. item.(*boundExternalURITreeItem).lock.Lock()
  1409. err = item.(*boundExternalURITreeItem).setIfChanged((*t.val)[id])
  1410. item.(*boundExternalURITreeItem).lock.Unlock()
  1411. } else {
  1412. item.(*boundURITreeItem).lock.Lock()
  1413. err = item.(*boundURITreeItem).doSet((*t.val)[id])
  1414. item.(*boundURITreeItem).lock.Unlock()
  1415. }
  1416. if err != nil {
  1417. retErr = err
  1418. }
  1419. }
  1420. return
  1421. }
  1422. func (t *boundURITree) SetValue(id string, v fyne.URI) error {
  1423. t.lock.Lock()
  1424. (*t.val)[id] = v
  1425. t.lock.Unlock()
  1426. item, err := t.GetItem(id)
  1427. if err != nil {
  1428. return err
  1429. }
  1430. return item.(URI).Set(v)
  1431. }
  1432. func bindURITreeItem(v *map[string]fyne.URI, id string, external bool) URI {
  1433. if external {
  1434. ret := &boundExternalURITreeItem{old: (*v)[id]}
  1435. ret.val = v
  1436. ret.id = id
  1437. return ret
  1438. }
  1439. return &boundURITreeItem{id: id, val: v}
  1440. }
  1441. type boundURITreeItem struct {
  1442. base
  1443. val *map[string]fyne.URI
  1444. id string
  1445. }
  1446. func (t *boundURITreeItem) Get() (fyne.URI, error) {
  1447. t.lock.Lock()
  1448. defer t.lock.Unlock()
  1449. v := *t.val
  1450. if item, ok := v[t.id]; ok {
  1451. return item, nil
  1452. }
  1453. return fyne.URI(nil), errOutOfBounds
  1454. }
  1455. func (t *boundURITreeItem) Set(val fyne.URI) error {
  1456. t.lock.Lock()
  1457. defer t.lock.Unlock()
  1458. return t.doSet(val)
  1459. }
  1460. func (t *boundURITreeItem) doSet(val fyne.URI) error {
  1461. (*t.val)[t.id] = val
  1462. t.trigger()
  1463. return nil
  1464. }
  1465. type boundExternalURITreeItem struct {
  1466. boundURITreeItem
  1467. old fyne.URI
  1468. }
  1469. func (t *boundExternalURITreeItem) setIfChanged(val fyne.URI) error {
  1470. if compareURI(val, t.old) {
  1471. return nil
  1472. }
  1473. (*t.val)[t.id] = val
  1474. t.old = val
  1475. t.trigger()
  1476. return nil
  1477. }