objects/tabbedcontainer.go

136 lines
3.2 KiB
Go
Raw Normal View History

2024-06-22 13:38:14 -06:00
package objects
import "git.tebibyte.media/tomo/tomo"
import "git.tebibyte.media/tomo/tomo/input"
import "git.tebibyte.media/tomo/objects/layouts"
type TabbedContainer struct {
tomo.ContainerBox
leftSpacer tomo.Box
rightSpacer tomo.Box
tabsRow tomo.ContainerBox
active string
tabs []*tab
}
func NewTabbedContainer () *TabbedContainer {
container := &TabbedContainer {
ContainerBox: tomo.NewContainerBox(),
}
2024-07-21 09:48:28 -06:00
container.SetRole(tomo.R("objects", "TabbedContainer"))
2024-07-25 10:58:38 -06:00
container.SetAttr(tomo.ALayout(layouts.Column { false, true }))
2024-06-22 13:38:14 -06:00
container.tabsRow = tomo.NewContainerBox()
2024-07-21 09:48:28 -06:00
container.tabsRow.SetRole(tomo.R("objects", "TabRow"))
2024-06-22 13:38:14 -06:00
container.Add(container.tabsRow)
container.leftSpacer = tomo.NewBox()
2024-07-21 09:48:28 -06:00
container.leftSpacer.SetRole(tomo.R("objects", "TabSpacer"))
container.leftSpacer.SetTag("left", true)
2024-06-22 13:38:14 -06:00
container.rightSpacer = tomo.NewBox()
2024-07-21 09:48:28 -06:00
container.rightSpacer.SetRole(tomo.R("objects", "TabSpacer"))
container.rightSpacer.SetTag("left", true)
2024-06-22 13:38:14 -06:00
container.ClearTabs()
container.setTabRowLayout()
return container
}
func (this *TabbedContainer) Activate (name string) {
if _, tab := this.findTab(this.active); tab != nil {
tab.setActive(false)
this.Remove(tab.root)
}
if _, tab := this.findTab(name); tab != nil {
tab.setActive(true)
this.Add(tab.root)
} else {
name = ""
}
this.active = name
}
func (this *TabbedContainer) AddTab (name string, root tomo.Object) {
tab := &tab {
TextBox: tomo.NewTextBox(),
name: name,
root: root,
}
2024-07-21 09:48:28 -06:00
tab.SetRole(tomo.R("objects", "Tab"))
2024-06-22 13:38:14 -06:00
tab.SetText(name)
2024-07-25 10:58:38 -06:00
tab.OnButtonDown(func (button input.Button) bool {
if button != input.ButtonLeft { return false }
2024-06-22 13:38:14 -06:00
this.Activate(name)
2024-07-25 10:58:38 -06:00
return true
})
tab.OnButtonUp(func (button input.Button) bool {
if button != input.ButtonLeft { return false }
return true
2024-06-22 13:38:14 -06:00
})
this.tabs = append(this.tabs, tab)
this.tabsRow.Insert(tab, this.rightSpacer)
this.setTabRowLayout()
// if the row was empty before, activate this tab
if len(this.tabs) == 1 {
this.Activate(name)
}
}
func (this *TabbedContainer) RemoveTab (name string) {
index, tab := this.findTab(name)
if index < 0 { return }
nextIndex := index - 1
this.tabsRow.Remove(tab)
this.tabs = append(this.tabs[:index], this.tabs[index - 1:]...)
this.setTabRowLayout()
if nextIndex < 0 { nextIndex = 0 }
if nextIndex >= len(this.tabs) { nextIndex = len(this.tabs) - 1 }
if nextIndex < 0 {
this.Activate("")
} else {
this.Activate(this.tabs[nextIndex].name)
}
}
func (this *TabbedContainer) ClearTabs () {
this.tabs = nil
this.tabsRow.Clear()
this.tabsRow.Add(this.leftSpacer)
this.tabsRow.Add(this.rightSpacer)
}
func (this *TabbedContainer) setTabRowLayout () {
row := make(layouts.Row, 1 + len(this.tabs) + 1)
row[len(row) - 1] = true
2024-07-25 10:58:38 -06:00
this.tabsRow.SetAttr(tomo.ALayout(row))
2024-06-22 13:38:14 -06:00
}
func (this *TabbedContainer) findTab (name string) (int, *tab) {
for index, tab := range this.tabs {
if tab.name == name { return index, tab }
}
return -1, nil
}
type tab struct {
tomo.TextBox
name string
root tomo.Object
}
func (this *tab) setActive (active bool) {
if active {
2024-07-21 09:48:28 -06:00
this.SetRole(tomo.R("objects", "Tab"))
this.SetTag("active", true)
2024-06-22 13:38:14 -06:00
} else {
2024-07-21 09:48:28 -06:00
this.SetRole(tomo.R("objects", "Tab"))
this.SetTag("active", false)
2024-06-22 13:38:14 -06:00
}
}