~pierrec/giox

ref: c164e218831e giox/widgetx/tabs.go -rw-r--r-- 1.8 KiB
c164e218Pierre Curto cm/iconx: update the set of icons 9 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package widgetx

import (
	"gioui.org/io/pointer"
	"gioui.org/layout"
	"gioui.org/widget"
)

// Tabs allows switching content from a list of label widgets.
type Tabs struct {
	List   layout.List
	clicks []widget.Clickable
	active int
}

func (ts *Tabs) init(n int) {
	if n > 0 && ts.active < 0 {
		// Set the first tab as the current one if none set.
		ts.SetActive(0)
	}
	ts.clicks = initClicks(ts.clicks, n)
}

func (ts *Tabs) update() {
	for i := range ts.clicks {
		for ts.clicks[i].Clicked() {
			ts.SetActive(i)
		}
	}
}

// SetActive sets the active tab to the one at index idx.
func (ts *Tabs) SetActive(idx int) {
	ts.active = idx + 1
}

// Active returns the index of the active tab.
func (ts *Tabs) Active() int {
	return ts.active - 1
}

// Remove removes the tab at index idx.
func (ts *Tabs) Remove(idx int) {
	n := len(ts.clicks) - 1
	copy(ts.clicks[idx:], ts.clicks[idx+1:])
	ts.clicks[n] = widget.Clickable{}
	ts.clicks = ts.clicks[:n]
	if ts.Active() == idx {
		ts.active = idx - 1
	}
}

// Layout lays out the content and list of labels.
// content may be called with a negative index if there is no tab at all.
func (ts *Tabs) Layout(gtx layout.Context, n int, label, content layout.ListElement) layout.Dimensions {
	ts.init(n)
	ts.update()
	axis := layout.Horizontal
	if ts.List.Axis == layout.Horizontal {
		axis = layout.Vertical
	}
	return layout.Flex{
		Axis: axis,
	}.Layout(gtx,
		layout.Rigid(func(gtx layout.Context) layout.Dimensions {
			return ts.List.Layout(gtx, n, func(gtx layout.Context, idx int) layout.Dimensions {
				defer pointer.PassOp{}.Push(gtx.Ops).Pop()
				return ts.clicks[idx].Layout(gtx, func(gtx layout.Context) layout.Dimensions {
					return label(gtx, idx)
				})
			})
		}),
		layout.Flexed(1, func(gtx layout.Context) layout.Dimensions {
			return content(gtx, ts.Active())
		}),
	)
}