1 /**
2  * @file lv_obj_style.h
3  *
4  */
5 
6 #ifndef LV_OBJ_STYLE_H
7 #define LV_OBJ_STYLE_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 /*********************
14  *      INCLUDES
15  *********************/
16 #include "../misc/lv_bidi.h"
17 #include "../misc/lv_style.h"
18 #include "../misc/lv_types.h"
19 
20 /*********************
21  *      DEFINES
22  *********************/
23 
24 /**********************
25  *      TYPEDEFS
26  **********************/
27 
28 typedef enum {
29     LV_STYLE_STATE_CMP_SAME,           /**< The style properties in the 2 states are identical */
30     LV_STYLE_STATE_CMP_DIFF_REDRAW,    /**< The differences can be shown with a simple redraw */
31     LV_STYLE_STATE_CMP_DIFF_DRAW_PAD,  /**< The differences can be shown with a simple redraw */
32     LV_STYLE_STATE_CMP_DIFF_LAYOUT,    /**< The differences can be shown with a simple redraw */
33 } lv_style_state_cmp_t;
34 
35 typedef uint32_t lv_style_selector_t;
36 
37 /**********************
38  * GLOBAL PROTOTYPES
39  **********************/
40 
41 /**
42  * Add a style to an object.
43  * @param obj       pointer to an object
44  * @param style     pointer to a style to add
45  * @param selector  OR-ed value of parts and state to which the style should be added
46  *
47  * Examples:
48  * @code
49  * lv_obj_add_style(btn, &style_btn, 0); //Default button style
50  *
51  * lv_obj_add_style(btn, &btn_red, LV_STATE_PRESSED); //Overwrite only some colors to red when pressed
52  * @endcode
53  */
54 void lv_obj_add_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector);
55 
56 /**
57  * Replaces a style of an object, preserving the order of the style stack (local styles and transitions are ignored).
58  * @param obj           pointer to an object
59  * @param old_style     pointer to a style to replace.
60  * @param new_style     pointer to a style to replace the old style with.
61  * @param selector      OR-ed values of states and a part to replace only styles with matching selectors. LV_STATE_ANY and LV_PART_ANY can be used
62  *
63  * Examples:
64  * @code
65  * lv_obj_replace_style(obj, &yellow_style, &blue_style, LV_PART_ANY | LV_STATE_ANY); //Replace a specific style
66  *
67  * lv_obj_replace_style(obj, &yellow_style, &blue_style, LV_PART_MAIN | LV_STATE_PRESSED); //Replace a specific style assigned to the main part when it is pressed
68  * @endcode
69  */
70 bool lv_obj_replace_style(lv_obj_t * obj, const lv_style_t * old_style, const lv_style_t * new_style,
71                           lv_style_selector_t selector);
72 
73 /**
74  * Remove a style from an object.
75  * @param obj       pointer to an object
76  * @param style     pointer to a style to remove. Can be NULL to check only the selector
77  * @param selector  OR-ed values of states and a part to remove only styles with matching selectors. LV_STATE_ANY and LV_PART_ANY can be used
78  *
79  * Examples:
80  * @code
81  * lv_obj_remove_style(obj, &style, LV_PART_ANY | LV_STATE_ANY); //Remove a specific style
82  *
83  * lv_obj_remove_style(obj, NULL, LV_PART_MAIN | LV_STATE_ANY); //Remove all styles from the main part
84  *
85  * lv_obj_remove_style(obj, NULL, LV_PART_ANY | LV_STATE_ANY); //Remove all styles
86  * @endcode
87  */
88 void lv_obj_remove_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector);
89 
90 /**
91  * Remove all styles from an object
92  * @param obj       pointer to an object
93  */
94 void lv_obj_remove_style_all(lv_obj_t * obj);
95 
96 /**
97  * Notify all object if a style is modified
98  * @param style     pointer to a style. Only the objects with this style will be notified
99  *                  (NULL to notify all objects)
100  */
101 void lv_obj_report_style_change(lv_style_t * style);
102 
103 /**
104  * Notify an object and its children about its style is modified.
105  * @param obj       pointer to an object
106  * @param part      the part whose style was changed. E.g. `LV_PART_ANY`, `LV_PART_MAIN`
107  * @param prop      `LV_STYLE_PROP_ANY` or an `LV_STYLE_...` property.
108  *                  It is used to optimize what needs to be refreshed.
109  *                  `LV_STYLE_PROP_INV` to perform only a style cache update
110  */
111 void lv_obj_refresh_style(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop);
112 
113 /**
114  * Enable or disable automatic style refreshing when a new style is added/removed to/from an object
115  * or any other style change happens.
116  * @param en        true: enable refreshing; false: disable refreshing
117  */
118 void lv_obj_enable_style_refresh(bool en);
119 
120 /**
121  * Get the value of a style property. The current state of the object will be considered.
122  * Inherited properties will be inherited.
123  * If a property is not set a default value will be returned.
124  * @param obj       pointer to an object
125  * @param part      a part from which the property should be get
126  * @param prop      the property to get
127  * @return          the value of the property.
128  *                  Should be read from the correct field of the `lv_style_value_t` according to the type of the property.
129  */
130 lv_style_value_t lv_obj_get_style_prop(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop);
131 
132 /**
133  * Check if an object has a specified style property for a given style selector.
134  * @param obj       pointer to an object
135  * @param selector  the style selector to be checked, defining the scope of the style to be examined.
136  * @param prop      the property to be checked.
137  * @return          true if the object has the specified selector and property, false otherwise.
138  */
139 bool lv_obj_has_style_prop(const lv_obj_t * obj, lv_style_selector_t selector, lv_style_prop_t prop);
140 
141 /**
142  * Set local style property on an object's part and state.
143  * @param obj       pointer to an object
144  * @param prop      the property
145  * @param value     value of the property. The correct element should be set according to the type of the property
146  * @param selector  OR-ed value of parts and state for which the style should be set
147  */
148 void lv_obj_set_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t value,
149                                  lv_style_selector_t selector);
150 
151 lv_style_res_t lv_obj_get_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t * value,
152                                            lv_style_selector_t selector);
153 
154 /**
155  * Remove a local style property from a part of an object with a given state.
156  * @param obj       pointer to an object
157  * @param prop      a style property to remove.
158  * @param selector  OR-ed value of parts and state for which the style should be removed
159  * @return true     the property was found and removed; false: the property was not found
160  */
161 bool lv_obj_remove_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_selector_t selector);
162 
163 /**
164  * Used internally for color filtering
165  */
166 lv_style_value_t lv_obj_style_apply_color_filter(const lv_obj_t * obj, lv_part_t part, lv_style_value_t v);
167 
168 /**
169  * Fade in an an object and all its children.
170  * @param obj       the object to fade in
171  * @param time      time of fade
172  * @param delay     delay to start the animation
173  */
174 void lv_obj_fade_in(lv_obj_t * obj, uint32_t time, uint32_t delay);
175 
176 /**
177  * Fade out an an object and all its children.
178  * @param obj       the object to fade out
179  * @param time      time of fade
180  * @param delay     delay to start the animation
181  */
182 void lv_obj_fade_out(lv_obj_t * obj, uint32_t time, uint32_t delay);
183 
lv_obj_style_get_selector_state(lv_style_selector_t selector)184 static inline lv_state_t lv_obj_style_get_selector_state(lv_style_selector_t selector)
185 {
186     return selector & 0xFFFF;
187 }
188 
lv_obj_style_get_selector_part(lv_style_selector_t selector)189 static inline lv_part_t lv_obj_style_get_selector_part(lv_style_selector_t selector)
190 {
191     return selector & 0xFF0000;
192 }
193 
194 #include "lv_obj_style_gen.h"
195 
lv_obj_set_style_pad_all(lv_obj_t * obj,int32_t value,lv_style_selector_t selector)196 static inline void lv_obj_set_style_pad_all(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
197 {
198     lv_obj_set_style_pad_left(obj, value, selector);
199     lv_obj_set_style_pad_right(obj, value, selector);
200     lv_obj_set_style_pad_top(obj, value, selector);
201     lv_obj_set_style_pad_bottom(obj, value, selector);
202 }
203 
lv_obj_set_style_pad_hor(lv_obj_t * obj,int32_t value,lv_style_selector_t selector)204 static inline void lv_obj_set_style_pad_hor(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
205 {
206     lv_obj_set_style_pad_left(obj, value, selector);
207     lv_obj_set_style_pad_right(obj, value, selector);
208 }
209 
lv_obj_set_style_pad_ver(lv_obj_t * obj,int32_t value,lv_style_selector_t selector)210 static inline void lv_obj_set_style_pad_ver(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
211 {
212     lv_obj_set_style_pad_top(obj, value, selector);
213     lv_obj_set_style_pad_bottom(obj, value, selector);
214 }
215 
lv_obj_set_style_margin_all(lv_obj_t * obj,int32_t value,lv_style_selector_t selector)216 static inline void lv_obj_set_style_margin_all(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
217 {
218     lv_obj_set_style_margin_left(obj, value, selector);
219     lv_obj_set_style_margin_right(obj, value, selector);
220     lv_obj_set_style_margin_top(obj, value, selector);
221     lv_obj_set_style_margin_bottom(obj, value, selector);
222 }
223 
lv_obj_set_style_margin_hor(lv_obj_t * obj,int32_t value,lv_style_selector_t selector)224 static inline void lv_obj_set_style_margin_hor(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
225 {
226     lv_obj_set_style_margin_left(obj, value, selector);
227     lv_obj_set_style_margin_right(obj, value, selector);
228 }
229 
lv_obj_set_style_margin_ver(lv_obj_t * obj,int32_t value,lv_style_selector_t selector)230 static inline void lv_obj_set_style_margin_ver(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
231 {
232     lv_obj_set_style_margin_top(obj, value, selector);
233     lv_obj_set_style_margin_bottom(obj, value, selector);
234 }
235 
lv_obj_set_style_pad_gap(lv_obj_t * obj,int32_t value,lv_style_selector_t selector)236 static inline void lv_obj_set_style_pad_gap(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
237 {
238     lv_obj_set_style_pad_row(obj, value, selector);
239     lv_obj_set_style_pad_column(obj, value, selector);
240 }
241 
lv_obj_set_style_size(lv_obj_t * obj,int32_t width,int32_t height,lv_style_selector_t selector)242 static inline void lv_obj_set_style_size(lv_obj_t * obj, int32_t width, int32_t height,
243                                          lv_style_selector_t selector)
244 {
245     lv_obj_set_style_width(obj, width, selector);
246     lv_obj_set_style_height(obj, height, selector);
247 }
248 
lv_obj_set_style_transform_scale(lv_obj_t * obj,int32_t value,lv_style_selector_t selector)249 static inline void lv_obj_set_style_transform_scale(lv_obj_t * obj, int32_t value,
250                                                     lv_style_selector_t selector)
251 {
252     lv_obj_set_style_transform_scale_x(obj, value, selector);
253     lv_obj_set_style_transform_scale_y(obj, value, selector);
254 }
255 
lv_obj_get_style_space_left(const lv_obj_t * obj,lv_part_t part)256 static inline int32_t lv_obj_get_style_space_left(const lv_obj_t * obj, lv_part_t part)
257 {
258     int32_t padding = lv_obj_get_style_pad_left(obj, part);
259     int32_t border_width = lv_obj_get_style_border_width(obj, part);
260     lv_border_side_t border_side = lv_obj_get_style_border_side(obj, part);
261     return (border_side & LV_BORDER_SIDE_LEFT) ? padding + border_width : padding;
262 }
263 
lv_obj_get_style_space_right(const lv_obj_t * obj,lv_part_t part)264 static inline int32_t lv_obj_get_style_space_right(const lv_obj_t * obj, lv_part_t part)
265 {
266     int32_t padding = lv_obj_get_style_pad_right(obj, part);
267     int32_t border_width = lv_obj_get_style_border_width(obj, part);
268     lv_border_side_t border_side = lv_obj_get_style_border_side(obj, part);
269     return (border_side & LV_BORDER_SIDE_RIGHT) ? padding + border_width : padding;
270 }
271 
lv_obj_get_style_space_top(const lv_obj_t * obj,lv_part_t part)272 static inline int32_t lv_obj_get_style_space_top(const lv_obj_t * obj, lv_part_t part)
273 {
274     int32_t padding = lv_obj_get_style_pad_top(obj, part);
275     int32_t border_width = lv_obj_get_style_border_width(obj, part);
276     lv_border_side_t border_side = lv_obj_get_style_border_side(obj, part);
277     return (border_side & LV_BORDER_SIDE_TOP) ? padding + border_width : padding;
278 }
279 
lv_obj_get_style_space_bottom(const lv_obj_t * obj,lv_part_t part)280 static inline int32_t lv_obj_get_style_space_bottom(const lv_obj_t * obj, lv_part_t part)
281 {
282     int32_t padding = lv_obj_get_style_pad_bottom(obj, part);
283     int32_t border_width = lv_obj_get_style_border_width(obj, part);
284     lv_border_side_t border_side = lv_obj_get_style_border_side(obj, part);
285     return (border_side & LV_BORDER_SIDE_BOTTOM) ? padding + border_width : padding;
286 }
287 
288 lv_text_align_t lv_obj_calculate_style_text_align(const lv_obj_t * obj, lv_part_t part, const char * txt);
289 
lv_obj_get_style_transform_scale_x_safe(const lv_obj_t * obj,lv_part_t part)290 static inline int32_t lv_obj_get_style_transform_scale_x_safe(const lv_obj_t * obj, lv_part_t part)
291 {
292     int32_t scale = lv_obj_get_style_transform_scale_x(obj, part);
293     return scale > 0 ? scale : 1;
294 }
295 
lv_obj_get_style_transform_scale_y_safe(const lv_obj_t * obj,lv_part_t part)296 static inline int32_t lv_obj_get_style_transform_scale_y_safe(const lv_obj_t * obj, lv_part_t part)
297 {
298     int32_t scale = lv_obj_get_style_transform_scale_y(obj, part);
299     return scale > 0 ? scale : 1;
300 }
301 
302 /**
303  * Get the `opa` style property from all parents and multiply and `>> 8` them.
304  * @param obj       the object whose opacity should be get
305  * @param part      the part whose opacity should be get. Non-MAIN parts will consider the `opa` of the MAIN part too
306  * @return          the final opacity considering the parents' opacity too
307  */
308 lv_opa_t lv_obj_get_style_opa_recursive(const lv_obj_t * obj, lv_part_t part);
309 
310 /**********************
311  *      MACROS
312  **********************/
313 
314 #ifdef __cplusplus
315 } /*extern "C"*/
316 #endif
317 
318 #endif /*LV_OBJ_STYLE_H*/
319