1 #include "evas_common_private.h"
2 #include "evas_private.h"
3 #include "efl_canvas_textblock_internal.h"
4 #include "eo_internal.h"
5
6 #define MY_CLASS EFL_TEXT_CURSOR_OBJECT_CLASS
7 #define MY_CLASS_NAME "Efl.Text.Cursor"
8
9 typedef struct
10 {
11 Efl_Text_Cursor_Handle *handle;
12 Efl_Canvas_Object *text_obj;
13 } Efl_Text_Cursor_Object_Data;
14
15 struct _Evas_Textblock_Selection_Iterator
16 {
17 Eina_Iterator iterator; /**< Eina Iterator. */
18 Eina_List *list; /**< Head of list. */
19 Eina_List *current; /**< Current node in loop. */
20 };
21
22 typedef struct _Evas_Textblock_Selection_Iterator Evas_Textblock_Selection_Iterator;
23
24 EFL_CLASS_SIMPLE_CLASS(efl_text_cursor_object, "Efl.Text.Cursor", EFL_TEXT_CURSOR_OBJECT_CLASS)
25
26 EOLIAN static void
_efl_text_cursor_object_position_set(Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd,int position)27 _efl_text_cursor_object_position_set(Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd, int position)
28 {
29 evas_textblock_cursor_pos_set(pd->handle, position);
30 }
31
32 EOLIAN static int
_efl_text_cursor_object_position_get(const Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd)33 _efl_text_cursor_object_position_get(const Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd)
34 {
35 return evas_textblock_cursor_pos_get(pd->handle);
36 }
37
38 EOLIAN static Eina_Unicode
_efl_text_cursor_object_content_get(const Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd)39 _efl_text_cursor_object_content_get(const Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd)
40 {
41 if (pd->handle && pd->handle->node)
42 return eina_ustrbuf_string_get(pd->handle->node->unicode)[pd->handle->pos];
43 else
44 return 0;
45 }
46
47 EOLIAN static Eina_Rect
_efl_text_cursor_object_content_geometry_get(const Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd)48 _efl_text_cursor_object_content_geometry_get(const Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd)
49 {
50 Eina_Rect rect = {0};
51 Eina_Bool item_is = evas_textblock_cursor_format_item_geometry_get(pd->handle, &(rect.x), &(rect.y), &(rect.w), &(rect.h));
52 if (item_is)
53 return rect;
54
55 evas_textblock_cursor_pen_geometry_get(pd->handle, &(rect.x), &(rect.y), &(rect.w), &(rect.h));
56
57 return rect;
58 }
59
60 EOLIAN static void
_efl_text_cursor_object_line_number_set(Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd,int line_number)61 _efl_text_cursor_object_line_number_set(Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd, int line_number)
62 {
63 evas_textblock_cursor_line_set(pd->handle, line_number);
64 }
65
66 EOLIAN static int
_efl_text_cursor_object_line_number_get(const Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd)67 _efl_text_cursor_object_line_number_get(const Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd)
68 {
69 Eina_Rect rect = {0};
70
71 return evas_textblock_cursor_line_geometry_get(pd->handle, &(rect.x), &(rect.y), &(rect.w), &(rect.h));
72 }
73
74 EOLIAN static Eina_Rect
_efl_text_cursor_object_cursor_geometry_get(const Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd,Efl_Text_Cursor_Type ctype)75 _efl_text_cursor_object_cursor_geometry_get(const Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd, Efl_Text_Cursor_Type ctype)
76 {
77 Eina_Rect rc = {0};
78 Evas_Textblock_Cursor_Type cursor_type = (ctype == EFL_TEXT_CURSOR_TYPE_BEFORE) ? EVAS_TEXTBLOCK_CURSOR_BEFORE : EVAS_TEXTBLOCK_CURSOR_UNDER;
79 evas_textblock_cursor_geometry_bidi_get(pd->handle, &rc.x, &rc.y, &rc.w, &rc.h, NULL, NULL, NULL, NULL, cursor_type);
80 return rc;
81 }
82
83 EOLIAN static Eina_Bool
_efl_text_cursor_object_lower_cursor_geometry_get(const Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd,Eina_Rect * geometry2)84 _efl_text_cursor_object_lower_cursor_geometry_get(const Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd, Eina_Rect *geometry2)
85 {
86 Eina_Rect rc = {0};
87 Eina_Bool b_ret = EINA_FALSE;
88 b_ret = evas_textblock_cursor_geometry_bidi_get(pd->handle, NULL, NULL, NULL, NULL, &rc.x, &rc.y, &rc.w, &rc.h, EVAS_TEXTBLOCK_CURSOR_BEFORE);
89 if (geometry2)
90 {
91 *geometry2 = rc;
92 }
93 return b_ret;
94 }
95
96 EOLIAN static Eina_Bool
_efl_text_cursor_object_equal(const Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd,const Efl_Text_Cursor_Object * dst)97 _efl_text_cursor_object_equal(const Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd, const Efl_Text_Cursor_Object *dst)
98 {
99 return evas_textblock_cursor_equal(pd->handle, efl_text_cursor_object_handle_get(dst));
100 }
101
102 EOLIAN static int
_efl_text_cursor_object_compare(const Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd,const Efl_Text_Cursor_Object * dst)103 _efl_text_cursor_object_compare(const Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd, const Efl_Text_Cursor_Object *dst)
104 {
105 return evas_textblock_cursor_compare(pd->handle, efl_text_cursor_object_handle_get(dst));
106 }
107
108 static void
_efl_text_cursor_object_copy(const Efl_Text_Cursor_Object * obj,Efl_Text_Cursor_Object * dst)109 _efl_text_cursor_object_copy(const Efl_Text_Cursor_Object *obj, Efl_Text_Cursor_Object *dst)
110 {
111 Efl_Text_Cursor_Object_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
112 EINA_SAFETY_ON_NULL_RETURN(pd);
113
114 Efl_Text_Cursor_Object_Data *pd_dest = efl_data_scope_safe_get(dst, MY_CLASS);
115 EINA_SAFETY_ON_NULL_RETURN(pd_dest);
116
117 if (!pd->handle) return;
118
119 Efl_Text_Cursor_Handle *handle = evas_object_textblock_cursor_new(pd->handle->obj);
120 evas_textblock_cursor_copy(pd->handle, handle);
121 pd_dest->text_obj = pd->text_obj;
122 efl_text_cursor_object_handle_set(dst, handle);
123 evas_textblock_cursor_unref(handle, NULL);
124 }
125
126 EOLIAN static Efl_Text_Cursor_Object *
_efl_text_cursor_object_efl_duplicate_duplicate(const Eo * obj,Efl_Text_Cursor_Object_Data * pd EINA_UNUSED)127 _efl_text_cursor_object_efl_duplicate_duplicate(const Eo *obj, Efl_Text_Cursor_Object_Data *pd EINA_UNUSED)
128 {
129 Efl_Text_Cursor_Object *dup = efl_text_cursor_object_create(efl_parent_get(obj));
130
131 _efl_text_cursor_object_copy(obj, dup);
132
133 return dup;
134 }
135
136 EOLIAN static Eina_Bool
_efl_text_cursor_object_move(Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd,Efl_Text_Cursor_Move_Type type)137 _efl_text_cursor_object_move(Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd, Efl_Text_Cursor_Move_Type type)
138 {
139 Eina_Bool moved = EINA_FALSE;
140 int pos = evas_textblock_cursor_pos_get(pd->handle);
141
142 switch (type) {
143 case EFL_TEXT_CURSOR_MOVE_TYPE_CHARACTER_NEXT :
144 moved = evas_textblock_cursor_char_next(pd->handle);
145 break;
146 case EFL_TEXT_CURSOR_MOVE_TYPE_CHARACTER_PREVIOUS :
147 moved = evas_textblock_cursor_char_prev(pd->handle);
148 break;
149 case EFL_TEXT_CURSOR_MOVE_TYPE_CLUSTER_NEXT :
150 moved = evas_textblock_cursor_cluster_next(pd->handle);
151 break;
152 case EFL_TEXT_CURSOR_MOVE_TYPE_CLUSTER_PREVIOUS :
153 moved = evas_textblock_cursor_cluster_prev(pd->handle);
154 break;
155 case EFL_TEXT_CURSOR_MOVE_TYPE_PARAGRAPH_START :
156 evas_textblock_cursor_paragraph_char_first(pd->handle);
157 if (pos != evas_textblock_cursor_pos_get(pd->handle))
158 moved = EINA_TRUE;
159 break;
160 case EFL_TEXT_CURSOR_MOVE_TYPE_PARAGRAPH_END :
161 evas_textblock_cursor_paragraph_char_last(pd->handle);
162 if (pos != evas_textblock_cursor_pos_get(pd->handle))
163 moved = EINA_TRUE;
164 break;
165 case EFL_TEXT_CURSOR_MOVE_TYPE_WORD_START :
166 moved = evas_textblock_cursor_word_start(pd->handle);
167 break;
168 case EFL_TEXT_CURSOR_MOVE_TYPE_WORD_END :
169 moved = evas_textblock_cursor_word_end(pd->handle);
170 break;
171 case EFL_TEXT_CURSOR_MOVE_TYPE_LINE_START :
172 evas_textblock_cursor_line_char_first(pd->handle);
173 if (pos != evas_textblock_cursor_pos_get(pd->handle))
174 moved = EINA_TRUE;
175 break;
176 case EFL_TEXT_CURSOR_MOVE_TYPE_LINE_END :
177 evas_textblock_cursor_line_char_last(pd->handle);
178 if (pos != evas_textblock_cursor_pos_get(pd->handle))
179 moved = EINA_TRUE;
180 break;
181 case EFL_TEXT_CURSOR_MOVE_TYPE_FIRST :
182 evas_textblock_cursor_paragraph_first(pd->handle);
183 if (pos != evas_textblock_cursor_pos_get(pd->handle))
184 moved = EINA_TRUE;
185 break;
186 case EFL_TEXT_CURSOR_MOVE_TYPE_LAST :
187 evas_textblock_cursor_paragraph_last(pd->handle);
188 if (pos != evas_textblock_cursor_pos_get(pd->handle))
189 moved = EINA_TRUE;
190 break;
191 case EFL_TEXT_CURSOR_MOVE_TYPE_PARAGRAPH_NEXT :
192 moved = evas_textblock_cursor_paragraph_next(pd->handle);
193 break;
194 case EFL_TEXT_CURSOR_MOVE_TYPE_PARAGRAPH_PREVIOUS :
195 moved = evas_textblock_cursor_paragraph_prev(pd->handle);
196 break;
197 }
198
199 return moved;
200 }
201
202 EOLIAN static void
_efl_text_cursor_object_char_delete(Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd)203 _efl_text_cursor_object_char_delete(Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd)
204 {
205 evas_textblock_cursor_char_delete(pd->handle);
206 }
207
208 EOLIAN static Eina_Bool
_efl_text_cursor_object_line_jump_by(Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd,int by)209 _efl_text_cursor_object_line_jump_by(Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd, int by)
210 {
211 if (!pd->handle) return EINA_FALSE;
212
213 Eina_Bool moved = EINA_FALSE;
214 int pos = evas_textblock_cursor_pos_get(pd->handle);
215 evas_textblock_cursor_line_jump_by(pd->handle, by);
216 moved = (pos != evas_textblock_cursor_pos_get(pd->handle));
217 return moved;
218 }
219
220 EOLIAN static void
_efl_text_cursor_object_char_coord_set(Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd,Eina_Position2D coord)221 _efl_text_cursor_object_char_coord_set(Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd, Eina_Position2D coord)
222 {
223 evas_textblock_cursor_char_coord_set(pd->handle, coord.x, coord.y);
224 }
225
226 EOLIAN static void
_efl_text_cursor_object_cluster_coord_set(Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd,Eina_Position2D coord)227 _efl_text_cursor_object_cluster_coord_set(Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd, Eina_Position2D coord)
228 {
229 evas_textblock_cursor_cluster_coord_set(pd->handle, coord.x, coord.y);
230 }
231
232 static int
_prepend_text_run2(Efl_Text_Cursor_Handle * cur,const char * s,const char * p)233 _prepend_text_run2(Efl_Text_Cursor_Handle *cur, const char *s, const char *p)
234 {
235 if ((s) && (p > s))
236 {
237 char *ts;
238
239 ts = alloca(p - s + 1);
240 strncpy(ts, s, p - s);
241 ts[p - s] = 0;
242 return evas_textblock_cursor_text_prepend(cur, ts);
243 }
244 return 0;
245 }
246
247 int
_cursor_text_append(Efl_Text_Cursor_Handle * cur,const char * text)248 _cursor_text_append(Efl_Text_Cursor_Handle *cur,
249 const char *text)
250 {
251 if (!text || !cur) return 0;
252
253 const char *off = text;
254 int len = 0;
255
256 Evas_Object_Protected_Data *obj = efl_data_scope_safe_get(cur->obj, EFL_CANVAS_OBJECT_CLASS);
257 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, 0);
258 evas_object_async_block(obj);
259
260 while (*off)
261 {
262 char *format = NULL;
263 int n = 1;
264 if (!strncmp(_PARAGRAPH_SEPARATOR_UTF8, off,
265 strlen(_PARAGRAPH_SEPARATOR_UTF8)))
266 {
267 format = "ps";
268 n = strlen(_PARAGRAPH_SEPARATOR_UTF8);
269 }
270 else if (!strncmp(_NEWLINE_UTF8, off, strlen(_NEWLINE_UTF8)))
271 {
272 format = "br";
273 n = strlen(_NEWLINE_UTF8);
274 }
275 else if (!strncmp(_TAB_UTF8, off, strlen(_TAB_UTF8)))
276 {
277 format = "tab";
278 n = strlen(_TAB_UTF8);
279 }
280
281 if (format)
282 {
283 len += _prepend_text_run2(cur, text, off);
284 if (evas_textblock_cursor_format_prepend(cur, format))
285 {
286 len++;
287 }
288 text = off + n; /* sync text with next segment */
289 }
290 off += n;
291 }
292 len += _prepend_text_run2(cur, text, off);
293 return len;
294 }
295
296 EOLIAN static void
_efl_text_cursor_object_text_insert(Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd,const char * text)297 _efl_text_cursor_object_text_insert(Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd, const char *text)
298 {
299 _cursor_text_append(pd->handle, text);
300 }
301
302 EOLIAN static char *
_efl_text_cursor_object_range_text_get(const Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd,Efl_Text_Cursor_Object * cur2)303 _efl_text_cursor_object_range_text_get(const Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd, Efl_Text_Cursor_Object *cur2)
304 {
305 return evas_textblock_cursor_range_text_get(pd->handle, efl_text_cursor_object_handle_get(cur2), EVAS_TEXTBLOCK_TEXT_PLAIN);
306 }
307
308 EOLIAN static void
_efl_text_cursor_object_markup_insert(Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd,const char * markup)309 _efl_text_cursor_object_markup_insert(Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd, const char *markup)
310 {
311 evas_object_textblock_text_markup_prepend(pd->handle, markup);
312 }
313
314 EOLIAN static char *
_efl_text_cursor_object_range_markup_get(const Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd,Efl_Text_Cursor_Object * cur2)315 _efl_text_cursor_object_range_markup_get(const Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd, Efl_Text_Cursor_Object *cur2)
316 {
317 return evas_textblock_cursor_range_text_get(pd->handle,efl_text_cursor_object_handle_get(cur2), EVAS_TEXTBLOCK_TEXT_MARKUP);
318 }
319
320 EOLIAN static Eina_Iterator *
_efl_text_cursor_object_range_geometry_get(Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd,Efl_Text_Cursor_Object * cur2)321 _efl_text_cursor_object_range_geometry_get(Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd, Efl_Text_Cursor_Object *cur2)
322 {
323 return evas_textblock_cursor_range_simple_geometry_get(pd->handle, efl_text_cursor_object_handle_get(cur2));
324 }
325
326 /** selection iterator */
327 /**
328 * @internal
329 * Returns the value of the current data of list node,
330 * and goes to the next list node.
331 *
332 * @param it the iterator.
333 * @param data the data of the current list node.
334 * @return EINA_FALSE if the current list node does not exists.
335 * Otherwise, returns EINA_TRUE.
336 */
337 static Eina_Bool
_evas_textblock_selection_iterator_next(Evas_Textblock_Selection_Iterator * it,void ** data)338 _evas_textblock_selection_iterator_next(Evas_Textblock_Selection_Iterator *it, void **data)
339 {
340 if (!it->current)
341 return EINA_FALSE;
342
343 *data = eina_list_data_get(it->current);
344 it->current = eina_list_next(it->current);
345
346 return EINA_TRUE;
347 }
348
349 /**
350 * @internal
351 * Gets the iterator container (Eina_List) which created the iterator.
352 * @param it the iterator.
353 * @return A pointer to Eina_List.
354 */
355 static Eina_List *
_evas_textblock_selection_iterator_get_container(Evas_Textblock_Selection_Iterator * it)356 _evas_textblock_selection_iterator_get_container(Evas_Textblock_Selection_Iterator *it)
357 {
358 return it->list;
359 }
360
361 /**
362 * @internal
363 * Frees the iterator container (Eina_List).
364 * @param it the iterator.
365 */
366 static void
_evas_textblock_selection_iterator_free(Evas_Textblock_Selection_Iterator * it)367 _evas_textblock_selection_iterator_free(Evas_Textblock_Selection_Iterator *it)
368 {
369 Eina_Rectangle *tr;
370
371 EINA_LIST_FREE(it->list, tr)
372 free(tr);
373 EINA_MAGIC_SET(&it->iterator, 0);
374 free(it);
375 }
376
377 /**
378 * @internal
379 * Creates newly allocated iterator associated to a list.
380 * @param list The list.
381 * @return If the memory cannot be allocated, NULL is returned.
382 * Otherwise, a valid iterator is returned.
383 */
384 static Eina_Iterator *
_evas_textblock_selection_iterator_new(Eina_List * list)385 _evas_textblock_selection_iterator_new(Eina_List *list)
386 {
387 Evas_Textblock_Selection_Iterator *it;
388
389 it = calloc(1, sizeof(Evas_Textblock_Selection_Iterator));
390 if (!it) return NULL;
391
392 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
393 it->list = list;
394 it->current = list;
395
396 it->iterator.version = EINA_ITERATOR_VERSION;
397 it->iterator.next = FUNC_ITERATOR_NEXT(
398 _evas_textblock_selection_iterator_next);
399 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
400 _evas_textblock_selection_iterator_get_container);
401 it->iterator.free = FUNC_ITERATOR_FREE(
402 _evas_textblock_selection_iterator_free);
403
404 return &it->iterator;
405 }
406
407 EOLIAN static Eina_Iterator *
_efl_text_cursor_object_range_precise_geometry_get(Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd,Efl_Text_Cursor_Object * cur2)408 _efl_text_cursor_object_range_precise_geometry_get(Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd, Efl_Text_Cursor_Object *cur2)
409 {
410 Eina_List *rects = evas_textblock_cursor_range_geometry_get(pd->handle, efl_text_cursor_object_handle_get(cur2));
411 return _evas_textblock_selection_iterator_new(rects);
412 }
413
414 EOLIAN static void
_efl_text_cursor_object_range_delete(Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd,Efl_Text_Cursor_Object * cur2)415 _efl_text_cursor_object_range_delete(Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd, Efl_Text_Cursor_Object *cur2)
416 {
417 evas_textblock_cursor_range_delete(pd->handle, efl_text_cursor_object_handle_get(cur2));
418 }
419
420 EAPI void
efl_text_cursor_object_handle_set(Eo * obj,Efl_Text_Cursor_Handle * handle)421 efl_text_cursor_object_handle_set(Eo *obj, Efl_Text_Cursor_Handle *handle)
422 {
423 Efl_Text_Cursor_Object_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
424 EINA_SAFETY_ON_NULL_RETURN(pd);
425 if (handle == pd->handle)
426 return;
427
428 Efl_Text_Cursor_Handle *old_handle = pd->handle;
429
430 pd->handle = evas_textblock_cursor_ref(handle, obj);
431
432 if (old_handle)
433 {
434 evas_textblock_cursor_unref(old_handle, obj);
435 }
436 }
437
438 EAPI Efl_Text_Cursor_Handle *
efl_text_cursor_object_handle_get(const Eo * obj)439 efl_text_cursor_object_handle_get(const Eo *obj)
440 {
441 Efl_Text_Cursor_Object_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
442 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL);
443 return pd->handle;
444 }
445
efl_text_cursor_object_create(Eo * parent)446 Eo* efl_text_cursor_object_create(Eo *parent)
447 {
448 return efl_add(efl_text_cursor_object_realized_class_get(), parent);
449 }
450
efl_text_cursor_object_text_object_set(Eo * cursor,Eo * canvas_text_obj,Eo * text_obj)451 void efl_text_cursor_object_text_object_set(Eo *cursor, Eo *canvas_text_obj, Eo *text_obj)
452 {
453 Efl_Text_Cursor_Object_Data *pd = efl_data_scope_safe_get(cursor, MY_CLASS);
454 EINA_SAFETY_ON_NULL_RETURN(pd);
455 Efl_Text_Cursor_Handle *handle = NULL;
456 if (efl_isa(canvas_text_obj, EFL_CANVAS_TEXTBLOCK_CLASS))
457 {
458 pd->text_obj = text_obj;
459 handle = evas_object_textblock_cursor_new(canvas_text_obj);
460 }
461 else
462 {
463 ERR("Expect Canvas Text Object");
464 }
465
466 if (handle)
467 {
468 efl_text_cursor_object_handle_set(cursor, handle);
469 evas_textblock_cursor_unref(handle, NULL);
470 }
471 }
472
473 EOLIAN static Efl_Canvas_Object *
_efl_text_cursor_object_text_object_get(const Eo * obj EINA_UNUSED,Efl_Text_Cursor_Object_Data * pd)474 _efl_text_cursor_object_text_object_get(const Eo *obj EINA_UNUSED, Efl_Text_Cursor_Object_Data *pd)
475 {
476 return pd->text_obj;
477 }
478
479 EOLIAN static void
_efl_text_cursor_object_efl_object_destructor(Eo * obj,Efl_Text_Cursor_Object_Data * pd)480 _efl_text_cursor_object_efl_object_destructor(Eo *obj, Efl_Text_Cursor_Object_Data *pd)
481 {
482 if (pd->handle)
483 {
484 evas_textblock_cursor_unref(pd->handle, obj);
485 pd->handle = NULL;
486 }
487
488 if (pd->text_obj)
489 {
490 pd->text_obj = NULL;
491 }
492
493 efl_destructor(efl_super(obj, MY_CLASS));
494
495 }
496
497 #include "efl_text_cursor_object.eo.c"
498