Hardware Button multiple points

Hi! Hope you are all safe in these crazy times!
So I am following this tutorial https://blog.littlevgl.com/2019-01-08/hardware-button and https://docs.littlevgl.com/en/html/porting/indev.html#types-of-input-devices to get 3 physical buttons to work but I am using micropython.
I already can work with 1 button but I can’t figure out how to set an array to use 3.
Here is a snip of my code:

class ButtonsInputDriver:
    def __init__(self, button, group=None):
        def input_callback(drv, data):
            if button.pressed_left:
                data.state = lv.INDEV_STATE.PR
            else:
                data.state = lv.INDEV_STATE.REL
            gc.collect()
            return False

        self.drv = lv.indev_drv_t()
        lv.indev_drv_init(self.drv)
        self.drv.type = lv.INDEV_TYPE.BUTTON
        self.drv.read_cb = input_callback
        self.win_drv = lv.indev_drv_register(self.drv)
        self.points = lv.point_t()
        self.points.x=20
        self.points.y=240
        lv.indev_set_button_points(self.win_drv, self.points)

Any idea on how to solve this? My problem right now is in the 4 last lines of code. I want to set multiple points (3 different buttons)
Thank you!!

That looks like a bug!

Here is lv_indev_set_button_points C prototype in lvgl:

void lv_indev_set_button_points(lv_indev_t * indev, const lv_point_t * points);

Here points parameter is declared as a pointer and not as an array.
When a parameter is passed as an array in a C function, it hints Micropython Binding that this is an array of elements and not a pointer to a single element.

For example, lv_line_set_points receives lv_point_t point_a[] as a parameter, and in Python line.set_points receives a list of points.

@kisvegabor - In order to solve this, I suggest fixing the prototype of lv_indev_set_button_points.
Perhaps there are other similar cases where we would want to change from pointer to array parameter?

1 Like

Aaaah I had the feeling that something was wrong… I had tried everything that I could remember to create a workable array… I even seen you talking about the line.set_points in other post and tried something similar, but no luck. Thank you @amirgon!

Any idea of how I can make a quick work around? I want to use 3 physical buttons but I don’t want to use the encoder version (due to program workflow). I would be grateful if someone could give me a hand.
Or any idea when the fix will be made?
Once again, thank you!

I’m not aware of a workaround, but the fix is so simple that you can implement it yourself very easily!
Just change the function prototype (on both H and C files) to:

void lv_indev_set_button_points(lv_indev_t * indev, const lv_point_t points[]);

Then build lv_micropython. That’s it.

C doesn’t make a difference between passing an array[] vs. passing a *pointer, so changing the function prototype doesn’t require any additional change in the C code. It’s just a hint for the Micropython Binding script. When the script runs as part of the build process, it would generate indev_set_button_points function that expects a list as the second argument.

After doing that (and making sure it really works), if you send a PR to lvgl we would very much appreciate it! :wink:

1 Like

Thank you for the help @amirgon ! I’ll give it a try and post my results here after!

@amirgon I’ve just fixed it.

1 Like