• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

fyne-io / fyne / 13061183842

30 Jan 2025 09:03PM UTC coverage: 60.871% (+1.8%) from 59.117%
13061183842

Pull #5431

github

dweymouth
update mobile driver too
Pull Request #5431: Add new callback-based settings listener API

22 of 52 new or added lines in 6 files covered. (42.31%)

524 existing lines in 25 files now uncovered.

25009 of 41085 relevant lines covered (60.87%)

817.44 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

9.52
/data/binding/bindlists.go
1
// auto-generated
2
// **** THIS FILE IS AUTO-GENERATED, PLEASE DO NOT EDIT IT **** //
3

4
package binding
5

6
import (
7
        "bytes"
8

9
        "fyne.io/fyne/v2"
10
)
11

12
// BoolList supports binding a list of bool values.
13
//
14
// Since: 2.0
15
type BoolList interface {
16
        DataList
17

18
        Append(value bool) error
19
        Get() ([]bool, error)
20
        GetValue(index int) (bool, error)
21
        Prepend(value bool) error
22
        Remove(value bool) error
23
        Set(list []bool) error
24
        SetValue(index int, value bool) error
25
}
26

27
// ExternalBoolList supports binding a list of bool values from an external variable.
28
//
29
// Since: 2.0
30
type ExternalBoolList interface {
31
        BoolList
32

33
        Reload() error
34
}
35

UNCOV
36
// NewBoolList returns a bindable list of bool values.
×
UNCOV
37
//
×
UNCOV
38
// Since: 2.0
×
39
func NewBoolList() BoolList {
40
        return &boundBoolList{val: &[]bool{}}
41
}
42

43
// BindBoolList returns a bound list of bool values, based on the contents of the passed slice.
UNCOV
44
// If your code changes the content of the slice this refers to you should call Reload() to inform the bindings.
×
UNCOV
45
//
×
UNCOV
46
// Since: 2.0
×
47
func BindBoolList(v *[]bool) ExternalBoolList {
48
        if v == nil {
49
                return NewBoolList().(ExternalBoolList)
50
        }
51

52
        b := &boundBoolList{val: v, updateExternal: true}
53

54
        for i := range *v {
55
                b.appendItem(bindBoolListItem(v, i, b.updateExternal))
56
        }
57

58
        return b
59
}
60

61
type boundBoolList struct {
62
        listBase
63

64
        updateExternal bool
65
        val            *[]bool
66
}
67

68
func (l *boundBoolList) Append(val bool) error {
69
        l.lock.Lock()
70
        *l.val = append(*l.val, val)
71

72
        trigger, err := l.doReload()
73
        l.lock.Unlock()
74

75
        if trigger {
×
76
                l.trigger()
×
77
        }
×
78

79
        return err
80
}
81

82
func (l *boundBoolList) Get() ([]bool, error) {
83
        l.lock.RLock()
×
84
        defer l.lock.RUnlock()
×
85

×
86
        return *l.val, nil
87
}
88

89
func (l *boundBoolList) GetValue(i int) (bool, error) {
90
        l.lock.RLock()
91
        defer l.lock.RUnlock()
92

93
        if i < 0 || i >= l.Length() {
94
                return false, errOutOfBounds
95
        }
96

97
        return (*l.val)[i], nil
98
}
99

100
func (l *boundBoolList) Prepend(val bool) error {
101
        l.lock.Lock()
102
        *l.val = append([]bool{val}, *l.val...)
103

104
        trigger, err := l.doReload()
105
        l.lock.Unlock()
106

107
        if trigger {
108
                l.trigger()
109
        }
110

111
        return err
112
}
113

114
func (l *boundBoolList) Reload() error {
5✔
115
        l.lock.Lock()
5✔
116
        trigger, err := l.doReload()
5✔
117
        l.lock.Unlock()
118

119
        if trigger {
120
                l.trigger()
121
        }
122

3✔
123
        return err
3✔
124
}
3✔
125

126
// Remove takes the specified bool out of the list.
127
//
128
// Since: 2.5
129
func (l *boundBoolList) Remove(val bool) error {
130
        l.lock.Lock()
131

132
        v := *l.val
133
        if len(v) == 0 {
134
                l.lock.Unlock()
135
                return nil
136
        }
137
        if v[0] == val {
138
                *l.val = v[1:]
139
        } else if v[len(v)-1] == val {
140
                *l.val = v[:len(v)-1]
141
        } else {
142
                id := -1
143
                for i, v := range v {
144
                        if v == val {
145
                                id = i
146
                                break
147
                        }
148
                }
149

150
                if id == -1 {
151
                        l.lock.Unlock()
152
                        return nil
153
                }
×
154
                *l.val = append(v[:id], v[id+1:]...)
×
UNCOV
155
        }
×
156

157
        trigger, err := l.doReload()
158
        l.lock.Unlock()
159

160
        if trigger {
161
                l.trigger()
×
162
        }
×
UNCOV
163

×
164
        return err
165
}
166

167
func (l *boundBoolList) Set(v []bool) error {
168
        l.lock.Lock()
169
        *l.val = v
170
        trigger, err := l.doReload()
171
        l.lock.Unlock()
172

173
        if trigger {
174
                l.trigger()
175
        }
176

177
        return err
178
}
179

180
func (l *boundBoolList) doReload() (trigger bool, retErr error) {
181
        oldLen := len(l.items)
182
        newLen := len(*l.val)
183
        if oldLen > newLen {
184
                for i := oldLen - 1; i >= newLen; i-- {
185
                        l.deleteItem(i)
186
                }
187
                trigger = true
188
        } else if oldLen < newLen {
189
                for i := oldLen; i < newLen; i++ {
190
                        l.appendItem(bindBoolListItem(l.val, i, l.updateExternal))
191
                }
192
                trigger = true
×
UNCOV
193
        }
×
UNCOV
194

×
195
        for i, item := range l.items {
196
                if i > oldLen || i > newLen {
197
                        break
198
                }
199

200
                var err error
×
201
                if l.updateExternal {
×
202
                        err = item.(*boundExternalBoolListItem).setIfChanged((*l.val)[i])
×
203
                } else {
×
204
                        err = item.(*boundBoolListItem).doSet((*l.val)[i])
205
                }
×
206
                if err != nil {
×
207
                        retErr = err
×
208
                }
×
UNCOV
209
        }
×
210
        return
×
UNCOV
211
}
×
212

213
func (l *boundBoolList) SetValue(i int, v bool) error {
×
214
        l.lock.RLock()
215
        len := l.Length()
216
        l.lock.RUnlock()
217

218
        if i < 0 || i >= len {
219
                return errOutOfBounds
220
        }
221

222
        l.lock.Lock()
223
        (*l.val)[i] = v
224
        l.lock.Unlock()
225

226
        item, err := l.GetItem(i)
227
        if err != nil {
228
                return err
229
        }
230
        return item.(Bool).Set(v)
231
}
232

233
func bindBoolListItem(v *[]bool, i int, external bool) Bool {
234
        if external {
235
                ret := &boundExternalBoolListItem{old: (*v)[i]}
236
                ret.val = v
237
                ret.index = i
238
                return ret
239
        }
240

241
        return &boundBoolListItem{val: v, index: i}
242
}
UNCOV
243

×
UNCOV
244
type boundBoolListItem struct {
×
UNCOV
245
        base
×
246

247
        val   *[]bool
248
        index int
249
}
250

251
func (b *boundBoolListItem) Get() (bool, error) {
×
252
        b.lock.Lock()
×
253
        defer b.lock.Unlock()
×
254

255
        if b.index < 0 || b.index >= len(*b.val) {
256
                return false, errOutOfBounds
257
        }
258

259
        return (*b.val)[b.index], nil
260
}
261

262
func (b *boundBoolListItem) Set(val bool) error {
263
        return b.doSet(val)
264
}
265

