|
Nugget
|
A helix selector, seen down its own axis. More...
#include <psyqo/helix-selector.hh>
Classes | |
| struct | Config |
| struct | Cursor |
| The cursor marker, as a triangle you can draw directly. More... | |
| struct | Event |
| struct | Slot |
| One visible item. More... | |
Public Member Functions | |
| void | setup (unsigned itemCount, const Config &config) |
| void | setOnEvent (eastl::function< void(Event)> &&callback) |
| void | setStickAngle (Angle a) |
| Crank by an absolute stick angle. | |
| void | step (int32_t items) |
| Crank by whole items. This is the d-pad adapter. | |
| void | activate () |
| Your confirm button's rising edge. | |
| void | update (const Trig<> &trig) |
| Settle one frame and rebuild the visible slots. | |
| unsigned | currentIndex () const |
| unsigned | visibleCount () const |
| const Slot & | slot (unsigned n) const |
| Slot 0 is the furthest from the camera. Draw them in order. | |
| const Cursor & | cursor () const |
| Where to draw the cursor marker, just inside the ring at the cursor angle. | |
| Angle | cursorAngle () const |
| The cursor's current angle, if you want to orient the marker you draw. | |
Static Public Attributes | |
| static constexpr unsigned | c_maxSlots = 48 |
A helix selector, seen down its own axis.
Items are laid out along a helix wrapped around a cylinder, and the camera looks straight down the helix axis, so the screen shows a spiral of annular sectors.
EVERY ITEM OWNS A FIXED SPOKE. Item i sits at angle i * 2pi / itemsPerTurn and never leaves it. What the crank moves is the CURSOR, which sweeps around the circle; items slide IN AND OUT along their own spokes as it approaches or passes them. So this is a dial, not a carousel: a is always in the same place on screen, and the user gets muscle memory for free.
It follows that item i and item i + itemsPerTurn share a spoke exactly, at different radii. That is the far-side doubling that shows what is coming, and it falls out of the geometry rather than being tuned in.
It also means the analog adapter is ABSOLUTE: the stick angle IS the cursor angle. Only the lap needs unwrapping, which setStickAngle does for you.
This class owns the geometry and the selection state and nothing else. It has no idea what a glyph is, what a character is, or that capital letters exist. It hands back quad corners plus a centre point per visible item and reports what got selected or activated; drawing, atlases, casing, text buffers and what "enter" means are all yours.
The helix is infinite and the item list is CYCLIC on it: the item at helix offset d is (cursor + d) mod itemCount, so cranking never hits an end, and one turn out from the first item is whatever the atlas has last.
| void psyqo::HelixSelector::activate | ( | ) |
Your confirm button's rising edge.
If the helix is still settling this snaps it to the target first and then fires, so a confirm is never swallowed mid-animation.
|
inline |
|
inline |
Where to draw the cursor marker, just inside the ring at the cursor angle.
|
inline |
The cursor's current angle, if you want to orient the marker you draw.
Crank by an absolute stick angle.
Feed this the raw stick direction every frame the stick is deflected enough to mean something, and simply stop calling it when it re-centres; the cursor stays where it was. The stick angle IS the cursor angle, so pointing somewhere new puts the cursor there directly. The only thing accumulated is the LAP: crossing the +/-pi seam moves you one turn along the helix rather than jumping the cursor to the far side of the dial.
|
inline |
Slot 0 is the furthest from the camera. Draw them in order.
|
inline |
Crank by whole items. This is the d-pad adapter.
Settle one frame and rebuild the visible slots.
|
inline |
|
staticconstexpr |