68 lines
1.7 KiB
Go
68 lines
1.7 KiB
Go
|
|
package ui
|
||
|
|
|
||
|
|
import (
|
||
|
|
tea "github.com/charmbracelet/bubbletea"
|
||
|
|
"github.com/charmbracelet/lipgloss"
|
||
|
|
|
||
|
|
"github.com/gmgauthier/gralculator/internal/calc"
|
||
|
|
)
|
||
|
|
|
||
|
|
// App is the root Bubble Tea model for the gralculator TUI.
|
||
|
|
// Phase 1/3 skeleton only — real implementation in phase 3.
|
||
|
|
type App struct {
|
||
|
|
engine *calc.Engine
|
||
|
|
width int
|
||
|
|
height int
|
||
|
|
|
||
|
|
// flash state etc. will be added during spike (see gostations patterns)
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewApp() *App {
|
||
|
|
return &App{
|
||
|
|
engine: calc.NewEngine(),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (a *App) Init() tea.Cmd {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (a *App) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||
|
|
switch msg := msg.(type) {
|
||
|
|
case tea.WindowSizeMsg:
|
||
|
|
a.width = msg.Width
|
||
|
|
a.height = msg.Height
|
||
|
|
case tea.KeyMsg:
|
||
|
|
switch msg.String() {
|
||
|
|
case "q", "ctrl+c", "esc":
|
||
|
|
return a, tea.Quit
|
||
|
|
case "tab":
|
||
|
|
// Will drive engine.CycleBase() + possible CERR flash
|
||
|
|
_ = a.engine.CycleBase()
|
||
|
|
// TODO (phase 3): trigger flash on error, re-render small row
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return a, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (a *App) View() string {
|
||
|
|
// Placeholder view. Real two-row display + keypad grid in phase 3.
|
||
|
|
// Will use lipgloss heavily for:
|
||
|
|
// - large number area (tall + styled)
|
||
|
|
// - small current-base row (highlighted label)
|
||
|
|
// - centered content card (lipgloss.Place)
|
||
|
|
// - button cells for keypad (including single "BASE")
|
||
|
|
// - flash styles (140ms color 63)
|
||
|
|
// - minimal hint row
|
||
|
|
base := a.engine.CurrentBase()
|
||
|
|
return lipgloss.NewStyle().Padding(1, 2).Render(
|
||
|
|
"gralculator skeleton\n\n" +
|
||
|
|
"Large number area (TODO)\n" +
|
||
|
|
"Current base: " + string(base) + " (press Tab to cycle)\n\n" +
|
||
|
|
"See docs/UI_DESIGN.md and spec.md",
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
// TODO (phase 3): full model with flashes, proper display rendering,
|
||
|
|
// keypad grid, Tab + other key handling wired to engine, resize/centering.
|