acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

lv_obj_class.c (5859B)

      1 /**
      2  * @file lv_obj_class.c
      3  *
      4  */
      5 
      6 /*********************
      7  *      INCLUDES
      8  *********************/
      9 #include "lv_obj.h"
     10 #include "lv_theme.h"
     11 
     12 /*********************
     13  *      DEFINES
     14  *********************/
     15 #define MY_CLASS &lv_obj_class
     16 
     17 /**********************
     18  *      TYPEDEFS
     19  **********************/
     20 
     21 /**********************
     22  *  GLOBAL PROTOTYPES
     23  **********************/
     24 
     25 /**********************
     26  *  STATIC PROTOTYPES
     27  **********************/
     28 static void lv_obj_construct(lv_obj_t * obj);
     29 static uint32_t get_instance_size(const lv_obj_class_t * class_p);
     30 
     31 /**********************
     32  *  STATIC VARIABLES
     33  **********************/
     34 
     35 /**********************
     36  *      MACROS
     37  **********************/
     38 
     39 /**********************
     40  *   GLOBAL FUNCTIONS
     41  **********************/
     42 
     43 lv_obj_t * lv_obj_class_create_obj(const lv_obj_class_t * class_p, lv_obj_t * parent)
     44 {
     45     LV_TRACE_OBJ_CREATE("Creating object with %p class on %p parent", (void *)class_p, (void *)parent);
     46     uint32_t s = get_instance_size(class_p);
     47     lv_obj_t * obj = lv_mem_alloc(s);
     48     if(obj == NULL) return NULL;
     49     lv_memset_00(obj, s);
     50     obj->class_p = class_p;
     51     obj->parent = parent;
     52 
     53     /*Create a screen*/
     54     if(parent == NULL) {
     55         LV_TRACE_OBJ_CREATE("creating a screen");
     56         lv_disp_t * disp = lv_disp_get_default();
     57         if(!disp) {
     58             LV_LOG_WARN("No display created yet. No place to assign the new screen");
     59             lv_mem_free(obj);
     60             return NULL;
     61         }
     62 
     63         if(disp->screens == NULL) {
     64             disp->screens = lv_mem_alloc(sizeof(lv_obj_t *));
     65             disp->screens[0] = obj;
     66             disp->screen_cnt = 1;
     67         }
     68         else {
     69             disp->screen_cnt++;
     70             disp->screens = lv_mem_realloc(disp->screens, sizeof(lv_obj_t *) * disp->screen_cnt);
     71             disp->screens[disp->screen_cnt - 1] = obj;
     72         }
     73 
     74         /*Set coordinates to full screen size*/
     75         obj->coords.x1 = 0;
     76         obj->coords.y1 = 0;
     77         obj->coords.x2 = lv_disp_get_hor_res(NULL) - 1;
     78         obj->coords.y2 = lv_disp_get_ver_res(NULL) - 1;
     79     }
     80     /*Create a normal object*/
     81     else {
     82         LV_TRACE_OBJ_CREATE("creating normal object");
     83         LV_ASSERT_OBJ(parent, MY_CLASS);
     84         if(parent->spec_attr == NULL) {
     85             lv_obj_allocate_spec_attr(parent);
     86         }
     87 
     88         if(parent->spec_attr->children == NULL) {
     89             parent->spec_attr->children = lv_mem_alloc(sizeof(lv_obj_t *));
     90             parent->spec_attr->children[0] = obj;
     91             parent->spec_attr->child_cnt = 1;
     92         }
     93         else {
     94             parent->spec_attr->child_cnt++;
     95             parent->spec_attr->children = lv_mem_realloc(parent->spec_attr->children,
     96                                                          sizeof(lv_obj_t *) * parent->spec_attr->child_cnt);
     97             parent->spec_attr->children[parent->spec_attr->child_cnt - 1] = obj;
     98         }
     99     }
    100 
    101     return obj;
    102 }
    103 
    104 void lv_obj_class_init_obj(lv_obj_t * obj)
    105 {
    106     lv_obj_mark_layout_as_dirty(obj);
    107     lv_obj_enable_style_refresh(false);
    108 
    109     lv_theme_apply(obj);
    110     lv_obj_construct(obj);
    111 
    112     lv_obj_enable_style_refresh(true);
    113     lv_obj_refresh_style(obj, LV_PART_ANY, LV_STYLE_PROP_ANY);
    114 
    115     lv_obj_refresh_self_size(obj);
    116 
    117     lv_group_t * def_group = lv_group_get_default();
    118     if(def_group && lv_obj_is_group_def(obj)) {
    119         lv_group_add_obj(def_group, obj);
    120     }
    121 
    122     lv_obj_t * parent = lv_obj_get_parent(obj);
    123     if(parent) {
    124         /*Call the ancestor's event handler to the parent to notify it about the new child.
    125          *Also triggers layout update*/
    126         lv_event_send(parent, LV_EVENT_CHILD_CHANGED, obj);
    127         lv_event_send(parent, LV_EVENT_CHILD_CREATED, obj);
    128 
    129         /*Invalidate the area if not screen created*/
    130         lv_obj_invalidate(obj);
    131     }
    132 }
    133 
    134 void _lv_obj_destruct(lv_obj_t * obj)
    135 {
    136     if(obj->class_p->destructor_cb) obj->class_p->destructor_cb(obj->class_p, obj);
    137 
    138     if(obj->class_p->base_class) {
    139         /*Don't let the descendant methods run during destructing the ancestor type*/
    140         obj->class_p = obj->class_p->base_class;
    141 
    142         /*Call the base class's destructor too*/
    143         _lv_obj_destruct(obj);
    144     }
    145 }
    146 
    147 bool lv_obj_is_editable(lv_obj_t * obj)
    148 {
    149     const lv_obj_class_t * class_p = obj->class_p;
    150 
    151     /*Find a base in which editable is set*/
    152     while(class_p && class_p->editable == LV_OBJ_CLASS_EDITABLE_INHERIT) class_p = class_p->base_class;
    153 
    154     if(class_p == NULL) return false;
    155 
    156     return class_p->editable == LV_OBJ_CLASS_EDITABLE_TRUE ? true : false;
    157 }
    158 
    159 bool lv_obj_is_group_def(lv_obj_t * obj)
    160 {
    161     const lv_obj_class_t * class_p = obj->class_p;
    162 
    163     /*Find a base in which group_def is set*/
    164     while(class_p && class_p->group_def == LV_OBJ_CLASS_GROUP_DEF_INHERIT) class_p = class_p->base_class;
    165 
    166     if(class_p == NULL) return false;
    167 
    168     return class_p->group_def == LV_OBJ_CLASS_GROUP_DEF_TRUE ? true : false;
    169 }
    170 
    171 /**********************
    172  *   STATIC FUNCTIONS
    173  **********************/
    174 
    175 static void lv_obj_construct(lv_obj_t * obj)
    176 {
    177     const lv_obj_class_t * original_class_p = obj->class_p;
    178 
    179     if(obj->class_p->base_class) {
    180         /*Don't let the descendant methods run during constructing the ancestor type*/
    181         obj->class_p = obj->class_p->base_class;
    182 
    183         /*Construct the base first*/
    184         lv_obj_construct(obj);
    185     }
    186 
    187     /*Restore the original class*/
    188     obj->class_p = original_class_p;
    189 
    190     if(obj->class_p->constructor_cb) obj->class_p->constructor_cb(obj->class_p, obj);
    191 }
    192 
    193 static uint32_t get_instance_size(const lv_obj_class_t * class_p)
    194 {
    195     /*Find a base in which instance size is set*/
    196     const lv_obj_class_t * base = class_p;
    197     while(base && base->instance_size == 0) base = base->base_class;
    198 
    199     if(base == NULL) return 0;  /*Never happens: set at least in `lv_obj` class*/
    200 
    201     return base->instance_size;
    202 }