Keyboard (lv_keyboard)

Overview

The Keyboard object is a special Button matrix with predefined keymaps and other features to realize a virtual keyboard to write texts into a Text area.

Parts and Styles

Similarly to Button matrices Keyboards consist of 2 part:

  • LV_PART_MAIN The main part. Uses all the typical background properties

  • LV_PART_ITEMS The buttons. Also uses all typical background properties as well as the text properties.

Usage

Modes

The Keyboards have the following modes:

The TEXT modes' layout contains buttons to change mode.

To set the mode manually, use lv_keyboard_set_mode(kb, mode). The default mode is LV_KEYBOARD_MODE_TEXT_UPPER.

Assign Text area

You can assign a Text area to the Keyboard to automatically put the clicked characters there. To assign the text area, use lv_keyboard_set_textarea(kb, ta).

Key Popovers

To enable key popovers on press, like on common Android and iOS keyboards, use lv_keyboard_set_popovers(kb, true). The default control maps are preconfigured to only show the popovers on keys that produce a symbol and not on e.g. space. If you use a custom keymap, set the LV_BTNMATRIX_CTRL_POPOVER flag for all keys that you want to show a popover.

Note that popovers for keys in the top row will draw outside the widget boundaries. To account for this, reserve extra free space on top of the keyboard or ensure that the keyboard is added after any widgets adjacent to its top boundary so that the popovers can draw over those.

The popovers currently are merely a visual effect and don't allow selecting additional characters such as accents yet.

New Keymap

You can specify a new map (layout) for the keyboard with lv_keyboard_set_map(kb, LV_KEYBOARD_MODE_..., kb_map, kb_ctrl). See the Button matrix for more information about creating new maps and ctrls.

Keep in mind that using following keywords will have the same effect as with the original map:

Events

The keyboard has a default event handler callback called lv_keyboard_def_event_cb(), which handles the button pressing, map changing, the assigned text area, etc. You can remove it and replace it with a custom event handler if you wish.

note:

In 8.0 and newer, adding an event handler to the keyboard does not remove the default event handler. This behavior differs from v7, where adding an event handler would always replace the previous one.

Learn more about Events.

Keys

  • LV_KEY_RIGHT/UP/LEFT/RIGHT To navigate among the buttons and select one.

  • LV_KEY_ENTER To press/release the selected button.

Learn more about Keys.

Examples

Keyboard with text area

#include "../../lv_examples.h"
#if LV_USE_KEYBOARD && LV_BUILD_EXAMPLES

static void ta_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * ta = lv_event_get_target(e);
    lv_obj_t * kb = lv_event_get_user_data(e);
    if(code == LV_EVENT_FOCUSED) {
        lv_keyboard_set_textarea(kb, ta);
        lv_obj_remove_flag(kb, LV_OBJ_FLAG_HIDDEN);
    }

    if(code == LV_EVENT_DEFOCUSED) {
        lv_keyboard_set_textarea(kb, NULL);
        lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
    }
}

void lv_example_keyboard_1(void)
{
    /*Create a keyboard to use it with an of the text areas*/
    lv_obj_t * kb = lv_keyboard_create(lv_screen_active());

    /*Create a text area. The keyboard will write here*/
    lv_obj_t * ta;
    ta = lv_textarea_create(lv_screen_active());
    lv_obj_align(ta, LV_ALIGN_TOP_LEFT, 10, 10);
    lv_obj_add_event(ta, ta_event_cb, LV_EVENT_ALL, kb);
    lv_textarea_set_placeholder_text(ta, "Hello");
    lv_obj_set_size(ta, 140, 80);

    ta = lv_textarea_create(lv_screen_active());
    lv_obj_align(ta, LV_ALIGN_TOP_RIGHT, -10, 10);
    lv_obj_add_event(ta, ta_event_cb, LV_EVENT_ALL, kb);
    lv_obj_set_size(ta, 140, 80);

    lv_keyboard_set_textarea(kb, ta);
}
#endif
def ta_event_cb(e,kb):
    code = e.get_code()
    ta = e.get_target_obj()
    if code == lv.EVENT.FOCUSED:
        kb.set_textarea(ta)
        kb.remove_flag(lv.obj.FLAG.HIDDEN)

    if code == lv.EVENT.DEFOCUSED:
        kb.set_textarea(None)
        kb.add_flag(lv.obj.FLAG.HIDDEN)

