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

159 lines
6.6 KiB
C

#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, "%d:%02d", hour, minute);
}
else {
lv_label_set_text_fmt(label, "%d:%02d %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