127 lines
2.9 KiB
Go
127 lines
2.9 KiB
Go
|
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(),
|
||
|
}
|
||
|
container.SetRole(tomo.R("objects", "TabbedContainer", ""))
|
||
|
container.SetLayout(layouts.Column { false, true } )
|
||
|
|
||
|
container.tabsRow = tomo.NewContainerBox()
|
||
|
container.tabsRow.SetRole(tomo.R("objects", "TabRow", ""))
|
||
|
container.Add(container.tabsRow)
|
||
|
|
||
|
container.leftSpacer = tomo.NewBox()
|
||
|
container.leftSpacer.SetRole(tomo.R("objects", "TabSpacer", "left"))
|
||
|
container.rightSpacer = tomo.NewBox()
|
||
|
container.rightSpacer.SetRole(tomo.R("objects", "TabSpacer", "right"))
|
||
|
|
||
|
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,
|
||
|
}
|
||
|
tab.SetRole(tomo.R("objects", "Tab", ""))
|
||
|
tab.SetText(name)
|
||
|
tab.OnMouseDown(func (button input.Button) {
|
||
|
if button != input.ButtonLeft { return }
|
||
|
this.Activate(name)
|
||
|
})
|
||
|
|
||
|
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
|
||
|
this.tabsRow.SetLayout(row)
|
||
|
}
|
||
|
|
||
|
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 {
|
||
|
this.SetRole(tomo.R("objects", "Tab", "active"))
|
||
|
} else {
|
||
|
this.SetRole(tomo.R("objects", "Tab", ""))
|
||
|
}
|
||
|
}
|
||
|
|