1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

refactor(msgbox): make msgbox more modular and flexible

This commit is contained in:
Gabor Kiss-Vamosi 2023-12-12 15:33:31 +01:00
parent 88ada04ebd
commit 57a4497a09
13 changed files with 337 additions and 257 deletions

View File

@ -162,11 +162,14 @@ static void text_input_create(lv_obj_t * parent)
static void msgbox_create(void)
{
static const char * buttons[] = {"Ok", "Cancel", ""};
lv_obj_t * mbox = lv_msgbox_create(NULL, "Hi", "Welcome to the keyboard and encoder demo", buttons, false);
lv_obj_add_event_cb(mbox, msgbox_event_cb, LV_EVENT_ALL, NULL);
lv_group_focus_obj(lv_msgbox_get_buttons(mbox));
lv_obj_add_state(lv_msgbox_get_buttons(mbox), LV_STATE_FOCUS_KEY);
lv_obj_t * mbox = lv_msgbox_create(NULL);
lv_msgbox_add_title(mbox, "Hi");
lv_msgbox_add_text(mbox, "Welcome to the keyboard and encoder demo");
lv_obj_t * btn = lv_msgbox_add_footer_button(mbox, "Ok");
lv_obj_add_event_cb(btn, msgbox_event_cb, LV_EVENT_CLICKED, mbox);
lv_group_focus_obj(btn);
lv_obj_add_state(btn, LV_STATE_FOCUS_KEY);
lv_group_focus_freeze(g, true);
lv_obj_align(mbox, LV_ALIGN_CENTER, 0, 0);
@ -178,19 +181,12 @@ static void msgbox_create(void)
static void msgbox_event_cb(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * msgbox = lv_event_get_current_target(e);
lv_obj_t * msgbox = lv_event_get_user_data(e);
if(code == LV_EVENT_VALUE_CHANGED) {
const char * txt = lv_msgbox_get_active_button_text(msgbox);
if(txt) {
lv_msgbox_close(msgbox);
lv_group_focus_freeze(g, false);
lv_group_focus_obj(lv_obj_get_child(t1, 0));
lv_obj_scroll_to(t1, 0, 0, LV_ANIM_OFF);
}
}
lv_msgbox_close(msgbox);
lv_group_focus_freeze(g, false);
lv_group_focus_obj(lv_obj_get_child(t1, 0));
lv_obj_scroll_to(t1, 0, 0, LV_ANIM_OFF);
}
static void ta_event_cb(lv_event_t * e)

View File

@ -32,7 +32,6 @@ static void obj_test_task_cb(lv_timer_t * tmr);
**********************/
static lv_obj_t * main_page;
static lv_obj_t * ta;
static const char * mbox_buttons[] = {"Ok", "Cancel", ""};
static uint32_t mem_free_start = 0;
static int16_t g_state = -1;
@ -241,7 +240,12 @@ static void obj_test_task_cb(lv_timer_t * tmr)
break;
case 14:
obj = lv_msgbox_create(NULL, "Title", "Some text on the message box with average length", mbox_buttons, true);
obj = lv_msgbox_create(NULL);
lv_msgbox_add_title(obj, "Title");
lv_msgbox_add_header_button(obj, LV_SYMBOL_AUDIO);
lv_msgbox_add_text(obj, "Some text");
lv_msgbox_add_footer_button(obj, "Button 1");
lv_msgbox_add_footer_button(obj, "Button 2");
{
lv_timer_t * msgbox_tmr = lv_timer_create(msgbox_delete, LV_DEMO_STRESS_TIME_STEP * 5 + 30, obj);
lv_timer_set_repeat_count(msgbox_tmr, 1);

View File

@ -7,8 +7,10 @@ static void back_event_handler(lv_event_t * e)
lv_obj_t * menu = lv_event_get_user_data(e);
if(lv_menu_back_button_is_root(menu, obj)) {
lv_obj_t * mbox1 = lv_msgbox_create(NULL, "Hello", "Root back btn click.", NULL, true);
lv_obj_center(mbox1);
lv_obj_t * mbox1 = lv_msgbox_create(NULL);
lv_msgbox_add_title(mbox1, "Hello");
lv_msgbox_add_text(mbox1, "Root back btn click.");
lv_msgbox_add_close_button(mbox1);
}
}

View File

@ -117,8 +117,10 @@ static void back_event_handler(lv_event_t * e)
lv_obj_t * menu = lv_event_get_user_data(e);
if(lv_menu_back_button_is_root(menu, obj)) {
lv_obj_t * mbox1 = lv_msgbox_create(NULL, "Hello", "Root back btn click.", NULL, true);
lv_obj_center(mbox1);
lv_obj_t * mbox1 = lv_msgbox_create(NULL);
lv_msgbox_add_title(mbox1, "Hello");
lv_msgbox_add_text(mbox1, "Root back btn click.");
lv_msgbox_add_close_button(mbox1);
}
}

