mirror of
https://github.com/rivo/tview.git
synced 2026-04-26 21:35:54 +03:00
[GH-ISSUE #662] Example of popup Modal by shortcut #487
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/tview#487
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @abitrolly on GitHub (Oct 11, 2021).
Original GitHub issue: https://github.com/rivo/tview/issues/662
https://github.com/rivo/tview/wiki/Modal example list modal hardwired to root or Pages elements. But I already have List as my root element, and I want to show modal (without buttons) when I press
iand close it onEscor clicking outside. Would be nice to have an example that demonstrates how that's possible.The straightforward approach I tried that doesn't work.
After pressing
ithe List border becomes single line, and it stops responding to events. Nothing else is shown. PressingEscdoesn't revert to previous state, but exits the application.@rivo commented on GitHub (Oct 29, 2021):
If you put your list at the root, you won't be able to show anything other than that list. (
SetFocus(infobox)will just shift the focus to a widget that is not part of the widget tree and thus not drawn anywhere.)So to show more widgets, in your case a
Modal, you need some kind of layout widget at the root, e.g.Grid,Flex, orPages. From what you're describing, I thinkPagesis what you want.@abitrolly commented on GitHub (Oct 30, 2021):
@rivo why it is not possible to attach the Modal dynamically to the root element?
@rivo commented on GitHub (Oct 30, 2021):
Sure, it's possible. Just use
app.SetRoot():Now (after pressing i) your list is not attached anymore, though.
@abitrolly commented on GitHub (Nov 9, 2021):
Nice. I think this high level overview is not described anywhere. Namely that for building a UI with
tviewyou first define a tree of elements, and then attach that tree to the app screen withapp.Root()call. If you define an element that is not in a tree or not attached, then it won't be visible.Now for the example - it works, but the list is gone from the background when switching root to infobox, because as you said it is not attached anymore. So is it possible to attach the infobox as a child modal to the list?
@rivo commented on GitHub (Nov 9, 2021):
I realize that. I have yet to add more examples and tutorials. It's just due to lack of time that this doesn't exist yet.
As mentioned in my first reply, to attach multiple primitives to the application, you need a container primitive (
Flex,Grid, orPages) at the root. In your example, I would suggestPages, to which you add your list and your modal. Then useSwitchToPage()to switch between the two.@abitrolly commented on GitHub (Nov 10, 2021):
In
Qt/PySide2anyWidgetcan be root, much like intview, but also any widget can have a parent and children - https://wiki.qt.io/Qt_for_Beginners#parenting_system - so I kind of expected something similar. Intviewthe only widgets that allow children are "layout" widget with its own APIs:.addPage().addItem().addItem()@rivo commented on GitHub (Nov 11, 2021):
Yes, that's correct.
@abitrolly commented on GitHub (Nov 11, 2021):
@rivo what do you think about adding bit flags to
.AddPage()API. Right now the code like this is not really readable.I am thinking about something line this.
Or maybe a backward compatible solution.
@abitrolly commented on GitHub (Nov 11, 2021):
@rivo
SwitchToPage()hides thelisttoo instead of sending it to the background. The example at https://github.com/rivo/tview/wiki/Modal is not using switching, so it is not affected.@abitrolly commented on GitHub (Nov 11, 2021):
I have to use
.ShowPage("infobox")to bring up modal on a background and then use.SwitchToPage("list")to turn it off.@abitrolly commented on GitHub (Nov 11, 2021):
Now I need to figure out how to deal with modal specific shortcuts, so that
Escclosed modal and not the whole app.@rivo commented on GitHub (Nov 11, 2021):
Box.SetInputCapture()is your friend.@abitrolly commented on GitHub (Nov 11, 2021):
Is there a way for a Modal to "quit" itself without holding a reference to global
Page?@abitrolly commented on GitHub (Nov 12, 2021):
I can not stop ESC event from propagating by returning
nil. With the following code the app still exits when ESC is pressed in the modal.@rivo commented on GitHub (Nov 13, 2021):
I don't know why your app exits when hitting Esc. That is not built-in. It only exits upon Ctrl-C. If you want to stop it from doing that, you can do that with
Application.SetInputCapture()on the application level. So I'm not sure what the issue with Esc is here. If you post some code that I can run, I might be able to tell you.The package doesn't provide a way for primitives to make themselves "disappear" and have container primitives handle that automatically. You can probably code up your own dependency injection by creating a custom constructor for your modal. Or you handle
Modal.SetDoneFunc()somewhere outside. But eventually, thePagesclass needs to switch the order of the primitives displayed to make that visible to the user.@abitrolly commented on GitHub (Nov 13, 2021):
@rivo here is the code.
@rivo commented on GitHub (Nov 13, 2021):
Ok, well, that makes sense. The
Application.SetInputCapture()call is evaluated first before any other overrides in primitives. So if you globally stop the application upon hitting Esc, that will always happen, regardless of what you do in yourModal. Same with q.It seems to me that you only want to close the application with Esc when the user is in the
List. So you'll want to capture the Esc event in your list instead of globally in the application.