feat: Carousel Launcher & Triple Click Home
This commit is contained in:
@@ -215,36 +215,41 @@ void sys_gfx_draw_action_bar(const char *left_hint, const char *right_hint)
|
||||
}
|
||||
}
|
||||
|
||||
/* UI Framework: Scrollable List Menu */
|
||||
/* UI Framework: Scrollable List Menu (Always centers highlighted entry) */
|
||||
void sys_gfx_draw_menu(int16_t y_start, const char *items[], size_t count, size_t selected_idx)
|
||||
{
|
||||
if (!items || count == 0) return;
|
||||
|
||||
size_t visible_count = 3;
|
||||
size_t top_idx = 0;
|
||||
int16_t y_center = y_start + 9;
|
||||
int16_t y_top = y_start;
|
||||
int16_t y_bot = y_start + 18;
|
||||
|
||||
if (selected_idx >= visible_count) {
|
||||
top_idx = selected_idx - visible_count + 1;
|
||||
if (count == 1) {
|
||||
sys_gfx_fill_rect(0, y_center - 1, OLED_WIDTH - 4, 9, COLOR_WHITE);
|
||||
sys_gfx_draw_char_3x5(2, y_center + 1, '>', COLOR_BLACK);
|
||||
sys_gfx_draw_str_5x7(8, y_center, items[0], COLOR_BLACK);
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < visible_count && (top_idx + i) < count; i++) {
|
||||
size_t item_idx = top_idx + i;
|
||||
int16_t y = y_start + (i * 9);
|
||||
// Top item: previous item in list (cyclically)
|
||||
size_t prev_idx = (selected_idx + count - 1) % count;
|
||||
sys_gfx_draw_str_5x7(8, y_top, items[prev_idx], COLOR_WHITE);
|
||||
|
||||
if (item_idx == selected_idx) {
|
||||
sys_gfx_fill_rect(0, y - 1, OLED_WIDTH - 3, 9, COLOR_WHITE);
|
||||
sys_gfx_draw_char_3x5(2, y + 1, '>', COLOR_BLACK);
|
||||
sys_gfx_draw_str_5x7(8, y, items[item_idx], COLOR_BLACK);
|
||||
} else {
|
||||
sys_gfx_draw_str_5x7(8, y, items[item_idx], COLOR_WHITE);
|
||||
}
|
||||
}
|
||||
// Center item: currently highlighted entry
|
||||
sys_gfx_fill_rect(0, y_center - 1, OLED_WIDTH - 4, 9, COLOR_WHITE);
|
||||
sys_gfx_draw_char_3x5(2, y_center + 1, '>', COLOR_BLACK);
|
||||
sys_gfx_draw_str_5x7(8, y_center, items[selected_idx], COLOR_BLACK);
|
||||
|
||||
if (count > visible_count) {
|
||||
// Bottom item: next item in list (cyclically)
|
||||
size_t next_idx = (selected_idx + 1) % count;
|
||||
sys_gfx_draw_str_5x7(8, y_bot, items[next_idx], COLOR_WHITE);
|
||||
|
||||
// Right-hand vertical scroll indicator
|
||||
if (count > 1) {
|
||||
sys_gfx_draw_line(OLED_WIDTH - 1, y_start, OLED_WIDTH - 1, y_start + 26, COLOR_WHITE);
|
||||
int16_t thumb_h = 27 / count;
|
||||
int16_t thumb_h = 27 / (int16_t)count;
|
||||
if (thumb_h < 3) thumb_h = 3;
|
||||
int16_t thumb_y = y_start + (selected_idx * (27 - thumb_h)) / (count - 1);
|
||||
int16_t thumb_y = y_start + (int16_t)((selected_idx * (27 - thumb_h)) / (count - 1));
|
||||
sys_gfx_fill_rect(OLED_WIDTH - 2, thumb_y, 2, thumb_h, COLOR_WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user