-
Notifications
You must be signed in to change notification settings - Fork 297
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
Switch to event-based input handling #684
Conversation
😲 wooohoooo! I'm a bit busy at the moment but will review this as soon as I can! From a quick glance however this already looks like a massive improvement 😸 thanks so much for taking the time for this @psFried, I think conrod and its users will benefit greatly as a result! |
Okydoke, I've had a read through and I really like the new system! Great stuff! Please don't be put off by the number of points below! Most of the following is related to small changes/improvements - nothing too serious:
I have some other ideas related widget-specific events, but I haven't looked closely enough to suggest anything meaningful just yet - this is probably plenty of notes for now anyways! Again, awesome stuff 😸 Just let me know if I've missed the mark with any of my comments! Otherwise, hopefully you find them useful 👍 |
@mitchmindtree Good feedback! I think I agree with most of those. I'm not going to have much time until next week, but I'd like to implement those suggestions. Initially, I actually did try to return
I think your first point was really a good idea, too. I've found that testing the If there's a lot of interest in starting to add test coverage, I can start working on support for it. Otherwise I'll probably just leave it as is. Do you want to start testing widgets? |
Yeah I know the kinds of crazy iterator types you're talking about! Here's a comment I made about it on an RFC which aimed to solve the problem heheh. There's been a lot of thought on this problem, and a couple follow up RFCs as well. For now unfortunately, the general workaround is to write your own type that implements So for example, in the case of pub struct KeysJustReleased<'a, I>
where I: Iterator<Item=&'a ConrodEvent>,
{
events: I,
lifetime: ::std::marker::PhantomData<&'a ()>,
}
impl<'a, I> Iterator for KeysJustReleased<'a, I>
where I: Iterator<Item=&'a ConrodEvent>,
{
type Item = Key;
fn next(&mut self) -> Option<Self::Item> {
while let Some(event) = self.events.next() {
if let ConrodEvent::Raw(Input::Release(Keyboard(key))) = *event {
return Some(key);
}
}
None
}
} Then the method in pub trait InputProvider<'a> {
type Events: Iterator<Item=&'a ConrodEvent>;
// ...
fn keys_just_released(&'a self) -> KeysJustReleased<'a, Self::Events> {
KeysJustReleased { events: self.events() }
}
// ...
} As you can see it's definitely a little more verbose :( but it does the job :) Re testing widgets: I've been super unsure about how to do this effectively myself, but i'm certainly open to adding some tests if you have a nice way of doing so in mind! |
I'm finally getting some time to finish up this PR, and just have a few things left to address.
I think there has to be some sort of threshold for this. In testing it out, if the threshold is 0, then it's really easy to end up generating drags instead of clicks, especially with a trackpad. The thing that I really don't like about having the drag threshold here is just that it won't match whatever threshold is set at the OS level. I think that the ultimate solution here would be to have a cross-platform way to get this threshold from the OS instead of just making up our own, but I haven't found a great way of doing that yet. On windows, we would just call this function (exposed in winapi-rs) to get the threshold, but I don't know how that's done on other systems yet. We'll have a similar problem once we start trying to detect double-clicks. There's a system setting for the time between clicks, as well as a distance threshold for those. tl;dr - I do think that some sort of global threshold is necessary. Is it acceptable to just keep the Edit:Looks like on Linux, the drag and double-click thresholds are controlled by GTK, QT, etc. I couldn't find any way to get that setting on OSX. I did find a similar issue here. It now seems to me to be of questionable value to try to come up with a cross-platform way of getting these thresholds. Might be best to just keep them in Conrod. |
@psFried interesting! One option might be to make |
@mitchmindtree |
…elative to a given Point
…oved tests to separate file
…and added tests for it
…nrodEvent instead of a reference to a vec
…eturn Iterators instead of Vecs
…ified by the application
At this point, I think I have addressed all of the feedback on the PR. Changing all the Still need to finish switching over the rest of the widgets to use the new input methods. Any thoughts about deprecating
I don't have a sense for how many projects are using custom widgets, so I don't know if any projects will be affected by this change. Thoughts? |
Just had one final review - looking great! There are a couple small changes I'd like to make, but I'd be happy to address them myself! I'm happy to merge this now as is and wait to remove I think there are a few projects using the custom widget API, however as long as we don't break the current version, I'm fine with removing |
Excellent 👍 I went ahead and updated the original InputRefactoring issue #670 to track the remaining items to be changed over to use the new @mitchmindtree I'd love to hear what other changes you were thinking of. If you want to do that pre-merge, you can just use this branch. |
Nice! I won't have time to make the changes today, I'll leave them inline in case you get a chance to get to them before I do :) |
|
||
/// Trait for something that provides events to be consumed by a widget. | ||
/// Provides a bunch of convenience methods for filtering out specific types of events. | ||
pub trait InputProvider<'a, T: Iterator<Item=&'a UiEvent>> { |
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 would be a little more idiomatic to move this T
type parameter to an associated type, i.e. something like type Events: Iterator<Item=&'a UiEvent>
. This is because we know that there may only be one type of event iterator per implementation of InputProvider
, i.e. GlobalInput
's is GlobalInputEventIterator
and WidgetInput
's is WidgetInputEventIterator
.
That all makes sense. You'll probably get to it before I do. I have family coming in from out of town, so I don't see myself getting much free time in the next week :) |
Aiight, I've got about half an hour now so I think I might just merge this and make the adjustments in a follow up PR :) Thanks again for this @psFried, such an awesome contribution! |
Switch to event-based input handling
Tweaks to events API following #684
WIP - do not merge yet
Ok, so here's a second crack at refactoring input handling. This ended up being a rather large departure from the current input handling, so I ended up using completely new structs instead of adding onto
UserInput
. The idea is that we could just deprecate the oldUserInput
and leave it around for a while for the sake of backwards compatibility. Don't know if that would really be worth it or not, though, since I have no idea how many people are actually using custom widgets.For the first pass, the only widget that I refactored to use the new
WidgetInput
was theButton
widget. I figured that would be the simplest one to start off with.All the other widgets still need to be switched over to use the new input methods:
I think it would be a good idea to wait until most of these widgets get switched over to using the new input methods before merging, just to make sure that
WidgetInput
has everything it needs to.Overall, I think this approach has worked out much better than the previous approach, but any feedback is certainly appreciated. Generally, this should make it really easy to solve #606. This PR already addresses: #569, #642 (though we could use to create a nicer api for sending events), #384, and of course #670.
Anyway, this is a pretty huge PR, so take your time looking it over and let me know if you see any room for improvement.