266
func (b *boundBoolListItem) doSet(val bool) error {
267
        b.lock.Lock()
268
        (*b.val)[b.index] = val
269
        b.lock.Unlock()
270

271
        b.trigger()
272
        return nil
273
}
274

275
type boundExternalBoolListItem struct {
276
        boundBoolListItem
277

278
        old bool
279
}
280

281
func (b *boundExternalBoolListItem) setIfChanged(val bool) error {
282
        b.lock.Lock()
×
283
        if val == b.old {
×
284
                b.lock.Unlock()
285
                return nil
286
        }
287
        (*b.val)[b.index] = val
288
        b.old = val
289

290
        b.lock.Unlock()
×
291
        b.trigger()
×
292
        return nil
×
UNCOV
293
}
×
294

UNCOV
295
// BytesList supports binding a list of []byte values.
×
UNCOV
296
//
×
UNCOV
297
// Since: 2.2
×
UNCOV
298
type BytesList interface {
×
UNCOV
299
        DataList
×
300

UNCOV
301
        Append(value []byte) error
×
302
        Get() ([][]byte, error)
303
        GetValue(index int) ([]byte, error)
304
        Prepend(value []byte) error
305
        Remove(value []byte) error
306
        Set(list [][]byte) error
307
        SetValue(index int, value []byte) error
308
}
309

310
// ExternalBytesList supports binding a list of []byte values from an external variable.
311
//
312
// Since: 2.2
313
type ExternalBytesList interface {
314
        BytesList
315

316
        Reload() error
317
}
318

319
// NewBytesList returns a bindable list of []byte values.
320
//
321
// Since: 2.2
322
func NewBytesList() BytesList {
323
        return &boundBytesList{val: &[][]byte{}}
324
}
325

326
// BindBytesList returns a bound list of []byte values, based on the contents of the passed slice.
327
// If your code changes the content of the slice this refers to you should call Reload() to inform the bindings.
328
//
329
// Since: 2.2
330
func BindBytesList(v *[][]byte) ExternalBytesList {
331
        if v == nil {
×
332
                return NewBytesList().(ExternalBytesList)
×
333
        }
×
334

335
        b := &boundBytesList{val: v, updateExternal: true}
336

337
        for i := range *v {
338
                b.appendItem(bindBytesListItem(v, i, b.updateExternal))
339
        }
×
UNCOV
340

×
341
        return b
×
342
}
343

344
type boundBytesList struct {
345
        listBase
346

347
        updateExternal bool
348
        val            *[][]byte
349
}
350

351
func (l *boundBytesList) Append(val []byte) error {
352
        l.lock.Lock()
353
        *l.val = append(*l.val, val)
354

355
        trigger, err := l.doReload()
356
        l.lock.Unlock()
357

358
        if trigger {
359
                l.trigger()
360
        }
361

362
        return err
363
}
364

365
func (l *boundBytesList) Get() ([][]byte, error) {
366
        l.lock.RLock()
367
        defer l.lock.RUnlock()
368

369
        return *l.val, nil
370
}
371

372
func (l *boundBytesList) GetValue(i int) ([]byte, error) {
373
        l.lock.RLock()
374
        defer l.lock.RUnlock()
375

376
        if i < 0 || i >= l.Length() {
377
                return nil, errOutOfBounds
378
        }
379

380
        return (*l.val)[i], nil
381
}
382

383
func (l *boundBytesList) Prepend(val []byte) error {
384
        l.lock.Lock()
385
        *l.val = append([][]byte{val}, *l.val...)
386

387
        trigger, err := l.doReload()
388
        l.lock.Unlock()
389

390
        if trigger {
391
                l.trigger()
392
        }
393

394
        return err
395
}
396

397
func (l *boundBytesList) Reload() error {
398
        l.lock.Lock()
399
        trigger, err := l.doReload()
400
        l.lock.Unlock()
401

402
        if trigger {
403
                l.trigger()
404
        }
405

406
        return err
407
}
408

409
// Remove takes the specified []byte out of the list.
410
//
411
// Since: 2.5
412
func (l *boundBytesList) Remove(val []byte) error {
413
        l.lock.Lock()
414

415
        v := *l.val
416
        if len(v) == 0 {
417
                l.lock.Unlock()
418
                return nil
419
        }
420
        if bytes.Equal(v[0], val) {
421
                *l.val = v[1:]
422
        } else if bytes.Equal(v[len(v)-1], val) {
423
                *l.val = v[:len(v)-1]
424
        } else {
425
                id := -1
426
                for i, v := range v {
427
                        if bytes.Equal(v, val) {
428
                                id = i
429
                                break
430
                        }
431
                }
432

433
                if id == -1 {
434
                        l.lock.Unlock()
435
                        return nil
436
                }
437
                *l.val = append(v[:id], v[id+1:]...)
438
        }
439

440
        trigger, err := l.doReload()
441
        l.lock.Unlock()
442

443
        if trigger {
444
                l.trigger()
445
        }
446

447
        return err
448
}
449

450
func (l *boundBytesList) Set(v [][]byte) error {
451
        l.lock.Lock()
452
        *l.val = v
453
        trigger, err := l.doReload()
454
        l.lock.Unlock()
455

456
        if trigger {
457
                l.trigger()
458
        }
459

460
        return err
461
}
462

463
func (l *boundBytesList) doReload() (trigger bool, retErr error) {
464
        oldLen := len(l.items)
465
        newLen := len(*l.val)
466
        if oldLen > newLen {
467
                for i := oldLen - 1; i >= newLen; i-- {
468
                        l.deleteItem(i)
469
                }
470
                trigger = true
471
        } else if oldLen < newLen {
472
                for i := oldLen; i < newLen; i++ {
473
                        l.appendItem(bindBytesListItem(l.val, i, l.updateExternal))
474
                }
475
                trigger = true
476
        }
477

478
        for i, item := range l.items {
479
                if i > oldLen || i > newLen {
480
                        break
481
                }
482

483
                var err error
484
                if l.updateExternal {
485
                        err = item.(*boundExternalBytesListItem).setIfChanged((*l.val)[i])
486
                } else {
487
                        err = item.(*boundBytesListItem).doSet((*l.val)[i])
488
                }
489
                if err != nil {
490
                        retErr = err
491
                }
492
        }
493
        return
494
}
495

496
func (l *boundBytesList) SetValue(i int, v []byte) error {
497
        l.lock.RLock()
498
        len := l.Length()
499
        l.lock.RUnlock()
500

501
        if i < 0 || i >= len {
502
                return errOutOfBounds
503
        }
504

505
        l.lock.Lock()
506
        (*l.val)[i] = v
507
        l.lock.Unlock()
508

509
        item, err := l.GetItem(i)
510
        if err != nil {
511
                return err
512
        }
513
        return item.(Bytes).Set(v)
514
}
515

516
func bindBytesListItem(v *[][]byte, i int, external bool) Bytes {
517
        if external {
518
                ret := &boundExternalBytesListItem{old: (*v)[i]}
519
                ret.val = v
520
                ret.index = i
521
                return ret
522
        }
523

524
        return &boundBytesListItem{val: v, index: i}
525
}
526

527
type boundBytesListItem struct {
528
        base
529

530
        val   *[][]byte
531
        index int
532
}
533

534
func (b *boundBytesListItem) Get() ([]byte, error) {
535
        b.lock.Lock()
536
        defer b.lock.Unlock()
537

538
        if b.index < 0 || b.index >= len(*b.val) {
539
                return nil, errOutOfBounds
540
        }
541

542
        return (*b.val)[b.index], nil
543
}
544

545
func (b *boundBytesListItem) Set(val []byte) error {
546
        return b.doSet(val)
547
}
548

549
func (b *boundBytesListItem) doSet(val []byte) error {
550
        b.lock.Lock()
551
        (*b.val)[b.index] = val
552
        b.lock.Unlock()
553

554
        b.trigger()
555
        return nil
556
}
557

558
type boundExternalBytesListItem struct {
559
        boundBytesListItem
560

561
        old []byte
562
}
563

