feat(ui): infinite wrap carousels

Arrow prev/next in home and games carousels now use modular
arithmetic ((cur + dir + n) % n) instead of clamping, so
pressing left on the first slide jumps to the last and vice
versa. Swipe still clamps at the edges (LVGL snap resists a
clean programmatic jump mid-gesture); arrow-wrap is seamless.
This commit is contained in:
L'électron rare
2026-06-21 11:44:05 +02:00
parent 7d2a5f9d1c
commit 6faca03549
2 changed files with 10 additions and 8 deletions
+5 -4
View File
@@ -344,7 +344,9 @@ static void gdots_update(int idx)
static void games_scroll_cb(lv_event_t *e)
{
lv_obj_t *t = lv_event_get_target(e);
int idx = (lv_obj_get_scroll_x(t) + GAMES_SLIDE_W / 2) / GAMES_SLIDE_W;
int32_t sx = lv_obj_get_scroll_x(t);
int idx = (int)((sx + GAMES_SLIDE_W / 2) / GAMES_SLIDE_W);
// Clamp for dot update; swipe past first/last will snap back naturally.
if (idx < 0) idx = 0;
if (idx >= GAMES_N_TILES) idx = GAMES_N_TILES - 1;
s_gcur = idx;
@@ -353,9 +355,8 @@ static void games_scroll_cb(lv_event_t *e)
static void games_arrow_cb(lv_event_t *e)
{
int idx = s_gcur + (int)(intptr_t)lv_event_get_user_data(e);
if (idx < 0) idx = 0;
if (idx >= GAMES_N_TILES) idx = GAMES_N_TILES - 1;
// Wrap-around: (cur + dir + n) % n handles both +1 and -1 cleanly.
int idx = (s_gcur + (int)(intptr_t)lv_event_get_user_data(e) + GAMES_N_TILES) % GAMES_N_TILES;
s_gcur = idx;
lv_obj_scroll_to_x(s_gtrack, idx * GAMES_SLIDE_W, LV_ANIM_ON);
gdots_update(idx);
+5 -4
View File
@@ -72,7 +72,9 @@ static void adots_update(int idx)
static void home_scroll_cb(lv_event_t *e)
{
lv_obj_t *t = lv_event_get_target(e);
int idx = (lv_obj_get_scroll_x(t) + HOME_SLIDE_W / 2) / HOME_SLIDE_W;
int32_t sx = lv_obj_get_scroll_x(t);
int idx = (int)((sx + HOME_SLIDE_W / 2) / HOME_SLIDE_W);
// Clamp for dot update; swipe past first/last will snap back naturally.
if (idx < 0) idx = 0;
if (idx >= s_n_acts) idx = s_n_acts - 1;
s_acur = idx;
@@ -81,9 +83,8 @@ static void home_scroll_cb(lv_event_t *e)
static void home_arrow_cb(lv_event_t *e)
{
int idx = s_acur + (int)(intptr_t)lv_event_get_user_data(e);
if (idx < 0) idx = 0;
if (idx >= s_n_acts) idx = s_n_acts - 1;
// Wrap-around: (cur + dir + n) % n handles both +1 and -1 cleanly.
int idx = (s_acur + (int)(intptr_t)lv_event_get_user_data(e) + s_n_acts) % s_n_acts;
s_acur = idx;
lv_obj_scroll_to_x(s_track, idx * HOME_SLIDE_W, LV_ANIM_ON);
adots_update(idx);