1 /**
2 * @file lv_fragment.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9
10 #include "lv_fragment.h"
11
12 #if LV_USE_FRAGMENT
13
14 /**********************
15 * STATIC PROTOTYPES
16 **********************/
17
18 static void cb_delete_assertion(lv_event_t * event);
19
20 /**********************
21 * GLOBAL FUNCTIONS
22 **********************/
23
lv_fragment_create(const lv_fragment_class_t * cls,void * args)24 lv_fragment_t * lv_fragment_create(const lv_fragment_class_t * cls, void * args)
25 {
26 LV_ASSERT_NULL(cls);
27 LV_ASSERT_NULL(cls->create_obj_cb);
28 LV_ASSERT(cls->instance_size > 0);
29 lv_fragment_t * instance = lv_mem_alloc(cls->instance_size);
30 lv_memset_00(instance, cls->instance_size);
31 instance->cls = cls;
32 instance->child_manager = lv_fragment_manager_create(instance);
33 if(cls->constructor_cb) {
34 cls->constructor_cb(instance, args);
35 }
36 return instance;
37 }
38
lv_fragment_del(lv_fragment_t * fragment)39 void lv_fragment_del(lv_fragment_t * fragment)
40 {
41 LV_ASSERT_NULL(fragment);
42 if(fragment->managed) {
43 lv_fragment_manager_remove(fragment->managed->manager, fragment);
44 return;
45 }
46 if(fragment->obj) {
47 lv_fragment_del_obj(fragment);
48 }
49 /* Objects will leak if this function called before objects deleted */
50 const lv_fragment_class_t * cls = fragment->cls;
51 if(cls->destructor_cb) {
52 cls->destructor_cb(fragment);
53 }
54 lv_fragment_manager_del(fragment->child_manager);
55 lv_mem_free(fragment);
56 }
57
lv_fragment_get_manager(lv_fragment_t * fragment)58 lv_fragment_manager_t * lv_fragment_get_manager(lv_fragment_t * fragment)
59 {
60 LV_ASSERT_NULL(fragment);
61 LV_ASSERT_NULL(fragment->managed);
62 return fragment->managed->manager;
63 }
64
lv_fragment_get_container(lv_fragment_t * fragment)65 lv_obj_t * const * lv_fragment_get_container(lv_fragment_t * fragment)
66 {
67 LV_ASSERT_NULL(fragment);
68 LV_ASSERT_NULL(fragment->managed);
69 return fragment->managed->container;
70 }
71
lv_fragment_get_parent(lv_fragment_t * fragment)72 lv_fragment_t * lv_fragment_get_parent(lv_fragment_t * fragment)
73 {
74 LV_ASSERT_NULL(fragment);
75 LV_ASSERT_NULL(fragment->managed);
76 return lv_fragment_manager_get_parent_fragment(fragment->managed->manager);
77 }
78
lv_fragment_create_obj(lv_fragment_t * fragment,lv_obj_t * container)79 lv_obj_t * lv_fragment_create_obj(lv_fragment_t * fragment, lv_obj_t * container)
80 {
81 lv_fragment_managed_states_t * states = fragment->managed;
82 if(states) {
83 states->destroying_obj = false;
84 }
85 const lv_fragment_class_t * cls = fragment->cls;
86 lv_obj_t * obj = cls->create_obj_cb(fragment, container);
87 LV_ASSERT_NULL(obj);
88 fragment->obj = obj;
89 lv_fragment_manager_create_obj(fragment->child_manager);
90 if(states) {
91 states->obj_created = true;
92 lv_obj_add_event_cb(obj, cb_delete_assertion, LV_EVENT_DELETE, NULL);
93 }
94 if(cls->obj_created_cb) {
95 cls->obj_created_cb(fragment, obj);
96 }
97 return obj;
98 }
99
lv_fragment_del_obj(lv_fragment_t * fragment)100 void lv_fragment_del_obj(lv_fragment_t * fragment)
101 {
102 LV_ASSERT_NULL(fragment);
103 lv_fragment_manager_del_obj(fragment->child_manager);
104 lv_fragment_managed_states_t * states = fragment->managed;
105 if(states) {
106 if(!states->obj_created) return;
107 states->destroying_obj = true;
108 bool cb_removed = lv_obj_remove_event_cb(fragment->obj, cb_delete_assertion);
109 LV_ASSERT(cb_removed);
110 }
111 LV_ASSERT_NULL(fragment->obj);
112 const lv_fragment_class_t * cls = fragment->cls;
113 if(cls->obj_will_delete_cb) {
114 cls->obj_will_delete_cb(fragment, fragment->obj);
115 }
116 lv_obj_del(fragment->obj);
117 if(cls->obj_deleted_cb) {
118 cls->obj_deleted_cb(fragment, fragment->obj);
119 }
120 if(states) {
121 states->obj_created = false;
122 }
123 fragment->obj = NULL;
124 }
125
lv_fragment_recreate_obj(lv_fragment_t * fragment)126 void lv_fragment_recreate_obj(lv_fragment_t * fragment)
127 {
128 LV_ASSERT_NULL(fragment);
129 LV_ASSERT_NULL(fragment->managed);
130 lv_fragment_del_obj(fragment);
131 lv_fragment_create_obj(fragment, *fragment->managed->container);
132 }
133
134 /**********************
135 * STATIC FUNCTIONS
136 **********************/
137
cb_delete_assertion(lv_event_t * event)138 static void cb_delete_assertion(lv_event_t * event)
139 {
140 LV_UNUSED(event);
141 LV_ASSERT_MSG(0, "Please delete objects with lv_fragment_destroy_obj");
142 }
143
144 #endif /*LV_USE_FRAGMENT*/
145