564
func (b *boundExternalBytesListItem) setIfChanged(val []byte) error {
565
        b.lock.Lock()
566
        if bytes.Equal(val, b.old) {
567
                b.lock.Unlock()
568
                return nil
569
        }
570
        (*b.val)[b.index] = val
571
        b.old = val
572

573
        b.lock.Unlock()
574
        b.trigger()
575
        return nil
576
}
577

578
// FloatList supports binding a list of float64 values.
579
//
580
// Since: 2.0
581
type FloatList interface {
582
        DataList
583

584
        Append(value float64) error
585
        Get() ([]float64, error)
586
        GetValue(index int) (float64, error)
587
        Prepend(value float64) error
588
        Remove(value float64) error
589
        Set(list []float64) error
590
        SetValue(index int, value float64) error
591
}
592

593
// ExternalFloatList supports binding a list of float64 values from an external variable.
594
//
595
// Since: 2.0
596
type ExternalFloatList interface {
597
        FloatList
598

599
        Reload() error
600
}
601

602
// NewFloatList returns a bindable list of float64 values.
603
//
604
// Since: 2.0
605
func NewFloatList() FloatList {
606
        return &boundFloatList{val: &[]float64{}}
607
}
608

609
// BindFloatList returns a bound list of float64 values, based on the contents of the passed slice.
610
// If your code changes the content of the slice this refers to you should call Reload() to inform the bindings.
611
//
612
// Since: 2.0
613
func BindFloatList(v *[]float64) ExternalFloatList {
614
        if v == nil {
615
                return NewFloatList().(ExternalFloatList)
616
        }
617

618
        b := &boundFloatList{val: v, updateExternal: true}
619

620
        for i := range *v {
621
                b.appendItem(bindFloatListItem(v, i, b.updateExternal))
622
        }
623

624
        return b
625
}
626

627
type boundFloatList struct {
628
        listBase
629

630
        updateExternal bool
631
        val            *[]float64
632
}
633

634
func (l *boundFloatList) Append(val float64) error {
635
        l.lock.Lock()
636
        *l.val = append(*l.val, val)
637

638
        trigger, err := l.doReload()
639
        l.lock.Unlock()
640

641
        if trigger {
642
                l.trigger()
643
        }
644

645
        return err
646
}
647

648
func (l *boundFloatList) Get() ([]float64, error) {
649
        l.lock.RLock()
650
        defer l.lock.RUnlock()
651

652
        return *l.val, nil
653
}
654

655
func (l *boundFloatList) GetValue(i int) (float64, error) {
656
        l.lock.RLock()
657
        defer l.lock.RUnlock()
658

659
        if i < 0 || i >= l.Length() {
660
                return 0.0, errOutOfBounds
661
        }
662

663
        return (*l.val)[i], nil
664
}
665

666
func (l *boundFloatList) Prepend(val float64) error {
667
        l.lock.Lock()
668
        *l.val = append([]float64{val}, *l.val...)
669

670
        trigger, err := l.doReload()
671
        l.lock.Unlock()
672

673
        if trigger {
674
                l.trigger()
675
        }
676

677
        return err
678
}
679

680
func (l *boundFloatList) Reload() error {
681
        l.lock.Lock()
682
        trigger, err := l.doReload()
683
        l.lock.Unlock()
684

685
        if trigger {
686
                l.trigger()
687
        }
688

689
        return err
690
}
691

692
// Remove takes the specified float64 out of the list.
693
//
694
// Since: 2.5
695
func (l *boundFloatList) Remove(val float64) error {
696
        l.lock.Lock()
697

698
        v := *l.val
699
        if len(v) == 0 {
700
                l.lock.Unlock()
701
                return nil
702
        }
703
        if v[0] == val {
704
                *l.val = v[1:]
705
        } else if v[len(v)-1] == val {
706
                *l.val = v[:len(v)-1]
707
        } else {
708
                id := -1
709
                for i, v := range v {
710
                        if v == val {
711
                                id = i
712
                                break
713
                        }
714
                }
715

716
                if id == -1 {
717
                        l.lock.Unlock()
718
                        return nil
719
                }
720
                *l.val = append(v[:id], v[id+1:]...)
721
        }
722

723
        trigger, err := l.doReload()
724
        l.lock.Unlock()
725

726
        if trigger {
727
                l.trigger()
728
        }
729

730
        return err
731
}
732

733
func (l *boundFloatList) Set(v []float64) error {
734
        l.lock.Lock()
735
        *l.val = v
736
        trigger, err := l.doReload()
737
        l.lock.Unlock()
738

739
        if trigger {
740
                l.trigger()
741
        }
742

743
        return err
744
}
745

746
func (l *boundFloatList) doReload() (trigger bool, retErr error) {
747
        oldLen := len(l.items)
748
        newLen := len(*l.val)
749
        if oldLen > newLen {
750
                for i := oldLen - 1; i >= newLen; i-- {
751
                        l.deleteItem(i)
752
                }
753
                trigger = true
754
        } else if oldLen < newLen {
755
                for i := oldLen; i < newLen; i++ {
756
                        l.appendItem(bindFloatListItem(l.val, i, l.updateExternal))
757
                }
758
                trigger = true
759
        }
760

761
        for i, item := range l.items {
762
                if i > oldLen || i > newLen {
763
                        break
764
                }
765

766
                var err error
767
                if l.updateExternal {
768
                        err = item.(*boundExternalFloatListItem).setIfChanged((*l.val)[i])
769
                } else {
770
                        err = item.(*boundFloatListItem).doSet((*l.val)[i])
771
                }
772
                if err != nil {
773
                        retErr = err
774
                }
775
        }
776
        return
777
}
778

779
func (l *boundFloatList) SetValue(i int, v float64) error {
780
        l.lock.RLock()
781
        len := l.Length()
782
        l.lock.RUnlock()
783

784
        if i < 0 || i >= len {
785
                return errOutOfBounds
786
        }
787

788
        l.lock.Lock()
789
        (*l.val)[i] = v
790
        l.lock.Unlock()
791

792
        item, err := l.GetItem(i)
793
        if err != nil {
794
                return err
795
        }
796
        return item.(Float).Set(v)
797
}
798

799
func bindFloatListItem(v *[]float64, i int, external bool) Float {
800
        if external {
801
                ret := &boundExternalFloatListItem{old: (*v)[i]}
802
                ret.val = v
803
                ret.index = i
804
                return ret
805
        }
806

807
        return &boundFloatListItem{val: v, index: i}
808
}
809

810
type boundFloatListItem struct {
811
        base
812

813
        val   *[]float64
814
        index int
815
}
816

817
func (b *boundFloatListItem) Get() (float64, error) {
818
        b.lock.Lock()
819
        defer b.lock.Unlock()
820

821
        if b.index < 0 || b.index >= len(*b.val) {
822
                return 0.0, errOutOfBounds
823
        }
824

825
        return (*b.val)[b.index], nil
826
}
827

828
func (b *boundFloatListItem) Set(val float64) error {
829
        return b.doSet(val)
830
}
831

832
func (b *boundFloatListItem) doSet(val float64) error {
833
        b.lock.Lock()
834
        (*b.val)[b.index] = val
835
        b.lock.Unlock()
836

837
        b.trigger()
838
        return nil
839
}
840

841
type boundExternalFloatListItem struct {
842
        boundFloatListItem
843

844
        old float64
845
}
846

847
func (b *boundExternalFloatListItem) setIfChanged(val float64) error {
848
        b.lock.Lock()
849
        if val == b.old {
850
                b.lock.Unlock()
851
                return nil
852
        }
853
        (*b.val)[b.index] = val
854
        b.old = val
855

856
        b.lock.Unlock()
857
        b.trigger()
858
        return nil
859
}
860