# Create a keyboard to use it with one of the text areas
kb = lv.keyboard(lv.screen_active())

# Create a text area. The keyboard will write here
ta = lv.textarea(lv.screen_active())
ta.set_width(200)
ta.align(lv.ALIGN.TOP_LEFT, 10, 10)
ta.add_event(lambda e: ta_event_cb(e,kb), lv.EVENT.ALL, None)
ta.set_placeholder_text("Hello")

ta = lv.textarea(lv.screen_active())
ta.set_width(200)
ta.align(lv.ALIGN.TOP_RIGHT, -10, 10)
ta.add_event(lambda e: ta_event_cb(e,kb), lv.EVENT.ALL, None)

kb.set_textarea(ta)


Keyboard with custom map

#include "../../lv_examples.h"
#if LV_USE_KEYBOARD && LV_BUILD_EXAMPLES

void lv_example_keyboard_2(void)
{
    /*Create an AZERTY keyboard map*/
    static const char * kb_map[] = {"A", "Z", "E", "R", "T", "Y", "U", "I", "O", "P", LV_SYMBOL_BACKSPACE, "\n",
                                    "Q", "S", "D", "F", "G", "J", "K", "L", "M",  LV_SYMBOL_NEW_LINE, "\n",
                                    "W", "X", "C", "V", "B", "N", ",", ".", ":", "!", "?", "\n",
                                    LV_SYMBOL_CLOSE, " ",  " ", " ", LV_SYMBOL_OK, NULL
                                   };

    /*Set the relative width of the buttons and other controls*/
    static const lv_buttonmatrix_ctrl_t kb_ctrl[] = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
                                                     4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
                                                     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
                                                     2, LV_BUTTONMATRIX_CTRL_HIDDEN | 2, 6, LV_BUTTONMATRIX_CTRL_HIDDEN | 2, 2
                                                    };

    /*Create a keyboard and add the new map as USER_1 mode*/
    lv_obj_t * kb = lv_keyboard_create(lv_screen_active());

    lv_keyboard_set_map(kb, LV_KEYBOARD_MODE_USER_1, kb_map, kb_ctrl);
    lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_USER_1);

    /*Create a text area. The keyboard will write here*/
    lv_obj_t * ta;
    ta = lv_textarea_create(lv_screen_active());
    lv_obj_align(ta, LV_ALIGN_TOP_MID, 0, 10);
    lv_obj_set_size(ta, lv_pct(90), 80);
    lv_obj_add_state(ta, LV_STATE_FOCUSED);

    lv_keyboard_set_textarea(kb, ta);
}
#endif
# Create an AZERTY keyboard map
kb_map = ["A", "Z", "E", "R", "T", "Y", "U", "I", "O", "P", lv.SYMBOL.BACKSPACE, "\n",
          "Q", "S", "D", "F", "G", "J", "K", "L", "M",  lv.SYMBOL.NEW_LINE, "\n",
          "W", "X", "C", "V", "B", "N", ",", ".", ":", "!", "?", "\n",
          lv.SYMBOL.CLOSE, " ",  " ", " ", lv.SYMBOL.OK, None]

# Set the relative width of the buttons and other controls
kb_ctrl = [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
           4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
           4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
           2, lv.buttonmatrix.CTRL.HIDDEN | 2, 6, lv.buttonmatrix.CTRL.HIDDEN | 2, 2]

# Create a keyboard and add the new map as USER_1 mode
kb = lv.keyboard(lv.screen_active())

kb.set_map(lv.keyboard.MODE.USER_1, kb_map, kb_ctrl)
kb.set_mode(lv.keyboard.MODE.USER_1)

# Create a text area. The keyboard will write here
ta = lv.textarea(lv.screen_active())
ta.align(lv.ALIGN.TOP_MID, 0, 10)
ta.set_size(lv.pct(90), 80)
ta.add_state(lv.STATE.FOCUSED)

kb.set_textarea(ta)


API

lv_keyboard.h