diff options
| -rw-r--r-- | cmd/clock.go | 155 | ||||
| -rw-r--r-- | cmd/timer.go | 62 | ||||
| -rw-r--r-- | internal/term/draw.go | 112 | ||||
| -rw-r--r-- | internal/term/screen.go | 70 |
4 files changed, 223 insertions, 176 deletions
diff --git a/cmd/clock.go b/cmd/clock.go index 69c125d..3e12590 100644 --- a/cmd/clock.go +++ b/cmd/clock.go @@ -4,109 +4,14 @@ import ( "log" "time" - "github.com/gdamore/tcell/v2" "github.com/spf13/cobra" -) - -func drawSquare(scr tcell.Screen, xOffset, yOffset, w, h int, style tcell.Style) { - for dx := 0; dx < w; dx++ { - x := xOffset + dx - for dy := 0; dy < h; dy++ { - y := yOffset + dy - scr.SetContent(x, y, ' ', nil, style) - } - } -} -func drawNumber(scr tcell.Screen, n, xOffset, yOffset, squareW, squareH int, style tcell.Style) { - defs := [...][15]bool{ - { - true, true, true, - true, false, true, - true, false, true, - true, false, true, - true, true, true, - }, - { - false, false, true, - false, false, true, - false, false, true, - false, false, true, - false, false, true, - }, - { - true, true, true, - false, false, true, - true, true, true, - true, false, false, - true, true, true, - }, - { - true, true, true, - false, false, true, - true, true, true, - false, false, true, - true, true, true, - }, - { - true, false, true, - true, false, true, - true, true, true, - false, false, true, - false, false, true, - }, - { - true, true, true, - true, false, false, - true, true, true, - false, false, true, - true, true, true, - }, - { - true, true, true, - true, false, false, - true, true, true, - true, false, true, - true, true, true, - }, - { - true, true, true, - false, false, true, - false, false, true, - false, false, true, - false, false, true, - }, - { - true, true, true, - true, false, true, - true, true, true, - true, false, true, - true, true, true, - }, - { - true, true, true, - true, false, true, - true, true, true, - false, false, true, - true, true, true, - }, - } - - squares := defs[n] - for i, draw := range squares { - if !draw { - continue - } - x := i % 3 - y := i / 3 - drawSquare(scr, xOffset+squareW*x, yOffset+squareH*y, squareW, squareH, style) - } -} + "github.com/nsfisis/term-clock/internal/term" +) -func drawClock(scr tcell.Screen, now time.Time, bgStyle, clockStyle tcell.Style) { +func drawClock(scr *term.Screen, now time.Time, bgStyle, fgStyle term.Style) { // Clear the entire screen. - scr.SetStyle(bgStyle) - scr.Clear() + scr.Clear(bgStyle) // Calculate square width/height and offset. scrW, scrH := scr.Size() @@ -130,53 +35,33 @@ func drawClock(scr tcell.Screen, now time.Time, bgStyle, clockStyle tcell.Style) // Hour hour := now.Hour() - drawNumber(scr, hour/10, xOffset+squareW*0, yOffset, squareW, squareH, clockStyle) - drawNumber(scr, hour%10, xOffset+squareW*4, yOffset, squareW, squareH, clockStyle) + term.DrawNumber(scr, hour/10, xOffset+squareW*0, yOffset, squareW, squareH, fgStyle) + term.DrawNumber(scr, hour%10, xOffset+squareW*4, yOffset, squareW, squareH, fgStyle) // Colon - drawSquare(scr, xOffset+squareW*8, yOffset+squareH*1, squareW, squareH, clockStyle) - drawSquare(scr, xOffset+squareW*8, yOffset+squareH*3, squareW, squareH, clockStyle) + term.DrawSquare(scr, xOffset+squareW*8, yOffset+squareH*1, squareW, squareH, fgStyle) + term.DrawSquare(scr, xOffset+squareW*8, yOffset+squareH*3, squareW, squareH, fgStyle) // Minute minute := now.Minute() - drawNumber(scr, minute/10, xOffset+squareW*10, yOffset, squareW, squareH, clockStyle) - drawNumber(scr, minute%10, xOffset+squareW*14, yOffset, squareW, squareH, clockStyle) + term.DrawNumber(scr, minute/10, xOffset+squareW*10, yOffset, squareW, squareH, fgStyle) + term.DrawNumber(scr, minute%10, xOffset+squareW*14, yOffset, squareW, squareH, fgStyle) } func cmdClock(cmd *cobra.Command, args []string) { - bgStyle := tcell.StyleDefault.Background(tcell.ColorReset).Foreground(tcell.ColorReset) - clockStyle := tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.ColorOlive) - - scr, err := tcell.NewScreen() + scr, err := term.NewScreen() if err != nil { log.Fatalf("%+v", err) } - if err := scr.Init(); err != nil { - log.Fatalf("%+v", err) - } - defer scr.Fini() + defer scr.Close() - drawClock(scr, time.Now(), bgStyle, clockStyle) + drawClock(scr, time.Now(), term.BgStyle, term.FgStyle) - quitC := make(chan struct{}) - - go func() { - for { - scr.Show() - - ev := scr.PollEvent() - switch ev := ev.(type) { - case *tcell.EventResize: - drawClock(scr, time.Now(), bgStyle, clockStyle) - scr.Sync() - case *tcell.EventKey: - if ev.Key() == tcell.KeyEscape || ev.Key() == tcell.KeyCtrlC || ev.Rune() == 'q' { - close(quitC) - return - } - } - } - }() + scr.OnResize(func() bool { + drawClock(scr, time.Now(), term.BgStyle, term.FgStyle) + return false + }) + go scr.DoEventLoop() t := time.NewTicker(1 * time.Second) defer t.Stop() @@ -184,11 +69,11 @@ func cmdClock(cmd *cobra.Command, args []string) { prev := time.Now() for { select { - case <-quitC: + case <-scr.QuitC: return case now := <-t.C: if now.Minute() != prev.Minute() { - drawClock(scr, now, bgStyle, clockStyle) + drawClock(scr, now, term.BgStyle, term.FgStyle) scr.Show() prev = now } diff --git a/cmd/timer.go b/cmd/timer.go index 3f46f92..ff11451 100644 --- a/cmd/timer.go +++ b/cmd/timer.go @@ -4,19 +4,19 @@ import ( "log" "time" - "github.com/gdamore/tcell/v2" "github.com/spf13/cobra" + + "github.com/nsfisis/term-clock/internal/term" ) -func drawTimer(scr tcell.Screen, leftTime time.Duration, bgStyle, clockStyle tcell.Style) { +func drawTimer(scr *term.Screen, leftTime time.Duration, bgStyle, fgStyle term.Style) { if leftTime<=0{ leftTime=0 - bgStyle, clockStyle = clockStyle, bgStyle + bgStyle, fgStyle = fgStyle, bgStyle } // Clear the entire screen. - scr.SetStyle(bgStyle) - scr.Clear() + scr.Clear(bgStyle) // Calculate square width/height and offset. scrW, scrH := scr.Size() @@ -40,17 +40,17 @@ func drawTimer(scr tcell.Screen, leftTime time.Duration, bgStyle, clockStyle tce // Minute minute := leftTime.Minutes() - drawNumber(scr, int(minute)/10, xOffset+squareW*0, yOffset, squareW, squareH, clockStyle) - drawNumber(scr, int(minute)%10, xOffset+squareW*4, yOffset, squareW, squareH, clockStyle) + term.DrawNumber(scr, int(minute)/10, xOffset+squareW*0, yOffset, squareW, squareH, fgStyle) + term.DrawNumber(scr, int(minute)%10, xOffset+squareW*4, yOffset, squareW, squareH, fgStyle) // Colon - drawSquare(scr, xOffset+squareW*8, yOffset+squareH*1, squareW, squareH, clockStyle) - drawSquare(scr, xOffset+squareW*8, yOffset+squareH*3, squareW, squareH, clockStyle) + term.DrawSquare(scr, xOffset+squareW*8, yOffset+squareH*1, squareW, squareH, fgStyle) + term.DrawSquare(scr, xOffset+squareW*8, yOffset+squareH*3, squareW, squareH, fgStyle) // Second second := leftTime.Seconds() - drawNumber(scr, int(second)/10, xOffset+squareW*10, yOffset, squareW, squareH, clockStyle) - drawNumber(scr, int(second)%10, xOffset+squareW*14, yOffset, squareW, squareH, clockStyle) + term.DrawNumber(scr, int(second)/10, xOffset+squareW*10, yOffset, squareW, squareH, fgStyle) + term.DrawNumber(scr, int(second)%10, xOffset+squareW*14, yOffset, squareW, squareH, fgStyle) } func cmdTimer(cmd *cobra.Command, args []string) { @@ -59,51 +59,31 @@ func cmdTimer(cmd *cobra.Command, args []string) { log.Fatalf("%+v", err) } - bgStyle := tcell.StyleDefault.Background(tcell.ColorReset).Foreground(tcell.ColorReset) - clockStyle := tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.ColorOlive) - - scr, err := tcell.NewScreen() + scr, err := term.NewScreen() if err != nil { log.Fatalf("%+v", err) } - if err := scr.Init(); err != nil { - log.Fatalf("%+v", err) - } - defer scr.Fini() + defer scr.Close() startTime := time.Now() - drawTimer(scr, (timerTime - time.Now().Sub(startTime)).Round(time.Second), bgStyle, clockStyle) + drawTimer(scr, (timerTime - time.Now().Sub(startTime)).Round(time.Second), term.BgStyle, term.FgStyle) - quitC := make(chan struct{}) - - go func() { - for { - scr.Show() - - ev := scr.PollEvent() - switch ev := ev.(type) { - case *tcell.EventResize: - drawTimer(scr, (timerTime - time.Now().Sub(startTime)).Round(time.Second), bgStyle, clockStyle) - scr.Sync() - case *tcell.EventKey: - if ev.Key() == tcell.KeyEscape || ev.Key() == tcell.KeyCtrlC || ev.Rune() == 'q' { - close(quitC) - return - } - } - } - }() + scr.OnResize(func() bool { + drawTimer(scr, (timerTime - time.Now().Sub(startTime)).Round(time.Second), term.BgStyle, term.FgStyle) + return false + }) + go scr.DoEventLoop() t := time.NewTicker(1 * time.Second) defer t.Stop() for { select { - case <-quitC: + case <-scr.QuitC: return case now := <-t.C: - drawTimer(scr, (timerTime - now.Sub(startTime)).Round(time.Second), bgStyle, clockStyle) + drawTimer(scr, (timerTime - now.Sub(startTime)).Round(time.Second), term.BgStyle, term.FgStyle) scr.Show() } } diff --git a/internal/term/draw.go b/internal/term/draw.go new file mode 100644 index 0000000..c6f297f --- /dev/null +++ b/internal/term/draw.go @@ -0,0 +1,112 @@ +package term + +import ( + "github.com/gdamore/tcell/v2" +) + +type Style tcell.Style; + +var ( + BgStyle Style + FgStyle Style +) + +func init() { + BgStyle = Style(tcell.StyleDefault.Background(tcell.ColorReset).Foreground(tcell.ColorReset)) + FgStyle = Style(tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.ColorOlive)) +} + +func DrawSquare(scr *Screen, xOffset, yOffset, w, h int, style Style) { + for dx := 0; dx < w; dx++ { + x := xOffset + dx + for dy := 0; dy < h; dy++ { + y := yOffset + dy + scr.scr.SetContent(x, y, ' ', nil, tcell.Style(style)) + } + } +} + +func DrawNumber(scr *Screen, n, xOffset, yOffset, squareW, squareH int, style Style) { + defs := [...][15]bool{ + { + true, true, true, + true, false, true, + true, false, true, + true, false, true, + true, true, true, + }, + { + false, false, true, + false, false, true, + false, false, true, + false, false, true, + false, false, true, + }, + { + true, true, true, + false, false, true, + true, true, true, + true, false, false, + true, true, true, + }, + { + true, true, true, + false, false, true, + true, true, true, + false, false, true, + true, true, true, + }, + { + true, false, true, + true, false, true, + true, true, true, + false, false, true, + false, false, true, + }, + { + true, true, true, + true, false, false, + true, true, true, + false, false, true, + true, true, true, + }, + { + true, true, true, + true, false, false, + true, true, true, + true, false, true, + true, true, true, + }, + { + true, true, true, + false, false, true, + false, false, true, + false, false, true, + false, false, true, + }, + { + true, true, true, + true, false, true, + true, true, true, + true, false, true, + true, true, true, + }, + { + true, true, true, + true, false, true, + true, true, true, + false, false, true, + true, true, true, + }, + } + + squares := defs[n] + for i, draw := range squares { + if !draw { + continue + } + x := i % 3 + y := i / 3 + DrawSquare(scr, xOffset+squareW*x, yOffset+squareH*y, squareW, squareH, style) + } +} diff --git a/internal/term/screen.go b/internal/term/screen.go new file mode 100644 index 0000000..14bfcfb --- /dev/null +++ b/internal/term/screen.go @@ -0,0 +1,70 @@ +package term + +import ( + "github.com/gdamore/tcell/v2" +) + +type Screen struct { + scr tcell.Screen + onResize func() bool + QuitC chan struct{} +} + +func NewScreen() (*Screen, error) { + scr, err := tcell.NewScreen() + if err != nil{ + return nil, err + } + err = scr.Init() + if err != nil{ + return nil, err + } + return &Screen{ + scr: scr, + QuitC: make(chan struct{}), + }, nil +} + +func (scr *Screen) Close() { + scr.scr.Fini() +} + +func (scr *Screen) Size() (int, int) { + return scr.scr.Size() +} + +func (scr *Screen) Clear(style Style) { + scr.scr.SetStyle(tcell.Style(style)) + scr.scr.Clear() +} + +func (scr *Screen) OnResize(handler func() bool) { + scr.onResize = handler +} + +func (scr *Screen) Show() { + scr.scr.Show() +} + +func (scr *Screen) DoEventLoop() { + for { + scr.scr.Show() + + ev := scr.scr.PollEvent() + switch ev := ev.(type) { + case *tcell.EventResize: + if scr.onResize != nil { + if quit := scr.onResize(); quit { + return + } + } + scr.scr.Sync() + case *tcell.EventKey: + if ev.Key() == tcell.KeyEscape || ev.Key() == tcell.KeyCtrlC || ev.Rune() == 'q' { + close(scr.QuitC) + return + } + scr.scr.Sync() + } + } +} |
