Merge branch 'master' into develop

pull/110/head
levko-burburas 6 years ago committed by GitHub
commit 76f71ddc98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -64,6 +64,8 @@ Add your issue here on GitHub. Feel free to get in touch if you have any questio
(There are no corresponding tags in the project. I only keep such a history in this README.)
- v0.15 (2018-05-02)
- `Flex` and `Grid` don't clear their background per default, thus allowing for custom modals. See the [Wiki](https://github.com/rivo/tview/wiki/Modal) for an example.
- v0.14 (2018-04-13)
- Added an `Escape()` function which keep strings like color or region tags from being recognized as such.
- Added `ANSIIWriter()` and `TranslateANSII()` which convert ANSII escape sequences to `tview` color tags.

@ -302,9 +302,12 @@ func (b *Box) Draw(screen tcell.Screen) {
// Fill background.
background := def.Background(b.backgroundColor)
for y := b.y; y < b.y+height; y++ {
for x := b.x; x < b.x+width; x++ {
screen.SetContent(x, y, ' ', nil, background)
if b.backgroundColor != tcell.ColorDefault {
for y := b.y; y < b.y+b.height; y++ {
for x := b.x; x < b.x+b.width; x++ {
screen.SetContent(x, y, ' ', nil, background)
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

@ -33,17 +33,24 @@ type Flex struct {
// FlexRow or FlexColumn.
direction int
// If set to true, will use the entire screen as its available space instead
// its box dimensions.
// If set to true, Flex will use the entire screen as its available space
// instead its box dimensions.
fullScreen bool
}
// NewFlex returns a new flexbox layout container with no primitives and its
// direction set to FlexColumn. To add primitives to this layout, see AddItem().
// To change the direction, see SetDirection().
//
// Note that Box, the superclass of Flex, will have its background color set to
// transparent so that any nil flex items will leave their background unchanged.
// To clear a Flex's background before any items are drawn, set it to the
// desired color:
//
// flex.SetBackgroundColor(tview.Styles.PrimitiveBackgroundColor)
func NewFlex() *Flex {
f := &Flex{
Box: NewBox(),
Box: NewBox().SetBackgroundColor(tcell.ColorDefault),
direction: FlexColumn,
}
f.focus = f
@ -102,8 +109,6 @@ func (f *Flex) RemoveItem(p Primitive) *Flex {
// Draw draws this primitive onto the screen.
func (f *Flex) Draw(screen tcell.Screen) {
f.Box.Draw(screen)
// Calculate size and position of the items.
// Do we use the entire screen?

@ -59,9 +59,16 @@ type Grid struct {
}
// NewGrid returns a new grid-based layout container with no initial primitives.
//
// Note that Box, the superclass of Grid, will have its background color set to
// transparent so that any grid areas not covered by any primitives will leave
// their background unchanged. To clear a Grid's background before any items are
// drawn, set it to the desired color:
//
// grid.SetBackgroundColor(tview.Styles.PrimitiveBackgroundColor)
func NewGrid() *Grid {
g := &Grid{
Box: NewBox(),
Box: NewBox().SetBackgroundColor(tcell.ColorDefault),
bordersColor: Styles.GraphicsColor,
}
g.focus = g

@ -367,6 +367,7 @@ func (i *InputField) Draw(screen tcell.Screen) {
text := i.text
if text == "" && i.placeholder != "" {
Print(screen, i.placeholder, x, y, fieldWidth, AlignLeft, i.placeholderTextColor)
}
textWidth := runewidth.StringWidth(text)

@ -832,10 +832,60 @@ func (t *TextView) Draw(screen tcell.Screen) {
}
// Print the line.
var currentTag, currentRegion, currentEscapeTag, skipped int
var currentTag, currentRegion, currentEscapeTag, skipped, runeSeqWidth int
runeSequence := make([]rune, 0, 10)
flush := func() {
if len(runeSequence) == 0 {
return
}
// Mix the existing style with the new style.
_, _, existingStyle, _ := screen.GetContent(x+posX, y+line-t.lineOffset)
_, background, _ := existingStyle.Decompose()
style := overlayStyle(background, defaultStyle, foregroundColor, backgroundColor, attributes)
// Do we highlight this character?
var highlighted bool
if len(regionID) > 0 {
if _, ok := t.highlights[regionID]; ok {
highlighted = true
}
}
if highlighted {
fg, bg, _ := style.Decompose()
if bg == tcell.ColorDefault {
r, g, b := fg.RGB()
c := colorful.Color{R: float64(r) / 255, G: float64(g) / 255, B: float64(b) / 255}
_, _, li := c.Hcl()
if li < .5 {
bg = tcell.ColorWhite
} else {
bg = tcell.ColorBlack
}
}
style = style.Background(fg).Foreground(bg)
}
// Draw the character.
var comb []rune
if len(runeSequence) > 1 {
// Allocate space for the combining characters only when necessary.
comb = make([]rune, len(runeSequence)-1)
copy(comb, runeSequence[1:])
}
for offset := 0; offset < runeSeqWidth; offset++ {
screen.SetContent(x+posX+offset, y+line-t.lineOffset, runeSequence[0], comb, style)
}
// Advance.
posX += runeSeqWidth
runeSequence = runeSequence[:0]
runeSeqWidth = 0
}
for pos, ch := range text {
// Get the color.
if currentTag < len(colorTags) && pos >= colorTagIndices[currentTag][0] && pos < colorTagIndices[currentTag][1] {
flush()
if pos == colorTagIndices[currentTag][1]-1 {
foregroundColor, backgroundColor, attributes = styleFromTag(foregroundColor, backgroundColor, attributes, colorTags[currentTag])
currentTag++
@ -845,6 +895,7 @@ func (t *TextView) Draw(screen tcell.Screen) {
// Get the region.
if currentRegion < len(regionIndices) && pos >= regionIndices[currentRegion][0] && pos < regionIndices[currentRegion][1] {
flush()
if pos == regionIndices[currentRegion][1]-1 {
regionID = regions[currentRegion][1]
currentRegion++
@ -854,6 +905,7 @@ func (t *TextView) Draw(screen tcell.Screen) {
// Skip the second-to-last character of an escape tag.
if currentEscapeTag < len(escapeIndices) && pos >= escapeIndices[currentEscapeTag][0] && pos < escapeIndices[currentEscapeTag][1] {
flush()
if pos == escapeIndices[currentEscapeTag][1]-1 {
currentEscapeTag++
} else if pos == escapeIndices[currentEscapeTag][1]-2 {
@ -864,7 +916,14 @@ func (t *TextView) Draw(screen tcell.Screen) {
// Determine the width of this rune.
chWidth := runewidth.RuneWidth(ch)
if chWidth == 0 {
continue
// If this is not a modifier, we treat it as a space character.
if len(runeSequence) == 0 {
ch = ' '
chWidth = 1
} else {
runeSequence = append(runeSequence, ch)
continue
}
}
// Skip to the right.
@ -874,15 +933,12 @@ func (t *TextView) Draw(screen tcell.Screen) {
}
// Stop at the right border.
if posX+chWidth > width {
if posX+runeSeqWidth+chWidth > width {
break
}
// Mix the existing style with the new style.
_, _, existingStyle, _ := screen.GetContent(x+posX, y+line-t.lineOffset)
_, background, _ := existingStyle.Decompose()
style := overlayStyle(background, defaultStyle, foregroundColor, backgroundColor, attributes)
// Flush the rune sequence.
flush()
// Do we highlight this character?
var highlighted bool
if len(regionID) > 0 {

@ -339,6 +339,9 @@ func printWithStyle(screen tcell.Screen, text string, x, y, maxWidth, align int,
width += w
start = index
}
for runewidth.RuneWidth(runes[start]) == 0 && start < len(runes) {
start++
}
return printWithStyle(screen, substring(start, len(runes)), x+maxWidth-width, y, width, AlignLeft, style)
} else if align == AlignCenter {
width := runewidth.StringWidth(strippedText)
@ -354,12 +357,15 @@ func printWithStyle(screen tcell.Screen, text string, x, y, maxWidth, align int,
var choppedLeft, choppedRight, leftIndex, rightIndex int
rightIndex = len(runes) - 1
for rightIndex > leftIndex && width-choppedLeft-choppedRight > maxWidth {
leftWidth := runewidth.RuneWidth(runes[leftIndex])
rightWidth := runewidth.RuneWidth(runes[rightIndex])
if choppedLeft < choppedRight {
leftWidth := runewidth.RuneWidth(runes[leftIndex])
choppedLeft += leftWidth
leftIndex++
for runewidth.RuneWidth(runes[leftIndex]) == 0 && leftIndex < len(runes) && leftIndex < rightIndex {
leftIndex++
}
} else {
rightWidth := runewidth.RuneWidth(runes[rightIndex])
choppedRight += rightWidth
rightIndex--
}
@ -375,9 +381,39 @@ func printWithStyle(screen tcell.Screen, text string, x, y, maxWidth, align int,
colorPos, escapePos int
foregroundColor, backgroundColor, attributes string
)
runeSequence := make([]rune, 0, 10)
runeSeqWidth := 0
flush := func() {
if len(runeSequence) == 0 {
return // Nothing to flush.
}
// Print the rune sequence.
finalX := x + drawnWidth
_, _, finalStyle, _ := screen.GetContent(finalX, y)
_, background, _ := finalStyle.Decompose()
finalStyle = overlayStyle(background, style, foregroundColor, backgroundColor, attributes)
var comb []rune
if len(runeSequence) > 1 {
// Allocate space for the combining characters only when necessary.
comb = make([]rune, len(runeSequence)-1)
copy(comb, runeSequence[1:])
}
for offset := 0; offset < runeSeqWidth; offset++ {
// To avoid undesired effects, we place the same character in all cells.
screen.SetContent(finalX+offset, y, runeSequence[0], comb, finalStyle)
}
// Advance and reset.
drawn += len(runeSequence)
drawnWidth += runeSeqWidth
runeSequence = runeSequence[:0]
runeSeqWidth = 0
}
for pos, ch := range text {
// Handle color tags.
if colorPos < len(colorIndices) && pos >= colorIndices[colorPos][0] && pos < colorIndices[colorPos][1] {
flush()
if pos == colorIndices[colorPos][1]-1 {
foregroundColor, backgroundColor, attributes = styleFromTag(foregroundColor, backgroundColor, attributes, colors[colorPos])
colorPos++
@ -387,6 +423,7 @@ func printWithStyle(screen tcell.Screen, text string, x, y, maxWidth, align int,
// Handle escape tags.
if escapePos < len(escapeIndices) && pos >= escapeIndices[escapePos][0] && pos < escapeIndices[escapePos][1] {
flush()
if pos == escapeIndices[escapePos][1]-1 {
escapePos++
} else if pos == escapeIndices[escapePos][1]-2 {
@ -397,21 +434,26 @@ func printWithStyle(screen tcell.Screen, text string, x, y, maxWidth, align int,
// Check if we have enough space for this rune.
chWidth := runewidth.RuneWidth(ch)
if drawnWidth+chWidth > maxWidth {
break
break // No. We're done then.
}
finalX := x + drawnWidth
// Print the rune.
_, _, finalStyle, _ := screen.GetContent(finalX, y)
_, background, _ := finalStyle.Decompose()
finalStyle = overlayStyle(background, style, foregroundColor, backgroundColor, attributes)
for offset := 0; offset < chWidth; offset++ {
// To avoid undesired effects, we place the same character in all cells.
screen.SetContent(finalX+offset, y, ch, nil, finalStyle)
// Put this rune in the queue.
if chWidth == 0 {
// If this is not a modifier, we treat it as a space character.
if len(runeSequence) == 0 {
ch = ' '
chWidth = 1
}
} else {
// We have a character. Flush all previous runes.
flush()
}
runeSequence = append(runeSequence, ch)
runeSeqWidth += chWidth
drawn++
drawnWidth += chWidth
}
if drawnWidth+runeSeqWidth <= maxWidth {
flush()
}
return drawn, drawnWidth

Loading…
Cancel
Save