Button matrix (lv_btnm)

Overview

The Button Matrix objects can display multiple buttons in rows and columns.

The main reasons for wanting to use a button matrix instead of a container and individual button objects are:

  • The button matrix is simpler to use for grid-based button layouts.

  • The button matrix consumes a lot less memory per button.

Button’s text

There is a text on each button. To specify them a descriptor string array, called map, needs to be used. The map can be set with lv_btnm_set_map(btnm, my_map). The declaration of a map should look like const char * map[] = {"btn1", "btn2", "btn3", ""}. Note that the last element has to be an empty string!

Use "\n" in the map to make line break. E.g. {"btn1", "btn2", "\n", "btn3", ""}. Each line’s buttons have their width calculated automatically.

Control buttons

The buttons width can be set relative to the other button in the same line with lv_btnm_set_btn_width(btnm, btn_id, width) E.g. in a line with two buttons: btnA, width = 1 and btnB, width = 2, btnA will have 33 % width and btnB will have 66 % width. It’s similar to how the flex-grow property works in CSS.

In addition to width, each button can be customized with the following parameters:

  • LV_BTNM_CTRL_HIDDEN - make a button hidden (hidden buttons still take up space in the layout, they are just not visible or clickable)

  • LV_BTNM_CTRL_NO_REPEAT - disable repeating when the button is long pressed

  • LV_BTNM_CTRL_INACTIVE - make a button inactive

  • LV_BTNM_CTRL_TGL_ENABLE - enable toggling of a button

  • LV_BTNM_CTRL_TGL_STATE - set the toggle state

  • LV_BTNM_CTRL_CLICK_TRIG - if 0, the button will react on press, if 1, will react on release

The set or clear a button’s control attribute, use lv_btnm_set_btn_ctrl(btnm, btn_id, LV_BTNM_CTRL_...) and lv_btnm_clear_btn_ctrl(btnm, btn_id, LV_BTNM_CTRL_...) respectively. More LV_BTNM_CTRL_... values can be Ored

The set/clear the same control attribute for all buttons of a button matrix, use lv_btnm_set_btn_ctrl_all(btnm, btn_id, LV_BTNM_CTRL_...) and lv_btnm_clear_btn_ctrl_all(btnm, btn_id, LV_BTNM_CTRL_...).

The set a control map for a button matrix (similarly to the map for the text), use lv_btnm_set_ctrl_map(btnm, ctrl_map). An element of ctrl_map should look like ctrl_map[0] = width | LV_BTNM_CTRL_NO_REPEAT |  LV_BTNM_CTRL_TGL_ENABLE. The number of elements should be equal to the number of buttons (excluding newlines characters).

One toggle

The “One toggle” feature can be enabled with lv_btnm_set_one_toggle(btnm, true) to allow only one button to be toggled at once.

Recolor

The texts on the button can be recolored similarly to the recolor feature for Label object. To enable it, use lv_btnm_set_recolor(btnm, true). After that a button with #FF0000 Red# text will be red.

Notes

The Button matrix object is very light weighted because the buttons are not created just virtually drawn on the fly. This way, 1 button use only 8 extra bytes instead of the ~100-150 byte size of a normal Button object (plus the size of its container and a label for each button).

The disadvantage of this setup is that the ability to style individual buttons to be different from others is limited (aside from the toggling feature). If you require that ability, using individual buttons is very likely to be a better approach.

Styles

The Button matrix works with 6 styles: a background and 5 button styles for each state. You can set the styles with lv_btnm_set_style(btn, LV_BTNM_STYLE_..., &style). The background and the buttons use the style.body properties. The labels use the style.text properties of the button styles.

  • LV_BTNM_STYLE_BG - Background style. Uses all style.body properties including padding Default: lv_style_pretty

  • LV_BTNM_STYLE_BTN_REL - style of the released buttons. Default: lv_style_btn_rel

  • LV_BTNM_STYLE_BTN_PR - style of the pressed buttons. Default: lv_style_btn_pr

  • LV_BTNM_STYLE_BTN_TGL_REL - style of the toggled released buttons. Default: lv_style_btn_tgl_rel

  • LV_BTNM_STYLE_BTN_TGL_PR - style of the toggled pressed buttons. Default: lv_style_btn_tgl_pr

  • LV_BTNM_STYLE_BTN_INA - style of the inactive buttons. Default: lv_style_btn_ina

Events

Besides the Generic events, the following Special events are sent by the button matrices:

  • LV_EVENT_VALUE_CHANGED - sent when the button is pressed/released or repeated after long press. The event data is set to the ID of the pressed/released button.

Learn more about Events.

Keys

The following Keys are processed by the Buttons:

  • LV_KEY_RIGHT/UP/LEFT/RIGHT - To navigate among the buttons to select one

  • LV_KEY_ENTER - To press/release the selected button

Learn more about Keys.

Example

C

Simple Button matrix

Simple Button matrix example in LittlevGL

code

#include "lvgl/lvgl.h"
#include <stdio.h>

