Roller Widget¶
Overview¶
The Roller widget displays a scrollable drum of text items. The user flicks up or down to spin the roller and land on a value. It is commonly used for time/date pickers and short numbered lists.
Enable¶
Creation¶
#ifdef MGUI_WIDGET_ENABLE_ROLLER
mgui_widget_t* roller = mgui_allocate_widget(
parent,
MGUI_WIDGET_ROLLER,
(mgui_area_t){x, y, width, height},
MGUI_COLOR_ELEM_DARK_SLATE // roller background
);
#endif
API Reference¶
Items¶
static const char* items[] = {"A", "B", "C"};
mgui_widget_roller_set_items(roller, items, 3);
// Set initial selection by index
mgui_widget_roller_set_selected(roller, 0);
// Read back
int16_t idx = mgui_widget_roller_get_selected(roller);
const char* txt = mgui_widget_roller_get_selected_text(roller);
Appearance¶
// How many rows are visible at once (odd values look best)
mgui_widget_roller_set_visible_count(roller, 3);
// Row height in pixels
mgui_widget_roller_set_item_height(roller, 40);
// Font for item text
mgui_widget_roller_set_font(roller, MGUI_FONT_LEXEND_24PT_2BPP);
// Highlight color of the selected center item
mgui_widget_roller_set_highlight_color(roller, MGUI_COLOR_PURPLE);
Infinite Scroll¶
Events¶
static void on_roller(mgui_widget_t* obj, mgui_event_t event) {
if (event == MGUI_EVENT_CHANGE) {
int16_t idx = mgui_widget_roller_get_selected(obj);
}
}
mgui_widget_click_handler(roller, on_roller);
Common Combinations¶
| Use Case | Setup |
|---|---|
| Time picker | Two rollers (HH + MM) with a colon label between |
| Date picker | Three rollers (day, month, year) |
| Speed / level picker | Roller with numeric strings, infinite scroll off |
| Measurement unit | Short roller (2–4 items) |
Examples¶
Hour : Minute Time Picker¶
Two rollers sharing the same style — covers items, visible_count, rl_font, infinite_scroll, highlight_color, and a separator label.

