/** * @file lv_demo_high_res_util.c * */ /********************* * INCLUDES *********************/ #include "lv_demo_high_res_private.h" #if LV_USE_DEMO_HIGH_RES #include "../../src/widgets/image/lv_image.h" #include "../../src/widgets/canvas/lv_canvas.h" #include "../../src/widgets/label/lv_label.h" /********************* * DEFINES *********************/ /********************** * TYPEDEFS **********************/ LV_FONT_DECLARE(font_lv_demo_high_res_roboto_medium_12) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_medium_16) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_medium_24) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_30) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_36) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_60) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_light_120) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_light_160) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_regular_30) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_regular_60) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_regular_20) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_regular_40) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_regular_45) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_regular_90) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_light_80) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_light_107) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_light_180) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_light_240) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_medium_8) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_medium_11) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_medium_18) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_medium_36) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_20) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_24) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_40) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_45) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_54) LV_FONT_DECLARE(font_lv_demo_high_res_roboto_slab_bold_90) /********************** * STATIC PROTOTYPES **********************/ static void init_fonts_sm(lv_style_t * fonts); static void init_fonts_md(lv_style_t * fonts); static void init_fonts_lg(lv_style_t * fonts); static void theme_observer_cb(lv_observer_t * observer, lv_subject_t * subject); static void free_ctx_event_cb(lv_event_t * e); static void label_text_temperature_cb(lv_observer_t * observer, lv_subject_t * subject); /********************** * STATIC PROTOTYPES **********************/ /********************** * STATIC VARIABLES **********************/ const lv_demo_high_res_theme_t lv_demo_high_res_theme_light = { .base = LV_COLOR_MAKE(0xff, 0xff, 0xff), .accent = LV_COLOR_MAKE(0xcc, 0x00, 0x00), }; const lv_demo_high_res_theme_t lv_demo_high_res_theme_dark = { .base = LV_COLOR_MAKE(0x00, 0x00, 0x00), .accent = LV_COLOR_MAKE(0xe1, 0x2b, 0x17), }; const lv_demo_high_res_sizes_t lv_demo_high_res_sizes_all[SIZE_COUNT] = { { .gap = {0, 2, 4, 6, 9, 12, 14, 16, 20, 24, 32}, .icon = {16, 21, 32, 42, 64}, .card_long_edge = 200, .widget_long_edge = 256, .card_short_edge = 120, .smart_home_arc_diameter = 107, .ev_charging_arc_diameter = 160, .smart_meter_collapsed_part_height = 48, .slider_width = 27, .small_chart_height = 67, .large_chart_height = 167, .card_radius = 12, .health_panel_width = 133, .settings_panel_width = 179, .home_bottom_margin_height = 53, .init_fonts_cb = init_fonts_sm }, { .gap = {0, 3, 6, 9, 12, 16, 20, 24, 30, 36, 48}, .icon = {24, 32, 48, 64, 96}, .card_long_edge = 300, .widget_long_edge = 384, .card_short_edge = 180, .smart_home_arc_diameter = 160, .ev_charging_arc_diameter = 240, .smart_meter_collapsed_part_height = 72, .slider_width = 40, .small_chart_height = 100, .large_chart_height = 250, .card_radius = 18, .health_panel_width = 200, .settings_panel_width = 268, .home_bottom_margin_height = 80, .init_fonts_cb = init_fonts_md }, { .gap = {0, 5, 10, 15, 18, 24, 30, 36, 45, 54, 72}, .icon = {36, 48, 72, 96, 144}, .card_long_edge = 450, .widget_long_edge = 576, .card_short_edge = 270, .smart_home_arc_diameter = 240, .ev_charging_arc_diameter = 360, .smart_meter_collapsed_part_height = 108, .slider_width = 60, .small_chart_height = 150, .large_chart_height = 375, .card_radius = 27, .health_panel_width = 300, .settings_panel_width = 402, .home_bottom_margin_height = 120, .init_fonts_cb = init_fonts_lg } }; /********************** * MACROS **********************/ #define ARRAY_LEN(arr) (sizeof(arr) / sizeof(*arr)) /********************** * GLOBAL FUNCTIONS **********************/ lv_obj_t * 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) { lv_demo_high_res_ctx_t * c = lv_malloc_zeroed(sizeof(lv_demo_high_res_ctx_t)); LV_ASSERT_MALLOC(c); lv_obj_t * base_obj = lv_obj_create(lv_screen_active()); lv_obj_set_user_data(base_obj, c); lv_obj_add_event_cb(base_obj, free_ctx_event_cb, LV_EVENT_DELETE, NULL); lv_display_t * disp = lv_display_get_default(); int32_t hres = lv_display_get_horizontal_resolution(disp); int32_t vres = lv_display_get_vertical_resolution(disp); bool is_exact; int32_t size; if(hres < 1280 && vres < 720) { is_exact = hres == 800 && vres == 480; size = SIZE_SM; } else if(hres < 1920 && vres < 1080) { is_exact = hres == 1280 && vres == 720; size = SIZE_MD; } else { is_exact = hres == 1920 && vres == 1080; size = SIZE_LG; } if(!is_exact) { LV_LOG_WARN("a display size of exactly 800x480, 1280x720, or 1920x1080 is recommended for the high-res demo"); } c->sz = &lv_demo_high_res_sizes_all[size]; static const struct { const char * name; lv_color_format_t cf; } image_details[IMG_COUNT] = { {"about_app_icon", LV_COLOR_FORMAT_ARGB8888}, {"album_art", LV_COLOR_FORMAT_ARGB8888}, {"arrow_left", LV_COLOR_FORMAT_ARGB8888}, {"backward_icon", LV_COLOR_FORMAT_ARGB8888}, {"cold_icon", LV_COLOR_FORMAT_ARGB8888}, {"dry_icon", LV_COLOR_FORMAT_ARGB8888}, {"energy_icon", LV_COLOR_FORMAT_ARGB8888}, {"ev_charging_app_icon", LV_COLOR_FORMAT_ARGB8888}, {"ev_charging_widget3_1_bg", LV_COLOR_FORMAT_ARGB8888}, {"ev_charging_widget3_bg", LV_COLOR_FORMAT_ARGB8888}, {"fan", LV_COLOR_FORMAT_ARGB8888}, {"forward_icon", LV_COLOR_FORMAT_ARGB8888}, {"health_icon", LV_COLOR_FORMAT_ARGB8888}, {"health_icon_bold", LV_COLOR_FORMAT_ARGB8888}, {"heat_icon", LV_COLOR_FORMAT_ARGB8888}, {"lamp", LV_COLOR_FORMAT_ARGB8888}, {"logout_icon", LV_COLOR_FORMAT_ARGB8888}, {"main_light_slider", LV_COLOR_FORMAT_ARGB8888}, {"minus", LV_COLOR_FORMAT_ARGB8888}, {"pager_left", LV_COLOR_FORMAT_ARGB8888}, {"pager_pause", LV_COLOR_FORMAT_ARGB8888}, {"pager_play", LV_COLOR_FORMAT_ARGB8888}, {"pager_right", LV_COLOR_FORMAT_ARGB8888}, {"play_icon", LV_COLOR_FORMAT_ARGB8888}, {"play_icon_1", LV_COLOR_FORMAT_ARGB8888}, {"plus", LV_COLOR_FORMAT_ARGB8888}, {"range_icon", LV_COLOR_FORMAT_ARGB8888}, {"setting_icon", LV_COLOR_FORMAT_ARGB8888}, {"setting_icon_bold", LV_COLOR_FORMAT_ARGB8888}, {"smart_home_app_icon", LV_COLOR_FORMAT_ARGB8888}, {"smart_home_widget1_bg", LV_COLOR_FORMAT_ARGB8888}, {"smart_home_widget2_bg", LV_COLOR_FORMAT_ARGB8888}, {"smart_meter_app_icon", LV_COLOR_FORMAT_ARGB8888}, {"thermostat_app_icon", LV_COLOR_FORMAT_ARGB8888}, {"time_icon", LV_COLOR_FORMAT_ARGB8888}, {"unlock", LV_COLOR_FORMAT_ARGB8888}, {"volume", LV_COLOR_FORMAT_ARGB8888}, {"weather", LV_COLOR_FORMAT_ARGB8888}, {"wifi_icon", LV_COLOR_FORMAT_ARGB8888}, {"light_bg_about", LV_COLOR_FORMAT_NATIVE}, {"dark_bg_about", LV_COLOR_FORMAT_NATIVE}, {"light_bg_ev_charging", LV_COLOR_FORMAT_NATIVE}, {"dark_bg_ev_charging", LV_COLOR_FORMAT_NATIVE}, {"light_bg_home", LV_COLOR_FORMAT_NATIVE}, {"dark_bg_home", LV_COLOR_FORMAT_NATIVE}, {"light_bg_smart_home", LV_COLOR_FORMAT_NATIVE}, {"dark_bg_smart_home", LV_COLOR_FORMAT_NATIVE}, {"light_bg_smart_meter", LV_COLOR_FORMAT_NATIVE}, {"dark_bg_smart_meter", LV_COLOR_FORMAT_NATIVE}, {"light_bg_thermostat", LV_COLOR_FORMAT_NATIVE}, {"dark_bg_thermostat", LV_COLOR_FORMAT_NATIVE}, {"light_dark_theme_icon", LV_COLOR_FORMAT_ARGB8888}, {"dark_dark_theme_icon", LV_COLOR_FORMAT_ARGB8888}, {"light_light_theme_icon", LV_COLOR_FORMAT_ARGB8888}, {"dark_light_theme_icon", LV_COLOR_FORMAT_ARGB8888}, {"light_widget1_bg", LV_COLOR_FORMAT_ARGB8888}, {"dark_widget1_bg", LV_COLOR_FORMAT_ARGB8888}, {"light_widget2_bg", LV_COLOR_FORMAT_ARGB8888}, {"dark_widget2_bg", LV_COLOR_FORMAT_ARGB8888}, {"light_widget3_bg", LV_COLOR_FORMAT_ARGB8888}, {"dark_widget3_bg", LV_COLOR_FORMAT_ARGB8888}, {"light_widget4_bg", LV_COLOR_FORMAT_ARGB8888}, {"dark_widget4_bg", LV_COLOR_FORMAT_ARGB8888}, {"light_widget5_bg", LV_COLOR_FORMAT_ARGB8888}, {"dark_widget5_bg", LV_COLOR_FORMAT_ARGB8888}, }; const char * size_prefix = size == SIZE_SM ? "sm" : size == SIZE_MD ? "md" : "lg"; for(uint32_t i = 0; i < IMG_COUNT; i++) { char path_buf[256]; int chars = lv_snprintf(path_buf, sizeof(path_buf), "%s/img_lv_demo_high_res_%s_%s.png", assets_path, image_details[i].name, size_prefix); LV_ASSERT(chars < (int)sizeof(path_buf)); c->imgs[i] = lv_demo_high_res_image_preload(path_buf, image_details[i].cf, LV_SCALE_NONE); } for(uint32_t i = 0; i < STYLE_COLOR_COUNT; i++) { for(uint32_t j = 0; j < STYLE_TYPE_COUNT; j++) { lv_style_init(&c->styles[i][j]); } } for(uint32_t i = 0; i < FONT_COUNT; i++) { lv_style_init(&c->fonts[i]); } c->sz->init_fonts_cb(c->fonts); lv_subject_init_pointer(&c->th, (void *)&lv_demo_high_res_theme_dark); c->th.user_data = c; lv_subject_add_observer(&c->th, theme_observer_cb, c); c->logo_path = lv_strdup(logo_path); LV_ASSERT_MALLOC(c->logo_path); c->slides_path = lv_strdup(slides_path); LV_ASSERT_MALLOC(c->slides_path); c->exit_cb = exit_cb; lv_subject_init_int(&c->temperature_units_are_celsius, 1); c->ev_charging_bg_cont = NULL; lv_subject_init_int(&c->ev_charging_progress, EV_CHARGING_RANGE_END * 0 / 100); lv_subject_init_int(&c->smart_meter_selected_bar, 4); c->top_margin_subjects_are_init = false; /* API subjects */ /* input subjects */ lv_subject_init_int(&c->api.subjects.hour, 9); lv_subject_init_int(&c->api.subjects.minute, 36); lv_subject_init_pointer(&c->api.subjects.week_day_name, "Tuesday"); lv_subject_init_int(&c->api.subjects.month_day, 31); lv_subject_init_pointer(&c->api.subjects.month_name, "October"); lv_subject_init_int(&c->api.subjects.temperature_outdoor, 140); /* tenths of a degree */ lv_subject_init_int(&c->api.subjects.temperature_indoor, 225); /* tenths of a degree */ lv_subject_init_pointer(&c->api.subjects.wifi_ssid, NULL); lv_subject_init_pointer(&c->api.subjects.wifi_ip, NULL); /* output subjects */ lv_subject_init_int(&c->api.subjects.music_play, 1); /* input+output subjects */ lv_subject_init_int(&c->api.subjects.locked, 0); lv_subject_init_int(&c->api.subjects.volume, 63); lv_subject_init_int(&c->api.subjects.main_light_temperature, 4000); lv_subject_init_int(&c->api.subjects.main_light_intensity, 52); lv_subject_init_int(&c->api.subjects.thermostat_fan_speed, 40); lv_subject_init_int(&c->api.subjects.thermostat_target_temperature, 240); /* tenths of a degree */ c->api.base_obj = base_obj; c->api.user_data = NULL; c->subject_groups.time.members[0] = &c->api.subjects.hour; c->subject_groups.time.members[1] = &c->api.subjects.minute; lv_subject_init_group(&c->subject_groups.time.group, c->subject_groups.time.members, ARRAY_LEN(c->subject_groups.time.members)); c->subject_groups.date.members[0] = &c->api.subjects.week_day_name; c->subject_groups.date.members[1] = &c->api.subjects.month_day; c->subject_groups.date.members[2] = &c->api.subjects.month_name; lv_subject_init_group(&c->subject_groups.date.group, c->subject_groups.date.members, ARRAY_LEN(c->subject_groups.date.members)); c->subject_groups.wifi.members[0] = &c->api.subjects.wifi_ssid; c->subject_groups.wifi.members[1] = &c->api.subjects.wifi_ip; lv_subject_init_group(&c->subject_groups.wifi.group, c->subject_groups.wifi.members, ARRAY_LEN(c->subject_groups.wifi.members)); lv_array_init(&c->about_slides_array, 1, sizeof(lv_image_dsc_t *)); lv_fs_dir_t dir; lv_fs_res_t fs_res = lv_fs_dir_open(&dir, slides_path); if(fs_res == LV_FS_RES_OK) { fs_res = lv_fs_dir_close(&dir); LV_ASSERT(fs_res == LV_FS_RES_OK); c->about_slides_dir_exists = true; for(int32_t i = 1; ; i++) { char buf[256]; lv_snprintf(buf, sizeof(buf), "%s/Slide%"LV_PRId32".png", slides_path, i); lv_fs_file_t file; fs_res = lv_fs_open(&file, buf, LV_FS_MODE_RD); if(fs_res != LV_FS_RES_OK) { break; } fs_res = lv_fs_close(&file); LV_ASSERT(fs_res == LV_FS_RES_OK); lv_image_header_t header; lv_result_t res = lv_image_decoder_get_info(buf, &header); if(res == LV_RESULT_INVALID) { LV_LOG_WARN("Couldn't read the header info of slide image"); continue; } /* the ratio of a slide's height to the display's height will be 9:16 */ int32_t scale = (9 * 256 * vres) / (16 * header.h); lv_image_dsc_t * loaded_draw_buf = lv_demo_high_res_image_preload(buf, LV_COLOR_FORMAT_NATIVE, scale); if(loaded_draw_buf == NULL) continue; lv_array_push_back(&c->about_slides_array, &loaded_draw_buf); if(scale != LV_SCALE_NONE) LV_LOG_INFO("A slide was scaled by %"LV_PRId32" (256 means 1:1)", scale); } } return base_obj; } lv_obj_t * lv_demo_high_res_simple_container_create(lv_obj_t * parent, bool vertical, int32_t pad, lv_flex_align_t align_cross_place) { lv_obj_t * obj = lv_obj_create(parent); lv_obj_remove_style_all(obj); lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); if(vertical) { lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN); lv_obj_set_style_pad_row(obj, pad, 0); } else { lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_ROW); lv_obj_set_style_pad_column(obj, pad, 0); } lv_obj_set_flex_align(obj, LV_FLEX_ALIGN_START, align_cross_place, align_cross_place); return obj; } void lv_demo_high_res_label_bind_temperature(lv_obj_t * label, lv_subject_t * subject, lv_demo_high_res_ctx_t * c) { lv_obj_set_user_data(label, c); lv_subject_add_observer_obj(subject, label_text_temperature_cb, label, subject); lv_subject_add_observer_obj(&c->temperature_units_are_celsius, label_text_temperature_cb, label, subject); } void lv_demo_high_res_theme_observer_image_src_cb(lv_observer_t * observer, lv_subject_t * subject) { lv_obj_t * obj = lv_observer_get_target_obj(observer); lv_image_dsc_t ** pair = lv_observer_get_user_data(observer); const lv_demo_high_res_theme_t * th = lv_subject_get_pointer(subject); if(th == &lv_demo_high_res_theme_light) { lv_image_set_src(obj, pair[0]); } else { lv_image_set_src(obj, pair[1]); } } void lv_demo_high_res_theme_observer_obj_bg_image_src_cb(lv_observer_t * observer, lv_subject_t * subject) { lv_obj_t * obj = lv_observer_get_target_obj(observer); lv_image_dsc_t ** pair = lv_observer_get_user_data(observer); const lv_demo_high_res_theme_t * th = lv_subject_get_pointer(subject); if(th == &lv_demo_high_res_theme_light) { lv_obj_set_style_bg_image_src(obj, pair[0], 0); } else { lv_obj_set_style_bg_image_src(obj, pair[1], 0); } } lv_image_dsc_t * lv_demo_high_res_image_preload(const void * src, lv_color_format_t cf, int32_t scale) { lv_image_header_t header; lv_result_t res = lv_image_decoder_get_info(src, &header); if(res == LV_RESULT_INVALID) { LV_LOG_WARN("Couldn't read the header info of source"); return NULL; } lv_draw_buf_t * dest; int32_t dest_w = header.w * scale / 256; int32_t dest_h = header.h * scale / 256; dest = lv_draw_buf_create(dest_w, dest_h, cf, LV_STRIDE_AUTO); lv_obj_t * canvas = lv_canvas_create(lv_screen_active()); lv_canvas_set_draw_buf(canvas, dest); lv_canvas_fill_bg(canvas, lv_color_hex3(0x000), LV_OPA_TRANSP); lv_layer_t layer; lv_canvas_init_layer(canvas, &layer); lv_draw_image_dsc_t dsc; lv_draw_image_dsc_init(&dsc); dsc.src = src; dsc.scale_x = scale; dsc.scale_y = scale; lv_area_t coords = {0, 0, header.w - 1, header.h - 1}; lv_draw_image(&layer, &dsc, &coords); lv_canvas_finish_layer(canvas, &layer); lv_obj_delete(canvas); return (lv_image_dsc_t *) dest; } /********************** * STATIC FUNCTIONS **********************/ static void init_fonts_sm(lv_style_t * fonts) { lv_style_set_text_font(&fonts[FONT_HEADING_MD], &font_lv_demo_high_res_roboto_slab_regular_20); lv_style_set_text_font(&fonts[FONT_HEADING_LG], &font_lv_demo_high_res_roboto_slab_regular_40); lv_style_set_text_font(&fonts[FONT_HEADING_XL], &font_lv_demo_high_res_roboto_slab_light_80); lv_style_set_text_font(&fonts[FONT_HEADING_XXL], &font_lv_demo_high_res_roboto_slab_light_107); lv_style_set_text_font(&fonts[FONT_LABEL_XS], &font_lv_demo_high_res_roboto_medium_8); lv_style_set_text_line_space(&fonts[FONT_LABEL_XS], 30 * lv_font_get_line_height(&font_lv_demo_high_res_roboto_medium_8) / 100); /* +30% */ /* 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% */ lv_style_set_text_font(&fonts[FONT_LABEL_SM], &font_lv_demo_high_res_roboto_medium_11); lv_style_set_text_font(&fonts[FONT_LABEL_MD], &font_lv_demo_high_res_roboto_medium_16); lv_style_set_text_font(&fonts[FONT_LABEL_LG], &font_lv_demo_high_res_roboto_slab_bold_20); lv_style_set_text_font(&fonts[FONT_LABEL_XL], &font_lv_demo_high_res_roboto_slab_bold_24); lv_style_set_text_font(&fonts[FONT_LABEL_2XL], &font_lv_demo_high_res_roboto_slab_bold_40); } static void init_fonts_md(lv_style_t * fonts) { lv_style_set_text_font(&fonts[FONT_HEADING_MD], &font_lv_demo_high_res_roboto_slab_regular_30); lv_style_set_text_font(&fonts[FONT_HEADING_LG], &font_lv_demo_high_res_roboto_slab_regular_60); lv_style_set_text_font(&fonts[FONT_HEADING_XL], &font_lv_demo_high_res_roboto_slab_light_120); lv_style_set_text_font(&fonts[FONT_HEADING_XXL], &font_lv_demo_high_res_roboto_slab_light_160); lv_style_set_text_font(&fonts[FONT_LABEL_XS], &font_lv_demo_high_res_roboto_medium_12); lv_style_set_text_line_space(&fonts[FONT_LABEL_XS], 30 * lv_font_get_line_height(&font_lv_demo_high_res_roboto_medium_12) / 100); /* +30% */ /* 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% */ lv_style_set_text_font(&fonts[FONT_LABEL_SM], &font_lv_demo_high_res_roboto_medium_16); lv_style_set_text_font(&fonts[FONT_LABEL_MD], &font_lv_demo_high_res_roboto_medium_24); lv_style_set_text_font(&fonts[FONT_LABEL_LG], &font_lv_demo_high_res_roboto_slab_bold_30); lv_style_set_text_font(&fonts[FONT_LABEL_XL], &font_lv_demo_high_res_roboto_slab_bold_36); lv_style_set_text_font(&fonts[FONT_LABEL_2XL], &font_lv_demo_high_res_roboto_slab_bold_60); } static void init_fonts_lg(lv_style_t * fonts) { lv_style_set_text_font(&fonts[FONT_HEADING_MD], &font_lv_demo_high_res_roboto_slab_regular_45); lv_style_set_text_font(&fonts[FONT_HEADING_LG], &font_lv_demo_high_res_roboto_slab_regular_90); lv_style_set_text_font(&fonts[FONT_HEADING_XL], &font_lv_demo_high_res_roboto_slab_light_180); lv_style_set_text_font(&fonts[FONT_HEADING_XXL], &font_lv_demo_high_res_roboto_slab_light_240); lv_style_set_text_font(&fonts[FONT_LABEL_XS], &font_lv_demo_high_res_roboto_medium_18); lv_style_set_text_line_space(&fonts[FONT_LABEL_XS], 30 * lv_font_get_line_height(&font_lv_demo_high_res_roboto_medium_18) / 100); /* +30% */ /* 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% */ lv_style_set_text_font(&fonts[FONT_LABEL_SM], &font_lv_demo_high_res_roboto_medium_24); lv_style_set_text_font(&fonts[FONT_LABEL_MD], &font_lv_demo_high_res_roboto_medium_36); lv_style_set_text_font(&fonts[FONT_LABEL_LG], &font_lv_demo_high_res_roboto_slab_bold_45); lv_style_set_text_font(&fonts[FONT_LABEL_XL], &font_lv_demo_high_res_roboto_slab_bold_54); lv_style_set_text_font(&fonts[FONT_LABEL_2XL], &font_lv_demo_high_res_roboto_slab_bold_90); } static void theme_observer_cb(lv_observer_t * observer, lv_subject_t * subject) { const lv_demo_high_res_theme_t * th = lv_subject_get_pointer(subject); const lv_demo_high_res_theme_t * th_other = th == &lv_demo_high_res_theme_light ? &lv_demo_high_res_theme_dark : &lv_demo_high_res_theme_light; lv_demo_high_res_ctx_t * c = lv_observer_get_user_data(observer); for(uint32_t i = 0; i < STYLE_COLOR_COUNT; i++) { lv_color_t color = i == STYLE_COLOR_BASE ? th->base : th->accent; lv_color_t color_inv = i == STYLE_COLOR_ACCENT ? th->accent : th_other->base; lv_style_set_bg_color(&c->styles[i][STYLE_TYPE_OBJ], color); lv_style_set_outline_color(&c->styles[i][STYLE_TYPE_OBJ], color); lv_style_set_text_color(&c->styles[i][STYLE_TYPE_TEXT], color_inv); lv_style_set_line_color(&c->styles[i][STYLE_TYPE_TEXT], color_inv); lv_style_set_image_recolor_opa(&c->styles[i][STYLE_TYPE_A8_IMG], LV_OPA_COVER); lv_style_set_image_recolor(&c->styles[i][STYLE_TYPE_A8_IMG], color_inv); } for(uint32_t i = 0; i < STYLE_COLOR_COUNT; i++) { for(uint32_t j = 0; j < STYLE_TYPE_COUNT; j++) { lv_obj_report_style_change(&c->styles[i][j]); } } } static void free_ctx_event_cb(lv_event_t * e) { lv_obj_t * base_obj = lv_event_get_target_obj(e); lv_demo_high_res_ctx_t * c = lv_obj_get_user_data(base_obj); lv_subject_deinit(&c->th); for(uint32_t i = 0; i < IMG_COUNT; i++) { lv_draw_buf_destroy((lv_draw_buf_t *)c->imgs[i]); } for(uint32_t i = 0; i < STYLE_COLOR_COUNT; i++) { for(uint32_t j = 0; j < STYLE_TYPE_COUNT; j++) { lv_style_reset(&c->styles[i][j]); } } for(uint32_t i = 0; i < FONT_COUNT; i++) { lv_style_reset(&c->fonts[i]); } lv_free(c->logo_path); lv_free(c->slides_path); lv_subject_deinit(&c->temperature_units_are_celsius); lv_subject_deinit(&c->ev_charging_progress); lv_subject_deinit(&c->smart_meter_selected_bar); lv_demo_high_res_top_margin_deinit_subjects(c); lv_subject_deinit(&c->subject_groups.time.group); lv_subject_deinit(&c->subject_groups.date.group); lv_subject_deinit(&c->subject_groups.wifi.group); lv_subject_t * subjects = (lv_subject_t *) &c->api.subjects; for(uint32_t i = 0; i < sizeof(c->api.subjects) / sizeof(lv_subject_t); i++) { lv_subject_deinit(&subjects[i]); } uint32_t about_slides_count = lv_array_size(&c->about_slides_array); for(uint32_t i = 0; i < about_slides_count; i++) { lv_image_dsc_t ** slide = lv_array_at(&c->about_slides_array, i); lv_draw_buf_destroy((lv_draw_buf_t *) *slide); } lv_array_deinit(&c->about_slides_array); lv_free(c); lv_obj_set_user_data(base_obj, NULL); } static void label_text_temperature_cb(lv_observer_t * observer, lv_subject_t * subject) { LV_UNUSED(subject); lv_subject_t * temperature_subject = lv_observer_get_user_data(observer); int32_t val = lv_subject_get_int(temperature_subject); lv_obj_t * label = lv_observer_get_target_obj(observer); lv_demo_high_res_ctx_t * c = lv_obj_get_user_data(label); if(!lv_subject_get_int(&c->temperature_units_are_celsius)) { /* convert to fahrenheit */ /* + 320 instead of 32 because temperatures in are tenths of a degree */ val = val * 9 / 5 + 320; } int32_t full = val / 10; int32_t fraction = val % 10; char buf[16]; if(fraction) { lv_snprintf(buf, sizeof(buf), "%"PRId32".%"PRId32"\xc2\xb0", full, fraction); } else { lv_snprintf(buf, sizeof(buf), "%"PRId32"\xc2\xb0", full); } lv_label_set_text(label, buf); } #endif /*LV_USE_DEMO_HIGH_RES*/