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.SetAttr(tomo.ALayout(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")) container.leftSpacer.SetTag("left", true) container.rightSpacer = tomo.NewBox() container.rightSpacer.SetRole(tomo.R("objects", "TabSpacer")) container.rightSpacer.SetTag("left", true) 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.OnButtonDown(func (button input.Button) bool { if button != input.ButtonLeft { return false } this.Activate(name) return true }) tab.OnButtonUp(func (button input.Button) bool { if button != input.ButtonLeft { return false } return true }) 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.SetAttr(tomo.ALayout(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")) this.SetTag("active", false) } else { this.SetRole(tomo.R("objects", "Tab")) this.SetTag("active", true) } }