1 #include "../../lv_examples.h"
2 #if LV_USE_OBSERVER && LV_USE_SLIDER && LV_USE_LABEL && LV_USE_ROLLER && LV_USE_DROPDOWN && LV_FONT_MONTSERRAT_30 && LV_BUILD_EXAMPLES
3
4 static lv_subject_t hour_subject;
5 static lv_subject_t minute_subject;
6 static lv_subject_t format_subject;
7 static lv_subject_t am_pm_subject;
8 static lv_subject_t time_subject;
9 static lv_subject_t * time_group_array_subject[] = {&hour_subject, &minute_subject, &format_subject, &am_pm_subject};
10 const char * hour12_options = "01\n02\n03\n04\n05\n06\n07\n08\n09\n10\n11\n12";
11 const char * hour24_options =
12 "00\n01\n02\n03\n04\n05\n06\n07\n08\n09\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23";
13 const char * minute_options =
14 "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";
15
16 static void set_btn_clicked_event_cb(lv_event_t * e);
17 static void close_clicked_event_cb(lv_event_t * e);
18 static void hour_roller_options_update(lv_observer_t * observer, lv_subject_t * subject);
19 static void time_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
20
21 typedef enum {
22 TIME_FORMAT_12,
23 TIME_FORMAT_24,
24 } time_format_t;
25
26 typedef enum {
27 TIME_AM,
28 TIME_PM,
29 } time_am_pm_t;
30
31 /**
32 * Show how to handle a complex time setting with hour, minute, 12/24 hour mode, and AM/PM switch
33 * In a real application the time can be displayed on multiple screens and it's not trivial
34 * how and where to store the current values and how to get them.
35 * In this example the widgets to set the time are create/deleted dynamically,
36 * yet they always know what the current values are by using subjects.
37 */
lv_example_observer_3(void)38 void lv_example_observer_3(void)
39 {
40 /*Initialize the subjects.
41 *The UI will update these and read the current values from here,
42 *however the application can update these values at any time and
43 *the widgets will be updated automatically. */
44 lv_subject_init_int(&hour_subject, 7);
45 lv_subject_init_int(&minute_subject, 45);
46 lv_subject_init_int(&format_subject, TIME_FORMAT_12);
47 lv_subject_init_int(&am_pm_subject, TIME_AM);
48 lv_subject_init_group(&time_subject, time_group_array_subject, 4);
49
50 /*Create the UI*/
51 lv_obj_t * time_label = lv_label_create(lv_screen_active());
52 lv_obj_set_style_text_font(time_label, &lv_font_montserrat_30, 0);
53 lv_subject_add_observer_obj(&time_subject, time_observer_cb, time_label, NULL);
54 lv_obj_set_pos(time_label, 24, 24);
55
56 lv_obj_t * set_btn = lv_button_create(lv_screen_active());
57 lv_obj_set_pos(set_btn, 180, 24);
58 lv_obj_add_event_cb(set_btn, set_btn_clicked_event_cb, LV_EVENT_CLICKED, NULL);
59
60 lv_obj_t * set_label = lv_label_create(set_btn);
61 lv_label_set_text(set_label, "Set");
62
63 /*Update some subjects to see if the UI is updated as well*/
64 lv_subject_set_int(&hour_subject, 9);
65 lv_subject_set_int(&minute_subject, 30);
66 lv_subject_set_int(&am_pm_subject, TIME_PM);
67 }
68
set_btn_clicked_event_cb(lv_event_t * e)69 static void set_btn_clicked_event_cb(lv_event_t * e)
70 {
71 lv_obj_t * set_btn = lv_event_get_target(e);
72 lv_obj_add_state(set_btn, LV_STATE_DISABLED);
73
74 lv_obj_t * cont = lv_obj_create(lv_screen_active());
75 lv_obj_set_size(cont, lv_pct(100), LV_SIZE_CONTENT);
76 lv_obj_align(cont, LV_ALIGN_BOTTOM_MID, 0, 0);
77
78 lv_obj_t * hour_roller = lv_roller_create(cont);
79 lv_obj_add_flag(hour_roller, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
80 lv_subject_add_observer_obj(&format_subject, hour_roller_options_update, hour_roller, NULL);
81 lv_roller_bind_value(hour_roller, &hour_subject);
82 lv_obj_set_pos(hour_roller, 0, 0);
83
84 lv_obj_t * min_roller = lv_roller_create(cont);
85 lv_roller_set_options(min_roller, minute_options, LV_ROLLER_MODE_NORMAL);
86 lv_roller_bind_value(min_roller, &minute_subject);
87 lv_obj_set_pos(min_roller, 64, 0);
88
89 lv_obj_t * format_dropdown = lv_dropdown_create(cont);
90 lv_dropdown_set_options(format_dropdown, "12\n24");
91 lv_dropdown_bind_value(format_dropdown, &format_subject);
92 lv_obj_set_pos(format_dropdown, 128, 0);
93 lv_obj_set_width(format_dropdown, 80);
94
95 lv_obj_t * am_pm_dropdown = lv_dropdown_create(cont);
96 lv_dropdown_set_options(am_pm_dropdown, "am\npm");
97 lv_dropdown_bind_value(am_pm_dropdown, &am_pm_subject);
98 lv_obj_bind_state_if_eq(am_pm_dropdown, &format_subject, LV_STATE_DISABLED, TIME_FORMAT_24);
99 lv_obj_set_pos(am_pm_dropdown, 128, 48);
100 lv_obj_set_width(am_pm_dropdown, 80);
101
102 lv_obj_t * close_btn = lv_button_create(cont);
103 lv_obj_align(close_btn, LV_ALIGN_TOP_RIGHT, 0, 0);
104 /*Pass the set_btn as user_data to make it non-disabled on close*/
105 lv_obj_add_event_cb(close_btn, close_clicked_event_cb, LV_EVENT_CLICKED, set_btn);
106
107 lv_obj_t * close_label = lv_label_create(close_btn);
108 lv_label_set_text(close_label, LV_SYMBOL_CLOSE);
109 }
110
close_clicked_event_cb(lv_event_t * e)111 static void close_clicked_event_cb(lv_event_t * e)
112 {
113 lv_obj_t * set_btn = lv_event_get_user_data(e);
114 lv_obj_t * close_btn = lv_event_get_target(e);
115 lv_obj_t * cont = lv_obj_get_parent(close_btn);
116 lv_obj_remove_state(set_btn, LV_STATE_DISABLED);
117 lv_obj_delete(cont);
118 }
119
120 /*Watch all related subject to display the current time correctly*/
time_observer_cb(lv_observer_t * observer,lv_subject_t * subject)121 static void time_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
122 {
123 int32_t hour = lv_subject_get_int(lv_subject_get_group_element(subject, 0));
124 int32_t minute = lv_subject_get_int(lv_subject_get_group_element(subject, 1));
125 int32_t format = lv_subject_get_int(lv_subject_get_group_element(subject, 2));
126 int32_t am_pm = lv_subject_get_int(lv_subject_get_group_element(subject, 3));
127
128 lv_obj_t * label = lv_observer_get_target(observer);
129
130 if(format == TIME_FORMAT_24) {
131 lv_label_set_text_fmt(label, "%" LV_PRId32 ":%02" LV_PRId32, hour, minute);
132 }
133 else {
134 lv_label_set_text_fmt(label, "%"LV_PRId32":%02"LV_PRId32" %s", hour + 1, minute, am_pm == TIME_AM ? "am" : "pm");
135 }
136 }
137
138 /*Change the hour options on format change*/
hour_roller_options_update(lv_observer_t * observer,lv_subject_t * subject)139 static void hour_roller_options_update(lv_observer_t * observer, lv_subject_t * subject)
140 {
141 lv_obj_t * roller = lv_observer_get_target(observer);
142 int32_t prev_selected = lv_roller_get_selected(roller);
143 int32_t v = lv_subject_get_int(subject);
144 if(v == TIME_FORMAT_12) {
145 prev_selected--;
146 if(prev_selected > 12) prev_selected -= 12;
147 lv_roller_set_options(roller, hour12_options, LV_ROLLER_MODE_NORMAL);
148 }
149 else {
150 prev_selected++;
151 lv_roller_set_options(roller, hour24_options, LV_ROLLER_MODE_NORMAL);
152 }
153
154 lv_roller_set_selected(roller, prev_selected, LV_ANIM_OFF);
155 lv_obj_send_event(roller, LV_EVENT_VALUE_CHANGED, NULL);
156 }
157
158 #endif
159