mirror of
https://github.com/VladimirMarkelov/clui.git
synced 2025-04-26 13:49:01 +08:00
#24 - add docs for Canvas
This commit is contained in:
parent
66d670edea
commit
56cf450553
93
canvas.go
93
canvas.go
@ -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)
|
||||
}
|
||||
|
50
interface.go
50
interface.go
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user