Better support for custom keyboards

Currently the keyboard widget is very nice, but cannot really be used to create a custom keyboard layout.
The built-in modes don’t cover all possibilities, and it should theoretically be easy to drop in custom map/ctrl but it does not work correctly as-is.
lv_keyboard_set_map and lv_keyboard_set_ctrl_map are linked to a lv_keyboard_mode_t mode, but if you want to create a new map in addition to the existing ones it is not possible.
Also, both of those functions call lv_keyboard_update_map which updates both the map and ctrl at the same time, so they must always be the same size. This makes it not possible to actually change the a map or ctrl to anything that doesn’t match the size of an existing map.

What have you missed?

There are a few that can be achieved by modifying the control map of the numbers keyboard:

  • IP address (no +/-)
  • Port # (no +/-, no period)

But there are some specific cases which might require a totally new map and control map. One example I have is a hexadecimal input, 0-F.

In my application, when someone selects a textarea, the keyboard pops up with the correct mapping for that textarea. While the keyboard is up, it is possible to select a different textarea with a different requirement (one could be text input, one could be #, one could be hex, etc), and so I switch the mapping on the fly. With the fixed mappings, you can’t “add” an additional one to switch to.

Perhaps the global (well, global to the keyboard) vars for the map/ctrl map could be created as part of the keyboard object itself (part of ext), and can grow in size, i.e. you can add your own user maps to the existing ones.

So you want an LV_KEYBOARD_MODE_CUSTOM which changes to ext->custom_map and ext->custom_ctrl_map. In other words, the goal is to use lv_keyboard_set_mode instead of lv_keyboard_set_map?

Hello, I think I might be running into the same issue, although I’m a complete newbe at lvgl (loving it so far btw!) and it’s likely that I am missing something obvious. I’m trying to reproduce a display touch number pad that also includes a Clear, and up/down for navigating between text entry boxes assigned to a group. the kb number option is close, but we don’t need the left/right for moving the cursor in the text field and I’m trying to replace that with navigation between text boxes in the group. I’ve tried the button matrix and a new map on the keyboard, but no solution yet and I"m here searching the forum for examples. Any suggestions would be greatly appreciated!

Well, maps and modes are linked with the keyboard.
But yes, there should add least be 1 custom mode.
Then, if you need multiple custom modes, you can switch out the map/ctrl_map for the custom mode.
Right now, you have to “overwrite” one of the existing modes’ maps/ctrl_maps. Once you have done that, you can’t recover the built-in map/ctrl_map for that built-in mode without deleting the keyboard object and creating a new one.

You can add a custom map with lv_keyboard_set_map and catch clicks on your custom keys in the keyboards event function with LV_EVENT_VALUE_CHANGED event.

Note that, you should call lv_keyboard_def_event_cb if a non-custom key was pressed to let the keyboard to handle them normally.

I see. Can we solve the issue even by making the built-in maps/ctrls public? (to let you reassign them)

Personally, I think adding one additional mode, something like this:

enum {
    LV_KEYBOARD_MODE_TEXT_LOWER,
    LV_KEYBOARD_MODE_TEXT_UPPER,
    LV_KEYBOARD_MODE_SPECIAL,
    LV_KEYBOARD_MODE_NUM,
    LV_KEYBOARD_MODE_CUSTOM,
};

Would be a better solution, as the user can always use this mode for their custom maps, while still being able to switch to the built in maps. I think this is more clear than overriding a built in mode, then resetting that mode’s maps back to original if you need to switch between the two. It is more clear to document as well. LV_KEYBOARD_MODE_CUSTOM corresponding map/ctrls can be empty by default.

Okay, it sounds reasonable.
It seems the highest level of flexibility could be achieved with:

lv_keyboard_set_map/ctrl(kb, mode, map);

So it allows you to redefine any maps (including your custom one). It has the cost that the map and ctrl of all modes needs to be stored in the keyboard but it’s only 10 pointers and usually, you have only 1 keyboard.