# Button Matrix (lv_buttonmatrix) (/widgets/buttonmatrix)



Overview [#overview]

The Button Matrix Widget is a lightweight way to display multiple
Buttons in rows and columns --- lightweight because the buttons are not
actually created but just virtually drawn on the fly.  With Button Matrix,
each button uses only eight extra bytes of memory instead of the \~100-150
bytes a normal [Button](/widgets/button) Widget plus the 100 or so bytes
for the [Label](/widgets/label) Widget.

New Button Matrix Widgets are added to the default group (if one is set).
Additionally, Button Matrix is an editable Widget:  it allows selecting and clicking
the buttons with encoder and keyboard navigation as well.

Parts and Styles [#parts-and-styles]

* <ApiLink name="LV_PART_MAIN" /> The background of the Button Matrix, uses the
  typical background style properties. `pad_row` and `pad_column`
  sets the space between the buttons.
* <ApiLink name="LV_PART_ITEMS" /> The buttons all use the text and typical background
  style properties except translations and transformations.

Usage [#usage]

Button map [#button-map]

The number of buttons, their positions and text are controlled by a descriptor string
array, called a *map*, passed to
<ApiLink name="lv_buttonmatrix_set_map" display="lv_buttonmatrix_set_map(btn_matrix, my_map)" />. The declaration of a map should
look like `const char * map[] = {"button1", "button2", "button3", NULL}`. Note
that the last element must be either `NULL` or an empty string
(`""`)!

Use `"\n"` in the map to insert a **line break**. E.g.
`{"button1", "button2", "\n", "button3", ""}`. Each line's buttons have their
width calculated automatically. So in the example the first row will
have 2 buttons each with 50% width and a second row with 1 button having
100% width.

<Callout type="info">
  The number of buttons neither includes the newline elements nor the terminating
  element of the array.
</Callout>

Button widths [#button-widths]

The buttons' width can be set in proportion to the width of other buttons in the same
row with <ApiLink name="lv_buttonmatrix_set_button_width" display="lv_buttonmatrix_set_button_width(btn_matrix, button_id, width)" /> E.g. in a
line with two buttons: *buttonA, width = 1* and *buttonB, width = 2*, *buttonA*
will have 33 % width and *buttonB* will have 66 % width.  This is similar to how the
["flex-grow"](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/flex-grow)
property works in CSS. The width must be in the range \[1..15] with the default being 1.

Button behavior [#button-behavior]

Each button's behavior can be customized with the following control flags:

* <ApiLink name="LV_BUTTONMATRIX_CTRL_HIDDEN" />: Hides button; it continues to hold its space in layout.
* <ApiLink name="LV_BUTTONMATRIX_CTRL_NO_REPEAT" />: Do not emit <ApiLink name="LV_EVENT_LONG_PRESSED_REPEAT" /> events while button is long-pressed.
* <ApiLink name="LV_BUTTONMATRIX_CTRL_DISABLED" />: Disables button like <ApiLink name="LV_STATE_DISABLED" /> on normal Widgets.
* <ApiLink name="LV_BUTTONMATRIX_CTRL_CHECKABLE" />: Enable toggling of <ApiLink name="LV_STATE_CHECKED" /> when clicked.
* <ApiLink name="LV_BUTTONMATRIX_CTRL_CHECKED" />: Make the button checked. It will use the <ApiLink name="LV_STATE_CHECKED" /> styles.
* <ApiLink name="LV_BUTTONMATRIX_CTRL_CLICK_TRIG" />: 1: Enables sending <ApiLink name="LV_EVENT_VALUE_CHANGED" /> on `CLICK`, 0: sends <ApiLink name="LV_EVENT_VALUE_CHANGED" /> on `PRESS`.
* <ApiLink name="LV_BUTTONMATRIX_CTRL_POPOVER" />: Show button text in a pop-over while being pressed.
* <ApiLink name="LV_BUTTONMATRIX_CTRL_RECOLOR" />: Enable text recoloring with `#color`
* <ApiLink name="LV_BUTTONMATRIX_CTRL_CUSTOM_1" />: Custom free-to-use flag
* <ApiLink name="LV_BUTTONMATRIX_CTRL_CUSTOM_2" />: Custom free-to-use flag

By default, these flags are disabled.

To set and clear a button's control flags, use

* <ApiLink name="lv_buttonmatrix_set_button_ctrl" display="lv_buttonmatrix_set_button_ctrl(btn_matrix, button_id, LV_BUTTONMATRIX_CTRL_...)" /> and
* <ApiLink name="lv_buttonmatrix_clear_button_ctrl" display="lv_buttonmatrix_clear_button_ctrl(btn_matrix, button_id, LV_BUTTONMATRIX_CTRL_...)" />

respectively.  `button_id` is a zero-based button index (0 = first button).
`LV_BUTTONMATRIX_CTRL_...` values can be bit-wise OR-ed together when passed to
these functions.

To set and clear the same control attribute for all buttons in a Button Matrix, use

* <ApiLink name="lv_buttonmatrix_set_button_ctrl_all" display="lv_buttonmatrix_set_button_ctrl_all(btn_matrix, LV_BUTTONMATRIX_CTRL_...)" /> and
* <ApiLink name="lv_buttonmatrix_clear_button_ctrl_all" display="lv_buttonmatrix_clear_button_ctrl_all(btn_matrix, LV_BUTTONMATRIX_CTRL_...)" />

respectively.

To set a control map for a Button Matrix (similar to Button map), use

* <ApiLink name="lv_buttonmatrix_set_ctrl_map" display="lv_buttonmatrix_set_ctrl_map(btn_matrix, ctrl_map)" />.

An element of `ctrl_map` should look like
<ApiLink name="ctrl_map" display="ctrl_map[0] = width | LV_BUTTONMATRIX_CTRL_NO_REPEAT |  LV_BUTTONMATRIX_CTRL_CHECKABLE" />.
The number of elements must be equal to the number of buttons.

One checked [#one-checked]

The "One-checked" feature can be enabled with
<ApiLink name="lv_buttonmatrix_set_one_checked" display="lv_buttonmatrix_set_one_checked(btn_matrix, true)" /> to allow only one button to
be checked at a time.

Events [#events]

* <ApiLink name="LV_EVENT_VALUE_CHANGED" />: Sent when a button is pressed/released or
  repeated after long press. The event parameter is set to the ID of
  the pressed/released button.

<ApiLink name="lv_buttonmatrix_get_selected_button" display="lv_buttonmatrix_get_selected_button(btn_matrix)" /> returns the index of the button
most recently released (the button with focus) or <ApiLink name="LV_BUTTONMATRIX_BUTTON_NONE" />
if no such button was found.

<ApiLink name="lv_buttonmatrix_get_button_text" display="lv_buttonmatrix_get_button_text(btn_matrix, button_id)" /> returns a pointer
to the text of the button specified by zero-based index `button_id`.

<Callout type="info" title="Further Reading">
  Learn more about [Events](/common-widget-features/events) emitted by all Widgets.

  Learn more about [events](/common-widget-features/events).
</Callout>

Keys [#keys]

* `LV_KEY_RIGHT/UP/LEFT/RIGHT` To navigate among the buttons to
  select one
* <ApiLink name="LV_KEY_ENTER" /> To press/release the selected button

Note that long pressing the Button Matrix with an encoder can mean to
enter/leave edit mode and simply long pressing a button to make it
repeat as well. To avoid this contradiction, add

<ApiLink name="lv_buttonmatrix_set_button_ctrl_all" display="lv_buttonmatrix_set_button_ctrl_all(btn_matrix, LV_BUTTONMATRIX_CTRL_CLICK_TRIG | LV_BUTTONMATRIX_CTRL_NO_REPEAT)" />

to the Button Matrix if used with an encoder.  This disables the repeat feature so
the button will not be activated upon leaving edit mode.

<Callout type="info" title="Further Reading">
  Learn more about [Keys](/main-modules/indev/keypad).
</Callout>

Examples [#examples]

Simple Button matrix [#simple-button-matrix]

<LvglExample name="lv_example_buttonmatrix_1" path="widgets/buttonmatrix/lv_example_buttonmatrix_1" />

Custom buttons [#custom-buttons]

<LvglExample name="lv_example_buttonmatrix_2" path="widgets/buttonmatrix/lv_example_buttonmatrix_2" />

Pagination [#pagination]

<LvglExample name="lv_example_buttonmatrix_3" path="widgets/buttonmatrix/lv_example_buttonmatrix_3" />

API [#api]
