mirror of
https://github.com/lvgl/lvgl.git
synced 2025-02-04 07:13:00 +08:00
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com>
168 lines
5.9 KiB
C
168 lines
5.9 KiB
C
#include "../../lv_examples.h"
|
|
#if LV_USE_OBSERVER && LV_USE_ARC && LV_USE_LABEL && LV_USE_BUTTON && LV_USE_SPINNER && LV_BUILD_EXAMPLES
|
|
|
|
typedef enum {
|
|
FW_UPDATE_STATE_IDLE,
|
|
FW_UPDATE_STATE_CONNECTING,
|
|
FW_UPDATE_STATE_CONNECTED,
|
|
FW_UPDATE_STATE_DOWNLOADING,
|
|
FW_UPDATE_STATE_CANCEL,
|
|
FW_UPDATE_STATE_READY,
|
|
} fw_update_state_t;
|
|
|
|
static void fw_upload_manager_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
|
|
static void fw_update_btn_clicked_event_cb(lv_event_t * e);
|
|
static void fw_update_close_event_cb(lv_event_t * e);
|
|
static void fw_update_win_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
|
|
|
|
static lv_subject_t fw_download_percent_subject;
|
|
static lv_subject_t fw_update_status_subject;
|
|
|
|
/**
|
|
* Show how to handle a complete firmware update process with observers.
|
|
* Normally it's hard to implement a firmware update process because in some cases
|
|
* - the App needs to was for the UI (wait for a button press)
|
|
* - the UI needs to wait for the App (connecting or downloading)
|
|
* With observers these complex mechanisms can be implemented a simple and clean way.
|
|
*/
|
|
void lv_example_observer_5(void)
|
|
{
|
|
lv_subject_init_int(&fw_download_percent_subject, 0);
|
|
lv_subject_init_int(&fw_update_status_subject, FW_UPDATE_STATE_IDLE);
|
|
|
|
lv_subject_add_observer(&fw_update_status_subject, fw_upload_manager_observer_cb, NULL);
|
|
|
|
/*Create start FW update button*/
|
|
lv_obj_t * btn = lv_button_create(lv_screen_active());
|
|
lv_obj_add_event_cb(btn, fw_update_btn_clicked_event_cb, LV_EVENT_CLICKED, NULL);
|
|
lv_obj_center(btn);
|
|
lv_obj_t * label = lv_label_create(btn);
|
|
lv_label_set_text(label, "Firmware update");
|
|
}
|
|
|
|
static void fw_update_btn_clicked_event_cb(lv_event_t * e)
|
|
{
|
|
LV_UNUSED(e);
|
|
lv_obj_t * win = lv_win_create(lv_screen_active());
|
|
lv_obj_set_size(win, lv_pct(90), lv_pct(90));
|
|
lv_obj_set_height(lv_win_get_header(win), 40);
|
|
lv_obj_set_style_radius(win, 8, 0);
|
|
lv_obj_set_style_shadow_width(win, 24, 0);
|
|
lv_obj_set_style_shadow_offset_x(win, 2, 0);
|
|
lv_obj_set_style_shadow_offset_y(win, 3, 0);
|
|
lv_obj_set_style_shadow_color(win, lv_color_hex3(0x888), 0);
|
|
lv_win_add_title(win, "Firmware update");
|
|
lv_obj_t * btn = lv_win_add_button(win, LV_SYMBOL_CLOSE, 40);
|
|
lv_obj_add_event_cb(btn, fw_update_close_event_cb, LV_EVENT_CLICKED, NULL);
|
|
lv_obj_center(win);
|
|
|
|
lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_IDLE);
|
|
lv_subject_add_observer_obj(&fw_update_status_subject, fw_update_win_observer_cb, win, NULL);
|
|
}
|
|
|
|
static void fw_update_close_event_cb(lv_event_t * e)
|
|
{
|
|
LV_UNUSED(e);
|
|
lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_CANCEL);
|
|
}
|
|
|
|
static void restart_btn_click_event_cb(lv_event_t * e)
|
|
{
|
|
lv_obj_t * win = lv_event_get_user_data(e);
|
|
lv_obj_delete(win);
|
|
lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_IDLE);
|
|
}
|
|
|
|
static void fw_update_win_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
|
|
{
|
|
lv_obj_t * win = lv_observer_get_target(observer);
|
|
lv_obj_t * cont = lv_win_get_content(win);
|
|
fw_update_state_t status = lv_subject_get_int(&fw_update_status_subject);
|
|
if(status == FW_UPDATE_STATE_IDLE) {
|
|
lv_obj_clean(cont);
|
|
lv_obj_t * spinner = lv_spinner_create(cont);
|
|
lv_obj_center(spinner);
|
|
lv_obj_set_size(spinner, 130, 130);
|
|
|
|
lv_obj_t * label = lv_label_create(cont);
|
|
lv_label_set_text(label, "Connecting");
|
|
lv_obj_center(label);
|
|
|
|
lv_subject_set_int(subject, FW_UPDATE_STATE_CONNECTING);
|
|
}
|
|
else if(status == FW_UPDATE_STATE_DOWNLOADING) {
|
|
lv_obj_clean(cont);
|
|
lv_obj_t * arc = lv_arc_create(cont);
|
|
lv_arc_bind_value(arc, &fw_download_percent_subject);
|
|
lv_obj_center(arc);
|
|
lv_obj_set_size(arc, 130, 130);
|
|
lv_obj_remove_flag(arc, LV_OBJ_FLAG_CLICKABLE);
|
|
|
|
lv_obj_t * label = lv_label_create(cont);
|
|
lv_label_bind_text(label, &fw_download_percent_subject, "%d %%");
|
|
lv_obj_center(label);
|
|
}
|
|
else if(status == FW_UPDATE_STATE_READY) {
|
|
lv_obj_clean(cont);
|
|
lv_obj_t * label = lv_label_create(cont);
|
|
lv_label_set_text(label, "Firmware update is ready");
|
|
lv_obj_align(label, LV_ALIGN_CENTER, 0, -20);
|
|
|
|
lv_obj_t * btn = lv_button_create(cont);
|
|
lv_obj_align(btn, LV_ALIGN_CENTER, 0, 20);
|
|
lv_obj_add_event_cb(btn, restart_btn_click_event_cb, LV_EVENT_CLICKED, win);
|
|
|
|
label = lv_label_create(btn);
|
|
lv_label_set_text(label, "Restart");
|
|
}
|
|
else if(status == FW_UPDATE_STATE_CANCEL) {
|
|
lv_obj_delete(win);
|
|
}
|
|
}
|
|
|
|
static void connect_timer_cb(lv_timer_t * t)
|
|
{
|
|
if(lv_subject_get_int(&fw_update_status_subject) != FW_UPDATE_STATE_CANCEL) {
|
|
lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_CONNECTED);
|
|
}
|
|
lv_timer_delete(t);
|
|
}
|
|
|
|
static void download_timer_cb(lv_timer_t * t)
|
|
{
|
|
if(lv_subject_get_int(&fw_update_status_subject) == FW_UPDATE_STATE_CANCEL) {
|
|
lv_timer_delete(t);
|
|
return;
|
|
}
|
|
|
|
int32_t v = lv_subject_get_int(&fw_download_percent_subject);
|
|
if(v < 100) {
|
|
lv_subject_set_int(&fw_download_percent_subject, v + 1);
|
|
}
|
|
else {
|
|
lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_READY);
|
|
lv_timer_delete(t);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Emulate connection and FW downloading by timers
|
|
*/
|
|
static void fw_upload_manager_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
|
|
{
|
|
LV_UNUSED(subject);
|
|
LV_UNUSED(observer);
|
|
|
|
fw_update_state_t state = lv_subject_get_int(&fw_update_status_subject);
|
|
if(state == FW_UPDATE_STATE_CONNECTING) {
|
|
lv_timer_create(connect_timer_cb, 2000, NULL);
|
|
}
|
|
else if(state == FW_UPDATE_STATE_CONNECTED) {
|
|
lv_subject_set_int(&fw_download_percent_subject, 0);
|
|
lv_subject_set_int(&fw_update_status_subject, FW_UPDATE_STATE_DOWNLOADING);
|
|
lv_timer_create(download_timer_cb, 50, NULL);
|
|
}
|
|
}
|
|
|
|
#endif
|