package clui import ( "fmt" xs "github.com/huandu/xstrings" ) // Represents an object visible content. Used by Composer to keep all screen info and by Window type FrameBuffer struct { buffer [][]Symbol w, h int } // Returns current width and height of a buffer func (fb *FrameBuffer) GetSize() (int, int) { return fb.w, fb.h } // Creates new buffer func NewFrameBuffer(w, h int) *FrameBuffer { if w < 5 || h < 5 { panic(fmt.Sprintf("Invalid buffer size: %vx%v.", w, h)) } c := new(FrameBuffer) c.w = w c.h = h c.buffer = make([][]Symbol, h) for i := 0; i < h; i++ { c.buffer[i] = make([]Symbol, w) } return c } // Fills buffers with color (the buffer is filled with spaces with defined background color) func (fb *FrameBuffer) Clear(bg Color) { s := Symbol{ch: ' ', fg: ColorWhite, bg: bg} for y := 0; y < fb.h; y++ { for x := 0; x < fb.w; x++ { fb.buffer[y][x] = s } } } func (fb *FrameBuffer) GetSymbol(x, y int) (Symbol, bool) { if x >= fb.w || x < 0 || y >= fb.h || y < 0 { return Symbol{ch: ' '}, false } else { return fb.buffer[y][x], true } } // Draws a text on a buffer, the method does not do any checks, never use it directly func (fb *FrameBuffer) rawTextOut(x, y int, text string, fg, bg Color) { dx := 0 for _, char := range text { s := Symbol{ch: char, fg: fg, bg: bg} fb.buffer[y][x+dx] = s dx++ } } // Draws a character on a buffer. There is no check, so never use it directly func (fb *FrameBuffer) rawRuneOut(x, y int, r rune, fg, bg Color) { s := Symbol{ch: r, fg: fg, bg: bg} fb.buffer[y][x] = s } // Draws text line on buffer func (fb *FrameBuffer) PutText(x, y int, text string, fg, bg Color) { // TODO: check for invalid x and y, and cutting must pay attention to x and y width := fb.w fb.rawTextOut(x, y, CutText(text, width), fg, bg) } func countBits(bt int) int { cnt := 0 for i := uint(0); i < 16; i++ { if (1<= w || y >= h || y < 0 || x+len(text) < 0 { return } length := xs.Len(text) if x+length < 0 { return } if x < 0 { text = xs.Slice(text, -x, -1) } if x+length >= w { text = xs.Slice(text, 0, w-x) } fb.rawTextOut(x+dx, y+dy, text, fg, bg) }