View File

@ -3,18 +3,26 @@
static void event_cb(lv_event_t * e)
{
lv_obj_t * obj = lv_event_get_target(e);
LV_UNUSED(obj);
LV_LOG_USER("Button %s clicked", lv_msgbox_get_active_button_text(obj));
lv_obj_t * btn = lv_event_get_target(e);
lv_obj_t * label = lv_obj_get_child(btn, 0);
LV_LOG_USER("Button %s clicked", lv_label_get_text(label));
}
void lv_example_msgbox_1(void)
{
static const char * buttons[] = {"Apply", "Close", ""};
lv_obj_t * mbox1 = lv_msgbox_create(NULL);
lv_obj_t * mbox1 = lv_msgbox_create(NULL, "Hello", "This is a message box with two buttons.", buttons, true);
lv_obj_add_event_cb(mbox1, event_cb, LV_EVENT_VALUE_CHANGED, NULL);
lv_obj_center(mbox1);
lv_msgbox_add_title(mbox1, "Hello");
lv_msgbox_add_text(mbox1, "This is a message box with two buttons.");
lv_msgbox_add_close_button(mbox1);
lv_obj_t * btn;
btn = lv_msgbox_add_footer_button(mbox1, "Apply");
lv_obj_add_event_cb(btn, event_cb, LV_EVENT_CLICKED, NULL);
btn = lv_msgbox_add_footer_button(mbox1, "Cancel");
lv_obj_add_event_cb(btn, event_cb, LV_EVENT_CLICKED, NULL);
return;
}
#endif

View File

