1 /**
2 * @file lv_msgbox.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9 #include "lv_msgbox.h"
10 #if LV_USE_MSGBOX
11
12 #include "../../../misc/lv_assert.h"
13
14 /*********************
15 * DEFINES
16 *********************/
17 #define LV_MSGBOX_FLAG_AUTO_PARENT LV_OBJ_FLAG_WIDGET_1 /*Mark that the parent was automatically created*/
18 #define MY_CLASS &lv_msgbox_class
19
20 /**********************
21 * TYPEDEFS
22 **********************/
23
24 /**********************
25 * STATIC PROTOTYPES
26 **********************/
27 static void msgbox_close_click_event_cb(lv_event_t * e);
28
29 /**********************
30 * STATIC VARIABLES
31 **********************/
32 const lv_obj_class_t lv_msgbox_class = {
33 .base_class = &lv_obj_class,
34 .width_def = LV_DPI_DEF * 2,
35 .height_def = LV_SIZE_CONTENT,
36 .instance_size = sizeof(lv_msgbox_t)
37 };
38
39 const lv_obj_class_t lv_msgbox_content_class = {
40 .base_class = &lv_obj_class,
41 .width_def = LV_PCT(100),
42 .height_def = LV_SIZE_CONTENT,
43 .instance_size = sizeof(lv_obj_t)
44 };
45
46 const lv_obj_class_t lv_msgbox_backdrop_class = {
47 .base_class = &lv_obj_class,
48 .width_def = LV_PCT(100),
49 .height_def = LV_PCT(100),
50 .instance_size = sizeof(lv_obj_t)
51 };
52
53 /**********************
54 * MACROS
55 **********************/
56
57 /**********************
58 * GLOBAL FUNCTIONS
59 **********************/
60
lv_msgbox_create(lv_obj_t * parent,const char * title,const char * txt,const char * btn_txts[],bool add_close_btn)61 lv_obj_t * lv_msgbox_create(lv_obj_t * parent, const char * title, const char * txt, const char * btn_txts[],
62 bool add_close_btn)
63 {
64 LV_LOG_INFO("begin");
65 bool auto_parent = false;
66 if(parent == NULL) {
67 auto_parent = true;
68 parent = lv_obj_class_create_obj(&lv_msgbox_backdrop_class, lv_layer_top());
69 LV_ASSERT_MALLOC(parent);
70 lv_obj_class_init_obj(parent);
71 lv_obj_clear_flag(parent, LV_OBJ_FLAG_IGNORE_LAYOUT);
72 lv_obj_set_size(parent, LV_PCT(100), LV_PCT(100));
73 }
74
75 lv_obj_t * obj = lv_obj_class_create_obj(&lv_msgbox_class, parent);
76 LV_ASSERT_MALLOC(obj);
77 if(obj == NULL) return NULL;
78 lv_obj_class_init_obj(obj);
79 lv_msgbox_t * mbox = (lv_msgbox_t *)obj;
80
81 if(auto_parent) lv_obj_add_flag(obj, LV_MSGBOX_FLAG_AUTO_PARENT);
82
83 lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_ROW_WRAP);
84
85 bool has_title = title && strlen(title) > 0;
86
87 /*When a close button is required, we need the empty label as spacer to push the button to the right*/
88 if(add_close_btn || has_title) {
89 mbox->title = lv_label_create(obj);
90 lv_label_set_text(mbox->title, has_title ? title : "");
91 lv_label_set_long_mode(mbox->title, LV_LABEL_LONG_SCROLL_CIRCULAR);
92 if(add_close_btn) lv_obj_set_flex_grow(mbox->title, 1);
93 else lv_obj_set_width(mbox->title, LV_PCT(100));
94 }
95
96 if(add_close_btn) {
97 mbox->close_btn = lv_btn_create(obj);
98 lv_obj_set_ext_click_area(mbox->close_btn, LV_DPX(10));
99 lv_obj_add_event_cb(mbox->close_btn, msgbox_close_click_event_cb, LV_EVENT_CLICKED, NULL);
100 lv_obj_t * label = lv_label_create(mbox->close_btn);
101 lv_label_set_text(label, LV_SYMBOL_CLOSE);
102 const lv_font_t * font = lv_obj_get_style_text_font(mbox->close_btn, LV_PART_MAIN);
103 lv_coord_t close_btn_size = lv_font_get_line_height(font) + LV_DPX(10);
104 lv_obj_set_size(mbox->close_btn, close_btn_size, close_btn_size);
105 lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
106 }
107
108 mbox->content = lv_obj_class_create_obj(&lv_msgbox_content_class, obj);
109 LV_ASSERT_MALLOC(mbox->content);
110 if(mbox->content == NULL) return NULL;
111 lv_obj_class_init_obj(mbox->content);
112
113 bool has_txt = txt && strlen(txt) > 0;
114 if(has_txt) {
115 mbox->text = lv_label_create(mbox->content);
116 lv_label_set_text(mbox->text, txt);
117 lv_label_set_long_mode(mbox->text, LV_LABEL_LONG_WRAP);
118 lv_obj_set_width(mbox->text, lv_pct(100));
119 }
120
121 if(btn_txts) {
122 mbox->btns = lv_btnmatrix_create(obj);
123 lv_btnmatrix_set_map(mbox->btns, btn_txts);
124 lv_btnmatrix_set_btn_ctrl_all(mbox->btns, LV_BTNMATRIX_CTRL_CLICK_TRIG | LV_BTNMATRIX_CTRL_NO_REPEAT);
125
126 uint32_t btn_cnt = 0;
127 while(btn_txts[btn_cnt] && btn_txts[btn_cnt][0] != '\0') {
128 btn_cnt++;
129 }
130
131 const lv_font_t * font = lv_obj_get_style_text_font(mbox->btns, LV_PART_ITEMS);
132 lv_coord_t btn_h = lv_font_get_line_height(font) + LV_DPI_DEF / 10;
133 lv_obj_set_size(mbox->btns, btn_cnt * (2 * LV_DPI_DEF / 3), btn_h);
134 lv_obj_set_style_max_width(mbox->btns, lv_pct(100), 0);
135 lv_obj_add_flag(mbox->btns, LV_OBJ_FLAG_EVENT_BUBBLE); /*To see the event directly on the message box*/
136 }
137
138 return obj;
139 }
140
lv_msgbox_get_title(lv_obj_t * obj)141 lv_obj_t * lv_msgbox_get_title(lv_obj_t * obj)
142 {
143 LV_ASSERT_OBJ(obj, MY_CLASS);
144 lv_msgbox_t * mbox = (lv_msgbox_t *)obj;
145 return mbox->title;
146 }
147
lv_msgbox_get_close_btn(lv_obj_t * obj)148 lv_obj_t * lv_msgbox_get_close_btn(lv_obj_t * obj)
149 {
150 LV_ASSERT_OBJ(obj, MY_CLASS);
151 lv_msgbox_t * mbox = (lv_msgbox_t *)obj;
152 return mbox->close_btn;
153 }
154
lv_msgbox_get_text(lv_obj_t * obj)155 lv_obj_t * lv_msgbox_get_text(lv_obj_t * obj)
156 {
157 LV_ASSERT_OBJ(obj, MY_CLASS);
158 lv_msgbox_t * mbox = (lv_msgbox_t *)obj;
159 return mbox->text;
160 }
161
lv_msgbox_get_content(lv_obj_t * obj)162 lv_obj_t * lv_msgbox_get_content(lv_obj_t * obj)
163 {
164 LV_ASSERT_OBJ(obj, MY_CLASS);
165 lv_msgbox_t * mbox = (lv_msgbox_t *)obj;
166 return mbox->content;
167 }
168
lv_msgbox_get_btns(lv_obj_t * obj)169 lv_obj_t * lv_msgbox_get_btns(lv_obj_t * obj)
170 {
171 LV_ASSERT_OBJ(obj, MY_CLASS);
172 lv_msgbox_t * mbox = (lv_msgbox_t *)obj;
173 return mbox->btns;
174 }
175
lv_msgbox_get_active_btn(lv_obj_t * mbox)176 uint16_t lv_msgbox_get_active_btn(lv_obj_t * mbox)
177 {
178 lv_obj_t * btnm = lv_msgbox_get_btns(mbox);
179 return lv_btnmatrix_get_selected_btn(btnm);
180 }
181
lv_msgbox_get_active_btn_text(lv_obj_t * mbox)182 const char * lv_msgbox_get_active_btn_text(lv_obj_t * mbox)
183 {
184 lv_obj_t * btnm = lv_msgbox_get_btns(mbox);
185 return lv_btnmatrix_get_btn_text(btnm, lv_btnmatrix_get_selected_btn(btnm));
186 }
187
lv_msgbox_close(lv_obj_t * mbox)188 void lv_msgbox_close(lv_obj_t * mbox)
189 {
190 if(lv_obj_has_flag(mbox, LV_MSGBOX_FLAG_AUTO_PARENT)) lv_obj_del(lv_obj_get_parent(mbox));
191 else lv_obj_del(mbox);
192 }
193
lv_msgbox_close_async(lv_obj_t * dialog)194 void lv_msgbox_close_async(lv_obj_t * dialog)
195 {
196 if(lv_obj_has_flag(dialog, LV_MSGBOX_FLAG_AUTO_PARENT)) lv_obj_del_async(lv_obj_get_parent(dialog));
197 else lv_obj_del_async(dialog);
198 }
199
200 /**********************
201 * STATIC FUNCTIONS
202 **********************/
203
msgbox_close_click_event_cb(lv_event_t * e)204 static void msgbox_close_click_event_cb(lv_event_t * e)
205 {
206 lv_obj_t * btn = lv_event_get_target(e);
207 lv_obj_t * mbox = lv_obj_get_parent(btn);
208 lv_msgbox_close(mbox);
209 }
210
211 #endif /*LV_USE_MSGBOX*/
212