mirror of
https://github.com/rivo/tview.git
synced 2025-04-28 13:48:53 +08:00
The inner area of a Box does not clamp to screen borders anymore. Consequently added some drawing optimization to primitives. Resolves #405
This commit is contained in:
parent
fe30520195
commit
ba670d23ba
23
box.go
23
box.go
@ -314,29 +314,6 @@ func (b *Box) Draw(screen tcell.Screen) {
|
|||||||
b.innerX = -1
|
b.innerX = -1
|
||||||
b.innerX, b.innerY, b.innerWidth, b.innerHeight = b.GetInnerRect()
|
b.innerX, b.innerY, b.innerWidth, b.innerHeight = b.GetInnerRect()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clamp inner rect to screen.
|
|
||||||
width, height := screen.Size()
|
|
||||||
if b.innerX < 0 {
|
|
||||||
b.innerWidth += b.innerX
|
|
||||||
b.innerX = 0
|
|
||||||
}
|
|
||||||
if b.innerX+b.innerWidth >= width {
|
|
||||||
b.innerWidth = width - b.innerX
|
|
||||||
}
|
|
||||||
if b.innerY+b.innerHeight >= height {
|
|
||||||
b.innerHeight = height - b.innerY
|
|
||||||
}
|
|
||||||
if b.innerY < 0 {
|
|
||||||
b.innerHeight += b.innerY
|
|
||||||
b.innerY = 0
|
|
||||||
}
|
|
||||||
if b.innerWidth < 0 {
|
|
||||||
b.innerWidth = 0
|
|
||||||
}
|
|
||||||
if b.innerHeight < 0 {
|
|
||||||
b.innerHeight = 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Focus is called when this primitive receives focus.
|
// Focus is called when this primitive receives focus.
|
||||||
|
4
list.go
4
list.go
@ -394,6 +394,10 @@ func (l *List) Draw(screen tcell.Screen) {
|
|||||||
// Determine the dimensions.
|
// Determine the dimensions.
|
||||||
x, y, width, height := l.GetInnerRect()
|
x, y, width, height := l.GetInnerRect()
|
||||||
bottomLimit := y + height
|
bottomLimit := y + height
|
||||||
|
_, totalHeight := screen.Size()
|
||||||
|
if bottomLimit > totalHeight {
|
||||||
|
bottomLimit = totalHeight
|
||||||
|
}
|
||||||
|
|
||||||
// Do we show any shortcuts?
|
// Do we show any shortcuts?
|
||||||
var showShortcuts bool
|
var showShortcuts bool
|
||||||
|
3
table.go
3
table.go
@ -563,6 +563,7 @@ func (t *Table) Draw(screen tcell.Screen) {
|
|||||||
t.Box.Draw(screen)
|
t.Box.Draw(screen)
|
||||||
|
|
||||||
// What's our available screen space?
|
// What's our available screen space?
|
||||||
|
_, totalHeight := screen.Size()
|
||||||
x, y, width, height := t.GetInnerRect()
|
x, y, width, height := t.GetInnerRect()
|
||||||
if t.borders {
|
if t.borders {
|
||||||
t.visibleRows = height / 2
|
t.visibleRows = height / 2
|
||||||
@ -800,7 +801,7 @@ ColumnLoop:
|
|||||||
}
|
}
|
||||||
drawBorder(columnX, rowY, ch)
|
drawBorder(columnX, rowY, ch)
|
||||||
rowY++
|
rowY++
|
||||||
if rowY >= height {
|
if rowY >= height || y+rowY >= totalHeight {
|
||||||
break // No space for the text anymore.
|
break // No space for the text anymore.
|
||||||
}
|
}
|
||||||
drawBorder(columnX, rowY, Borders.Vertical)
|
drawBorder(columnX, rowY, Borders.Vertical)
|
||||||
|
145
textview.go
145
textview.go
@ -752,6 +752,7 @@ func (t *TextView) Draw(screen tcell.Screen) {
|
|||||||
t.Lock()
|
t.Lock()
|
||||||
defer t.Unlock()
|
defer t.Unlock()
|
||||||
t.Box.Draw(screen)
|
t.Box.Draw(screen)
|
||||||
|
totalWidth, totalHeight := screen.Size()
|
||||||
|
|
||||||
// Get the available size.
|
// Get the available size.
|
||||||
x, y, width, height := t.GetInnerRect()
|
x, y, width, height := t.GetInnerRect()
|
||||||
@ -838,7 +839,7 @@ func (t *TextView) Draw(screen tcell.Screen) {
|
|||||||
defaultStyle := tcell.StyleDefault.Foreground(t.textColor)
|
defaultStyle := tcell.StyleDefault.Foreground(t.textColor)
|
||||||
for line := t.lineOffset; line < len(t.index); line++ {
|
for line := t.lineOffset; line < len(t.index); line++ {
|
||||||
// Are we done?
|
// Are we done?
|
||||||
if line-t.lineOffset >= height {
|
if line-t.lineOffset >= height || y+line-t.lineOffset >= totalHeight {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -868,82 +869,84 @@ func (t *TextView) Draw(screen tcell.Screen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Print the line.
|
// Print the line.
|
||||||
var colorPos, regionPos, escapePos, tagOffset, skipped int
|
if y+line-t.lineOffset >= 0 {
|
||||||
iterateString(strippedText, func(main rune, comb []rune, textPos, textWidth, screenPos, screenWidth int) bool {
|
var colorPos, regionPos, escapePos, tagOffset, skipped int
|
||||||
// Process tags.
|
iterateString(strippedText, func(main rune, comb []rune, textPos, textWidth, screenPos, screenWidth int) bool {
|
||||||
for {
|
// Process tags.
|
||||||
if colorPos < len(colorTags) && textPos+tagOffset >= colorTagIndices[colorPos][0] && textPos+tagOffset < colorTagIndices[colorPos][1] {
|
for {
|
||||||
// Get the color.
|
if colorPos < len(colorTags) && textPos+tagOffset >= colorTagIndices[colorPos][0] && textPos+tagOffset < colorTagIndices[colorPos][1] {
|
||||||
foregroundColor, backgroundColor, attributes = styleFromTag(foregroundColor, backgroundColor, attributes, colorTags[colorPos])
|
// Get the color.
|
||||||
tagOffset += colorTagIndices[colorPos][1] - colorTagIndices[colorPos][0]
|
foregroundColor, backgroundColor, attributes = styleFromTag(foregroundColor, backgroundColor, attributes, colorTags[colorPos])
|
||||||
colorPos++
|
tagOffset += colorTagIndices[colorPos][1] - colorTagIndices[colorPos][0]
|
||||||
} else if regionPos < len(regionIndices) && textPos+tagOffset >= regionIndices[regionPos][0] && textPos+tagOffset < regionIndices[regionPos][1] {
|
colorPos++
|
||||||
// Get the region.
|
} else if regionPos < len(regionIndices) && textPos+tagOffset >= regionIndices[regionPos][0] && textPos+tagOffset < regionIndices[regionPos][1] {
|
||||||
regionID = regions[regionPos][1]
|
// Get the region.
|
||||||
tagOffset += regionIndices[regionPos][1] - regionIndices[regionPos][0]
|
regionID = regions[regionPos][1]
|
||||||
regionPos++
|
tagOffset += regionIndices[regionPos][1] - regionIndices[regionPos][0]
|
||||||
} else {
|
regionPos++
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip the second-to-last character of an escape tag.
|
|
||||||
if escapePos < len(escapeIndices) && textPos+tagOffset == escapeIndices[escapePos][1]-2 {
|
|
||||||
tagOffset++
|
|
||||||
escapePos++
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 {
|
} else {
|
||||||
bg = tcell.ColorBlack
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
style = style.Background(fg).Foreground(bg)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip to the right.
|
// Skip the second-to-last character of an escape tag.
|
||||||
if !t.wrap && skipped < skip {
|
if escapePos < len(escapeIndices) && textPos+tagOffset == escapeIndices[escapePos][1]-2 {
|
||||||
skipped += screenWidth
|
tagOffset++
|
||||||
return false
|
escapePos++
|
||||||
}
|
|
||||||
|
|
||||||
// Stop at the right border.
|
|
||||||
if posX+screenWidth > width {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the character.
|
|
||||||
for offset := screenWidth - 1; offset >= 0; offset-- {
|
|
||||||
if offset == 0 {
|
|
||||||
screen.SetContent(x+posX+offset, y+line-t.lineOffset, main, comb, style)
|
|
||||||
} else {
|
|
||||||
screen.SetContent(x+posX+offset, y+line-t.lineOffset, ' ', nil, style)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Advance.
|
// Mix the existing style with the new style.
|
||||||
posX += screenWidth
|
_, _, existingStyle, _ := screen.GetContent(x+posX, y+line-t.lineOffset)
|
||||||
return false
|
_, 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip to the right.
|
||||||
|
if !t.wrap && skipped < skip {
|
||||||
|
skipped += screenWidth
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop at the right border.
|
||||||
|
if posX+screenWidth > width || x+posX >= totalWidth {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the character.
|
||||||
|
for offset := screenWidth - 1; offset >= 0; offset-- {
|
||||||
|
if offset == 0 {
|
||||||
|
screen.SetContent(x+posX+offset, y+line-t.lineOffset, main, comb, style)
|
||||||
|
} else {
|
||||||
|
screen.SetContent(x+posX+offset, y+line-t.lineOffset, ' ', nil, style)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Advance.
|
||||||
|
posX += screenWidth
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this view is not scrollable, we'll purge the buffer of lines that have
|
// If this view is not scrollable, we'll purge the buffer of lines that have
|
||||||
|
@ -575,6 +575,7 @@ func (t *TreeView) Draw(screen tcell.Screen) {
|
|||||||
if t.root == nil {
|
if t.root == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
_, totalHeight := screen.Size()
|
||||||
|
|
||||||
t.process()
|
t.process()
|
||||||
|
|
||||||
@ -609,7 +610,7 @@ func (t *TreeView) Draw(screen tcell.Screen) {
|
|||||||
lineStyle := tcell.StyleDefault.Background(t.backgroundColor).Foreground(t.graphicsColor)
|
lineStyle := tcell.StyleDefault.Background(t.backgroundColor).Foreground(t.graphicsColor)
|
||||||
for index, node := range t.nodes {
|
for index, node := range t.nodes {
|
||||||
// Skip invisible parts.
|
// Skip invisible parts.
|
||||||
if posY >= y+height+1 {
|
if posY >= y+height+1 || posY >= totalHeight {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if index < t.offsetY {
|
if index < t.offsetY {
|
||||||
|
5
util.go
5
util.go
@ -247,7 +247,8 @@ func Print(screen tcell.Screen, text string, x, y, maxWidth, align int, color tc
|
|||||||
// printWithStyle works like Print() but it takes a style instead of just a
|
// printWithStyle works like Print() but it takes a style instead of just a
|
||||||
// foreground color.
|
// foreground color.
|
||||||
func printWithStyle(screen tcell.Screen, text string, x, y, maxWidth, align int, style tcell.Style) (int, int) {
|
func printWithStyle(screen tcell.Screen, text string, x, y, maxWidth, align int, style tcell.Style) (int, int) {
|
||||||
if maxWidth <= 0 || len(text) == 0 {
|
totalWidth, totalHeight := screen.Size()
|
||||||
|
if maxWidth <= 0 || len(text) == 0 || y < 0 || y >= totalHeight {
|
||||||
return 0, 0
|
return 0, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,7 +366,7 @@ func printWithStyle(screen tcell.Screen, text string, x, y, maxWidth, align int,
|
|||||||
)
|
)
|
||||||
iterateString(strippedText, func(main rune, comb []rune, textPos, length, screenPos, screenWidth int) bool {
|
iterateString(strippedText, func(main rune, comb []rune, textPos, length, screenPos, screenWidth int) bool {
|
||||||
// Only continue if there is still space.
|
// Only continue if there is still space.
|
||||||
if drawnWidth+screenWidth > maxWidth {
|
if drawnWidth+screenWidth > maxWidth || x+drawnWidth >= totalWidth {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user