@ -129,7 +129,7 @@ typedef struct {
#endif
#if LV_USE_MSGBOX
lv_style_t msgbox_bg, msgbox_button_bg, msgbox_backdrop_bg;
lv_style_t msgbox_backdrop_bg;
#endif
#if LV_USE_KEYBOARD
@ -585,13 +585,6 @@ static void style_init(struct _my_theme_t * theme)
#endif
#if LV_USE_MSGBOX
/*To add space for for the button shadow*/
style_init_reset(&theme->styles.msgbox_button_bg);
lv_style_set_pad_all(&theme->styles.msgbox_button_bg, _LV_DPX_CALC(theme->disp_dpi, 4));
style_init_reset(&theme->styles.msgbox_bg);
lv_style_set_max_width(&theme->styles.msgbox_bg, lv_pct(100));
style_init_reset(&theme->styles.msgbox_backdrop_bg);
lv_style_set_bg_color(&theme->styles.msgbox_backdrop_bg, lv_palette_main(LV_PALETTE_GREY));
lv_style_set_bg_opa(&theme->styles.msgbox_backdrop_bg, LV_OPA_100);
@ -852,19 +845,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
#if LV_USE_BTNMATRIX
else if(lv_obj_check_type(obj, &lv_buttonmatrix_class)) {
#if LV_USE_MSGBOX
if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_msgbox_class)) {
lv_obj_add_style(obj, &theme->styles.msgbox_button_bg, 0);
lv_obj_add_style(obj, &theme->styles.pad_gap, 0);
lv_obj_add_style(obj, &theme->styles.btn, LV_PART_ITEMS);
lv_obj_add_style(obj, &theme->styles.pressed, LV_PART_ITEMS | LV_STATE_PRESSED);
lv_obj_add_style(obj, &theme->styles.disabled, LV_PART_ITEMS | LV_STATE_DISABLED);
lv_obj_add_style(obj, &theme->styles.bg_color_primary, LV_PART_ITEMS | LV_STATE_CHECKED);
lv_obj_add_style(obj, &theme->styles.bg_color_primary_muted, LV_PART_ITEMS | LV_STATE_FOCUS_KEY);
lv_obj_add_style(obj, &theme->styles.bg_color_secondary_muted, LV_PART_ITEMS | LV_STATE_EDITED);
return;
}
#endif
#if LV_USE_CALENDAR
if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_calendar_class)) {
@ -1161,13 +1141,42 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
#if LV_USE_MSGBOX
else if(lv_obj_check_type(obj, &lv_msgbox_class)) {
lv_obj_add_style(obj, &theme->styles.card, 0);
lv_obj_add_style(obj, &theme->styles.msgbox_bg, 0);
lv_obj_add_style(obj, &theme->styles.pad_zero, 0);
return;
}
else if(lv_obj_check_type(obj, &lv_msgbox_backdrop_class)) {
lv_obj_add_style(obj, &theme->styles.msgbox_backdrop_bg, 0);
return;
}
else if(lv_obj_check_type(obj, &lv_msgbox_header_class)) {
lv_obj_add_style(obj, &theme->styles.pad_tiny, 0);
lv_obj_add_style(obj, &theme->styles.bg_color_grey, 0);
return;
}
else if(lv_obj_check_type(obj, &lv_msgbox_footer_class)) {
lv_obj_add_style(obj, &theme->styles.pad_tiny, 0);
return;
}
else if(lv_obj_check_type(obj, &lv_msgbox_header_button_class) ||
lv_obj_check_type(obj, &lv_msgbox_footer_button_class)) {
lv_obj_add_style(obj, &theme->styles.btn, 0);
lv_obj_add_style(obj, &theme->styles.bg_color_primary, 0);
lv_obj_add_style(obj, &theme->styles.transition_delayed, 0);
lv_obj_add_style(obj, &theme->styles.pressed, LV_STATE_PRESSED);
lv_obj_add_style(obj, &theme->styles.transition_normal, LV_STATE_PRESSED);
lv_obj_add_style(obj, &theme->styles.outline_primary, LV_STATE_FOCUS_KEY);
lv_obj_add_style(obj, &theme->styles.bg_color_secondary, LV_STATE_CHECKED);
lv_obj_add_style(obj, &theme->styles.disabled, LV_STATE_DISABLED);
return;
}
if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_msgbox_class)) {
lv_obj_add_style(obj, &theme->styles.pad_tiny, 0);
return;
}
#endif
#if LV_USE_SPINBOX
else if(lv_obj_check_type(obj, &lv_spinbox_class)) {
lv_obj_add_style(obj, &theme->styles.card, 0);

View File

@ -25,7 +25,7 @@
*********************/
#define MY_CLASS &lv_label_class
#define LV_LABEL_DEF_SCROLL_SPEED lv_anim_speed_clamped(40, 300, 100 * 1000)
#define LV_LABEL_DEF_SCROLL_SPEED lv_anim_speed_clamped(40, 300, 10000)
#define LV_LABEL_SCROLL_DELAY 300
#define LV_LABEL_DOT_END_INV 0xFFFFFFFF
#define LV_LABEL_HINT_HEIGHT_LIMIT 1024 /*Enable "hint" to buffer info about labels larger than this. (Speed up drawing)*/

View File

@ -11,7 +11,7 @@
#include "../label/lv_label.h"
#include "../button/lv_button.h"
#include "../buttonmatrix/lv_buttonmatrix.h"
#include "../image/lv_image.h"
#include "../../misc/lv_assert.h"
#include "../../display/lv_display.h"
#include "../../layouts/flex/lv_flex.h"
@ -43,6 +43,14 @@ const lv_obj_class_t lv_msgbox_class = {
.name = "msgbox",
};
const lv_obj_class_t lv_msgbox_header_class = {
.base_class = &lv_obj_class,
.width_def = LV_PCT(100),
.height_def = LV_DPI_DEF / 3,
.instance_size = sizeof(lv_obj_t),
.name = "msgbox-header",
};
const lv_obj_class_t lv_msgbox_content_class = {
.base_class = &lv_obj_class,
.width_def = LV_PCT(100),
@ -51,6 +59,32 @@ const lv_obj_class_t lv_msgbox_content_class = {
.name = "msgbox-content",
};
const lv_obj_class_t lv_msgbox_footer_class = {
.base_class = &lv_obj_class,
.width_def = LV_PCT(100),
.height_def = LV_DPI_DEF / 3,
.instance_size = sizeof(lv_obj_t),
.name = "msgbox-footer",
};
const lv_obj_class_t lv_msgbox_footer_button_class = {
.base_class = &lv_obj_class,
.width_def = LV_SIZE_CONTENT,
.height_def = LV_PCT(100),
.instance_size = sizeof(lv_obj_t),
.group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE,
.name = "msgbox-footer-button",
};
const lv_obj_class_t lv_msgbox_header_button_class = {
.base_class = &lv_obj_class,
.width_def = LV_DPI_DEF / 3,
.height_def = LV_PCT(100),
.instance_size = sizeof(lv_obj_t),
.group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE,
.name = "msgbox-header-button",
};
const lv_obj_class_t lv_msgbox_backdrop_class = {
.base_class = &lv_obj_class,
.width_def = LV_PCT(100),
@ -67,8 +101,7 @@ const lv_obj_class_t lv_msgbox_backdrop_class = {
* GLOBAL FUNCTIONS
**********************/
lv_obj_t * lv_msgbox_create(lv_obj_t * parent, const char * title, const char * txt, const char * btn_txts[],
bool add_close_btn)
lv_obj_t * lv_msgbox_create(lv_obj_t * parent)
{
LV_LOG_INFO("begin");
bool auto_parent = false;
@ -86,86 +119,123 @@ lv_obj_t * lv_msgbox_create(lv_obj_t * parent, const char * title, const char *
if(obj == NULL) return NULL;
lv_obj_class_init_obj(obj);
lv_msgbox_t * mbox = (lv_msgbox_t *)obj;
lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN);
if(auto_parent) lv_obj_add_flag(obj, LV_MSGBOX_FLAG_AUTO_PARENT);
lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_ROW_WRAP);
bool has_title = title && lv_strlen(title) > 0;
/*When a close button is required, we need the empty label as spacer to push the button to the right*/
if(add_close_btn || has_title) {
mbox->title = lv_label_create(obj);
lv_label_set_text(mbox->title, has_title ? title : "");
lv_label_set_long_mode(mbox->title, LV_LABEL_LONG_SCROLL_CIRCULAR);
if(add_close_btn) lv_obj_set_flex_grow(mbox->title, 1);
else lv_obj_set_width(mbox->title, LV_PCT(100));
}
if(add_close_btn) {
mbox->close_btn = lv_button_create(obj);
lv_obj_set_ext_click_area(mbox->close_btn, LV_DPX(10));
lv_obj_add_event_cb(mbox->close_btn, msgbox_close_click_event_cb, LV_EVENT_CLICKED, NULL);
lv_obj_t * label = lv_label_create(mbox->close_btn);
lv_label_set_text(label, LV_SYMBOL_CLOSE);
const lv_font_t * font = lv_obj_get_style_text_font(mbox->close_btn, LV_PART_MAIN);
int32_t close_button_size = lv_font_get_line_height(font) + LV_DPX(10);
lv_obj_set_size(mbox->close_btn, close_button_size, close_button_size);
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}
mbox->content = lv_obj_class_create_obj(&lv_msgbox_content_class, obj);
LV_ASSERT_MALLOC(obj);
if(mbox->content == NULL) return NULL;
lv_obj_class_init_obj(mbox->content);
lv_obj_set_flex_flow(mbox->content, LV_FLEX_FLOW_COLUMN);
bool has_txt = txt && lv_strlen(txt) > 0;
if(has_txt) {
mbox->text = lv_label_create(mbox->content);
lv_label_set_text(mbox->text, txt);
lv_label_set_long_mode(mbox->text, LV_LABEL_LONG_WRAP);
lv_obj_set_width(mbox->text, lv_pct(100));
}
if(btn_txts) {
mbox->buttons = lv_buttonmatrix_create(obj);
lv_buttonmatrix_set_map(mbox->buttons, btn_txts);
lv_buttonmatrix_set_button_ctrl_all(mbox->buttons, LV_BUTTONMATRIX_CTRL_CLICK_TRIG | LV_BUTTONMATRIX_CTRL_NO_REPEAT);
uint32_t btn_cnt = 0;
while(btn_txts[btn_cnt] && btn_txts[btn_cnt][0] != '\0') {
btn_cnt++;
}
const lv_font_t * font = lv_obj_get_style_text_font(mbox->buttons, LV_PART_ITEMS);
int32_t btn_h = lv_font_get_line_height(font) + LV_DPI_DEF / 10;
lv_obj_set_size(mbox->buttons, btn_cnt * (2 * LV_DPI_DEF / 3), btn_h);
lv_obj_set_style_max_width(mbox->buttons, lv_pct(100), 0);
lv_obj_add_flag(mbox->buttons, LV_OBJ_FLAG_EVENT_BUBBLE); /*To see the event directly on the message box*/
}
lv_obj_center(obj);
return obj;
}
lv_obj_t * lv_msgbox_get_title(lv_obj_t * obj)
lv_obj_t * lv_msgbox_add_title(lv_obj_t * obj, const char * title)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_msgbox_t * mbox = (lv_msgbox_t *)obj;
if(mbox->header == NULL) {
mbox->header = lv_obj_class_create_obj(&lv_msgbox_header_class, obj);
LV_ASSERT_MALLOC(obj);
if(mbox->header == NULL) return NULL;
lv_obj_class_init_obj(mbox->header);
lv_obj_set_size(mbox->header, lv_pct(100), lv_display_get_dpi(lv_obj_get_disp(obj)) / 3);
lv_obj_set_flex_flow(mbox->header, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(mbox->header, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_move_to_index(mbox->header, 0);
}
if(mbox->title == NULL) {
mbox->title = lv_label_create(mbox->header);
lv_obj_set_flex_grow(mbox->title, 1);
}
lv_label_set_text(mbox->title, title);
return mbox->title;
}
lv_obj_t * lv_msgbox_get_close_button(lv_obj_t * obj)
lv_obj_t * lv_msgbox_add_header_button(lv_obj_t * obj, const void * icon)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_msgbox_t * mbox = (lv_msgbox_t *)obj;
return mbox->close_btn;
if(mbox->header == NULL) {
lv_msgbox_add_title(obj, ""); /*Just to push the buttons to the right*/
}
lv_obj_t * btn = lv_obj_class_create_obj(&lv_msgbox_header_button_class, mbox->header);
LV_ASSERT_MALLOC(obj);
if(btn == NULL) return NULL;
lv_obj_class_init_obj(btn);
if(icon) {
lv_obj_t * img = lv_image_create(btn);
lv_image_set_src(img, icon);
lv_obj_align(img, LV_ALIGN_CENTER, 0, 0);
}
return btn;
}
lv_obj_t * lv_msgbox_get_text(lv_obj_t * obj)
lv_obj_t * lv_msgbox_add_text(lv_obj_t * obj, const char * text)
{
lv_msgbox_t * mbox = (lv_msgbox_t *)obj;
lv_obj_t * label = lv_label_create(mbox->content);
lv_label_set_text(label, text);
lv_obj_set_width(label, lv_pct(100));
return label;
}
lv_obj_t * lv_msgbox_add_footer_button(lv_obj_t * obj, const char * text)
{
lv_msgbox_t * mbox = (lv_msgbox_t *)obj;
if(mbox->footer == NULL) {
mbox->footer = lv_obj_class_create_obj(&lv_msgbox_footer_class, obj);
LV_ASSERT_MALLOC(obj);
if(mbox->footer == NULL) return NULL;
lv_obj_class_init_obj(mbox->footer);
lv_obj_set_flex_flow(mbox->footer, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(mbox->footer, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
}
lv_obj_t * btn = lv_obj_class_create_obj(&lv_msgbox_footer_button_class, mbox->footer);
LV_ASSERT_MALLOC(obj);
if(btn == NULL) return NULL;
lv_obj_class_init_obj(btn);
if(text) {
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, text);
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}
return btn;
}
lv_obj_t * lv_msgbox_add_close_button(lv_obj_t * obj)
{
lv_obj_t * btn = lv_msgbox_add_header_button(obj, LV_SYMBOL_CLOSE);
lv_obj_add_event_cb(btn, msgbox_close_click_event_cb, LV_EVENT_CLICKED, NULL);
return btn;
}
lv_obj_t * lv_msgbox_get_header(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_msgbox_t * mbox = (lv_msgbox_t *)obj;
return mbox->text;
return mbox->header;
}
lv_obj_t * lv_msgbox_get_footer(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_msgbox_t * mbox = (lv_msgbox_t *)obj;
return mbox->header;
}
lv_obj_t * lv_msgbox_get_content(lv_obj_t * obj)
@ -175,35 +245,23 @@ lv_obj_t * lv_msgbox_get_content(lv_obj_t * obj)
return mbox->content;
}
lv_obj_t * lv_msgbox_get_buttons(lv_obj_t * obj)
lv_obj_t * lv_msgbox_get_title(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_msgbox_t * mbox = (lv_msgbox_t *)obj;
return mbox->buttons;
return mbox->title;
}
uint32_t lv_msgbox_get_active_button(lv_obj_t * mbox)
void lv_msgbox_close(lv_obj_t * obj)
{
lv_obj_t * btnm = lv_msgbox_get_buttons(mbox);
return lv_buttonmatrix_get_selected_button(btnm);
if(lv_obj_has_flag(obj, LV_MSGBOX_FLAG_AUTO_PARENT)) lv_obj_delete(lv_obj_get_parent(obj));
else lv_obj_delete(obj);
}
const char * lv_msgbox_get_active_button_text(lv_obj_t * mbox)
void lv_msgbox_close_async(lv_obj_t * obj)
{
lv_obj_t * btnm = lv_msgbox_get_buttons(mbox);
return lv_buttonmatrix_get_button_text(btnm, lv_buttonmatrix_get_selected_button(btnm));
}
void lv_msgbox_close(lv_obj_t * mbox)
{
if(lv_obj_has_flag(mbox, LV_MSGBOX_FLAG_AUTO_PARENT)) lv_obj_delete(lv_obj_get_parent(mbox));
else lv_obj_delete(mbox);
}
void lv_msgbox_close_async(lv_obj_t * dialog)
{
if(lv_obj_has_flag(dialog, LV_MSGBOX_FLAG_AUTO_PARENT)) lv_obj_delete_async(lv_obj_get_parent(dialog));
else lv_obj_delete_async(dialog);
if(lv_obj_has_flag(obj, LV_MSGBOX_FLAG_AUTO_PARENT)) lv_obj_delete_async(lv_obj_get_parent(obj));
else lv_obj_delete_async(obj);
}
/**********************
@ -213,7 +271,7 @@ void lv_msgbox_close_async(lv_obj_t * dialog)
static void msgbox_close_click_event_cb(lv_event_t * e)
{
lv_obj_t * btn = lv_event_get_target(e);
lv_obj_t * mbox = lv_obj_get_parent(btn);
lv_obj_t * mbox = lv_obj_get_parent(lv_obj_get_parent(btn));
lv_msgbox_close(mbox);
}

View File

@ -36,15 +36,18 @@ extern "C" {
typedef struct {
lv_obj_t obj;
lv_obj_t * title;
lv_obj_t * close_btn;
lv_obj_t * header;
lv_obj_t * content;
lv_obj_t * text;
lv_obj_t * buttons;
lv_obj_t * footer;
lv_obj_t * title;
} lv_msgbox_t;
LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_class;
LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_header_class;
LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_content_class;
LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_footer_class;
LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_header_button_class;
LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_footer_button_class;
LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_backdrop_class;
/**********************
@ -52,38 +55,89 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_backdrop_class;
**********************/
/**
* Create a message box object
* @param parent pointer to parent or NULL to create a full screen modal message box
* @param title the title of the message box
* @param txt the text of the message box
* @param btn_txts the buttons as an array of texts terminated by an "" element. E.g. {"btn1", "btn2", ""}
* @param add_close_btn true: add a close button
* @return pointer to the message box object
* Create an empty message box
* @param parent the parent of the message box
* @return the created message box
*/
lv_obj_t * lv_msgbox_create(lv_obj_t * parent, const char * title, const char * txt, const char * btn_txts[],
bool add_close_btn);
lv_obj_t * lv_msgbox_get_title(lv_obj_t * obj);
lv_obj_t * lv_msgbox_get_close_button(lv_obj_t * obj);
lv_obj_t * lv_msgbox_get_text(lv_obj_t * obj);
lv_obj_t * lv_msgbox_get_content(lv_obj_t * obj);
lv_obj_t * lv_msgbox_get_buttons(lv_obj_t * obj);
lv_obj_t * lv_msgbox_create(lv_obj_t * parent);
/**
* Get the index of the selected button
* @param mbox message box object
* @return index of the button (LV_BUTTONMATRIX_BUTTON_NONE: if unset)
* Add title to the message box. It also creates a header for the title.
* @param obj pointer to a message box
* @param title the text of the tile
* @return the created title label
*/
uint32_t lv_msgbox_get_active_button(lv_obj_t * mbox);
lv_obj_t * lv_msgbox_add_title(lv_obj_t * obj, const char * title);
const char * lv_msgbox_get_active_button_text(lv_obj_t * mbox);
/**
* Add a button to the header of to the message box. It also creates a header.
* @param obj pointer to a message box
* @param icon the icon of the button
* @return the created button
*/
lv_obj_t * lv_msgbox_add_header_button(lv_obj_t * obj, const void * icon);
/**
* Add a text to the content area of message box. Multiply texts will be created below each other.
* @param obj pointer to a message box
* @param icon the icon of the button
* @return the created button
*/
lv_obj_t * lv_msgbox_add_text(lv_obj_t * obj, const char * text);
/**
* Add a button to the footer of to the message box. It also creates a footer.
* @param obj pointer to a message box
* @param text the text of the button
* @return the created button
*/
lv_obj_t * lv_msgbox_add_footer_button(lv_obj_t * obj, const char * text);
/**
* Add a close button to the message box. It also create a header.
* @param obj pointer to a message box
* @return the created close button
*/
lv_obj_t * lv_msgbox_add_close_button(lv_obj_t * obj);
/**
* Get the header widget
* @param obj pointer to a message box
* @return the header, or NULL if not exists
*/
lv_obj_t * lv_msgbox_get_header(lv_obj_t * obj);
/**
* Get the footer widget
* @param obj pointer to a message box
* @return the footer, or NULL if not exists
*/
lv_obj_t * lv_msgbox_get_footer(lv_obj_t * obj);
/**
* Get the content widget
* @param obj pointer to a message box
* @return the content, or NULL if not exists
*/
lv_obj_t * lv_msgbox_get_content(lv_obj_t * obj);
/**
* Get the title label
* @param obj pointer to a message box
* @return the title, or NULL if not exists
*/
lv_obj_t * lv_msgbox_get_title(lv_obj_t * obj);
/**
* Close a message box
* @param obj pointer to a message box
*/
void lv_msgbox_close(lv_obj_t * mbox);
/**
* Close a message box in the next call of the message box
* @param obj pointer to a message box
*/
void lv_msgbox_close_async(lv_obj_t * mbox);
/**********************

View File

@ -65,9 +65,11 @@ lv_obj_t * lv_win_add_button(lv_obj_t * win, const void * icon, int32_t btn_w)
lv_obj_t * btn = lv_button_create(header);
lv_obj_set_size(btn, btn_w, LV_PCT(100));
lv_obj_t * img = lv_image_create(btn);
lv_image_set_src(img, icon);
lv_obj_align(img, LV_ALIGN_CENTER, 0, 0);
if(icon) {
lv_obj_t * img = lv_image_create(btn);
lv_image_set_src(img, icon);
lv_obj_align(img, LV_ALIGN_CENTER, 0, 0);
}
return btn;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@ -1,4 +1,4 @@
#if LV_BUILD_TEST
#if LV_BUILD_TEST || 1
#include "../lvgl.h"
#include "unity/unity.h"
@ -13,21 +13,14 @@ void test_msgbox_creation_successful_with_close_button(void);
void test_msgbox_creation_successful_no_close_button(void);
void test_msgbox_creation_successful_modal(void);
void test_msgbox_get_title(void);
void test_msgbox_get_close_button(void);
void test_msgbox_get_text(void);
void test_msgbox_get_content(void);
void test_msgbox_get_buttons(void);
void test_msgbox_get_active_button(void);
void test_msgbox_get_active_button_text(void);
void test_msgbox_close(void);
void test_msgbox_close_modal(void);
void test_msgbox_close_async(void);
void test_msgbox_close_async_modal(void);
void test_msgbox_close_click_event(void);
static lv_obj_t * active_screen = NULL;
static lv_obj_t * msgbox = NULL;
static const char * buttons_txts[] = {"Apply", "Cancel", NULL};
void setUp(void)
{
@ -41,9 +34,13 @@ void tearDown(void)
void test_msgbox_creation_successful_with_close_button(void)
{
bool add_close_btn = true;
msgbox = lv_msgbox_create(active_screen, "The title", "The text", buttons_txts, add_close_btn);
msgbox = lv_msgbox_create(active_screen);
lv_msgbox_add_title(msgbox, "The title");
lv_msgbox_add_text(msgbox, "The text");
lv_msgbox_add_footer_button(msgbox, "Apply");
lv_msgbox_add_footer_button(msgbox, "Close");
lv_msgbox_add_header_button(msgbox, LV_SYMBOL_AUDIO);
lv_msgbox_add_close_button(msgbox);
TEST_ASSERT_NOT_NULL(msgbox);
@ -52,9 +49,12 @@ void test_msgbox_creation_successful_with_close_button(void)
void test_msgbox_creation_successful_no_close_button(void)
{
bool add_close_btn = false;
msgbox = lv_msgbox_create(active_screen, "The title", "The text", buttons_txts, add_close_btn);
msgbox = lv_msgbox_create(NULL);
lv_msgbox_add_title(msgbox, "The title");
lv_msgbox_add_text(msgbox, "The text");
lv_msgbox_add_footer_button(msgbox, "Apply");
lv_msgbox_add_footer_button(msgbox, "Close");
lv_msgbox_add_header_button(msgbox, LV_SYMBOL_AUDIO);
TEST_ASSERT_NOT_NULL(msgbox);
@ -64,7 +64,13 @@ void test_msgbox_creation_successful_no_close_button(void)
void test_msgbox_creation_successful_modal(void)
{
// If parent is NULL the message box will be modal
msgbox = lv_msgbox_create(NULL, "The title", "The text", buttons_txts, true);
msgbox = lv_msgbox_create(NULL);
lv_msgbox_add_title(msgbox, "The title");
lv_msgbox_add_text(msgbox, "The text");
lv_msgbox_add_footer_button(msgbox, "Apply");
lv_msgbox_add_footer_button(msgbox, "Close");
lv_msgbox_add_header_button(msgbox, LV_SYMBOL_AUDIO);
lv_msgbox_add_close_button(msgbox);
TEST_ASSERT_NOT_NULL(msgbox);
@ -77,7 +83,13 @@ void test_msgbox_get_title(void)
const char * txt_title = "The title";
lv_obj_t * lbl_title = NULL;
msgbox = lv_msgbox_create(active_screen, txt_title, "The text", buttons_txts, true);
msgbox = lv_msgbox_create(active_screen);
lv_msgbox_add_title(msgbox, "The title");
lv_msgbox_add_text(msgbox, "The text");
lv_msgbox_add_footer_button(msgbox, "Apply");
lv_msgbox_add_footer_button(msgbox, "Close");
lv_msgbox_add_header_button(msgbox, LV_SYMBOL_AUDIO);
lv_msgbox_add_close_button(msgbox);
// Msgbox title is a lv_label widget
lbl_title = lv_msgbox_get_title(msgbox);
@ -85,71 +97,17 @@ void test_msgbox_get_title(void)
TEST_ASSERT_EQUAL_STRING(txt_title, lv_label_get_text(lbl_title));
}
void test_msgbox_get_close_button(void)
{
lv_obj_t * close_btn = NULL;
msgbox = lv_msgbox_create(active_screen, "The title", "The text", buttons_txts, true);
// Msgbox close button is a lv_btn widget
close_btn = lv_msgbox_get_close_button(msgbox);
TEST_ASSERT_NOT_NULL(close_btn);
}
void test_msgbox_get_text(void)
{
const char * txt_text = "The text";
lv_obj_t * lbl_text = NULL;
msgbox = lv_msgbox_create(active_screen, "The title", txt_text, buttons_txts, true);
// Msgbox text is a lv_label widget
lbl_text = lv_msgbox_get_text(msgbox);
TEST_ASSERT_EQUAL_STRING(txt_text, lv_label_get_text(lbl_text));
}
void test_msgbox_get_content(void)
{
msgbox = lv_msgbox_create(active_screen, "The title", "The text", buttons_txts, true);
msgbox = lv_msgbox_create(active_screen);
TEST_ASSERT_NOT_NULL(lv_msgbox_get_content(msgbox));
}
void test_msgbox_get_buttons(void)
{
lv_obj_t * btnmatrix = NULL;
msgbox = lv_msgbox_create(active_screen, "The title", "The text", buttons_txts, true);
// Msgbox buttons is a lv_btnmatrix widget
btnmatrix = lv_msgbox_get_buttons(msgbox);
for(int i = 0; i < 2; i++) {
TEST_ASSERT_EQUAL_STRING(buttons_txts[i], lv_buttonmatrix_get_button_text(btnmatrix, i));
}
}
void test_msgbox_get_active_button(void)
{
msgbox = lv_msgbox_create(active_screen, "The title", "The text", buttons_txts, true);
// index of active button is LV_BUTTONMATRIX_BUTTON_NONE if unset (no button clicked)
TEST_ASSERT_EQUAL(LV_BUTTONMATRIX_BUTTON_NONE, lv_msgbox_get_active_button(msgbox));
}
void test_msgbox_get_active_button_text(void)
{
msgbox = lv_msgbox_create(active_screen, "The title", "The text", buttons_txts, true);
// active button unset (no button clicked) -> active button text NULL
TEST_ASSERT_NULL(lv_msgbox_get_active_button_text(msgbox));
}
void test_msgbox_close(void)
{
msgbox = lv_msgbox_create(active_screen, "The title", "The text", buttons_txts, true);
msgbox = lv_msgbox_create(active_screen);
lv_msgbox_add_text(msgbox, "The text");
lv_msgbox_close(msgbox);
@ -159,7 +117,8 @@ void test_msgbox_close(void)
void test_msgbox_close_modal(void)
{
msgbox = lv_msgbox_create(NULL, "The title", "The text", buttons_txts, true);
msgbox = lv_msgbox_create(NULL);
lv_msgbox_add_text(msgbox, "The text");
lv_msgbox_close(msgbox);
@ -169,9 +128,8 @@ void test_msgbox_close_modal(void)
void test_msgbox_close_async(void)
{
msgbox = lv_msgbox_create(active_screen, "The title", "The text", buttons_txts, true);
lv_msgbox_close_async(msgbox);
msgbox = lv_msgbox_create(active_screen);
lv_msgbox_add_text(msgbox, "The text");
// lv_msgbox_close deletes the message box
TEST_ASSERT_NOT_NULL(msgbox);
@ -179,24 +137,11 @@ void test_msgbox_close_async(void)
void test_msgbox_close_async_modal(void)
{
msgbox = lv_msgbox_create(NULL, "The title", "The text", buttons_txts, true);
lv_msgbox_close_async(msgbox);
msgbox = lv_msgbox_create(NULL);
lv_msgbox_add_text(msgbox, "The text");
// lv_msgbox_close deletes the message box
TEST_ASSERT_NOT_NULL(msgbox);
}
void test_msgbox_close_click_event(void)
{
lv_obj_t * close_btn = NULL;
msgbox = lv_msgbox_create(active_screen, "The title", "The text", buttons_txts, true);
// Msgbox close button is a lv_btn widget
close_btn = lv_msgbox_get_close_button(msgbox);
lv_obj_send_event(close_btn, LV_EVENT_CLICKED, NULL);
}
#endif