-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcomponent_tabs.v
172 lines (153 loc) · 3.36 KB
/
component_tabs.v
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
module uicomponent
import ui
import gx
enum Mode {
vertical
horizontal
accordion
}
[heap]
struct Tabs {
pub mut:
id string
layout &ui.Stack // required
active string
tab_bar &ui.Stack
pages map[string]ui.Widget
mode Mode
tab_width f64
tab_height f64
tab_spacing f64
// To become a component of a parent component
component voidptr
}
[params]
pub struct TabsConfig {
id string
mode Mode = .vertical
active int
tabs []string
pages []ui.Widget
tab_width f64 = 50.0
tab_height f64 = 30.0
tab_spacing f64 = 5.0
}
pub fn tabs(c TabsConfig) &ui.Stack {
mut children := []ui.Widget{}
for i, tab in c.tabs {
children << ui.canvas_layout(
id: tab_id(c.id, i)
on_click: tab_click
on_key_down: tab_key_down
children: [
ui.at(0, 0, ui.label(text: tab)),
]
)
}
// Layout
mut tab_bar := ui.row(
id: '${c.id}_tabbar'
widths: c.tab_width
heights: c.tab_height
spacing: c.tab_spacing
children: children
)
mut m_pages := map[string]ui.Widget{}
for i, page in c.pages {
m_pages[tab_id(c.id, i)] = page
}
tab_active := tab_id(c.id, c.active)
println('active: $tab_active')
mut layout := ui.column(
id: c.id
widths: [ui.compact, ui.stretch]
heights: [ui.compact, ui.stretch]
children: [
tab_bar,
m_pages[tab_active],
]
)
mut tabs := &Tabs{
id: c.id
layout: layout
active: tab_active
tab_bar: tab_bar
pages: m_pages
mode: c.mode
tab_width: c.tab_width
tab_height: c.tab_height
tab_spacing: c.tab_spacing
}
for i, mut page in c.pages {
if mut page is ui.Stack {
ui.component_connect(tabs, page)
} else if mut page is ui.CanvasLayout {
ui.component_connect(tabs, page)
}
mut tab := tab_bar.children[i]
if mut tab is ui.CanvasLayout {
ui.component_connect(tabs, tab)
}
}
ui.component_connect(tabs, layout, tab_bar)
layout.component_init = tabs_init
return layout
}
pub fn component_tabs(w ui.ComponentChild) &Tabs {
return &Tabs(w.component)
}
fn tabs_init(layout &ui.Stack) {
mut tabs := component_tabs(layout)
for id, mut page in tabs.pages {
println('tab $id initialized')
page.init(layout)
}
tabs.update_tab_colors()
// set width and height of tab
// for mut tab in tabs.tab_bar.children {
// tab.width =
// }
tabs.layout.update_layout()
}
fn tab_key_down(e ui.KeyEvent, c &ui.CanvasLayout) {
if e.key in [.up, .down] {
mut tabs := component_tabs(c)
tabs.transpose()
}
}
fn tab_click(e ui.MouseEvent, c &ui.CanvasLayout) {
mut tabs := component_tabs(c)
// println("selected $c.id")
tabs.layout.children[1] = tabs.pages[c.id]
tabs.layout.update_layout()
win := tabs.layout.ui.window
win.update_layout()
// set current
tabs.active = c.id
tabs.update_tab_colors()
}
fn tab_id(id string, i int) string {
return '${id}_tab_$i'
}
fn (tabs &Tabs) update_tab_colors() {
for tab in tabs.tab_bar.children {
if mut tab is ui.CanvasLayout {
color := if tab.id == tabs.active { gx.rgb(200, 200, 100) } else { gx.white }
// println("$tab.id == $tabs.active -> $color")
tab.bg_color = color
}
}
}
fn (mut tabs Tabs) transpose() {
if tabs.mode in [.vertical, .horizontal] {
if tabs.mode == .vertical {
tabs.mode = .horizontal
} else {
tabs.mode = .vertical
}
tabs.tab_bar.transpose(false)
tabs.tab_bar.update_layout()
tabs.layout.transpose(false)
tabs.layout.update_layout()
}
}