-
Notifications
You must be signed in to change notification settings - Fork 1
/
tabs.go
130 lines (109 loc) · 3.32 KB
/
tabs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package goey
import (
"bitbucket.org/rj/goey/base"
)
var (
tabsKind = base.NewKind("bitbucket.org/rj/goey.Tabs")
)
// Tabs describes a widget that shows a tabs.
//
// The size of the control will match the size of the currently selected child
// element, although padding will added as required to provide space for the
// border and the tabs. However, when the user switches tabs, a relayout of
// the entire window is not forced.
//
// When calling UpdateProps, setting Value to an integer less than zero will
// leave the currently selected tab unchanged.
type Tabs struct {
Value int // Index of the selected tab
Children []TabItem // Description of the tabs
Insets Insets // Space between edge of element and the child element.
OnChange func(int) // OnChange will be called whenever the user selects a different tab
}
// TabItem describes a tab for a Tab widget.
type TabItem struct {
Caption string // Text to describe the contents of this tab
Child base.Widget // Child widget for the tab
}
// Kind returns the concrete type for use in the Widget interface.
// Users should not need to use this method directly.
func (*Tabs) Kind() *base.Kind {
return &tabsKind
}
// Mount creates a tabs control in the GUI.
// The newly created widget will be a child of the widget specified by parent.
func (w *Tabs) Mount(parent base.Control) (base.Element, error) {
// Ensure that the Value is a useable index.
if w.Value < 0 {
w.Value = 0
}
w.UpdateValue()
// Forward to the platform-dependant code
return w.mount(parent)
}
// UpdateValue ensures that the index for the currently selected tab is with
// the allowed range.
func (w *Tabs) UpdateValue() {
if w.Value >= len(w.Children) {
w.Value = len(w.Children) - 1
}
}
func (*tabsElement) Kind() *base.Kind {
return &tabsKind
}
func (w *tabsElement) Layout(bc base.Constraints) base.Size {
insets := w.controlInsets()
insets.X += w.insets.Left + w.insets.Right
insets.Y += w.insets.Top + w.insets.Bottom
if w.child == nil {
return bc.Constrain(base.Size{
Width: insets.X,
Height: insets.Y,
})
}
size := w.child.Layout(bc.Inset(insets.X, insets.Y))
return base.Size{
Width: size.Width + insets.X,
Height: size.Height + insets.Y,
}
}
func (w *tabsElement) MinIntrinsicHeight(width base.Length) base.Length {
insets := w.controlInsets()
insets.X += w.insets.Left + w.insets.Right
insets.Y += w.insets.Top + w.insets.Bottom
if w.child == nil {
return insets.Y
}
if width == base.Inf {
return w.child.MinIntrinsicHeight(base.Inf) + insets.Y
}
return w.child.MinIntrinsicHeight(width - insets.X)
}
func (w *tabsElement) MinIntrinsicWidth(height base.Length) base.Length {
insets := w.controlInsets()
insets.X += w.insets.Left + w.insets.Right
insets.Y += w.insets.Top + w.insets.Bottom
if w.child == nil {
return insets.X
}
if height == base.Inf {
return max(
w.controlTabsMinWidth(),
w.child.MinIntrinsicWidth(base.Inf)+insets.X,
)
}
return max(
w.controlTabsMinWidth(),
w.child.MinIntrinsicWidth(height-insets.Y),
)
}
func (w *tabsElement) UpdateProps(data base.Widget) error {
// Cast to correct type.
tabs := data.(*Tabs)
// Ensure that the Value is a useable index.
tabs.UpdateValue()
// Update properties.
// Forward to the platform-dependant code where necessary.
w.insets = tabs.Insets
return w.updateProps(tabs)
}