static void event_handler(lv_obj_t * obj, lv_event_t event)
{
    if(event == LV_EVENT_VALUE_CHANGED) {
        const char * txt = lv_btnm_get_active_btn_text(obj);

        printf("%s was pressed\n", txt);
    }
}


static const char * btnm_map[] = {"1", "2", "3", "4", "5", "\n",
                                  "6", "7", "8", "9", "0", "\n",
                                  "Action1", "Action2", ""};

void lv_ex_btnm_1(void)
{
    lv_obj_t * btnm1 = lv_btnm_create(lv_scr_act(), NULL);
    lv_btnm_set_map(btnm1, btnm_map);
    lv_btnm_set_btn_width(btnm1, 10, 2);        /*Make "Action1" twice as wide as "Action2"*/
    lv_obj_align(btnm1, NULL, LV_ALIGN_CENTER, 0, 0);
    lv_obj_set_event_cb(btnm1, event_handler);
}

MicroPython

Simple Button matrix

Simple Button matrix example in LittlevGL with MicroPython

code

def event_handler(obj, event):
    if event == lv.EVENT.VALUE_CHANGED:
        txt = obj.get_active_btn_text()
        print("%s was pressed" % txt)

btnm_map = ["1", "2", "3", "4", "5", "\n",
            "6", "7", "8", "9", "0", "\n",
            "Action1", "Action2", ""]

btnm1 = lv.btnm(lv.scr_act())
btnm1.set_map(btnm_map)
btnm1.set_btn_width(10, 2)        # Make "Action1" twice as wide as "Action2"
btnm1.align(None, lv.ALIGN.CENTER, 0, 0)
btnm1.set_event_cb(event_handler)

API

Typedefs

typedef uint16_t lv_btnm_ctrl_t
typedef uint8_t lv_btnm_style_t

Enums

enum [anonymous]

Type to store button control bits (disabled, hidden etc.)

Values:

enumerator LV_BTNM_CTRL_HIDDEN = 0x0008

Button hidden

enumerator LV_BTNM_CTRL_NO_REPEAT = 0x0010

Do not repeat press this button.

enumerator LV_BTNM_CTRL_INACTIVE = 0x0020

Disable this button.

enumerator LV_BTNM_CTRL_TGL_ENABLE = 0x0040

Button can be toggled.

enumerator LV_BTNM_CTRL_TGL_STATE = 0x0080

Button is currently toggled (e.g. checked).

enumerator LV_BTNM_CTRL_CLICK_TRIG = 0x0100

1: Send LV_EVENT_SELECTED on CLICK, 0: Send LV_EVENT_SELECTED on PRESS

enum [anonymous]

Values:

enumerator LV_BTNM_STYLE_BG
enumerator LV_BTNM_STYLE_BTN_REL
enumerator LV_BTNM_STYLE_BTN_PR
enumerator LV_BTNM_STYLE_BTN_TGL_REL
enumerator LV_BTNM_STYLE_BTN_TGL_PR
enumerator LV_BTNM_STYLE_BTN_INA

Functions

LV_EXPORT_CONST_INT(LV_BTNM_BTN_NONE)
lv_obj_t *lv_btnm_create(lv_obj_t *par, const lv_obj_t *copy)

Create a button matrix objects

Return

pointer to the created button matrix

Parameters
  • par: pointer to an object, it will be the parent of the new button matrix

  • copy: pointer to a button matrix object, if not NULL then the new object will be copied from it

void lv_btnm_set_map(const lv_obj_t *btnm, const char *map[])

Set a new map. Buttons will be created/deleted according to the map. The button matrix keeps a reference to the map and so the string array must not be deallocated during the life of the matrix.

Parameters
  • btnm: pointer to a button matrix object

  • map: pointer a string array. The last string has to be: “”. Use “\n” to make a line break.

void lv_btnm_set_ctrl_map(const lv_obj_t *btnm, const lv_btnm_ctrl_t ctrl_map[])

Set the button control map (hidden, disabled etc.) for a button matrix. The control map array will be copied and so may be deallocated after this function returns.

Parameters
  • btnm: pointer to a button matrix object

  • ctrl_map: pointer to an array of lv_btn_ctrl_t control bytes. The length of the array and position of the elements must match the number and order of the individual buttons (i.e. excludes newline entries). An element of the map should look like e.g.: ctrl_map[0] = width | LV_BTNM_CTRL_NO_REPEAT | LV_BTNM_CTRL_TGL_ENABLE

void lv_btnm_set_pressed(const lv_obj_t *btnm, uint16_t id)

Set the pressed button i.e. visually highlight it. Mainly used a when the btnm is in a group to show the selected button

Parameters
  • btnm: pointer to button matrix object

  • id: index of the currently pressed button (LV_BTNM_BTN_NONE to unpress)

void lv_btnm_set_style(lv_obj_t *btnm, lv_btnm_style_t type, const lv_style_t *style)

Set a style of a button matrix

Parameters
  • btnm: pointer to a button matrix object

  • type: which style should be set

  • style: pointer to a style

void lv_btnm_set_recolor(const lv_obj_t *btnm, bool en)

Enable recoloring of button’s texts

