package main import ( "errors" "fmt" "strings" "time" todotxt "github.com/br0xen/go-todotxt" "github.com/br0xen/termbox-util" termbox "github.com/nsf/termbox-go" ) // TaskScreen holds all that's going on type TaskScreen struct { viewPort *ViewPort message string messageTimeout time.Duration messageTime time.Time inputModal *termboxUtil.InputModal confirmModal *termboxUtil.ConfirmModal currentTaskId int displayTask *todotxt.Task } const ( TaskBundleTaskIdKey = "taskscreen.taskid" ) func (screen *TaskScreen) initialize(bundle Bundle) error { var err error screen.currentTaskId = bundle.getInt(TaskBundleTaskIdKey, -1) if screen.currentTaskId == -1 { return errors.New("Task Screen Initialization Failed") } if screen.displayTask, err = app.TaskList.GetTask(screen.currentTaskId); err != nil { return err } return nil } func (screen *TaskScreen) handleKeyEvent(event termbox.Event) int { if event.Key == termbox.KeyBackspace || event.Key == termbox.KeyBackspace2 || event.Ch == 'h' || event.Key == termbox.KeyArrowLeft { return ScreenMain } else if event.Ch == 'j' || event.Key == termbox.KeyArrowDown { screen.moveCursorDown() } else if event.Ch == 'k' || event.Key == termbox.KeyArrowUp { screen.moveCursorUp() } return ScreenTask } func (screen *TaskScreen) drawScreen() { screen.drawHeader() yPos := 1 termboxUtil.DrawStringAtPoint(screen.displayTask.Todo, 0, yPos, DefaultFg, DefaultBg) yPos++ termboxUtil.DrawStringAtPoint(fmt.Sprintf("Priority: %s", screen.displayTask.Priority), 0, yPos, DefaultFg, DefaultBg) yPos++ termboxUtil.DrawStringAtPoint(fmt.Sprintf("Projects: %s", screen.displayTask.Projects), 0, yPos, DefaultFg, DefaultBg) yPos++ termboxUtil.DrawStringAtPoint(fmt.Sprintf("Contexts: %s", screen.displayTask.Contexts), 0, yPos, DefaultFg, DefaultBg) yPos++ termboxUtil.DrawStringAtPoint("Additional Tags:", 0, yPos, DefaultFg, DefaultBg) yPos++ for k, v := range screen.displayTask.AdditionalTags { termboxUtil.DrawStringAtPoint(fmt.Sprintf("%s: %s", k, v), 0, yPos, DefaultFg, DefaultBg) yPos++ } screen.drawFooter() } func (screen *TaskScreen) drawHeader() { width, _ := termbox.Size() headerString := screen.displayTask.Todo spaces := strings.Repeat(" ", ((width-len(headerString))/2)+1) termboxUtil.DrawStringAtPoint(fmt.Sprintf("%s%s%s", spaces, headerString, spaces), 0, 0, TitleFg, TitleBg) } func (screen *TaskScreen) drawFooter() { if screen.messageTimeout > 0 && time.Since(screen.messageTime) > screen.messageTimeout { screen.clearMessage() } _, height := termbox.Size() termboxUtil.DrawStringAtPoint(screen.message, 0, height-1, DefaultFg, DefaultBg) } func (screen *TaskScreen) moveCursorDown() bool { screen.viewPort.cursor++ return true } func (screen *TaskScreen) moveCursorUp() bool { screen.viewPort.cursor-- return true } func (screen *TaskScreen) setMessage(msg string) { screen.message = msg screen.messageTime = time.Now() screen.messageTimeout = time.Second * 2 } /* setMessageWithTimeout lets you specify the timeout for the message * setting it to -1 means it won't timeout */ func (screen *TaskScreen) setMessageWithTimeout(msg string, timeout time.Duration) { screen.message = msg screen.messageTime = time.Now() screen.messageTimeout = timeout } func (screen *TaskScreen) clearMessage() { screen.message = "" screen.messageTimeout = -1 }