1
0
mirror of https://github.com/gizak/termui.git synced 2025-04-24 13:48:50 +08:00

Added support to GetText() and GetRawText() functions in textbox widget

This commit is contained in:
Andre Magalhaes 2019-03-19 11:52:42 -04:00
parent 08e68490f3
commit 24f4cc3260
7 changed files with 173 additions and 0 deletions

1
go.mod
View File

@ -7,6 +7,7 @@ require (
github.com/mattn/go-runewidth v0.0.2
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d
github.com/stretchr/testify v1.3.0
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 // indirect
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b // indirect
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e // indirect

7
go.sum
View File

@ -1,5 +1,7 @@
github.com/cjbassi/drawille-go v0.0.0-20190126131713-27dc511fe6fd h1:XtfPmj9tQRilnrEmI1HjQhxXWRhEM+m8CACtaMJE/kM=
github.com/cjbassi/drawille-go v0.0.0-20190126131713-27dc511fe6fd/go.mod h1:vjcQJUZJYD3MeVGhtZXSMnCHfUNZxsyYzJt90eCYxK4=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/pprof v0.0.0-20190109223431-e84dfd68c163 h1:beB+Da4k9B1zmgag78k3k1Bx4L/fdWr5FwNa0f8RxmY=
github.com/google/pprof v0.0.0-20190109223431-e84dfd68c163/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c=
@ -10,6 +12,11 @@ github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzC
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d h1:x3S6kxmy49zXVVyhcnrFqxvNVCBPb2KZ9hV2RBdS840=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 h1:Pn8fQdvx+z1avAi7fdM2kRYWQNxGlavNDSyzrQg2SsU=
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8=
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b h1:Elez2XeF2p9uyVj0yEUDqQ56NFcDtcBNkYP7yv8YbUE=

View File

@ -1,5 +1,7 @@
package termui
import "strings"
// Color is an integer from -1 to 255
// -1 = ColorClear
// 0-255 = Xterm colors
@ -63,3 +65,22 @@ func NewStyle(fg Color, args ...interface{}) Style {
modifier,
}
}
//String returns a string representation of a Style
func (self Style) String() string {
styles := make([]string, 0)
if color, ok := textColorMap[self.Fg]; ok && self.Fg != StyleClear.Fg {
styles = append(styles, tokenFg + tokenValueSeparator + color)
}
if color, ok := textColorMap[self.Bg]; ok && self.Bg != StyleClear.Bg {
styles = append(styles, tokenBg + tokenValueSeparator + color)
}
if mod, ok := textModifierMap[self.Modifier]; ok && self.Modifier != StyleClear.Modifier {
styles = append(styles, tokenModifier + tokenValueSeparator + mod)
}
return strings.Join(styles, tokenItemSeparator)
}

View File

