lvgl/lvgl

get_x_aligned returns wrong value in case of percentage unit

leidto opened this issue · 6 comments

LVGL version

v9.1.0

What happened?

btn.get_x_aligned() returns incorrect x value (if you use percentage), for example: 536870922

How to reproduce?

import display_driver
import lvgl as lv

scr = lv.obj()
btn = lv.button(scr)
btn.align(lv.ALIGN.CENTER, 0, 0)

btn.set_x(lv.pct(10))

label = lv.label(btn)
label.set_text('Hello World!')

lv.screen_load(scr)

print('btn x value:', btn.get_x_aligned())

get_x_aligned grabs the style property for x position of the object while get_x does a bit more to give you the real pixel value. The reason get_x_aligned reports 536870922 is because percent values are represented as special large numbers.

I was able to get 192 with

btn.update_layout()
print('btn x value:', btn.get_x())

The update_layout is needed to calculate the real pixel location.

The docstring for get_x_aligned (lv_obj_get_x_aligned) is:

/**
 * Get the actually set x coordinate of object, i.e. the offset form the set alignment
 * @param obj       pointer to an object
 * @return          the set x coordinate
 */
int32_t lv_obj_get_x_aligned(const lv_obj_t * obj);

And the docstring for get_x (lv_obj_get_x) is:

/**
 * Get the x coordinate of object.
 * @param obj       pointer to an object
 * @return          distance of `obj` from the left side of its parent plus the parent's left padding
 * @note            The position of the object is recalculated only on the next redraw. To force coordinate recalculation
 *                  call `lv_obj_update_layout(obj)`.
 * @note            Zero return value means the object is on the left padding of the parent, and not on the left edge.
 * @note            Scrolling of the parent doesn't change the returned value.
 * @note            The returned value is always the distance from the parent even if `obj` is positioned by a layout.
 */
int32_t lv_obj_get_x(const lv_obj_t * obj);

Interesting. The get_x_aligned method doesn't make much sense in this form. I'm looking for a method to get the aligned coordinates. In this case the 192 is incorrect, because is relative to the top left but I work with a centered button in this case. I'd like to get the aligned coordinates.

Fair enough! In fact, get_x_aligned doesn't do what that docstring says.

@kisvegabor should this be fixed? If so, should it call get_x internally and then calculate the offset based on the currently set align?

The docstring says

Get the actually set x coordinate of object, i.e. the offset form the set alignment

So if you set the x offset in pixels, it will return it. If you set %, it would return that. In fact, update_layout is not required as get_x_aligned reads the data from the styles directly.

int32_t lv_obj_get_x_aligned(const lv_obj_t * obj)
{
    return lv_obj_get_style_x(obj, LV_PART_MAIN);
}

Ah you're right, it's always correct for pixel values.

@leidto you can do this

print('btn x value:', lv.pct_to_px(
    btn.get_x_aligned(),            # value
    btn.get_parent().get_width()    # base
))
btn x value: 42

42 is 10% of 420, the screen width.

pct_to_px method is my friend, thank you both for your help!