Description
I would like to properly implement a custom theme for use in my projects.
I have studied the lv_theme_template.h and lv_theme_template.c
I have decided to create my own theme derived from the lv_material_theme, as I will only for now be making some minor changes to it to suite my needs.
I understand that I can just use the material theme, and then apply style changes throughout my code, but I really want to get it to work this way.
I do not want it to reside in components/lvgl/, and placed my theme files in project/main.
What MCU/Processor/Board and compiler are you using?
VSCode 1.53.0-insider, ESP32-WROOM-32E Devkit 4.0
Espressif plugin 0.5.1
ESP-IDF release/4.2
Win 10
KConfig used.
What LVGL version are you using?
LVGL 7.8.1
What do you want to achieve?
Discussed above in description.
What have you tried so far?
Copied lv_theme_material.h and lv_theme_material.c to project/main folder.
Renamed to lv_theme_test.h and lv_theme_test.c
Modified both files changing all references to theme_material to theme_test, with find - replace maintaining case.
I added the lv_theme_test.c to my main/CMakeLists.txt set(Sources)
set(SOURCES "main.c" "lv_theme_test.c")
idf_component_register(SRCS ${SOURCES}
INCLUDE_DIRS .
REQUIRES lvgl_esp32_drivers lvgl lvgl_touch lvgl_tft)
target_compile_definitions(${COMPONENT_LIB} PUBLIC -DLV_LVGL_H_INCLUDE_SIMPLE)
It would not compile as the paths are incorrect for the includes.
I modified those and it still would not compile.
I had to comment out the following code:
/* This trick is required only to avoid the garbage collection of
* styles' data if LVGL is used in a binding (e.g. Micropython)
* In a general case styles could be simple `static lv_style_t my style` variables*/
// if(!inited) {
// LV_GC_ROOT(_lv_theme_test_styles) = lv_mem_alloc(sizeof(theme_styles_t));
// styles = (theme_styles_t *)LV_GC_ROOT(_lv_theme_test_styles);
// }
As obiously _lv_theme_test_styles is not defined in lv_gc.h
/*********************
* DEFINES
*********************/
#define LV_ITERATE_ROOTS(f) \
f(lv_ll_t, _lv_task_ll) /*Linked list to store the lv_tasks*/ \
f(lv_ll_t, _lv_disp_ll) /*Linked list of screens*/ \
f(lv_ll_t, _lv_indev_ll) /*Linked list of screens*/ \
f(lv_ll_t, _lv_drv_ll) \
f(lv_ll_t, _lv_file_ll) \
f(lv_ll_t, _lv_anim_ll) \
f(lv_ll_t, _lv_group_ll) \
f(lv_ll_t, _lv_img_defoder_ll) \
f(lv_ll_t, _lv_obj_style_trans_ll) \
f(lv_img_cache_entry_t*, _lv_img_cache_array) \
f(lv_task_t*, _lv_task_act) \
f(lv_mem_buf_arr_t , _lv_mem_buf) \
f(_lv_draw_mask_saved_arr_t , _lv_draw_mask_list) \
f(void * , _lv_theme_material_styles) \
f(void * , _lv_theme_template_styles) \
f(void * , _lv_theme_mono_styles) \
f(void * , _lv_theme_empty_styles) \
f(uint8_t *, _lv_font_decompr_buf) \
I then had another look at lv_theme_template.c, noticed my mistake, and reintroduced the same code from lv_theme_template.c
lv_theme_t * lv_theme_loadassist_init(lv_color_t color_primary, lv_color_t color_secondary, uint32_t flags,
const lv_font_t * font_small, const lv_font_t * font_normal, const lv_font_t * font_subtitle,
const lv_font_t * font_title)
{
//From lv_theme_template.c as lv_theme_material.c will not compile
/* This trick is required only to avoid the garbage collection of
* styles' data if LVGL is used in a binding (e.g. Micropython)
* In a general case styles could be simple `static lv_style_t my style` variables*/
if(!inited) {
#if defined(LV_GC_INCLUDE)
LV_GC_ROOT(_lv_theme_template_styles) = lv_mem_alloc(sizeof(theme_styles_t));
styles = (theme_styles_t *)LV_GC_ROOT(_lv_theme_template_styles);
#else
styles = lv_mem_alloc(sizeof(theme_styles_t));
#endif
}
obviously this time not renaming anything.
applied the following to KConfig:
After this it worked as desired.
The real issue
Was this the correct procedure to follow, or is there a more eloquent method to apply a custom theme following proper procedures?
A problem I didn’t pick up the first time round:
As per the image above, the Kconfig will result in
LV_THEME_DEFAULT being set incorrectly:
It will be set to:
LV_THEME_DEFAULT_INIT lv_theme_template_init
I think this is by design, but now the following will always fail for a switch I use to implement changing from dark to light theme:
static void color_chg_event_cb(lv_obj_t * sw, lv_event_t e)
{
/* The next if statement will always fail, as don't know how to
fix Kconfig even at project level to make my lv_theme_test
the default theme and set the flags, and initial fonts,
as for eg. the material theme.
*/
if(LV_THEME_DEFAULT_INIT != lv_theme_test_init) return;
if(e == LV_EVENT_VALUE_CHANGED) {
uint32_t flag = LV_THEME_TEST_FLAG_LIGHT;
if(lv_switch_get_state(sw)) flag = LV_THEME_TEST_FLAG_DARK;
{
LV_THEME_DEFAULT_INIT(lv_theme_get_color_primary(), lv_theme_get_color_secondary(),
flag,
lv_theme_get_font_small(), lv_theme_get_font_normal(), lv_theme_get_font_subtitle(), lv_theme_get_font_title());
}
}
}
So I have no way of changing the theme, and my LV_THEME_DEFUALT(s) are incorrectly set to the Template Theme values.
I would ask at the same time that you help me with this, as it still falls in my scope of my question above for properly implementing a Custom Theme.
Thanking you in advance.