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 // ListTimers Commands CmdArchiveTimer // Goto Screen Commands CmdGotoSettings CmdGotoTimerList ) // Styles var ( DefaultStyle = wandle.NewStyle( termbox.RGBToAttribute(uint8(0), uint8(255), uint8(0)), termbox.RGBToAttribute(uint8(0), uint8(0), uint8(0)), ) ErrStyle = wandle.NewStyle( termbox.RGBToAttribute(uint8(255), uint8(0), uint8(0)), termbox.RGBToAttribute(uint8(0), uint8(0), uint8(0)), ) ) 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(DefaultStyle) 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