1 /**
2 * @file lv_demo_high_res_util.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/canvas/lv_canvas.h"
15 #include "../../src/widgets/label/lv_label.h"
16
17 /*********************
18 * DEFINES
19 *********************/
20
21 /**********************
22 * TYPEDEFS
23 **********************/
24
25 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_medium_12)
26 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_medium_16)
27 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_medium_24)
28 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_30)
29 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_36)
30 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_60)
31 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_light_120)
32 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_light_160)
33 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_regular_30)
34 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_regular_60)
35
36 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_regular_20)
37 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_regular_40)
38 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_regular_45)
39 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_regular_90)
40
41 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_light_80)
42 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_light_107)
43 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_light_180)
44 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_light_240)
45
46 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_medium_8)
47 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_medium_11)
48 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_medium_18)
49 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_medium_36)
50
51 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_20)
52 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_24)
53 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_40)
54 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_45)
55 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_54)
56 LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_90)
57
58 /**********************
59 * STATIC PROTOTYPES
60 **********************/
61
62 static void init_fonts_sm(lv_style_t * fonts);
63 static void init_fonts_md(lv_style_t * fonts);
64 static void init_fonts_lg(lv_style_t * fonts);
65 static void theme_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
66 static void free_ctx_event_cb(lv_event_t * e);
67 static void label_text_temperature_cb(lv_observer_t * observer, lv_subject_t * subject);
68
69 /**********************
70 * STATIC PROTOTYPES
71 **********************/
72
73 /**********************
74 * STATIC VARIABLES
75 **********************/
76
77 const lv_demo_high_res_theme_t lv_demo_high_res_theme_light = {
78 .base = LV_COLOR_MAKE(0xff, 0xff, 0xff),
79 .accent = LV_COLOR_MAKE(0xcc, 0x00, 0x00),
80 };
81
82 const lv_demo_high_res_theme_t lv_demo_high_res_theme_dark = {
83 .base = LV_COLOR_MAKE(0x00, 0x00, 0x00),
84 .accent = LV_COLOR_MAKE(0xe1, 0x2b, 0x17),
85 };
86
87 const lv_demo_high_res_sizes_t lv_demo_high_res_sizes_all[SIZE_COUNT] = {
88 {
89 .gap = {0, 2, 4, 6, 9, 12, 14, 16, 20, 24, 32},
90 .icon = {16, 21, 32, 42, 64},
91 .card_long_edge = 200,
92 .widget_long_edge = 256,
93 .card_short_edge = 120,
94 .smart_home_arc_diameter = 107,
95 .ev_charging_arc_diameter = 160,
96 .smart_meter_collapsed_part_height = 48,
97 .slider_width = 27,
98 .small_chart_height = 67,
99 .large_chart_height = 167,
100 .card_radius = 12,
101 .health_panel_width = 133,
102 .settings_panel_width = 179,
103 .home_bottom_margin_height = 53,
104 .init_fonts_cb = init_fonts_sm
105 },
106 {
107 .gap = {0, 3, 6, 9, 12, 16, 20, 24, 30, 36, 48},
108 .icon = {24, 32, 48, 64, 96},
109 .card_long_edge = 300,
110 .widget_long_edge = 384,
111 .card_short_edge = 180,
112 .smart_home_arc_diameter = 160,
113 .ev_charging_arc_diameter = 240,
114 .smart_meter_collapsed_part_height = 72,
115 .slider_width = 40,
116 .small_chart_height = 100,
117 .large_chart_height = 250,
118 .card_radius = 18,
119 .health_panel_width = 200,
120 .settings_panel_width = 268,
121 .home_bottom_margin_height = 80,
122 .init_fonts_cb = init_fonts_md
123 },
124 {
125 .gap = {0, 5, 10, 15, 18, 24, 30, 36, 45, 54, 72},
126 .icon = {36, 48, 72, 96, 144},
127 .card_long_edge = 450,
128 .widget_long_edge = 576,
129 .card_short_edge = 270,
130 .smart_home_arc_diameter = 240,
131 .ev_charging_arc_diameter = 360,
132 .smart_meter_collapsed_part_height = 108,
133 .slider_width = 60,
134 .small_chart_height = 150,
135 .large_chart_height = 375,
136 .card_radius = 27,
137 .health_panel_width = 300,
138 .settings_panel_width = 402,
139 .home_bottom_margin_height = 120,
140 .init_fonts_cb = init_fonts_lg
141 }
142 };
143
144 /**********************
145 * MACROS
146 **********************/
147
148 #define ARRAY_LEN(arr) (sizeof(arr) / sizeof(*arr))
149
150 /**********************
151 * GLOBAL FUNCTIONS
152 **********************/
153
lv_demo_high_res_base_obj_create(const char * assets_path,const char * logo_path,const char * slides_path,lv_demo_high_res_exit_cb_t exit_cb)154 lv_obj_t * lv_demo_high_res_base_obj_create(const char * assets_path,
155 const char * logo_path,
156 const char * slides_path,
157 lv_demo_high_res_exit_cb_t exit_cb)
158 {
159 lv_demo_high_res_ctx_t * c = lv_malloc_zeroed(sizeof(lv_demo_high_res_ctx_t));
160 LV_ASSERT_MALLOC(c);
161 lv_obj_t * base_obj = lv_obj_create(lv_screen_active());
162 lv_obj_set_user_data(base_obj, c);
163 lv_obj_add_event_cb(base_obj, free_ctx_event_cb, LV_EVENT_DELETE, NULL);
164
165 lv_display_t * disp = lv_display_get_default();
166 int32_t hres = lv_display_get_horizontal_resolution(disp);
167 int32_t vres = lv_display_get_vertical_resolution(disp);
168 bool is_exact;
169 int32_t size;
170 if(hres < 1280 && vres < 720) {
171 is_exact = hres == 800 && vres == 480;
172 size = SIZE_SM;
173 }
174 else if(hres < 1920 && vres < 1080) {
175 is_exact = hres == 1280 && vres == 720;
176 size = SIZE_MD;
177 }
178 else {
179 is_exact = hres == 1920 && vres == 1080;
180 size = SIZE_LG;
181 }
182 if(!is_exact) {
183 LV_LOG_WARN("a display size of exactly 800x480, 1280x720, or 1920x1080 is recommended for the high-res demo");
184 }
185 c->sz = &lv_demo_high_res_sizes_all[size];
186
187 static const struct {
188 const char * name;
189 lv_color_format_t cf;
190 } image_details[IMG_COUNT] = {
191 {"about_app_icon", LV_COLOR_FORMAT_ARGB8888},
192 {"album_art", LV_COLOR_FORMAT_ARGB8888},
193 {"arrow_left", LV_COLOR_FORMAT_ARGB8888},
194 {"backward_icon", LV_COLOR_FORMAT_ARGB8888},
195 {"cold_icon", LV_COLOR_FORMAT_ARGB8888},
196 {"dry_icon", LV_COLOR_FORMAT_ARGB8888},
197 {"energy_icon", LV_COLOR_FORMAT_ARGB8888},
198 {"ev_charging_app_icon", LV_COLOR_FORMAT_ARGB8888},
199 {"ev_charging_widget3_1_bg", LV_COLOR_FORMAT_ARGB8888},
200 {"ev_charging_widget3_bg", LV_COLOR_FORMAT_ARGB8888},
201 {"fan", LV_COLOR_FORMAT_ARGB8888},
202 {"forward_icon", LV_COLOR_FORMAT_ARGB8888},
203 {"health_icon", LV_COLOR_FORMAT_ARGB8888},
204 {"health_icon_bold", LV_COLOR_FORMAT_ARGB8888},
205 {"heat_icon", LV_COLOR_FORMAT_ARGB8888},
206 {"lamp", LV_COLOR_FORMAT_ARGB8888},
207 {"logout_icon", LV_COLOR_FORMAT_ARGB8888},
208 {"main_light_slider", LV_COLOR_FORMAT_ARGB8888},
209 {"minus", LV_COLOR_FORMAT_ARGB8888},
210 {"pager_left", LV_COLOR_FORMAT_ARGB8888},
211 {"pager_pause", LV_COLOR_FORMAT_ARGB8888},
212 {"pager_play", LV_COLOR_FORMAT_ARGB8888},
213 {"pager_right", LV_COLOR_FORMAT_ARGB8888},
214 {"play_icon", LV_COLOR_FORMAT_ARGB8888},
215 {"play_icon_1", LV_COLOR_FORMAT_ARGB8888},
216 {"plus", LV_COLOR_FORMAT_ARGB8888},
217 {"range_icon", LV_COLOR_FORMAT_ARGB8888},
218 {"setting_icon", LV_COLOR_FORMAT_ARGB8888},
219 {"setting_icon_bold", LV_COLOR_FORMAT_ARGB8888},
220 {"smart_home_app_icon", LV_COLOR_FORMAT_ARGB8888},
221 {"smart_home_widget1_bg", LV_COLOR_FORMAT_ARGB8888},
222 {"smart_home_widget2_bg", LV_COLOR_FORMAT_ARGB8888},
223 {"smart_meter_app_icon", LV_COLOR_FORMAT_ARGB8888},
224 {"thermostat_app_icon", LV_COLOR_FORMAT_ARGB8888},
225 {"time_icon", LV_COLOR_FORMAT_ARGB8888},
226 {"unlock", LV_COLOR_FORMAT_ARGB8888},
227 {"volume", LV_COLOR_FORMAT_ARGB8888},
228 {"weather", LV_COLOR_FORMAT_ARGB8888},
229 {"wifi_icon", LV_COLOR_FORMAT_ARGB8888},
230 {"light_bg_about", LV_COLOR_FORMAT_NATIVE},
231 {"dark_bg_about", LV_COLOR_FORMAT_NATIVE},
232 {"light_bg_ev_charging", LV_COLOR_FORMAT_NATIVE},
233 {"dark_bg_ev_charging", LV_COLOR_FORMAT_NATIVE},
234 {"light_bg_home", LV_COLOR_FORMAT_NATIVE},
235 {"dark_bg_home", LV_COLOR_FORMAT_NATIVE},
236 {"light_bg_smart_home", LV_COLOR_FORMAT_NATIVE},
237 {"dark_bg_smart_home", LV_COLOR_FORMAT_NATIVE},
238 {"light_bg_smart_meter", LV_COLOR_FORMAT_NATIVE},
239 {"dark_bg_smart_meter", LV_COLOR_FORMAT_NATIVE},
240 {"light_bg_thermostat", LV_COLOR_FORMAT_NATIVE},
241 {"dark_bg_thermostat", LV_COLOR_FORMAT_NATIVE},
242 {"light_dark_theme_icon", LV_COLOR_FORMAT_ARGB8888},
243 {"dark_dark_theme_icon", LV_COLOR_FORMAT_ARGB8888},
244 {"light_light_theme_icon", LV_COLOR_FORMAT_ARGB8888},
245 {"dark_light_theme_icon", LV_COLOR_FORMAT_ARGB8888},
246 {"light_widget1_bg", LV_COLOR_FORMAT_ARGB8888},
247 {"dark_widget1_bg", LV_COLOR_FORMAT_ARGB8888},
248 {"light_widget2_bg", LV_COLOR_FORMAT_ARGB8888},
249 {"dark_widget2_bg", LV_COLOR_FORMAT_ARGB8888},
250 {"light_widget3_bg", LV_COLOR_FORMAT_ARGB8888},
251 {"dark_widget3_bg", LV_COLOR_FORMAT_ARGB8888},
252 {"light_widget4_bg", LV_COLOR_FORMAT_ARGB8888},
253 {"dark_widget4_bg", LV_COLOR_FORMAT_ARGB8888},
254 {"light_widget5_bg", LV_COLOR_FORMAT_ARGB8888},
255 {"dark_widget5_bg", LV_COLOR_FORMAT_ARGB8888},
256 };
257 const char * size_prefix = size == SIZE_SM ? "sm" : size == SIZE_MD ? "md" : "lg";
258 for(uint32_t i = 0; i < IMG_COUNT; i++) {
259 char path_buf[256];
260 int chars = lv_snprintf(path_buf, sizeof(path_buf), "%s/img_lv_demo_high_res_%s_%s.png",
261 assets_path, image_details[i].name, size_prefix);
262 LV_ASSERT(chars < (int)sizeof(path_buf));
263 c->imgs[i] = lv_demo_high_res_image_preload(path_buf, image_details[i].cf, LV_SCALE_NONE);
264 }
265
266 for(uint32_t i = 0; i < STYLE_COLOR_COUNT; i++) {
267 for(uint32_t j = 0; j < STYLE_TYPE_COUNT; j++) {
268 lv_style_init(&c->styles[i][j]);
269 }
270 }
271
272 for(uint32_t i = 0; i < FONT_COUNT; i++) {
273 lv_style_init(&c->fonts[i]);
274 }
275 c->sz->init_fonts_cb(c->fonts);
276
277 lv_subject_init_pointer(&c->th, (void *)&lv_demo_high_res_theme_dark);
278 c->th.user_data = c;
279 lv_subject_add_observer(&c->th, theme_observer_cb, c);
280
281 c->logo_path = lv_strdup(logo_path);
282 LV_ASSERT_MALLOC(c->logo_path);
283 c->slides_path = lv_strdup(slides_path);
284 LV_ASSERT_MALLOC(c->slides_path);
285
286 c->exit_cb = exit_cb;
287
288 lv_subject_init_int(&c->temperature_units_are_celsius, 1);
289 c->ev_charging_bg_cont = NULL;
290 lv_subject_init_int(&c->ev_charging_progress, EV_CHARGING_RANGE_END * 0 / 100);
291 lv_subject_init_int(&c->smart_meter_selected_bar, 4);
292
293 c->top_margin_subjects_are_init = false;
294
295 /* API subjects */
296
297 /* input subjects */
298 lv_subject_init_int(&c->api.subjects.hour, 9);
299 lv_subject_init_int(&c->api.subjects.minute, 36);
300 lv_subject_init_pointer(&c->api.subjects.week_day_name, "Tuesday");
301 lv_subject_init_int(&c->api.subjects.month_day, 31);
302 lv_subject_init_pointer(&c->api.subjects.month_name, "October");
303 lv_subject_init_int(&c->api.subjects.temperature_outdoor, 140); /* tenths of a degree */
304 lv_subject_init_int(&c->api.subjects.temperature_indoor, 225); /* tenths of a degree */
305 lv_subject_init_pointer(&c->api.subjects.wifi_ssid, NULL);
306 lv_subject_init_pointer(&c->api.subjects.wifi_ip, NULL);
307
308 /* output subjects */
309 lv_subject_init_int(&c->api.subjects.music_play, 1);
310
311 /* input+output subjects */
312 lv_subject_init_int(&c->api.subjects.locked, 0);
313 lv_subject_init_int(&c->api.subjects.volume, 63);
314 lv_subject_init_int(&c->api.subjects.main_light_temperature, 4000);
315 lv_subject_init_int(&c->api.subjects.main_light_intensity, 52);
316 lv_subject_init_int(&c->api.subjects.thermostat_fan_speed, 40);
317 lv_subject_init_int(&c->api.subjects.thermostat_target_temperature, 240); /* tenths of a degree */
318
319 c->api.base_obj = base_obj;
320 c->api.user_data = NULL;
321
322 c->subject_groups.time.members[0] = &c->api.subjects.hour;
323 c->subject_groups.time.members[1] = &c->api.subjects.minute;
324 lv_subject_init_group(&c->subject_groups.time.group, c->subject_groups.time.members,
325 ARRAY_LEN(c->subject_groups.time.members));
326 c->subject_groups.date.members[0] = &c->api.subjects.week_day_name;
327 c->subject_groups.date.members[1] = &c->api.subjects.month_day;
328 c->subject_groups.date.members[2] = &c->api.subjects.month_name;
329 lv_subject_init_group(&c->subject_groups.date.group, c->subject_groups.date.members,
330 ARRAY_LEN(c->subject_groups.date.members));
331 c->subject_groups.wifi.members[0] = &c->api.subjects.wifi_ssid;
332 c->subject_groups.wifi.members[1] = &c->api.subjects.wifi_ip;
333 lv_subject_init_group(&c->subject_groups.wifi.group, c->subject_groups.wifi.members,
334 ARRAY_LEN(c->subject_groups.wifi.members));
335
336 lv_array_init(&c->about_slides_array, 1, sizeof(lv_image_dsc_t *));
337 lv_fs_dir_t dir;
338 lv_fs_res_t fs_res = lv_fs_dir_open(&dir, slides_path);
339 if(fs_res == LV_FS_RES_OK) {
340 fs_res = lv_fs_dir_close(&dir);
341 LV_ASSERT(fs_res == LV_FS_RES_OK);
342
343 c->about_slides_dir_exists = true;
344
345 for(int32_t i = 1; ; i++) {
346 char buf[256];
347 lv_snprintf(buf, sizeof(buf), "%s/Slide%"LV_PRId32".png", slides_path, i);
348 lv_fs_file_t file;
349 fs_res = lv_fs_open(&file, buf, LV_FS_MODE_RD);
350 if(fs_res != LV_FS_RES_OK) {
351 break;
352 }
353 fs_res = lv_fs_close(&file);
354 LV_ASSERT(fs_res == LV_FS_RES_OK);
355
356 lv_image_header_t header;
357 lv_result_t res = lv_image_decoder_get_info(buf, &header);
358 if(res == LV_RESULT_INVALID) {
359 LV_LOG_WARN("Couldn't read the header info of slide image");
360 continue;
361 }
362 /* the ratio of a slide's height to the display's height will be 9:16 */
363 int32_t scale = (9 * 256 * vres) / (16 * header.h);
364
365 lv_image_dsc_t * loaded_draw_buf = lv_demo_high_res_image_preload(buf, LV_COLOR_FORMAT_NATIVE, scale);
366 if(loaded_draw_buf == NULL) continue;
367 lv_array_push_back(&c->about_slides_array, &loaded_draw_buf);
368
369 if(scale != LV_SCALE_NONE) LV_LOG_INFO("A slide was scaled by %"LV_PRId32" (256 means 1:1)", scale);
370 }
371 }
372
373 return base_obj;
374 }
375
lv_demo_high_res_simple_container_create(lv_obj_t * parent,bool vertical,int32_t pad,lv_flex_align_t align_cross_place)376 lv_obj_t * lv_demo_high_res_simple_container_create(lv_obj_t * parent, bool vertical, int32_t pad,
377 lv_flex_align_t align_cross_place)
378 {
379 lv_obj_t * obj = lv_obj_create(parent);
380 lv_obj_remove_style_all(obj);
381 lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
382 if(vertical) {
383 lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN);
384 lv_obj_set_style_pad_row(obj, pad, 0);
385 }
386 else {
387 lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_ROW);
388 lv_obj_set_style_pad_column(obj, pad, 0);
389 }
390 lv_obj_set_flex_align(obj, LV_FLEX_ALIGN_START, align_cross_place, align_cross_place);
391 return obj;
392 }
393
lv_demo_high_res_label_bind_temperature(lv_obj_t * label,lv_subject_t * subject,lv_demo_high_res_ctx_t * c)394 void lv_demo_high_res_label_bind_temperature(lv_obj_t * label, lv_subject_t * subject, lv_demo_high_res_ctx_t * c)
395 {
396 lv_obj_set_user_data(label, c);
397 lv_subject_add_observer_obj(subject, label_text_temperature_cb, label, subject);
398 lv_subject_add_observer_obj(&c->temperature_units_are_celsius, label_text_temperature_cb, label, subject);
399 }
400
lv_demo_high_res_theme_observer_image_src_cb(lv_observer_t * observer,lv_subject_t * subject)401 void lv_demo_high_res_theme_observer_image_src_cb(lv_observer_t * observer, lv_subject_t * subject)
402 {
403 lv_obj_t * obj = lv_observer_get_target_obj(observer);
404 lv_image_dsc_t ** pair = lv_observer_get_user_data(observer);
405
406 const lv_demo_high_res_theme_t * th = lv_subject_get_pointer(subject);
407
408 if(th == &lv_demo_high_res_theme_light) {
409 lv_image_set_src(obj, pair[0]);
410 }
411 else {
412 lv_image_set_src(obj, pair[1]);
413 }
414 }
415
lv_demo_high_res_theme_observer_obj_bg_image_src_cb(lv_observer_t * observer,lv_subject_t * subject)416 void lv_demo_high_res_theme_observer_obj_bg_image_src_cb(lv_observer_t * observer, lv_subject_t * subject)
417 {
418 lv_obj_t * obj = lv_observer_get_target_obj(observer);
419 lv_image_dsc_t ** pair = lv_observer_get_user_data(observer);
420
421 const lv_demo_high_res_theme_t * th = lv_subject_get_pointer(subject);
422
423 if(th == &lv_demo_high_res_theme_light) {
424 lv_obj_set_style_bg_image_src(obj, pair[0], 0);
425 }
426 else {
427 lv_obj_set_style_bg_image_src(obj, pair[1], 0);
428 }
429 }
430
lv_demo_high_res_image_preload(const void * src,lv_color_format_t cf,int32_t scale)431 lv_image_dsc_t * lv_demo_high_res_image_preload(const void * src, lv_color_format_t cf, int32_t scale)
432 {
433 lv_image_header_t header;
434 lv_result_t res = lv_image_decoder_get_info(src, &header);
435 if(res == LV_RESULT_INVALID) {
436 LV_LOG_WARN("Couldn't read the header info of source");
437 return NULL;
438 }
439
440 lv_draw_buf_t * dest;
441 int32_t dest_w = header.w * scale / 256;
442 int32_t dest_h = header.h * scale / 256;
443 dest = lv_draw_buf_create(dest_w, dest_h, cf, LV_STRIDE_AUTO);
444
445 lv_obj_t * canvas = lv_canvas_create(lv_screen_active());
446 lv_canvas_set_draw_buf(canvas, dest);
447 lv_canvas_fill_bg(canvas, lv_color_hex3(0x000), LV_OPA_TRANSP);
448
449 lv_layer_t layer;
450 lv_canvas_init_layer(canvas, &layer);
451
452 lv_draw_image_dsc_t dsc;
453 lv_draw_image_dsc_init(&dsc);
454 dsc.src = src;
455 dsc.scale_x = scale;
456 dsc.scale_y = scale;
457
458 lv_area_t coords = {0, 0, header.w - 1, header.h - 1};
459 lv_draw_image(&layer, &dsc, &coords);
460 lv_canvas_finish_layer(canvas, &layer);
461
462 lv_obj_delete(canvas);
463
464 return (lv_image_dsc_t *) dest;
465 }
466
467 /**********************
468 * STATIC FUNCTIONS
469 **********************/
470
init_fonts_sm(lv_style_t * fonts)471 static void init_fonts_sm(lv_style_t * fonts)
472 {
473 lv_style_set_text_font(&fonts[FONT_HEADING_MD], &font_lv_demo_high_res_roboto_slab_regular_20);
474 lv_style_set_text_font(&fonts[FONT_HEADING_LG], &font_lv_demo_high_res_roboto_slab_regular_40);
475 lv_style_set_text_font(&fonts[FONT_HEADING_XL], &font_lv_demo_high_res_roboto_slab_light_80);
476 lv_style_set_text_font(&fonts[FONT_HEADING_XXL], &font_lv_demo_high_res_roboto_slab_light_107);
477 lv_style_set_text_font(&fonts[FONT_LABEL_XS], &font_lv_demo_high_res_roboto_medium_8);
478 lv_style_set_text_line_space(&fonts[FONT_LABEL_XS],
479 30 * lv_font_get_line_height(&font_lv_demo_high_res_roboto_medium_8) / 100); /* +30% */
480 /* lv_style_set_text_letter_space(&fonts[FONT_LABEL_XS], 197 * lv_font_get_letter_space(&font_lv_demo_high_res_roboto_medium_8) / 200); */ /* -1.5% */
481 lv_style_set_text_font(&fonts[FONT_LABEL_SM], &font_lv_demo_high_res_roboto_medium_11);
482 lv_style_set_text_font(&fonts[FONT_LABEL_MD], &font_lv_demo_high_res_roboto_medium_16);
483 lv_style_set_text_font(&fonts[FONT_LABEL_LG], &font_lv_demo_high_res_roboto_slab_bold_20);
484 lv_style_set_text_font(&fonts[FONT_LABEL_XL], &font_lv_demo_high_res_roboto_slab_bold_24);
485 lv_style_set_text_font(&fonts[FONT_LABEL_2XL], &font_lv_demo_high_res_roboto_slab_bold_40);
486 }
487
init_fonts_md(lv_style_t * fonts)488 static void init_fonts_md(lv_style_t * fonts)
489 {
490 lv_style_set_text_font(&fonts[FONT_HEADING_MD], &font_lv_demo_high_res_roboto_slab_regular_30);
491 lv_style_set_text_font(&fonts[FONT_HEADING_LG], &font_lv_demo_high_res_roboto_slab_regular_60);
492 lv_style_set_text_font(&fonts[FONT_HEADING_XL], &font_lv_demo_high_res_roboto_slab_light_120);
493 lv_style_set_text_font(&fonts[FONT_HEADING_XXL], &font_lv_demo_high_res_roboto_slab_light_160);
494 lv_style_set_text_font(&fonts[FONT_LABEL_XS], &font_lv_demo_high_res_roboto_medium_12);
495 lv_style_set_text_line_space(&fonts[FONT_LABEL_XS],
496 30 * lv_font_get_line_height(&font_lv_demo_high_res_roboto_medium_12) / 100); /* +30% */
497 /* lv_style_set_text_letter_space(&fonts[FONT_LABEL_XS], 197 * lv_font_get_letter_space(&font_lv_demo_high_res_roboto_medium_12) / 200); */ /* -1.5% */
498 lv_style_set_text_font(&fonts[FONT_LABEL_SM], &font_lv_demo_high_res_roboto_medium_16);
499 lv_style_set_text_font(&fonts[FONT_LABEL_MD], &font_lv_demo_high_res_roboto_medium_24);
500 lv_style_set_text_font(&fonts[FONT_LABEL_LG], &font_lv_demo_high_res_roboto_slab_bold_30);
501 lv_style_set_text_font(&fonts[FONT_LABEL_XL], &font_lv_demo_high_res_roboto_slab_bold_36);
502 lv_style_set_text_font(&fonts[FONT_LABEL_2XL], &font_lv_demo_high_res_roboto_slab_bold_60);
503 }
504
init_fonts_lg(lv_style_t * fonts)505 static void init_fonts_lg(lv_style_t * fonts)
506 {
507 lv_style_set_text_font(&fonts[FONT_HEADING_MD], &font_lv_demo_high_res_roboto_slab_regular_45);
508 lv_style_set_text_font(&fonts[FONT_HEADING_LG], &font_lv_demo_high_res_roboto_slab_regular_90);
509 lv_style_set_text_font(&fonts[FONT_HEADING_XL], &font_lv_demo_high_res_roboto_slab_light_180);
510 lv_style_set_text_font(&fonts[FONT_HEADING_XXL], &font_lv_demo_high_res_roboto_slab_light_240);
511 lv_style_set_text_font(&fonts[FONT_LABEL_XS], &font_lv_demo_high_res_roboto_medium_18);
512 lv_style_set_text_line_space(&fonts[FONT_LABEL_XS],
513 30 * lv_font_get_line_height(&font_lv_demo_high_res_roboto_medium_18) / 100); /* +30% */
514 /* lv_style_set_text_letter_space(&fonts[FONT_LABEL_XS], 197 * lv_font_get_letter_space(&font_lv_demo_high_res_roboto_medium_18) / 200); */ /* -1.5% */
515 lv_style_set_text_font(&fonts[FONT_LABEL_SM], &font_lv_demo_high_res_roboto_medium_24);
516 lv_style_set_text_font(&fonts[FONT_LABEL_MD], &font_lv_demo_high_res_roboto_medium_36);
517 lv_style_set_text_font(&fonts[FONT_LABEL_LG], &font_lv_demo_high_res_roboto_slab_bold_45);
518 lv_style_set_text_font(&fonts[FONT_LABEL_XL], &font_lv_demo_high_res_roboto_slab_bold_54);
519 lv_style_set_text_font(&fonts[FONT_LABEL_2XL], &font_lv_demo_high_res_roboto_slab_bold_90);
520 }
521
theme_observer_cb(lv_observer_t * observer,lv_subject_t * subject)522 static void theme_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
523 {
524 const lv_demo_high_res_theme_t * th = lv_subject_get_pointer(subject);
525 const lv_demo_high_res_theme_t * th_other = th == &lv_demo_high_res_theme_light ? &lv_demo_high_res_theme_dark :
526 &lv_demo_high_res_theme_light;
527 lv_demo_high_res_ctx_t * c = lv_observer_get_user_data(observer);
528
529 for(uint32_t i = 0; i < STYLE_COLOR_COUNT; i++) {
530 lv_color_t color = i == STYLE_COLOR_BASE ? th->base : th->accent;
531 lv_color_t color_inv = i == STYLE_COLOR_ACCENT ? th->accent : th_other->base;
532
533 lv_style_set_bg_color(&c->styles[i][STYLE_TYPE_OBJ], color);
534 lv_style_set_outline_color(&c->styles[i][STYLE_TYPE_OBJ], color);
535
536 lv_style_set_text_color(&c->styles[i][STYLE_TYPE_TEXT], color_inv);
537 lv_style_set_line_color(&c->styles[i][STYLE_TYPE_TEXT], color_inv);
538
539 lv_style_set_image_recolor_opa(&c->styles[i][STYLE_TYPE_A8_IMG], LV_OPA_COVER);
540 lv_style_set_image_recolor(&c->styles[i][STYLE_TYPE_A8_IMG], color_inv);
541 }
542
543 for(uint32_t i = 0; i < STYLE_COLOR_COUNT; i++) {
544 for(uint32_t j = 0; j < STYLE_TYPE_COUNT; j++) {
545 lv_obj_report_style_change(&c->styles[i][j]);
546 }
547 }
548 }
549
free_ctx_event_cb(lv_event_t * e)550 static void free_ctx_event_cb(lv_event_t * e)
551 {
552 lv_obj_t * base_obj = lv_event_get_target_obj(e);
553 lv_demo_high_res_ctx_t * c = lv_obj_get_user_data(base_obj);
554
555 lv_subject_deinit(&c->th);
556
557 for(uint32_t i = 0; i < IMG_COUNT; i++) {
558 lv_draw_buf_destroy((lv_draw_buf_t *)c->imgs[i]);
559 }
560
561 for(uint32_t i = 0; i < STYLE_COLOR_COUNT; i++) {
562 for(uint32_t j = 0; j < STYLE_TYPE_COUNT; j++) {
563 lv_style_reset(&c->styles[i][j]);
564 }
565 }
566
567 for(uint32_t i = 0; i < FONT_COUNT; i++) {
568 lv_style_reset(&c->fonts[i]);
569 }
570
571 lv_free(c->logo_path);
572 lv_free(c->slides_path);
573
574 lv_subject_deinit(&c->temperature_units_are_celsius);
575 lv_subject_deinit(&c->ev_charging_progress);
576 lv_subject_deinit(&c->smart_meter_selected_bar);
577
578 lv_demo_high_res_top_margin_deinit_subjects(c);
579
580 lv_subject_deinit(&c->subject_groups.time.group);
581 lv_subject_deinit(&c->subject_groups.date.group);
582 lv_subject_deinit(&c->subject_groups.wifi.group);
583
584 lv_subject_t * subjects = (lv_subject_t *) &c->api.subjects;
585 for(uint32_t i = 0; i < sizeof(c->api.subjects) / sizeof(lv_subject_t); i++) {
586 lv_subject_deinit(&subjects[i]);
587 }
588
589 uint32_t about_slides_count = lv_array_size(&c->about_slides_array);
590 for(uint32_t i = 0; i < about_slides_count; i++) {
591 lv_image_dsc_t ** slide = lv_array_at(&c->about_slides_array, i);
592 lv_draw_buf_destroy((lv_draw_buf_t *) *slide);
593 }
594 lv_array_deinit(&c->about_slides_array);
595
596 lv_free(c);
597
598 lv_obj_set_user_data(base_obj, NULL);
599 }
600
label_text_temperature_cb(lv_observer_t * observer,lv_subject_t * subject)601 static void label_text_temperature_cb(lv_observer_t * observer, lv_subject_t * subject)
602 {
603 LV_UNUSED(subject);
604 lv_subject_t * temperature_subject = lv_observer_get_user_data(observer);
605 int32_t val = lv_subject_get_int(temperature_subject);
606 lv_obj_t * label = lv_observer_get_target_obj(observer);
607 lv_demo_high_res_ctx_t * c = lv_obj_get_user_data(label);
608
609 if(!lv_subject_get_int(&c->temperature_units_are_celsius)) {
610 /* convert to fahrenheit */
611 /* + 320 instead of 32 because temperatures in are tenths of a degree */
612 val = val * 9 / 5 + 320;
613 }
614
615 int32_t full = val / 10;
616 int32_t fraction = val % 10;
617 char buf[16];
618 if(fraction) {
619 lv_snprintf(buf, sizeof(buf), "%"PRId32".%"PRId32"\xc2\xb0", full, fraction);
620 }
621 else {
622 lv_snprintf(buf, sizeof(buf), "%"PRId32"\xc2\xb0", full);
623 }
624
625 lv_label_set_text(label, buf);
626 }
627
628 #endif /*LV_USE_DEMO_HIGH_RES*/
629