Instability/Inconsistency of grid, Newbutton Output
The following experimental code is being reported - as seen below, which seems to produce component output instability and inconsistency. When used, there is no reliability that the movement or appearance of the selected button's blue background will follow the up and down input of the arrow keys from the keyboard. The top and first button is supposed to be selected. This happens intermittently, as does the selection of buttons when using the keyboard.
package main
import (
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
"fmt"
)
func main() {
app := tview.NewApplication()
// Create the buttons
buttons := []string {"test 1", "test 2", "test 3", "test 4", "test 5"}
grid := tview.NewGrid().SetColumns(45, 65, 45).SetRows(3, 3, 3, 3, 3, 3, 3, 3, 3, 3)
// Add buttons to the grid
for i, label := range buttons {
grid.AddItem(tview.NewButton(label).SetBorder(true).SetTitle("[ "+label+" ]"), i, 0, 1, 1, 0, 0, false)
}
f := tview.NewInputField()
f.SetBorder(true)
f.SetTitle("Enter")
g := tview.NewButton("Some text") //.SetBorder(true)
grid.AddItem(g, 5, 0, 1, 1, 0, 0, true)
grid.AddItem(f, 6, 0, 1, 1, 0, 0, true)
grid.AddItem(tview.NewTextView().SetText("Some small text").SetTextAlign(tview.AlignCenter), 7, 0, 1, 1, 0, 0, true)
// Blue area button
supr := tview.NewButton("test 1")
supr.SetBackgroundColor(tcell.ColorBlue)
supr.SetBorder(false)
grid.AddItem(supr, 0, 0, 1, 1, 0, 0, true)
currentRow := 0 // Track the current row of the blue area
// Function to update the blue area position
moveBlueArea := func(delta int) {
newRow := currentRow + delta
if newRow < 0 { newRow = 0 }
if newRow >= len(buttons) { newRow = len(buttons) - 1}
//if newRow >= 0 && newRow < len(buttons) {
grid.RemoveItem(supr) // Remove from current position
supr := tview.NewButton(buttons[newRow])
grid.AddItem(supr, newRow, 0, 1, 1, 0, 0, true) // Add to new position
currentRow = newRow
//}
}
// Add the blue area initially
grid.AddItem(supr, currentRow, 0, 1, 1, 0, 0, true)
// Set up key handlers
app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
switch event.Key() {
case tcell.KeyUp:
moveBlueArea(-1) // Move up
case tcell.KeyDown:
moveBlueArea(1) // Move down
case tcell.KeyTAB:
f.SetInputCapture(func(e *tcell.EventKey) *tcell.EventKey { fmt.Println("Key pressed:", e); return e })
case tcell.KeyEnter:
app.Stop() // Exit on Enter key
}
return event
})
// Set up the layout and run the application
if err := app.SetRoot(grid, true).SetFocus(grid).Run(); err != nil {
panic(err)
}
}
Various experiments have been done to:
- Rewrite or rebuild the entire display - even with or without the exception of the selected button.
- To add or change the background colour properties, of each selected button, including those which are not; and then back to point number one.
However, regardless of what methods are used, the output results always remain the same and haphazard. Is there a way to make the interactive output stable?
The following line in your code
supr := tview.NewButton(buttons[newRow])
creates a new variable with the new button. But the scope of this variable extends only until the end of the function. So you're actually not updating your global supr variable with this. Thus, you end up always removing the same button that does not exist anymore after the first deletion. It has no effect.
There are Golang linters who can catch this mistake. You might want to look into them.
Other than that, I would also say, maybe try to avoid deleting and creating elements on the fly like that. Maybe what you really want is to call SetDisabled(). Or maybe just switch the focus using SetFocus(). Have a look at the Form implementation. It switches between different elements, similarly to what you're doing. Or maybe just use Form directly, then you don't have to worry about it.
Ok. Thank you for giving such an insightful understanding. I will definitely look into this.
Will close this for now. Feel to open a new issue if needed.