861
// IntList supports binding a list of int values.
862
//
863
// Since: 2.0
864
type IntList interface {
865
        DataList
866

867
        Append(value int) error
868
        Get() ([]int, error)
869
        GetValue(index int) (int, error)
870
        Prepend(value int) error
871
        Remove(value int) error
872
        Set(list []int) error
873
        SetValue(index int, value int) error
874
}
875

876
// ExternalIntList supports binding a list of int values from an external variable.
877
//
878
// Since: 2.0
879
type ExternalIntList interface {
880
        IntList
881

882
        Reload() error
883
}
884

885
// NewIntList returns a bindable list of int values.
886
//
887
// Since: 2.0
888
func NewIntList() IntList {
889
        return &boundIntList{val: &[]int{}}
890
}
891

892
// BindIntList returns a bound list of int values, based on the contents of the passed slice.
893
// If your code changes the content of the slice this refers to you should call Reload() to inform the bindings.
894
//
895
// Since: 2.0
896
func BindIntList(v *[]int) ExternalIntList {
897
        if v == nil {
898
                return NewIntList().(ExternalIntList)
899
        }
900

901
        b := &boundIntList{val: v, updateExternal: true}
902

903
        for i := range *v {
904
                b.appendItem(bindIntListItem(v, i, b.updateExternal))
905
        }
906

907
        return b
908
}
909

910
type boundIntList struct {
911
        listBase
912

913
        updateExternal bool
914
        val            *[]int
915
}
916

917
func (l *boundIntList) Append(val int) error {
918
        l.lock.Lock()
919
        *l.val = append(*l.val, val)
920

921
        trigger, err := l.doReload()
922
        l.lock.Unlock()
923

924
        if trigger {
925
                l.trigger()
926
        }
927

928
        return err
929
}
930

931
func (l *boundIntList) Get() ([]int, error) {
932
        l.lock.RLock()
933
        defer l.lock.RUnlock()
934

935
        return *l.val, nil
936
}
937

938
func (l *boundIntList) GetValue(i int) (int, error) {
939
        l.lock.RLock()
940
        defer l.lock.RUnlock()
941

942
        if i < 0 || i >= l.Length() {
943
                return 0, errOutOfBounds
944
        }
945

946
        return (*l.val)[i], nil
947
}
948

949
func (l *boundIntList) Prepend(val int) error {
950
        l.lock.Lock()
951
        *l.val = append([]int{val}, *l.val...)
952

953
        trigger, err := l.doReload()
954
        l.lock.Unlock()
955

956
        if trigger {
957
                l.trigger()
958
        }
959

960
        return err
961
}
962

963
func (l *boundIntList) Reload() error {
964
        l.lock.Lock()
965
        trigger, err := l.doReload()
966
        l.lock.Unlock()
967

968
        if trigger {
969
                l.trigger()
970
        }
971

972
        return err
973
}
974

975
// Remove takes the specified int out of the list.
976
//
977
// Since: 2.5
978
func (l *boundIntList) Remove(val int) error {
979
        l.lock.Lock()
980

981
        v := *l.val
982
        if len(v) == 0 {
983
                l.lock.Unlock()
984
                return nil
985
        }
986
        if v[0] == val {
987
                *l.val = v[1:]
988
        } else if v[len(v)-1] == val {
989
                *l.val = v[:len(v)-1]
990
        } else {
991
                id := -1
992
                for i, v := range v {
993
                        if v == val {
994
                                id = i
995
                                break
996
                        }
997
                }
998

999
                if id == -1 {
1000
                        l.lock.Unlock()
1001
                        return nil
1002
                }
1003
                *l.val = append(v[:id], v[id+1:]...)
1004
        }
1005

1006
        trigger, err := l.doReload()
1007
        l.lock.Unlock()
1008

1009
        if trigger {
1010
                l.trigger()
1011
        }
1012

1013
        return err
1014
}
1015

1016
func (l *boundIntList) Set(v []int) error {
1017
        l.lock.Lock()
1018
        *l.val = v
1019
        trigger, err := l.doReload()
1020
        l.lock.Unlock()
1021

1022
        if trigger {
1023
                l.trigger()
1024
        }
1025

1026
        return err
1027
}
1028

1029
func (l *boundIntList) doReload() (trigger bool, retErr error) {
1030
        oldLen := len(l.items)
1031
        newLen := len(*l.val)
1032
        if oldLen > newLen {
1033
                for i := oldLen - 1; i >= newLen; i-- {
1034
                        l.deleteItem(i)
1035
                }
1036
                trigger = true
1037
        } else if oldLen < newLen {
1038
                for i := oldLen; i < newLen; i++ {
1039
                        l.appendItem(bindIntListItem(l.val, i, l.updateExternal))
1040
                }
1041
                trigger = true
1042
        }
1043

1044
        for i, item := range l.items {
1045
                if i > oldLen || i > newLen {
1046
                        break
1047
                }
1048

1049
                var err error
1050
                if l.updateExternal {
1051
                        err = item.(*boundExternalIntListItem).setIfChanged((*l.val)[i])
1052
                } else {
1053
                        err = item.(*boundIntListItem).doSet((*l.val)[i])
1054
                }
1055
                if err != nil {
1056
                        retErr = err
1057
                }
1058
        }
1059
        return
1060
}
1061

1062
func (l *boundIntList) SetValue(i int, v int) error {
1063
        l.lock.RLock()
1064
        len := l.Length()
1065
        l.lock.RUnlock()
1066

1067
        if i < 0 || i >= len {
1068
                return errOutOfBounds
1069
        }
1070

1071
        l.lock.Lock()
1072
        (*l.val)[i] = v
1073
        l.lock.Unlock()
1074

1075
        item, err := l.GetItem(i)
1076
        if err != nil {
1077
                return err
1078
        }
1079
        return item.(Int).Set(v)
1080
}
1081

1082
func bindIntListItem(v *[]int, i int, external bool) Int {
1083
        if external {
1084
                ret := &boundExternalIntListItem{old: (*v)[i]}
1085
                ret.val = v
1086
                ret.index = i
1087
                return ret
1088
        }
1089

1090
        return &boundIntListItem{val: v, index: i}
1091
}
1092

1093
type boundIntListItem struct {
1094
        base
1095

1096
        val   *[]int
1097
        index int
1098
}
1099

1100
func (b *boundIntListItem) Get() (int, error) {
1101
        b.lock.Lock()
1102
        defer b.lock.Unlock()
1103

1104
        if b.index < 0 || b.index >= len(*b.val) {
1105
                return 0, errOutOfBounds
1106
        }
1107

1108
        return (*b.val)[b.index], nil
1109
}
1110

1111
func (b *boundIntListItem) Set(val int) error {
1112
        return b.doSet(val)
1113
}
1114

1115
func (b *boundIntListItem) doSet(val int) error {
1116
        b.lock.Lock()
1117
        (*b.val)[b.index] = val
1118
        b.lock.Unlock()
1119

1120
        b.trigger()
1121
        return nil
1122
}
1123

1124
type boundExternalIntListItem struct {
1125
        boundIntListItem
1126

1127
        old int
1128
}
1129

1130
func (b *boundExternalIntListItem) setIfChanged(val int) error {
1131
        b.lock.Lock()
1132
        if val == b.old {
1133
                b.lock.Unlock()
1134
                return nil
1135
        }
1136
        (*b.val)[b.index] = val
1137
        b.old = val
1138

1139
        b.lock.Unlock()
1140
        b.trigger()
1141
        return nil
1142
}
1143

1144
// RuneList supports binding a list of rune values.
1145
//
1146
// Since: 2.0
1147
type RuneList interface {
1148
        DataList
1149

1150
        Append(value rune) error
1151
        Get() ([]rune, error)
1152
        GetValue(index int) (rune, error)
1153
        Prepend(value rune) error
1154
        Remove(value rune) error
1155
        Set(list []rune) error
1156
        SetValue(index int, value rune) error
1157
}
1158

1159
// ExternalRuneList supports binding a list of rune values from an external variable.
1160
//
1161
// Since: 2.0
1162
type ExternalRuneList interface {
1163
        RuneList
1164

1165
        Reload() error
1166
}
1167

