diff --git a/cmd/gotime-cui/gotime-cui b/cmd/gotime-cui/gotime-cui index 49e53a9..bc198b6 100755 Binary files a/cmd/gotime-cui/gotime-cui and b/cmd/gotime-cui/gotime-cui differ diff --git a/cmd/gotime-cui/main.go b/cmd/gotime-cui/main.go index 9d42a36..7aae423 100644 --- a/cmd/gotime-cui/main.go +++ b/cmd/gotime-cui/main.go @@ -2,52 +2,79 @@ package main import ( "fmt" - "os" - "strconv" - "gogs.bullercodeworks.com/brian/gotime" + termbox "github.com/nsf/termbox-go" + "gogs.bullercodeworks.com/brian/user-config" ) +const AppName = "gotime" + func main() { - /* - err := termbox.Init() - if err != nil { - panic(err) - } - defer termbox.Close() - */ - dir := "/home/brbuller/.timewarrior/" + cfg, err := userConfig.NewConfig(AppName) - op := os.Args[1] - var id int - var err error - - if len(os.Args) > 2 { - id, err = strconv.Atoi(os.Args[2]) - if err != nil { - panic(err) - } + if cfg.Get("dir") != "" { + var dir string + fmt.Print("Timewarrior Data Directory: ") + fmt.Scanln(&dir) } - got := gotime.Create(dir) + err = termbox.Init() + if err != nil { + panic(err) + } + defer termbox.Close() + termbox.SetOutputMode(termbox.Output256) - switch op { - case "ls": - tmrs := got.GetAllTimers() - for i := range tmrs { - fmt.Println("@" + strconv.Itoa(tmrs[i].Id) + ": " + tmrs[i].ToString()) + style := defaultStyle() + mainLoop(style) + + /* + dir := "/home/brbuller/.timewarrior/" + + op := os.Args[1] + var id int + var err error + + if len(os.Args) > 2 { + id, err = strconv.Atoi(os.Args[2]) + if err != nil { + panic(err) + } } - case "tag": - if _, err := got.AddTagsToTimer(id, os.Args[3:]); err != nil { - panic(err) + + got := gotime.Create(dir) + + switch op { + case "ls": + tmrs := got.GetAllTimers() + for i := range tmrs { + fmt.Println("@" + strconv.Itoa(tmrs[i].Id) + ": " + tmrs[i].ToString()) + } + case "tag": + if _, err := got.AddTagsToTimer(id, os.Args[3:]); err != nil { + panic(err) + } + case "untag": + if _, err := got.RemoveTagsFromTimer(id, os.Args[3:]); err != nil { + panic(err) + } + case "start": + got.StartTimer() + case "stop": + got.StopTimer() } - case "untag": - if _, err := got.RemoveTagsFromTimer(id, os.Args[3:]); err != nil { - panic(err) - } - case "start": - got.StartTimer() - case "stop": - got.StopTimer() + */ +} + +const ( + MainScreenIndex = iota + AboutScreenIndex + ExitScreenIndex +) + +func createScreens() []Screen { + return []Screen{ + CreateMainScreen(), + AboutScreen(0), } } diff --git a/cmd/gotime-cui/mainloop.go b/cmd/gotime-cui/mainloop.go new file mode 100644 index 0000000..56c1e6a --- /dev/null +++ b/cmd/gotime-cui/mainloop.go @@ -0,0 +1,37 @@ +// +build !windows + +package main + +import ( + "os" + "syscall" + + "github.com/nsf/termbox-go" +) + +func mainLoop(style Style) { + screens := createScreens() + displayScreen := screens[MainScreenIndex] + layoutAndDrawScreen(displayScreen, style) + for { + event := termbox.PollEvent() + if event.Type == termbox.EventKey { + if event.Key == termbox.KeyCtrlZ { + process, _ := os.FindProcess(os.Getpid()) + termbox.Close() + process.Signal(syscall.SIGSTOP) + termbox.Init() + } + newScreenIndex := displayScreen.handleKeyEvent(event) + if newScreenIndex < len(screens) { + displayScreen = screens[newScreenIndex] + layoutAndDrawScreen(displayScreen, style) + } else { + break + } + } + if event.Type == termbox.EventResize { + layoutAndDrawScreen(displayScreen, style) + } + } +} diff --git a/cmd/gotime-cui/screen.go b/cmd/gotime-cui/screen.go new file mode 100644 index 0000000..b7102be --- /dev/null +++ b/cmd/gotime-cui/screen.go @@ -0,0 +1,20 @@ +package main + +import termbox "github.com/nsf/termbox-go" + +type Screen interface { + handleKeyEvent(event termbox.Event) int + performLayout() + drawScreen(style Style) +} + +func drawBackground(bg termbox.Attribute) { + termbox.Clear(0, bg) +} + +func layoutAndDrawScreen(screen Screen, style Style) { + screen.performLayout() + drawBackground(style.defaultBg) + screen.drawScreen(style) + termbox.Flush() +} diff --git a/cmd/gotime-cui/screen_about.go b/cmd/gotime-cui/screen_about.go new file mode 100644 index 0000000..15cb8d6 --- /dev/null +++ b/cmd/gotime-cui/screen_about.go @@ -0,0 +1,142 @@ +package main + +import ( + "fmt" + + "github.com/br0xen/termbox-util" + "github.com/nsf/termbox-go" +) + +/* +Command is a struct for associating descriptions to keys +*/ +type Command struct { + key string + description string +} + +// AboutScreen is just a basic 'int' type that we can extend to make this screen +type AboutScreen struct { + titleArt []string + commands [][]Command +} + +func CreateAboutScreen() *AboutScreen { + var err error + s := new(AboutScreen) + s.titleArt = []string{ + " __ _ ", + " ___ ____ / /_(_)_ _ ___ ", + " / _ `/ _ \\/ __/ / ' \\/ -_)", + " \\_, /\\___/\\__/_/_/_/_/\\__/ ", + "/___/ ", + } + s.commands = append(s.commands, []Command{ + {"h,←", "close parent"}, + {"j,↓", "down"}, + {"k,↑", "up"}, + {"l,→", "open item"}, + + {"g", "goto top"}, + {"G", "goto bottom"}, + {"ctrl+f", "jump down"}, + {"ctrl+b", "jump up"}, + }) + s.commands = append(s.commands, []Command{ + {"p,P", "create pair/at parent"}, + {"b,B", "create bucket/at parent"}, + {"e", "edit value of pair"}, + {"r", "rename pair/bucket"}, + {"D", "delete item"}, + {"x,X", "export as string/json to file"}, + {"?", "this screen"}, + {"q", "quit program"}, + }) +} + +func (screen *AboutScreen) drawCommandsAtPoint(x int, y int, style Style) { + xPos, yPos := x, y + for _, cmds := range screen.commands { + for index, cmd := range commands { + termboxUtil.DrawStringAtPoint(fmt.Sprintf("%6s", cmd.key), xPos, yPos, style.defaultFg, style.defaultBg) + termboxUtil.DrawStringAtPoint(cmd.description, xPos+8, yPos, style.defaultFg, style.defaultBg) + yPos++ + if index > 2 && index%2 == 1 { + yPos++ + } + } + } +} + +func (screen *AboutScreen) handleKeyEvent(event termbox.Event) int { + return MainScreenIndex +} + +func (screen *AboutScreen) performLayout() {} + +func (screen *AboutScreen) drawScreen(style Style) { + defaultFg := style.defaultFg + defaultBg := style.defaultBg + width, height := termbox.Size() + + firstLine := screen.titleArt[0] + startX := (width - len(firstLine)) / 2 + startY := ((height - 2*len(template)) / 2) - 2 + xPos := startX + yPos := startY + if height <= 20 { + title := AppName + startY = 0 + yPos = 0 + termboxUtil.DrawStringAtPoint(title, (width-len(title))/2, startY, style.titleFg, style.titleBg) + } else { + if height < 25 { + startY = 0 + yPos = 0 + } + for _, line := range template { + xPos = startX + for _, runeValue := range line { + bg := defaultBg + displayRune := ' ' + if runeValue != ' ' { + displayRune = runeValue + termbox.SetCell(xPos, yPos, displayRune, defaultFg, bg) + } + xPos++ + } + yPos++ + } + } + + commands1 := [...]Command{ + {"h,←", "close parent"}, + {"j,↓", "down"}, + {"k,↑", "up"}, + {"l,→", "open item"}, + + {"g", "goto top"}, + {"G", "goto bottom"}, + {"ctrl+f", "jump down"}, + {"ctrl+b", "jump up"}, + } + + commands2 := [...]Command{ + {"p,P", "create pair/at parent"}, + {"b,B", "create bucket/at parent"}, + {"e", "edit value of pair"}, + {"r", "rename pair/bucket"}, + {"D", "delete item"}, + {"x,X", "export as string/json to file"}, + + {"?", "this screen"}, + {"q", "quit program"}, + } + xPos = startX // + 20 + yPos++ + + drawCommandsAtPoint(commands1[:], xPos, yPos+1, style) + drawCommandsAtPoint(commands2[:], xPos+20, yPos+1, style) + exitTxt := "Press any key to return to browser" + termboxUtil.DrawStringAtPoint(exitTxt, (width-len(exitTxt))/2, height-1, style.titleFg, style.titleBg) +} diff --git a/cmd/gotime-cui/screen_main.go b/cmd/gotime-cui/screen_main.go new file mode 100644 index 0000000..c8aa156 --- /dev/null +++ b/cmd/gotime-cui/screen_main.go @@ -0,0 +1,40 @@ +package main + +import ( + termbox "github.com/nsf/termbox-go" + "gogs.bullercodeworks.com/brian/gotime" + "gogs.bullercodeworks.com/brian/user-config" +) + +type MainScreen struct { + config *userConfig.Config + got *gotime.GoTime +} + +func CreateMainScreen() *MainScreen { + var err error + m := new(MainScreen) + + m.config, err = userConfig.NewConfig(AppName) + + if m.config.Get("dir") != "" { + m.got = gotime.Create(dir) + } + + return *m +} + +func (screen *MainScreen) handleKeyEvent(event termbox.Event) int { + if event.Ch == '?' { + return AboutScreenIndex + } + return MainScreenIndex +} + +func (screen *MainScreen) performLayout() { + +} + +func (screen *MainScreen) drawScreen(style Style) { + +} diff --git a/cmd/gotime-cui/style.go b/cmd/gotime-cui/style.go new file mode 100644 index 0000000..a2ddb3c --- /dev/null +++ b/cmd/gotime-cui/style.go @@ -0,0 +1,27 @@ +package main + +import termbox "github.com/nsf/termbox-go" + +/* +Style Defines the colors for the terminal display, basically +*/ +type Style struct { + defaultBg termbox.Attribute + defaultFg termbox.Attribute + titleFg termbox.Attribute + titleBg termbox.Attribute + cursorFg termbox.Attribute + cursorBg termbox.Attribute +} + +func defaultStyle() Style { + var style Style + style.defaultBg = termbox.ColorBlack + style.defaultFg = termbox.ColorWhite + style.titleFg = termbox.ColorBlack + style.titleBg = termbox.ColorGreen + style.cursorFg = termbox.ColorBlack + style.cursorBg = termbox.ColorGreen + + return style +}