1 /**
2  * @file lv_theme.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "lv_theme.h"
10 #include "../lv_core/lv_obj.h"
11 
12 /*********************
13  *      DEFINES
14  *********************/
15 
16 /**********************
17  *      TYPEDEFS
18  **********************/
19 
20 /**********************
21  *  STATIC PROTOTYPES
22  **********************/
23 
24 /**********************
25  *  STATIC VARIABLES
26  **********************/
27 
28 #if LV_THEME_LIVE_UPDATE == 0
29 static lv_theme_t * current_theme;
30 #else
31 /* If live update is used then a big `lv_style_t` array is used to store the real styles of the
32  * theme not only pointers. On `lv_theme_set_current` the styles of the theme are copied to this
33  * array. The pointers in `current_theme` are initialized to point to the styles in the array. This
34  * way the theme styles will always point to the same memory address even after theme is change.
35  * (The pointers in the theme points to the styles declared by the theme itself) */
36 
37 /* Store the styles in this array. */
38 static lv_style_t th_styles[LV_THEME_STYLE_COUNT];
39 static bool inited = false;
40 static lv_theme_t current_theme;
41 #endif
42 
43 /**********************
44  *      MACROS
45  **********************/
46 
47 /**********************
48  *   GLOBAL FUNCTIONS
49  **********************/
50 
51 /**
52  * Set a theme for the system.
53  * From now, all the created objects will use styles from this theme by default
54  * @param th pointer to theme (return value of: 'lv_theme_init_xxx()')
55  */
lv_theme_set_current(lv_theme_t * th)56 void lv_theme_set_current(lv_theme_t * th)
57 {
58 #if LV_THEME_LIVE_UPDATE == 0
59     current_theme = th;
60 
61 #if LV_USE_GROUP
62     /*Copy group style modification callback functions*/
63     memcpy(&current_theme->group, &th->group, sizeof(th->group));
64 #endif
65 
66     /*Let the object know their style might change*/
67     lv_obj_report_style_mod(NULL);
68 
69 #else
70     uint32_t style_num = sizeof(th->style) / sizeof(lv_style_t *); /*Number of styles in a theme*/
71 
72     if(!inited) {
73         /*Initialize the style pointers `current_theme` to point to the `th_styles` style array */
74         uint16_t i;
75         lv_style_t ** cur_th_style_p = (lv_style_t **)&current_theme.style;
76         for(i = 0; i < style_num; i++) {
77             uintptr_t adr = (uintptr_t)&th_styles[i];
78             memcpy(&cur_th_style_p[i], &adr, sizeof(lv_style_t *));
79         }
80         inited = true;
81     }
82 
83     /*Copy the styles pointed by the new theme to the `th_styles` style array*/
84     uint16_t i;
85     lv_style_t ** th_style = (lv_style_t **)&th->style;
86     for(i = 0; i < style_num; i++) {
87         uintptr_t s = (uintptr_t)th_style[i];
88         if(s) memcpy(&th_styles[i], (void *)s, sizeof(lv_style_t));
89     }
90 
91 #if LV_USE_GROUP
92     /*Copy group style modification callback functions*/
93     memcpy(&current_theme.group, &th->group, sizeof(th->group));
94 #endif
95 
96     /*Let the object know their style might change*/
97     lv_obj_report_style_mod(NULL);
98 
99 #endif
100 
101 #if LV_USE_GROUP
102     lv_group_report_style_mod(NULL);
103 #endif
104 }
105 
106 /**
107  * Get the current system theme.
108  * @return pointer to the current system theme. NULL if not set.
109  */
lv_theme_get_current(void)110 lv_theme_t * lv_theme_get_current(void)
111 {
112 #if LV_THEME_LIVE_UPDATE == 0
113     return current_theme;
114 #else
115     if(!inited)
116         return NULL;
117     else
118         return &current_theme;
119 #endif
120 }
121 
122 /**********************
123  *   STATIC FUNCTIONS
124  **********************/
125