{
"elements": [
{
"type": "box",
"name": "Screen",
"x": 0, "y": 0, "w": 320, "h": 240,
"color": "0xC6C6C6",
"children": [
{
"type": "roller",
"name": "HourRoller",
"x": 70, "y": 40, "w": 70, "h": 160,
"color": "0x3A2939",
"items": ["00","01","02","03","04","05","06","07","08","09",
"10","11","12","13","14","15","16","17","18","19",
"20","21","22","23"],
"selected": 12,
"visible_count": 3,
"rl_font": "MGUI_FONT_LEXEND_24PT_2BPP",
"infinite_scroll": true,
"highlight_color": "0x5900CC"
},
{
"type": "label",
"name": "Colon",
"x": 145, "y": 80, "w": 20, "h": 40,
"color": "0xC6C6C6",
"text": ":",
"font": "MGUI_FONT_LEXEND_24PT_2BPP"
},
{
"type": "roller",
"name": "MinRoller",
"x": 170, "y": 40, "w": 70, "h": 160,
"color": "0x3A2939",
"items": ["00","05","10","15","20","25","30","35","40","45","50","55"],
"selected": 0,
"visible_count": 3,
"rl_font": "MGUI_FONT_LEXEND_24PT_2BPP",
"infinite_scroll": true,
"highlight_color": "0x5900CC"
}
]
}
]
}
mgui_widget_t* screen = mgui_allocate_widget(
NULL, MGUI_WIDGET_BOX,
(mgui_area_t){0, 0, 320, 240},
MGUI_COLOR_LIGHT_GRAY);
#ifdef MGUI_WIDGET_ENABLE_ROLLER
static const char* hour_roller_items[] = {
"00","01","02","03","04","05","06","07","08","09",
"10","11","12","13","14","15","16","17","18","19",
"20","21","22","23"
};
mgui_widget_t* hour_roller = mgui_allocate_widget(
screen, MGUI_WIDGET_ROLLER,
(mgui_area_t){70, 40, 70, 160},
MGUI_COLOR_ELEM_DARK_SLATE);
mgui_widget_roller_set_items(hour_roller, hour_roller_items, 24);
mgui_widget_roller_set_selected(hour_roller, 12);
mgui_widget_roller_set_visible_count(hour_roller, 3);
mgui_widget_roller_set_font(hour_roller, MGUI_FONT_LEXEND_24PT_2BPP);
mgui_widget_roller_set_infinite_scroll(hour_roller, true);
mgui_widget_roller_set_highlight_color(hour_roller, MGUI_COLOR_PURPLE);
#endif /* MGUI_WIDGET_ENABLE_ROLLER */
mgui_widget_t* colon = mgui_allocate_widget(
screen, MGUI_WIDGET_LABEL,
(mgui_area_t){145, 80, 20, 40},
MGUI_COLOR_LIGHT_GRAY);
mgui_widget_label_set_text(colon, ":");
mgui_widget_label_set_font_type(colon, MGUI_FONT_LEXEND_24PT_2BPP);
mgui_widget_align(colon, MGUI_ALIGN_CENTER);
#ifdef MGUI_WIDGET_ENABLE_ROLLER
static const char* min_roller_items[] = {
"00","05","10","15","20","25","30","35","40","45","50","55"
};
mgui_widget_t* min_roller = mgui_allocate_widget(
screen, MGUI_WIDGET_ROLLER,
(mgui_area_t){170, 40, 70, 160},
MGUI_COLOR_ELEM_DARK_SLATE);
mgui_widget_roller_set_items(min_roller, min_roller_items, 12);
mgui_widget_roller_set_selected(min_roller, 0);
mgui_widget_roller_set_visible_count(min_roller, 3);
mgui_widget_roller_set_font(min_roller, MGUI_FONT_LEXEND_24PT_2BPP);
mgui_widget_roller_set_infinite_scroll(min_roller, true);
mgui_widget_roller_set_highlight_color(min_roller, MGUI_COLOR_PURPLE);
#endif /* MGUI_WIDGET_ENABLE_ROLLER */
Level Picker (1–5, No Wrap)¶
A short roller with infinite scroll off and a change callback — covers selected readback and MGUI_EVENT_CHANGE.

{
"elements": [
{
"type": "box",
"name": "Screen",
"x": 0, "y": 0, "w": 320, "h": 240,
"color": "0xC6C6C6",
"children": [
{
"type": "roller",
"name": "LevelRoller",
"x": 0, "y": 0, "w": 100, "h": 150,
"color": "0x3A2939",
"align": "MGUI_ALIGN_CENTER",
"items": ["1","2","3","4","5"],
"selected": 2,
"visible_count": 3,
"highlight_color": "0x2DA852",
"infinite_scroll": false
}
]
}
]
}
#ifdef MGUI_WIDGET_ENABLE_ROLLER
static const char* level_roller_items[] = {"1","2","3","4","5"};
mgui_widget_t* level_roller = mgui_allocate_widget(
screen, MGUI_WIDGET_ROLLER,
(mgui_area_t){0, 0, 100, 150},
MGUI_COLOR_ELEM_DARK_SLATE);
mgui_widget_align(level_roller, MGUI_ALIGN_CENTER);
mgui_widget_roller_set_items(level_roller, level_roller_items, 5);
mgui_widget_roller_set_selected(level_roller, 2);
mgui_widget_roller_set_visible_count(level_roller, 3);
mgui_widget_roller_set_highlight_color(level_roller, MGUI_COLOR_EMERALD);
mgui_widget_roller_set_infinite_scroll(level_roller, false);
static void on_level(mgui_widget_t* obj, mgui_event_t event) {
if (event == MGUI_EVENT_CHANGE) {
int16_t level = mgui_widget_roller_get_selected(obj) + 1;
// use level (1–5)
}
}
mgui_widget_click_handler(level_roller, on_level);
#endif /* MGUI_WIDGET_ENABLE_ROLLER */