package main import ( "log" "strings" "github.com/gdamore/tcell/v3" "github.com/gdamore/tcell/v3/color" ) func drawText(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style, text string) { row := y1 col := x1 var width int for text != "" { text, width = s.Put(col, row, text, style) col += width if col >= x2 { row++ col = x1 } if row > y2 { break } if width == 0 { // incomplete grapheme at end of string break } } } func main() { var title string = ` ⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⢀⣾⣿⣿⣿⣿⣿⡆⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⡆⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⡀⠀⠀⠀⠀⢀⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣠⣤⣤⣼⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀⠀⠀⠀⠀ ⠀⠀⠀⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀ ⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀ ⠀⠀⠀⠘⣿⣿⣿⣿⠟⠁⠀⠀⠀⠹⣿⣿⣿⣿⣿⠟⠁⠀⠀⠹⣿⣿⡿⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⣿⣿⣿⡇⠀⠀⠀⢼⣿⠀⢿⣿⣿⣿⣿⠀⣾⣷⠀⠀⢿⣿⣷⠀⠀⠀⠀⠀ ⠀⠀⠀⢠⣿⣿⣿⣷⡀⠀⠀⠈⠋⢀⣿⣿⣿⣿⣿⡀⠙⠋⠀⢀⣾⣿⣿⠀⠀⠀⠀⠀ ⢀⣀⣀⣀⣿⣿⣿⣿⣿⣶⣶⣶⣶⣿⣿⣿⣿⣾⣿⣷⣦⣤⣴⣿⣿⣿⣿⣤⠤⢤⣤⡄ ⠈⠉⠉⢉⣙⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⣀⣀⣀⡀⠀ ⠐⠚⠋⠉⢀⣬⡿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⣥⣀⡀⠈⠀⠈⠛ ⠀⠀⠴⠚⠉⠀⠀⠀⠉⠛⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⠋⠁⠀⠀⠀⠉⠛⠢⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ /$$ /$$ /$$ /$$ /$$ ⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀| $$ | $$ |__/| $$| $$ ⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀| $$ | $$ /$$$$$$ /$$$$$$$ /$$| $$| $$ /$$$$$$ ⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀| $$ / $$/|____ $$| $$__ $$| $$| $$| $$ |____ $$ ⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀ \ $$ $$/ /$$$$$$$| $$ \ $$| $$| $$| $$ /$$$$$$$ ⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀ \ $$$/ /$$__ $$| $$ | $$| $$| $$| $$ /$$__ $$ ⠀⠀⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀ \ $/ | $$$$$$$| $$ | $$| $$| $$| $$| $$$$$$$ ⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀ \_/ \_______/|__/ |__/|__/|__/|__/ \_______/ /$$$$$$ /$$ /$$ /$$__ $$ | $$ | $$ | $$ \ $$ /$$$$$$$ /$$ /$$ /$$$$$$ /$$$$$$$ /$$$$$$ /$$ /$$ /$$$$$$ /$$$$$$ /$$$$$$$ | $$$$$$$$ /$$__ $$| $$ /$$//$$__ $$| $$__ $$|_ $$_/ | $$ | $$ /$$__ $$ /$$__ $$ /$$_____/ | $$__ $$| $$ | $$ \ $$/$$/| $$$$$$$$| $$ \ $$ | $$ | $$ | $$| $$ \__/| $$$$$$$$| $$$$$$ | $$ | $$| $$ | $$ \ $$$/ | $$_____/| $$ | $$ | $$ /$$| $$ | $$| $$ | $$_____/ \____ $$ | $$ | $$| $$$$$$$ \ $/ | $$$$$$$| $$ | $$ | $$$$/| $$$$$$/| $$ | $$$$$$$ /$$$$$$$/ |__/ |__/ \_______/ \_/ \_______/|__/ |__/ \___/ \______/ |__/ \_______/|_______/ ` lines := strings.Split(title, "\n") defStyle := tcell.StyleDefault.Background(color.Reset).Foreground(color.NewHexColor(0xf3e5ab)) // Initialize screen s, err := tcell.NewScreen() if err != nil { log.Fatalf("%+v", err) } if err := s.Init(); err != nil { log.Fatalf("%+v", err) } s.SetStyle(defStyle) s.Clear() quit := func() { // You have to catch panics in a defer, clean up, and // re-raise them - otherwise your application can // die without leaving any diagnostic trace. maybePanic := recover() s.Fini() if maybePanic != nil { panic(maybePanic) } } defer quit() // Here's how to get the screen size when you need it. // xmax, ymax := s.Size() // Here's an example of how to inject a keystroke where it will // be picked up by a future read of the event queue. Note that // care should be used to avoid blocking writes to the queue if // this is done from the same thread that is responsible for reading // the queue, or else a single-party deadlock might occur. // s.EventQ() <- tcell.NewEventKey(tcell.KeyRune, rune('a'), 0) // Event loop for { // Update screen s.Show() // Poll event (this can be in a select statement as well) ev := <-s.EventQ() xmax, ymax := s.Size() for l:= range lines{ drawText(s,10, l, xmax, ymax, defStyle, lines[l]) } // Process event switch ev := ev.(type) { case *tcell.EventResize: s.Sync() case *tcell.EventKey: if ev.Key() == tcell.KeyEscape || ev.Key() == tcell.KeyCtrlC { return } else if ev.Key() == tcell.KeyCtrlL { s.Sync() } } } }