Useful code pattering for repeated options

Figured this would be helpful for people.

In the UI Creator there are options for everything within LVGL (Boy is this a lot of tying to do, but in the end will make it complete).

For example Button Maps, each button has 6 options (No Repeat, Inactive, etc). Well in order to record the UI changes we need a call back.

In order to minimize the number of different call backs, what I did was:

  1. Create a single call back for all of the options.
  2. In the call back do this:
    if (event != LV_EVENT_VALUE_CHANGED)
        return;
    std::string option = lv_cb_get_text(obj);

Since each cb option has different text, I can assign the value based on that, and have a single call back for all checkboxes.

Easy pizzy.

The whole function, for completeness

void BtnmEditorWindow::optCB(lv_obj_t* obj, lv_event_t event)
{
    if (event != LV_EVENT_VALUE_CHANGED)
        return;
    std::string option = lv_cb_get_text(obj);

    bool checked = lv_cb_is_checked(obj);
    uint16_t flag = 0;
    if (option == "Hidden")
    {
        flag = LV_BTNM_CTRL_HIDDEN;
    }
    if (option == "No Repeat")
    {
        flag = LV_BTNM_CTRL_NO_REPEAT;
    }
    if (option == "Inactive")
    {
        flag = LV_BTNM_CTRL_INACTIVE;
    }
    if (option == "Toggle Enable")
    {
        flag = LV_BTNM_CTRL_TGL_ENABLE;
    }
    if (option == "Toggle State")
    {
        flag = LV_BTNM_CTRL_TGL_STATE;
    }
    if (option == "Click Trigger")
    {
        flag = LV_BTNM_CTRL_CLICK_TRIG;
    }

    if (flag != 0)
    {
        if (checked)
            buttons[selectedButton].ctrlBits = buttons[selectedButton].ctrlBits |= flag;
        else
            buttons[selectedButton].ctrlBits = buttons[selectedButton].ctrlBits &= ~flag;
    }

    // Reset all the ctrl bits
    static std::vector<lv_btnm_ctrl_t> ctrlMap;
    ctrlMap.clear();
    for (int i = 0; i < buttons.size(); i++)
        ctrlMap.push_back(buttons[i].ctrlBits);
    lv_btnm_set_ctrl_map(preview, ctrlMap.data());
}
1 Like

Yes, it’s good idea to re-use event callbacks. Thanks for sharing!

An other option to identify the objects with their user_data.

Absolutely on user_data. I use it extensively.

In this case it was not necessary, because there was already a differentiator on the text.

Within LVGL UI Creator, normally I have code for creating objects, which in turn all use a similar call back. For example Text Areas.

All text areas need the following:

  1. Set them active when clicked upon to get keyboard input (Also deactivate all of the ones in the group)
  2. Set the variable they are tied to when they are changed
  3. Some other internal things like reset the object with the variable’s new data, etc.

So, using this paradigm, I simply have code that creates the TA, and registers to a single callback for each of the text areas.

1 Like