1 /**
2  * @file lv_theme_simple.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "../lv_theme_private.h"
10 #include "../../../lvgl.h" /*To see all the widgets*/
11 
12 #if LV_USE_THEME_SIMPLE
13 
14 #include "lv_theme_simple.h"
15 #include "../../core/lv_global.h"
16 
17 /*********************
18  *      DEFINES
19  *********************/
20 
21 struct _my_theme_t;
22 typedef struct _my_theme_t my_theme_t;
23 
24 #define theme_def (*(my_theme_t **)(&LV_GLOBAL_DEFAULT()->theme_simple))
25 
26 #define COLOR_SCR     lv_palette_lighten(LV_PALETTE_GREY, 4)
27 #define COLOR_WHITE   lv_color_white()
28 #define COLOR_LIGHT   lv_palette_lighten(LV_PALETTE_GREY, 2)
29 #define COLOR_DARK    lv_palette_main(LV_PALETTE_GREY)
30 #define COLOR_DIM     lv_palette_darken(LV_PALETTE_GREY, 2)
31 #define SCROLLBAR_WIDTH     2
32 
33 /**********************
34  *      TYPEDEFS
35  **********************/
36 typedef struct {
37     lv_style_t scr;
38     lv_style_t transp;
39     lv_style_t white;
40     lv_style_t light;
41     lv_style_t dark;
42     lv_style_t dim;
43     lv_style_t scrollbar;
44 #if LV_USE_ARC
45     lv_style_t arc_line;
46     lv_style_t arc_knob;
47 #endif
48 #if LV_USE_TEXTAREA
49     lv_style_t ta_cursor;
50 #endif
51 } my_theme_styles_t;
52 
53 struct _my_theme_t {
54     lv_theme_t base;
55     my_theme_styles_t styles;
56     bool inited;
57 };
58 
59 /**********************
60  *  STATIC PROTOTYPES
61  **********************/
62 static void style_init_reset(lv_style_t * style);
63 static void theme_apply(lv_theme_t * th, lv_obj_t * obj);
64 
65 /**********************
66  *  STATIC VARIABLES
67  **********************/
68 
69 /**********************
70  *      MACROS
71  **********************/
72 
73 /**********************
74  *   STATIC FUNCTIONS
75  **********************/
76 
style_init(my_theme_t * theme)77 static void style_init(my_theme_t * theme)
78 {
79     style_init_reset(&theme->styles.scrollbar);
80     lv_style_set_bg_opa(&theme->styles.scrollbar, LV_OPA_COVER);
81     lv_style_set_bg_color(&theme->styles.scrollbar, COLOR_DARK);
82     lv_style_set_width(&theme->styles.scrollbar,  SCROLLBAR_WIDTH);
83 
84     style_init_reset(&theme->styles.scr);
85     lv_style_set_bg_opa(&theme->styles.scr, LV_OPA_COVER);
86     lv_style_set_bg_color(&theme->styles.scr, COLOR_SCR);
87     lv_style_set_text_color(&theme->styles.scr, COLOR_DIM);
88 
89     style_init_reset(&theme->styles.transp);
90     lv_style_set_bg_opa(&theme->styles.transp, LV_OPA_TRANSP);
91 
92     style_init_reset(&theme->styles.white);
93     lv_style_set_bg_opa(&theme->styles.white, LV_OPA_COVER);
94     lv_style_set_bg_color(&theme->styles.white, COLOR_WHITE);
95     lv_style_set_line_width(&theme->styles.white, 1);
96     lv_style_set_line_color(&theme->styles.white, COLOR_WHITE);
97     lv_style_set_arc_width(&theme->styles.white, 2);
98     lv_style_set_arc_color(&theme->styles.white, COLOR_WHITE);
99 
100     style_init_reset(&theme->styles.light);
101     lv_style_set_bg_opa(&theme->styles.light, LV_OPA_COVER);
102     lv_style_set_bg_color(&theme->styles.light, COLOR_LIGHT);
103     lv_style_set_line_width(&theme->styles.light, 1);
104     lv_style_set_line_color(&theme->styles.light, COLOR_LIGHT);
105     lv_style_set_arc_width(&theme->styles.light, 2);
106     lv_style_set_arc_color(&theme->styles.light, COLOR_LIGHT);
107 
108     style_init_reset(&theme->styles.dark);
109     lv_style_set_bg_opa(&theme->styles.dark, LV_OPA_COVER);
110     lv_style_set_bg_color(&theme->styles.dark, COLOR_DARK);
111     lv_style_set_line_width(&theme->styles.dark, 1);
112     lv_style_set_line_color(&theme->styles.dark, COLOR_DARK);
113     lv_style_set_arc_width(&theme->styles.dark, 2);
114     lv_style_set_arc_color(&theme->styles.dark, COLOR_DARK);
115 
116     style_init_reset(&theme->styles.dim);
117     lv_style_set_bg_opa(&theme->styles.dim, LV_OPA_COVER);
118     lv_style_set_bg_color(&theme->styles.dim, COLOR_DIM);
119     lv_style_set_line_width(&theme->styles.dim, 1);
120     lv_style_set_line_color(&theme->styles.dim, COLOR_DIM);
121     lv_style_set_arc_width(&theme->styles.dim, 2);
122     lv_style_set_arc_color(&theme->styles.dim, COLOR_DIM);
123 
124 #if LV_USE_ARC
125     style_init_reset(&theme->styles.arc_line);
126     lv_style_set_arc_width(&theme->styles.arc_line, 6);
127     style_init_reset(&theme->styles.arc_knob);
128     lv_style_set_pad_all(&theme->styles.arc_knob, 5);
129 #endif
130 
131 #if LV_USE_TEXTAREA
132     style_init_reset(&theme->styles.ta_cursor);
133     lv_style_set_border_side(&theme->styles.ta_cursor, LV_BORDER_SIDE_LEFT);
134     lv_style_set_border_color(&theme->styles.ta_cursor, COLOR_DIM);
135     lv_style_set_border_width(&theme->styles.ta_cursor, 2);
136     lv_style_set_bg_opa(&theme->styles.ta_cursor, LV_OPA_TRANSP);
137     lv_style_set_anim_duration(&theme->styles.ta_cursor, 500);
138 #endif
139 }
140 
141 /**********************
142  *   GLOBAL FUNCTIONS
143  **********************/
144 
lv_theme_simple_is_inited(void)145 bool lv_theme_simple_is_inited(void)
146 {
147     my_theme_t * theme = theme_def;
148     if(theme == NULL) return false;
149     return theme->inited;
150 }
151 
lv_theme_simple_get(void)152 lv_theme_t * lv_theme_simple_get(void)
153 {
154     if(!lv_theme_simple_is_inited()) {
155         return NULL;
156     }
157 
158     return (lv_theme_t *)theme_def;
159 }
160 
lv_theme_simple_deinit(void)161 void lv_theme_simple_deinit(void)
162 {
163     my_theme_t * theme = theme_def;
164     if(theme) {
165         if(theme->inited) {
166             lv_style_t * theme_styles = (lv_style_t *)(&(theme->styles));
167             uint32_t i;
168             for(i = 0; i < sizeof(my_theme_styles_t) / sizeof(lv_style_t); i++) {
169                 lv_style_reset(theme_styles + i);
170             }
171         }
172         lv_free(theme_def);
173         theme_def = NULL;
174     }
175 }
176 
lv_theme_simple_init(lv_display_t * disp)177 lv_theme_t * lv_theme_simple_init(lv_display_t * disp)
178 {
179     /*This trick is required only to avoid the garbage collection of
180      *styles' data if LVGL is used in a binding (e.g. MicroPython)
181      *In a general case styles could be in simple `static lv_style_t my_style...` variables*/
182     if(!lv_theme_simple_is_inited()) {
183         theme_def  = lv_malloc_zeroed(sizeof(my_theme_t));
184     }
185 
186     my_theme_t * theme = theme_def;
187 
188     theme->base.disp = disp;
189     theme->base.font_small = LV_FONT_DEFAULT;
190     theme->base.font_normal = LV_FONT_DEFAULT;
191     theme->base.font_large = LV_FONT_DEFAULT;
192     theme->base.apply_cb = theme_apply;
193 
194     style_init(theme);
195 
196     if(disp == NULL || lv_display_get_theme(disp) == (lv_theme_t *)theme) {
197         lv_obj_report_style_change(NULL);
198     }
199 
200     theme->inited = true;
201 
202     return (lv_theme_t *)theme_def;
203 }
204 
theme_apply(lv_theme_t * th,lv_obj_t * obj)205 static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
206 {
207     LV_UNUSED(th);
208 
209     my_theme_t * theme = theme_def;
210     lv_obj_t * parent = lv_obj_get_parent(obj);
211 
212     if(parent == NULL) {
213         lv_obj_add_style(obj, &theme->styles.scr, 0);
214         lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR);
215         return;
216     }
217 
218     if(lv_obj_check_type(obj, &lv_obj_class)) {
219 #if LV_USE_TABVIEW
220         /*Tabview content area*/
221         if(lv_obj_check_type(parent, &lv_tabview_class)) {
222             lv_obj_add_style(obj, &theme->styles.scr, 0);
223             return;
224         }
225         /*Tabview pages*/
226         else if(lv_obj_check_type(lv_obj_get_parent(parent), &lv_tabview_class)) {
227             lv_obj_add_style(obj, &theme->styles.scr, 0);
228             lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR);
229             return;
230         }
231 #endif
232 
233 #if LV_USE_WIN
234         /*Header*/
235         if(lv_obj_check_type(parent, &lv_win_class) && lv_obj_get_child(parent, 0) == obj) {
236             lv_obj_add_style(obj, &theme->styles.light, 0);
237             return;
238         }
239         /*Content*/
240         else if(lv_obj_check_type(parent, &lv_win_class) && lv_obj_get_child(parent, 1) == obj) {
241             lv_obj_add_style(obj, &theme->styles.light, 0);
242             lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR);
243             return;
244         }
245 #endif
246         lv_obj_add_style(obj, &theme->styles.white, 0);
247         lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR);
248     }
249 #if LV_USE_BUTTON
250     else if(lv_obj_check_type(obj, &lv_button_class)) {
251         lv_obj_add_style(obj, &theme->styles.dark, 0);
252     }
253 #endif
254 
255 #if LV_USE_BUTTONMATRIX
256     else if(lv_obj_check_type(obj, &lv_buttonmatrix_class)) {
257 #if LV_USE_MSGBOX
258         if(lv_obj_check_type(parent, &lv_msgbox_class)) {
259             lv_obj_add_style(obj, &theme->styles.light, LV_PART_ITEMS);
260             return;
261         }
262 #endif
263 #if LV_USE_TABVIEW
264         if(lv_obj_check_type(parent, &lv_tabview_class)) {
265             lv_obj_add_style(obj, &theme->styles.light, LV_PART_ITEMS);
266             return;
267         }
268 #endif
269         lv_obj_add_style(obj, &theme->styles.white, 0);
270         lv_obj_add_style(obj, &theme->styles.light, LV_PART_ITEMS);
271     }
272 #endif
273 
274 #if LV_USE_BAR
275     else if(lv_obj_check_type(obj, &lv_bar_class)) {
276         lv_obj_add_style(obj, &theme->styles.light, 0);
277         lv_obj_add_style(obj, &theme->styles.dark, LV_PART_INDICATOR);
278     }
279 #endif
280 
281 #if LV_USE_SLIDER
282     else if(lv_obj_check_type(obj, &lv_slider_class)) {
283         lv_obj_add_style(obj, &theme->styles.light, 0);
284         lv_obj_add_style(obj, &theme->styles.dark, LV_PART_INDICATOR);
285         lv_obj_add_style(obj, &theme->styles.dim, LV_PART_KNOB);
286     }
287 #endif
288 
289 #if LV_USE_TABLE
290     else if(lv_obj_check_type(obj, &lv_table_class)) {
291         lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR);
292         lv_obj_add_style(obj, &theme->styles.light, LV_PART_ITEMS);
293     }
294 #endif
295 
296 #if LV_USE_CHECKBOX
297     else if(lv_obj_check_type(obj, &lv_checkbox_class)) {
298         lv_obj_add_style(obj, &theme->styles.light, LV_PART_INDICATOR);
299         lv_obj_add_style(obj, &theme->styles.dark, LV_PART_INDICATOR | LV_STATE_CHECKED);
300     }
301 #endif
302 
303 #if LV_USE_SWITCH
304     else if(lv_obj_check_type(obj, &lv_switch_class)) {
305         lv_obj_add_style(obj, &theme->styles.light, 0);
306         lv_obj_add_style(obj, &theme->styles.dim, LV_PART_KNOB);
307     }
308 #endif
309 
310 #if LV_USE_CHART
311     else if(lv_obj_check_type(obj, &lv_chart_class)) {
312         lv_obj_add_style(obj, &theme->styles.white, 0);
313         lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR);
314         lv_obj_add_style(obj, &theme->styles.light, LV_PART_ITEMS);
315         lv_obj_add_style(obj, &theme->styles.dark, LV_PART_CURSOR);
316     }
317 #endif
318 
319 #if LV_USE_ROLLER
320     else if(lv_obj_check_type(obj, &lv_roller_class)) {
321         lv_obj_add_style(obj, &theme->styles.light, 0);
322         lv_obj_add_style(obj, &theme->styles.dark, LV_PART_SELECTED);
323     }
324 #endif
325 
326 #if LV_USE_DROPDOWN
327     else if(lv_obj_check_type(obj, &lv_dropdown_class)) {
328         lv_obj_add_style(obj, &theme->styles.white, 0);
329     }
330     else if(lv_obj_check_type(obj, &lv_dropdownlist_class)) {
331         lv_obj_add_style(obj, &theme->styles.white, 0);
332         lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR);
333         lv_obj_add_style(obj, &theme->styles.light, LV_PART_SELECTED);
334         lv_obj_add_style(obj, &theme->styles.dark, LV_PART_SELECTED | LV_STATE_CHECKED);
335     }
336 #endif
337 
338 #if LV_USE_ARC
339     else if(lv_obj_check_type(obj, &lv_arc_class)) {
340         lv_obj_add_style(obj, &theme->styles.light, 0);
341         lv_obj_add_style(obj, &theme->styles.transp, 0);
342         lv_obj_add_style(obj, &theme->styles.arc_line, 0);
343         lv_obj_add_style(obj, &theme->styles.dark, LV_PART_INDICATOR);
344         lv_obj_add_style(obj, &theme->styles.arc_line, LV_PART_INDICATOR);
345         lv_obj_add_style(obj, &theme->styles.dim, LV_PART_KNOB);
346         lv_obj_add_style(obj, &theme->styles.arc_knob, LV_PART_KNOB);
347     }
348 #endif
349 
350 #if LV_USE_SPINNER
351     else if(lv_obj_check_type(obj, &lv_spinner_class)) {
352         lv_obj_add_style(obj, &theme->styles.light, 0);
353         lv_obj_add_style(obj, &theme->styles.transp, 0);
354         lv_obj_add_style(obj, &theme->styles.arc_line, 0);
355         lv_obj_add_style(obj, &theme->styles.dark, LV_PART_INDICATOR);
356         lv_obj_add_style(obj, &theme->styles.arc_line, LV_PART_INDICATOR);
357     }
358 #endif
359 
360 #if LV_USE_TEXTAREA
361     else if(lv_obj_check_type(obj, &lv_textarea_class)) {
362         lv_obj_add_style(obj, &theme->styles.white, 0);
363         lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR);
364         lv_obj_add_style(obj, &theme->styles.ta_cursor, LV_PART_CURSOR | LV_STATE_FOCUSED);
365     }
366 #endif
367 
368 #if LV_USE_CALENDAR
369     else if(lv_obj_check_type(obj, &lv_calendar_class)) {
370         lv_obj_add_style(obj, &theme->styles.light, 0);
371     }
372 #endif
373 
374 #if LV_USE_KEYBOARD
375     else if(lv_obj_check_type(obj, &lv_keyboard_class)) {
376         lv_obj_add_style(obj, &theme->styles.scr, 0);
377         lv_obj_add_style(obj, &theme->styles.white, LV_PART_ITEMS);
378         lv_obj_add_style(obj, &theme->styles.light, LV_PART_ITEMS | LV_STATE_CHECKED);
379     }
380 #endif
381 #if LV_USE_LIST
382     else if(lv_obj_check_type(obj, &lv_list_class)) {
383         lv_obj_add_style(obj, &theme->styles.light, 0);
384         lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR);
385         return;
386     }
387     else if(lv_obj_check_type(obj, &lv_list_text_class)) {
388 
389     }
390     else if(lv_obj_check_type(obj, &lv_list_button_class)) {
391         lv_obj_add_style(obj, &theme->styles.dark, 0);
392 
393     }
394 #endif
395 #if LV_USE_MSGBOX
396     else if(lv_obj_check_type(obj, &lv_msgbox_class)) {
397         lv_obj_add_style(obj, &theme->styles.light, 0);
398         return;
399     }
400 #endif
401 #if LV_USE_SPINBOX
402     else if(lv_obj_check_type(obj, &lv_spinbox_class)) {
403         lv_obj_add_style(obj, &theme->styles.light, 0);
404         lv_obj_add_style(obj, &theme->styles.dark, LV_PART_CURSOR);
405     }
406 #endif
407 #if LV_USE_TILEVIEW
408     else if(lv_obj_check_type(obj, &lv_tileview_class)) {
409         lv_obj_add_style(obj, &theme->styles.scr, 0);
410         lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR);
411     }
412     else if(lv_obj_check_type(obj, &lv_tileview_tile_class)) {
413         lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR);
414     }
415 #endif
416 
417 #if LV_USE_LED
418     else if(lv_obj_check_type(obj, &lv_led_class)) {
419         lv_obj_add_style(obj, &theme->styles.light, 0);
420     }
421 #endif
422 }
423 
424 /**********************
425  *   STATIC FUNCTIONS
426  **********************/
427 
style_init_reset(lv_style_t * style)428 static void style_init_reset(lv_style_t * style)
429 {
430     if(lv_theme_simple_is_inited()) {
431         lv_style_reset(style);
432     }
433     else {
434         lv_style_init(style);
435     }
436 }
437 
438 #endif
439