You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently in Red there's a mix of three focus models:
Single per-OS focused face
This is the model closest to the actual UX: there is at any point in time only one focused (receiving keyboard events) widget in the OS. Presence of this model is evidenced by the fact that (at least on Windows) set-focus on any face activates (brings to top) its parent window.
Per-window focused face
Presence of this model is evidenced by the fact that each window face has a /selected facet, and that to move the focus it suffices to set this facet (as done by the set-focus function).
A tree of /selected faces
Presence of this model is evidenced by other (than window) container face types having a /selected facet - e.g. panel, tab-panel, group-box.
As a result of this mix-up we're having numerous focus-related issues and total inability to reliably tell programmatically (on Red level) where the focus currently is (e.g. in a multi-window program we can't tell which window is in focus).
UX requirements for the focus model as I see are as follows:
Only one widget in the OS has focus at any moment in time
Parents of a focused widget are aware of the focus and may also alter their appearance (e.g. active window's title bar)
When some container widgets (window, tab) are activated, focus may go directly into one of their children. They can be nested, so activation of an outer container may trigger activation of an inner container, which in turn may trigger activation of its child
To satisfy these requirements with minimal complexity I propose adopting the following focus implementation based on model (1):
A global per-interpreter setting holds the currently focused widget (e.g. system/view/focus):
it should equal none when focus is in another program, and when set to none, currently active window should be deactivated
it should be set to the currently focused face when it is the target of keyboard events in the currently active window; setting it should focus the face and bring window to top
it should be set to the currently active window when no face has focus, or when window menu is interacted with (as it has no equivalent face in Red)
ideally it should be assumed that objects other than face can be assigned to it (e.g. space objects); in this case a helper function should be exposed to connect that space object to the actual parent base face focusing procedure in the OS
Each face's or space's location on the widgets tree is known from the chain of its and its ancestors' /parent facets, so having a global setting holding the widget is enough, and there's no need in a separate "focus tree" formed by /selected facets or anything else.
Focus events are captured/bubbled (as they currently are).
Some widgets (e.g. window and tab-panel faces) should remember their last focused child and restore focus to this child on window activation or when switching between tabs (e.g. the same /selected but with a note that it's not the same as focused)
Normally for this to work, on-focus event should be captured by each container face before it reaches the child. Since Red View UI is powered by the OS, actual capture will be hidden in the R/S part. But I think it still must follow the event capturing phase so that Red-level on-detect event coincides with the actual memorization of the child.
I also suggest that whenever container has scrollbars, once focus is set to its (probably deep) child, it should scroll itself to make that child visible. Other cases where such "bringing widget to focus" should be performed is when widget content is changed - usually as a result of keystroke input, but there may be other cases (like input simulation or interactive UI tutorials), where it may be useful, so it would be best to make this functionality available to the programmer. Ideally, the procedure should be "deep" in a sense that it should bubble through all the ascendants and scroll them to render the altered UI region visible.
The text was updated successfully, but these errors were encountered:
Currently in Red there's a mix of three focus models:
Single per-OS focused face
This is the model closest to the actual UX: there is at any point in time only one focused (receiving keyboard events) widget in the OS. Presence of this model is evidenced by the fact that (at least on Windows)
set-focus
on any face activates (brings to top) its parent window.Per-window focused face
Presence of this model is evidenced by the fact that each window face has a
/selected
facet, and that to move the focus it suffices to set this facet (as done by theset-focus
function).A tree of
/selected
facesPresence of this model is evidenced by other (than window) container face types having a
/selected
facet - e.g.panel
,tab-panel
,group-box
.As a result of this mix-up we're having numerous focus-related issues and total inability to reliably tell programmatically (on Red level) where the focus currently is (e.g. in a multi-window program we can't tell which window is in focus).
UX requirements for the focus model as I see are as follows:
To satisfy these requirements with minimal complexity I propose adopting the following focus implementation based on model (1):
A global per-interpreter setting holds the currently focused widget (e.g.
system/view/focus
):none
when focus is in another program, and when set tonone
, currently active window should be deactivatedEach face's or space's location on the widgets tree is known from the chain of its and its ancestors'
/parent
facets, so having a global setting holding the widget is enough, and there's no need in a separate "focus tree" formed by/selected
facets or anything else.Focus events are captured/bubbled (as they currently are).
Some widgets (e.g.
window
andtab-panel
faces) should remember their last focused child and restore focus to this child on window activation or when switching between tabs (e.g. the same/selected
but with a note that it's not the same as focused)Normally for this to work,
on-focus
event should be captured by each container face before it reaches the child. Since Red View UI is powered by the OS, actual capture will be hidden in the R/S part. But I think it still must follow the event capturing phase so that Red-levelon-detect
event coincides with the actual memorization of the child.I also suggest that whenever container has scrollbars, once focus is set to its (probably deep) child, it should scroll itself to make that child visible. Other cases where such "bringing widget to focus" should be performed is when widget content is changed - usually as a result of keystroke input, but there may be other cases (like input simulation or interactive UI tutorials), where it may be useful, so it would be best to make this functionality available to the programmer. Ideally, the procedure should be "deep" in a sense that it should bubble through all the ascendants and scroll them to render the altered UI region visible.
The text was updated successfully, but these errors were encountered: