Difference in Slider widget behavior between version 8.3 and 9.0

There seems to be a difference in the way the Slider widget works between version 8.3 and 9.0 when using a background image for the indicator.

Here is how it works in version 8.3:

indicator_8.3

And here is how it works in version 9.0:

indicator_9.0

Here is the code for slider creation:

lv_obj_t *obj = lv_slider_create(parent_obj);
lv_obj_set_pos(obj, -1, -10);
lv_obj_set_size(obj, 332, 396);
lv_obj_add_event_cb(obj, event_handler_cb_screen_1_print_slider_print_view, LV_EVENT_ALL, flowState);
lv_obj_set_style_align(obj, LV_ALIGN_LEFT_MID, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_image_src(obj, &img_print_view_bg, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_color(obj, lv_color_hex(0xff000000), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_image_src(obj, &img_print_view_front, LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_set_style_bg_color(obj, lv_color_hex(0xff000000), LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(obj, 0, LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_set_style_align(obj, LV_ALIGN_LEFT_MID, LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_set_style_radius(obj, 0, LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_set_style_bg_color(obj, lv_color_hex(0xff000000), LV_PART_KNOB | LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(obj, 0, LV_PART_KNOB | LV_STATE_DEFAULT);

Does anyone have an idea how to make the indicator in version 9.0 to behave like in 8.3?

for this specific design I would create an lv_image object and set it where the slider is and then create slider object to set it as a child of the image object. The slider object you would set the background color opacity to zero and set the indicator opacity to whatever you want to make it kind of see through and set the color of the indicator to whatever it is you want.

it would be something along the lines of

lv_obj_t *img = lv_img_create(parent_obj);
lv_img_set_src(img, &img_print_view_front);
lv_obj_set_pos(img, -1, -10);
lv_obj_set_size(img, 332, 396);
lv_obj_set_style_align(img, LV_ALIGN_LEFT_MID, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_t *obj = lv_slider_create(img);
lv_obj_set_size(obj, 332, 396);
lv_obj_set_style_align(obj, LV_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_add_event_cb(obj, event_handler_cb_screen_1_print_slider_print_view, LV_EVENT_ALL, flowState);
lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_color(obj, lv_color_hex(0x000000), LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(obj, 125, LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_set_style_radius(obj, 0, LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_set_style_bg_color(obj, lv_color_hex(0xff000000), LV_PART_KNOB | LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(obj, 0, LV_PART_KNOB | LV_STATE_DEFAULT);

using layers and opacity is the trick to get the most efficient and also the fastest rendering that can be done. This way the image in only being rendered a single time and it has nothing to do with the operation of the slider. so the image doesn’t have to be rendered when the slider moves. It is much faster to render a single color and opacity for the indicator.

Some of the function names you might have to change to make them LVGL v9.0 compliant but other than that it should work. At the very least it gives you the general idea of what to do.

I can’t achieve what I want in the way you described.

LVGL 8.3:

indicator_9.0_3

LVGL 9.0:

indicator_9.0_3

Also, I can’t agree with this statement, I think a part of image must be rendered each time you move the slider.

This way the image in only being rendered a single time and it has nothing to do with the operation of the slider.

OK so I am confused as to why the second slider in your example is not doing what you want it to?

Is it because the slider is upside down? If that is the case it’s an easy fix to flip it. Otherwise the effect is the same yes?

so to change the orientation

lv_obj_set_style_base_dir(slider, LV_BASE_DIR_RTL, 0);

Oh and you are correct about it rendering the image again. It would only be rendering part of a single image though instead of having to render a whole image and part of a second image.

Yes, you are right, if I can flip it then it would be (almost) the same. But LV_BASE_DIR_RTL doesn’t flip it.

Also, there is this issue of round corners:

image

I can set radius style for the indicator to match round corner of the image:

image

But then I will have this problem:

image

Anyway, with slightly different background image maybe I can make it work.

I think how it worked in version 8.3 works great with any combination of main and indicator images. I don’t understand why this change was made in 9.0, maybe it’s a bug that no one has noticed so far.

You figured out how to correct the issue with the rounded corners, problem is it is going to round all 4 corners if you set it to do it to the indicator. You want to do that that to the whole slider and not just the indicator.

So when the bar is all the way down you can see it. That is easy top handle with an event callback to for when the value gets set. When the value gets to zero then make the indicator opacity 0. and when the value is anything other than zero set the opacity to whatever it is you want it set to.

let me see the code you are using now.

Here is the code, but please note that my original question is more about why the behavior of the slider was changed in version 9.0 in what I consider to be an inferior way, and less about how to implement this specific slider.

lv_obj_t *obj = lv_img_create(parent_obj);
lv_obj_set_pos(obj, 333, 466);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_img_set_src(obj, &img_print_view_bg);
lv_obj_add_flag(obj, LV_OBJ_FLAG_ADV_HITTEST);
lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE);
{
    lv_obj_t *parent_obj = obj;
    {
        lv_obj_t *obj = lv_img_create(parent_obj);
        lv_obj_set_pos(obj, 0, 0);
        lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
        lv_img_set_src(obj, &img_print_view_front);
        lv_obj_add_flag(obj, LV_OBJ_FLAG_ADV_HITTEST);
        lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE);
        {
            lv_obj_t *parent_obj = obj;
            {
                lv_obj_t *obj = lv_slider_create(parent_obj);
                lv_obj_set_pos(obj, 20, 21);
                lv_obj_set_size(obj, 292, 353);
                lv_slider_set_value(obj, 25, LV_ANIM_OFF);
                lv_obj_set_style_bg_color(obj, lv_color_hex(0xff000000), LV_PART_MAIN | LV_STATE_DEFAULT);
                lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
                lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
                lv_obj_set_style_base_dir(obj, LV_BASE_DIR_RTL, LV_PART_MAIN | LV_STATE_DEFAULT);
                lv_obj_set_style_bg_color(obj, lv_color_hex(0xff000000), LV_PART_INDICATOR | LV_STATE_DEFAULT);
                lv_obj_set_style_bg_opa(obj, 125, LV_PART_INDICATOR | LV_STATE_DEFAULT);
                lv_obj_set_style_align(obj, LV_ALIGN_LEFT_MID, LV_PART_INDICATOR | LV_STATE_DEFAULT);
                lv_obj_set_style_radius(obj, 17, LV_PART_INDICATOR | LV_STATE_DEFAULT);
                lv_obj_set_style_bg_color(obj, lv_color_hex(0xff000000), LV_PART_KNOB | LV_STATE_DEFAULT);
                lv_obj_set_style_bg_opa(obj, 0, LV_PART_KNOB | LV_STATE_DEFAULT);
                lv_obj_set_style_radius(obj, 0, LV_PART_KNOB | LV_STATE_DEFAULT);
            }
        }
    }
}

You should be able to just run this test code. add in the bits that you need to initialize your display compile and flash it and then run it. This is all that should need to be done in order to have it work.

You cannot change the order in which the different items are created otherwise it will screw up the layering and you will see things you don’t want to be seeing in the rendering.

I also included the images I used as well to show you what I did.
ui_test.zip (475.9 KB)