1 /** 2 * @file lv_observer.h 3 * 4 */ 5 6 #ifndef LV_OBSERVER_H 7 #define LV_OBSERVER_H 8 9 #ifdef __cplusplus 10 extern "C" { 11 #endif 12 13 /********************* 14 * INCLUDES 15 *********************/ 16 17 #include "../../core/lv_obj.h" 18 #if LV_USE_OBSERVER 19 20 /********************* 21 * DEFINES 22 *********************/ 23 24 /********************** 25 * TYPEDEFS 26 **********************/ 27 28 /** 29 * Values for lv_submect_t's `type` field. 30 */ 31 typedef enum { 32 LV_SUBJECT_TYPE_INVALID = 0, /**< indicates subject not initialized yet*/ 33 LV_SUBJECT_TYPE_NONE = 1, /**< a null value like None or NILt*/ 34 LV_SUBJECT_TYPE_INT = 2, /**< an int32_t*/ 35 LV_SUBJECT_TYPE_POINTER = 3, /**< a void pointer*/ 36 LV_SUBJECT_TYPE_COLOR = 4, /**< an lv_color_t*/ 37 LV_SUBJECT_TYPE_GROUP = 5, /**< an array of subjects*/ 38 LV_SUBJECT_TYPE_STRING = 6, /**< a char pointer*/ 39 } lv_subject_type_t; 40 41 /** 42 * A common type to handle all the various observable types in the same way 43 */ 44 typedef union { 45 int32_t num; /**< Integer number (opacity, enums, booleans or "normal" numbers)*/ 46 const void * pointer; /**< Constant pointer (string buffer, format string, font, cone text, etc)*/ 47 lv_color_t color; /**< Color */ 48 } lv_subject_value_t; 49 50 /** 51 * The subject (an observable value) 52 */ 53 typedef struct { 54 lv_ll_t subs_ll; /**< Subscribers*/ 55 uint32_t type : 4; 56 uint32_t size : 28; /**< Might be used to store a size related to `type`*/ 57 lv_subject_value_t value; /**< Actual value*/ 58 lv_subject_value_t prev_value; /**< Previous value*/ 59 uint32_t notify_restart_query : 1; /**< If an observer deleted start notifying from the beginning. */ 60 void * user_data; /**< Additional parameter, can be used freely by the user*/ 61 } lv_subject_t; 62 63 /** 64 * Callback called when the observed value changes 65 * @param observer pointer to the observer of the callback 66 * @param subject pointer to the subject of the observer 67 */ 68 typedef void (*lv_observer_cb_t)(lv_observer_t * observer, lv_subject_t * subject); 69 70 /********************** 71 * GLOBAL PROTOTYPES 72 **********************/ 73 74 /** 75 * Initialize an integer type subject 76 * @param subject pointer to the subject 77 * @param value initial value 78 */ 79 void lv_subject_init_int(lv_subject_t * subject, int32_t value); 80 81 /** 82 * Set the value of an integer subject. It will notify all the observers as well. 83 * @param subject pointer to the subject 84 * @param value the new value 85 */ 86 void lv_subject_set_int(lv_subject_t * subject, int32_t value); 87 88 /** 89 * Get the current value of an integer subject 90 * @param subject pointer to the subject 91 * @return the current value 92 */ 93 int32_t lv_subject_get_int(lv_subject_t * subject); 94 95 /** 96 * Get the previous value of an integer subject 97 * @param subject pointer to the subject 98 * @return the current value 99 */ 100 int32_t lv_subject_get_previous_int(lv_subject_t * subject); 101 102 /** 103 * Initialize a string type subject 104 * @param subject pointer to the subject 105 * @param buf pointer to a buffer to store the string 106 * @param prev_buf pointer to a buffer to store the previous string, can be NULL if not used 107 * @param size size of the buffer 108 * @param value initial value as a string, e.g. "hello" 109 * @note the string subject stores the whole string, not only a pointer 110 */ 111 void lv_subject_init_string(lv_subject_t * subject, char * buf, char * prev_buf, size_t size, const char * value); 112 113 /** 114 * Copy a string to a subject. It will notify all the observers as well. 115 * @param subject pointer to the subject 116 * @param buf the new string 117 */ 118 void lv_subject_copy_string(lv_subject_t * subject, const char * buf); 119 120 /** 121 * Print a formatted string to a subject. It will notify all the observers as well. 122 * @param subject pointer to the subject 123 * @param format the format string 124 */ 125 void lv_subject_snprintf(lv_subject_t * subject, const char * format, ...) LV_FORMAT_ATTRIBUTE(2, 3); 126 127 /** 128 * Get the current value of an string subject 129 * @param subject pointer to the subject 130 * @return pointer to the buffer containing the current value 131 */ 132 const char * lv_subject_get_string(lv_subject_t * subject); 133 134 /** 135 * Get the previous value of an string subject 136 * @param subject pointer to the subject 137 * @return pointer to the buffer containing the current value 138 * @note NULL will be returned if NULL was passed in `lv_subject_init_string()` 139 * as `prev_buf` 140 */ 141 const char * lv_subject_get_previous_string(lv_subject_t * subject); 142 143 /** 144 * Initialize an pointer type subject 145 * @param subject pointer to the subject 146 * @param value initial value 147 */ 148 void lv_subject_init_pointer(lv_subject_t * subject, void * value); 149 150 /** 151 * Set the value of a pointer subject. It will notify all the observers as well. 152 * @param subject pointer to the subject 153 * @param ptr new value 154 */ 155 void lv_subject_set_pointer(lv_subject_t * subject, void * ptr); 156 157 /** 158 * Get the current value of a pointer subject 159 * @param subject pointer to the subject 160 * @return current value 161 */ 162 const void * lv_subject_get_pointer(lv_subject_t * subject); 163 164 /** 165 * Get the previous value of a pointer subject 166 * @param subject pointer to the subject 167 * @return current value 168 */ 169 const void * lv_subject_get_previous_pointer(lv_subject_t * subject); 170 171 /** 172 * Initialize an color type subject 173 * @param subject pointer to the subject 174 * @param color initial value 175 */ 176 void lv_subject_init_color(lv_subject_t * subject, lv_color_t color); 177 178 /** 179 * Set the value of a color subject. It will notify all the observers as well. 180 * @param subject pointer to the subject 181 * @param color new value 182 */ 183 void lv_subject_set_color(lv_subject_t * subject, lv_color_t color); 184 185 /** 186 * Get the current value of a color subject 187 * @param subject pointer to the subject 188 * @return current value 189 */ 190 lv_color_t lv_subject_get_color(lv_subject_t * subject); 191 192 /** 193 * Get the previous value of a color subject 194 * @param subject pointer to the subject 195 * @return current value 196 */ 197 lv_color_t lv_subject_get_previous_color(lv_subject_t * subject); 198 199 /** 200 * Initialize a subject group 201 * @param subject pointer to the subject 202 * @param list list of other subject addresses, any of these changes `subject` will be notified 203 * @param list_len number of elements in `list` 204 */ 205 void lv_subject_init_group(lv_subject_t * subject, lv_subject_t * list[], uint32_t list_len); 206 207 /** 208 * Remove all the observers from a subject and free all allocated memories in it 209 * @param subject pointer to the subject 210 * @note objects added with `lv_subject_add_observer_obj` should be already deleted or 211 * removed manually. 212 */ 213 void lv_subject_deinit(lv_subject_t * subject); 214 215 /** 216 * Get an element from the subject group's list 217 * @param subject pointer to the subject 218 * @param index index of the element to get 219 * @return pointer a subject from the list, or NULL if the index is out of bounds 220 */ 221 lv_subject_t * lv_subject_get_group_element(lv_subject_t * subject, int32_t index); 222 223 /** 224 * Add an observer to a subject. When the subject changes `observer_cb` will be called. 225 * @param subject pointer to the subject 226 * @param observer_cb callback to call 227 * @param user_data optional user data 228 * @return pointer to the created observer 229 */ 230 lv_observer_t * lv_subject_add_observer(lv_subject_t * subject, lv_observer_cb_t observer_cb, void * user_data); 231 232 /** 233 * Add an observer to a subject for an object. 234 * When the object is deleted, it will be removed from the subject automatically. 235 * @param subject pointer to the subject 236 * @param observer_cb callback to call 237 * @param obj pointer to an object 238 * @param user_data optional user data 239 * @return pointer to the created observer 240 */ 241 lv_observer_t * lv_subject_add_observer_obj(lv_subject_t * subject, lv_observer_cb_t observer_cb, lv_obj_t * obj, 242 void * user_data); 243 244 /** 245 * Add an observer to a subject and also save a target. 246 * @param subject pointer to the subject 247 * @param observer_cb callback to call 248 * @param target pointer to any data 249 * @param user_data optional user data 250 * @return pointer to the created observer 251 */ 252 lv_observer_t * lv_subject_add_observer_with_target(lv_subject_t * subject, lv_observer_cb_t observer_cb, 253 void * target, void * user_data); 254 255 /** 256 * Remove an observer from its subject 257 * @param observer pointer to an observer 258 */ 259 void lv_observer_remove(lv_observer_t * observer); 260 261 /** 262 * Remove the observers of an object from a subject or all subjects 263 * @param obj the object whose observers should be removed 264 * @param subject the subject to remove the object from, or `NULL` to remove from all subjects 265 * @note This function can be used e.g. when an object's subject(s) needs to be replaced by other subject(s) 266 */ 267 void lv_obj_remove_from_subject(lv_obj_t * obj, lv_subject_t * subject); 268 269 /** 270 * Get the target of an observer 271 * @param observer pointer to an observer 272 * @return pointer to the saved target 273 */ 274 void * lv_observer_get_target(lv_observer_t * observer); 275 276 /** 277 * Get the target object of the observer. 278 * It's the same as `lv_observer_get_target` and added only 279 * for semantic reasons 280 * @param observer pointer to an observer 281 * @return pointer to the saved object target 282 */ 283 lv_obj_t * lv_observer_get_target_obj(lv_observer_t * observer); 284 285 /** 286 * Get the user data of the observer. 287 * @param observer pointer to an observer 288 * @return void pointer to the saved user data 289 */ 290 void * lv_observer_get_user_data(const lv_observer_t * observer); 291 292 /** 293 * Notify all observers of subject 294 * @param subject pointer to a subject 295 */ 296 void lv_subject_notify(lv_subject_t * subject); 297 298 /** 299 * Set an object flag if an integer subject's value is equal to a reference value, clear the flag otherwise 300 * @param obj pointer to an object 301 * @param subject pointer to a subject 302 * @param flag flag to set or clear (e.g. `LV_OBJ_FLAG_HIDDEN`) 303 * @param ref_value reference value to compare the subject's value with 304 * @return pointer to the created observer 305 */ 306 lv_observer_t * lv_obj_bind_flag_if_eq(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value); 307 308 /** 309 * Set an object flag if an integer subject's value is not equal to a reference value, clear the flag otherwise 310 * @param obj pointer to an object 311 * @param subject pointer to a subject 312 * @param flag flag to set or clear (e.g. `LV_OBJ_FLAG_HIDDEN`) 313 * @param ref_value reference value to compare the subject's value with 314 * @return pointer to the created observer 315 */ 316 lv_observer_t * lv_obj_bind_flag_if_not_eq(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, 317 int32_t ref_value); 318 319 /** 320 * Set an object state if an integer subject's value is equal to a reference value, clear the flag otherwise 321 * @param obj pointer to an object 322 * @param subject pointer to a subject 323 * @param state state to set or clear (e.g. `LV_STATE_CHECKED`) 324 * @param ref_value reference value to compare the subject's value with 325 * @return pointer to the created observer 326 */ 327 lv_observer_t * lv_obj_bind_state_if_eq(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value); 328 329 /** 330 * Set an object state if an integer subject's value is not equal to a reference value, clear the flag otherwise 331 * @param obj pointer to an object 332 * @param subject pointer to a subject 333 * @param state state to set or clear (e.g. `LV_STATE_CHECKED`) 334 * @param ref_value reference value to compare the subject's value with 335 * @return pointer to the created observer 336 */ 337 lv_observer_t * lv_obj_bind_state_if_not_eq(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, 338 int32_t ref_value); 339 340 /** 341 * Set an integer subject to 1 when an object is checked and set it 0 when unchecked. 342 * @param obj pointer to an object 343 * @param subject pointer to a subject 344 * @return pointer to the created observer 345 * @note Ensure the object's `LV_OBJ_FLAG_CHECKABLE` flag is set 346 */ 347 lv_observer_t * lv_obj_bind_checked(lv_obj_t * obj, lv_subject_t * subject); 348 349 #if LV_USE_LABEL 350 /** 351 * Bind an integer, string, or pointer subject to a label. 352 * @param obj pointer to a label 353 * @param subject pointer to a subject 354 * @param fmt optional format string with 1 format specifier (e.g. "%d °C") 355 * or NULL to bind the value directly. 356 * @return pointer to the created observer 357 * @note fmt == NULL can be used only with string and pointer subjects. 358 * @note if the subject is a pointer must point to a `\0` terminated string. 359 */ 360 lv_observer_t * lv_label_bind_text(lv_obj_t * obj, lv_subject_t * subject, const char * fmt); 361 #endif 362 363 #if LV_USE_ARC 364 /** 365 * Bind an integer subject to an arc's value 366 * @param obj pointer to an arc 367 * @param subject pointer to a subject 368 * @return pointer to the created observer 369 */ 370 lv_observer_t * lv_arc_bind_value(lv_obj_t * obj, lv_subject_t * subject); 371 #endif 372 373 #if LV_USE_SLIDER 374 /** 375 * Bind an integer subject to a slider's value 376 * @param obj pointer to a slider 377 * @param subject pointer to a subject 378 * @return pointer to the created observer 379 */ 380 lv_observer_t * lv_slider_bind_value(lv_obj_t * obj, lv_subject_t * subject); 381 #endif 382 383 #if LV_USE_ROLLER 384 /** 385 * Bind an integer subject to a roller's value 386 * @param obj pointer to a roller 387 * @param subject pointer to a subject 388 * @return pointer to the created observer 389 */ 390 lv_observer_t * lv_roller_bind_value(lv_obj_t * obj, lv_subject_t * subject); 391 #endif 392 393 #if LV_USE_DROPDOWN 394 /** 395 * Bind an integer subject to a dropdown's value 396 * @param obj pointer to a drop down 397 * @param subject pointer to a subject 398 * @return pointer to the created observer 399 */ 400 lv_observer_t * lv_dropdown_bind_value(lv_obj_t * obj, lv_subject_t * subject); 401 #endif 402 403 /********************** 404 * MACROS 405 **********************/ 406 407 #endif /*LV_USE_OBSERVER*/ 408 409 #ifdef __cplusplus 410 } /*extern "C"*/ 411 #endif 412 413 #endif /*LV_OBSERVER_H*/ 414