1168
// NewRuneList returns a bindable list of rune values.
1169
//
1170
// Since: 2.0
1171
func NewRuneList() RuneList {
1172
        return &boundRuneList{val: &[]rune{}}
1173
}
1174

1175
// BindRuneList returns a bound list of rune values, based on the contents of the passed slice.
1176
// If your code changes the content of the slice this refers to you should call Reload() to inform the bindings.
1177
//
1178
// Since: 2.0
1179
func BindRuneList(v *[]rune) ExternalRuneList {
1180
        if v == nil {
1181
                return NewRuneList().(ExternalRuneList)
1182
        }
1183

1184
        b := &boundRuneList{val: v, updateExternal: true}
1185

1186
        for i := range *v {
1187
                b.appendItem(bindRuneListItem(v, i, b.updateExternal))
1188
        }
1189

1190
        return b
1191
}
1192

1193
type boundRuneList struct {
1194
        listBase
1195

1196
        updateExternal bool
1197
        val            *[]rune
1198
}
1199

1200
func (l *boundRuneList) Append(val rune) error {
1201
        l.lock.Lock()
1202
        *l.val = append(*l.val, val)
1203

1204
        trigger, err := l.doReload()
1205
        l.lock.Unlock()
1206

1207
        if trigger {
1208
                l.trigger()
1209
        }
1210

1211
        return err
1212
}
1213

1214
func (l *boundRuneList) Get() ([]rune, error) {
1215
        l.lock.RLock()
1216
        defer l.lock.RUnlock()
1217

1218
        return *l.val, nil
1219
}
1220

1221
func (l *boundRuneList) GetValue(i int) (rune, error) {
1222
        l.lock.RLock()
1223
        defer l.lock.RUnlock()
1224

1225
        if i < 0 || i >= l.Length() {
1226
                return rune(0), errOutOfBounds
1227
        }
1228

1229
        return (*l.val)[i], nil
1230
}
1231

1232
func (l *boundRuneList) Prepend(val rune) error {
1233
        l.lock.Lock()
1234
        *l.val = append([]rune{val}, *l.val...)
1235

1236
        trigger, err := l.doReload()
1237
        l.lock.Unlock()
1238

1239
        if trigger {
1240
                l.trigger()
1241
        }
1242

1243
        return err
1244
}
1245

1246
func (l *boundRuneList) Reload() error {
1247
        l.lock.Lock()
1248
        trigger, err := l.doReload()
1249
        l.lock.Unlock()
1250

1251
        if trigger {
1252
                l.trigger()
1253
        }
1254

1255
        return err
1256
}
1257

1258
// Remove takes the specified rune out of the list.
1259
//
1260
// Since: 2.5
1261
func (l *boundRuneList) Remove(val rune) error {
1262
        l.lock.Lock()
1263

1264
        v := *l.val
1265
        if len(v) == 0 {
1266
                l.lock.Unlock()
1267
                return nil
1268
        }
1269
        if v[0] == val {
1270
                *l.val = v[1:]
1271
        } else if v[len(v)-1] == val {
1272
                *l.val = v[:len(v)-1]
1273
        } else {
1274
                id := -1
1275
                for i, v := range v {
1276
                        if v == val {
1277
                                id = i
1278
                                break
1279
                        }
1280
                }
1281

1282
                if id == -1 {
1283
                        l.lock.Unlock()
1284
                        return nil
1285
                }
1286
                *l.val = append(v[:id], v[id+1:]...)
1287
        }
1288

1289
        trigger, err := l.doReload()
1290
        l.lock.Unlock()
1291

1292
        if trigger {
1293
                l.trigger()
1294
        }
1295

1296
        return err
1297
}
1298

1299
func (l *boundRuneList) Set(v []rune) error {
1300
        l.lock.Lock()
1301
        *l.val = v
1302
        trigger, err := l.doReload()
1303
        l.lock.Unlock()
1304

1305
        if trigger {
1306
                l.trigger()
1307
        }
1308

1309
        return err
1310
}
1311

1312
func (l *boundRuneList) doReload() (trigger bool, retErr error) {
1313
        oldLen := len(l.items)
1314
        newLen := len(*l.val)
1315
        if oldLen > newLen {
1316
                for i := oldLen - 1; i >= newLen; i-- {
1317
                        l.deleteItem(i)
1318
                }
1319
                trigger = true
1320
        } else if oldLen < newLen {
1321
                for i := oldLen; i < newLen; i++ {
1322
                        l.appendItem(bindRuneListItem(l.val, i, l.updateExternal))
1323
                }
1324
                trigger = true
1325
        }
1326

1327
        for i, item := range l.items {
1328
                if i > oldLen || i > newLen {
1329
                        break
1330
                }
1331

1332
                var err error
1333
                if l.updateExternal {
1334
                        err = item.(*boundExternalRuneListItem).setIfChanged((*l.val)[i])
1335
                } else {
1336
                        err = item.(*boundRuneListItem).doSet((*l.val)[i])
1337
                }
1338
                if err != nil {
1339
                        retErr = err
1340
                }
1341
        }
1342
        return
1343
}
1344

1345
func (l *boundRuneList) SetValue(i int, v rune) error {
1346
        l.lock.RLock()
1347
        len := l.Length()
1348
        l.lock.RUnlock()
1349

1350
        if i < 0 || i >= len {
1351
                return errOutOfBounds
1352
        }
1353

1354
        l.lock.Lock()
1355
        (*l.val)[i] = v
1356
        l.lock.Unlock()
1357

1358
        item, err := l.GetItem(i)
1359
        if err != nil {
1360
                return err
1361
        }
1362
        return item.(Rune).Set(v)
1363
}
1364

1365
func bindRuneListItem(v *[]rune, i int, external bool) Rune {
1366
        if external {
1367
                ret := &boundExternalRuneListItem{old: (*v)[i]}
1368
                ret.val = v
1369
                ret.index = i
1370
                return ret
1371
        }
1372

1373
        return &boundRuneListItem{val: v, index: i}
1374
}
1375

1376
type boundRuneListItem struct {
1377
        base
1378

1379
        val   *[]rune
1380
        index int
1381
}
1382

1383
func (b *boundRuneListItem) Get() (rune, error) {
1384
        b.lock.Lock()
1385
        defer b.lock.Unlock()
1386

1387
        if b.index < 0 || b.index >= len(*b.val) {
1388
                return rune(0), errOutOfBounds
1389
        }
1390

1391
        return (*b.val)[b.index], nil
1392
}
1393

1394
func (b *boundRuneListItem) Set(val rune) error {
1395
        return b.doSet(val)
1396
}
1397

1398
func (b *boundRuneListItem) doSet(val rune) error {
1399
        b.lock.Lock()
1400
        (*b.val)[b.index] = val
1401
        b.lock.Unlock()
1402

1403
        b.trigger()
1404
        return nil
1405
}
1406

1407
type boundExternalRuneListItem struct {
1408
        boundRuneListItem
1409

1410
        old rune
1411
}
1412

1413
func (b *boundExternalRuneListItem) setIfChanged(val rune) error {
1414
        b.lock.Lock()
1415
        if val == b.old {
1416
                b.lock.Unlock()
1417
                return nil
1418
        }
1419
        (*b.val)[b.index] = val
1420
        b.old = val
1421

1422
        b.lock.Unlock()
1423
        b.trigger()
1424
        return nil
1425
}
1426

1427
// StringList supports binding a list of string values.
1428
//
1429
// Since: 2.0
1430
type StringList interface {
1431
        DataList
1432

1433
        Append(value string) error
1434
        Get() ([]string, error)
1435
        GetValue(index int) (string, error)
1436
        Prepend(value string) error
1437
        Remove(value string) error
1438
        Set(list []string) error
1439
        SetValue(index int, value string) error
1440
}
1441

