#include "../../lv_examples.h" #if LV_USE_OBSERVER && LV_USE_SLIDER && LV_USE_LABEL && LV_USE_ROLLER && LV_USE_DROPDOWN && LV_FONT_MONTSERRAT_30 && LV_BUILD_EXAMPLES static lv_subject_t hour_subject; static lv_subject_t minute_subject; static lv_subject_t format_subject; static lv_subject_t am_pm_subject; static lv_subject_t time_subject; static lv_subject_t * time_group_array_subject[] = {&hour_subject, &minute_subject, &format_subject, &am_pm_subject}; const char * hour12_options = "01\n02\n03\n04\n05\n06\n07\n08\n09\n10\n11\n12"; const char * hour24_options = "00\n01\n02\n03\n04\n05\n06\n07\n08\n09\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23"; const char * minute_options = "00\n01\n02\n03\n04\n05\n06\n07\n08\n09\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n40\n41\n42\n43\n44\n45\n46\n47\n48\n49\n50\n51\n52\n53\n54\n55\n56\n57\n58\n59"; static void set_btn_clicked_event_cb(lv_event_t * e); static void close_clicked_event_cb(lv_event_t * e); static void hour_roller_options_update(lv_observer_t * observer, lv_subject_t * subject); static void time_observer_cb(lv_observer_t * observer, lv_subject_t * subject); typedef enum { TIME_FORMAT_12, TIME_FORMAT_24, } time_format_t; typedef enum { TIME_AM, TIME_PM, } time_am_pm_t; /** * Show how to handle a complex time setting with hour, minute, 12/24 hour mode, and AM/PM switch * In a real application the time can be displayed on multiple screens and it's not trivial * how and where to store the current values and how to get them. * In this example the widgets to set the time are create/deleted dynamically, * yet they always know what the current values are by using subjects. */ void lv_example_observer_3(void) { /*Initialize the subjects. *The UI will update these and read the current values from here, *however the application can update these values at any time and *the widgets will be updated automatically. */ lv_subject_init_int(&hour_subject, 7); lv_subject_init_int(&minute_subject, 45); lv_subject_init_int(&format_subject, TIME_FORMAT_12); lv_subject_init_int(&am_pm_subject, TIME_AM); lv_subject_init_group(&time_subject, time_group_array_subject, 4); /*Create the UI*/ lv_obj_t * time_label = lv_label_create(lv_screen_active()); lv_obj_set_style_text_font(time_label, &lv_font_montserrat_30, 0); lv_subject_add_observer_obj(&time_subject, time_observer_cb, time_label, NULL); lv_obj_set_pos(time_label, 24, 24); lv_obj_t * set_btn = lv_button_create(lv_screen_active()); lv_obj_set_pos(set_btn, 180, 24); lv_obj_add_event_cb(set_btn, set_btn_clicked_event_cb, LV_EVENT_CLICKED, NULL); lv_obj_t * set_label = lv_label_create(set_btn); lv_label_set_text(set_label, "Set"); /*Update some subjects to see if the UI is updated as well*/ lv_subject_set_int(&hour_subject, 9); lv_subject_set_int(&minute_subject, 30); lv_subject_set_int(&am_pm_subject, TIME_PM); } static void set_btn_clicked_event_cb(lv_event_t * e) { lv_obj_t * set_btn = lv_event_get_target(e); lv_obj_add_state(set_btn, LV_STATE_DISABLED); lv_obj_t * cont = lv_obj_create(lv_screen_active()); lv_obj_set_size(cont, lv_pct(100), LV_SIZE_CONTENT); lv_obj_align(cont, LV_ALIGN_BOTTOM_MID, 0, 0); lv_obj_t * hour_roller = lv_roller_create(cont); lv_obj_add_flag(hour_roller, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK); lv_subject_add_observer_obj(&format_subject, hour_roller_options_update, hour_roller, NULL); lv_roller_bind_value(hour_roller, &hour_subject); lv_obj_set_pos(hour_roller, 0, 0); lv_obj_t * min_roller = lv_roller_create(cont); lv_roller_set_options(min_roller, minute_options, LV_ROLLER_MODE_NORMAL); lv_roller_bind_value(min_roller, &minute_subject); lv_obj_set_pos(min_roller, 64, 0); lv_obj_t * format_dropdown = lv_dropdown_create(cont); lv_dropdown_set_options(format_dropdown, "12\n24"); lv_dropdown_bind_value(format_dropdown, &format_subject); lv_obj_set_pos(format_dropdown, 128, 0); lv_obj_set_width(format_dropdown, 80); lv_obj_t * am_pm_dropdown = lv_dropdown_create(cont); lv_dropdown_set_options(am_pm_dropdown, "am\npm"); lv_dropdown_bind_value(am_pm_dropdown, &am_pm_subject); lv_obj_bind_state_if_eq(am_pm_dropdown, &format_subject, LV_STATE_DISABLED, TIME_FORMAT_24); lv_obj_set_pos(am_pm_dropdown, 128, 48); lv_obj_set_width(am_pm_dropdown, 80); lv_obj_t * close_btn = lv_button_create(cont); lv_obj_align(close_btn, LV_ALIGN_TOP_RIGHT, 0, 0); /*Pass the set_btn as user_data to make it non-disabled on close*/ lv_obj_add_event_cb(close_btn, close_clicked_event_cb, LV_EVENT_CLICKED, set_btn); lv_obj_t * close_label = lv_label_create(close_btn); lv_label_set_text(close_label, LV_SYMBOL_CLOSE); } static void close_clicked_event_cb(lv_event_t * e) { lv_obj_t * set_btn = lv_event_get_user_data(e); lv_obj_t * close_btn = lv_event_get_target(e); lv_obj_t * cont = lv_obj_get_parent(close_btn); lv_obj_remove_state(set_btn, LV_STATE_DISABLED); lv_obj_delete(cont); } /*Watch all related subject to display the current time correctly*/ static void time_observer_cb(lv_observer_t * observer, lv_subject_t * subject) { int32_t hour = lv_subject_get_int(lv_subject_get_group_element(subject, 0)); int32_t minute = lv_subject_get_int(lv_subject_get_group_element(subject, 1)); int32_t format = lv_subject_get_int(lv_subject_get_group_element(subject, 2)); int32_t am_pm = lv_subject_get_int(lv_subject_get_group_element(subject, 3)); lv_obj_t * label = lv_observer_get_target(observer); if(format == TIME_FORMAT_24) { lv_label_set_text_fmt(label, "%" LV_PRId32 ":%02" LV_PRId32, hour, minute); } else { lv_label_set_text_fmt(label, "%"LV_PRId32":%02"LV_PRId32" %s", hour + 1, minute, am_pm == TIME_AM ? "am" : "pm"); } } /*Change the hour options on format change*/ static void hour_roller_options_update(lv_observer_t * observer, lv_subject_t * subject) { lv_obj_t * roller = lv_observer_get_target(observer); int32_t prev_selected = lv_roller_get_selected(roller); int32_t v = lv_subject_get_int(subject); if(v == TIME_FORMAT_12) { prev_selected--; if(prev_selected > 12) prev_selected -= 12; lv_roller_set_options(roller, hour12_options, LV_ROLLER_MODE_NORMAL); } else { prev_selected++; lv_roller_set_options(roller, hour24_options, LV_ROLLER_MODE_NORMAL); } lv_roller_set_selected(roller, prev_selected, LV_ANIM_OFF); lv_obj_send_event(roller, LV_EVENT_VALUE_CHANGED, NULL); } #endif