#24 - add docs for Canvas

This commit is contained in:
Vladimir Markelov 2015-10-26 17:19:22 -07:00
parent 66d670edea
commit 56cf450553
2 changed files with 94 additions and 49 deletions

View File

@ -6,15 +6,19 @@ import (
term "github.com/nsf/termbox-go"
)
// Represents an object visible content. Used by Composer to keep all screen info and by Window
/*
FrameBuffer represents an object visible content. Used by Composer to
keep all screen info and by View. All methods of FrameBuffer use relative
corrdinate system that starts at left top FrameBuffer corner as 0,0
*/
type FrameBuffer struct {
buffer [][]term.Cell
w, h int
}
// Creates new buffer
// NewFrameBuffer creates new buffer. Width and height of a new buffer cannot be less than 3
func NewFrameBuffer(w, h int) *FrameBuffer {
if w < 5 || h < 5 {
if w < 3 || h < 3 {
panic(fmt.Sprintf("Invalid size: %vx%v.", w, h))
}
@ -24,17 +28,22 @@ func NewFrameBuffer(w, h int) *FrameBuffer {
return c
}
// Returns current width and height of a buffer
func (fb *FrameBuffer) Size() (int, int) {
// Size returns current size
func (fb *FrameBuffer) Size() (width int, height int) {
return fb.w, fb.h
}
/*
SetSize sets the new FrameBuffer size. If new size does not equal old size then
FrameBuffer is recreated and cleared with default colors. Both FrameBuffer width and
height must be greater than 2
*/
func (fb *FrameBuffer) SetSize(w, h int) {
if w == fb.w && h == fb.h {
return
}
if w < 5 || h < 5 {
if w < 3 || h < 3 {
panic(fmt.Sprintf("Invalid size: %vx%v.", w, h))
}
@ -46,7 +55,7 @@ func (fb *FrameBuffer) SetSize(w, h int) {
}
}
// Fills buffers with color (the buffer is filled with spaces with defined background color)
// Clear fills FrameBuffer with given background color
func (fb *FrameBuffer) Clear(bg term.Attribute) {
s := term.Cell{Ch: ' ', Fg: ColorWhite, Bg: bg}
for y := 0; y < fb.h; y++ {
@ -56,6 +65,7 @@ func (fb *FrameBuffer) Clear(bg term.Attribute) {
}
}
// FillRect fills area of FrameBuffer with user-defined rune and colors
func (fb *FrameBuffer) FillRect(x, y, w, h int, s term.Cell) {
if x < 0 {
w += x
@ -79,6 +89,8 @@ func (fb *FrameBuffer) FillRect(x, y, w, h int, s term.Cell) {
}
}
// Symbol returns current FrameBuffer cell value at given coordinates.
// If coordinates are outside FrameBuffer ok is false
func (fb *FrameBuffer) Symbol(x, y int) (term.Cell, bool) {
if x >= fb.w || x < 0 || y >= fb.h || y < 0 {
return term.Cell{Ch: ' '}, false
@ -87,6 +99,7 @@ func (fb *FrameBuffer) Symbol(x, y int) (term.Cell, bool) {
return fb.buffer[y][x], true
}
// PutSymbol sets value for the FrameBuffer cell: rune and its colors. Returns result of operation: e.g, if the symbol position is outside FrameBuffer the operation fails and the function returns false
func (fb *FrameBuffer) PutSymbol(x, y int, s term.Cell) bool {
if x < 0 || x >= fb.w || y < 0 || y >= fb.h {
return false
@ -96,6 +109,7 @@ func (fb *FrameBuffer) PutSymbol(x, y int, s term.Cell) bool {
return true
}
// PutChar sets value for the FrameBuffer cell: rune and its colors. Returns result of operation: e.g, if the symbol position is outside FrameBuffer the operation fails and the function returns false
func (fb *FrameBuffer) PutChar(x, y int, c rune, fg, bg term.Attribute) bool {
if x < 0 || x >= fb.w || y < 0 || y >= fb.h {
return false
@ -105,7 +119,7 @@ func (fb *FrameBuffer) PutChar(x, y int, c rune, fg, bg term.Attribute) bool {
return true
}
// Draws text line on buffer
// PutText draws horizontal string on FrameBuffer clipping by FrameBuffer boundaries. x and y are starting point, text is a string to display, fg and bg are text and background attributes
func (fb *FrameBuffer) PutText(x, y int, text string, fg, bg term.Attribute) {
width := fb.w
@ -128,7 +142,9 @@ func (fb *FrameBuffer) PutText(x, y int, text string, fg, bg term.Attribute) {
}
}
// Draws vertical text line on buffer
// PutVerticalText draws vertical string on FrameBuffer clipping by
// FrameBuffer boundaries. x and y are starting point, text is a string
// to display, fg and bg are text and background attributes
func (fb *FrameBuffer) PutVerticalText(x, y int, text string, fg, bg term.Attribute) {
height := fb.h
@ -151,33 +167,29 @@ func (fb *FrameBuffer) PutVerticalText(x, y int, text string, fg, bg term.Attrib
}
}
// Draws vertical text line on buffer
func (fb *FrameBuffer) PutTextVertical(x, y int, text string, fg, bg term.Attribute) {
height := fb.h
if (y < 0 && xs.Len(text) <= -y) || x >= fb.w || y > 0 || y >= fb.h {
return
}
if y < 0 {
yy := -y
y = 0
text = xs.Slice(text, yy, -1)
}
text = CutText(text, height)
dy := 0
for _, char := range text {
s := term.Cell{Ch: char, Fg: fg, Bg: bg}
fb.buffer[y+dy][x] = s
dy++
}
}
/*
PutColorizedText draws multicolor string on Canvas clipping by Canvas boundaries.
Multiline is not supported. Align feature is limited: the text is aligned only if it is
shorter than maximum width, and displayed left aligned otherwise.
Various parts of text can be colorized with html-like tags. Every tag must start with '<'
followed by tag type and colon(without space between them), atrribute in human redable form,
and closing '>'.
Available tags are:
'f' & 't' - sets new text color
'b' - sets new background color
Available attributes (it is possible to write a few attributes for one tag separated with space):
empty string - reset the color to default value (that is passed as argument)
'bold' or 'bright' - bold or brigther color(depends on terminal)
'underline' and 'underlined' - underined text(not every terminal can do it)
'reversed' - reversed text and background
other available attributes are color names: black, red, green, yellow, blue, magenta, cyan, white.
Example: PutColorizedText(0, 0, 10, "<t:red bold><b:yellow>E<t:>xample, ColorBlack, ColorWhite, Horizontal, AlignLeft)
It displays red letter 'C' on a yellow background, then switch text color to default one and draws
other letters in black text and yellow background colors. Default background color is not used, so
it can be set as ColroDefault in a method call
*/
func (fb *FrameBuffer) PutColorizedText(x, y, max int, text string, fg, bg term.Attribute, dir Direction, align Align) {
// file, _ := os.OpenFile("debugui.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
// logger := log.New(file, "", log.Ldate|log.Ltime|log.Lshortfile)
sReal := UnColorizeText(text)
var dx, dy int
if dir == Horizontal {
@ -193,7 +205,6 @@ func (fb *FrameBuffer) PutColorizedText(x, y, max int, text string, fg, bg term.
parser := NewColorParser(text, fg, bg)
elem := parser.NextElement()
for elem.Type != ElemEndOfText && max > 0 {
// logger.Printf("ELEM: %v", elem)
if elem.Type == ElemPrintable {
fb.PutChar(x, y, elem.Ch, elem.Fg, elem.Bg)
x += dx
@ -205,6 +216,12 @@ func (fb *FrameBuffer) PutColorizedText(x, y, max int, text string, fg, bg term.
}
}
/*
DrawFrame paints a frame inside FrameBuffer with optional border
rune set(by default, in case of border is empty string, the rune set
equals "─│┌┐└┘" - single border). The inner area of frame is not
filled - in other words it is transparent
*/
func (fb *FrameBuffer) DrawFrame(x, y, w, h int, fg, bg term.Attribute, frameChars string) {
if h < 1 || w < 1 {
return
@ -249,7 +266,11 @@ func (fb *FrameBuffer) DrawFrame(x, y, w, h int, fg, bg term.Attribute, frameCha
}
}
// x, y - absolute console coordinates
/*
SetCursorPos sets text caret position. In opposite to other FrameBuffer
methods, x and y - are absolute console coordinates. Use negative values
if you want to hide the caret. Used by controls like EditField
*/
func (fb *FrameBuffer) SetCursorPos(x, y int) {
term.SetCursor(x, y)
}

View File

@ -5,26 +5,50 @@ import (
"log"
)
/*
Screen is a core of the library. It dispatches keyboard and mouse messages, supports theming, and manages views
*/
type Screen interface {
// Theme returns the current color theme
Theme() Theme
PutEvent(Event)
DestroyView(View)
// PutEvent sends an event directly to the the event loop. It is used by some controls to ask Screen to repaint console
PutEvent(event Event)
// DestroyView removes view from the view list and makes the next view in the view stack active. It is not possible to destroy the last view - Screen must have at least one visible view
DestroyView(view View)
Logger() *log.Logger
}
/*
Canvas is a 'graphical' buffer than represents a View or Screen. Its size equal size of parent object and supports a full set of painting methods
*/
type Canvas interface {
SetSize(int, int)
Size() (int, int)
PutSymbol(int, int, term.Cell) bool
PutText(int, int, string, term.Attribute, term.Attribute)
PutVerticalText(int, int, string, term.Attribute, term.Attribute)
PutColorizedText(int, int, int, string, term.Attribute, term.Attribute, Direction, Align)
Symbol(int, int) (term.Cell, bool)
Clear(term.Attribute)
FillRect(int, int, int, int, term.Cell)
DrawFrame(int, int, int, int, term.Attribute, term.Attribute, string)
SetCursorPos(int, int)
// SetSize sets the new Canvas size. If new size does not equal old size then Canvas is recreated and cleared with default colors. Both Canvas width and height must be greater than 2
SetSize(width int, height int)
// Size returns current Canvas size
Size() (width int, height int)
// PutSymbol sets value for the Canvas cell: rune and its colors. Returns result of operation: e.g, if the symbol position is outside Canvas the operation fails and the function returns false
PutSymbol(x int, y int, symbol term.Cell) bool
// PutText draws horizontal string on Canvas clipping by Canvas boundaries. x and y are starting point, text is a string to display, fg and bg are text and background attributes
PutText(x int, y int, text string, fg term.Attribute, bg term.Attribute)
// PutVerticalText draws vertical string on Canvas clipping by Canvas boundaries. x and y are starting point, text is a string to display, fg and bg are text and background attributes
PutVerticalText(x int, y int, text string, fg term.Attribute, bg term.Attribute)
/*
PutColorizedText draws multicolor string on Canvas clipping by Canvas boundaries.
Multiline is not supported. Align feature is limited: the text is aligned only if it is
shorter than maximum width, and displayed left aligned otherwise
*/
PutColorizedText(x int, y int, maxWidth int, text string, fg term.Attribute, bg term.Attribute, dir Direction, align Align)
// Symbol returns current Canvas cell value at given coordinates. If coordinates are outside Canvas ok is false
Symbol(x int, y int) (symbol term.Cell, ok bool)
// Clear fills Canvas with given background color
Clear(bg term.Attribute)
// FillRect fills area of Canvas with user-defined rune and colors
FillRect(x int, y int, width int, height int, symbol term.Cell)
// DrawFrame paints a frame inside Canvas with optional border rune set(by default, in case of border is empty string, the rune set equals "─│┌┐└┘" - single border). The inner area of frame is not filled - in other words it is transparent
DrawFrame(x int, y int, width int, height int, fg term.Attribute, bg term.Attribute, border string)
// SetCursorPos sets text caret position. Used by controls like EditField
SetCursorPos(x int, y int)
}
type Theme interface {