Search guides and the APICtrl K
  1. API reference
  2. Native GUI

gfx/animated_position.h

AnimatedPosition: a position that a finger throws, and that carries on moving after it lets go -- and ViewportDragScroller, which uses two of them to scroll a Viewport by dragging its content.

#include <sonore/gfx/animated_position.h>
On this page

Design notes

Why the application has to integrate a flick

A wheel or a precision trackpad arrives already smoothed: the operating system turns a flick into a decelerating stream of scroll events, and the Viewport only has to follow them. A finger on a touch screen, or a pen, arrives as a DRAG -- positions, and then a release. Nothing after the release says the list should keep moving; the momentum has to be worked out from how fast the finger was going when it left, and then integrated, frame by frame, against friction. That is this.

Behaviours

The reference's two, with its defaults:

ContinuousWithMomentum  coasts at the release velocity, losing a fraction
                        of it to friction every 60th of a second, and
                        stops once slower than a minimum. The friction is
                        integrated exactly over the elapsed time rather
                        than applied per call, so a flick goes the same
                        distance at 30, 60 or 144 Hz.
SnapToPageBoundaries    settles on the nearest whole number -- a page --
                        or the next one in the direction of a fast flick.

A behaviour is any type with releasedWithVelocity(position, velocity), getNextPosition(old, elapsed) and isStopped(position): write a third for a detent, a rubber band, a carousel.

The clock

As everywhere in this SDK, time is an argument or an injectable function, so the decay and the snap are exact tests. ViewportDragScroller ticks itself from a VBlankAttachment while it coasts -- once per display refresh, which is what makes the motion smooth -- unless told to leave the ticking to its owner.

Types 4

Settles on a whole number: page boundaries, when one unit is one page.

template <typename Behaviour> class AnimatedPosition

A one-dimensional position that can be dragged and then let go of.

beginDrag / drag(deltaFromStart) / endDrag follow a gesture, measuring its velocity as it goes; on endDrag the behaviour takes over and update(now) moves the position until the behaviour says it has stopped.

class ViewportDragScroller : private MouseListener

Scroll a Viewport by dragging its content, with momentum -- the reference's Viewport::setScrollOnDragMode, as an object attached to the viewport.

Listens to everything inside the viewed component, so a drag that starts on a row, a label or a button still scrolls. It does not start until the pointer has moved a few pixels, so a tap is still a tap. Drags on the viewport's own scroll bars, and on any component given to setIgnoresDragsFrom, are left alone -- a slider in a scrolling list must move its value, not the list.

↑↓ to move↵ to openEvery public name in the headers, and every guide