2022-03-27 00:01:24 +00:00
|
|
|
package modal
|
|
|
|
|
|
|
|
import (
|
|
|
|
tea "github.com/charmbracelet/bubbletea"
|
2022-07-28 11:36:16 +00:00
|
|
|
"github.com/lmika/audax/internal/dynamo-browse/ui/teamodels/layout"
|
|
|
|
"github.com/lmika/audax/internal/dynamo-browse/ui/teamodels/utils"
|
2022-03-27 00:01:24 +00:00
|
|
|
"log"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Modal is a tea model which displays modes on a stack. Only the top-level model is display and will receive
|
|
|
|
// keyboard and mouse events.
|
|
|
|
type Modal struct {
|
|
|
|
baseMode tea.Model
|
|
|
|
modeStack []tea.Model
|
|
|
|
}
|
|
|
|
|
|
|
|
func New(baseMode tea.Model) Modal {
|
|
|
|
return Modal{baseMode: baseMode}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m Modal) Init() tea.Cmd {
|
2022-03-27 04:53:58 +00:00
|
|
|
return m.baseMode.Init()
|
2022-03-27 00:01:24 +00:00
|
|
|
}
|
|
|
|
|
2022-03-27 04:53:58 +00:00
|
|
|
// Push pushes a new model onto the modal stack
|
|
|
|
func (m *Modal) Push(model tea.Model) {
|
2022-03-27 00:01:24 +00:00
|
|
|
m.modeStack = append(m.modeStack, model)
|
|
|
|
log.Printf("pusing new mode: len = %v", len(m.modeStack))
|
|
|
|
}
|
|
|
|
|
2022-03-27 04:53:58 +00:00
|
|
|
// Pop pops a model from the stack
|
|
|
|
func (m *Modal) Pop() (p tea.Model) {
|
2022-03-27 00:01:24 +00:00
|
|
|
if len(m.modeStack) > 0 {
|
2022-03-27 04:53:58 +00:00
|
|
|
p = m.modeStack[len(m.modeStack)-1]
|
2022-03-27 00:01:24 +00:00
|
|
|
m.modeStack = m.modeStack[:len(m.modeStack)-1]
|
2022-03-27 04:53:58 +00:00
|
|
|
return p
|
2022-03-27 00:01:24 +00:00
|
|
|
}
|
2022-03-27 04:53:58 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Len returns the number of models on the mode stack
|
|
|
|
func (m Modal) Len() int {
|
|
|
|
return len(m.modeStack)
|
2022-03-27 00:01:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m Modal) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
|
|
var cc utils.CmdCollector
|
|
|
|
|
|
|
|
switch msg := msg.(type) {
|
|
|
|
case tea.KeyMsg, tea.MouseMsg:
|
|
|
|
// only notify top level stack
|
|
|
|
if len(m.modeStack) > 0 {
|
|
|
|
m.modeStack[len(m.modeStack)-1] = cc.Collect(m.modeStack[len(m.modeStack)-1].Update(msg))
|
|
|
|
} else {
|
|
|
|
m.baseMode = cc.Collect(m.baseMode.Update(msg))
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
// notify all modes of other events
|
|
|
|
// TODO: is this right?
|
|
|
|
m.baseMode = cc.Collect(m.baseMode.Update(msg))
|
|
|
|
for i, s := range m.modeStack {
|
|
|
|
m.modeStack[i] = cc.Collect(s.Update(msg))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return m, cc.Cmd()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m Modal) View() string {
|
|
|
|
// only show top level mode
|
|
|
|
if len(m.modeStack) > 0 {
|
|
|
|
log.Printf("viewing mode stack: len = %v", len(m.modeStack))
|
|
|
|
return m.modeStack[len(m.modeStack)-1].View()
|
|
|
|
}
|
|
|
|
return m.baseMode.View()
|
|
|
|
}
|
2022-03-27 04:53:58 +00:00
|
|
|
|
|
|
|
func (m Modal) Resize(w, h int) layout.ResizingModel {
|
|
|
|
m.baseMode = layout.Resize(m.baseMode, w, h)
|
|
|
|
for i := range m.modeStack {
|
|
|
|
m.modeStack[i] = layout.Resize(m.modeStack[i], w, h)
|
|
|
|
}
|
|
|
|
return m
|
|
|
|
}
|