161 lines
3 KiB
Go
161 lines
3 KiB
Go
package main
|
||
|
||
import (
|
||
"log"
|
||
"os"
|
||
"time"
|
||
"strconv"
|
||
"unicode/utf8"
|
||
|
||
|
||
"github.com/gdamore/tcell/v2"
|
||
)
|
||
|
||
const (
|
||
dayWidth = 2
|
||
smallGap = 1
|
||
largeGap = 3
|
||
monthWidth = 7*dayWidth + 6*smallGap
|
||
monthHeight = (31+6+(7-1))/7 + 2
|
||
)
|
||
|
||
var (
|
||
months = [...]string{"", "Јануар", "Фебруар", "Март", "Април", "Мај", "Јун",
|
||
"Јул", "Август", "Септембар", "Октобар", "Новембар", "Децембар"}
|
||
weekdays = [...]string{"Недеља", "Понедељак", "Уторак", "Среда", "Четвртак",
|
||
"Петак", "Субота"}
|
||
)
|
||
|
||
var (
|
||
wall tcell.Screen
|
||
defStyle tcell.Style
|
||
selStyle tcell.Style
|
||
)
|
||
|
||
var (
|
||
selTime time.Time
|
||
today time.Time
|
||
)
|
||
|
||
func max(a, b int) int {
|
||
if a > b {
|
||
return a
|
||
}
|
||
return b
|
||
}
|
||
|
||
func min(a, b int) int {
|
||
if a < b {
|
||
return a
|
||
}
|
||
return b
|
||
}
|
||
|
||
func date(year int, month time.Month, day int) time.Time {
|
||
return time.Date(year, month, day, 0, 0, 0, 0, time.Local)
|
||
}
|
||
|
||
func centeredText(s string, x, y, width int, scr tcell.Screen, style tcell.Style) {
|
||
start := x + max((width - utf8.RuneCountInString(s)) / 2, 0)
|
||
i := 0
|
||
for _, char := range s {
|
||
if i >= width {
|
||
break;
|
||
}
|
||
|
||
scr.SetContent(start + i, y, char, nil, style)
|
||
i++
|
||
}
|
||
}
|
||
|
||
func wrappedText(s string, scr tcell.Screen, style tcell.Style) {
|
||
x := 0
|
||
y := 0
|
||
w, h := scr.Size()
|
||
for _, char := range s {
|
||
if x >= w {
|
||
if y >= h {
|
||
break;
|
||
}
|
||
x = 0
|
||
y++
|
||
}
|
||
scr.SetContent(x, y, char, nil, style)
|
||
x++
|
||
}
|
||
}
|
||
|
||
func drawMonth(m time.Month, x, y int) {
|
||
centeredText(months[m], x, y, monthWidth, wall, defStyle)
|
||
|
||
for i := 1; i <= 7; i++ {
|
||
centeredText(weekdays[i % 7], x + (i - 1) * (dayWidth + smallGap), y + 1, dayWidth, wall, defStyle)
|
||
}
|
||
|
||
dayNum := date(selTime.Year(), m + 1, 0).Day()
|
||
for i := 1; i <= dayNum; i++ {
|
||
weekday := int(date(selTime.Year(), m, i).Weekday())
|
||
style := defStyle
|
||
if selTime.Day() == i && selTime.Month() == m {
|
||
style = selStyle
|
||
}
|
||
centeredText(
|
||
strconv.Itoa(i),
|
||
x + ((weekday - 1 + 7) % 7) * (dayWidth + smallGap),
|
||
y + 2,
|
||
2,
|
||
wall,
|
||
style)
|
||
if weekday == 0 {
|
||
y++
|
||
}
|
||
}
|
||
}
|
||
|
||
func drawWall() {
|
||
}
|
||
|
||
func main() {
|
||
today = time.Now()
|
||
selTime = today
|
||
var err error
|
||
wall, err = tcell.NewScreen()
|
||
if err != nil {
|
||
log.Fatalf("%+v", err)
|
||
}
|
||
if err := wall.Init(); err != nil {
|
||
log.Fatalf("%+v", err)
|
||
}
|
||
defStyle = tcell.StyleDefault.Background(tcell.ColorReset).Foreground(tcell.ColorReset)
|
||
selStyle = tcell.StyleDefault.Background(tcell.ColorReset).Foreground(tcell.GetColor("green")).Bold(true)
|
||
|
||
wall.SetStyle(defStyle)
|
||
wall.Clear()
|
||
drawMonth(time.January, 0, 0)
|
||
drawMonth(time.July, monthWidth * 2, 0)
|
||
|
||
|
||
quit := func() {
|
||
wall.Fini()
|
||
os.Exit(0)
|
||
}
|
||
for {
|
||
// Update screen
|
||
wall.Show()
|
||
|
||
// Poll event
|
||
ev := wall.PollEvent()
|
||
|
||
// Process event
|
||
switch ev := ev.(type) {
|
||
case *tcell.EventResize:
|
||
wall.Sync()
|
||
case *tcell.EventKey:
|
||
if ev.Key() == tcell.KeyEscape || ev.Key() == tcell.KeyCtrlC ||
|
||
ev.Rune() == 'Q' || ev.Rune() == 'q' {
|
||
quit()
|
||
}
|
||
}
|
||
}
|
||
}
|