Skip to content
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

[WIP/POC] Libscroll Integration #766

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@
"timber": "glennsl/timber#ae065bb",
"libscroll": "link:../libscroll-re",
"reason-sdl2": "revery-ui/reason-sdl2#a52eee7",
"esy-sdl2": "revery-ui/esy-sdl2#13ac578"
"esy-sdl2": "link:../esy-sdl2",
"reason-sdl2": "link:../reason-sdl2"
},
"devDependencies": {
"ocaml": "~4.8",
Expand Down
31 changes: 31 additions & 0 deletions src/UI_Components/ScrollView.re
Original file line number Diff line number Diff line change
Expand Up @@ -180,10 +180,41 @@ let%component make =
}
}*/

let scrollForFrameFlip = (timestamp: int) => {
// call into libscroll to sample new position
}

let scroll = (wheelEvent: NodeEvents.mouseWheelEventParams) => {
switch (scrollViewRef^) {
| Some(scrollview) => {//Libscroll.push_pan(scrollview, Libscroll.Axis.Vertical, 10.0, 0)
Log.info("Scrollview existed");

Libscroll.set_source(scrollview, wheelEvent.source);

switch(wheelEvent.deltaX) {
| Some(delta) => {
Libscroll.push_pan(scrollview, Libscroll.Axis.Horizontal, delta, wheelEvent.timestamp);
}
| None => ()
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this an option? Wouldn't a delta of 0 be "neutral" and effectively do nothing anyway?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it wasn't doing interpolation/prediction then yes, but with both enabled it would mean that acceleration goes to infinity and velocity drops to zero, which would cause weird stuttering if event ordering isn't consistent (and also make it so that fling sometimes wouldn't work)

Copy link
Member

@glennsl glennsl Mar 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you not just weed out the 0s from the interpolation? Or does the None have some other significance?

Like, if it was not an option, would this not be equivalent?

if (wheelEvent.deltaX != 0) {
  Libscroll.push_pan(scrollview, Libscroll.Axis.Horizontal, wheelEvent.deltaX, wheelEvent.timestamp);
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably, at least on Wayland I never seem to get a zero delta. I still need to figure out how to drag prediction toward zero if velocity drops but no zero event or fling event comes in.

It seems semantically odd to special case zero delta to me but it might be fine

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find it odd that it needs to be special-cased too, but I would consider both using an option and weeding out 0s special-casing. A delta of 0 seems completely normal to me, so I'm wondering if the problem is somewhere else in the model. Unless you work with imperfect sensor data, which of course happens sometimes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these were polymorphic variants, you wouldn't even need to do the mapping. It's a good use case for it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, how would that work? Am not super familiar with them

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Polymorphic variants are the structurally typed equivalents of ordinary variants. Their identity is derived from the type itself, not from any definition. In this case specifically that means SDL and libscroll can share a polymorphic variant type without either library knowing about the other.

By example, it looks like this:

let functionTakingPolyVariant = (poly: [`Number(int) | `Text(string)]) =>
  switch (poly) {
  | `Number(num) => "Number: " ++ string_of_int(num)
  | `Text(text) => "Text: " ++ text
  };

let str = functionTakingPolyVariant(`Number(42));

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something I'm also remembering here, is that wayland sends events for when the source axis changes for a pan, and that contains an undefined delta. I probably need a way of excluding the delta as well. Might make sense to have a more general axis enum indicating horizontal, vertical, or undefined (undefined meaning the delta is meaningless, and shouldn't be interpreted)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at how this interacts with scroll stop events makes me want to bring back the guard, for single accesses.

Effectively what I want to encode is the variant/enum

Info(Source)
Fling(Axis, Source) |
Interrupt(Axis, Source) |
Pan(Axis, Source, delta)

in a way that is fairly ideomatic in c and translates well across to reasonml/rust code. What are your opinions on doing that nicely?

I might be overfitting for the linux way of handling input, but afaik it's pretty similar on OSX and can be fully described for the Windows model (just compose multiple events)


switch(wheelEvent.deltaY) {
| Some(delta) => {
Libscroll.push_pan(scrollview, Libscroll.Axis.Vertical, delta, wheelEvent.timestamp);
}
| None => ()
};

switch(wheelEvent.isFling) {
| true => Libscroll.push_fling(scrollview, wheelEvent.timestamp);
| false => ()
};
Copy link
Member

@glennsl glennsl Mar 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use pattern matching for boolean conditionals. That's what if expressions are for. They communicate intent better, are less noisy, and also shorter in cases like this where you can skip the else branch:

Suggested change
switch(wheelEvent.isFling) {
| true => Libscroll.push_fling(scrollview, wheelEvent.timestamp);
| false => ()
};
if (wheelEvent.isFling) {
Libscroll.push_fling(scrollview, wheelEvent.timestamp);
};

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, will change


switch(wheelEvent.isInterrupt) {
| true => Libscroll.push_interrupt(scrollview, wheelEvent.timestamp);
| false => ()
};

}
| None => Log.error("Scrollview not present on event dispatch");
}
Expand Down