Roller resets position and loses focus on click using encoder

Description

I have a roller and an encoder for input.

When I press the encoder button the roller selection goes back to the top and the roller loses focus. The event LV_EVENT_VALUE_CHANGED is never triggered.

What MCU/Processor/Board and compiler are you using?

STM32, arm-none-eabi-g++

What LVGL version are you using?

v8 (current master)

What do you want to achieve?

Select an option from a roller using an encoder.

What have you tried so far?

Changing event filters on roller callback function.

Code to reproduce

#define MY_DISP_HOR_RES 128
#define MY_DISP_VER_RES 64

extern daisy::Sprout hw;
extern Store store;

daisy::FixedCapStr<10> debug_string("");

lv_disp_t * disp;

lv_obj_t * page_1;
lv_group_t * g;

lv_obj_t * roller1;
lv_obj_t * debuglabel;

void DisplayFlush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p)
{
  int32_t x, y;

  for(y = area->y1; y <= area->y2; y++)
  {
    for(x = area->x1; x <= area->x2; x++)
    {
      hw.display.DrawPixel(x, y, color_p->full);
      color_p++;
    }
  }

  hw.display.Update();
  lv_disp_flush_ready(disp);
}

void EncoderRead(lv_indev_drv_t * drv, lv_indev_data_t*data)
{
  if (store.enc_value != 0){
    data->enc_diff = store.enc_value;
    store.enc_value = 0;
  }

  if(hw.encoder.Pressed()) data->state = LV_INDEV_STATE_PR;
  else data->state = LV_INDEV_STATE_REL;
}

static void RollerEventHandler(lv_event_t * e)
{
  lv_event_code_t code = lv_event_get_code(e);
  lv_obj_t * obj = lv_event_get_target(e);

  if(code == LV_KEY_UP || code == LV_KEY_DOWN)
  {
    debug_string.Clear();
    debug_string.AppendInt(lv_roller_get_selected(obj));
    lv_label_set_text(debuglabel, debug_string);
  }

  if(code == LV_EVENT_VALUE_CHANGED)
  {
    debug_string.Clear();
    debug_string.AppendInt(42);
    lv_label_set_text(debuglabel, debug_string);
  }
}

static void LvglInit()
{
  lv_init();

  static lv_disp_draw_buf_t disp_buf;
  static lv_color_t buf[MY_DISP_HOR_RES * 10];
  lv_disp_draw_buf_init (&disp_buf, buf, NULL, MY_DISP_HOR_RES * 10);

  lv_disp_drv_t disp_drv;
  lv_disp_drv_init(&disp_drv);
  disp_drv.flush_cb = DisplayFlush;
  disp_drv.draw_buf = &disp_buf;
  disp_drv.hor_res = MY_DISP_HOR_RES;
  disp_drv.ver_res = MY_DISP_VER_RES;
  disp = lv_disp_drv_register(&disp_drv);

  g = lv_group_create();

  //ENCODER INIT
  lv_indev_drv_t indev_drv;
  lv_indev_drv_init(&indev_drv);
  indev_drv.type = LV_INDEV_TYPE_ENCODER;
  indev_drv.read_cb = EncoderRead;
  lv_indev_t * my_indev = lv_indev_drv_register(&indev_drv);

  lv_indev_set_group(my_indev, g);

  lv_theme_t * th;
  th = lv_theme_mono_init(disp, true, &lv_font_unscii_8);
  lv_disp_set_theme(disp, th);

  page_1 = lv_obj_create(NULL);
  lv_scr_load(page_1);

  //ROLLER
  roller1 = lv_roller_create(page_1);
  lv_roller_set_options(roller1,
    "Opt 1\n"
    "Opt 2\n"
    "Opt 3\n"
    "Opt 4\n"
    "Opt 5\n"
    , LV_ROLLER_MODE_NORMAL
  );

  lv_obj_set_width(roller1, 64);
  lv_obj_set_height(roller1, 120);
  lv_obj_set_align(roller1, LV_ALIGN_LEFT_MID);
  lv_roller_set_visible_row_count(roller1, 3);
  lv_obj_add_event_cb(roller1, RollerEventHandler, LV_EVENT_ALL, NULL);

  lv_group_add_obj(g, roller1);

  // Debugging label
  debuglabel = lv_label_create(page_1);
  lv_obj_set_align(debuglabel, LV_ALIGN_TOP_RIGHT);
  debug_string.Clear();
  debug_string.Append("OK");
  lv_label_set_text(debuglabel, debug_string);

  lv_group_add_obj(g, debuglabel);
}

Screenshot and/or video

Here’s a video of the behavior: