Description
We have a dropdown list that can contain up to 2000 items in it, but when paging down it reaches 256 and the scrollbar indicates it’s at the end of the list but you can still page down and the item is displayed in main part of the dropdown but the dropdown list part stays at 256.
What MCU/Processor/Board and compiler are you using?
I can reproduce this on my Linux PC using SDL and on the actual target which is SAMA5D1 board running Linux.
What LVGL version are you using?
v8.3
What do you want to achieve?
I would like to be able to page all the way down to the end.
What have you tried so far?
I can’t find any solution. I’ve checked through the configuration files but can’t find any limit on drop down lists.
Code to reproduce
Here is example code to reproduce on a Linux PC, it creates 2000 items, 0000, 0001, … 1999 and uses left and right arrow keys to page up and down by 10.
#include "lvgl.h"
#include "lv_drivers/sdl/sdl.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#define ITEM_COUNT 2000
#define SDL_HOR_RES 320
#define SDL_VER_RES 240
static lv_color_t buf1[SDL_HOR_RES * SDL_VER_RES];
static lv_disp_draw_buf_t draw_buf;
static lv_indev_drv_t indev_drv;
static lv_group_t *group;
static void keyboard_event_cb(lv_event_t *e)
{
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t *cb = lv_event_get_target(e);
if (code == LV_EVENT_KEY) {
uint32_t key = lv_event_get_key(e);
switch (key) {
case LV_KEY_UP:
lv_dropdown_set_selected(cb, lv_dropdown_get_selected(cb) - 1);
break;
case LV_KEY_DOWN:
lv_dropdown_set_selected(cb, lv_dropdown_get_selected(cb) + 1);
break;
case LV_KEY_LEFT: {
int sel = lv_dropdown_get_selected(cb) - 10;
lv_dropdown_set_selected(cb, sel < 0 ? 0 : sel);
break;
}
case LV_KEY_RIGHT: {
int sel = lv_dropdown_get_selected(cb) + 10;
if (sel >= ITEM_COUNT) sel = ITEM_COUNT - 1;
lv_dropdown_set_selected(cb, sel);
break;
}
}
}
}
static char options[(ITEM_COUNT * 5)]; // Each item is "0000\n" (4 chars + 1 for '\0')
static void create_combobox(void)
{
lv_obj_t *cb = lv_dropdown_create(lv_scr_act());
lv_obj_set_size(cb, 150, 40);
lv_obj_align(cb, LV_ALIGN_CENTER, 0, 0);
for (int i = 0; i < ITEM_COUNT; i++) {
snprintf(&options[i*5], 6, "%04d\n", i);
}
options[(ITEM_COUNT * 5)-1] = '\0';
lv_dropdown_set_options_static(cb, options);
lv_obj_add_event_cb(cb, keyboard_event_cb, LV_EVENT_KEY, NULL);
// Add dropdown to the group to receive keyboard input
lv_group_add_obj(group, cb);
lv_group_focus_obj(cb);
}
int main(void)
{
lv_init();
/* Use the 'sdl' driver which creates window on PC's monitor to simulate a display*/
sdl_init();
lv_disp_draw_buf_init(&draw_buf, buf1, NULL, SDL_HOR_RES * SDL_VER_RES);
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.draw_buf = &draw_buf;
disp_drv.flush_cb = sdl_display_flush;
disp_drv.hor_res = SDL_HOR_RES;
disp_drv.ver_res = SDL_VER_RES;
lv_disp_drv_register(&disp_drv);
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_KEYPAD;
indev_drv.read_cb = sdl_keyboard_read;
lv_indev_t *kb_indev = lv_indev_drv_register(&indev_drv);
// Create a group for keyboard input
group = lv_group_create();
lv_indev_set_group(kb_indev, group);
create_combobox();
while(!sdl_quit_qry) {
lv_timer_handler();
usleep(5000); // Sleep for 5 milliseconds
}
return 0;
}
uint32_t
custom_tick_get(void)
{
static uint64_t start_ms = 0;
struct timeval tv_now;
uint64_t now_ms;
uint32_t time_ms;
if (start_ms == 0) {
struct timeval tv_start;
gettimeofday(&tv_start, NULL);
start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;
}
gettimeofday(&tv_now, NULL);
now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;
time_ms = now_ms - start_ms;
return time_ms;
}