1442
// ExternalStringList supports binding a list of string values from an external variable.
1443
//
1444
// Since: 2.0
1445
type ExternalStringList interface {
1446
        StringList
1447

1448
        Reload() error
1449
}
1450

1451
// NewStringList returns a bindable list of string values.
1452
//
1453
// Since: 2.0
1454
func NewStringList() StringList {
1455
        return &boundStringList{val: &[]string{}}
1456
}
1457

1458
// BindStringList returns a bound list of string values, based on the contents of the passed slice.
1459
// If your code changes the content of the slice this refers to you should call Reload() to inform the bindings.
1460
//
1461
// Since: 2.0
1462
func BindStringList(v *[]string) ExternalStringList {
1463
        if v == nil {
1464
                return NewStringList().(ExternalStringList)
1465
        }
1466

1467
        b := &boundStringList{val: v, updateExternal: true}
1468

1469
        for i := range *v {
1470
                b.appendItem(bindStringListItem(v, i, b.updateExternal))
1471
        }
1472

1473
        return b
1474
}
1475

1476
type boundStringList struct {
1477
        listBase
1478

1479
        updateExternal bool
1480
        val            *[]string
1481
}
1482

1483
func (l *boundStringList) Append(val string) error {
1484
        l.lock.Lock()
1485
        *l.val = append(*l.val, val)
1486

1487
        trigger, err := l.doReload()
1488
        l.lock.Unlock()
1489

1490
        if trigger {
1491
                l.trigger()
1492
        }
1493

1494
        return err
1495
}
1496

1497
func (l *boundStringList) Get() ([]string, error) {
1498
        l.lock.RLock()
1499
        defer l.lock.RUnlock()
1500

1501
        return *l.val, nil
1502
}
1503

1504
func (l *boundStringList) GetValue(i int) (string, error) {
1505
        l.lock.RLock()
1506
        defer l.lock.RUnlock()
1507

1508
        if i < 0 || i >= l.Length() {
1509
                return "", errOutOfBounds
1510
        }
1511

1512
        return (*l.val)[i], nil
1513
}
1514

1515
func (l *boundStringList) Prepend(val string) error {
1516
        l.lock.Lock()
1517
        *l.val = append([]string{val}, *l.val...)
1518

1519
        trigger, err := l.doReload()
1520
        l.lock.Unlock()
1521

1522
        if trigger {
1523
                l.trigger()
1524
        }
1525

1526
        return err
1527
}
1528

1529
func (l *boundStringList) Reload() error {
1530
        l.lock.Lock()
1531
        trigger, err := l.doReload()
1532
        l.lock.Unlock()
1533

1534
        if trigger {
1535
                l.trigger()
1536
        }
1537

1538
        return err
1539
}
1540

1541
// Remove takes the specified string out of the list.
1542
//
1543
// Since: 2.5
1544
func (l *boundStringList) Remove(val string) error {
1545
        l.lock.Lock()
1546

1547
        v := *l.val
1548
        if len(v) == 0 {
1549
                l.lock.Unlock()
1550
                return nil
1551
        }
1552
        if v[0] == val {
1553
                *l.val = v[1:]
1554
        } else if v[len(v)-1] == val {
1555
                *l.val = v[:len(v)-1]
1556
        } else {
1557
                id := -1
1558
                for i, v := range v {
1559
                        if v == val {
1560
                                id = i
1561
                                break
1562
                        }
1563
                }
1564

1565
                if id == -1 {
1566
                        l.lock.Unlock()
1567
                        return nil
1568
                }
1569
                *l.val = append(v[:id], v[id+1:]...)
1570
        }
1571

1572
        trigger, err := l.doReload()
1573
        l.lock.Unlock()
1574

1575
        if trigger {
1576
                l.trigger()
1577
        }
1578

1579
        return err
1580
}
1581

1582
func (l *boundStringList) Set(v []string) error {
1583
        l.lock.Lock()
1584
        *l.val = v
1585
        trigger, err := l.doReload()
1586
        l.lock.Unlock()
1587

1588
        if trigger {
1589
                l.trigger()
1590
        }
1591

1592
        return err
1593
}
1594

1595
func (l *boundStringList) doReload() (trigger bool, retErr error) {
1596
        oldLen := len(l.items)
1597
        newLen := len(*l.val)
1598
        if oldLen > newLen {
1599
                for i := oldLen - 1; i >= newLen; i-- {
1600
                        l.deleteItem(i)
1601
                }
1602
                trigger = true
1603
        } else if oldLen < newLen {
1604
                for i := oldLen; i < newLen; i++ {
1605
                        l.appendItem(bindStringListItem(l.val, i, l.updateExternal))
1606
                }
1607
                trigger = true
1608
        }
1609

1610
        for i, item := range l.items {
1611
                if i > oldLen || i > newLen {
1612
                        break
1613
                }
1614

1615
                var err error
1616
                if l.updateExternal {
1617
                        err = item.(*boundExternalStringListItem).setIfChanged((*l.val)[i])
1618
                } else {
1619
                        err = item.(*boundStringListItem).doSet((*l.val)[i])
1620
                }
1621
                if err != nil {
1622
                        retErr = err
1623
                }
1624
        }
1625
        return
1626
}
1627

1628
func (l *boundStringList) SetValue(i int, v string) error {
1629
        l.lock.RLock()
1630
        len := l.Length()
1631
        l.lock.RUnlock()
1632

1633
        if i < 0 || i >= len {
1634
                return errOutOfBounds
1635
        }
1636

1637
        l.lock.Lock()
1638
        (*l.val)[i] = v
1639
        l.lock.Unlock()
1640

1641
        item, err := l.GetItem(i)
1642
        if err != nil {
1643
                return err
1644
        }
1645
        return item.(String).Set(v)
1646
}
1647

1648
func bindStringListItem(v *[]string, i int, external bool) String {
1649
        if external {
1650
                ret := &boundExternalStringListItem{old: (*v)[i]}
1651
                ret.val = v
1652
                ret.index = i
1653
                return ret
1654
        }
1655

1656
        return &boundStringListItem{val: v, index: i}
1657
}
1658

1659
type boundStringListItem struct {
1660
        base
1661

1662
        val   *[]string
1663
        index int
1664
}
1665

1666
func (b *boundStringListItem) Get() (string, error) {
1667
        b.lock.Lock()
1668
        defer b.lock.Unlock()
1669

1670
        if b.index < 0 || b.index >= len(*b.val) {
1671
                return "", errOutOfBounds
1672
        }
1673

1674
        return (*b.val)[b.index], nil
1675
}
1676

1677
func (b *boundStringListItem) Set(val string) error {
1678
        return b.doSet(val)
1679
}
1680

1681
func (b *boundStringListItem) doSet(val string) error {
1682
        b.lock.Lock()
1683
        (*b.val)[b.index] = val
1684
        b.lock.Unlock()
1685

1686
        b.trigger()
1687
        return nil
1688
}
1689

1690
type boundExternalStringListItem struct {
1691
        boundStringListItem
1692

1693
        old string
1694
}
1695

1696
func (b *boundExternalStringListItem) setIfChanged(val string) error {
1697
        b.lock.Lock()
1698
        if val == b.old {
1699
                b.lock.Unlock()
1700
                return nil
1701
        }
1702
        (*b.val)[b.index] = val
1703
        b.old = val
1704

1705
        b.lock.Unlock()
1706
        b.trigger()
1707
        return nil
1708
}
1709

1710
// UntypedList supports binding a list of any values.
1711
//
1712
// Since: 2.1
1713
type UntypedList interface {
1714
        DataList
1715

1716
        Append(value any) error
1717
        Get() ([]any, error)
1718
        GetValue(index int) (any, error)
1719
        Prepend(value any) error
1720
        Remove(value any) error
1721
        Set(list []any) error
1722
        SetValue(index int, value any) error
1723
}
1724

