summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2017-12-07 21:16:45 -0200
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2017-12-08 18:04:29 -0200
commit1e5b03c8a5747ab0f01ecac3161dc388f5303981 (patch)
tree78c51f0ba6e5f861abd5b719abca7e2479b08ddf
parent6fdf0b3a82369982b664adff6d7870670ea8523f (diff)
elm: Fix efl_ui_list_segarray insertiondevs/felipealmeida/efl-ui-list
-rw-r--r--src/lib/elementary/efl_ui_list_segarray.c107
1 files changed, 83 insertions, 24 deletions
diff --git a/src/lib/elementary/efl_ui_list_segarray.c b/src/lib/elementary/efl_ui_list_segarray.c
index bfc311a528..3f891a8835 100644
--- a/src/lib/elementary/efl_ui_list_segarray.c
+++ b/src/lib/elementary/efl_ui_list_segarray.c
@@ -110,30 +110,19 @@ void efl_ui_list_segarray_flush(Efl_Ui_List_SegArray* segarray)
110 segarray->root = NULL; 110 segarray->root = NULL;
111} 111}
112 112
113static Efl_Ui_List_Item* _create_item(Efl_Model* model, Efl_Ui_List_SegArray_Node* node, unsigned int index) 113static Efl_Ui_List_Item* _create_item_partial(Efl_Model* model)
114{ 114{
115 Efl_Ui_List_Item* item = calloc(1, sizeof(Efl_Ui_List_Item)); 115 Efl_Ui_List_Item* item = calloc(1, sizeof(Efl_Ui_List_Item));
116 item->item.children = model; 116 item->item.children = model;
117 item->item.index_offset = index - node->first;
118 item->item.tree_node = node;
119 return item; 117 return item;
120} 118}
121 119
122void efl_ui_list_segarray_insert(Efl_Ui_List_SegArray* segarray, int index, Efl_Model* model) 120static Efl_Ui_List_Item* _create_item(Efl_Model* model, Efl_Ui_List_SegArray_Node* node, unsigned int index)
123{ 121{
124 Efl_Ui_List_SegArray_Node *node; 122 Efl_Ui_List_Item* item = _create_item_partial(model);
125 123 item->item.index_offset = index - node->first;
126 node = (void*)eina_rbtree_inline_lookup(EINA_RBTREE_GET(segarray->root), 124 item->item.tree_node = node;
127 &index, sizeof(index), &_insert_lookup_cb, NULL); 125 return item;
128 if (!node)
129 node = _alloc_node(segarray, index, segarray->array_initial_size);
130
131 assert(node->length < node->max); //don't have space in node to put this item
132 assert((index - node->first) == node->length); //TODO FIXME there is other item in this place need move others
133
134 node->pointers[node->length] = _create_item(model, node, index);
135 node->length++;
136 segarray->count++;
137} 126}
138 127
139Efl_Ui_List_Item* 128Efl_Ui_List_Item*
@@ -155,7 +144,10 @@ efl_ui_list_segarray_remove(Efl_Ui_List_SegArray* segarray, int index)
155 segarray->count--; 144 segarray->count--;
156 node->length--; 145 node->length--;
157 146
158 if (offset < node->length) 147 if (offset >= node->length) return NULL;
148
149 memmove(node->pointers[offset], node->pointers[offset+1], sizeof(Efl_Ui_List_Item*)*(node->length - offset));
150 while (offset < node->length)
159 { 151 {
160 while (offset < node->length) 152 while (offset < node->length)
161 { 153 {
@@ -164,16 +156,83 @@ efl_ui_list_segarray_remove(Efl_Ui_List_SegArray* segarray, int index)
164 --item->item.index_offset; 156 --item->item.index_offset;
165 ++offset; 157 ++offset;
166 } 158 }
159 }
160
161 node = (void*)EINA_RBTREE_GET(node)->son[EINA_RBTREE_LEFT];
162 iterator = eina_rbtree_iterator_infix((void*)node);
163 while(eina_iterator_next(iterator, (void**)&node))
164 node->first--;
165
166 return rt;
167}
168
169static void
170_efl_ui_list_segarray_insert_at_node(Efl_Ui_List_SegArray* segarray, int index, Efl_Ui_List_Item* item, Efl_Ui_List_SegArray_Node* node)
171{
172 Eina_Iterator* iterator;
173 int pos;
174
175 if(node && node->length != node->max && (index - node->first) <= node->length)
176 {
177 pos = index - node->first;
178 item->item.tree_node = node;
179 item->item.index_offset = pos;
180 if(pos < node->length)
181 {
182 assert(node->length != node->max);
167 183
168 iterator = eina_rbtree_iterator_infix((void*)node); 184 memmove(&node->pointers[pos], &node->pointers[pos+1], sizeof(node->pointers[pos])*(node->length - pos));
169 eina_iterator_next(iterator, (void**)&node); 185 node->pointers[pos] = item;
170 while(eina_iterator_next(iterator, (void**)&node)) 186 node->length++;
171 node->first--; 187 }
188 else
189 {
190 assert(pos == node->length);
191
192 assert(node->length != node->max);
193 node->pointers[pos] = item;
194 node->length++;
195 }
196 }
197 else
198 {
199 node = _alloc_node(segarray, index, segarray->array_initial_size);
200 node->pointers[0] = item;
201 node->length++;
202 item->item.index_offset = 0;
203 item->item.tree_node = node;
204 }
172 205
173 eina_iterator_free(iterator); 206 node = (void*)EINA_RBTREE_GET(node)->son[EINA_RBTREE_LEFT];
207 iterator = eina_rbtree_iterator_infix((void*)node);
208 while(eina_iterator_next(iterator, (void**)&node))
209 {
210 node->first++;
174 } 211 }
175 212
176 return rt; 213 eina_iterator_free(iterator);
214}
215
216
217void efl_ui_list_segarray_insert(Efl_Ui_List_SegArray* segarray, int index, Efl_Model* model)
218{
219 Efl_Ui_List_SegArray_Node* node, *next;
220 Efl_Ui_List_Item* item;
221
222 item = _create_item_partial(model);
223
224 node = (void*)eina_rbtree_inline_lookup(EINA_RBTREE_GET(segarray->root),
225 &index, sizeof(index), &_insert_lookup_cb, NULL);
226 if(node)
227 {
228 next = (void*)EINA_RBTREE_GET(node)->son[EINA_RBTREE_LEFT];
229 if(next && next->first <= index)
230 _efl_ui_list_segarray_insert_at_node(segarray, index, item, next);
231 else
232 _efl_ui_list_segarray_insert_at_node(segarray, index, item, node);
233 }
234 else
235 _efl_ui_list_segarray_insert_at_node(segarray, index, item, NULL);
177} 236}
178 237
179void efl_ui_list_segarray_insert_accessor(Efl_Ui_List_SegArray* segarray, int first, Eina_Accessor* accessor) 238void efl_ui_list_segarray_insert_accessor(Efl_Ui_List_SegArray* segarray, int first, Eina_Accessor* accessor)