-
Notifications
You must be signed in to change notification settings - Fork 317
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
controller/keyboard navigation support for <select> #566
Conversation
80fdc9f
to
a34a52a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the pull request!
I think scrolling inside select boxes is one of those things that haven't been tested a whole lot, nice to see it getting some needed attention.
I don't believe it is justified to diverge from the HTML behavior in terms of change
events and escape key. I think the current behavior here useful in many situations. So my suggest ion is to remove the value_last_selected
logic.
When testing this PR, I am getting quite some quirky behavior: The selection box keeps closing on me. Sometimes just when pressing arrow keys or when selecting an option. I tested this on the demo sample.
Another behavior that I noticed is that the scrollbar keeps flashing on and off as I press arrow keys to select new options. However, I see that this occurs in master too, so it is unrelated to this PR. But maybe you could take a look at that while you're at it? :)
selectbox now scrolls when nav is being used
Can you elaborate on this?
SetSelection(GetOption(value_last_selected), true); | ||
value_last_selected = -1; | ||
} | ||
ShowSelectBox(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think hiding the box is perfectly fine here. However, I don't think we should set the selection back. When we change the selected option (with arrow keys or otherwise), we commit it and send change
events. I don't think reverting that change is the right thing for escape. And as you mention too, web browser also seems to keep the selected value.
I think this behavior you want is better implemented locally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll remove this from the PR. I kinda wish the change itself was deferred, though, because scrolling through the list on controller emits a ton of change events (they have to "focus" every element to get the active one). This is how browsers handle it, too ("change" isn't emitted until you actually press enter or click on an option), so this is one way we're currently diverging from browsers (the escape thing I can live with, especially if this is implemented).
if (selection != -1) | ||
{ | ||
Rml::ScrollIntoViewOptions scrollOptions { | ||
box_layout_dirty == DropDownBoxLayoutType::Open ? Rml::ScrollAlignment::Start : Rml::ScrollAlignment::Nearest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you elaborate on the box_layout_dirty condition here, why do we need that?
Can you explain the motivation behind using Start
? I wonder if using Rml::ScrollAlignment::Nearest
always is the more appropriate choice. Especially when scrolling up it feels weird that it keeps selection at the bottom.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's a matter of preference thing, when I was using Nearest it felt awkward to have the selection start at the bottom of the list. Might also depend how you have the box styled or something. Looking at how browsers handle it, though, it seems they are using (the equivalent to) End on open (opening the box with a selection that has a scrolling area always puts it at the bottom of the list) rather than Nearest. I'll have to play more with this.
Nearest is used when scrolling normally, though, so the selection should 'float' like it does in browsers. At least that's the behavior I experienced when testing it locally (it won't scroll until the edges are reached): https://streamable.com/rwiyew
I've not seen either of these locally, oddly enough. If I run into them I'll certainly fix them. I'll check the demo sample to see if I can repro it there.
The actual scroll box moves now if you are using KI_UP/KI_DOWN. Before, the box would just stay where it was, meaning you could not read the option being selected. |
Converting to draft for now as I won't have time for a while to poke these. |
I understand. I haven't been able to follow up on PRs and issues as much as I'd like lately, so things might have been a bit slow from my side too. There are some nice improvements here, so I hope you are able to resume at some point. But of course at you own discretion, cheers. |
Yeah I'm hoping to come back to this in a few weeks - just a lot of projects going on. I shall return, though! (EDIT: also super excited about the Filters/Effects PR seemingly being ready for merging; I've had my eye on it for a while!) |
Alright, I'm ready for this to get reviewed again. I removed the escape key functionality from this PR, but I still recommend we look into this; I'm using this functionality in our games and it's absolutely vital that escape/Back Button cancels the select box, because otherwise it switches menus which is not the behavior a user will expect from hitting escape/Back with a dropdown open. I can open it as a separate PR and we can figure out the details. I addressed the feedback that was left unaddressed before. Let me know what you think! |
Thanks for getting back at this one, very much appreciate that! I'll have to hold this one for a bit, right now I need to focus on the upcoming release, which hopefully is not too far out. After that I'll get back to this and the other PRs, cheers. |
- selectbox now scrolls when nav is being used - selectbox ensures that the selected option is scrolled into view, anchored to the top - "escape" can be used to cancel selection
Use separate bool for layout_dirty vs box just opened, as these two states are not really mutually exclusive. Fixes a bug where the box was not considered just opened since the "open" state was overwritten by the "switch" state. Use center vertical alignment for a just opened box. This is admittedly a subjective matter. However, it looked a bit weird to me how it would scroll past the first few elements when you select, say, just the second or third element. With center, both the first few, and the last items, are shown when selecting something near the beginning or the end respectively. This also feels more symmetrical when the selection box ends up being placed above the select element.
0c5ddd7
to
13e210c
Compare
Hey, I finally got around to taking a look at this one. I pushed a new commit with some suggested changes here:
Let me know if this sounds reasonable to you. While working with this, I discovered several related issues that I've started looking at (not due to this PR). Including some weird scrollbar behavior. So I will push some follow-up commits after this one has been merged. |
Working a bit more on these follow-ups, I am planning to make a related change: 514bd17. Just letting you know in case you have some input on that. |
Yeah sounds reasonable to me - sorry I've been mostly unavailable for the past week or so & taking a minor vacation soon, but I'll be able to have a closer look when I start working on the UI for our next projects since I want to upgrade to 6.0. I trust your judgment on the usability; if it feels good to you for keyboard nav, it should feel good for controller too. Thanks! EDIT: reading back up too, I did want to stress again about the cancel button behavior; it also matches what web browsers do, as escape (or the matching 'cancel' button on console web browsers) closes select boxes too without bubbling the key up to the menu. |
Sounds good, I merged this one for now, and also just pushed a lot of related fixups. We can follow up in the future if we want to tweak it more. As for cancel button behavior. I played around with browsers a bit, see in particular this fiddle, I don't really see the behavior you describe. When I press escape, it commits whichever option is selected and changes the value accordingly, just as if pressing enter. An interesting sidenote, I noticed a difference between Firefox and Chromium though. When selecting different options with the keyboard, in Firefox the value is changed in the background immediately, but the onchange/oninput event is only submitted when it closes. On Chrome, the value changes only when it closes (when the events are submitted). In any case, I generally agree that it would be a nice functionality. How about: We add a new method to the select element called |
This reverts the value to the one set when the selection box was opened. This is particularly helpful for use cases where e.g. the "Escape" key should cancel the selection. Added example usage to the demo sample.
Yeah that's fine, but what was happening before was ESCAPE was backing out of the menu if you have the ESCAPE key set to return to previous menu - the key was bubbling up to the menu itself. I don't know if that's still how it is, but that's how it was in 5.0 prior to this branch. If you have a <select> open it should send the key to the selectbox to close the box, but not bubble it back up to the menu (because the selectbox consumed it). I'm trying to think of any other control that might have similar behavior with keyboard navigation - maybe input type="text / textarea? If you hit ENTER on it, it activates the control letting you type into it, and escape should exit focus of the input but not send the key back to the menu since you don't want to return to the previous menu which is the natural use-case of the escape key. Yeah 702 is exactly what this would go under, so that makes sense to me. |
So I believe we don't do any special actions for the escape key at all. And since it is not handled, it bubbles up like every other key that is not handled. I suspect the escape behavior is something you added yourselves. We could always discuss whether we should have some default actions for that. But regardless, if you make some custom actions to handle the key, the appropriate thing is to call |
Yeah, it's something I added - I just mean that it seems logical for <select> and text inputs to natively handle escape. I have a hard time seeing a situation where you wouldn't want that behavior by default, & we'd just be adding it to every single select/input we use anyways so it seems like a waste/extra boilerplate that the underlying framework should be handling itself. |
This is a PR to address #565 as well as some other things I ran into while using <select>.
KI_ESCAPE can now be used to cancel a selectbox operation - this is currently done very naively, by simply storing the index of the current selection on open and restoring it on KI_ESCAPE if it is set (any change to the options list while it is open will remove the ability to cancel selection). This is a break from HTML standard behaviors, but I needed it for my project on all select boxes and it seemed like something that might be useful for others too (especially for something like a video resolution selector; in games people tend to expect a way to cancel a select box, esp on controller)(The third point was removed in the PR, but keeping this block below for posterity)
The third 'fix' is messy, and I wonder if diverging from the way browsers handling it is worth looking into:
this is a bit more than I wanted to shove into a single PR and wanted to discuss it further before I commit to changing any behaviors like that though.