~eliasnaur/gio-patches

Re: [PATCH gio] io/router: add support for ScrollRange

Details
Message ID
<C9ILE0LNJPG8.1Y8MPQEGOIOWQ@themachine>
DKIM signature
pass
Download raw message
On Thu Feb 25, 2021 at 10:33, Pierre Curto wrote:
> > +// Return whether or not handler at pos has a hit.
> > > +func (q *pointerQueue) opHitTag(handler event.Tag, pos f32.Point) bool {
> > > +     pass := true
> > > +     idx := len(q.hitTree) - 1
> > > +     for idx >= 0 {
> > > +             n := &q.hitTree[idx]
> > > +             if !q.hit(n.area, pos) {
> > > +                     idx--
> > > +                     continue
> > > +             }
> > > +             if n.tag == handler && n.scrollArea != (f32.Rectangle{}) {
> > > +                     p := q.invTransform(n.area, pos)
> > > +                     if p.In(n.scrollArea) {
> >
> > My suggestion for ranges were not meant as extensions to the existing
> > AreaOps, which already bound the InputOps in the (absolute) x,y
> > dimensions.
> >
> > Rather, the vertical and horizontal ranges bound the handlers in the
> > (relative) scroll dimensions. For example, a vertical List will report
> > HorizontalRange (Min:0, Max:0) because it can't be scrolled
> > horizontally. If it is scrolled to the top, VerticalRange min will be 0,
> > and its max the total height of the children not yet scrolled into view
> > (or MaxInt if List doesn't know the total height).
> >
> > With that information, the pointer router can precisely decide where to
> > deliver scroll events. It can even split up a scroll event between
> > multiple handlers if their ranges are lower than the scrolled amount.
> >
> > Apologies for not being clearer.
> >
>
> Thanks for the details, it now answers the question I previously had on the
> list.
>
>
> >
> > > +                             return true
> > > +                     }
> > > +             }
> > > +             pass = pass && n.pass
> > > +             if pass {
> > > +                     idx--
> > > +             } else {
> > > +                     idx = n.next
> > > +             }
> > > +     }
> > > +     return false
> > > +}
> > > +
> > >  func (q *pointerQueue) invTransform(areaIdx int, p f32.Point) f32.Point
> > {
> > >       if areaIdx == -1 {
> > >               return p
> > > @@ -335,6 +373,9 @@ func (q *pointerQueue) deliverEvent(p *pointerInfo,
> > events *handlerEvents, e poi
> > >               if e.Type&h.types == 0 {
> > >                       continue
> > >               }
> > > +             if e.Type == pointer.Scroll && !q.opHitTag(k, e.Position) {
> > > +                     continue
> > > +             }
> > >               e := e
> > >               if p.pressed && len(p.handlers) == 1 {
> > >                       e.Priority = pointer.Grabbed
> > > diff --git a/widget/editor.go b/widget/editor.go
> > > index 99c66b96..8f49d35b 100644
> > > --- a/widget/editor.go
> > > +++ b/widget/editor.go
> > > @@ -547,7 +547,12 @@ func (e *Editor) layout(gtx layout.Context)
> > layout.Dimensions {
> > >       r.Max.X += pointerPadding
> > >       pointer.Rect(r).Add(gtx.Ops)
> > >       pointer.CursorNameOp{Name: pointer.CursorText}.Add(gtx.Ops)
> > > -     e.scroller.Add(gtx.Ops)
> > > +     var xScroll, yScroll pointer.ScrollRange

Should we make the horizontal/vertical scroll ranges two image.Points,
for the same reason gtx.Constraints are modeled as two image.Points?
(I don't know).

> > > +     if e.focused {
> >
> > Why make Editor scrollable only when focused?
> >
>
> Because in a vertical List of Editors, how to distinguish where vertical
> scrolls should go:
> the list or the editor?
>

Scrolls will be distributed between handlers that contain the pointer,
foremost first.

Consider a vertical scroll of +50 pixels, and an Editor on top of a List
both containing the pointer. Their vertical ranges are,

Editor: [Min: 0, Max: 20]
List: [Min: -30, Max: MaxInt]

The router then splits the scroll in two, one +20 pixels vertical scroll
to the Editor, and one +30 scroll to the List.

A vertical scroll of -50 pixels result in a single -30 scroll to the
List, discarding the remaining -20 (or List receives all -50 pixels to
indicate "overscrolling"). The Editor's receives no scroll event because
its vertical min is zero.

Elias
Reply to thread Export thread (mbox)