Add TextView.SetVerticalAlign

Resolves #68.
This commit is contained in:
Trevor Slocum 2021-07-05 12:52:52 -07:00
parent 7b45918cfa
commit 964fd51438
4 changed files with 48 additions and 8 deletions

View File

@ -1,6 +1,7 @@
v1.5.6 (WIP)
- Add TrueColorTags option and do not use TrueColor tag values by default
- Add TextView.SetHighlightForegroundColor and TextView.SetHighlightBackgroundColor
- Add TextView.SetVerticalAlign
- Add Button.SetCursorRune (cursors are now shown within Buttons when focused by default)
- Add CheckBox.SetCursorRune (cursors are now shown within CheckBoxes when focused by default)
- Add DropDown.SetAlwaysDrawDropDownSymbol (DropDown symbols are now shown only when focused by default)

View File

@ -32,6 +32,7 @@ const textView1 = `[green]func[white] [yellow]main[white]() {
// TextView1 demonstrates the basic text view.
func TextView1(nextSlide func()) (title string, info string, content cview.Primitive) {
textView := cview.NewTextView()
textView.SetVerticalAlign(cview.AlignBottom)
textView.SetTextColor(tcell.ColorYellow.TrueColor())
textView.SetDoneFunc(func(key tcell.Key) {
nextSlide()

View File

@ -119,9 +119,12 @@ type TextView struct {
// If set to true, the buffer will be reindexed each time it is modified.
reindex bool
// The text alignment, one of AlignLeft, AlignCenter, or AlignRight.
// The horizontal text alignment, one of AlignLeft, AlignCenter, or AlignRight.
align int
// The vertical text alignment, one of AlignTop, AlignMiddle, or AlignBottom.
valign VerticalAlignment
// Information about visible regions as of the last call to Draw().
regionInfos []*textViewRegion
@ -227,6 +230,7 @@ func NewTextView() *TextView {
scrollBarVisibility: ScrollBarAuto,
scrollBarColor: Styles.ScrollBarColor,
align: AlignLeft,
valign: AlignTop,
wrap: true,
textColor: Styles.PrimaryTextColor,
highlightForeground: Styles.PrimitiveBackgroundColor,
@ -291,8 +295,8 @@ func (t *TextView) SetWordWrap(wrapOnWords bool) {
t.wordWrap = wrapOnWords
}
// SetTextAlign sets the text alignment within the text view. This must be
// either AlignLeft, AlignCenter, or AlignRight.
// SetTextAlign sets the horizontal alignment of the text. This must be either
// AlignLeft, AlignCenter, or AlignRight.
func (t *TextView) SetTextAlign(align int) {
t.Lock()
defer t.Unlock()
@ -303,6 +307,18 @@ func (t *TextView) SetTextAlign(align int) {
t.align = align
}
// SetVerticalAlign sets the vertical alignment of the text. This must be
// either AlignTop, AlignMiddle, or AlignBottom.
func (t *TextView) SetVerticalAlign(valign VerticalAlignment) {
t.Lock()
defer t.Unlock()
if t.valign != valign {
t.index = nil
}
t.valign = valign
}
// SetTextColor sets the initial color of the text (which can be changed
// dynamically by sending color strings in square brackets to the text view if
// dynamic colors are enabled).
@ -1118,6 +1134,16 @@ func (t *TextView) Draw(screen tcell.Screen) {
}
}
// Calculate offset to apply vertical alignment
verticalOffset := 0
if len(t.index) < height {
if t.valign == AlignMiddle {
verticalOffset = (height - len(t.index)) / 2
} else if t.valign == AlignBottom {
verticalOffset = height - len(t.index)
}
}
// Draw the buffer.
defaultStyle := tcell.StyleDefault.Foreground(t.textColor).Background(t.backgroundColor)
for line := t.lineOffset; line < len(t.index); line++ {
@ -1160,8 +1186,10 @@ func (t *TextView) Draw(screen tcell.Screen) {
posX = 0
}
drawAtY := y + line - t.lineOffset + verticalOffset
// Print the line.
if y+line-t.lineOffset >= 0 {
if drawAtY >= 0 {
var colorPos, regionPos, escapePos, tagOffset, skipped int
iterateString(string(strippedText), func(main rune, comb []rune, textPos, textWidth, screenPos, screenWidth int) bool {
// Process tags.
@ -1203,7 +1231,7 @@ func (t *TextView) Draw(screen tcell.Screen) {
}
// Mix the existing style with the new style.
_, _, existingStyle, _ := screen.GetContent(x+posX, y+line-t.lineOffset)
_, _, existingStyle, _ := screen.GetContent(x+posX, drawAtY)
_, background, _ := existingStyle.Decompose()
style := overlayStyle(background, defaultStyle, foregroundColor, backgroundColor, attributes)
@ -1250,9 +1278,9 @@ func (t *TextView) Draw(screen tcell.Screen) {
// 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)
screen.SetContent(x+posX+offset, drawAtY, main, comb, style)
} else {
screen.SetContent(x+posX+offset, y+line-t.lineOffset, ' ', nil, style)
screen.SetContent(x+posX+offset, drawAtY, ' ', nil, style)
}
}

12
util.go
View File

@ -21,13 +21,23 @@ var TrueColorTags = false
// value of color, ColorDefault, results in default terminal colors.
var ColorUnset = tcell.ColorSpecial | 108
// Text alignment within a box.
// Horizontal alignment within a box.
const (
AlignLeft = iota
AlignCenter
AlignRight
)
// VerticalAlignment represents vertical alignment.
type VerticalAlignment int
// Vertical alignment within a box.
const (
AlignTop VerticalAlignment = iota
AlignMiddle
AlignBottom
)
// Common regular expressions.
var (
colorPattern = regexp.MustCompile(`\[([a-zA-Z]+|#[0-9a-zA-Z]{6}|\-)?(:([a-zA-Z]+|#[0-9a-zA-Z]{6}|\-)?(:([bdilrsu]+|\-)?)?)?\]`)