1 /**
2  * @file lv_demo_high_res_app_smart_home.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 
10 #include "lv_demo_high_res_private.h"
11 #if LV_USE_DEMO_HIGH_RES
12 
13 #include "../../src/widgets/image/lv_image.h"
14 #include "../../src/widgets/label/lv_label.h"
15 #include "../../src/widgets/slider/lv_slider.h"
16 #include "../../src/widgets/arc/lv_arc.h"
17 
18 /*********************
19  *      DEFINES
20  *********************/
21 
22 /**********************
23  *      TYPEDEFS
24  **********************/
25 
26 /**********************
27  *  STATIC PROTOTYPES
28  **********************/
29 
30 static void back_clicked_cb(lv_event_t * e);
31 static void create_widget1(lv_demo_high_res_ctx_t * c, lv_obj_t * widgets);
32 static void charging_arc_observer(lv_observer_t * observer, lv_subject_t * subject);
33 static void charging_percent_label_observer(lv_observer_t * observer, lv_subject_t * subject);
34 static void charging_time_until_full_label_observer(lv_observer_t * observer, lv_subject_t * subject);
35 static void create_widget_charging(lv_demo_high_res_ctx_t * c, lv_obj_t * widgets);
36 static void widget2_slider_released_cb(lv_event_t * e);
37 static void widget2_slider_locked_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
38 static void create_widget2(lv_demo_high_res_ctx_t * c, lv_obj_t * widgets);
39 static void widget3_play_pause_clicked_cb(lv_event_t * e);
40 static void create_widget3(lv_demo_high_res_ctx_t * c, lv_obj_t * widgets);
41 static void create_widget4(lv_demo_high_res_ctx_t * c, lv_obj_t * widgets);
42 
43 /**********************
44  *  STATIC VARIABLES
45  **********************/
46 
47 /**********************
48  *      MACROS
49  **********************/
50 
51 /**********************
52  *   GLOBAL FUNCTIONS
53  **********************/
54 
lv_demo_high_res_app_smart_home(lv_obj_t * base_obj)55 void lv_demo_high_res_app_smart_home(lv_obj_t * base_obj)
56 {
57     lv_demo_high_res_ctx_t * c = lv_obj_get_user_data(base_obj);
58 
59     /* background */
60 
61     lv_obj_t * bg = base_obj;
62     lv_obj_remove_style_all(bg);
63     lv_obj_set_size(bg, LV_PCT(100), LV_PCT(100));
64 
65     lv_obj_t * bg_img = lv_image_create(bg);
66     lv_subject_add_observer_obj(&c->th, lv_demo_high_res_theme_observer_image_src_cb, bg_img,
67                                 &c->imgs[IMG_LIGHT_BG_SMART_HOME]);
68 
69     lv_obj_t * bg_cont = lv_obj_create(bg);
70     lv_obj_remove_style_all(bg_cont);
71     lv_obj_set_size(bg_cont, LV_PCT(100), LV_PCT(100));
72     lv_obj_set_flex_flow(bg_cont, LV_FLEX_FLOW_COLUMN);
73     lv_obj_set_style_pad_top(bg_cont, c->sz->gap[7], 0);
74 
75     /* top margin */
76 
77     lv_demo_high_res_top_margin_create(bg_cont,
78                                        c->sz == &lv_demo_high_res_sizes_all[SIZE_SM] ? c->sz->gap[9] : c->sz->gap[10], true, c);
79 
80     /* app info */
81 
82     lv_obj_t * app_info = lv_demo_high_res_simple_container_create(bg_cont, true, c->sz->gap[4], LV_FLEX_ALIGN_START);
83     lv_obj_set_style_pad_top(app_info, c->sz->gap[10], 0);
84     lv_obj_set_style_pad_left(app_info, c->sz->gap[10], 0);
85 
86     lv_obj_t * back = lv_demo_high_res_simple_container_create(app_info, false, c->sz->gap[2], LV_FLEX_ALIGN_CENTER);
87     lv_obj_add_event_cb(back, back_clicked_cb, LV_EVENT_CLICKED, NULL);
88 
89     lv_obj_t * back_icon = lv_image_create(back);
90     lv_image_set_src(back_icon, c->imgs[IMG_ARROW_LEFT]);
91     lv_obj_add_style(back_icon, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_A8_IMG], 0);
92     lv_obj_add_flag(back_icon, LV_OBJ_FLAG_EVENT_BUBBLE);
93 
94     lv_obj_t * back_label = lv_label_create(back);
95     lv_label_set_text_static(back_label, "Back");
96     lv_obj_set_style_text_opa(back_label, LV_OPA_60, 0);
97     lv_obj_add_style(back_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
98     lv_obj_add_style(back_label, &c->fonts[FONT_HEADING_MD], 0);
99 
100     lv_obj_t * app_label = lv_label_create(app_info);
101     lv_label_set_text_static(app_label, "Smart Home");
102     lv_obj_add_style(app_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
103     lv_obj_add_style(app_label, &c->fonts[FONT_HEADING_LG], 0);
104 
105     /* widgets */
106 
107     lv_obj_t * widgets = lv_obj_create(bg_cont);
108     lv_obj_remove_style_all(widgets);
109     lv_obj_set_width(widgets, LV_PCT(100));
110     lv_obj_set_flex_grow(widgets, 1);
111     lv_obj_set_style_pad_bottom(widgets, c->sz->gap[10], 0);
112     lv_obj_set_style_pad_left(widgets, c->sz->gap[10], 0);
113     lv_obj_set_style_pad_right(widgets, c->sz->gap[10], 0);
114     lv_obj_set_flex_flow(widgets, LV_FLEX_FLOW_ROW);
115     lv_obj_set_style_pad_column(widgets, c->sz->gap[7], 0);
116     lv_obj_set_flex_align(widgets, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_END);
117 
118     create_widget1(c, widgets);
119     create_widget_charging(c, widgets);
120     create_widget2(c, widgets);
121     create_widget3(c, widgets);
122     create_widget4(c, widgets);
123 }
124 
125 /**********************
126  *   STATIC FUNCTIONS
127  **********************/
128 
back_clicked_cb(lv_event_t * e)129 static void back_clicked_cb(lv_event_t * e)
130 {
131     lv_obj_t * back = lv_event_get_target_obj(e);
132 
133     lv_obj_t * base_obj = lv_obj_get_parent(lv_obj_get_parent(lv_obj_get_parent(back)));
134     lv_obj_clean(base_obj);
135     lv_demo_high_res_home(base_obj);
136 }
137 
create_widget1(lv_demo_high_res_ctx_t * c,lv_obj_t * widgets)138 static void create_widget1(lv_demo_high_res_ctx_t * c, lv_obj_t * widgets)
139 {
140     lv_obj_t * widget = lv_obj_create(widgets);
141     lv_obj_remove_style_all(widget);
142     lv_obj_set_size(widget, c->sz->card_long_edge, c->sz->card_long_edge);
143     lv_obj_set_style_bg_image_src(widget, c->imgs[IMG_SMART_HOME_WIDGET1_BG], 0);
144     lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0);
145     lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN);
146     lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
147 
148     lv_obj_t * top_label = lv_label_create(widget);
149     lv_label_set_text_static(top_label, "Climate Control");
150     lv_obj_set_width(top_label, LV_PCT(100));
151     lv_obj_add_style(top_label, &c->fonts[FONT_LABEL_MD], 0);
152     lv_obj_set_style_text_color(top_label, lv_color_white(), 0);
153 
154     lv_obj_t * main_temp_box = lv_obj_create(widget);
155     lv_obj_remove_style_all(main_temp_box);
156     lv_obj_set_size(main_temp_box, LV_PCT(100), LV_SIZE_CONTENT);
157     lv_obj_set_style_pad_ver(main_temp_box, c->sz->gap[6], 0);
158     lv_obj_set_style_bg_color(main_temp_box, lv_color_white(), 0);
159     lv_obj_set_style_bg_opa(main_temp_box, LV_OPA_20, 0);
160     lv_obj_set_style_radius(main_temp_box, LV_COORD_MAX, 0);
161 
162     lv_obj_t * main_temp = lv_label_create(main_temp_box);
163     lv_obj_add_style(main_temp, &c->fonts[FONT_LABEL_2XL], 0);
164     lv_obj_set_style_text_color(main_temp, lv_color_white(), 0);
165     lv_obj_center(main_temp);
166     lv_demo_high_res_label_bind_temperature(main_temp, &c->api.subjects.temperature_indoor, c);
167 
168     lv_obj_t * outdoor_temp_box = lv_demo_high_res_simple_container_create(widget, true, c->sz->gap[2],
169                                                                            LV_FLEX_ALIGN_CENTER);
170 
171     lv_obj_t * outdoor_temp = lv_label_create(outdoor_temp_box);
172     lv_obj_add_style(outdoor_temp, &c->fonts[FONT_LABEL_XL], 0);
173     lv_obj_set_style_text_color(outdoor_temp, lv_color_white(), 0);
174     lv_demo_high_res_label_bind_temperature(outdoor_temp, &c->api.subjects.temperature_outdoor, c);
175 
176     lv_obj_t * outdoor_label = lv_label_create(outdoor_temp_box);
177     lv_label_set_text_static(outdoor_label, "Outdoor");
178     lv_obj_add_style(outdoor_label, &c->fonts[FONT_LABEL_SM], 0);
179     lv_obj_set_style_text_color(outdoor_label, lv_color_white(), 0);
180 }
181 
charging_arc_observer(lv_observer_t * observer,lv_subject_t * subject)182 static void charging_arc_observer(lv_observer_t * observer, lv_subject_t * subject)
183 {
184     lv_obj_t * arc = lv_observer_get_target_obj(observer);
185     lv_arc_set_value(arc, lv_map(lv_subject_get_int(subject), 0, EV_CHARGING_RANGE_END, 0, 100));
186 }
187 
charging_percent_label_observer(lv_observer_t * observer,lv_subject_t * subject)188 static void charging_percent_label_observer(lv_observer_t * observer, lv_subject_t * subject)
189 {
190     lv_obj_t * label = lv_observer_get_target_obj(observer);
191     lv_label_set_text_fmt(label, "%"LV_PRId32"%%", lv_map(lv_subject_get_int(subject), 0, EV_CHARGING_RANGE_END, 0, 100));
192 }
193 
charging_time_until_full_label_observer(lv_observer_t * observer,lv_subject_t * subject)194 static void charging_time_until_full_label_observer(lv_observer_t * observer, lv_subject_t * subject)
195 {
196     lv_obj_t * label = lv_observer_get_target_obj(observer);
197     int32_t v_range_time_to_full = lv_map(lv_subject_get_int(subject), 0, EV_CHARGING_RANGE_END, 72, 0);
198     int32_t whole = v_range_time_to_full / 10;
199     int32_t fraction = v_range_time_to_full % 10;
200     lv_label_set_text_fmt(label, "%"LV_PRId32".%"LV_PRId32, whole, fraction);
201 }
202 
create_widget_charging(lv_demo_high_res_ctx_t * c,lv_obj_t * widgets)203 static void create_widget_charging(lv_demo_high_res_ctx_t * c, lv_obj_t * widgets)
204 {
205     lv_obj_t * widget = lv_obj_create(widgets);
206     lv_obj_remove_style_all(widget);
207     lv_obj_set_size(widget, c->sz->card_long_edge, c->sz->card_long_edge);
208     lv_obj_set_style_bg_image_src(widget, c->imgs[IMG_SMART_HOME_WIDGET2_BG], 0);
209     lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0);
210     lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN);
211     lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
212 
213     lv_obj_t * top_label = lv_label_create(widget);
214     lv_label_set_text_static(top_label, "Charging");
215     lv_obj_set_width(top_label, LV_PCT(100));
216     lv_obj_add_style(top_label, &c->fonts[FONT_LABEL_MD], 0);
217     lv_obj_set_style_text_color(top_label, lv_color_white(), 0);
218 
219     lv_obj_t * arc_cont = lv_obj_create(widget);
220     lv_obj_remove_style_all(arc_cont);
221     lv_obj_set_width(arc_cont, LV_PCT(100));
222     lv_obj_set_flex_grow(arc_cont, 1);
223 
224     lv_obj_t * arc = lv_arc_create(arc_cont);
225     lv_obj_set_align(arc, LV_ALIGN_BOTTOM_MID);
226     lv_obj_set_size(arc, c->sz->smart_home_arc_diameter, c->sz->smart_home_arc_diameter);
227     lv_arc_set_rotation(arc, 270);
228     lv_arc_set_bg_angles(arc, 0, 360);
229     lv_obj_remove_style(arc, NULL, LV_PART_KNOB);
230     lv_obj_remove_flag(arc, LV_OBJ_FLAG_CLICKABLE);
231     lv_obj_set_style_arc_rounded(arc, false, 0);
232     lv_obj_set_style_arc_rounded(arc, false, LV_PART_INDICATOR);
233     lv_obj_set_style_arc_width(arc, 8, 0);
234     lv_obj_set_style_arc_width(arc, 8, LV_PART_INDICATOR);
235     lv_obj_set_style_arc_color(arc, lv_color_white(), 0);
236     lv_obj_set_style_arc_color(arc, lv_color_white(), LV_PART_INDICATOR);
237     lv_obj_set_style_arc_opa(arc, LV_OPA_20, 0);
238     lv_subject_add_observer_obj(&c->ev_charging_progress, charging_arc_observer, arc, NULL);
239 
240     lv_obj_t * percent_label = lv_label_create(arc);
241     lv_obj_add_style(percent_label, &c->fonts[FONT_LABEL_XL], 0);
242     lv_obj_set_style_text_color(percent_label, lv_color_white(), 0);
243     lv_obj_center(percent_label);
244     lv_subject_add_observer_obj(&c->ev_charging_progress, charging_percent_label_observer, percent_label, NULL);
245 
246     lv_obj_t * num_label_cont = lv_demo_high_res_simple_container_create(widget,
247                                                                          false,
248                                                                          c->sz->gap[1],
249                                                                          LV_FLEX_ALIGN_END);
250     lv_obj_set_width(num_label_cont, LV_PCT(100));
251 
252     lv_obj_t * time_to_full_num_label = lv_label_create(num_label_cont);
253     lv_obj_add_style(time_to_full_num_label, &c->fonts[FONT_LABEL_XL], 0);
254     lv_obj_set_style_text_color(time_to_full_num_label, lv_color_white(), 0);
255     lv_subject_add_observer_obj(&c->ev_charging_progress, charging_time_until_full_label_observer, time_to_full_num_label,
256                                 NULL);
257 
258     lv_obj_t * h_label = lv_label_create(num_label_cont);
259     lv_label_set_text_static(h_label, "h");
260     lv_obj_add_style(h_label, &c->fonts[FONT_LABEL_SM], 0);
261     lv_obj_set_style_text_color(h_label, lv_color_white(), 0);
262 
263     lv_obj_t * time_to_full_label = lv_label_create(widget);
264     lv_label_set_text_static(time_to_full_label, "Time to full charge");
265     lv_obj_add_style(time_to_full_label, &c->fonts[FONT_LABEL_SM], 0);
266     lv_obj_set_style_text_color(time_to_full_label, lv_color_white(), 0);
267     lv_obj_set_width(time_to_full_label, LV_PCT(100));
268 }
269 
widget2_slider_released_cb(lv_event_t * e)270 static void widget2_slider_released_cb(lv_event_t * e)
271 {
272     lv_obj_t * slider = lv_event_get_target_obj(e);
273     lv_demo_high_res_ctx_t * c = lv_event_get_user_data(e);
274     lv_subject_set_int(&c->api.subjects.locked, lv_slider_get_value(slider) >= 100);
275 }
276 
widget2_slider_locked_observer_cb(lv_observer_t * observer,lv_subject_t * subject)277 static void widget2_slider_locked_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
278 {
279     lv_obj_t * slider = lv_observer_get_target_obj(observer);
280     bool locked = lv_subject_get_int(subject);
281     lv_slider_set_value(slider, locked ? 100 : 0, LV_ANIM_ON);
282     lv_obj_update_flag(slider, LV_OBJ_FLAG_CLICKABLE, !locked);
283 }
284 
create_widget2(lv_demo_high_res_ctx_t * c,lv_obj_t * widgets)285 static void create_widget2(lv_demo_high_res_ctx_t * c, lv_obj_t * widgets)
286 {
287     lv_obj_t * widget = lv_obj_create(widgets);
288     lv_obj_remove_style_all(widget);
289     lv_obj_set_size(widget, c->sz->card_long_edge, c->sz->card_long_edge);
290     lv_subject_add_observer_obj(&c->th, lv_demo_high_res_theme_observer_obj_bg_image_src_cb, widget,
291                                 &c->imgs[IMG_LIGHT_WIDGET2_BG]);
292     lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0);
293     lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN);
294     lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
295 
296     lv_obj_t * top_label = lv_label_create(widget);
297     lv_label_set_text_static(top_label, "Lock");
298     lv_obj_set_width(top_label, LV_PCT(100));
299     lv_obj_add_style(top_label, &c->fonts[FONT_LABEL_MD], 0);
300     lv_obj_add_style(top_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
301 
302     lv_obj_t * slider = lv_slider_create(widget);
303     lv_obj_set_size(slider, LV_PCT(100), c->sz->icon[ICON_2XL]);
304     lv_obj_set_style_pad_hor(slider, c->sz->icon[ICON_2XL] / 2, 0);
305     lv_obj_set_style_pad_all(slider, 0, LV_PART_KNOB);
306     lv_obj_set_style_bg_opa(slider, 0, LV_PART_INDICATOR);
307     lv_obj_add_flag(slider, LV_OBJ_FLAG_ADV_HITTEST);
308     lv_obj_set_style_bg_image_src(slider, c->imgs[IMG_UNLOCK], LV_PART_KNOB);
309     lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_KNOB);
310     lv_obj_set_style_bg_color(slider, lv_color_white(), 0);
311     lv_obj_set_style_bg_opa(slider, LV_OPA_30, 0);
312     lv_slider_set_value(slider, lv_subject_get_int(&c->api.subjects.locked) ? 100 : 0, LV_ANIM_OFF);
313     lv_obj_set_style_anim_duration(slider, lv_anim_speed(2000), 0);
314     lv_obj_add_event_cb(slider, widget2_slider_released_cb, LV_EVENT_RELEASED, c);
315     lv_subject_add_observer_obj(&c->api.subjects.locked, widget2_slider_locked_observer_cb, slider, c);
316 
317     lv_obj_t * bottom_label = lv_label_create(widget);
318     lv_label_set_text_static(bottom_label, "Swipe to lock screen");
319     lv_obj_add_style(bottom_label, &c->fonts[FONT_LABEL_SM], 0);
320     lv_obj_add_style(bottom_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
321 }
322 
widget3_play_pause_clicked_cb(lv_event_t * e)323 static void widget3_play_pause_clicked_cb(lv_event_t * e)
324 {
325     lv_obj_t * play_pause_img = lv_event_get_target_obj(e);
326     lv_demo_high_res_ctx_t * c = lv_event_get_user_data(e);
327 
328     bool was_playing = lv_image_get_src(play_pause_img) == c->imgs[IMG_PLAY_ICON];
329     lv_image_set_src(play_pause_img, c->imgs[was_playing ? IMG_PLAY_ICON_1 : IMG_PLAY_ICON]);
330     lv_subject_set_int(&c->api.subjects.music_play, !was_playing);
331 }
332 
create_widget3(lv_demo_high_res_ctx_t * c,lv_obj_t * widgets)333 static void create_widget3(lv_demo_high_res_ctx_t * c, lv_obj_t * widgets)
334 {
335     lv_obj_t * widget = lv_obj_create(widgets);
336     lv_obj_remove_style_all(widget);
337     lv_obj_set_size(widget, c->sz->card_long_edge, c->sz->card_long_edge);
338     lv_subject_add_observer_obj(&c->th, lv_demo_high_res_theme_observer_obj_bg_image_src_cb, widget,
339                                 &c->imgs[IMG_LIGHT_WIDGET3_BG]);
340     lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0);
341 
342     lv_obj_t * top_label = lv_label_create(widget);
343     lv_label_set_text_static(top_label, "Speaker");
344     lv_obj_add_style(top_label, &c->fonts[FONT_LABEL_MD], 0);
345     lv_obj_add_style(top_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
346     lv_obj_set_align(top_label, LV_ALIGN_TOP_LEFT);
347 
348     lv_obj_t * music_labels_box = lv_demo_high_res_simple_container_create(widget, true, c->sz->gap[1],
349                                                                            LV_FLEX_ALIGN_START);
350     lv_obj_set_align(music_labels_box, LV_ALIGN_BOTTOM_LEFT);
351     lv_obj_t * song_title = lv_label_create(music_labels_box);
352     lv_label_set_text_static(song_title, "there, then, now");
353     lv_obj_add_style(song_title, &c->fonts[FONT_LABEL_SM], 0);
354     lv_obj_add_style(song_title, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
355     lv_obj_t * song_artist = lv_label_create(music_labels_box);
356     lv_label_set_text_static(song_artist, "imagiro, Lowswimm...");
357     lv_obj_add_style(song_artist, &c->fonts[FONT_LABEL_SM], 0);
358     lv_obj_add_style(song_artist, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
359     lv_obj_set_style_text_opa(song_artist, LV_OPA_40, 0);
360 
361     lv_obj_t * slider = lv_slider_create(widget);
362     lv_obj_set_size(slider, c->sz->slider_width, LV_PCT(100));
363     lv_obj_set_align(slider, LV_ALIGN_RIGHT_MID);
364     lv_obj_set_style_bg_color(slider, lv_color_white(), 0);
365     lv_obj_set_style_bg_opa(slider, 30, 0);
366     lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_INDICATOR);
367     lv_obj_set_style_radius(slider, c->sz->gap[4], 0);
368     lv_obj_set_style_radius(slider, c->sz->gap[4], LV_PART_INDICATOR);
369     lv_obj_set_style_bg_color(slider, lv_color_black(), LV_PART_KNOB);
370     lv_obj_set_style_pad_top(slider, -(c->sz->slider_width - 6) / 2 - 8, LV_PART_KNOB);
371     lv_obj_set_style_pad_bottom(slider, -(c->sz->slider_width - 6) / 2 + 8, LV_PART_KNOB);
372     lv_obj_set_style_pad_hor(slider, -(c->sz->slider_width - 12) / 2, LV_PART_KNOB);
373 
374     lv_obj_t * slider_pct_label = lv_label_create(slider);
375     lv_obj_add_style(slider_pct_label, &c->fonts[FONT_LABEL_XS], 0);
376     lv_obj_add_style(slider_pct_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
377     lv_obj_align(slider_pct_label, LV_ALIGN_TOP_MID, 0, 10);
378 
379     lv_slider_bind_value(slider, &c->api.subjects.volume);
380     lv_label_bind_text(slider_pct_label, &c->api.subjects.volume, "%"PRId32"%%");
381 
382     lv_obj_t * slider_volume_img = lv_image_create(slider);
383     lv_image_set_src(slider_volume_img, c->imgs[IMG_VOLUME]);
384     lv_obj_align(slider_volume_img, LV_ALIGN_BOTTOM_MID, 0, -8);
385 
386     lv_obj_t * album_art = lv_image_create(widget);
387     lv_image_set_src(album_art, c->imgs[IMG_ALBUM_ART]);
388 
389     lv_obj_t * controls = lv_demo_high_res_simple_container_create(widget, false, 0, LV_FLEX_ALIGN_CENTER);
390     lv_obj_set_align(controls, LV_ALIGN_LEFT_MID);
391 
392     lv_obj_t * prev_song = lv_image_create(controls);
393     lv_image_set_src(prev_song, c->imgs[IMG_BACKWARD_ICON]);
394     lv_obj_set_style_image_recolor(prev_song, lv_color_white(), 0);
395     lv_obj_set_style_image_recolor_opa(prev_song, LV_OPA_COVER, 0);
396 
397     lv_obj_t * play_pause_img = lv_image_create(controls);
398     lv_image_set_src(play_pause_img, c->imgs[lv_subject_get_int(&c->api.subjects.music_play) ? IMG_PLAY_ICON :
399                                              IMG_PLAY_ICON_1]);
400     lv_obj_set_style_image_recolor(play_pause_img, lv_color_white(), 0);
401     lv_obj_set_style_image_recolor_opa(play_pause_img, LV_OPA_COVER, 0);
402     lv_obj_add_flag(play_pause_img, LV_OBJ_FLAG_CLICKABLE);
403     lv_obj_add_event_cb(play_pause_img, widget3_play_pause_clicked_cb, LV_EVENT_CLICKED, c);
404 
405     lv_obj_t * next_song = lv_image_create(controls);
406     lv_image_set_src(next_song, c->imgs[IMG_FORWARD_ICON]);
407     lv_obj_set_style_image_recolor(next_song, lv_color_white(), 0);
408     lv_obj_set_style_image_recolor_opa(next_song, LV_OPA_COVER, 0);
409 
410     lv_obj_align_to(album_art, controls, LV_ALIGN_CENTER, 0, 0);
411 }
412 
create_widget4(lv_demo_high_res_ctx_t * c,lv_obj_t * widgets)413 static void create_widget4(lv_demo_high_res_ctx_t * c, lv_obj_t * widgets)
414 {
415     lv_obj_t * widget = lv_obj_create(widgets);
416     lv_obj_remove_style_all(widget);
417     lv_obj_set_size(widget, c->sz->widget_long_edge, c->sz->card_long_edge);
418     lv_subject_add_observer_obj(&c->th, lv_demo_high_res_theme_observer_obj_bg_image_src_cb, widget,
419                                 &c->imgs[IMG_LIGHT_WIDGET4_BG]);
420     lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0);
421     lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN);
422     lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
423     lv_obj_remove_flag(widget, LV_OBJ_FLAG_SCROLLABLE);
424 
425     lv_obj_t * top_label = lv_label_create(widget);
426     lv_label_set_text_static(top_label, "Main Light");
427     lv_obj_add_style(top_label, &c->fonts[FONT_LABEL_MD], 0);
428     lv_obj_add_style(top_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
429 
430     lv_obj_t * temperature_box = lv_demo_high_res_simple_container_create(widget, true, c->sz->gap[5], LV_FLEX_ALIGN_START);
431     lv_obj_set_width(temperature_box, LV_PCT(100));
432     lv_obj_set_style_pad_ver(temperature_box, 8, 0); /* so the slider knob is not clipped */
433 
434     lv_obj_t * temperature_slider = lv_slider_create(temperature_box);
435     lv_obj_set_size(temperature_slider, LV_PCT(100), c->imgs[IMG_MAIN_LIGHT_SLIDER]->header.h);
436     lv_obj_set_style_bg_opa(temperature_slider, LV_OPA_TRANSP, 0);
437     lv_obj_set_style_bg_opa(temperature_slider, LV_OPA_TRANSP, LV_PART_INDICATOR);
438     lv_obj_set_style_bg_color(temperature_slider, lv_color_white(), LV_PART_KNOB);
439     lv_obj_set_style_radius(temperature_slider, 0, 0);
440     lv_obj_set_style_pad_ver(temperature_slider, 4, 0);
441     lv_obj_set_style_pad_hor(temperature_slider, -((c->sz->slider_width - 6) / 2), LV_PART_KNOB);
442     lv_obj_set_style_bg_image_src(temperature_slider, c->imgs[IMG_MAIN_LIGHT_SLIDER], 0);
443     lv_slider_set_range(temperature_slider, 0, 20000);
444 
445     lv_obj_t * temperature_label_box = lv_demo_high_res_simple_container_create(temperature_box, true, c->sz->gap[1],
446                                                                                 LV_FLEX_ALIGN_START);
447     lv_obj_t * temperature_label = lv_label_create(temperature_label_box);
448     lv_label_set_text_static(temperature_label, "Light temperature");
449     lv_obj_add_style(temperature_label, &c->fonts[FONT_LABEL_SM], 0);
450     lv_obj_add_style(temperature_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
451     lv_obj_t * temperature_value_label = lv_label_create(temperature_label_box);
452     lv_obj_add_style(temperature_value_label, &c->fonts[FONT_LABEL_SM], 0);
453     lv_obj_add_style(temperature_value_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
454     lv_obj_set_style_text_opa(temperature_value_label, LV_OPA_40, 0);
455 
456     lv_slider_bind_value(temperature_slider, &c->api.subjects.main_light_temperature);
457     lv_label_bind_text(temperature_value_label, &c->api.subjects.main_light_temperature, "%"PRId32" K");
458 
459     lv_obj_t * slider = lv_slider_create(widget);
460     lv_obj_set_size(slider, LV_PCT(100), c->sz->slider_width);
461     lv_obj_set_style_bg_color(slider, lv_color_white(), 0);
462     lv_obj_set_style_bg_opa(slider, 30, 0);
463     lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_INDICATOR);
464     lv_obj_set_style_radius(slider, c->sz->gap[4], 0);
465     lv_obj_set_style_radius(slider, c->sz->gap[4], LV_PART_INDICATOR);
466     lv_obj_set_style_bg_color(slider, lv_color_black(), LV_PART_KNOB);
467     lv_obj_set_style_pad_right(slider, -(c->sz->slider_width - 6) / 2 - 8, LV_PART_KNOB);
468     lv_obj_set_style_pad_left(slider, -(c->sz->slider_width - 6) / 2 + 8, LV_PART_KNOB);
469     lv_obj_set_style_pad_ver(slider, -(c->sz->slider_width - 12) / 2, LV_PART_KNOB);
470 
471     lv_obj_t * slider_pct_label = lv_label_create(slider);
472     lv_obj_add_style(slider_pct_label, &c->fonts[FONT_LABEL_XS], 0);
473     lv_obj_add_style(slider_pct_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0);
474     lv_obj_align(slider_pct_label, LV_ALIGN_RIGHT_MID, -10, 0);
475 
476     lv_slider_bind_value(slider, &c->api.subjects.main_light_intensity);
477     lv_label_bind_text(slider_pct_label, &c->api.subjects.main_light_intensity, "%"PRId32"%%");
478 
479     lv_obj_t * slider_lamp_img = lv_image_create(slider);
480     lv_image_set_src(slider_lamp_img, c->imgs[IMG_LAMP]);
481     lv_obj_align(slider_lamp_img, LV_ALIGN_LEFT_MID, 8, 0);
482 }
483 
484 #endif /*LV_USE_DEMO_HIGH_RES*/
485