Open abitrolly opened 2 years ago
References are top-down in tview
only for various reasons. (And maintaining both directions is a nightmare.) I don't see a parent relationship coming to tview
any time soon. I thought we had solved your #662 issue. If there's still something open, we can work to find a solution.
@rivo yep, #662 is not solved, because there were no diagrams to explain how the event system works, what it is called top-down
and why app and root is at the top. Now that I've moved through the code, the main complain is that I don't want to hardcode widget references and shortcuts inside its parent widgets.
I my head widgets form dynamic stack of windows, where top window on the screen is getting focus and can choose either to process a key, or to forward it down the stack. Again I think that the modal help screen that is invoked by F1 should be able to work from any place in app, and take a notion of current context. I was almost able to do it with pages, but such MRE is not there yet.
From what I can tell, #662 was resolved. There were no further open questions. We can reopen it if you need help achieving some specific objective.
I understand that you have a different mental model of how a GUI library should be organized. Maybe this is coming from Qt/Pyside2 which you mentioned? I don't know. But tview
is not designed in that way and it's unlikely that it will be completely restructured to fit a different architectural philosophy.
If you have a specific problem, something that cannot be done at the moment, please describe it in detail so it can be reproduced, and I will give my best to provide a solution.
Ok, the problem. I need a parent widget to forward shortcut to child widget if the child widget overrides this shortcut, without explicitly coding all child shortcuts into parent widget.
This is a description of a general solution rather than a specific problem description. What I meant was for you to describe what the user does or wants to do in your application and how that can currently not be achieved. Maybe you want to include a screenshot, if that helps?
The screenshot.
From here https://gitlab.com/abitrolly/dnf-go-gui
I want to show popup with package description if pressed I
or ENTER
. Help for the current widget if pressed F1
. ESC
to close current dialog.
Oh yea, I also want to display bottom bar with these shortcuts that should change depending on current dialog.
Lots of ways to do this. Here's some example code. Adding the bottom bar is "left as an exercise to the reader". (Check out the presentation demo in the repo for ideas.)
package main
import (
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
)
var helpTexts = map[string]string{
"updates": "Help text for update table",
"info": "Help text for info text view",
}
func main() {
app := tview.NewApplication()
pages := tview.NewPages()
updates(pages)
info(pages)
showHelp := help(pages)
app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
if event.Key() == tcell.KeyF1 {
page, _ := pages.GetFrontPage()
text, ok := helpTexts[page]
if ok {
showHelp(text)
}
return nil
}
return event
})
if err := app.SetRoot(pages, true).Run(); err != nil {
panic(err)
}
}
func updates(pages *tview.Pages) {
table := tview.NewTable().
SetSelectable(true, false).
SetCellSimple(0, 0, "update1").
SetCellSimple(1, 0, "update2").
SetSelectedFunc(func(row, column int) {
pages.SwitchToPage("info")
})
table.SetBorder(true).SetTitle("Updates")
pages.AddPage("updates", table, true, true)
}
func info(pages *tview.Pages) {
text := tview.NewTextView().
SetText("Some information here...")
text.SetBorder(true).
SetTitle("Info").
SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
if event.Key() == tcell.KeyEnter {
pages.SwitchToPage("updates")
return nil
} else {
return event
}
})
pages.AddPage("info", text, true, false)
}
func help(pages *tview.Pages) func(text string) {
textView := tview.NewTextView()
textView.SetBorder(true).
SetTitle("Help").
SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
if event.Key() == tcell.KeyEscape {
pages.HidePage("help")
return nil
} else {
return event
}
})
pages.AddPage("help", tview.NewGrid().
SetRows(0, 8, 0).
SetColumns(0, 80, 0).
AddItem(textView, 1, 1, 1, 1, 0, 0, true), true, false)
return func(text string) {
textView.SetText(text)
pages.ShowPage("help")
}
}
info
and help
information should be popups with package listing always visible on the background. And in case of help
page for info
, help
should be rendered on top, so that when the help
is discarded, the info
became active again. Also I don't want to hardcode return path from info
dialog into updates
page. Like info
page should know nothing about who called it. It should just receive parameter of what package to show.
info
andhelp
information should be popups with package listing always visible on the background.
Sure. Use ShowPage()
instead of SwitchToPage()
for the info page. This should also result in your other requirements as Pages
is basically a deck of cards. If you hide the top card, the one below it will automatically become the top card again.
I'm not going to code this for you. It's all there and it's all possible. You just need to dive into the code a little.
Ok. I will try it.
I still need Qt Parenting System for blocking modal in #662 to start shortcut processing from the topmost widget and then forward unhandled shortcuts to parents. The problem is that
tview
doesn't have this universal parent relationship.Would it be good to add
SetParent/GetParent
toBox
primitive and let methods likePages.AddPage
set it?