@ -44,12 +44,30 @@ var StyleParserColorMap = map[string]Color{
"magenta": ColorMagenta,
}
var textColorMap = map[Color]string{
ColorRed: "red",
ColorBlue: "blue",
ColorBlack: "black",
ColorCyan: "cyan",
ColorYellow: "yellow",
ColorWhite: "white",
ColorClear: "clear",
ColorGreen: "green",
ColorMagenta: "magenta",
}
var modifierMap = map[string]Modifier{
"bold": ModifierBold,
"underline": ModifierUnderline,
"reverse": ModifierReverse,
}
var textModifierMap = map[Modifier]string{
ModifierBold: "bold",
ModifierUnderline: "underline",
ModifierReverse: "reverse",
}
// readStyle translates an []rune like `fg:red,mod:bold,bg:white` to a style
func readStyle(runes []rune, defaultStyle Style) Style {
style := defaultStyle

View File

@ -8,6 +8,7 @@ import (
"fmt"
"math"
"reflect"
"strings"
rw "github.com/mattn/go-runewidth"
wordwrap "github.com/mitchellh/go-wordwrap"
@ -187,6 +188,40 @@ func RunesToStyledCells(runes []rune, style Style) []Cell {
return cells
}
//CellsToText converts []Cell to a string without any formatting tags
func CellsToText(cells []Cell) string {
runes := make([]rune, len(cells))
for i, cell := range cells {
runes[i] = cell.Rune
}
return string(runes)
}
//CellsToStyledText converts []Cell to a string preserving the formatting tags
func CellsToStyledText(cells []Cell, defaultStyle Style) string {
sb := strings.Builder{}
runes := make([]rune, len(cells))
currentStyle := cells[0].Style
var j int
for _, cell := range cells {
if currentStyle != cell.Style {
writeText(&sb, runes[:j], currentStyle, defaultStyle)
currentStyle = cell.Style
j=0
}
runes[j] = cell.Rune
j++
}
//Write the last characters left in runes slice
writeText(&sb, runes[:j], currentStyle, defaultStyle)
return sb.String()
}
func CellsToString(cells []Cell) string {
runes := make([]rune, len(cells))
for i, cell := range cells {
@ -195,6 +230,19 @@ func CellsToString(cells []Cell) string {
return string(runes)
}
func writeText(sb *strings.Builder,runes []rune, currentStyle Style, defaultStyle Style) {
if currentStyle != defaultStyle {
sb.WriteByte(tokenBeginStyledText)
sb.WriteString(string(runes))
sb.WriteByte(tokenEndStyledText)
sb.WriteByte(tokenBeginStyle)
sb.WriteString(currentStyle.String())
sb.WriteByte(tokenEndStyle)
} else {
sb.WriteString(string(runes))
}
}
func TrimCells(cells []Cell, w int) []Cell {
s := CellsToString(cells)
s = TrimString(s, w)
@ -221,6 +269,22 @@ func SplitCells(cells []Cell, r rune) [][]Cell {
return splitCells
}
//JoinCells converts [][]cell to a []cell using r as line breaker
func JoinCells(cells [][]Cell, r rune) []Cell {
joinCells := make([]Cell, 0)
lb := Cell{Rune: r}
length := len(cells)
for i, cell := range cells {
if i < length - 1 {
cell = append(cell, lb)
}
joinCells = append(joinCells, cell...)
}
return joinCells
}
type CellWithX struct {
X int
Cell Cell

View File

@ -116,6 +116,20 @@ func (self *TextBox) SetText(input string) {
self.InsertText(input)
}
//GetText gets the text in string format along all its formatting tags
func (self *TextBox) Text() string {
cells := JoinCells(self.text, '\n')
return CellsToStyledText(cells, self.TextStyle)
}
//GetText gets the text in string format without any formatting tags
func (self *TextBox) RawText() string {
cells := JoinCells(self.text, '\n')
return CellsToText(cells)
}
func (self *TextBox) MoveCursorLeft() {
self.MoveCursor(self.cursorPoint.X-1, self.cursorPoint.Y)
}

48
widgets/textbox_test.go Normal file
View File

@ -0,0 +1,48 @@
package widgets
import (
"testing"
"github.com/stretchr/testify/assert"
)
//TestGetRawText test simple string
func TestGetRawText(t *testing.T) {
text := "My Sample RawText"
tb := NewTextBox()
tb.SetText(text)
assert.Equal(t, text, tb.RawText())
}
//TestGetRawTextWithLBs test line breaks in the text
func TestGetRawTextWithLBs(t *testing.T) {
text := `My Sample RawText
with
line
breaks`
tb := NewTextBox()
tb.SetText(text)
assert.Equal(t, text, tb.RawText())
}
//TestGetStyledText test styled text
func TestGetStyledText(t *testing.T) {
text := "[red text](fg:red,mod:bold) more text [blue text](fg:blue,mod:bold) a bit more"
tb := NewTextBox()
tb.SetText(text)
assert.Equal(t, text, tb.Text())
}
//TestGetStyledText2 test styled text ending in a styled string
func TestGetStyledText2(t *testing.T) {
text := "[red text](fg:red,mod:bold) more text [blue text](fg:blue,mod:bold) a [bit more](fg:black)"
tb := NewTextBox()
tb.SetText(text)
assert.Equal(t, text, tb.Text())
}