Compare commits

..

No commits in common. "ce08487eff286a3c7640a6548de2f45b5094f3a8" and "8b80520f8c1ee09a7fe7adf05d14b81b12fdf225" have entirely different histories.

View File

@ -6,13 +6,13 @@ import "git.tebibyte.media/tomo/objects/layouts"
var _ tomo.Object = new(Notebook) var _ tomo.Object = new(Notebook)
// Notebook holds multiple objects, each in their own page. The user can click // Notebook holds multiple objects, each in their own tab. The user can click
// the tab bar at the top to choose which one is activated. // the tab bar at the top to choose which one is activated.
// //
// Sub-components: // Sub-components:
// - TabRow sits at the top of the container and contains a row of tabs. // - TabRow sits at the top of the container and contains a row of tabs.
// - TabSpacer sits at either end of the tab row, bookending the list of tabs. // - TabSpacer sits at either end of the tab row, bookending the list of tabs.
// - Tab appears in the tab row for each tab in the notebook. The user can // - Tab appears in the tab row for each tab in the container. The user can
// click on the tab to switch to it. // click on the tab to switch to it.
// //
// TabSpacer tags: // TabSpacer tags:
@ -20,39 +20,39 @@ var _ tomo.Object = new(Notebook)
// - [right] The spacer is on the right. // - [right] The spacer is on the right.
// //
// Tab tags: // Tab tags:
// - [active] The tab is currently active and its page is visible. // - [active] The tab is currently active and its contents are visible.
type Notebook struct { type Notebook struct {
box tomo.ContainerBox box tomo.ContainerBox
leftSpacer tomo.Box leftSpacer tomo.Box
rightSpacer tomo.Box rightSpacer tomo.Box
tabsRow tomo.ContainerBox tabsRow tomo.ContainerBox
active string active string
pages []*page tabs []*tab
} }
// NewNotebook creates a new tabbed notebook. // NewNotebook creates a new tabbed notebook.
func NewNotebook () *Notebook { func NewNotebook () *Notebook {
notebook := &Notebook { Notebook := &Notebook {
box: tomo.NewContainerBox(), box: tomo.NewContainerBox(),
} }
notebook.box.SetRole(tomo.R("objects", "Notebook")) Notebook.box.SetRole(tomo.R("objects", "Notebook"))
notebook.box.SetAttr(tomo.ALayout(layouts.Column { false, true })) Notebook.box.SetAttr(tomo.ALayout(layouts.Column { false, true }))
notebook.tabsRow = tomo.NewContainerBox() Notebook.tabsRow = tomo.NewContainerBox()
notebook.tabsRow.SetRole(tomo.R("objects", "TabRow")) Notebook.tabsRow.SetRole(tomo.R("objects", "TabRow"))
notebook.box.Add(notebook.tabsRow) Notebook.box.Add(Notebook.tabsRow)
notebook.leftSpacer = tomo.NewBox() Notebook.leftSpacer = tomo.NewBox()
notebook.leftSpacer.SetRole(tomo.R("objects", "TabSpacer")) Notebook.leftSpacer.SetRole(tomo.R("objects", "TabSpacer"))
notebook.leftSpacer.SetTag("left", true) Notebook.leftSpacer.SetTag("left", true)
notebook.rightSpacer = tomo.NewBox() Notebook.rightSpacer = tomo.NewBox()
notebook.rightSpacer.SetRole(tomo.R("objects", "TabSpacer")) Notebook.rightSpacer.SetRole(tomo.R("objects", "TabSpacer"))
notebook.rightSpacer.SetTag("right", true) Notebook.rightSpacer.SetTag("right", true)
notebook.Clear() Notebook.ClearTabs()
notebook.setTabRowLayout() Notebook.setTabRowLayout()
return notebook return Notebook
} }
// GetBox returns the underlying box. // GetBox returns the underlying box.
@ -60,7 +60,7 @@ func (this *Notebook) GetBox () tomo.Box {
return this.box return this.box
} }
// Activate switches to a named page. // Activate switches to a named tab.
func (this *Notebook) Activate (name string) { func (this *Notebook) Activate (name string) {
if _, tab := this.findTab(this.active); tab != nil { if _, tab := this.findTab(this.active); tab != nil {
tab.setActive(false) tab.setActive(false)
@ -75,82 +75,82 @@ func (this *Notebook) Activate (name string) {
this.active = name this.active = name
} }
// Add adds an object as a page with the specified name. // AddTab adds an object as a tab with the specified name.
func (this *Notebook) Add (name string, root tomo.Object) { func (this *Notebook) AddTab (name string, root tomo.Object) {
pag := &page { tab := &tab {
TextBox: tomo.NewTextBox(), TextBox: tomo.NewTextBox(),
name: name, name: name,
root: root, root: root,
} }
pag.SetRole(tomo.R("objects", "Tab")) tab.SetRole(tomo.R("objects", "Tab"))
pag.SetText(name) tab.SetText(name)
pag.OnButtonDown(func (button input.Button) bool { tab.OnButtonDown(func (button input.Button) bool {
if button != input.ButtonLeft { return false } if button != input.ButtonLeft { return false }
this.Activate(name) this.Activate(name)
return true return true
}) })
pag.OnButtonUp(func (button input.Button) bool { tab.OnButtonUp(func (button input.Button) bool {
if button != input.ButtonLeft { return false } if button != input.ButtonLeft { return false }
return true return true
}) })
this.pages = append(this.pages, pag) this.tabs = append(this.tabs, tab)
this.tabsRow.Insert(pag, this.rightSpacer) this.tabsRow.Insert(tab, this.rightSpacer)
this.setTabRowLayout() this.setTabRowLayout()
// if the row was empty before, activate this tab // if the row was empty before, activate this tab
if len(this.pages) == 1 { if len(this.tabs) == 1 {
this.Activate(name) this.Activate(name)
} }
} }
// Remove removes the named page. // RemoveTab removes the named tab.
func (this *Notebook) Remove (name string) { func (this *Notebook) RemoveTab (name string) {
index, tab := this.findTab(name) index, tab := this.findTab(name)
if index < 0 { return } if index < 0 { return }
nextIndex := index - 1 nextIndex := index - 1
this.tabsRow.Remove(tab) this.tabsRow.Remove(tab)
this.pages = append(this.pages[:index], this.pages[index - 1:]...) this.tabs = append(this.tabs[:index], this.tabs[index - 1:]...)
this.setTabRowLayout() this.setTabRowLayout()
if nextIndex < 0 { nextIndex = 0 } if nextIndex < 0 { nextIndex = 0 }
if nextIndex >= len(this.pages) { nextIndex = len(this.pages) - 1 } if nextIndex >= len(this.tabs) { nextIndex = len(this.tabs) - 1 }
if nextIndex < 0 { if nextIndex < 0 {
this.Activate("") this.Activate("")
} else { } else {
this.Activate(this.pages[nextIndex].name) this.Activate(this.tabs[nextIndex].name)
} }
} }
// Clear removes all tabs. // ClearTabs removes all tabs.
func (this *Notebook) Clear () { func (this *Notebook) ClearTabs () {
this.pages = nil this.tabs = nil
this.tabsRow.Clear() this.tabsRow.Clear()
this.tabsRow.Add(this.leftSpacer) this.tabsRow.Add(this.leftSpacer)
this.tabsRow.Add(this.rightSpacer) this.tabsRow.Add(this.rightSpacer)
} }
func (this *Notebook) setTabRowLayout () { func (this *Notebook) setTabRowLayout () {
row := make(layouts.Row, 1 + len(this.pages) + 1) row := make(layouts.Row, 1 + len(this.tabs) + 1)
row[len(row) - 1] = true row[len(row) - 1] = true
this.tabsRow.SetAttr(tomo.ALayout(row)) this.tabsRow.SetAttr(tomo.ALayout(row))
} }
func (this *Notebook) findTab (name string) (int, *page) { func (this *Notebook) findTab (name string) (int, *tab) {
for index, pag := range this.pages { for index, tab := range this.tabs {
if pag.name == name { return index, pag } if tab.name == name { return index, tab }
} }
return -1, nil return -1, nil
} }
type page struct { type tab struct {
tomo.TextBox tomo.TextBox
name string name string
root tomo.Object root tomo.Object
} }
func (this *page) setActive (active bool) { func (this *tab) setActive (active bool) {
if active { if active {
this.SetRole(tomo.R("objects", "Tab")) this.SetRole(tomo.R("objects", "Tab"))
this.SetTag("active", true) this.SetTag("active", true)