1725
// ExternalUntypedList supports binding a list of any values from an external variable.
1726
//
1727
// Since: 2.1
1728
type ExternalUntypedList interface {
1729
        UntypedList
1730

1731
        Reload() error
1732
}
1733

1734
// NewUntypedList returns a bindable list of any values.
1735
//
1736
// Since: 2.1
1737
func NewUntypedList() UntypedList {
1738
        return &boundUntypedList{val: &[]any{}}
1739
}
1740

1741
// BindUntypedList returns a bound list of any values, based on the contents of the passed slice.
1742
// If your code changes the content of the slice this refers to you should call Reload() to inform the bindings.
1743
//
1744
// Since: 2.1
1745
func BindUntypedList(v *[]any) ExternalUntypedList {
1746
        if v == nil {
1747
                return NewUntypedList().(ExternalUntypedList)
1748
        }
1749

1750
        b := &boundUntypedList{val: v, updateExternal: true}
1751

1752
        for i := range *v {
1753
                b.appendItem(bindUntypedListItem(v, i, b.updateExternal))
1754
        }
1755

1756
        return b
1757
}
1758

1759
type boundUntypedList struct {
1760
        listBase
1761

1762
        updateExternal bool
1763
        val            *[]any
1764
}
1765

1766
func (l *boundUntypedList) Append(val any) error {
1767
        l.lock.Lock()
1768
        *l.val = append(*l.val, val)
1769

1770
        trigger, err := l.doReload()
1771
        l.lock.Unlock()
1772

1773
        if trigger {
1774
                l.trigger()
1775
        }
1776

1777
        return err
1778
}
1779

1780
func (l *boundUntypedList) Get() ([]any, error) {
1781
        l.lock.RLock()
1782
        defer l.lock.RUnlock()
1783

1784
        return *l.val, nil
1785
}
1786

1787
func (l *boundUntypedList) GetValue(i int) (any, error) {
1788
        l.lock.RLock()
1789
        defer l.lock.RUnlock()
1790

1791
        if i < 0 || i >= l.Length() {
1792
                return nil, errOutOfBounds
1793
        }
1794

1795
        return (*l.val)[i], nil
1796
}
1797

1798
func (l *boundUntypedList) Prepend(val any) error {
1799
        l.lock.Lock()
1800
        *l.val = append([]any{val}, *l.val...)
1801

1802
        trigger, err := l.doReload()
1803
        l.lock.Unlock()
1804

1805
        if trigger {
1806
                l.trigger()
1807
        }
1808

1809
        return err
1810
}
1811

1812
func (l *boundUntypedList) Reload() error {
1813
        l.lock.Lock()
1814
        trigger, err := l.doReload()
1815
        l.lock.Unlock()
1816

1817
        if trigger {
1818
                l.trigger()
1819
        }
1820

1821
        return err
1822
}
1823

1824
// Remove takes the specified any out of the list.
1825
//
1826
// Since: 2.5
1827
func (l *boundUntypedList) Remove(val any) error {
1828
        l.lock.Lock()
1829

1830
        v := *l.val
1831
        if len(v) == 0 {
1832
                l.lock.Unlock()
1833
                return nil
1834
        }
1835
        if v[0] == val {
1836
                *l.val = v[1:]
1837
        } else if v[len(v)-1] == val {
1838
                *l.val = v[:len(v)-1]
1839
        } else {
1840
                id := -1
1841
                for i, v := range v {
1842
                        if v == val {
1843
                                id = i
1844
                                break
1845
                        }
1846
                }
1847

1848
                if id == -1 {
1849
                        l.lock.Unlock()
1850
                        return nil
1851
                }
1852
                *l.val = append(v[:id], v[id+1:]...)
1853
        }
1854

1855
        trigger, err := l.doReload()
1856
        l.lock.Unlock()
1857

1858
        if trigger {
1859
                l.trigger()
1860
        }
1861

1862
        return err
1863
}
1864

1865
func (l *boundUntypedList) Set(v []any) error {
1866
        l.lock.Lock()
1867
        *l.val = v
1868
        trigger, err := l.doReload()
1869
        l.lock.Unlock()
1870

1871
        if trigger {
1872
                l.trigger()
1873
        }
1874

1875
        return err
1876
}
1877

1878
func (l *boundUntypedList) doReload() (trigger bool, retErr error) {
1879
        oldLen := len(l.items)
1880
        newLen := len(*l.val)
1881
        if oldLen > newLen {
1882
                for i := oldLen - 1; i >= newLen; i-- {
1883
                        l.deleteItem(i)
1884
                }
1885
                trigger = true
1886
        } else if oldLen < newLen {
1887
                for i := oldLen; i < newLen; i++ {
1888
                        l.appendItem(bindUntypedListItem(l.val, i, l.updateExternal))
1889
                }
1890
                trigger = true
1891
        }
1892

1893
        for i, item := range l.items {
1894
                if i > oldLen || i > newLen {
1895
                        break
1896
                }
1897

1898
                var err error
1899
                if l.updateExternal {
1900
                        err = item.(*boundExternalUntypedListItem).setIfChanged((*l.val)[i])
1901
                } else {
1902
                        err = item.(*boundUntypedListItem).doSet((*l.val)[i])
1903
                }
1904
                if err != nil {
1905
                        retErr = err
1906
                }
1907
        }
1908
        return
1909
}
1910

1911
func (l *boundUntypedList) SetValue(i int, v any) error {
1912
        l.lock.RLock()
1913
        len := l.Length()
1914
        l.lock.RUnlock()
1915

1916
        if i < 0 || i >= len {
1917
                return errOutOfBounds
1918
        }
1919

1920
        l.lock.Lock()
1921
        (*l.val)[i] = v
1922
        l.lock.Unlock()
1923

1924
        item, err := l.GetItem(i)
1925
        if err != nil {
1926
                return err
1927
        }
1928
        return item.(Untyped).Set(v)
1929
}
1930

1931
func bindUntypedListItem(v *[]any, i int, external bool) Untyped {
1932
        if external {
1933
                ret := &boundExternalUntypedListItem{old: (*v)[i]}
1934
                ret.val = v
1935
                ret.index = i
1936
                return ret
1937
        }
1938

1939
        return &boundUntypedListItem{val: v, index: i}
1940
}
1941

1942
type boundUntypedListItem struct {
1943
        base
1944

1945
        val   *[]any
1946
        index int
1947
}
1948

1949
func (b *boundUntypedListItem) Get() (any, error) {
1950
        b.lock.Lock()
1951
        defer b.lock.Unlock()
1952

1953
        if b.index < 0 || b.index >= len(*b.val) {
1954
                return nil, errOutOfBounds
1955
        }
1956

1957
        return (*b.val)[b.index], nil
1958
}
1959

1960
func (b *boundUntypedListItem) Set(val any) error {
1961
        return b.doSet(val)
1962
}
1963

1964
func (b *boundUntypedListItem) doSet(val any) error {
1965
        b.lock.Lock()
1966
        (*b.val)[b.index] = val
1967
        b.lock.Unlock()
1968

1969
        b.trigger()
1970
        return nil
1971
}
1972

1973
type boundExternalUntypedListItem struct {
1974
        boundUntypedListItem
1975

1976
        old any
1977
}
1978

1979
func (b *boundExternalUntypedListItem) setIfChanged(val any) error {
1980
        b.lock.Lock()
1981
        if val == b.old {
1982
                b.lock.Unlock()
1983
                return nil
1984
        }
1985
        (*b.val)[b.index] = val
1986
        b.old = val
1987

1988
        b.lock.Unlock()
1989
        b.trigger()
1990
        return nil
1991
}
1992

1993
// URIList supports binding a list of fyne.URI values.
1994
//
1995
// Since: 2.1
1996
type URIList interface {
1997
        DataList
1998

1999
        Append(value fyne.URI) error
2000
        Get() ([]fyne.URI, error)
2001
        GetValue(index int) (fyne.URI, error)
2002
        Prepend(value fyne.URI) error
2003
        Remove(value fyne.URI) error
2004
        Set(list []fyne.URI) error
2005
        SetValue(index int, value fyne.URI) error
2006
}
2007

