1package main 2 3import ( 4 "github.com/nsf/termbox-go" 5) 6 7var curCol = 0 8var curRune = 0 9var backbuf []termbox.Cell 10var bbw, bbh int 11 12var runes = []rune{' ', '░', '▒', '▓', '█'} 13var colors = []termbox.Attribute{ 14 termbox.ColorBlack, 15 termbox.ColorRed, 16 termbox.ColorGreen, 17 termbox.ColorYellow, 18 termbox.ColorBlue, 19 termbox.ColorMagenta, 20 termbox.ColorCyan, 21 termbox.ColorWhite, 22} 23 24type attrFunc func(int) (rune, termbox.Attribute, termbox.Attribute) 25 26func updateAndDrawButtons(current *int, x, y int, mx, my int, n int, attrf attrFunc) { 27 lx, ly := x, y 28 for i := 0; i < n; i++ { 29 if lx <= mx && mx <= lx+3 && ly <= my && my <= ly+1 { 30 *current = i 31 } 32 r, fg, bg := attrf(i) 33 termbox.SetCell(lx+0, ly+0, r, fg, bg) 34 termbox.SetCell(lx+1, ly+0, r, fg, bg) 35 termbox.SetCell(lx+2, ly+0, r, fg, bg) 36 termbox.SetCell(lx+3, ly+0, r, fg, bg) 37 termbox.SetCell(lx+0, ly+1, r, fg, bg) 38 termbox.SetCell(lx+1, ly+1, r, fg, bg) 39 termbox.SetCell(lx+2, ly+1, r, fg, bg) 40 termbox.SetCell(lx+3, ly+1, r, fg, bg) 41 lx += 4 42 } 43 lx, ly = x, y 44 for i := 0; i < n; i++ { 45 if *current == i { 46 fg := termbox.ColorRed | termbox.AttrBold 47 bg := termbox.ColorDefault 48 termbox.SetCell(lx+0, ly+2, '^', fg, bg) 49 termbox.SetCell(lx+1, ly+2, '^', fg, bg) 50 termbox.SetCell(lx+2, ly+2, '^', fg, bg) 51 termbox.SetCell(lx+3, ly+2, '^', fg, bg) 52 } 53 lx += 4 54 } 55} 56 57func update_and_redraw_all(mx, my int) { 58 termbox.Clear(termbox.ColorDefault, termbox.ColorDefault) 59 if mx != -1 && my != -1 { 60 backbuf[bbw*my+mx] = termbox.Cell{Ch: runes[curRune], Fg: colors[curCol]} 61 } 62 copy(termbox.CellBuffer(), backbuf) 63 _, h := termbox.Size() 64 updateAndDrawButtons(&curRune, 0, 0, mx, my, len(runes), func(i int) (rune, termbox.Attribute, termbox.Attribute) { 65 return runes[i], termbox.ColorDefault, termbox.ColorDefault 66 }) 67 updateAndDrawButtons(&curCol, 0, h-3, mx, my, len(colors), func(i int) (rune, termbox.Attribute, termbox.Attribute) { 68 return ' ', termbox.ColorDefault, colors[i] 69 }) 70 termbox.Flush() 71} 72 73func reallocBackBuffer(w, h int) { 74 bbw, bbh = w, h 75 backbuf = make([]termbox.Cell, w*h) 76} 77 78func main() { 79 err := termbox.Init() 80 if err != nil { 81 panic(err) 82 } 83 defer termbox.Close() 84 termbox.SetInputMode(termbox.InputEsc | termbox.InputMouse) 85 reallocBackBuffer(termbox.Size()) 86 update_and_redraw_all(-1, -1) 87 88mainloop: 89 for { 90 mx, my := -1, -1 91 switch ev := termbox.PollEvent(); ev.Type { 92 case termbox.EventKey: 93 if ev.Key == termbox.KeyEsc { 94 break mainloop 95 } 96 case termbox.EventMouse: 97 if ev.Key == termbox.MouseLeft { 98 mx, my = ev.MouseX, ev.MouseY 99 } 100 case termbox.EventResize: 101 reallocBackBuffer(ev.Width, ev.Height) 102 } 103 update_and_redraw_all(mx, my) 104 } 105} 106