ui/tabbedview.go
Maarten Heremans 864255113c Initial Commit
2024-03-30 17:45:07 +01:00

186 lines
3.3 KiB
Go

package ui
import (
"sync"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
)
type TabbedView struct {
*BaseView
// The array of child views
tabViews []View
// The current active view
currentTabView View
// The tabs
tabs *container.AppTabs
// The location of teh tabs in the view
tabLocation container.TabLocation
mu sync.Mutex
}
// NewTabbedView creates a new tabbed view
func NewTabbedView(
controller Controller,
tabLocation container.TabLocation,
tabview ...View,
) *TabbedView {
v := new(TabbedView)
v.BaseView = NewBaseView(v, controller)
v.tabViews = tabview
v.tabLocation = tabLocation
return v
}
func (v *TabbedView) Initialize() fyne.CanvasObject {
v.buildUI()
return v.BaseView.Initialize()
}
func (v *TabbedView) OnShow() {
v.BaseView.OnShow()
if v.currentTabView != nil {
v.currentTabView.OnShow()
}
}
func (v *TabbedView) OnHide() {
if v.currentTabView != nil {
v.currentTabView.OnHide()
}
v.BaseView.OnHide()
}
func (v *TabbedView) Refresh() {
if v.currentTabView != nil {
v.currentTabView.Refresh()
}
v.BaseView.Refresh()
}
func (v *TabbedView) Append(tabview ...View) {
v.mu.Lock()
defer v.mu.Unlock()
v.tabViews = append(v.tabViews, tabview...)
for _, tv := range tabview {
v.tabs.Append(container.NewTabItem(
tv.Title(), tv.Initialize()))
}
}
func (v *TabbedView) RemoveActive() {
currIdx := v.tabs.SelectedIndex()
v.Remove(currIdx)
}
func (v *TabbedView) Remove(idx int) {
if idx < 0 || idx >= len(v.tabViews) {
return
}
curIdx := v.tabs.SelectedIndex()
isCurrent := (curIdx == idx) && (v.currentTabView != nil)
v.mu.Lock()
defer v.mu.Unlock()
if isCurrent {
v.currentTabView.OnHide()
v.currentTabView = nil
}
v.tabViews = append(v.tabViews[0:curIdx], v.tabViews[curIdx+1:]...)
v.tabs.RemoveIndex(idx)
if isCurrent {
if idx > 0 {
idx = idx - 1
}
if idx < len(v.tabViews) {
v.tabs.SelectIndex(curIdx)
}
}
}
func (v *TabbedView) NumTabs() int {
return len(v.tabViews)
}
func (v *TabbedView) TabIndex(view View) int {
for idx, tv := range v.tabViews {
if tv.Equals(view) {
return idx
}
}
return -1
}
func (v *TabbedView) SelectTabIndex(index int) {
v.tabs.SelectIndex(index)
}
func (v *TabbedView) SelectTab(view View) {
v.SelectTabIndex(v.TabIndex(view))
}
func (v *TabbedView) buildUI() {
v.tabs = container.NewAppTabs()
v.tabs.SetTabLocation(v.tabLocation)
v.tabs.OnSelected = func(tab *container.TabItem) {
LogWindowEventMessage(
v, OnTabSelected,
"Selected tab: %s",
tab.Text,
)
go func() {
v.mu.Lock()
defer v.mu.Unlock()
idx := v.tabs.SelectedIndex()
if idx < 0 || idx >= len(v.tabViews) {
return
}
v.currentTabView = v.tabViews[idx]
v.currentTabView.OnShow()
}()
}
v.tabs.OnUnselected = func(tab *container.TabItem) {
LogWindowEventMessage(
v, OnTabUnselected,
"Unselected tab: %s",
tab.Text,
)
go func() {
v.mu.Lock()
defer v.mu.Unlock()
idx := v.tabs.SelectedIndex()
if idx < 0 || idx >= len(v.tabViews) {
return
}
if v.currentTabView != nil && v.currentTabView.Equals(v.tabViews[idx]) {
v.currentTabView.OnHide()
v.currentTabView = nil
}
}()
}
for _, tv := range v.tabViews {
v.tabs.Append(container.NewTabItem(tv.Title(), tv.Initialize()))
}
if len(v.tabViews) > 0 {
v.currentTabView = v.tabViews[0]
}
v.CanvasObject = v.tabs
}