Parameters
  • btnm: pointer to button matrix object

  • en: true: enable recoloring; false: disable

void lv_btnm_set_btn_ctrl(const lv_obj_t *btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl)

Set the attributes of a button of the button matrix

Parameters
  • btnm: pointer to button matrix object

  • btn_id: 0 based index of the button to modify. (Not counting new lines)

void lv_btnm_clear_btn_ctrl(const lv_obj_t *btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl)

Clear the attributes of a button of the button matrix

Parameters
  • btnm: pointer to button matrix object

  • btn_id: 0 based index of the button to modify. (Not counting new lines)

void lv_btnm_set_btn_ctrl_all(lv_obj_t *btnm, lv_btnm_ctrl_t ctrl)

Set the attributes of all buttons of a button matrix

Parameters
  • btnm: pointer to a button matrix object

  • ctrl: attribute(s) to set from lv_btnm_ctrl_t. Values can be ORed.

void lv_btnm_clear_btn_ctrl_all(lv_obj_t *btnm, lv_btnm_ctrl_t ctrl)

Clear the attributes of all buttons of a button matrix

Parameters
  • btnm: pointer to a button matrix object

  • ctrl: attribute(s) to set from lv_btnm_ctrl_t. Values can be ORed.

  • en: true: set the attributes; false: clear the attributes

void lv_btnm_set_btn_width(const lv_obj_t *btnm, uint16_t btn_id, uint8_t width)

Set a single buttons relative width. This method will cause the matrix be regenerated and is a relatively expensive operation. It is recommended that initial width be specified using lv_btnm_set_ctrl_map and this method only be used for dynamic changes.

Parameters
  • btnm: pointer to button matrix object

  • btn_id: 0 based index of the button to modify.

  • width: Relative width compared to the buttons in the same row. [1..7]

void lv_btnm_set_one_toggle(lv_obj_t *btnm, bool one_toggle)

Make the button matrix like a selector widget (only one button may be toggled at a time).

Toggling must be enabled on the buttons you want to be selected with lv_btnm_set_ctrl or lv_btnm_set_btn_ctrl_all.

Parameters
  • btnm: Button matrix object

  • one_toggle: Whether “one toggle” mode is enabled

const char **lv_btnm_get_map_array(const lv_obj_t *btnm)

Get the current map of a button matrix

Return

the current map

Parameters
  • btnm: pointer to a button matrix object

bool lv_btnm_get_recolor(const lv_obj_t *btnm)

Check whether the button’s text can use recolor or not

Return

true: text recolor enable; false: disabled

Parameters
  • btnm: pointer to button matrix object

uint16_t lv_btnm_get_active_btn(const lv_obj_t *btnm)

Get the index of the lastly “activated” button by the user (pressed, released etc) Useful in the the event_cb to get the text of the button, check if hidden etc.

Return

index of the last released button (LV_BTNM_BTN_NONE: if unset)

Parameters
  • btnm: pointer to button matrix object

const char *lv_btnm_get_active_btn_text(const lv_obj_t *btnm)

Get the text of the lastly “activated” button by the user (pressed, released etc) Useful in the the event_cb

Return

text of the last released button (NULL: if unset)

Parameters
  • btnm: pointer to button matrix object

uint16_t lv_btnm_get_pressed_btn(const lv_obj_t *btnm)

Get the pressed button’s index. The button be really pressed by the user or manually set to pressed with lv_btnm_set_pressed

Return

index of the pressed button (LV_BTNM_BTN_NONE: if unset)

Parameters
  • btnm: pointer to button matrix object

const char *lv_btnm_get_btn_text(const lv_obj_t *btnm, uint16_t btn_id)

Get the button’s text

Return

text of btn_index` button

Parameters
  • btnm: pointer to button matrix object

  • btn_id: the index a button not counting new line characters. (The return value of lv_btnm_get_pressed/released)

bool lv_btnm_get_btn_ctrl(lv_obj_t *btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl)

Get the whether a control value is enabled or disabled for button of a button matrix

Return

true: long press repeat is disabled; false: long press repeat enabled

Parameters
  • btnm: pointer to a button matrix object

  • btn_id: the index a button not counting new line characters. (E.g. the return value of lv_btnm_get_pressed/released)

  • ctrl: control values to check (ORed value can be used)

const lv_style_t *lv_btnm_get_style(const lv_obj_t *btnm, lv_btnm_style_t type)

Get a style of a button matrix

Return

style pointer to a style

Parameters
  • btnm: pointer to a button matrix object

  • type: which style should be get

bool lv_btnm_get_one_toggle(const lv_obj_t *btnm)

Find whether “one toggle” mode is enabled.

Return

whether “one toggle” mode is enabled

Parameters
  • btnm: Button matrix object

struct lv_btnm_ext_t

Public Members

const char **map_p
lv_area_t *button_areas
lv_btnm_ctrl_t *ctrl_bits
const lv_style_t *styles_btn[_LV_BTN_STATE_NUM]
uint16_t btn_cnt
uint16_t btn_id_pr
uint16_t btn_id_act
uint8_t recolor
uint8_t one_toggle