2008
// ExternalURIList supports binding a list of fyne.URI values from an external variable.
2009
//
2010
// Since: 2.1
2011
type ExternalURIList interface {
2012
        URIList
2013

2014
        Reload() error
2015
}
2016

2017
// NewURIList returns a bindable list of fyne.URI values.
2018
//
2019
// Since: 2.1
2020
func NewURIList() URIList {
2021
        return &boundURIList{val: &[]fyne.URI{}}
2022
}
2023

2024
// BindURIList returns a bound list of fyne.URI values, based on the contents of the passed slice.
2025
// If your code changes the content of the slice this refers to you should call Reload() to inform the bindings.
2026
//
2027
// Since: 2.1
2028
func BindURIList(v *[]fyne.URI) ExternalURIList {
2029
        if v == nil {
2030
                return NewURIList().(ExternalURIList)
2031
        }
2032

2033
        b := &boundURIList{val: v, updateExternal: true}
2034

2035
        for i := range *v {
2036
                b.appendItem(bindURIListItem(v, i, b.updateExternal))
2037
        }
2038

2039
        return b
2040
}
2041

2042
type boundURIList struct {
2043
        listBase
2044

2045
        updateExternal bool
2046
        val            *[]fyne.URI
2047
}
2048

2049
func (l *boundURIList) Append(val fyne.URI) error {
2050
        l.lock.Lock()
2051
        *l.val = append(*l.val, val)
2052

2053
        trigger, err := l.doReload()
2054
        l.lock.Unlock()
2055

2056
        if trigger {
2057
                l.trigger()
2058
        }
2059

2060
        return err
2061
}
2062

2063
func (l *boundURIList) Get() ([]fyne.URI, error) {
2064
        l.lock.RLock()
2065
        defer l.lock.RUnlock()
2066

2067
        return *l.val, nil
2068
}
2069

2070
func (l *boundURIList) GetValue(i int) (fyne.URI, error) {
2071
        l.lock.RLock()
2072
        defer l.lock.RUnlock()
2073

2074
        if i < 0 || i >= l.Length() {
2075
                return fyne.URI(nil), errOutOfBounds
2076
        }
2077

2078
        return (*l.val)[i], nil
2079
}
2080

2081
func (l *boundURIList) Prepend(val fyne.URI) error {
2082
        l.lock.Lock()
2083
        *l.val = append([]fyne.URI{val}, *l.val...)
2084

2085
        trigger, err := l.doReload()
2086
        l.lock.Unlock()
2087

2088
        if trigger {
2089
                l.trigger()
2090
        }
2091

2092
        return err
2093
}
2094

2095
func (l *boundURIList) Reload() error {
2096
        l.lock.Lock()
2097
        trigger, err := l.doReload()
2098
        l.lock.Unlock()
2099

2100
        if trigger {
2101
                l.trigger()
2102
        }
2103

2104
        return err
2105
}
2106

2107
// Remove takes the specified fyne.URI out of the list.
2108
//
2109
// Since: 2.5
2110
func (l *boundURIList) Remove(val fyne.URI) error {
2111
        l.lock.Lock()
2112

2113
        v := *l.val
2114
        if len(v) == 0 {
2115
                l.lock.Unlock()
2116
                return nil
2117
        }
2118
        if compareURI(v[0], val) {
2119
                *l.val = v[1:]
2120
        } else if compareURI(v[len(v)-1], val) {
2121
                *l.val = v[:len(v)-1]
2122
        } else {
2123
                id := -1
2124
                for i, v := range v {
2125
                        if compareURI(v, val) {
2126
                                id = i
2127
                                break
2128
                        }
2129
                }
2130

2131
                if id == -1 {
2132
                        l.lock.Unlock()
2133
                        return nil
2134
                }
2135
                *l.val = append(v[:id], v[id+1:]...)
2136
        }
2137

2138
        trigger, err := l.doReload()
2139
        l.lock.Unlock()
2140

2141
        if trigger {
2142
                l.trigger()
2143
        }
2144

2145
        return err
2146
}
2147

2148
func (l *boundURIList) Set(v []fyne.URI) error {
2149
        l.lock.Lock()
2150
        *l.val = v
2151
        trigger, err := l.doReload()
2152
        l.lock.Unlock()
2153

2154
        if trigger {
2155
                l.trigger()
2156
        }
2157

2158
        return err
2159
}
2160

2161
func (l *boundURIList) doReload() (trigger bool, retErr error) {
2162
        oldLen := len(l.items)
2163
        newLen := len(*l.val)
2164
        if oldLen > newLen {
2165
                for i := oldLen - 1; i >= newLen; i-- {
2166
                        l.deleteItem(i)
2167
                }
2168
                trigger = true
2169
        } else if oldLen < newLen {
2170
                for i := oldLen; i < newLen; i++ {
2171
                        l.appendItem(bindURIListItem(l.val, i, l.updateExternal))
2172
                }
2173
                trigger = true
2174
        }
2175

2176
        for i, item := range l.items {
2177
                if i > oldLen || i > newLen {
2178
                        break
2179
                }
2180

2181
                var err error
2182
                if l.updateExternal {
2183
                        err = item.(*boundExternalURIListItem).setIfChanged((*l.val)[i])
2184
                } else {
2185
                        err = item.(*boundURIListItem).doSet((*l.val)[i])
2186
                }
2187
                if err != nil {
2188
                        retErr = err
2189
                }
2190
        }
2191
        return
2192
}
2193

2194
func (l *boundURIList) SetValue(i int, v fyne.URI) error {
2195
        l.lock.RLock()
2196
        len := l.Length()
2197
        l.lock.RUnlock()
2198

2199
        if i < 0 || i >= len {
2200
                return errOutOfBounds
2201
        }
2202

2203
        l.lock.Lock()
2204
        (*l.val)[i] = v
2205
        l.lock.Unlock()
2206

2207
        item, err := l.GetItem(i)
2208
        if err != nil {
2209
                return err
2210
        }
2211
        return item.(URI).Set(v)
2212
}
2213

2214
func bindURIListItem(v *[]fyne.URI, i int, external bool) URI {
2215
        if external {
2216
                ret := &boundExternalURIListItem{old: (*v)[i]}
2217
                ret.val = v
2218
                ret.index = i
2219
                return ret
2220
        }
2221

2222
        return &boundURIListItem{val: v, index: i}
2223
}
2224

2225
type boundURIListItem struct {
2226
        base
2227

2228
        val   *[]fyne.URI
2229
        index int
2230
}
2231

2232
func (b *boundURIListItem) Get() (fyne.URI, error) {
2233
        b.lock.Lock()
2234
        defer b.lock.Unlock()
2235

2236
        if b.index < 0 || b.index >= len(*b.val) {
2237
                return fyne.URI(nil), errOutOfBounds
2238
        }
2239

2240
        return (*b.val)[b.index], nil
2241
}
2242

2243
func (b *boundURIListItem) Set(val fyne.URI) error {
2244
        return b.doSet(val)
2245
}
2246

2247
func (b *boundURIListItem) doSet(val fyne.URI) error {
2248
        b.lock.Lock()
2249
        (*b.val)[b.index] = val
2250
        b.lock.Unlock()
2251

2252
        b.trigger()
2253
        return nil
2254
}
2255

2256
type boundExternalURIListItem struct {
2257
        boundURIListItem
2258

2259
        old fyne.URI
2260
}
2261

2262
func (b *boundExternalURIListItem) setIfChanged(val fyne.URI) error {
2263
        b.lock.Lock()
2264
        if compareURI(val, b.old) {
2265
                b.lock.Unlock()
2266
                return nil
2267
        }
2268
        (*b.val)[b.index] = val
2269
        b.old = val
2270

2271
        b.lock.Unlock()
2272
        b.trigger()
2273
        return nil
2274
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc