mirror of
https://github.com/rivo/tview.git
synced 2026-04-26 21:35:54 +03:00
[GH-ISSUE #426] Ability to set GetFocusable object #310
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/tview#310
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 @millerlogic on GitHub (Apr 8, 2020).
Original GitHub issue: https://github.com/rivo/tview/issues/426
Within tview, the various widgets can directly set the Box.focus which is returned by GetFocusable. But if I want to make my own 3rd party based on Box, it looks like I don't have the ability to set this focus value. Should there be Box.SetFocusable?
Example:
An alternative would be to have a second Box constructor which allows passing in the focus object. In this case I suppose all widgets would need this extra constructor, to pass the focus object up the hierarchy. This alternative way sounds not as convenient.
Thanks
@millerlogic commented on GitHub (Apr 11, 2020):
Here is SetFocusable func for above if you want to fetch it,
github.com/millerlogic/tview@0445361d52However, I realized there may be a bigger problem with focus handling. What happened is I wanted a custom type based on InputField, but I eventually tracked down references to the wrong type floating around.
Create and use
&CInput{InputField: tview.NewInputField()}The problem is that tview.InputField will set focus to its own type, in InputField.MouseHandler it calls
setFocus(i)- this is on the InputField inner type rather than on my CInput. So this means Application.GetFocus is not referencing the correct type.This was a quick workaround that works but is not a good long-term solution.
It overrides the setFocus func so that calling it on the inner type will actually call it on the outer type. I would then have to do this for all functions that set focus and all derived types.
So here is a possible solution I came up with: https://github.com/rivo/tview/compare/master...millerlogic:box-self
Rather than having a focusable object, just keep a reference to the outer type's primitive. This allows the type itself to focus the correct type, check if it's focused, and so on.
I decided to make it a field rather than getter/setter functions because it's only relevant within the type itself. If external code has a Primitive reference, it should always be the correct outer type.
However it could be given a different name or use getter/setter instead.
Hopefully you understand the situation. Please let me know your thoughts, thanks
@millerlogic commented on GitHub (May 2, 2020):
Quick follow up.
I realize a field named
Selfmight not look like a good design. But I have heard many times that user interfaces are generally the best application for OOP, and this self reference makes it that much closer to OOP style. At first I hesitated to try this option and have not done this in any other Go code, but in this case it seems like it might be a reasonable fit. It might make sense to rename the field toPrimitiveor something else less unfavorable.Also if you ever do change the way key input works so that key events go down the hierarchy like mouse events do, the different widgets might want to check if they have the current focus, and this change would allow it. Otherwise, the function receiver might not match the Application.GetFocus. (or is
p.GetFocusable() == app.GetFocus().GetFocusable()the solution? Even so, I'm not crazy about the way nested types would be referenced)Finally, I can add the Focusable and GetFocusable back for backwards compatibility, it can just return the self ref.
You don't necessarily need to look at the code for this discussion, I just wanted to give it a try and remove my workaround. Feel free to let me know what's wrong with my approach or if I should be doing anything differently.
Thanks for your ongoing support for the package!
@rivo commented on GitHub (Aug 18, 2020):
As for your first example, you can definitely keep another local reference in your class:
But then it requires you to also override
GetFocusable(). And I realize that you may still have problems doing that because I access thefocuslocal variable directly sometimes. I could change that so that I always callGetFocusable(). It sounds like this would solve your problem but I'm not 100% sure because I haven't spent a lot of time investigating this.Let me know if you want to try that route.
@rivo commented on GitHub (Jan 11, 2021):
Please open a new issue and reference this one if you need more information.