saket / telephoto

Building blocks for designing media experiences in Compose UI
https://saket.github.io/telephoto/
Apache License 2.0
962 stars 30 forks source link

Handle overscroll? #7

Open DSteve595 opened 1 year ago

DSteve595 commented 1 year ago

In the pager sample, horizontal overscroll is achieved automatically via the pager hitting its bounds. This doesn't give vertical overscroll though.

Should zoomable things trigger their own overscroll when panning at the edges? I would think so, as Modifier.scrollable() gives things overscroll at their scroll edges. Is it possible to do that without consuming the touches, thereby allowing e.g. parent pagers to still work?

saket commented 1 year ago

The easiest way to solve this would have been detecting gestures using nested scrolling, but Compose UI's APIs aren't ready for 2d nested scrolling yet.

Should zoomable things trigger their own overscroll when panning at the edges?

Yes! I could use nested scrolling only for manually showing overscrolls. Will try implementing this after v1.

Is it possible to do that without consuming the touches, thereby allowing e.g. parent pagers to still work?

I… don't think I can stop consuming a gesture after it has started. Parent pagers will not pick up partially consumed gestures because all gesture handlers start with a down event.

K1rakishou commented 1 year ago

I… don't think I can stop consuming a gesture after it has started. Parent pagers will not pick up partially consumed gestures because all gesture handlers start with a down event.

@saket I have encountered a similar problem in one of my projects and even suggested a potential solution to the compose team but they haven't done anything with it yet. Maybe if enough people "star" the issue they will actually consider adding it? Because this seems like a missing piece of the Compose gestures API.

https://issuetracker.google.com/issues/232131792

The general idea is to be able to send custom pointer events from within PointerInputScope/AwaitPointerEventScope. This way, you can start consuming incoming events and if after some time (for example after detecting the touch slop) you determined that you don't want the rest of the enets you can simulate a "down" event, pass it to children and after that "re-route" the rest of the events to children.

Right now (as you have already noted) it's impossible because after you have consumed the "down" event, pointerInputs of child composables won't receive the rest of the events (since most of the gesture detectors start with "awaitFirstDown()").