2
1
Fork 0
swim/board.go

180 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"fmt"
"os"
"strings"
"time"
"tildegit.org/sloum/swim/termios"
)
const (
swimLogo string = "\033[7m ▟\033[27m "
cursorHome string = "\033[0;0H"
styleOff string = "\033[0m"
upAndLeft string = "\033[1A\033[500D"
cursorEnd string = "\033[500;500H"
)
type Board struct {
Title string
Body string
Created time.Time
Lanes []Lane
Current int // Index of current lane
Message string
MsgErr bool
Width int
Height int
Zoom int
}
func (b *Board) Run() {
defer termios.Restore()
termios.SetCharMode()
var ch rune
for {
b.Draw()
ch = Getch()
switch ch {
case 'Q':
termios.Restore()
os.Exit(0)
case 'N':
b.CreateLane()
case 'n':
b.CreateStory()
case '\n':
// View current story
case 'h', 'j', 'k', 'l':
// Move cursor, context dependent
// If a story is open, will scroll
// the story, otherwise will select
// a story
case 'c':
// Comment on current story
case 'a':
// Archive the current story
case 'd':
// Delete current story
case 'D':
// Delete current lane
case 'e':
// Edit current story
case ':':
b.EnterCommand()
case '+':
// b.ZoomIn()
case '-':
// b.ZoomOut()
}
}
}
func (b *Board) ClearMessage() {
b.Message = ""
b.MsgErr = false
}
func (b *Board) SetMessage(msg string, isError bool) {
b.Message = msg
b.MsgErr = isError
}
func (b *Board) CreateLane() {
laneTitle, err := GetAndConfirmCommandLine("Lane Title: ")
if err != nil {
b.SetMessage(err.Error(), true)
return
}
b.Lanes = append(b.Lanes, MakeLane(laneTitle))
if b.Current < 0 {
b.Current = 0
}
}
func (b *Board) CreateStory() {
b.Lanes[b.Current].CreateStory(b)
}
func (b Board) PrintHeader() string {
return fmt.Sprintf("%s%s%-*.*s%s\n", style.Header, swimLogo, b.Width-12, b.Width-12, b.Title, styleOff)
}
func (b Board) PrintInputArea() string {
return fmt.Sprintf("%s%-*.*s%s\n", style.Input, b.Width, b.Width, " ", styleOff)
}
func (b Board) PrintLanes() string {
var out strings.Builder
laneWidth := b.Width / b.Zoom
if len(b.Lanes) == 0 {
for i := 0; i < b.Height - 3; i++ {
out.WriteString(fmt.Sprintf("%s%*.*s%s\n", style.Lane, b.Width, b.Width, " ", styleOff))
}
return out.String()
}
laneText := make([][]string, 0, len(b.Lanes))
maxLen := 0
for _, l := range b.Lanes {
s := l.StringSlice(laneWidth)
laneText = append(laneText, s)
if len(s) > maxLen {
maxLen = len(s)
}
}
for i := 0; i < b.Height - 3; i++ {
for li, l := range laneText {
// TODO fix this
if li >= b.Zoom {
out.WriteRune('\n')
break
}
if i < len(l) {
out.WriteString(l[i])
} else {
out.WriteString(fmt.Sprintf("%s%*.*s%s", style.Lane, laneWidth, laneWidth, " ", styleOff))
}
}
}
out.WriteString(styleOff)
return out.String()
}
func (b *Board) EnterCommand() {
var out strings.Builder
out.WriteString(upAndLeft) // Move up one and over all
out.WriteString(style.Input)
fmt.Print(out.String())
command, err := GetLine(":")
if err != nil {
b.SetMessage(err.Error(), true)
}
b.SetMessage(command, false)
}
func (b Board) PrintMessage() string {
var out strings.Builder
if b.MsgErr {
out.WriteString(style.MessageErr)
} else {
out.WriteString(style.Message)
}
out.WriteString(fmt.Sprintf("%-*.*s%s", b.Width, b.Width, b.Message, styleOff))
return out.String()
}
func (b Board) Draw() {
var out strings.Builder
out.WriteString(cursorHome)
out.WriteString(b.PrintHeader())
out.WriteString(b.PrintLanes())
out.WriteString(b.PrintInputArea())
out.WriteString(b.PrintMessage())
fmt.Print(out.String())
}