diff --git a/main.go b/main.go index e63d916..b2d98fd 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import "fmt" import "time" +import "sync" import "bytes" import "image" import _ "embed" @@ -14,9 +15,10 @@ var iconBytes []byte var application = &stone.Application { } -var now time.Time var viewingMonth int +var currentMonth int var columns, rows int +var drawMutex sync.Mutex var shortMonthNames = []string { "", @@ -43,7 +45,7 @@ func main () { application.SetIcon([]image.Image { icon }) application.OnStart(onStart) - application.OnResize(redraw) + application.OnResize(onResize) application.OnPress(onPress) application.OnScroll(onScroll) @@ -52,6 +54,9 @@ func main () { } func onScroll (x, y int) { + drawMutex.Lock() + defer drawMutex.Unlock() + viewingMonth += y * columns application.Clear() redraw() @@ -61,50 +66,98 @@ func onScroll (x, y int) { func onPress (button stone.Button, modifiers stone.Modifiers) { switch button { case stone.KeyUp: + drawMutex.Lock() + defer drawMutex.Unlock() + viewingMonth -= columns application.Clear() redraw() application.Draw() + case stone.KeyDown: + drawMutex.Lock() + defer drawMutex.Unlock() + viewingMonth += columns application.Clear() redraw() application.Draw() + case stone.KeyPageUp: + drawMutex.Lock() + defer drawMutex.Unlock() + viewingMonth -= columns * rows application.Clear() redraw() application.Draw() + case stone.KeyPageDown: + drawMutex.Lock() + defer drawMutex.Unlock() + viewingMonth += columns * rows application.Clear() redraw() application.Draw() + } } func onStart () { - now = time.Now() - viewingMonth = int(now.Month() - 1) + now.Year() * 12 + currentMonth = canonMonth(time.Now()) + viewingMonth = currentMonth redraw() + go tick() +} + +func onResize () { + drawMutex.Lock() + defer drawMutex.Unlock() + + redraw() +} + +func tick () { + for { + time.Sleep(time.Second) + drawMutex.Lock() + + newMonth := canonMonth(time.Now()) + if currentMonth != newMonth { + currentMonth = newMonth + + pageSize := columns * rows + if currentMonth < viewingMonth { + viewingMonth -= pageSize + } else if currentMonth >= viewingMonth + pageSize { + viewingMonth += pageSize + } + + application.Clear() + redraw() + application.Draw() + } + + drawMutex.Unlock() + } } func redraw () { width, height := application.Size() + columns = (width - 20) / 23 + 1 + rows = height / 10 + 1 monthIter := viewingMonth - rows = 0 - columns = (width - 20) / 23 + 1 xOffset := (width - columns * 23) / 2 + 1 - for y := 0; y < height; y += 10 { - for x := 0; x < width - 19; x += 23 { + for y := 0; y < rows; y ++ { + for x := 0; x < columns; x ++ { drawMonth ( - x + xOffset, y, + x * 23 + xOffset, y * 10, monthIter / 12, time.Month(wrap(monthIter, 12) + 1)) monthIter ++ } - rows ++ } } @@ -118,7 +171,7 @@ func wrap (value, around int) (wrapped int) { } func drawMonth (xOffset, yOffset, year int, month time.Month) { - current := month == now.Month() && year == now.Year() + current := int(month) - 1 + year * 12 == currentMonth bce := year < 0 if bce { year *= -1 } @@ -159,7 +212,7 @@ func drawMonth (xOffset, yOffset, year int, month time.Month) { fmt.Fprint(application, dayIter) } - if current && dayIter == int(now.Day()) { + if current && dayIter == int(time.Now().Day()) { application.SetColor(x, y, stone.ColorRed) application.SetColor(x + 1, y, stone.ColorRed) } else if weekday == 0 || weekday == 6 { @@ -205,3 +258,8 @@ func daysInMonth (year int, month time.Month) (days int) { return } + +func canonMonth (when time.Time) (month int) { + month = int(when.Month() - 1) + when.Year() * 12 + return +}