From 3fe1ca0474f206335a4efb8be84ae3696a9d8938 Mon Sep 17 00:00:00 2001 From: Erik Winter Date: Sun, 24 Dec 2023 13:33:15 +0100 Subject: [PATCH] tabset --- cmd/terminal-client/tui/basemodel.go | 69 +++++++------------------- cmd/terminal-client/tui/tabset.go | 74 ++++++++++++++++++++++++++++ cmd/terminal-client/tui/tui.go | 9 +--- 3 files changed, 93 insertions(+), 59 deletions(-) create mode 100644 cmd/terminal-client/tui/tabset.go diff --git a/cmd/terminal-client/tui/basemodel.go b/cmd/terminal-client/tui/basemodel.go index 9e3d8be..ca0494c 100644 --- a/cmd/terminal-client/tui/basemodel.go +++ b/cmd/terminal-client/tui/basemodel.go @@ -13,8 +13,7 @@ import ( type baseModel struct { emdb *client.EMDB tmdb *client.TMDB - Tabs []string - TabContent tea.Model + tabs *TabSet activeTab int initialized bool logger *Logger @@ -31,7 +30,7 @@ func NewBaseModel(emdb *client.EMDB, tmdb *client.TMDB, logger *Logger) (tea.Mod m := baseModel{ emdb: emdb, tmdb: tmdb, - Tabs: []string{"Erik's movie database", "The movie database"}, + tabs: NewTabSet(), logViewport: logViewport, logger: logger, } @@ -54,19 +53,22 @@ func (m baseModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case "ctrl+c", "q", "esc": return m, tea.Quit case "right", "tab": - m.TabContent, cmd = m.nextTab() - cmds = append(cmds, cmd) - return m, tea.Batch(cmds...) + m.tabs.Next() case "left", "shift+tab": - m.TabContent, cmd = m.prevTab() - cmds = append(cmds, cmd) - return m, tea.Batch(cmds...) + m.tabs.Previous() + default: + cmds = append(cmds, m.tabs.Update(msg)) } case tea.WindowSizeMsg: m.windowSize = msg if !m.initialized { - m.TabContent, cmd = NewTabEMDB(m.emdb, m.logger) + var emdbTab, tmdbTab tea.Model + emdbTab, cmd = NewTabEMDB(m.emdb, m.logger) cmds = append(cmds, cmd) + tmdbTab, cmd = NewTabTMDB(m.tmdb, m.logger) + cmds = append(cmds, cmd) + m.tabs.AddTab("emdb", "EMDB", emdbTab) + m.tabs.AddTab("tmdb", "TMDB", tmdbTab) m.initialized = true } m.Log(fmt.Sprintf("new window size: %dx%d", msg.Width, msg.Height)) @@ -75,14 +77,12 @@ func (m baseModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { Width: m.contentSize.Width, Height: m.contentSize.Height, } - m.TabContent, cmd = m.TabContent.Update(tabSize) - cmds = append(cmds, cmd) + cmds = append(cmds, m.tabs.Update(tabSize)) m.Log("done with resize") + default: + cmds = append(cmds, m.tabs.Update(msg)) } - m.TabContent, cmd = m.TabContent.Update(msg) - cmds = append(cmds, cmd) - m.logViewport.SetContent(strings.Join(m.logger.Lines, "\n")) m.logViewport.GotoBottom() m.logViewport, cmd = m.logViewport.Update(msg) @@ -100,26 +100,14 @@ func (m baseModel) View() string { } doc := strings.Builder{} - doc.WriteString(m.renderMenu()) + doc.WriteString(lipgloss.PlaceHorizontal(m.contentSize.Width, lipgloss.Left, m.tabs.ViewMenu())) doc.WriteString("\n") - doc.WriteString(m.renderTabContent()) + doc.WriteString(m.tabs.ViewContent()) doc.WriteString("\n") doc.WriteString(m.renderLog()) return docStyle.Render(doc.String()) } -func (m *baseModel) nextTab() (tea.Model, tea.Cmd) { - m.activeTab = min(m.activeTab+1, len(m.Tabs)-1) - - return m.newTab() -} - -func (m *baseModel) prevTab() (tea.Model, tea.Cmd) { - m.activeTab = max(m.activeTab-1, 0) - - return m.newTab() -} - func (m *baseModel) newTab() (tea.Model, tea.Cmd) { switch m.activeTab { case 0: @@ -131,29 +119,6 @@ func (m *baseModel) newTab() (tea.Model, tea.Cmd) { } } -func (m *baseModel) renderMenu() string { - var items []string - for i, t := range m.Tabs { - if i == m.activeTab { - items = append(items, lipgloss.NewStyle(). - Foreground(colorHighLightForeGround). - Render(fmt.Sprintf(" * %s ", t))) - continue - } - - items = append(items, lipgloss.NewStyle(). - Foreground(colorNormalForeground). - Render(fmt.Sprintf(" %s ", t))) - } - - return lipgloss.PlaceHorizontal(m.contentSize.Width, lipgloss.Left, lipgloss.JoinHorizontal(lipgloss.Top, items...)) -} - -func (m *baseModel) renderTabContent() string { - content := m.TabContent.View() - return windowStyle.Width(m.contentSize.Width).Height(m.contentSize.Height).Render(content) -} - func (m *baseModel) renderLog() string { return windowStyle.Width(m.contentSize.Width).Height(logLineCount).Render(m.logViewport.View()) } diff --git a/cmd/terminal-client/tui/tabset.go b/cmd/terminal-client/tui/tabset.go new file mode 100644 index 0000000..af4459f --- /dev/null +++ b/cmd/terminal-client/tui/tabset.go @@ -0,0 +1,74 @@ +package tui + +import ( + "fmt" + + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" +) + +type TabSet struct { + active int + order []string + title map[string]string + tabs map[string]tea.Model +} + +func NewTabSet() *TabSet { + return &TabSet{ + order: make([]string, 0), + title: make(map[string]string), + tabs: make(map[string]tea.Model), + } +} + +func (t *TabSet) AddTab(name, title string, model tea.Model) { + t.order = append(t.order, name) + t.title[name] = title + t.tabs[name] = model +} + +func (t *TabSet) Next() { + t.active++ + if t.active > len(t.order)-1 { + t.active = 0 + } +} + +func (t *TabSet) Previous() { + t.active-- + if t.active < 0 { + t.active = len(t.order) - 1 + } +} + +func (t *TabSet) Update(msg tea.Msg) tea.Cmd { + var cmd tea.Cmd + name := t.order[t.active] + t.tabs[name], cmd = t.tabs[name].Update(msg) + + return cmd +} + +func (t *TabSet) ViewMenu() string { + var items []string + for i, name := range t.order { + if i == t.active { + items = append(items, lipgloss.NewStyle(). + Foreground(colorHighLightForeGround). + Render(fmt.Sprintf(" * %s ", t.title[name]))) + continue + } + + items = append(items, lipgloss.NewStyle(). + Foreground(colorNormalForeground). + Render(fmt.Sprintf(" %s ", t.title[name]))) + } + return lipgloss.JoinHorizontal(lipgloss.Top, items...) + + //return +} + +func (t *TabSet) ViewContent() string { + return t.tabs[t.order[t.active]].View() +} diff --git a/cmd/terminal-client/tui/tui.go b/cmd/terminal-client/tui/tui.go index a9c6a60..a276b69 100644 --- a/cmd/terminal-client/tui/tui.go +++ b/cmd/terminal-client/tui/tui.go @@ -31,13 +31,8 @@ func NewLogger() *Logger { } } -func (l *Logger) SetProgram(p *tea.Program) { - l.p = p -} - -func (l *Logger) Log(s string) { - l.Lines = append(l.Lines, s) -} +func (l *Logger) SetProgram(p *tea.Program) { l.p = p } +func (l *Logger) Log(s string) { l.Lines = append(l.Lines, s) } type TabSizeMsgType tea.WindowSizeMsg