feat(color): Add support for information bubble popups (#3903)
* Add information bubble popup window. * Use fixed BLACK and WHITE colors.
This commit is contained in:
@@ -111,3 +111,39 @@ void POPUP_WARNING_ON_UI_TASK(const char * message, const char * info, bool wait
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BubbleDialog : public Window
|
||||
{
|
||||
public:
|
||||
BubbleDialog(const char* message, int timeout) :
|
||||
Window(MainWindow::instance(), rect_t{50, LCD_H - 100, LCD_W - 100, 50}, OPAQUE, 0, etx_bubble_popup_create)
|
||||
{
|
||||
lv_obj_set_parent(lvobj, lv_layer_top());
|
||||
|
||||
auto label = lv_label_create(lvobj);
|
||||
lv_label_set_text(label, message);
|
||||
lv_obj_center(label);
|
||||
lv_obj_set_width(label, lv_pct(100));
|
||||
lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0);
|
||||
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
|
||||
|
||||
endTime = RTOS_GET_MS() + timeout;
|
||||
}
|
||||
|
||||
bool isBubblePopup() override { return true; }
|
||||
|
||||
void checkEvents() override
|
||||
{
|
||||
if (RTOS_GET_MS() >= endTime) {
|
||||
deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
uint32_t endTime;
|
||||
};
|
||||
|
||||
void POPUP_BUBBLE(const char* message, uint32_t timeout)
|
||||
{
|
||||
new BubbleDialog(message, timeout);
|
||||
}
|
||||
|
||||
@@ -28,5 +28,6 @@ typedef std::function<void(const char *, const char *, int, int)> ProgressHandle
|
||||
void POPUP_INFORMATION(const char * message);
|
||||
void POPUP_WARNING(const char * message, const char * info = nullptr);
|
||||
void POPUP_WARNING_ON_UI_TASK(const char * message, const char * info = nullptr, bool waitForClose = true);
|
||||
void POPUP_BUBBLE(const char * message, uint32_t timeout);
|
||||
|
||||
void show_ui_popup();
|
||||
|
||||
@@ -107,6 +107,8 @@ typedef struct {
|
||||
lv_style_t cb_marker;
|
||||
lv_style_t cb_marker_checked;
|
||||
|
||||
// Bubble popup
|
||||
lv_style_t bubble_popup;
|
||||
} my_theme_styles_t;
|
||||
|
||||
/**********************
|
||||
@@ -327,6 +329,14 @@ static void style_init(void)
|
||||
lv_style_init(&styles.cb_marker_checked);
|
||||
lv_style_set_bg_img_src(&styles.cb_marker_checked, LV_SYMBOL_OK);
|
||||
lv_style_set_text_font(&styles.cb_marker_checked, theme.font_small);
|
||||
|
||||
// Bubble popup
|
||||
lv_style_init(&styles.bubble_popup);
|
||||
lv_style_set_bg_opa(&styles.bubble_popup, LV_OPA_COVER);
|
||||
lv_style_set_pad_all(&styles.bubble_popup, 4);
|
||||
lv_style_set_border_opa(&styles.bubble_popup, LV_OPA_COVER);
|
||||
lv_style_set_border_width(&styles.bubble_popup, 3);
|
||||
lv_style_set_radius(&styles.bubble_popup, 10);
|
||||
}
|
||||
|
||||
// Always update colors in case theme changes
|
||||
@@ -395,6 +405,10 @@ static void style_init(void)
|
||||
lv_style_set_border_color(&styles.cb_marker_checked, makeLvColor(COLOR_THEME_SECONDARY1));
|
||||
lv_style_set_bg_color(&styles.cb_marker_checked, makeLvColor(COLOR_THEME_SECONDARY1));
|
||||
lv_style_set_text_color(&styles.cb_marker_checked, makeLvColor(COLOR_THEME_PRIMARY2));
|
||||
|
||||
lv_style_set_bg_color(&styles.bubble_popup, makeLvColor(COLOR2FLAGS(WHITE)));
|
||||
lv_style_set_border_color(&styles.bubble_popup, makeLvColor(COLOR2FLAGS(BLACK)));
|
||||
lv_style_set_text_color(&styles.bubble_popup, makeLvColor(COLOR2FLAGS(BLACK)));
|
||||
}
|
||||
|
||||
/**********************
|
||||
@@ -598,6 +612,11 @@ void etx_checkbox_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
lv_obj_add_style(obj, &styles.disabled, LV_PART_INDICATOR | LV_STATE_DISABLED);
|
||||
}
|
||||
|
||||
void bubble_popup_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
{
|
||||
lv_obj_add_style(obj, &styles.bubble_popup, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Object classes
|
||||
@@ -796,6 +815,19 @@ const lv_obj_class_t etx_checkbox_class = {
|
||||
.instance_size = sizeof(lv_checkbox_t),
|
||||
};
|
||||
|
||||
const lv_obj_class_t etx_bubble_popup_class = {
|
||||
.base_class = &window_base_class,
|
||||
.constructor_cb = bubble_popup_constructor,
|
||||
.destructor_cb = nullptr,
|
||||
.user_data = nullptr,
|
||||
.event_cb = nullptr,
|
||||
.width_def = LV_DPI_DEF,
|
||||
.height_def = LV_DPI_DEF,
|
||||
.editable = LV_OBJ_CLASS_EDITABLE_FALSE,
|
||||
.group_def = LV_OBJ_CLASS_GROUP_DEF_FALSE,
|
||||
.instance_size = sizeof(lv_obj_t)
|
||||
};
|
||||
|
||||
// Event handlers
|
||||
static void field_edit_event(const lv_obj_class_t* class_p, lv_event_t* e)
|
||||
{
|
||||
@@ -913,6 +945,11 @@ lv_obj_t* etx_choice_create(lv_obj_t* parent)
|
||||
return etx_create(&etx_choice_class, parent);
|
||||
}
|
||||
|
||||
lv_obj_t* etx_bubble_popup_create(lv_obj_t* parent)
|
||||
{
|
||||
return etx_create(&etx_bubble_popup_class, parent);
|
||||
}
|
||||
|
||||
lv_obj_t* etx_bar_create(lv_obj_t* parent)
|
||||
{
|
||||
return etx_create(&etx_bar_class, parent);
|
||||
|
||||
@@ -43,6 +43,13 @@ void MainWindow::run(bool trash)
|
||||
auto opaque = Layer::getFirstOpaque();
|
||||
if (opaque) opaque->checkEvents();
|
||||
|
||||
auto copy = children;
|
||||
for (auto child: copy) {
|
||||
if (!child->deleted() && child->isBubblePopup()) {
|
||||
child->checkEvents();
|
||||
}
|
||||
}
|
||||
|
||||
if (trash) emptyTrash();
|
||||
|
||||
auto delta = ticksNow() - start;
|
||||
|
||||
@@ -41,6 +41,7 @@ lv_obj_t* etx_modal_content_create(lv_obj_t* parent);
|
||||
lv_obj_t* etx_modal_title_create(lv_obj_t* parent);
|
||||
lv_obj_t* etx_bar_create(lv_obj_t* parent);
|
||||
lv_obj_t* etx_checkbox_create(lv_obj_t* parent);
|
||||
lv_obj_t* etx_bubble_popup_create(lv_obj_t* parent);
|
||||
|
||||
lv_obj_t* input_mix_line_create(lv_obj_t* parent);
|
||||
lv_obj_t* input_mix_group_create(lv_obj_t* parent);
|
||||
|
||||
+2
@@ -204,6 +204,8 @@ class Window
|
||||
virtual bool isTopBar() { return false; }
|
||||
virtual bool isWidgetsContainer() { return false; }
|
||||
|
||||
virtual bool isBubblePopup() { return false; }
|
||||
|
||||
protected:
|
||||
static std::list<Window*> trash;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user