Instead of always clearing before printing text, the text could be filled with empty spaces (this is what tcell.Clear()
does in the background anyways)
func render(screen tcell.Screen, question string, options []*Choice, config *Config, selectedChoice *Choice) {
//screen.Clear()
_, maximumThatCanBeDisplayed := screen.Size()
lineNumber := 0
questionLines := strings.Split(question, "\n")
for _, line := range questionLines {
printText(screen, 1, lineNumber, line, config.TextColor, config.BackgroundColor, config.SelectedTextBold)
lineNumber += 1
}
min := selectedChoice.Id + len(questionLines)
max := maximumThatCanBeDisplayed
if selectedChoice.Id > max {
min += 1
max += 1
}
for _, option := range options {
if option.Id <= (min+1)-maximumThatCanBeDisplayed && !(option.Id > (min+1)-maximumThatCanBeDisplayed) {
continue
}
if option.Selected {
printText(screen, 1, lineNumber, fmt.Sprintf("> %s", option.Value), config.SelectedTextColor, config.BackgroundColor, config.SelectedTextBold)
} else {
printText(screen, 1, lineNumber, fmt.Sprintf(" %s", option.Value), config.TextColor, config.BackgroundColor, config.SelectedTextBold)
}
lineNumber += 1
}
screen.Show()
}
func printText(screen tcell.Screen, x, y int, text string, fg, bg tcell.Color, bold bool) {
for _, character := range text {
screen.SetCell(x, y, tcell.StyleDefault.Background(bg).Foreground(fg).Bold(bold), character)
x += runewidth.RuneWidth(character)
}
// instead of using screen.Clear(), we'll just update the ENTIRE line with empty spaces
width, _ := screen.Size()
for i := len(text); i < width; i++ {
screen.SetCell(x, y, tcell.StyleDefault.Background(bg).Foreground(fg), ' ')
x += runewidth.RuneWidth(' ')
}
}
Note that when the list of choices doesn't fit in the screen, this will cause some issues (e.g. bottom lines aren't updated), so something need to be done about that