gime/ui/ui.go
2023-01-06 09:34:55 -06:00

129 lines
2.5 KiB
Go

package ui
import (
"fmt"
"os"
"time"
"git.bullercodeworks.com/brian/gime/cli"
"git.bullercodeworks.com/brian/wandle"
"github.com/nsf/termbox-go"
)
// Screen/Source Ids
const (
ListTimersId = ScreenMsgSource(iota << 8)
SettingsId
ErrorId
)
// Commands
const (
CmdCanceled = ScreenMsgCommand(iota)
CmdSaved
// Goto Screen Commands
CmdGotoSettings
CmdGotoTimerList
)
func RunTUI(p *cli.Program) error {
ui := NewUi(p)
ui.debug = true
if err := ui.Start(); err != nil {
return err
}
// Exiting
fmt.Printf("Done\n")
return nil
}
type Ui struct {
debug bool
wandle *wandle.Program
program *cli.Program
err error
screens map[ScreenMsgSource]wandle.Screen
prevScreen, currScreen ScreenMsgSource
}
func NewUi(p *cli.Program) *Ui {
ui := &Ui{
screens: make(map[ScreenMsgSource]wandle.Screen),
program: p,
err: p.Initialize(),
}
var s wandle.Screen
var sId ScreenMsgSource
if ui.err != nil {
s, sId = NewSettingsScreen(ui), SettingsId
} else {
if ui.err = ui.program.LoadTimerList(); ui.err != nil {
s, sId = NewSettingsScreen(ui), SettingsId
} else if ui.err = ui.program.LoadDoneList(); ui.err != nil {
s, sId = NewSettingsScreen(ui), SettingsId
} else {
s, sId = NewListTimersScreen(ui), ListTimersId
}
}
ui.screens[sId] = s
ui.currScreen = sId
ui.wandle = wandle.NewProgram(s)
ui.wandle.Style(wandle.NewStyle(
termbox.RGBToAttribute(uint8(0), uint8(255), uint8(0)),
termbox.RGBToAttribute(uint8(0), uint8(0), uint8(0)),
))
return ui
}
func (u *Ui) GotoScreen(id ScreenMsgSource) func() wandle.Msg {
u.prevScreen, u.currScreen = u.currScreen, id
if s, ok := u.screens[id]; ok {
return wandle.SwitchScreenCmd(s)
}
var s wandle.Screen
switch id {
case ListTimersId:
s = NewListTimersScreen(u)
case SettingsId:
s = NewSettingsScreen(u)
}
u.screens[id] = s
return wandle.SwitchScreenCmd(s)
}
func (u *Ui) CanGoBack() bool {
return u.prevScreen > 0
}
func (u *Ui) GoBack() func() wandle.Msg {
if !u.CanGoBack() {
return nil
}
return u.GotoScreen(u.prevScreen)
}
func (u *Ui) Log(v string) error {
f, err := os.OpenFile("gime.log", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
panic(err)
}
defer f.Close()
_, err = f.WriteString(fmt.Sprintf("%s: %s\n", time.Now().Format(time.RFC3339), v))
return err
}
func (u *Ui) Start() error {
return u.wandle.Start()
}
type ScreenMsg struct {
source ScreenMsgSource
command ScreenMsgCommand
data interface{}
err error
}
type ScreenMsgSource int
type ScreenMsgCommand int