forked from enlightenment/efl
6593 lines
174 KiB
C
6593 lines
174 KiB
C
#include "edje_private.h"
|
|
|
|
#include "../evas/canvas/evas_box_eo.h"
|
|
#include "../evas/canvas/evas_line_eo.h"
|
|
#include "../evas/canvas/evas_text_eo.h"
|
|
|
|
typedef struct _Edje_Box_Layout Edje_Box_Layout;
|
|
struct _Edje_Box_Layout
|
|
{
|
|
EINA_RBTREE;
|
|
Evas_Object_Box_Layout func;
|
|
void *(*layout_data_get)(void *);
|
|
void (*layout_data_free)(void *);
|
|
void *data;
|
|
void (*free_data)(void *);
|
|
char name[];
|
|
};
|
|
|
|
static Eina_Hash *_edje_color_class_hash = NULL;
|
|
static Eina_Hash *_edje_text_class_hash = NULL;
|
|
static Eina_Hash *_edje_size_class_hash = NULL;
|
|
|
|
Efl_Observable *_edje_color_class_member = NULL;
|
|
Efl_Observable *_edje_text_class_member = NULL;
|
|
Efl_Observable *_edje_size_class_member = NULL;
|
|
|
|
static Eina_Rbtree *_edje_box_layout_registry = NULL;
|
|
|
|
char *_edje_fontset_append = NULL;
|
|
char *_edje_fontset_append_escaped = NULL;
|
|
FLOAT_T _edje_scale = ZERO;
|
|
Eina_Bool _edje_password_show_last = EINA_FALSE;
|
|
double _edje_password_show_last_timeout = 0;
|
|
int _edje_util_freeze_val = 0;
|
|
int _edje_util_freeze_calc_count = 0;
|
|
Eina_List *_edje_util_freeze_calc_list = NULL;
|
|
|
|
const char *_edje_language = NULL;
|
|
const char *_edje_cache_path = NULL;
|
|
|
|
typedef struct _Edje_List_Foreach_Data Edje_List_Foreach_Data;
|
|
struct _Edje_List_Foreach_Data
|
|
{
|
|
Eina_List *list;
|
|
};
|
|
|
|
typedef struct _Edje_Refcount Edje_Refcount;
|
|
struct _Edje_Refcount
|
|
{
|
|
EINA_REFCOUNT;
|
|
|
|
Edje *ed;
|
|
};
|
|
|
|
static Eina_Bool _edje_color_class_list_foreach(const Eina_Hash *hash, const void *key, void *data, void *fdata);
|
|
static Eina_Bool _edje_text_class_list_foreach(const Eina_Hash *hash, const void *key, void *data, void *fdata);
|
|
static Eina_Bool _edje_size_class_list_foreach(const Eina_Hash *hash, const void *key, void *data, void *fdata);
|
|
static void _edje_object_image_preload_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
|
|
static void _edje_object_signal_preload_cb(void *data, Evas_Object *obj, const char *emission, const char *source);
|
|
static void _edje_user_def_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *child EINA_UNUSED, void *einfo EINA_UNUSED);
|
|
static void _edje_child_remove(Edje *ed, Edje_Real_Part *rp, Evas_Object *child);
|
|
|
|
Edje_Real_Part *_edje_real_part_recursive_get_helper(Edje **ed, char **path);
|
|
|
|
static void
|
|
_edje_user_definition_free_internal(Edje_User_Defined *eud)
|
|
{
|
|
Evas_Object *child = NULL;
|
|
switch (eud->type)
|
|
{
|
|
case EDJE_USER_SWALLOW:
|
|
child = eud->u.swallow.child;
|
|
break;
|
|
|
|
case EDJE_USER_BOX_PACK:
|
|
child = eud->u.box.child;
|
|
break;
|
|
|
|
case EDJE_USER_TABLE_PACK:
|
|
child = eud->u.table.child;
|
|
break;
|
|
|
|
default: break;
|
|
}
|
|
if (child) evas_object_event_callback_del_full(child, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
|
|
eina_stringshare_del(eud->part);
|
|
free(eud);
|
|
}
|
|
|
|
static void
|
|
_edje_user_definition_list_free_internal(Eina_List *l)
|
|
{
|
|
Edje_User_Defined *eud;
|
|
EINA_LIST_FREE(l, eud)
|
|
_edje_user_definition_free_internal(eud);
|
|
}
|
|
|
|
static Edje_User_Defined *
|
|
_edje_user_definition_new(Edje_User_Defined_Type type, const char *part, Edje *ed)
|
|
{
|
|
Edje_User_Defined *eud;
|
|
|
|
if (!ed->user_defined)
|
|
ed->user_defined = eina_hash_string_superfast_new((Eina_Free_Cb)_edje_user_definition_list_free_internal);
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(ed->user_defined, NULL);
|
|
|
|
eud = malloc(sizeof (Edje_User_Defined));
|
|
if (!eud) return NULL;
|
|
|
|
eud->type = type;
|
|
eud->part = eina_stringshare_add(part);
|
|
eud->ed = ed;
|
|
eina_hash_list_direct_append(ed->user_defined, eud->part, eud);
|
|
|
|
return eud;
|
|
}
|
|
|
|
void
|
|
_edje_user_definition_free(Edje_User_Defined *eud)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
switch (eud->type)
|
|
{
|
|
case EDJE_USER_SWALLOW:
|
|
rp = _edje_real_part_recursive_get(&eud->ed, eud->part);
|
|
if (rp)
|
|
{
|
|
_edje_real_part_swallow_clear(eud->ed, rp);
|
|
if ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
|
|
(rp->typedata.swallow))
|
|
{
|
|
rp->typedata.swallow->swallowed_object = NULL;
|
|
rp->typedata.swallow->swallow_params.min.w = 0;
|
|
rp->typedata.swallow->swallow_params.min.h = 0;
|
|
rp->typedata.swallow->swallow_params.max.w = 0;
|
|
rp->typedata.swallow->swallow_params.max.h = 0;
|
|
}
|
|
eud->ed->dirty = EINA_TRUE;
|
|
eud->ed->recalc_call = EINA_TRUE;
|
|
#ifdef EDJE_CALC_CACHE
|
|
rp->invalidate = EINA_TRUE;
|
|
#endif
|
|
/* this seems to be as unnecessary as the one in part_unswallow()
|
|
* cedric, 1 February 2016
|
|
*/
|
|
// _edje_recalc_do(eud->ed);
|
|
}
|
|
break;
|
|
|
|
case EDJE_USER_BOX_PACK:
|
|
rp = _edje_real_part_recursive_get(&eud->ed, eud->part);
|
|
if (rp) _edje_child_remove(eud->ed, rp, eud->u.box.child);
|
|
break;
|
|
|
|
case EDJE_USER_TABLE_PACK:
|
|
rp = _edje_real_part_recursive_get(&eud->ed, eud->part);
|
|
if (rp) _edje_child_remove(eud->ed, rp, eud->u.table.child);
|
|
break;
|
|
|
|
case EDJE_USER_TEXT_STYLE:
|
|
{
|
|
Edje_Part_Text_Prop *prop;
|
|
EINA_LIST_FREE(eud->u.text_style.props, prop)
|
|
{
|
|
free(prop);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case EDJE_USER_STRING:
|
|
case EDJE_USER_DRAG_STEP:
|
|
case EDJE_USER_DRAG_PAGE:
|
|
case EDJE_USER_DRAG_VALUE:
|
|
case EDJE_USER_DRAG_SIZE:
|
|
case EDJE_USER_TEXT_EXPAND:
|
|
break;
|
|
}
|
|
|
|
/* edje may be destructing */
|
|
if (eud->ed->user_defined) eina_hash_list_remove(eud->ed->user_defined, eud->part, eud);
|
|
_edje_user_definition_free_internal(eud);
|
|
}
|
|
|
|
static void
|
|
_edje_user_def_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *child EINA_UNUSED, void *einfo EINA_UNUSED)
|
|
{
|
|
Edje_User_Defined *eud = data;
|
|
|
|
_edje_user_definition_free(eud);
|
|
}
|
|
|
|
/************************** API Routines **************************/
|
|
|
|
#define FASTFREEZE 1
|
|
|
|
EAPI void
|
|
edje_freeze(void)
|
|
{
|
|
#ifdef FASTFREEZE
|
|
_edje_util_freeze_val++;
|
|
#else
|
|
// FIXME: could just have a global freeze instead of per object
|
|
// above i tried.. but this broke some things. notable e17's menus. why?
|
|
Edje *ed;
|
|
|
|
EINA_INLIST_FOREACH(_edje_edjes, ed) edje_object_freeze(ed->obj);
|
|
#endif
|
|
}
|
|
|
|
#ifdef FASTFREEZE
|
|
static void
|
|
_edje_util_thaw_edje(Edje *ed)
|
|
{
|
|
unsigned short i;
|
|
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
rp = ed->table_parts[i];
|
|
if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
|
|
((rp->type == EDJE_RP_TYPE_SWALLOW) &&
|
|
(rp->typedata.swallow)) &&
|
|
(rp->typedata.swallow->swallowed_object))
|
|
{
|
|
Edje *ed2;
|
|
|
|
ed2 = _edje_fetch(rp->typedata.swallow->swallowed_object);
|
|
if (ed2) _edje_util_thaw_edje(ed2);
|
|
}
|
|
}
|
|
if ((ed->recalc) && (ed->freeze == 0)) _edje_recalc_do(ed);
|
|
}
|
|
|
|
#endif
|
|
|
|
void
|
|
_edje_language_signal_emit(Edje *ed, Evas_Object *obj, char *signal)
|
|
{
|
|
unsigned short i;
|
|
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp = ed->table_parts[i];
|
|
|
|
if (rp->part->type == EDJE_PART_TYPE_TEXT ||
|
|
rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
|
|
{
|
|
Edje_Part_Description_Text *text;
|
|
|
|
text = (Edje_Part_Description_Text *)rp->param1.description;
|
|
if (text->text.text.translated)
|
|
text->text.text.translated = NULL;
|
|
|
|
if (rp->param2)
|
|
{
|
|
text = (Edje_Part_Description_Text *)rp->param2->description;
|
|
if (text->text.text.translated)
|
|
text->text.text.translated = NULL;
|
|
}
|
|
|
|
if (rp->custom)
|
|
{
|
|
text = (Edje_Part_Description_Text *)rp->custom->description;
|
|
if (text->text.text.translated)
|
|
text->text.text.translated = NULL;
|
|
}
|
|
}
|
|
}
|
|
edje_object_signal_emit(obj, signal, "edje");
|
|
edje_object_calc_force(obj);
|
|
}
|
|
|
|
EOLIAN void
|
|
_efl_canvas_layout_efl_ui_i18n_language_set(Eo *obj, Edje *ed, const char *locale)
|
|
{
|
|
const char *lookup;
|
|
char *signal;
|
|
size_t length;
|
|
|
|
if (!locale) return;
|
|
lookup = strstr(locale, ".");
|
|
length = lookup ? (size_t)(lookup - locale) : strlen(locale);
|
|
|
|
eina_stringshare_replace_length(&ed->language, locale, length);
|
|
|
|
signal = alloca(length + 15);
|
|
if (ed->language)
|
|
snprintf(signal, length + 15, "edje,language,%s", ed->language);
|
|
else
|
|
snprintf(signal, length + 15, "edje,language,%s", "none");
|
|
|
|
_edje_language_signal_emit(ed, obj, signal);
|
|
}
|
|
|
|
EOLIAN const char *
|
|
_efl_canvas_layout_efl_ui_i18n_language_get(const Eo *obj EINA_UNUSED, Edje *ed)
|
|
{
|
|
if (!ed->language)
|
|
return _edje_language;
|
|
|
|
return ed->language;
|
|
}
|
|
|
|
EAPI void
|
|
edje_language_set(const char *locale)
|
|
{
|
|
Edje *ed;
|
|
const char *lookup;
|
|
char *signal;
|
|
char *loc;
|
|
int length;
|
|
|
|
lookup = strstr(locale, ".");
|
|
length = lookup ? lookup - locale : (int)strlen(locale);
|
|
loc = alloca(length + 1);
|
|
memcpy(loc, locale, length);
|
|
loc[length] = '\0';
|
|
|
|
eina_stringshare_replace(&_edje_language, loc);
|
|
|
|
signal = alloca(length + 15);
|
|
snprintf(signal, length + 15, "edje,language,%s", loc);
|
|
|
|
EINA_INLIST_FOREACH(_edje_edjes, ed)
|
|
{
|
|
if (ed->language) continue;
|
|
_edje_language_signal_emit(ed, ed->obj, signal);
|
|
}
|
|
}
|
|
|
|
EAPI void
|
|
edje_thaw(void)
|
|
{
|
|
#ifdef FASTFREEZE
|
|
if (!_edje_util_freeze_val) return;
|
|
_edje_util_freeze_val--;
|
|
if ((_edje_util_freeze_val == 0) && (_edje_util_freeze_calc_count > 0))
|
|
{
|
|
Edje *ed;
|
|
|
|
_edje_util_freeze_calc_count = 0;
|
|
EINA_LIST_FREE(_edje_util_freeze_calc_list, ed)
|
|
{
|
|
_edje_util_thaw_edje(ed);
|
|
ed->freeze_calc = EINA_FALSE;
|
|
}
|
|
}
|
|
#else
|
|
Edje *ed;
|
|
|
|
EINA_INLIST_FOREACH(_edje_edjes, ed) edje_object_thaw(ed->obj);
|
|
#endif
|
|
}
|
|
|
|
EAPI void
|
|
edje_fontset_append_set(const char *fonts)
|
|
{
|
|
if (_edje_fontset_append)
|
|
{
|
|
free(_edje_fontset_append);
|
|
free(_edje_fontset_append_escaped);
|
|
}
|
|
_edje_fontset_append = fonts ? strdup(fonts) : NULL;
|
|
_edje_fontset_append_escaped = fonts ? eina_str_escape(fonts) : NULL;
|
|
}
|
|
|
|
EAPI const char *
|
|
edje_fontset_append_get(void)
|
|
{
|
|
return _edje_fontset_append;
|
|
}
|
|
|
|
EAPI void
|
|
edje_scale_set(double scale)
|
|
{
|
|
Edje *ed;
|
|
|
|
if (EQ(_edje_scale, FROM_DOUBLE(scale))) return;
|
|
_edje_scale = FROM_DOUBLE(scale);
|
|
EINA_INLIST_FOREACH(_edje_edjes, ed) edje_object_calc_force(ed->obj);
|
|
}
|
|
|
|
EAPI double
|
|
edje_scale_get(void)
|
|
{
|
|
return TO_DOUBLE(_edje_scale);
|
|
}
|
|
|
|
EAPI void
|
|
edje_password_show_last_set(Eina_Bool password_show_last)
|
|
{
|
|
if (_edje_password_show_last == password_show_last) return;
|
|
_edje_password_show_last = password_show_last;
|
|
}
|
|
|
|
EAPI void
|
|
edje_password_show_last_timeout_set(double password_show_last_timeout)
|
|
{
|
|
if (EINA_DBL_EQ(_edje_password_show_last_timeout, password_show_last_timeout)) return;
|
|
_edje_password_show_last_timeout = password_show_last_timeout;
|
|
}
|
|
|
|
EOLIAN void
|
|
_efl_canvas_layout_efl_gfx_entity_scale_set(Eo *obj EINA_UNUSED, Edje *ed, double scale)
|
|
{
|
|
Edje *ged;
|
|
Evas_Object *o;
|
|
Eina_List *l;
|
|
unsigned short i;
|
|
|
|
if (EQ(ed->scale, FROM_DOUBLE(scale))) return;
|
|
ed->scale = FROM_DOUBLE(scale);
|
|
EINA_LIST_FOREACH(ed->groups, l, ged)
|
|
edje_object_scale_set(ged->obj, scale);
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *ep;
|
|
ep = ed->table_parts[i];
|
|
if ((ep->part->type == EDJE_PART_TYPE_BOX) ||
|
|
(ep->part->type == EDJE_PART_TYPE_TABLE))
|
|
{
|
|
EINA_LIST_FOREACH(ep->typedata.container->items, l, o)
|
|
edje_object_scale_set(o, scale);
|
|
}
|
|
}
|
|
_edje_recalc(ed);
|
|
}
|
|
|
|
EOLIAN double
|
|
_efl_canvas_layout_efl_gfx_entity_scale_get(const Eo *obj EINA_UNUSED, Edje *ed)
|
|
{
|
|
return TO_DOUBLE(ed->scale);
|
|
}
|
|
|
|
EAPI double
|
|
edje_object_base_scale_get(const Evas_Object *obj)
|
|
{
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
if (!ed || !ed->file) return 1.0;
|
|
return TO_DOUBLE(ed->file->base_scale);
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_efl_canvas_layout_efl_ui_i18n_mirrored_get(const Eo *obj EINA_UNUSED, Edje *ed)
|
|
{
|
|
return ed->is_rtl;
|
|
}
|
|
|
|
void
|
|
_edje_object_orientation_inform(Evas_Object *obj)
|
|
{
|
|
if (!obj) return;
|
|
if (edje_object_mirrored_get(obj))
|
|
edje_object_signal_emit(obj, "edje,state,rtl", "edje");
|
|
else
|
|
edje_object_signal_emit(obj, "edje,state,ltr", "edje");
|
|
}
|
|
|
|
EOLIAN void
|
|
_efl_canvas_layout_efl_ui_i18n_mirrored_set(Eo *obj, Edje *ed, Eina_Bool rtl)
|
|
{
|
|
unsigned short i;
|
|
|
|
if (ed->is_rtl == rtl) return;
|
|
|
|
ed->is_rtl = rtl;
|
|
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *ep;
|
|
const char *s;
|
|
double v;
|
|
|
|
ep = ed->table_parts[i];
|
|
s = ep->param1.description->state.name,
|
|
v = ep->param1.description->state.value;
|
|
_edje_part_description_apply(ed, ep, s, v, NULL, 0.0);
|
|
ep->chosen_description = ep->param1.description;
|
|
}
|
|
if (!ed->freeze) _edje_recalc_do(ed);
|
|
|
|
_edje_object_orientation_inform(obj);
|
|
|
|
return;
|
|
}
|
|
|
|
EOLIAN const char *
|
|
_efl_canvas_layout_efl_layout_group_group_data_get(const Eo *obj EINA_UNUSED, Edje *ed, const char *key)
|
|
{
|
|
if (!key) return NULL;
|
|
if (!ed->collection) return NULL;
|
|
if (!ed->collection->data) return NULL;
|
|
|
|
return edje_string_get(eina_hash_find(ed->collection->data, key));
|
|
}
|
|
|
|
EOLIAN int
|
|
_efl_canvas_layout_efl_layout_calc_calc_freeze(Eo *obj EINA_UNUSED, Edje *ed)
|
|
{
|
|
unsigned short i;
|
|
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
rp = ed->table_parts[i];
|
|
if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
|
|
((rp->type == EDJE_RP_TYPE_SWALLOW) &&
|
|
(rp->typedata.swallow)) &&
|
|
(rp->typedata.swallow->swallowed_object))
|
|
edje_object_freeze(rp->typedata.swallow->swallowed_object);
|
|
}
|
|
return _edje_util_freeze(ed);
|
|
}
|
|
|
|
EOLIAN int
|
|
_efl_canvas_layout_efl_layout_calc_calc_thaw(Eo *obj EINA_UNUSED, Edje *ed)
|
|
{
|
|
unsigned short i;
|
|
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
rp = ed->table_parts[i];
|
|
if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
|
|
((rp->type == EDJE_RP_TYPE_SWALLOW) &&
|
|
(rp->typedata.swallow)) &&
|
|
(rp->typedata.swallow->swallowed_object))
|
|
edje_object_thaw(rp->typedata.swallow->swallowed_object);
|
|
}
|
|
return _edje_util_thaw(ed);
|
|
}
|
|
|
|
static Eina_Bool
|
|
_edje_color_class_set_internal(Eina_Hash *hash, const char *color_class, Efl_Gfx_Color_Class_Layer layer, int r, int g, int b, int a, Eina_Bool *need_update)
|
|
{
|
|
Edje_Color_Class *cc;
|
|
|
|
if (!color_class)
|
|
return EINA_FALSE;
|
|
|
|
if (r < 0) r = 0;
|
|
else if (r > 255)
|
|
r = 255;
|
|
if (g < 0) g = 0;
|
|
else if (g > 255)
|
|
g = 255;
|
|
if (b < 0) b = 0;
|
|
else if (b > 255)
|
|
b = 255;
|
|
if (a < 0) a = 0;
|
|
else if (a > 255)
|
|
a = 255;
|
|
|
|
cc = eina_hash_find(hash, color_class);
|
|
if (cc)
|
|
{
|
|
switch (layer)
|
|
{
|
|
case EFL_GFX_COLOR_CLASS_LAYER_NORMAL:
|
|
if ((cc->r == r) && (cc->g == g) &&
|
|
(cc->b == b) && (cc->a == a))
|
|
{
|
|
*need_update = EINA_FALSE;
|
|
return EINA_TRUE;
|
|
}
|
|
break;
|
|
|
|
case EFL_GFX_COLOR_CLASS_LAYER_OUTLINE:
|
|
if ((cc->r2 == r) && (cc->g2 == g) &&
|
|
(cc->b2 == b) && (cc->a2 == a))
|
|
{
|
|
*need_update = EINA_FALSE;
|
|
return EINA_TRUE;
|
|
}
|
|
break;
|
|
|
|
case EFL_GFX_COLOR_CLASS_LAYER_SHADOW:
|
|
if ((cc->r3 == r) && (cc->g3 == g) &&
|
|
(cc->b3 == b) && (cc->a3 == a))
|
|
{
|
|
*need_update = EINA_FALSE;
|
|
return EINA_TRUE;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return EINA_FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cc = calloc(1, sizeof(Edje_Color_Class));
|
|
if (!cc) return EINA_FALSE;
|
|
|
|
cc->name = eina_stringshare_add(color_class);
|
|
if (!cc->name)
|
|
{
|
|
free(cc);
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
eina_hash_direct_add(hash, cc->name, cc);
|
|
}
|
|
|
|
switch (layer)
|
|
{
|
|
case EFL_GFX_COLOR_CLASS_LAYER_NORMAL:
|
|
cc->r = r;
|
|
cc->g = g;
|
|
cc->b = b;
|
|
cc->a = a;
|
|
break;
|
|
|
|
case EFL_GFX_COLOR_CLASS_LAYER_OUTLINE:
|
|
cc->r2 = r;
|
|
cc->g2 = g;
|
|
cc->b2 = b;
|
|
cc->a2 = a;
|
|
break;
|
|
|
|
case EFL_GFX_COLOR_CLASS_LAYER_SHADOW:
|
|
cc->r3 = r;
|
|
cc->g3 = g;
|
|
cc->b3 = b;
|
|
cc->a3 = a;
|
|
break;
|
|
}
|
|
|
|
*need_update = EINA_TRUE;
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_edje_color_class_get_internal(Edje_Color_Class *cc, Efl_Gfx_Color_Class_Layer layer, int *r, int *g, int *b, int *a)
|
|
{
|
|
if (cc)
|
|
{
|
|
switch (layer)
|
|
{
|
|
case EFL_GFX_COLOR_CLASS_LAYER_NORMAL:
|
|
if (r) *r = cc->r;
|
|
if (g) *g = cc->g;
|
|
if (b) *b = cc->b;
|
|
if (a) *a = cc->a;
|
|
break;
|
|
|
|
case EFL_GFX_COLOR_CLASS_LAYER_OUTLINE:
|
|
if (r) *r = cc->r2;
|
|
if (g) *g = cc->g2;
|
|
if (b) *b = cc->b2;
|
|
if (a) *a = cc->a2;
|
|
break;
|
|
|
|
case EFL_GFX_COLOR_CLASS_LAYER_SHADOW:
|
|
if (r) *r = cc->r3;
|
|
if (g) *g = cc->g3;
|
|
if (b) *b = cc->b3;
|
|
if (a) *a = cc->a3;
|
|
break;
|
|
}
|
|
return EINA_TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (r) *r = 0;
|
|
if (g) *g = 0;
|
|
if (b) *b = 0;
|
|
if (a) *a = 0;
|
|
|
|
return EINA_FALSE;
|
|
}
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_color_class_set(const char *color_class, int r, int g, int b, int a, int r2, int g2, int b2, int a2, int r3, int g3, int b3, int a3)
|
|
{
|
|
Eina_Bool int_ret = EINA_TRUE;
|
|
|
|
int_ret &= efl_gfx_color_class_set(_edje_global(), color_class, EFL_GFX_COLOR_CLASS_LAYER_NORMAL, r, g, b, a);
|
|
int_ret &= efl_gfx_color_class_set(_edje_global(), color_class, EFL_GFX_COLOR_CLASS_LAYER_OUTLINE, r2, g2, b2, a2);
|
|
int_ret &= efl_gfx_color_class_set(_edje_global(), color_class, EFL_GFX_COLOR_CLASS_LAYER_SHADOW, r3, g3, b3, a3);
|
|
|
|
return int_ret;
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_edje_global_efl_gfx_color_class_color_class_set(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED,
|
|
const char *color_class, Efl_Gfx_Color_Class_Layer layer, int r, int g, int b, int a)
|
|
{
|
|
Eina_Bool int_ret;
|
|
Eina_Bool need_update = EINA_FALSE;
|
|
|
|
if (!_edje_color_class_hash)
|
|
_edje_color_class_hash = eina_hash_string_superfast_new(NULL);
|
|
|
|
int_ret = _edje_color_class_set_internal(_edje_color_class_hash, color_class, layer, r, g, b, a, &need_update);
|
|
|
|
if ((int_ret) && (need_update))
|
|
efl_observable_observers_update(_edje_color_class_member, color_class, "color_class,set");
|
|
|
|
return int_ret;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_color_class_get(const char *color_class, int *r, int *g, int *b, int *a, int *r2, int *g2, int *b2, int *a2, int *r3, int *g3, int *b3, int *a3)
|
|
{
|
|
Eina_Bool int_ret = EINA_TRUE;
|
|
|
|
int_ret &= efl_gfx_color_class_get(_edje_global(), color_class, EFL_GFX_COLOR_CLASS_LAYER_NORMAL, r, g, b, a);
|
|
int_ret &= efl_gfx_color_class_get(_edje_global(), color_class, EFL_GFX_COLOR_CLASS_LAYER_OUTLINE, r2, g2, b2, a2);
|
|
int_ret &= efl_gfx_color_class_get(_edje_global(), color_class, EFL_GFX_COLOR_CLASS_LAYER_SHADOW, r3, g3, b3, a3);
|
|
|
|
return int_ret;
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_edje_global_efl_gfx_color_class_color_class_get(const Eo *obj EINA_UNUSED, void *pd EINA_UNUSED,
|
|
const char *color_class, Efl_Gfx_Color_Class_Layer layer, int *r, int *g, int *b, int *a)
|
|
{
|
|
Edje_Color_Class *cc;
|
|
|
|
if (!color_class)
|
|
cc = NULL;
|
|
else
|
|
cc = eina_hash_find(_edje_color_class_hash, color_class);
|
|
|
|
return _edje_color_class_get_internal(cc, layer, r, g, b, a);
|
|
}
|
|
|
|
EAPI void
|
|
edje_color_class_del(const char *color_class)
|
|
{
|
|
efl_gfx_color_class_del(_edje_global(), color_class);
|
|
}
|
|
|
|
EOLIAN void
|
|
_edje_global_efl_gfx_color_class_color_class_del(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, const char *color_class)
|
|
{
|
|
Edje_Color_Class *cc;
|
|
|
|
if (!color_class) return;
|
|
|
|
cc = eina_hash_find(_edje_color_class_hash, color_class);
|
|
if (!cc) return;
|
|
|
|
eina_hash_del(_edje_color_class_hash, color_class, cc);
|
|
eina_stringshare_del(cc->name);
|
|
free(cc);
|
|
|
|
efl_observable_observers_update(_edje_color_class_member, color_class, "color_class,del");
|
|
}
|
|
|
|
Eina_List *
|
|
edje_color_class_list(void)
|
|
{
|
|
Edje_List_Foreach_Data fdata;
|
|
|
|
if (!_edje_color_class_hash) return NULL;
|
|
memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
|
|
eina_hash_foreach(_edje_color_class_hash,
|
|
_edje_color_class_list_foreach, &fdata);
|
|
|
|
return fdata.list;
|
|
}
|
|
|
|
typedef struct _Edje_Active_Color_Class_Iterator Edje_Active_Color_Class_Iterator;
|
|
struct _Edje_Active_Color_Class_Iterator
|
|
{
|
|
Eina_Iterator iterator;
|
|
|
|
Edje_Color_Class cc;
|
|
|
|
Eina_Iterator *classes;
|
|
};
|
|
|
|
static Eina_Bool
|
|
_edje_color_class_active_iterator_next(Eina_Iterator *it, void **data)
|
|
{
|
|
Edje_Active_Color_Class_Iterator *et = (void *)it;
|
|
Efl_Observable_Tuple *tuple = NULL;
|
|
Efl_Observer *o;
|
|
Edje *ed;
|
|
Edje_Color_Class *cc = NULL;
|
|
|
|
if (!eina_iterator_next(et->classes, (void **)&tuple)) return EINA_FALSE;
|
|
if (!tuple) return EINA_FALSE;
|
|
|
|
if (!eina_iterator_next(tuple->data, (void **)&o)) return EINA_FALSE;
|
|
|
|
ed = efl_data_scope_get(o, EFL_CANVAS_LAYOUT_CLASS);
|
|
if (!ed) return EINA_FALSE;
|
|
|
|
/*
|
|
We actually need to ask on an object to get the correct value.
|
|
It is being assumed that the color key are the same for all object here.
|
|
This can some times not be the case, but for now we should be fine.
|
|
*/
|
|
cc = _edje_color_class_find(ed, tuple->key);
|
|
if (!cc) return EINA_FALSE;
|
|
et->cc = *cc;
|
|
|
|
/*
|
|
Any of the Edje object referenced should have a file with a valid
|
|
description for this color class. Let's bet on that for now.
|
|
*/
|
|
if (ed->file)
|
|
cc = eina_hash_find(ed->file->color_hash, tuple->key);
|
|
if (!cc) return EINA_FALSE;
|
|
et->cc.desc = cc->desc;
|
|
|
|
*data = &et->cc;
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static void *
|
|
_edje_color_class_active_iterator_container(Eina_Iterator *it EINA_UNUSED)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
_edje_color_class_active_iterator_free(Eina_Iterator *it)
|
|
{
|
|
Edje_Active_Color_Class_Iterator *et = (void *)it;
|
|
|
|
eina_iterator_free(et->classes);
|
|
EINA_MAGIC_SET(&et->iterator, 0);
|
|
free(et);
|
|
}
|
|
|
|
EAPI Eina_Iterator *
|
|
edje_color_class_active_iterator_new(void)
|
|
{
|
|
Edje_Active_Color_Class_Iterator *it;
|
|
|
|
if (!_edje_color_class_member) return NULL;
|
|
it = calloc(1, sizeof (Edje_Active_Color_Class_Iterator));
|
|
if (!it) return NULL;
|
|
|
|
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
|
|
it->classes = efl_observable_iterator_tuple_new(_edje_color_class_member);
|
|
|
|
it->iterator.version = EINA_ITERATOR_VERSION;
|
|
it->iterator.next = _edje_color_class_active_iterator_next;
|
|
it->iterator.get_container = _edje_color_class_active_iterator_container;
|
|
it->iterator.free = _edje_color_class_active_iterator_free;
|
|
|
|
return &it->iterator;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_edje_color_class_list_foreach(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data EINA_UNUSED, void *fdata)
|
|
{
|
|
Edje_List_Foreach_Data *fd;
|
|
|
|
fd = fdata;
|
|
fd->list = eina_list_append(fd->list, strdup(key));
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_object_color_class_set(Evas_Object *obj, const char *color_class, int r, int g, int b, int a, int r2, int g2, int b2, int a2, int r3, int g3, int b3, int a3)
|
|
{
|
|
Eina_Bool int_ret = EINA_TRUE;
|
|
|
|
int_ret &= efl_gfx_color_class_set(obj, color_class, EFL_GFX_COLOR_CLASS_LAYER_NORMAL, r, g, b, a);
|
|
int_ret &= efl_gfx_color_class_set(obj, color_class, EFL_GFX_COLOR_CLASS_LAYER_OUTLINE, r2, g2, b2, a2);
|
|
int_ret &= efl_gfx_color_class_set(obj, color_class, EFL_GFX_COLOR_CLASS_LAYER_SHADOW, r3, g3, b3, a3);
|
|
|
|
return int_ret;
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_efl_canvas_layout_efl_gfx_color_class_color_class_set(Eo *obj EINA_UNUSED, Edje *ed, const char *color_class, Efl_Gfx_Color_Class_Layer layer, int r, int g, int b, int a)
|
|
{
|
|
Eina_Bool int_ret;
|
|
Eina_Bool need_update;
|
|
|
|
int_ret = _edje_color_class_set_internal(ed->color_classes, color_class, layer, r, g, b, a, &need_update);
|
|
|
|
if ((int_ret) && (need_update))
|
|
{
|
|
Edje_Real_Part *rp;
|
|
unsigned short i;
|
|
|
|
ed->dirty = EINA_TRUE;
|
|
ed->recalc_call = EINA_TRUE;
|
|
#ifdef EDJE_CALC_CACHE
|
|
ed->all_part_change = EINA_TRUE;
|
|
#endif
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
rp = ed->table_parts[i];
|
|
if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
|
|
((rp->type == EDJE_RP_TYPE_SWALLOW) &&
|
|
(rp->typedata.swallow)) &&
|
|
(rp->typedata.swallow->swallowed_object))
|
|
efl_gfx_color_class_set(rp->typedata.swallow->swallowed_object,
|
|
color_class, layer, r, g, b, a);
|
|
}
|
|
|
|
_edje_recalc(ed);
|
|
_edje_emit(ed, "color_class,set", color_class);
|
|
}
|
|
|
|
return int_ret;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_object_color_class_get(const Evas_Object *obj, const char *color_class, int *r, int *g, int *b, int *a, int *r2, int *g2, int *b2, int *a2, int *r3, int *g3, int *b3, int *a3)
|
|
{
|
|
Eina_Bool int_ret = EINA_TRUE;
|
|
|
|
int_ret &= efl_gfx_color_class_get(obj, color_class, EFL_GFX_COLOR_CLASS_LAYER_NORMAL, r, g, b, a);
|
|
int_ret &= efl_gfx_color_class_get(obj, color_class, EFL_GFX_COLOR_CLASS_LAYER_OUTLINE, r2, g2, b2, a2);
|
|
int_ret &= efl_gfx_color_class_get(obj, color_class, EFL_GFX_COLOR_CLASS_LAYER_SHADOW, r3, g3, b3, a3);
|
|
|
|
return int_ret;
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_efl_canvas_layout_efl_gfx_color_class_color_class_get(const Eo *obj EINA_UNUSED, Edje *ed, const char *color_class, Efl_Gfx_Color_Class_Layer layer, int *r, int *g, int *b, int *a)
|
|
{
|
|
Edje_Color_Class *cc;
|
|
|
|
if (!color_class)
|
|
cc = NULL;
|
|
else
|
|
cc = _edje_color_class_find(ed, color_class);
|
|
|
|
return _edje_color_class_get_internal(cc, layer, r, g, b, a);
|
|
}
|
|
|
|
EAPI const char *
|
|
edje_object_color_class_description_get(const Evas_Object *obj, const char *color_class)
|
|
{
|
|
return efl_gfx_color_class_description_get(obj, color_class);
|
|
}
|
|
|
|
EOLIAN const char *
|
|
_efl_canvas_layout_efl_gfx_color_class_color_class_description_get(const Eo *obj EINA_UNUSED, Edje *ed, const char *color_class)
|
|
{
|
|
Edje_Color_Class *cc = _edje_color_class_find(ed, color_class);
|
|
return cc ? cc->desc : NULL;
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_color_class_del(Evas_Object *obj, const char *color_class)
|
|
{
|
|
efl_gfx_color_class_del(obj, color_class);
|
|
}
|
|
|
|
EOLIAN void
|
|
_efl_canvas_layout_efl_gfx_color_class_color_class_del(Eo *obj EINA_UNUSED, Edje *ed, const char *color_class)
|
|
{
|
|
Edje_Color_Class *cc = NULL;
|
|
unsigned short i;
|
|
|
|
if (!color_class) return;
|
|
|
|
eina_hash_del(ed->color_classes, color_class, cc);
|
|
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
rp = ed->table_parts[i];
|
|
if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
|
|
((rp->type == EDJE_RP_TYPE_SWALLOW) &&
|
|
(rp->typedata.swallow)) &&
|
|
(rp->typedata.swallow->swallowed_object))
|
|
efl_gfx_color_class_del(rp->typedata.swallow->swallowed_object, color_class);
|
|
}
|
|
|
|
ed->dirty = EINA_TRUE;
|
|
ed->recalc_call = EINA_TRUE;
|
|
#ifdef EDJE_CALC_CACHE
|
|
ed->all_part_change = EINA_TRUE;
|
|
#endif
|
|
_edje_recalc(ed);
|
|
_edje_emit(ed, "color_class,del", color_class);
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_object_color_class_clear(const Evas_Object *obj)
|
|
{
|
|
efl_gfx_color_class_clear((Eo *)obj);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EOLIAN void
|
|
_efl_canvas_layout_efl_gfx_color_class_color_class_clear(Eo *obj EINA_UNUSED, Edje *ed)
|
|
{
|
|
Edje_List_Foreach_Data fdata;
|
|
Edje_Color_Class *cc = NULL;
|
|
Eina_List *l;
|
|
char *color_class;
|
|
unsigned short i;
|
|
|
|
memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
|
|
eina_hash_foreach(ed->color_classes, _edje_color_class_list_foreach, &fdata);
|
|
|
|
EINA_LIST_FOREACH(fdata.list, l, color_class)
|
|
eina_hash_del(ed->color_classes, color_class, cc);
|
|
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
rp = ed->table_parts[i];
|
|
if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
|
|
((rp->type == EDJE_RP_TYPE_SWALLOW) &&
|
|
(rp->typedata.swallow)) &&
|
|
(rp->typedata.swallow->swallowed_object))
|
|
efl_gfx_color_class_clear(rp->typedata.swallow->swallowed_object);
|
|
}
|
|
|
|
ed->dirty = EINA_TRUE;
|
|
ed->recalc_call = EINA_TRUE;
|
|
#ifdef EDJE_CALC_CACHE
|
|
ed->all_part_change = EINA_TRUE;
|
|
#endif
|
|
_edje_recalc(ed);
|
|
|
|
EINA_LIST_FREE(fdata.list, color_class)
|
|
{
|
|
_edje_emit(ed, "color_class,del", color_class);
|
|
free(color_class);
|
|
}
|
|
}
|
|
|
|
typedef struct _Edje_File_Color_Class_Iterator Edje_File_Color_Class_Iterator;
|
|
struct _Edje_File_Color_Class_Iterator
|
|
{
|
|
Edje_Active_Color_Class_Iterator it;
|
|
|
|
Edje_File *edf;
|
|
};
|
|
|
|
static Eina_Bool
|
|
_edje_mmap_color_class_iterator_next(Eina_Iterator *it, void **data)
|
|
{
|
|
Edje_File_Color_Class_Iterator *et = (void *)it;
|
|
Eina_Hash_Tuple *tuple = NULL;
|
|
Edje_Color_Class *cc = NULL;
|
|
|
|
if (!eina_iterator_next(et->it.classes, (void **)&tuple)) return EINA_FALSE;
|
|
if (!tuple) return EINA_FALSE;
|
|
|
|
cc = tuple->data;
|
|
|
|
et->it.cc = *cc;
|
|
|
|
*data = &et->it.cc;
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static void *
|
|
_edje_mmap_color_class_iterator_container(Eina_Iterator *it)
|
|
{
|
|
Edje_File_Color_Class_Iterator *et = (void *)it;
|
|
|
|
return et->edf->f;
|
|
}
|
|
|
|
static void
|
|
_edje_mmap_color_class_iterator_free(Eina_Iterator *it)
|
|
{
|
|
Edje_File_Color_Class_Iterator *et = (void *)it;
|
|
|
|
eina_iterator_free(et->it.classes);
|
|
_edje_cache_file_unref(et->edf);
|
|
EINA_MAGIC_SET(&et->it.iterator, 0);
|
|
free(et);
|
|
}
|
|
|
|
EAPI Eina_Iterator *
|
|
edje_mmap_color_class_iterator_new(Eina_File *f)
|
|
{
|
|
Edje_File_Color_Class_Iterator *it;
|
|
Edje_File *edf;
|
|
int error_ret;
|
|
|
|
edf = _edje_cache_file_coll_open(f, NULL, &error_ret, NULL, NULL);
|
|
if (!edf) return NULL;
|
|
|
|
it = calloc(1, sizeof (Edje_File_Color_Class_Iterator));
|
|
if (!it) goto on_error;
|
|
|
|
EINA_MAGIC_SET(&it->it.iterator, EINA_MAGIC_ITERATOR);
|
|
it->edf = edf;
|
|
it->it.classes = eina_hash_iterator_tuple_new(edf->color_hash);
|
|
|
|
it->it.iterator.version = EINA_ITERATOR_VERSION;
|
|
it->it.iterator.next = _edje_mmap_color_class_iterator_next;
|
|
it->it.iterator.get_container = _edje_mmap_color_class_iterator_container;
|
|
it->it.iterator.free = _edje_mmap_color_class_iterator_free;
|
|
|
|
return &it->it.iterator;
|
|
|
|
on_error:
|
|
_edje_cache_file_unref(edf);
|
|
return NULL;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_text_class_set(const char *text_class, const char *font, Evas_Font_Size size)
|
|
{
|
|
return efl_gfx_text_class_set(_edje_global(), text_class, font, (Efl_Font_Size)size);
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_edje_global_efl_gfx_text_class_text_class_set(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED,
|
|
const char *text_class, const char *font, Efl_Font_Size size)
|
|
{
|
|
Edje_Text_Class *tc;
|
|
|
|
if (!text_class) return EINA_FALSE;
|
|
if (!font) font = "";
|
|
|
|
tc = eina_hash_find(_edje_text_class_hash, text_class);
|
|
/* Create new text class */
|
|
if (!tc)
|
|
{
|
|
tc = calloc(1, sizeof(Edje_Text_Class));
|
|
if (!tc) return EINA_FALSE;
|
|
tc->name = eina_stringshare_add(text_class);
|
|
if (!tc->name)
|
|
{
|
|
free(tc);
|
|
return EINA_FALSE;
|
|
}
|
|
if (!_edje_text_class_hash) _edje_text_class_hash = eina_hash_string_superfast_new(NULL);
|
|
eina_hash_add(_edje_text_class_hash, text_class, tc);
|
|
|
|
tc->font = eina_stringshare_add(font);
|
|
tc->size = size;
|
|
}
|
|
else
|
|
{
|
|
/* Match and the same, return */
|
|
if (((tc->font && font) && !strcmp(tc->font, font)) &&
|
|
(tc->size == size))
|
|
return EINA_TRUE;
|
|
|
|
/* Update the class found */
|
|
eina_stringshare_replace(&tc->font, font);
|
|
tc->size = size;
|
|
}
|
|
|
|
/* Tell all members of the text class to recalc */
|
|
efl_observable_observers_update(_edje_text_class_member, text_class, NULL);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_text_class_get(const char *text_class, const char **font, Evas_Font_Size *size)
|
|
{
|
|
return efl_gfx_text_class_get(_edje_global(), text_class, font, (Efl_Font_Size *)size);
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_edje_global_efl_gfx_text_class_text_class_get(const Eo *obj EINA_UNUSED, void *pd EINA_UNUSED,
|
|
const char *text_class, const char **font, Efl_Font_Size *size)
|
|
{
|
|
Edje_Text_Class *tc;
|
|
|
|
if (!text_class) return EINA_FALSE;
|
|
|
|
tc = eina_hash_find(_edje_text_class_hash, text_class);
|
|
|
|
if (tc)
|
|
{
|
|
if (font) *font = tc->font;
|
|
if (size) *size = tc->size;
|
|
}
|
|
else
|
|
{
|
|
if (font) *font = NULL;
|
|
if (size) *size = 0;
|
|
|
|
return EINA_FALSE;
|
|
}
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EAPI void
|
|
edje_text_class_del(const char *text_class)
|
|
{
|
|
efl_gfx_text_class_del(_edje_global(), text_class);
|
|
}
|
|
|
|
EOLIAN void
|
|
_edje_global_efl_gfx_text_class_text_class_del(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, const char *text_class)
|
|
{
|
|
Edje_Text_Class *tc;
|
|
|
|
if (!text_class) return;
|
|
|
|
tc = eina_hash_find(_edje_text_class_hash, text_class);
|
|
if (!tc) return;
|
|
|
|
eina_hash_del(_edje_text_class_hash, text_class, tc);
|
|
eina_stringshare_del(tc->name);
|
|
eina_stringshare_del(tc->font);
|
|
free(tc);
|
|
|
|
efl_observable_observers_update(_edje_text_class_member, text_class, NULL);
|
|
}
|
|
|
|
Eina_List *
|
|
edje_text_class_list(void)
|
|
{
|
|
Edje_List_Foreach_Data fdata;
|
|
|
|
if (!_edje_text_class_hash) return NULL;
|
|
memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
|
|
eina_hash_foreach(_edje_text_class_hash,
|
|
_edje_text_class_list_foreach, &fdata);
|
|
return fdata.list;
|
|
}
|
|
|
|
typedef struct _Edje_Active_Text_Class_Iterator Edje_Active_Text_Class_Iterator;
|
|
struct _Edje_Active_Text_Class_Iterator
|
|
{
|
|
Eina_Iterator iterator;
|
|
Edje_Text_Class tc;
|
|
Eina_Iterator *classes;
|
|
};
|
|
|
|
static Eina_Bool
|
|
_edje_text_class_active_iterator_next(Eina_Iterator *it, void **data)
|
|
{
|
|
Edje_Active_Text_Class_Iterator *et = (void *)it;
|
|
Efl_Observable_Tuple *tuple = NULL;
|
|
Efl_Observer *o;
|
|
Edje *ed;
|
|
Edje_Text_Class *tc;
|
|
|
|
if (!eina_iterator_next(et->classes, (void **)&tuple)) return EINA_FALSE;
|
|
if (!tuple) return EINA_FALSE;
|
|
|
|
if (!eina_iterator_next(tuple->data, (void **)&o)) return EINA_FALSE;
|
|
|
|
ed = efl_data_scope_get(o, EFL_CANVAS_LAYOUT_CLASS);
|
|
if (!ed) return EINA_FALSE;
|
|
|
|
/*
|
|
We actually need to ask on an object to get the correct value.
|
|
It is being assumed that the size key are the same for all object here.
|
|
This can some times not be the case, but for now we should be fine.
|
|
*/
|
|
tc = _edje_text_class_find(ed, tuple->key);
|
|
if (!tc) return EINA_FALSE;
|
|
et->tc = *tc;
|
|
|
|
*data = &et->tc;
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static void *
|
|
_edje_text_class_active_iterator_container(Eina_Iterator *it EINA_UNUSED)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
_edje_text_class_active_iterator_free(Eina_Iterator *it)
|
|
{
|
|
Edje_Active_Text_Class_Iterator *et = (void *)it;
|
|
|
|
eina_iterator_free(et->classes);
|
|
EINA_MAGIC_SET(&et->iterator, 0);
|
|
free(et);
|
|
}
|
|
|
|
EAPI Eina_Iterator *
|
|
edje_text_class_active_iterator_new(void)
|
|
{
|
|
Edje_Active_Text_Class_Iterator *it;
|
|
|
|
if (!_edje_text_class_member) return NULL;
|
|
it = calloc(1, sizeof (Edje_Active_Text_Class_Iterator));
|
|
if (!it) return NULL;
|
|
|
|
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
|
|
it->classes = efl_observable_iterator_tuple_new(_edje_text_class_member);
|
|
|
|
it->iterator.version = EINA_ITERATOR_VERSION;
|
|
it->iterator.next = _edje_text_class_active_iterator_next;
|
|
it->iterator.get_container = _edje_text_class_active_iterator_container;
|
|
it->iterator.free = _edje_text_class_active_iterator_free;
|
|
|
|
return &it->iterator;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_edje_text_class_list_foreach(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data EINA_UNUSED, void *fdata)
|
|
{
|
|
Edje_List_Foreach_Data *fd;
|
|
|
|
fd = fdata;
|
|
fd->list = eina_list_append(fd->list, eina_stringshare_add(key));
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_object_text_class_set(Evas_Object *obj, const char *text_class, const char *font, Evas_Font_Size size)
|
|
{
|
|
return efl_gfx_text_class_set(obj, text_class, font, (Efl_Font_Size)size);
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_efl_canvas_layout_efl_gfx_text_class_text_class_set(Eo *obj EINA_UNUSED, Edje *ed, const char *text_class, const char *font, Efl_Font_Size size)
|
|
{
|
|
Edje_Text_Class *tc = NULL;
|
|
unsigned short i;
|
|
|
|
if ((!ed) || (!text_class)) return EINA_FALSE;
|
|
|
|
tc = eina_hash_find(ed->text_classes, text_class);
|
|
|
|
/* for each text_class in the edje */
|
|
if (tc)
|
|
{
|
|
if ((tc->name) && (!strcmp(tc->name, text_class)))
|
|
{
|
|
/* Match and the same, return */
|
|
if ((tc->size == size) &&
|
|
((tc->font == font) ||
|
|
(tc->font && font && !strcmp(tc->font, font))))
|
|
{
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
/* Update new text class properties */
|
|
eina_stringshare_replace(&tc->font, font);
|
|
tc->size = size;
|
|
}
|
|
}
|
|
|
|
if (!tc)
|
|
{
|
|
/* No matches, create a new text class */
|
|
tc = calloc(1, sizeof(Edje_Text_Class));
|
|
if (!tc) return EINA_FALSE;
|
|
tc->name = eina_stringshare_add(text_class);
|
|
if (!tc->name)
|
|
{
|
|
free(tc);
|
|
return EINA_FALSE;
|
|
}
|
|
tc->font = eina_stringshare_add(font);
|
|
tc->size = size;
|
|
/* Add to edje's text class list */
|
|
eina_hash_direct_add(ed->text_classes, tc->name, tc);
|
|
}
|
|
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
rp = ed->table_parts[i];
|
|
if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
|
|
((rp->type == EDJE_RP_TYPE_SWALLOW) &&
|
|
(rp->typedata.swallow)) &&
|
|
(rp->typedata.swallow->swallowed_object))
|
|
efl_gfx_text_class_set(rp->typedata.swallow->swallowed_object,
|
|
text_class, font, size);
|
|
}
|
|
|
|
efl_observer_update(obj, _edje_text_class_member, text_class, NULL);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_object_text_class_get(const Evas_Object *obj, const char *text_class, const char **font, Evas_Font_Size *size)
|
|
{
|
|
return efl_gfx_text_class_get(obj, text_class, font, (Efl_Font_Size *)size);
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_efl_canvas_layout_efl_gfx_text_class_text_class_get(const Eo *obj EINA_UNUSED, Edje *ed, const char *text_class, const char **font, Efl_Font_Size *size)
|
|
{
|
|
Edje_Text_Class *tc = _edje_text_class_find(ed, text_class);
|
|
|
|
if (tc)
|
|
{
|
|
if (font) *font = tc->font;
|
|
if (size) *size = tc->size;
|
|
}
|
|
else
|
|
{
|
|
if (font) *font = NULL;
|
|
if (size) *size = 0;
|
|
|
|
return EINA_FALSE;
|
|
}
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_text_class_del(Evas_Object *obj, const char *text_class)
|
|
{
|
|
efl_gfx_text_class_del(obj, text_class);
|
|
}
|
|
|
|
EOLIAN void
|
|
_efl_canvas_layout_efl_gfx_text_class_text_class_del(Eo *obj EINA_UNUSED, Edje *ed, const char *text_class)
|
|
{
|
|
Edje_Text_Class *tc = NULL;
|
|
unsigned short i;
|
|
|
|
if (!text_class) return;
|
|
|
|
eina_hash_del(ed->text_classes, text_class, tc);
|
|
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
rp = ed->table_parts[i];
|
|
if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
|
|
((rp->type == EDJE_RP_TYPE_SWALLOW) &&
|
|
(rp->typedata.swallow)) &&
|
|
(rp->typedata.swallow->swallowed_object))
|
|
efl_gfx_text_class_del(rp->typedata.swallow->swallowed_object, text_class);
|
|
}
|
|
|
|
efl_observer_update(obj, _edje_text_class_member, text_class, NULL);
|
|
}
|
|
|
|
typedef struct _Edje_File_Text_Class_Iterator Edje_File_Text_Class_Iterator;
|
|
struct _Edje_File_Text_Class_Iterator
|
|
{
|
|
Edje_Active_Text_Class_Iterator it;
|
|
|
|
Edje_File *edf;
|
|
};
|
|
|
|
static Eina_Bool
|
|
_edje_mmap_text_class_iterator_next(Eina_Iterator *it, void **data)
|
|
{
|
|
Edje_File_Text_Class_Iterator *et = (void *)it;
|
|
Eina_Hash_Tuple *tuple = NULL;
|
|
Edje_Text_Class *tc = NULL;
|
|
|
|
if (!eina_iterator_next(et->it.classes, (void **)&tuple)) return EINA_FALSE;
|
|
if (!tuple) return EINA_FALSE;
|
|
|
|
tc = tuple->data;
|
|
|
|
et->it.tc = *tc;
|
|
|
|
*data = &et->it.tc;
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static void *
|
|
_edje_mmap_text_class_iterator_container(Eina_Iterator *it)
|
|
{
|
|
Edje_File_Text_Class_Iterator *et = (void *)it;
|
|
|
|
return et->edf->f;
|
|
}
|
|
|
|
static void
|
|
_edje_mmap_text_class_iterator_free(Eina_Iterator *it)
|
|
{
|
|
Edje_File_Text_Class_Iterator *et = (void *)it;
|
|
|
|
eina_iterator_free(et->it.classes);
|
|
_edje_cache_file_unref(et->edf);
|
|
EINA_MAGIC_SET(&et->it.iterator, 0);
|
|
free(et);
|
|
}
|
|
|
|
EAPI Eina_Iterator *
|
|
edje_mmap_text_class_iterator_new(Eina_File *f)
|
|
{
|
|
Edje_File_Text_Class_Iterator *it;
|
|
Edje_File *edf;
|
|
int error_ret;
|
|
|
|
edf = _edje_cache_file_coll_open(f, NULL, &error_ret, NULL, NULL);
|
|
if (!edf) return NULL;
|
|
|
|
it = calloc(1, sizeof (Edje_File_Text_Class_Iterator));
|
|
if (!it) goto on_error;
|
|
|
|
EINA_MAGIC_SET(&it->it.iterator, EINA_MAGIC_ITERATOR);
|
|
it->edf = edf;
|
|
it->it.classes = eina_hash_iterator_tuple_new(edf->text_hash);
|
|
|
|
it->it.iterator.version = EINA_ITERATOR_VERSION;
|
|
it->it.iterator.next = _edje_mmap_text_class_iterator_next;
|
|
it->it.iterator.get_container = _edje_mmap_text_class_iterator_container;
|
|
it->it.iterator.free = _edje_mmap_text_class_iterator_free;
|
|
|
|
return &it->it.iterator;
|
|
|
|
on_error:
|
|
_edje_cache_file_unref(edf);
|
|
return NULL;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_size_class_set(const char *size_class, Evas_Coord minw, Evas_Coord minh, Evas_Coord maxw, Evas_Coord maxh)
|
|
{
|
|
return efl_gfx_size_class_set(_edje_global(), size_class, minw, minh, maxw, maxh);
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_edje_global_efl_gfx_size_class_size_class_set(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, const char *size_class,
|
|
Evas_Coord minw, Evas_Coord minh, Evas_Coord maxw, Evas_Coord maxh)
|
|
{
|
|
Edje_Size_Class *sc;
|
|
|
|
if (!size_class) return EINA_FALSE;
|
|
|
|
sc = eina_hash_find(_edje_size_class_hash, size_class);
|
|
/* Create new size class */
|
|
if (!sc)
|
|
{
|
|
sc = calloc(1, sizeof(Edje_Size_Class));
|
|
if (!sc) return EINA_FALSE;
|
|
sc->name = eina_stringshare_add(size_class);
|
|
if (!sc->name)
|
|
{
|
|
free(sc);
|
|
return EINA_FALSE;
|
|
}
|
|
if (!_edje_size_class_hash) _edje_size_class_hash = eina_hash_string_superfast_new(NULL);
|
|
eina_hash_add(_edje_size_class_hash, size_class, sc);
|
|
|
|
sc->minw = minw;
|
|
sc->minh = minh;
|
|
sc->maxw = maxw;
|
|
sc->maxh = maxh;
|
|
}
|
|
else
|
|
{
|
|
/* Match and the same, return */
|
|
if ((sc->minw == minw) && (sc->minh == minh) &&
|
|
(sc->maxw == maxw) && (sc->maxh == maxh))
|
|
return EINA_TRUE;
|
|
|
|
/* Update the class found */
|
|
sc->minw = minw;
|
|
sc->minh = minh;
|
|
sc->maxw = maxw;
|
|
sc->maxh = maxh;
|
|
}
|
|
|
|
/* Tell all members of the size class to recalc */
|
|
efl_observable_observers_update(_edje_size_class_member, size_class, NULL);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_size_class_get(const char *size_class, Evas_Coord *minw, Evas_Coord *minh, Evas_Coord *maxw, Evas_Coord *maxh)
|
|
{
|
|
return efl_gfx_size_class_get(_edje_global(), size_class, minw, minh, maxw, maxh);
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_edje_global_efl_gfx_size_class_size_class_get(const Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, const char *size_class,
|
|
Evas_Coord *minw, Evas_Coord *minh, Evas_Coord *maxw, Evas_Coord *maxh)
|
|
{
|
|
Edje_Size_Class *sc;
|
|
|
|
if (!size_class) return EINA_FALSE;
|
|
|
|
sc = eina_hash_find(_edje_size_class_hash, size_class);
|
|
|
|
if (sc)
|
|
{
|
|
if (minw) *minw = sc->minw;
|
|
if (minh) *minh = sc->minh;
|
|
if (maxw) *maxw = sc->maxw;
|
|
if (maxh) *maxh = sc->maxh;
|
|
}
|
|
else
|
|
{
|
|
if (minw) *minw = 0;
|
|
if (minh) *minh = 0;
|
|
if (maxw) *maxw = 0;
|
|
if (maxh) *maxh = 0;
|
|
|
|
return EINA_FALSE;
|
|
}
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EAPI void
|
|
edje_size_class_del(const char *size_class)
|
|
{
|
|
efl_gfx_size_class_del(_edje_global(), size_class);
|
|
}
|
|
|
|
EOLIAN void
|
|
_edje_global_efl_gfx_size_class_size_class_del(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, const char *size_class)
|
|
{
|
|
Edje_Size_Class *sc;
|
|
|
|
if (!size_class) return;
|
|
|
|
sc = eina_hash_find(_edje_size_class_hash, size_class);
|
|
if (!sc) return;
|
|
|
|
eina_hash_del(_edje_size_class_hash, size_class, sc);
|
|
eina_stringshare_del(sc->name);
|
|
free(sc);
|
|
|
|
efl_observable_observers_update(_edje_size_class_member, size_class, NULL);
|
|
}
|
|
|
|
Eina_List *
|
|
edje_size_class_list(void)
|
|
{
|
|
Edje_List_Foreach_Data fdata;
|
|
|
|
if (!_edje_size_class_hash) return NULL;
|
|
memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
|
|
eina_hash_foreach(_edje_size_class_hash,
|
|
_edje_size_class_list_foreach, &fdata);
|
|
return fdata.list;
|
|
}
|
|
|
|
typedef struct _Edje_Active_Size_Class_Iterator Edje_Active_Size_Class_Iterator;
|
|
struct _Edje_Active_Size_Class_Iterator
|
|
{
|
|
Eina_Iterator iterator;
|
|
Edje_Size_Class sc;
|
|
Eina_Iterator *classes;
|
|
};
|
|
|
|
static Eina_Bool
|
|
_edje_size_class_active_iterator_next(Eina_Iterator *it, void **data)
|
|
{
|
|
Edje_Active_Size_Class_Iterator *et = (void *)it;
|
|
Efl_Observable_Tuple *tuple = NULL;
|
|
Efl_Observer *o;
|
|
Edje *ed;
|
|
Edje_Size_Class *sc;
|
|
|
|
if (!eina_iterator_next(et->classes, (void **)&tuple)) return EINA_FALSE;
|
|
if (!tuple) return EINA_FALSE;
|
|
|
|
if (!eina_iterator_next(tuple->data, (void **)&o)) return EINA_FALSE;
|
|
|
|
ed = efl_data_scope_get(o, EFL_CANVAS_LAYOUT_CLASS);
|
|
if (!ed) return EINA_FALSE;
|
|
|
|
/*
|
|
We actually need to ask on an object to get the correct value.
|
|
It is being assumed that the size key are the same for all object here.
|
|
This can some times not be the case, but for now we should be fine.
|
|
*/
|
|
sc = _edje_size_class_find(ed, tuple->key);
|
|
if (!sc) return EINA_FALSE;
|
|
et->sc = *sc;
|
|
|
|
*data = &et->sc;
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static void *
|
|
_edje_size_class_active_iterator_container(Eina_Iterator *it EINA_UNUSED)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
_edje_size_class_active_iterator_free(Eina_Iterator *it)
|
|
{
|
|
Edje_Active_Size_Class_Iterator *et = (void *)it;
|
|
|
|
eina_iterator_free(et->classes);
|
|
EINA_MAGIC_SET(&et->iterator, 0);
|
|
free(et);
|
|
}
|
|
|
|
EAPI Eina_Iterator *
|
|
edje_size_class_active_iterator_new(void)
|
|
{
|
|
Edje_Active_Size_Class_Iterator *it;
|
|
|
|
if (!_edje_size_class_member) return NULL;
|
|
it = calloc(1, sizeof (Edje_Active_Size_Class_Iterator));
|
|
if (!it) return NULL;
|
|
|
|
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
|
|
it->classes = efl_observable_iterator_tuple_new(_edje_size_class_member);
|
|
|
|
it->iterator.version = EINA_ITERATOR_VERSION;
|
|
it->iterator.next = _edje_size_class_active_iterator_next;
|
|
it->iterator.get_container = _edje_size_class_active_iterator_container;
|
|
it->iterator.free = _edje_size_class_active_iterator_free;
|
|
|
|
return &it->iterator;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_edje_size_class_list_foreach(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data EINA_UNUSED, void *fdata)
|
|
{
|
|
Edje_List_Foreach_Data *fd;
|
|
|
|
fd = fdata;
|
|
fd->list = eina_list_append(fd->list, eina_stringshare_add(key));
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_object_size_class_set(Evas_Object *obj, const char *size_class, Evas_Coord minw, Evas_Coord minh, Evas_Coord maxw, Evas_Coord maxh)
|
|
{
|
|
return efl_gfx_size_class_set(obj, size_class, minw, minh, maxw, maxh);
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_efl_canvas_layout_efl_gfx_size_class_size_class_set(Eo *obj EINA_UNUSED, Edje *ed, const char *size_class, Evas_Coord minw, Evas_Coord minh, Evas_Coord maxw, Evas_Coord maxh)
|
|
{
|
|
Edje_Size_Class *sc = NULL;
|
|
unsigned short i;
|
|
|
|
if ((!ed) || (!size_class)) return EINA_FALSE;
|
|
|
|
/* for each size_class in the edje */
|
|
sc = eina_hash_find(ed->size_classes, size_class);
|
|
|
|
if (sc)
|
|
{
|
|
if ((sc->minw == minw) && (sc->minh == minh) &&
|
|
(sc->maxw == maxw) && (sc->maxh == maxh))
|
|
{
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
/* Update new size class properties */
|
|
sc->minw = minw;
|
|
sc->minh = minh;
|
|
sc->maxw = maxw;
|
|
sc->maxh = maxh;
|
|
}
|
|
else
|
|
{
|
|
/* No matches, create a new size class */
|
|
sc = calloc(1, sizeof(Edje_Size_Class));
|
|
if (!sc) return EINA_FALSE;
|
|
sc->name = eina_stringshare_add(size_class);
|
|
if (!sc->name)
|
|
{
|
|
free(sc);
|
|
return EINA_FALSE;
|
|
}
|
|
sc->minw = minw;
|
|
sc->minh = minh;
|
|
sc->maxw = maxw;
|
|
sc->maxh = maxh;
|
|
/* Add to edje's size class list */
|
|
eina_hash_direct_add(ed->size_classes, sc->name, sc);
|
|
}
|
|
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
rp = ed->table_parts[i];
|
|
if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
|
|
((rp->type == EDJE_RP_TYPE_SWALLOW) &&
|
|
(rp->typedata.swallow)) &&
|
|
(rp->typedata.swallow->swallowed_object))
|
|
efl_gfx_size_class_set(rp->typedata.swallow->swallowed_object,
|
|
size_class, minw, minh, maxw, maxh);
|
|
}
|
|
|
|
efl_observable_observers_update(_edje_size_class_member, size_class, NULL);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_object_size_class_get(const Evas_Object *obj, const char *size_class, Evas_Coord *minw, Evas_Coord *minh, Evas_Coord *maxw, Evas_Coord *maxh)
|
|
{
|
|
return efl_gfx_size_class_get(obj, size_class, minw, minh, maxw, maxh);
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_efl_canvas_layout_efl_gfx_size_class_size_class_get(const Eo *obj EINA_UNUSED, Edje *ed, const char *size_class, Evas_Coord *minw, Evas_Coord *minh, Evas_Coord *maxw, Evas_Coord *maxh)
|
|
{
|
|
Edje_Size_Class *sc = _edje_size_class_find(ed, size_class);
|
|
|
|
if (sc)
|
|
{
|
|
if (minw) *minw = sc->minw;
|
|
if (minh) *minh = sc->minh;
|
|
if (maxw) *maxw = sc->maxw;
|
|
if (maxh) *maxh = sc->maxh;
|
|
}
|
|
else
|
|
{
|
|
if (minw) *minw = 0;
|
|
if (minh) *minh = 0;
|
|
if (maxw) *maxw = 0;
|
|
if (maxh) *maxh = 0;
|
|
|
|
return EINA_FALSE;
|
|
}
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_size_class_del(Evas_Object *obj, const char *size_class)
|
|
{
|
|
efl_gfx_size_class_del(obj, size_class);
|
|
}
|
|
|
|
EOLIAN void
|
|
_efl_canvas_layout_efl_gfx_size_class_size_class_del(Eo *obj EINA_UNUSED, Edje *ed, const char *size_class)
|
|
{
|
|
Edje_Size_Class *sc = NULL;
|
|
unsigned short i;
|
|
|
|
if (!size_class) return;
|
|
|
|
eina_hash_del(ed->size_classes, size_class, sc);
|
|
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
rp = ed->table_parts[i];
|
|
if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
|
|
((rp->type == EDJE_RP_TYPE_SWALLOW) &&
|
|
(rp->typedata.swallow)) &&
|
|
(rp->typedata.swallow->swallowed_object))
|
|
efl_gfx_size_class_del(rp->typedata.swallow->swallowed_object, size_class);
|
|
}
|
|
|
|
efl_observable_observers_update(_edje_size_class_member, size_class, NULL);
|
|
}
|
|
|
|
typedef struct _Edje_File_Size_Class_Iterator Edje_File_Size_Class_Iterator;
|
|
struct _Edje_File_Size_Class_Iterator
|
|
{
|
|
Edje_Active_Size_Class_Iterator it;
|
|
Edje_File *edf;
|
|
};
|
|
|
|
static Eina_Bool
|
|
_edje_mmap_size_class_iterator_next(Eina_Iterator *it, void **data)
|
|
{
|
|
Edje_File_Size_Class_Iterator *et = (void *)it;
|
|
Eina_Hash_Tuple *tuple = NULL;
|
|
Edje_Size_Class *sc = NULL;
|
|
|
|
if (!eina_iterator_next(et->it.classes, (void **)&tuple)) return EINA_FALSE;
|
|
if (!tuple) return EINA_FALSE;
|
|
|
|
sc = tuple->data;
|
|
|
|
et->it.sc = *sc;
|
|
|
|
*data = &et->it.sc;
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static void *
|
|
_edje_mmap_size_class_iterator_container(Eina_Iterator *it)
|
|
{
|
|
Edje_File_Size_Class_Iterator *et = (void *)it;
|
|
|
|
return et->edf->f;
|
|
}
|
|
|
|
static void
|
|
_edje_mmap_size_class_iterator_free(Eina_Iterator *it)
|
|
{
|
|
Edje_File_Size_Class_Iterator *et = (void *)it;
|
|
|
|
eina_iterator_free(et->it.classes);
|
|
_edje_cache_file_unref(et->edf);
|
|
EINA_MAGIC_SET(&et->it.iterator, 0);
|
|
free(et);
|
|
}
|
|
|
|
EAPI Eina_Iterator *
|
|
edje_mmap_size_class_iterator_new(Eina_File *f)
|
|
{
|
|
Edje_File_Size_Class_Iterator *it;
|
|
Edje_File *edf;
|
|
int error_ret;
|
|
|
|
edf = _edje_cache_file_coll_open(f, NULL, &error_ret, NULL, NULL);
|
|
if (!edf) return NULL;
|
|
|
|
it = calloc(1, sizeof (Edje_File_Size_Class_Iterator));
|
|
if (!it) goto on_error;
|
|
|
|
EINA_MAGIC_SET(&it->it.iterator, EINA_MAGIC_ITERATOR);
|
|
it->edf = edf;
|
|
it->it.classes = eina_hash_iterator_tuple_new(edf->size_hash);
|
|
|
|
it->it.iterator.version = EINA_ITERATOR_VERSION;
|
|
it->it.iterator.next = _edje_mmap_size_class_iterator_next;
|
|
it->it.iterator.get_container = _edje_mmap_size_class_iterator_container;
|
|
it->it.iterator.free = _edje_mmap_size_class_iterator_free;
|
|
|
|
return &it->it.iterator;
|
|
|
|
on_error:
|
|
_edje_cache_file_unref(edf);
|
|
return NULL;
|
|
}
|
|
|
|
/* Legacy API: exposes internal object. Easy to abuse. */
|
|
EAPI const Evas_Object *
|
|
edje_object_part_object_get(const Eo *obj, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
if ((!ed) || (!part)) return NULL;
|
|
|
|
/* Need to recalc before providing the object. */
|
|
if (!ed->freeze) _edje_recalc_do(ed);
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return NULL;
|
|
|
|
return rp->object;
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_item_provider_set(Edje_Object *obj, Edje_Item_Provider_Cb func, void *data)
|
|
{
|
|
Edje *ed = _edje_fetch(obj);
|
|
if (!ed) return;
|
|
ed->item_provider.func = func;
|
|
ed->item_provider.data = data;
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_text_change_cb_set(Eo *obj, Edje_Text_Change_Cb func, void *data)
|
|
{
|
|
unsigned short i;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
if (!ed) return;
|
|
ed->text_change.func = func;
|
|
ed->text_change.data = data;
|
|
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
rp = ed->table_parts[i];
|
|
if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
|
|
((rp->type == EDJE_RP_TYPE_SWALLOW) &&
|
|
(rp->typedata.swallow)) &&
|
|
(rp->typedata.swallow->swallowed_object))
|
|
edje_object_text_change_cb_set(rp->typedata.swallow->swallowed_object, func, data);
|
|
}
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_object_part_text_raw_generic_set(Edje *ed, Evas_Object *obj, Edje_Real_Part *rp, const char *part, const char *text, Eina_Bool set_markup, Eina_Bool legacy)
|
|
{
|
|
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
|
|
(!rp->typedata.text)) return EINA_TRUE;
|
|
if ((!rp->typedata.text->text) && (!text))
|
|
return EINA_TRUE; /* nothing to do, no error */
|
|
if ((rp->typedata.text->text) && (text) &&
|
|
(!strcmp(rp->typedata.text->text, text)))
|
|
return EINA_TRUE; /* nothing to do, no error */
|
|
if (rp->typedata.text->text)
|
|
{
|
|
eina_stringshare_del(rp->typedata.text->text);
|
|
rp->typedata.text->text = NULL;
|
|
}
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
_edje_entry_text_markup_set(rp, text);
|
|
else
|
|
if (text)
|
|
{
|
|
if (legacy || (rp->part->type == EDJE_PART_TYPE_TEXT) || set_markup)
|
|
{
|
|
rp->typedata.text->text = eina_stringshare_add(text);
|
|
}
|
|
else // !legacy && (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
|
|
// && !set_markup
|
|
{
|
|
char *mkup;
|
|
mkup = efl_text_markup_util_text_to_markup(
|
|
text);
|
|
rp->typedata.text->text = eina_stringshare_add(mkup);
|
|
free(mkup);
|
|
}
|
|
}
|
|
ed->dirty = EINA_TRUE;
|
|
ed->recalc_call = EINA_TRUE;
|
|
ed->recalc_hints = EINA_TRUE;
|
|
#ifdef EDJE_CALC_CACHE
|
|
rp->invalidate = EINA_TRUE;
|
|
#endif
|
|
_edje_recalc(ed);
|
|
if (ed->text_change.func)
|
|
ed->text_change.func(ed->text_change.data, obj, part);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_object_part_text_raw_set(Edje *ed, Evas_Object *obj, Edje_Real_Part *rp, const char *part, const char *text)
|
|
{
|
|
return _edje_object_part_text_raw_generic_set(ed, obj, rp, part, text,
|
|
EINA_FALSE, EINA_TRUE);
|
|
}
|
|
|
|
Edje_User_Defined *
|
|
_edje_user_text_style_definition_fetch(Edje *ed, const char *part)
|
|
{
|
|
Edje_User_Defined *eud;
|
|
Eina_List *l, *ll;
|
|
|
|
l = eina_hash_find(ed->user_defined, part);
|
|
EINA_LIST_FOREACH(l, ll, eud)
|
|
if (eud->type == EDJE_USER_TEXT_STYLE) break;
|
|
|
|
if (!eud)
|
|
{
|
|
eud = _edje_user_definition_new(EDJE_USER_TEXT_STYLE, part, ed);
|
|
if (!eud) return NULL;
|
|
eud->u.text_style.types = EDJE_PART_TEXT_PROP_NONE;
|
|
eud->u.text_style.props = NULL;
|
|
}
|
|
|
|
return eud;
|
|
}
|
|
|
|
Edje_User_Defined *
|
|
_edje_user_text_expand_definition_fetch(Edje *ed, const char *part)
|
|
{
|
|
Edje_User_Defined *eud;
|
|
Eina_List *l, *ll;
|
|
|
|
l = eina_hash_find(ed->user_defined, part);
|
|
EINA_LIST_FOREACH(l, ll, eud)
|
|
if (eud->type == EDJE_USER_TEXT_EXPAND) break;
|
|
|
|
if (!eud)
|
|
{
|
|
eud = _edje_user_definition_new(EDJE_USER_TEXT_EXPAND, part, ed);
|
|
if (!eud) return NULL;
|
|
eud->u.text_expand.expand = EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_NONE;
|
|
}
|
|
|
|
return eud;
|
|
}
|
|
|
|
void
|
|
_edje_user_define_string(Edje *ed, const char *part, const char *raw_text, Edje_Text_Type type)
|
|
{
|
|
/* NOTE: This one is tricky, text is referenced in rp->typedata.text->text for the life of the
|
|
rp. So on edje_object_file_set, we should first ref it, before destroying the old
|
|
layout. */
|
|
Edje_User_Defined *eud;
|
|
Eina_List *l, *ll;
|
|
|
|
l = eina_hash_find(ed->user_defined, part);
|
|
EINA_LIST_FOREACH(l, ll, eud)
|
|
if (eud->type == EDJE_USER_STRING)
|
|
{
|
|
if (!raw_text)
|
|
{
|
|
_edje_user_definition_free(eud);
|
|
return;
|
|
}
|
|
eud->u.string.text = raw_text;
|
|
eud->u.string.type = type;
|
|
return;
|
|
}
|
|
|
|
eud = _edje_user_definition_new(EDJE_USER_STRING, part, ed);
|
|
if (!eud) return;
|
|
eud->u.string.text = raw_text;
|
|
eud->u.string.type = type;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_efl_text_text_set(Eo *obj, Edje *ed, const char *part, const char *text,
|
|
Eina_Bool legacy, Eina_Bool set_markup)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Eina_Bool int_ret;
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
if ((!ed->file) && (!legacy))
|
|
{
|
|
_edje_user_define_string(ed, part, eina_stringshare_add(text),
|
|
set_markup ? EDJE_TEXT_TYPE_MARKUP : EDJE_TEXT_TYPE_NORMAL);
|
|
return EINA_TRUE;
|
|
}
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return EINA_FALSE;
|
|
if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
|
|
(rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return EINA_FALSE;
|
|
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
|
|
(!rp->typedata.text))
|
|
{
|
|
return EINA_TRUE;
|
|
}
|
|
int_ret = _edje_object_part_text_raw_generic_set(ed, obj, rp, part, text,
|
|
set_markup, legacy);
|
|
_edje_user_define_string(ed, part, rp->typedata.text->text,
|
|
set_markup ? EDJE_TEXT_TYPE_MARKUP : EDJE_TEXT_TYPE_NORMAL);
|
|
return int_ret;
|
|
}
|
|
|
|
const char *
|
|
_edje_efl_text_text_get(const Eo *obj EINA_UNUSED, Edje *ed, const char *part,
|
|
Eina_Bool legacy, Eina_Bool get_markup)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part)) return NULL;
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return NULL;
|
|
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
|
|
(!rp->typedata.text)) return NULL;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
return _edje_entry_text_get(rp);
|
|
}
|
|
else
|
|
{
|
|
if (rp->part->type == EDJE_PART_TYPE_TEXT)
|
|
{
|
|
Edje_Part_Description_Text *desc;
|
|
if (rp->typedata.text->text)
|
|
return rp->typedata.text->text;
|
|
else
|
|
{
|
|
desc = (Edje_Part_Description_Text *) rp->chosen_description;
|
|
if (desc->text.text.translated)
|
|
return desc->text.text.translated;
|
|
else
|
|
return desc->text.text.str;
|
|
}
|
|
}
|
|
if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
|
|
{
|
|
const char *entry;
|
|
if (legacy)
|
|
{
|
|
if (rp->typedata.text->text)
|
|
{
|
|
entry = rp->typedata.text->text;
|
|
}
|
|
else
|
|
{
|
|
#ifdef EDJE_CALC_CACHE
|
|
if (rp->invalidate || ed->all_part_change)
|
|
#else
|
|
if (ed->dirty)
|
|
#endif
|
|
_edje_recalc_do(ed);
|
|
entry = evas_object_textblock_text_markup_get(rp->object);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (get_markup)
|
|
{
|
|
#ifdef EDJE_CALC_CACHE
|
|
if (rp->invalidate || ed->all_part_change)
|
|
#else
|
|
if (ed->dirty)
|
|
#endif
|
|
_edje_recalc_do(ed);
|
|
entry = efl_text_markup_get(rp->object);
|
|
}
|
|
else
|
|
{
|
|
entry = rp->typedata.text->text;
|
|
}
|
|
}
|
|
|
|
return entry;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
EAPI const char *
|
|
edje_object_part_text_selection_get(const Eo *obj, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return NULL;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return NULL;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
return _edje_entry_selection_get(rp);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_select_none(const Eo *obj, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
_edje_entry_select_none(rp);
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_select_all(const Eo *obj, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
_edje_entry_select_all(rp);
|
|
}
|
|
|
|
EOLIAN void
|
|
_efl_canvas_layout_part_text_cursor_geometry_get(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if (x) *x = 0;
|
|
if (y) *y = 0;
|
|
if (w) *w = 0;
|
|
if (h) *h = 0;
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_cursor_geometry_get(rp, x, y, w, h, NULL);
|
|
if (x) *x -= ed->x;
|
|
if (y) *y -= ed->y;
|
|
}
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_select_allow_set(const Eo *obj, const char *part, Eina_Bool allow)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
_edje_entry_select_allow_set(rp, allow);
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_select_abort(const Eo *obj, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
_edje_entry_select_abort(rp);
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_select_begin(const Eo *obj, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
_edje_entry_select_begin(rp);
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_select_extend(const Eo *obj, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
_edje_entry_select_extend(rp);
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_efl_canvas_layout_part_text_cursor_next(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return EINA_FALSE;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
return _edje_entry_cursor_next(rp, cur);
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_efl_canvas_layout_part_text_cursor_prev(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return EINA_FALSE;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
return _edje_entry_cursor_prev(rp, cur);
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_efl_canvas_layout_part_text_cursor_up(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return EINA_FALSE;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
return _edje_entry_cursor_up(rp, cur);
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_efl_canvas_layout_part_text_cursor_down(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return EINA_FALSE;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
return _edje_entry_cursor_down(rp, cur);
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
EOLIAN void
|
|
_efl_canvas_layout_part_text_cursor_begin_set(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_cursor_begin(rp, cur);
|
|
}
|
|
}
|
|
|
|
EOLIAN void
|
|
_efl_canvas_layout_part_text_cursor_end_set(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_cursor_end(rp, cur);
|
|
}
|
|
}
|
|
|
|
EOLIAN void
|
|
_efl_canvas_layout_part_text_cursor_copy(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor src, Edje_Cursor dst)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_cursor_copy(rp, src, dst);
|
|
}
|
|
}
|
|
|
|
EOLIAN void
|
|
_efl_canvas_layout_part_text_cursor_line_begin_set(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_cursor_line_begin(rp, cur);
|
|
}
|
|
}
|
|
|
|
EOLIAN void
|
|
_efl_canvas_layout_part_text_cursor_line_end_set(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_cursor_line_end(rp, cur);
|
|
}
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_efl_canvas_layout_part_text_cursor_coord_set(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur, Evas_Coord x, Evas_Coord y)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return EINA_FALSE;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
return _edje_entry_cursor_coord_set(rp, cur, x, y);
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
EOLIAN void
|
|
_efl_canvas_layout_part_text_cursor_pos_set(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur, int pos)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_cursor_pos_set(rp, cur, pos);
|
|
}
|
|
}
|
|
|
|
EOLIAN int
|
|
_efl_canvas_layout_part_text_cursor_pos_get(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
|
|
{
|
|
int ret;
|
|
Edje_Real_Part *rp;
|
|
ret = 0;
|
|
|
|
if ((!ed) || (!part)) return ret;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
ret = _edje_entry_cursor_pos_get(rp, cur);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
EAPI void *
|
|
edje_object_part_text_imf_context_get(const Eo *obj, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return NULL;
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, (char *)part);
|
|
if (!rp) return NULL;
|
|
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
return _edje_entry_imf_context_get(rp);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_imf_context_reset(const Eo *obj, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_imf_context_reset(rp);
|
|
}
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_input_panel_layout_set(Eo *obj, const char *part, Edje_Input_Panel_Layout layout)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_input_panel_layout_set(rp, layout);
|
|
}
|
|
}
|
|
|
|
EAPI Edje_Input_Panel_Layout
|
|
edje_object_part_text_input_panel_layout_get(const Eo *obj, const char *part)
|
|
{
|
|
Edje_Input_Panel_Layout ret;
|
|
Edje_Real_Part *rp;
|
|
ret = EDJE_INPUT_PANEL_LAYOUT_INVALID;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return ret;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
ret = _edje_entry_input_panel_layout_get(rp);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_input_panel_layout_variation_set(Eo *obj, const char *part, int variation)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_input_panel_layout_variation_set(rp, variation);
|
|
}
|
|
}
|
|
|
|
EAPI int
|
|
edje_object_part_text_input_panel_layout_variation_get(const Eo *obj, const char *part)
|
|
{
|
|
int r;
|
|
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
r = 0;
|
|
if ((!ed) || (!part)) return r;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return r;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
r = _edje_entry_input_panel_layout_variation_get(rp);
|
|
}
|
|
return r;
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_autocapital_type_set(Eo *obj, const char *part, Edje_Text_Autocapital_Type autocapital_type)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_autocapital_type_set(rp, autocapital_type);
|
|
}
|
|
}
|
|
|
|
EAPI Edje_Text_Autocapital_Type
|
|
edje_object_part_text_autocapital_type_get(const Eo *obj, const char *part)
|
|
{
|
|
Edje_Text_Autocapital_Type ret;
|
|
Edje_Real_Part *rp;
|
|
ret = EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return ret;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
ret = _edje_entry_autocapital_type_get(rp);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_prediction_allow_set(Eo *obj, const char *part, Eina_Bool prediction)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_prediction_allow_set(rp, prediction);
|
|
}
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_object_part_text_prediction_allow_get(const Eo *obj, const char *part)
|
|
{
|
|
Eina_Bool ret;
|
|
Edje_Real_Part *rp;
|
|
ret = EINA_FALSE;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return ret;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
ret = _edje_entry_prediction_allow_get(rp);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_input_hint_set(Eo *obj, const char *part, Edje_Input_Hints input_hints)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_input_hint_set(rp, input_hints);
|
|
}
|
|
}
|
|
|
|
EAPI Edje_Input_Hints
|
|
edje_object_part_text_input_hint_get(const Eo *obj, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return EINA_FALSE;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
return _edje_entry_input_hint_get(rp);
|
|
}
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_input_panel_enabled_set(Eo *obj, const char *part, Eina_Bool enabled)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_input_panel_enabled_set(rp, enabled);
|
|
}
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_object_part_text_input_panel_enabled_get(const Eo *obj, const char *part)
|
|
{
|
|
Eina_Bool ret;
|
|
Edje_Real_Part *rp;
|
|
ret = EINA_FALSE;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return ret;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
ret = _edje_entry_input_panel_enabled_get(rp);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_input_panel_show(const Eo *obj, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
_edje_entry_input_panel_show(rp);
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_input_panel_hide(const Eo *obj, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
_edje_entry_input_panel_hide(rp);
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_input_panel_language_set(Eo *obj, const char *part, Edje_Input_Panel_Lang lang)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_input_panel_language_set(rp, lang);
|
|
}
|
|
}
|
|
|
|
EAPI Edje_Input_Panel_Lang
|
|
edje_object_part_text_input_panel_language_get(const Eo *obj, const char *part)
|
|
{
|
|
Edje_Input_Panel_Lang ret;
|
|
Edje_Real_Part *rp;
|
|
ret = EDJE_INPUT_PANEL_LANG_AUTOMATIC;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return ret;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
ret = _edje_entry_input_panel_language_get(rp);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_input_panel_imdata_set(Eo *obj, const char *part, const void *data, int len)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_input_panel_imdata_set(rp, data, len);
|
|
}
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_input_panel_imdata_get(const Eo *obj, const char *part, void *data, int *len)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_input_panel_imdata_get(rp, data, len);
|
|
}
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_input_panel_return_key_type_set(Eo *obj, const char *part, Edje_Input_Panel_Return_Key_Type return_key_type)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_input_panel_return_key_type_set(rp, return_key_type);
|
|
}
|
|
}
|
|
|
|
EAPI Edje_Input_Panel_Return_Key_Type
|
|
edje_object_part_text_input_panel_return_key_type_get(const Eo *obj, const char *part)
|
|
{
|
|
Edje_Input_Panel_Return_Key_Type ret;
|
|
Edje_Real_Part *rp;
|
|
ret = EDJE_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return ret;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
ret = _edje_entry_input_panel_return_key_type_get(rp);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_input_panel_return_key_disabled_set(Eo *obj, const char *part, Eina_Bool disabled)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_input_panel_return_key_disabled_set(rp, disabled);
|
|
}
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_object_part_text_input_panel_return_key_disabled_get(const Eo *obj, const char *part)
|
|
{
|
|
Eina_Bool ret;
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ret = EINA_FALSE;
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return ret;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
ret = _edje_entry_input_panel_return_key_disabled_get(rp);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_input_panel_show_on_demand_set(Eo *obj, const char *part, Eina_Bool ondemand)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_input_panel_show_on_demand_set(rp, ondemand);
|
|
}
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_object_part_text_input_panel_show_on_demand_get(const Eo *obj, const char *part)
|
|
{
|
|
Eina_Bool ret;
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ret = EINA_FALSE;
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return ret;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
ret = _edje_entry_input_panel_show_on_demand_get(rp);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_text_prediction_hint_set(Eo *obj, const char *part, const char *prediction_hint)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_prediction_hint_set(rp, prediction_hint);
|
|
}
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_efl_content_content_set(Edje *ed, const char *part, Efl_Gfx_Entity *obj_swallow)
|
|
{
|
|
Edje_Real_Part *rp, *rpcur;
|
|
Edje_User_Defined *eud = NULL;
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
|
|
/* Need to recalc before providing the object. */
|
|
// XXX: I guess this is not required, removing for testing purposes
|
|
// XXX: uncomment if you see glitches in e17 or others.
|
|
// XXX: by Gustavo, January 21th 2009.
|
|
// XXX: I got a backtrace with over 30000 calls without this,
|
|
// XXX: only with 32px shelves. The problem is probably somewhere else,
|
|
// XXX: but until it's found, leave this here.
|
|
// XXX: by Sachiel, January 21th 2009, 19:30 UTC
|
|
// GFY: I decided to try removing this while optimizing some edc and saw
|
|
// SRS: no downside after moderate testing, so I decided to commit it.
|
|
// LOL: - zmike, 1 April 2015
|
|
//_edje_recalc_do(ed);
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
rpcur = evas_object_data_get(obj_swallow, "\377 edje.swallowing_part");
|
|
if (rpcur)
|
|
{
|
|
Edje *sed;
|
|
|
|
/* the object is already swallowed in the requested part */
|
|
if (rpcur == rp) return EINA_TRUE;
|
|
sed = evas_object_data_get(obj_swallow, ".edje");
|
|
if (sed)
|
|
{
|
|
/* The object is already swallowed somewhere, unswallow it first */
|
|
edje_object_part_unswallow(sed->obj, obj_swallow);
|
|
}
|
|
}
|
|
|
|
if (!ed->file)
|
|
{
|
|
eud = _edje_user_definition_new(EDJE_USER_SWALLOW, part, ed);
|
|
if (eud)
|
|
{
|
|
evas_object_event_callback_add(obj_swallow, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
|
|
eud->u.swallow.child = obj_swallow;
|
|
}
|
|
return EINA_TRUE;
|
|
}
|
|
if (!rp)
|
|
{
|
|
DBG("cannot swallow part %s: part not exist!", part);
|
|
return EINA_FALSE;
|
|
}
|
|
if (rp->part->type != EDJE_PART_TYPE_SWALLOW)
|
|
{
|
|
ERR("cannot swallow part %s: not swallow type!", rp->part->name);
|
|
return EINA_FALSE;
|
|
}
|
|
if ((rp->type != EDJE_RP_TYPE_SWALLOW) ||
|
|
(!rp->typedata.swallow)) return EINA_FALSE;
|
|
_edje_real_part_swallow(ed, rp, obj_swallow, EINA_TRUE);
|
|
|
|
if (rp->typedata.swallow->swallowed_object)
|
|
{
|
|
eud = _edje_user_definition_new(EDJE_USER_SWALLOW, part, ed);
|
|
if (eud)
|
|
{
|
|
evas_object_event_callback_add(obj_swallow, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
|
|
eud->u.swallow.child = obj_swallow;
|
|
}
|
|
}
|
|
efl_event_callback_call(ed->obj, EFL_CONTENT_EVENT_CONTENT_CHANGED, obj_swallow);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EAPI void
|
|
edje_extern_object_min_size_set(Evas_Object *obj, Evas_Coord minw, Evas_Coord minh)
|
|
{
|
|
if (!obj) return;
|
|
|
|
evas_object_size_hint_min_set(obj, minw, minh);
|
|
}
|
|
|
|
EAPI void
|
|
edje_extern_object_max_size_set(Evas_Object *obj, Evas_Coord maxw, Evas_Coord maxh)
|
|
{
|
|
if (!obj) return;
|
|
|
|
evas_object_size_hint_max_set(obj, maxw, maxh);
|
|
}
|
|
|
|
EAPI void
|
|
edje_extern_object_aspect_set(Evas_Object *obj, Edje_Aspect_Control aspect, Evas_Coord aw, Evas_Coord ah)
|
|
{
|
|
if (!obj) return;
|
|
Evas_Aspect_Control asp;
|
|
|
|
asp = EVAS_ASPECT_CONTROL_NONE;
|
|
switch (aspect)
|
|
{
|
|
case EDJE_ASPECT_CONTROL_NONE: asp = EVAS_ASPECT_CONTROL_NONE; break;
|
|
|
|
case EDJE_ASPECT_CONTROL_NEITHER: asp = EVAS_ASPECT_CONTROL_NEITHER; break;
|
|
|
|
case EDJE_ASPECT_CONTROL_HORIZONTAL: asp = EVAS_ASPECT_CONTROL_HORIZONTAL; break;
|
|
|
|
case EDJE_ASPECT_CONTROL_VERTICAL: asp = EVAS_ASPECT_CONTROL_VERTICAL; break;
|
|
|
|
case EDJE_ASPECT_CONTROL_BOTH: asp = EVAS_ASPECT_CONTROL_BOTH; break;
|
|
|
|
default: break;
|
|
}
|
|
if (aw < 1) aw = 1;
|
|
if (ah < 1) ah = 1;
|
|
evas_object_size_hint_aspect_set(obj, asp, aw, ah);
|
|
}
|
|
|
|
struct edje_box_layout_builtin
|
|
{
|
|
const char *name;
|
|
Evas_Object_Box_Layout cb;
|
|
};
|
|
|
|
static Evas_Object_Box_Layout
|
|
_edje_box_layout_builtin_find(const char *name)
|
|
{
|
|
const struct edje_box_layout_builtin _edje_box_layout_builtin[] = {
|
|
{"horizontal", evas_object_box_layout_horizontal},
|
|
{"horizontal_flow", evas_object_box_layout_flow_horizontal},
|
|
{"horizontal_homogeneous", evas_object_box_layout_homogeneous_horizontal},
|
|
{"horizontal_max", evas_object_box_layout_homogeneous_max_size_horizontal},
|
|
{"stack", evas_object_box_layout_stack},
|
|
{"vertical", evas_object_box_layout_vertical},
|
|
{"vertical_flow", evas_object_box_layout_flow_vertical},
|
|
{"vertical_homogeneous", evas_object_box_layout_homogeneous_vertical},
|
|
{"vertical_max", evas_object_box_layout_homogeneous_max_size_vertical},
|
|
{NULL, NULL}
|
|
};
|
|
const struct edje_box_layout_builtin *base;
|
|
|
|
switch (name[0])
|
|
{
|
|
case 'h':
|
|
base = _edje_box_layout_builtin + 0;
|
|
break;
|
|
|
|
case 's':
|
|
base = _edje_box_layout_builtin + 4;
|
|
break;
|
|
|
|
case 'v':
|
|
base = _edje_box_layout_builtin + 5;
|
|
break;
|
|
|
|
default:
|
|
return NULL;
|
|
}
|
|
|
|
for (; (base->name) && (base->name[0] == name[0]); base++)
|
|
if (strcmp(base->name, name) == 0)
|
|
return base->cb;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static Eina_Rbtree_Direction
|
|
_edje_box_layout_part_external_node_cmp(const Eina_Rbtree *left, const Eina_Rbtree *right, EINA_UNUSED void *data)
|
|
{
|
|
Edje_Box_Layout *l = (Edje_Box_Layout *)left;
|
|
Edje_Box_Layout *r = (Edje_Box_Layout *)right;
|
|
|
|
if (strcmp(l->name, r->name) < 0)
|
|
return EINA_RBTREE_RIGHT;
|
|
else
|
|
return EINA_RBTREE_LEFT;
|
|
}
|
|
|
|
static int
|
|
_edje_box_layout_part_external_find_cmp(const Eina_Rbtree *node, const void *key, EINA_UNUSED int length, EINA_UNUSED void *data)
|
|
{
|
|
Edje_Box_Layout *l = (Edje_Box_Layout *)node;
|
|
return strcmp(key, l->name);
|
|
}
|
|
|
|
static Edje_Box_Layout *
|
|
_edje_box_layout_part_external_find(const char *name)
|
|
{
|
|
return (Edje_Box_Layout *)eina_rbtree_inline_lookup
|
|
(_edje_box_layout_registry, name, 0, _edje_box_layout_part_external_find_cmp,
|
|
NULL);
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_object_part_text_prediction_hint_hash_set(Eo *obj, const char *part, const char *key, const char *value)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return EINA_FALSE;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
return _edje_entry_prediction_hint_hash_set(rp, key, value);
|
|
}
|
|
else
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_object_part_text_prediction_hint_hash_del(Eo *obj, const char *part, const char *key)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return EINA_FALSE;
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
return _edje_entry_prediction_hint_hash_del(rp, key);
|
|
}
|
|
else
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_box_layout_find(const char *name, Evas_Object_Box_Layout *cb, void **data, void(**free_data) (void *data))
|
|
{
|
|
const Edje_Box_Layout *l;
|
|
|
|
if (!name) return EINA_FALSE;
|
|
|
|
*cb = _edje_box_layout_builtin_find(name);
|
|
if (*cb)
|
|
{
|
|
*free_data = NULL;
|
|
*data = NULL;
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
l = _edje_box_layout_part_external_find(name);
|
|
if (!l) return EINA_FALSE;
|
|
|
|
*cb = l->func;
|
|
*free_data = l->layout_data_free;
|
|
if (l->layout_data_get)
|
|
*data = l->layout_data_get(l->data);
|
|
else
|
|
*data = NULL;
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
_edje_box_layout_part_external_free(Eina_Rbtree *node, EINA_UNUSED void *data)
|
|
{
|
|
Edje_Box_Layout *l = (Edje_Box_Layout *)node;
|
|
|
|
if (l->data && l->free_data)
|
|
l->free_data(l->data);
|
|
free(l);
|
|
}
|
|
|
|
static Edje_Box_Layout *
|
|
_edje_box_layout_part_external_new(const char *name, Evas_Object_Box_Layout func, void *(*layout_data_get)(void *), void (*layout_data_free)(void *), void (*free_data)(void *), void *data)
|
|
{
|
|
Edje_Box_Layout *l;
|
|
size_t name_len;
|
|
|
|
name_len = strlen(name) + 1;
|
|
l = malloc(sizeof(Edje_Box_Layout) + name_len);
|
|
if (!l) return NULL;
|
|
|
|
l->func = func;
|
|
l->layout_data_get = layout_data_get;
|
|
l->layout_data_free = layout_data_free;
|
|
l->free_data = free_data;
|
|
l->data = data;
|
|
|
|
memcpy(l->name, name, name_len);
|
|
|
|
return l;
|
|
}
|
|
|
|
EAPI void
|
|
edje_box_layout_register(const char *name, Evas_Object_Box_Layout func, void *(*layout_data_get)(void *), void (*layout_data_free)(void *), void (*free_data)(void *), void *data)
|
|
{
|
|
Edje_Box_Layout *l;
|
|
|
|
if (!name) return;
|
|
|
|
if (_edje_box_layout_builtin_find(name))
|
|
{
|
|
ERR("Cannot register layout '%s': would override builtin!",
|
|
name);
|
|
|
|
if (data && free_data) free_data(data);
|
|
return;
|
|
}
|
|
|
|
l = _edje_box_layout_part_external_find(name);
|
|
if (!l)
|
|
{
|
|
if (!func)
|
|
{
|
|
if (data && free_data) free_data(data);
|
|
return;
|
|
}
|
|
|
|
l = _edje_box_layout_part_external_new
|
|
(name, func, layout_data_get, layout_data_free, free_data, data);
|
|
if (!l)
|
|
return;
|
|
|
|
_edje_box_layout_registry = eina_rbtree_inline_insert
|
|
(_edje_box_layout_registry, (Eina_Rbtree *)l,
|
|
_edje_box_layout_part_external_node_cmp, NULL);
|
|
}
|
|
else
|
|
{
|
|
if (func)
|
|
{
|
|
if (l->data && l->free_data) l->free_data(l->data);
|
|
|
|
l->func = func;
|
|
l->layout_data_get = layout_data_get;
|
|
l->layout_data_free = layout_data_free;
|
|
l->free_data = free_data;
|
|
l->data = data;
|
|
}
|
|
else
|
|
{
|
|
if (data && free_data) free_data(data);
|
|
|
|
_edje_box_layout_registry = eina_rbtree_inline_remove
|
|
(_edje_box_layout_registry, (Eina_Rbtree *)l,
|
|
_edje_box_layout_part_external_node_cmp, NULL);
|
|
_edje_box_layout_part_external_free((Eina_Rbtree *)l, NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
static Edje_Real_Part *
|
|
_swallow_real_part_get(Evas_Object *obj_swallow)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if (!obj_swallow)
|
|
return NULL;
|
|
|
|
rp = (Edje_Real_Part *)evas_object_data_get(obj_swallow, "\377 edje.swallowing_part");
|
|
if (!rp)
|
|
return NULL;
|
|
if (rp->part->type != EDJE_PART_TYPE_SWALLOW)
|
|
{
|
|
ERR("part %s is not a swallow type!", rp->part->name);
|
|
return NULL;
|
|
}
|
|
|
|
if ((rp->type != EDJE_RP_TYPE_SWALLOW) || (!rp->typedata.swallow))
|
|
return NULL;
|
|
|
|
if (rp->typedata.swallow->swallowed_object == obj_swallow)
|
|
return rp;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_efl_canvas_layout_content_remove(Eo *obj EINA_UNUSED, Edje *ed, Evas_Object *obj_swallow)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje_User_Defined *eud;
|
|
Eina_Iterator *it;
|
|
Eina_List *l, *ll;
|
|
|
|
rp = _swallow_real_part_get(obj_swallow);
|
|
if (!rp) return EINA_FALSE;
|
|
|
|
it = eina_hash_iterator_data_new(ed->user_defined);
|
|
EINA_ITERATOR_FOREACH(it, l)
|
|
{
|
|
EINA_LIST_FOREACH(l, ll, eud)
|
|
if ((eud->type == EDJE_USER_SWALLOW) && (eud->u.swallow.child == obj_swallow))
|
|
{
|
|
_edje_user_definition_free(eud);
|
|
eina_iterator_free(it);
|
|
return EINA_TRUE;
|
|
}
|
|
}
|
|
eina_iterator_free(it);
|
|
_edje_real_part_swallow_clear(ed, rp);
|
|
rp->typedata.swallow->swallowed_object = NULL;
|
|
rp->typedata.swallow->swallow_params.min.w = 0;
|
|
rp->typedata.swallow->swallow_params.min.h = 0;
|
|
rp->typedata.swallow->swallow_params.max.w = 0;
|
|
rp->typedata.swallow->swallow_params.max.h = 0;
|
|
ed->dirty = EINA_TRUE;
|
|
ed->recalc_call = EINA_TRUE;
|
|
#ifdef EDJE_CALC_CACHE
|
|
rp->invalidate = EINA_TRUE;
|
|
#endif
|
|
/* this seems to be as unnecessary as the calc in part_swallow()
|
|
* -zmike, 6 April 2015
|
|
*/
|
|
//_edje_recalc_do(ed);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
typedef struct _Content_Part_Iterator Content_Part_Iterator;
|
|
struct _Content_Part_Iterator
|
|
{
|
|
Eina_Iterator iterator;
|
|
Eo *object;
|
|
Edje *ed;
|
|
unsigned index;
|
|
};
|
|
|
|
static Eina_Bool
|
|
_content_part_iterator_next(Content_Part_Iterator *it, void **data)
|
|
{
|
|
for (; it->index < it->ed->table_parts_size; it->index++)
|
|
{
|
|
Edje_Real_Part *rp = it->ed->table_parts[it->index];
|
|
if (rp->part && rp->part->type == EDJE_PART_TYPE_SWALLOW)
|
|
{
|
|
if (data) *data = (void*) rp->typedata.swallow->swallowed_object;
|
|
it->index++;
|
|
return EINA_TRUE;
|
|
}
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
static Eo *
|
|
_content_part_iterator_get_container(Content_Part_Iterator *it)
|
|
{
|
|
return it->object;
|
|
}
|
|
|
|
static void
|
|
_content_part_iterator_free(Content_Part_Iterator *it)
|
|
{
|
|
free(it);
|
|
}
|
|
|
|
EOLIAN Eina_Iterator*
|
|
_efl_canvas_layout_efl_container_content_iterate(Eo *obj, Edje *ed)
|
|
{
|
|
Content_Part_Iterator *it;
|
|
|
|
it = calloc(1, sizeof(*it));
|
|
if (!it) return NULL;
|
|
|
|
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
|
|
|
|
it->iterator.version = EINA_ITERATOR_VERSION;
|
|
it->iterator.next = FUNC_ITERATOR_NEXT(_content_part_iterator_next);
|
|
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_content_part_iterator_get_container);
|
|
it->iterator.free = FUNC_ITERATOR_FREE(_content_part_iterator_free);
|
|
it->object = obj;
|
|
it->ed = ed;
|
|
it->index = 0;
|
|
|
|
return &it->iterator;
|
|
}
|
|
|
|
EOLIAN int
|
|
_efl_canvas_layout_efl_container_content_count(Eo *obj EINA_UNUSED, Edje *pd)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
int result = 0;
|
|
|
|
for (int i = 0; i < pd->table_parts_size; ++i)
|
|
{
|
|
rp = pd->table_parts[i];
|
|
if (rp->part && rp->part->type == EDJE_PART_TYPE_SWALLOW)
|
|
result ++;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
Efl_Gfx_Entity *
|
|
_edje_efl_content_content_get(Edje *ed, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part)) return NULL;
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return NULL;
|
|
|
|
if (rp->type != EDJE_RP_TYPE_SWALLOW)
|
|
{
|
|
ERR("Edje group '%s' part '%s' is not a swallow. Did "
|
|
"you mean to call efl_part() instead?", ed->group, part);
|
|
return NULL;
|
|
}
|
|
|
|
if (!rp->typedata.swallow) return NULL;
|
|
return rp->typedata.swallow->swallowed_object;
|
|
}
|
|
|
|
EOLIAN Eo *
|
|
_efl_canvas_layout_efl_part_part_get(Eo *obj, Edje *ed, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part)) return NULL;
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp)
|
|
{
|
|
// Note: This could be disabled if debug is not required.
|
|
static const Edje_Real_Part _invalid_part = {};
|
|
rp = (Edje_Real_Part *) &_invalid_part;
|
|
return _edje_invalid_internal_proxy_get(obj, ed, rp, part);
|
|
}
|
|
|
|
if (rp->part->type == EDJE_PART_TYPE_BOX)
|
|
return _edje_box_internal_proxy_get(obj, ed, rp, rp->part->name);
|
|
else if (rp->part->type == EDJE_PART_TYPE_TABLE)
|
|
return _edje_table_internal_proxy_get(obj, ed, rp, rp->part->name);
|
|
else if (rp->part->type == EDJE_PART_TYPE_SWALLOW)
|
|
return _edje_swallow_internal_proxy_get(obj, ed, rp, rp->part->name);
|
|
else if (rp->part->type == EDJE_PART_TYPE_EXTERNAL)
|
|
return _edje_external_internal_proxy_get(obj, ed, rp, rp->part->name);
|
|
else if (rp->part->type == EDJE_PART_TYPE_TEXT)
|
|
return _edje_text_internal_proxy_get(obj, ed, rp, rp->part->name);
|
|
else if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
|
|
return _edje_text_internal_proxy_get(obj, ed, rp, rp->part->name);
|
|
else
|
|
return _edje_other_internal_proxy_get(obj, ed, rp, rp->part->name);
|
|
}
|
|
|
|
EOLIAN Eina_Size2D
|
|
_efl_canvas_layout_efl_layout_group_group_size_min_get(const Eo *obj EINA_UNUSED, Edje *ed)
|
|
{
|
|
if ((!ed) || (!ed->collection))
|
|
return EINA_SIZE2D(0, 0);
|
|
|
|
return ed->collection->prop.min;
|
|
}
|
|
|
|
EOLIAN Eina_Size2D
|
|
_efl_canvas_layout_efl_layout_group_group_size_max_get(const Eo *obj EINA_UNUSED, Edje *ed)
|
|
{
|
|
Eina_Size2D sz;
|
|
|
|
if ((!ed) || (!ed->collection))
|
|
return EINA_SIZE2D(0, 0);
|
|
|
|
/* Need to recalc before providing the object. */
|
|
if (!ed->freeze) _edje_recalc_do(ed);
|
|
|
|
sz = ed->collection->prop.max;
|
|
|
|
/* XXX TODO: use 0 as max, fix things that break. */
|
|
if (sz.w == 0) sz.w = EDJE_INF_MAX_W;
|
|
if (sz.h == 0) sz.h = EDJE_INF_MAX_H;
|
|
return sz;
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_efl_canvas_layout_efl_layout_group_part_exist_get(const Eo *obj EINA_UNUSED, Edje *ed, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if (!part) return EINA_FALSE;
|
|
if (ed->delete_me) return EINA_FALSE;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return EINA_FALSE;
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EOLIAN void
|
|
_efl_canvas_layout_efl_layout_calc_calc_force(Eo *obj EINA_UNUSED, Edje *ed)
|
|
{
|
|
int pf, pf2;
|
|
|
|
if (!ed) return;
|
|
ed->dirty = EINA_TRUE;
|
|
#ifdef EDJE_CALC_CACHE
|
|
ed->all_part_change = EINA_TRUE;
|
|
#endif
|
|
|
|
pf2 = _edje_util_freeze_val;
|
|
pf = ed->freeze;
|
|
|
|
_edje_util_freeze_val = 0;
|
|
ed->freeze = 0;
|
|
|
|
_edje_recalc_do(ed);
|
|
|
|
ed->freeze = pf;
|
|
_edje_util_freeze_val = pf2;
|
|
}
|
|
|
|
EOLIAN Eina_Rect
|
|
_efl_canvas_layout_efl_layout_calc_calc_parts_extends(Eo *obj EINA_UNUSED, Edje *ed)
|
|
{
|
|
Evas_Coord xx1 = INT_MAX, yy1 = INT_MAX;
|
|
Evas_Coord xx2 = 0, yy2 = 0, w = 0, h = 0;
|
|
unsigned short i;
|
|
|
|
ed->calc_only = EINA_TRUE;
|
|
|
|
/* Need to recalc before providing the object. */
|
|
ed->dirty = EINA_TRUE;
|
|
_edje_recalc_do(ed);
|
|
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Evas_Coord rpx1, rpy1;
|
|
Evas_Coord rpx2, rpy2;
|
|
|
|
rp = ed->table_parts[i];
|
|
|
|
rpx1 = rp->x;
|
|
rpy1 = rp->y;
|
|
rpx2 = rpx1 + rp->w;
|
|
rpy2 = rpy1 + rp->h;
|
|
|
|
if (xx1 > rpx1) xx1 = rpx1;
|
|
if (yy1 > rpy1) yy1 = rpy1;
|
|
if (xx2 < rpx2) xx2 = rpx2;
|
|
if (yy2 < rpy2) yy2 = rpy2;
|
|
}
|
|
|
|
ed->calc_only = EINA_FALSE;
|
|
|
|
if ((xx2 - xx1) > 0) w = xx2 - xx1;
|
|
if ((yy2 - yy1) > 0) h = yy2 - yy1;
|
|
|
|
return (Eina_Rect) { (Eina_Rectangle) { xx1, yy1, w, h } };
|
|
}
|
|
|
|
EOLIAN Eina_Size2D
|
|
_efl_canvas_layout_efl_layout_calc_calc_size_min(Eo *obj EINA_UNUSED, Edje *ed, Eina_Size2D restricted)
|
|
{
|
|
const int CALC_COUNT_LIMIT = 255;
|
|
|
|
Evas_Coord orig_w, orig_h; //original edje size
|
|
int max_over_w, max_over_h; //maximum over-calculated size.
|
|
int calc_count = 0;
|
|
Eina_Bool repeat_w, repeat_h;
|
|
Eina_Bool reset_max = EINA_TRUE;
|
|
Edje_Real_Part *pep = NULL;
|
|
/* Only for legacy calculation logic */
|
|
Evas_Coord ins_l, ins_r;
|
|
Eina_Bool has_fixed_tb;
|
|
Eina_Bool legacy_calc;
|
|
Eina_Size2D ret;
|
|
|
|
if ((!ed) || (!ed->collection))
|
|
return restricted;
|
|
|
|
/*
|
|
* It decides a calculation logic according to efl_version of Edje file.
|
|
* There was wrong/special consideration for Textblock parts.
|
|
* Becasue of that, Textblock parts can have minimum size according to its text contents
|
|
* even if there is [text.min: 0 0]. It made people confused.
|
|
*
|
|
* To keep backward compatibility, legacy_calc will be used for old version of EDJ files.
|
|
* With enabling legacy_calc, You can't see proper min/max result accroding to documents.
|
|
*/
|
|
if (!ed->file || ((ed->file->efl_version.major >= 1) && (ed->file->efl_version.minor >= 19)))
|
|
legacy_calc = EINA_FALSE;
|
|
else
|
|
legacy_calc = EINA_TRUE;
|
|
|
|
//Simulate object minimum size.
|
|
ed->calc_only = EINA_TRUE;
|
|
|
|
orig_w = ed->w;
|
|
orig_h = ed->h;
|
|
|
|
again:
|
|
//restrict minimum size to
|
|
ed->w = restricted.w;
|
|
ed->h = restricted.h;
|
|
|
|
max_over_w = 0;
|
|
max_over_h = 0;
|
|
|
|
do
|
|
{
|
|
unsigned short i;
|
|
|
|
calc_count++;
|
|
|
|
repeat_w = EINA_FALSE;
|
|
repeat_h = EINA_FALSE;
|
|
ed->dirty = EINA_TRUE;
|
|
#ifdef EDJE_CALC_CACHE
|
|
ed->all_part_change = EINA_TRUE;
|
|
#endif
|
|
_edje_recalc_do(ed);
|
|
|
|
if (reset_max)
|
|
{
|
|
max_over_w = 0;
|
|
max_over_h = 0;
|
|
}
|
|
|
|
pep = NULL;
|
|
/* Only for legacy calculation logic */
|
|
has_fixed_tb = EINA_TRUE;
|
|
|
|
//for parts
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *ep = ed->table_parts[i];
|
|
|
|
if (!ep->chosen_description) continue;
|
|
|
|
//diff, how much it's over-sized.
|
|
int over_w = (ep->w - ep->req.w);
|
|
int over_h = (ep->h - ep->req.h);
|
|
|
|
/* Only for legacy calculation logic */
|
|
Eina_Bool skip_h = EINA_FALSE;
|
|
|
|
//width
|
|
if (!ep->chosen_description->fixed.w)
|
|
{
|
|
if ((legacy_calc) && (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK))
|
|
{
|
|
//We care textblock width size specially.
|
|
Evas_Coord tb_mw;
|
|
evas_object_textblock_size_formatted_get(ep->object,
|
|
&tb_mw, NULL);
|
|
evas_object_textblock_style_insets_get(ep->object, &ins_l, &ins_r, NULL, NULL);
|
|
tb_mw = ins_l + tb_mw + ins_r;
|
|
tb_mw -= ep->req.w;
|
|
if (tb_mw > over_w) over_w = tb_mw;
|
|
has_fixed_tb = EINA_FALSE;
|
|
}
|
|
|
|
if (over_w > max_over_w)
|
|
{
|
|
max_over_w = over_w;
|
|
repeat_w = EINA_TRUE;
|
|
pep = ep;
|
|
|
|
/* Only for legacy calculation logic */
|
|
skip_h = EINA_TRUE;
|
|
}
|
|
}
|
|
//height
|
|
if (!ep->chosen_description->fixed.h)
|
|
{
|
|
if (legacy_calc)
|
|
{
|
|
if ((ep->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
|
|
((Edje_Part_Description_Text *)ep->chosen_description)->text.min_x ||
|
|
!skip_h)
|
|
{
|
|
if (over_h > max_over_h)
|
|
{
|
|
max_over_h = over_h;
|
|
repeat_h = EINA_TRUE;
|
|
pep = ep;
|
|
}
|
|
}
|
|
|
|
if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
|
|
has_fixed_tb = EINA_FALSE;
|
|
}
|
|
else if (over_h > max_over_h)
|
|
{
|
|
max_over_h = over_h;
|
|
repeat_h = EINA_TRUE;
|
|
pep = ep;
|
|
}
|
|
}
|
|
}
|
|
if (repeat_w)
|
|
{
|
|
ed->w += max_over_w;
|
|
|
|
//exceptional handling.
|
|
if (ed->w < restricted.w) ed->w = restricted.w;
|
|
}
|
|
if (repeat_h)
|
|
{
|
|
ed->h += max_over_h;
|
|
|
|
//exceptional handling.
|
|
if (ed->h < restricted.h) ed->h = restricted.h;
|
|
}
|
|
|
|
if (reset_max && (calc_count > CALC_COUNT_LIMIT))
|
|
{
|
|
if (legacy_calc)
|
|
{
|
|
/* Only print it if we have a non-fixed textblock.
|
|
* We should possibly avoid all of this if in this case, but in
|
|
* the meanwhile, just doing this. */
|
|
if (!has_fixed_tb)
|
|
{
|
|
if (pep)
|
|
ERR("file %s, group %s has a non-fixed part '%s'. Adding 'fixed: 1 1;' to source EDC may help. Continuing discarding faulty part.",
|
|
ed->path, ed->group, pep->part->name);
|
|
else
|
|
ERR("file %s, group %s runs infinite minimum calculation loops.Continuing discarding faulty parts.",
|
|
ed->path, ed->group);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* We should possibly avoid all of this if in this case, but in
|
|
* the meanwhile, just doing this. */
|
|
if (pep)
|
|
ERR("file %s, group %s has a non-fixed part '%s'. Adding 'fixed: 1 1;' to source EDC may help. Continuing discarding faulty part.",
|
|
ed->path, ed->group, pep->part->name);
|
|
else
|
|
ERR("file %s, group %s runs infinite minimum calculation loops.Continuing discarding faulty parts.",
|
|
ed->path, ed->group);
|
|
}
|
|
|
|
reset_max = EINA_FALSE;
|
|
goto again;
|
|
}
|
|
}
|
|
while (repeat_w || repeat_h);
|
|
|
|
ed->min.w = ed->w;
|
|
ed->min.h = ed->h;
|
|
ret = EINA_SIZE2D(ed->min.w, ed->min.h);
|
|
|
|
ed->w = orig_w;
|
|
ed->h = orig_h;
|
|
|
|
ed->dirty = EINA_TRUE;
|
|
#ifdef EDJE_CALC_CACHE
|
|
ed->all_part_change = EINA_TRUE;
|
|
#endif
|
|
_edje_recalc(ed);
|
|
ed->calc_only = EINA_FALSE;
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* FIXME: Correctly return other states */
|
|
const char *
|
|
_edje_object_part_state_get(Edje *ed, const char *part, double *val_ret)
|
|
{
|
|
const char *ret;
|
|
|
|
Edje_Real_Part *rp;
|
|
ret = "";
|
|
|
|
if ((!ed) || (!part))
|
|
{
|
|
if (val_ret) *val_ret = 0;
|
|
return ret;
|
|
}
|
|
|
|
/* Need to recalc before providing the object. */
|
|
_edje_recalc_do(ed);
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp)
|
|
{
|
|
if (val_ret) *val_ret = 0;
|
|
INF("part not found");
|
|
return ret;
|
|
}
|
|
if (rp->chosen_description)
|
|
{
|
|
if (val_ret) *val_ret = rp->chosen_description->state.value;
|
|
if (rp->chosen_description->state.name)
|
|
ret = rp->chosen_description->state.name;
|
|
else
|
|
ret = "default";
|
|
return ret;
|
|
}
|
|
else
|
|
{
|
|
if (rp->param1.description)
|
|
{
|
|
if (val_ret) *val_ret = rp->param1.description->state.value;
|
|
if (rp->param1.description->state.name)
|
|
ret = rp->param1.description->state.name;
|
|
else
|
|
ret = "default";
|
|
return ret;
|
|
}
|
|
}
|
|
if (val_ret) *val_ret = 0;
|
|
|
|
return ret;
|
|
}
|
|
|
|
Edje_Drag_Dir
|
|
_edje_object_part_drag_dir_get(Edje *ed, const char *part)
|
|
{
|
|
Edje_Drag_Dir ret;
|
|
Edje_Real_Part *rp;
|
|
ret = EDJE_DRAG_DIR_NONE;
|
|
|
|
if ((!ed) || (!part)) return ret;
|
|
|
|
/* Need to recalc before providing the object. */
|
|
_edje_recalc_do(ed);
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if ((rp->part->dragable.x) && (rp->part->dragable.y)) ret = EDJE_DRAG_DIR_XY;
|
|
else if (rp->part->dragable.x)
|
|
ret = EDJE_DRAG_DIR_X;
|
|
else if (rp->part->dragable.y)
|
|
ret = EDJE_DRAG_DIR_Y;
|
|
|
|
return ret;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_object_part_drag_value_set(Edje *ed, const char *part, double dx, double dy)
|
|
{
|
|
Edje_Real_Part *rp = NULL;
|
|
Edje_User_Defined *eud;
|
|
Eina_List *l, *ll;
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
if (ed->file)
|
|
{
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return EINA_FALSE;
|
|
if (!rp->drag) return EINA_FALSE;
|
|
}
|
|
|
|
l = eina_hash_find(ed->user_defined, part);
|
|
EINA_LIST_FOREACH(l, ll, eud)
|
|
if (eud->type == EDJE_USER_DRAG_VALUE)
|
|
{
|
|
eud->u.drag_position.x = dx;
|
|
eud->u.drag_position.y = dy;
|
|
break;
|
|
}
|
|
if (!eud)
|
|
{
|
|
eud = _edje_user_definition_new(EDJE_USER_DRAG_VALUE, part, ed);
|
|
if (eud)
|
|
{
|
|
eud->u.drag_position.x = dx;
|
|
eud->u.drag_position.y = dy;
|
|
}
|
|
}
|
|
if (!ed->file) return EINA_TRUE;
|
|
|
|
if (rp->part->dragable.confine_id != -1)
|
|
{
|
|
dx = CLAMP(dx, 0.0, 1.0);
|
|
dy = CLAMP(dy, 0.0, 1.0);
|
|
}
|
|
if (rp->part->dragable.x < 0) dx = 1.0 - dx;
|
|
if (rp->part->dragable.y < 0) dy = 1.0 - dy;
|
|
if (EQ(rp->drag->val.x, FROM_DOUBLE(dx)) && EQ(rp->drag->val.y, FROM_DOUBLE(dy)))
|
|
{
|
|
return EINA_TRUE;
|
|
}
|
|
rp->drag->val.x = FROM_DOUBLE(dx);
|
|
rp->drag->val.y = FROM_DOUBLE(dy);
|
|
#ifdef EDJE_CALC_CACHE
|
|
rp->invalidate = EINA_TRUE;
|
|
#endif
|
|
_edje_dragable_pos_set(ed, rp, rp->drag->val.x, rp->drag->val.y);
|
|
_edje_emit(ed, "drag,set", rp->part->name);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
/* FIXME: Should this be x and y instead of dx/dy? */
|
|
Eina_Bool
|
|
_edje_object_part_drag_value_get(Edje *ed, const char *part, double *dx, double *dy)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
double ddx, ddy;
|
|
|
|
if ((!ed) || (!part))
|
|
{
|
|
if (dx) *dx = 0;
|
|
if (dy) *dy = 0;
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
/* Need to recalc before providing the object. */
|
|
_edje_recalc_do(ed);
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp || !rp->drag)
|
|
{
|
|
if (dx) *dx = 0;
|
|
if (dy) *dy = 0;
|
|
return EINA_FALSE;
|
|
}
|
|
ddx = TO_DOUBLE(rp->drag->val.x);
|
|
ddy = TO_DOUBLE(rp->drag->val.y);
|
|
if (rp->part->dragable.x < 0) ddx = 1.0 - ddx;
|
|
if (rp->part->dragable.y < 0) ddy = 1.0 - ddy;
|
|
if (dx) *dx = ddx;
|
|
if (dy) *dy = ddy;
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_object_part_drag_size_set(Edje *ed, const char *part, double dw, double dh)
|
|
{
|
|
Edje_Real_Part *rp = NULL;
|
|
Edje_User_Defined *eud;
|
|
Eina_List *l, *ll;
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (ed->file)
|
|
{
|
|
if (!rp) return EINA_FALSE;
|
|
if (!rp->drag) return EINA_FALSE;
|
|
}
|
|
|
|
l = eina_hash_find(ed->user_defined, part);
|
|
EINA_LIST_FOREACH(l, ll, eud)
|
|
if (eud->type == EDJE_USER_DRAG_SIZE)
|
|
{
|
|
eud->u.drag_size.w = dw;
|
|
eud->u.drag_size.h = dh;
|
|
break;
|
|
}
|
|
if (!eud)
|
|
{
|
|
eud = _edje_user_definition_new(EDJE_USER_DRAG_SIZE, part, ed);
|
|
if (eud)
|
|
{
|
|
eud->u.drag_size.w = dw;
|
|
eud->u.drag_size.h = dh;
|
|
}
|
|
}
|
|
if (!ed->file) return EINA_TRUE;
|
|
|
|
if (dw < 0.0) dw = 0.0;
|
|
else if (dw > 1.0)
|
|
dw = 1.0;
|
|
if (dh < 0.0) dh = 0.0;
|
|
else if (dh > 1.0)
|
|
dh = 1.0;
|
|
if (EQ(rp->drag->size.x, FROM_DOUBLE(dw)) && EQ(rp->drag->size.y, FROM_DOUBLE(dh)))
|
|
{
|
|
return EINA_TRUE;
|
|
}
|
|
rp->drag->size.x = FROM_DOUBLE(dw);
|
|
rp->drag->size.y = FROM_DOUBLE(dh);
|
|
ed->dirty = EINA_TRUE;
|
|
ed->recalc_call = EINA_TRUE;
|
|
#ifdef EDJE_CALC_CACHE
|
|
rp->invalidate = EINA_TRUE;
|
|
#endif
|
|
_edje_recalc(ed);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_object_part_drag_size_get(Edje *ed, const char *part, double *dw, double *dh)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part))
|
|
{
|
|
if (dw) *dw = 0;
|
|
if (dh) *dh = 0;
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
/* Need to recalc before providing the object. */
|
|
_edje_recalc_do(ed);
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp || !rp->drag)
|
|
{
|
|
if (dw) *dw = 0;
|
|
if (dh) *dh = 0;
|
|
return EINA_FALSE;
|
|
}
|
|
if (dw) *dw = TO_DOUBLE(rp->drag->size.x);
|
|
if (dh) *dh = TO_DOUBLE(rp->drag->size.y);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_object_part_drag_step_set(Edje *ed, const char *part, double dx, double dy)
|
|
{
|
|
Edje_Real_Part *rp = NULL;
|
|
Edje_User_Defined *eud;
|
|
Eina_List *l, *ll;
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (ed->file)
|
|
{
|
|
if (!rp) return EINA_FALSE;
|
|
if (!rp->drag) return EINA_FALSE;
|
|
}
|
|
|
|
l = eina_hash_find(ed->user_defined, part);
|
|
EINA_LIST_FOREACH(l, ll, eud)
|
|
if (eud->type == EDJE_USER_DRAG_STEP)
|
|
{
|
|
eud->u.drag_position.x = dx;
|
|
eud->u.drag_position.y = dy;
|
|
break;
|
|
}
|
|
if (!eud)
|
|
{
|
|
eud = _edje_user_definition_new(EDJE_USER_DRAG_STEP, part, ed);
|
|
if (eud)
|
|
{
|
|
eud->u.drag_position.x = dx;
|
|
eud->u.drag_position.y = dy;
|
|
}
|
|
}
|
|
if (!ed->file) return EINA_TRUE;
|
|
|
|
if (dx < 0.0) dx = 0.0;
|
|
else if (dx > 1.0)
|
|
dx = 1.0;
|
|
if (dy < 0.0) dy = 0.0;
|
|
else if (dy > 1.0)
|
|
dy = 1.0;
|
|
rp->drag->step.x = FROM_DOUBLE(dx);
|
|
rp->drag->step.y = FROM_DOUBLE(dy);
|
|
#ifdef EDJE_CALC_CACHE
|
|
rp->invalidate = EINA_TRUE;
|
|
#endif
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_object_part_drag_step_get(Edje *ed, const char *part, double *dx, double *dy)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part))
|
|
{
|
|
if (dx) *dx = 0;
|
|
if (dy) *dy = 0;
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
/* Need to recalc before providing the object. */
|
|
_edje_recalc_do(ed);
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp || !rp->drag)
|
|
{
|
|
if (dx) *dx = 0;
|
|
if (dy) *dy = 0;
|
|
return EINA_FALSE;
|
|
}
|
|
if (dx) *dx = TO_DOUBLE(rp->drag->step.x);
|
|
if (dy) *dy = TO_DOUBLE(rp->drag->step.y);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_object_part_drag_page_set(Edje *ed, const char *part, double dx, double dy)
|
|
{
|
|
Edje_Real_Part *rp = NULL;
|
|
Edje_User_Defined *eud;
|
|
Eina_List *l, *ll;
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
if (ed->file)
|
|
{
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return EINA_FALSE;
|
|
if (!rp->drag) return EINA_FALSE;
|
|
}
|
|
|
|
l = eina_hash_find(ed->user_defined, part);
|
|
EINA_LIST_FOREACH(l, ll, eud)
|
|
if (eud->type == EDJE_USER_DRAG_PAGE)
|
|
{
|
|
eud->u.drag_position.x = dx;
|
|
eud->u.drag_position.y = dy;
|
|
break;
|
|
}
|
|
if (!eud)
|
|
{
|
|
eud = _edje_user_definition_new(EDJE_USER_DRAG_PAGE, part, ed);
|
|
if (eud)
|
|
{
|
|
eud->u.drag_position.x = dx;
|
|
eud->u.drag_position.y = dy;
|
|
}
|
|
}
|
|
if (!ed->file) return EINA_TRUE;
|
|
|
|
if (dx < 0.0) dx = 0.0;
|
|
else if (dx > 1.0)
|
|
dx = 1.0;
|
|
if (dy < 0.0) dy = 0.0;
|
|
else if (dy > 1.0)
|
|
dy = 1.0;
|
|
rp->drag->page.x = FROM_DOUBLE(dx);
|
|
rp->drag->page.y = FROM_DOUBLE(dy);
|
|
#ifdef EDJE_CALC_CACHE
|
|
rp->invalidate = EINA_TRUE;
|
|
#endif
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_object_part_drag_page_get(Edje *ed, const char *part, double *dx, double *dy)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part))
|
|
{
|
|
if (dx) *dx = 0;
|
|
if (dy) *dy = 0;
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
/* Need to recalc before providing the object. */
|
|
_edje_recalc_do(ed);
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp || !rp->drag)
|
|
{
|
|
if (dx) *dx = 0;
|
|
if (dy) *dy = 0;
|
|
return EINA_FALSE;
|
|
}
|
|
if (dx) *dx = TO_DOUBLE(rp->drag->page.x);
|
|
if (dy) *dy = TO_DOUBLE(rp->drag->page.y);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_object_part_drag_step(Edje *ed, const char *part, double dx, double dy)
|
|
{
|
|
Edje_Real_Part *rp = NULL;
|
|
FLOAT_T px, py;
|
|
Edje_User_Defined *eud;
|
|
Eina_List *l, *ll;
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
if (ed->file)
|
|
{
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return EINA_FALSE;
|
|
if (!rp->drag) return EINA_FALSE;
|
|
}
|
|
|
|
l = eina_hash_find(ed->user_defined, part);
|
|
EINA_LIST_FOREACH(l, ll, eud)
|
|
if (eud->type == EDJE_USER_DRAG_STEP)
|
|
{
|
|
eud->u.drag_position.x = dx;
|
|
eud->u.drag_position.y = dy;
|
|
break;
|
|
}
|
|
if (!eud)
|
|
{
|
|
eud = _edje_user_definition_new(EDJE_USER_DRAG_STEP, part, ed);
|
|
if (eud)
|
|
{
|
|
eud->u.drag_position.x = dx;
|
|
eud->u.drag_position.y = dy;
|
|
}
|
|
}
|
|
if (!ed->file) return EINA_TRUE;
|
|
|
|
px = rp->drag->val.x;
|
|
py = rp->drag->val.y;
|
|
rp->drag->val.x = ADD(px, MUL(FROM_DOUBLE(dx),
|
|
MUL(rp->drag->step.x, rp->part->dragable.x)));
|
|
rp->drag->val.y = ADD(py, MUL(FROM_DOUBLE(dy),
|
|
MUL(rp->drag->step.y, rp->part->dragable.y)));
|
|
rp->drag->val.x = CLAMP(rp->drag->val.x, ZERO, FROM_DOUBLE(1.0));
|
|
rp->drag->val.y = CLAMP(rp->drag->val.y, ZERO, FROM_DOUBLE(1.0));
|
|
if (EQ(px, rp->drag->val.x) && EQ(py, rp->drag->val.y))
|
|
{
|
|
return EINA_TRUE;
|
|
}
|
|
#ifdef EDJE_CALC_CACHE
|
|
rp->invalidate = EINA_TRUE;
|
|
#endif
|
|
_edje_dragable_pos_set(ed, rp, rp->drag->val.x, rp->drag->val.y);
|
|
_edje_emit(ed, "drag,step", rp->part->name);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_object_part_drag_page(Edje *ed, const char *part, double dx, double dy)
|
|
{
|
|
Edje_Real_Part *rp = NULL;
|
|
FLOAT_T px, py;
|
|
Edje_User_Defined *eud;
|
|
Eina_List *l, *ll;
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
if (ed->file)
|
|
{
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return EINA_FALSE;
|
|
if (!rp->drag) return EINA_FALSE;
|
|
}
|
|
|
|
l = eina_hash_find(ed->user_defined, part);
|
|
EINA_LIST_FOREACH(l, ll, eud)
|
|
if (eud->type == EDJE_USER_DRAG_PAGE)
|
|
{
|
|
eud->u.drag_position.x = dx;
|
|
eud->u.drag_position.y = dy;
|
|
break;
|
|
}
|
|
if (!eud)
|
|
{
|
|
eud = _edje_user_definition_new(EDJE_USER_DRAG_PAGE, part, ed);
|
|
if (eud)
|
|
{
|
|
eud->u.drag_position.x = dx;
|
|
eud->u.drag_position.y = dy;
|
|
}
|
|
}
|
|
if (!ed->file) return EINA_TRUE;
|
|
|
|
px = rp->drag->val.x;
|
|
py = rp->drag->val.y;
|
|
rp->drag->val.x = ADD(px, MUL(FROM_DOUBLE(dx), MUL(rp->drag->page.x, rp->part->dragable.x)));
|
|
rp->drag->val.y = ADD(py, MUL(FROM_DOUBLE(dy), MUL(rp->drag->page.y, rp->part->dragable.y)));
|
|
rp->drag->val.x = CLAMP(rp->drag->val.x, ZERO, FROM_DOUBLE(1.0));
|
|
rp->drag->val.y = CLAMP(rp->drag->val.y, ZERO, FROM_DOUBLE(1.0));
|
|
if (EQ(px, rp->drag->val.x) && EQ(py, rp->drag->val.y))
|
|
{
|
|
return EINA_TRUE;
|
|
}
|
|
#ifdef EDJE_CALC_CACHE
|
|
rp->invalidate = EINA_TRUE;
|
|
#endif
|
|
_edje_dragable_pos_set(ed, rp, rp->drag->val.x, rp->drag->val.y);
|
|
_edje_emit(ed, "drag,page", rp->part->name);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
void
|
|
_edje_box_init(void)
|
|
{
|
|
}
|
|
|
|
void
|
|
_edje_box_shutdown(void)
|
|
{
|
|
if (!_edje_box_layout_registry)
|
|
return;
|
|
|
|
eina_rbtree_delete
|
|
(_edje_box_layout_registry, _edje_box_layout_part_external_free, NULL);
|
|
_edje_box_layout_registry = NULL;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_part_box_append(Edje *ed, const char *part, Evas_Object *child)
|
|
{
|
|
Eina_Bool ret;
|
|
Edje_Real_Part *rp = NULL;
|
|
ret = EINA_FALSE;
|
|
|
|
if ((!ed) || (!part) || (!child)) return ret;
|
|
|
|
if (ed->file)
|
|
{
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if (rp->part->type != EDJE_PART_TYPE_BOX) return ret;
|
|
}
|
|
|
|
if ((!ed->file) || _edje_real_part_box_append(ed, rp, child))
|
|
{
|
|
Edje_User_Defined *eud;
|
|
|
|
eud = _edje_user_definition_new(EDJE_USER_BOX_PACK, part, ed);
|
|
if (!eud) return ret;
|
|
eud->u.box.child = child;
|
|
eud->u.box.index = -1;
|
|
|
|
evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
|
|
ret = EINA_TRUE;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_part_box_prepend(Edje *ed, const char *part, Evas_Object *child)
|
|
{
|
|
Eina_Bool ret;
|
|
Edje_Real_Part *rp = NULL;
|
|
ret = EINA_FALSE;
|
|
|
|
if ((!ed) || (!part)) return ret;
|
|
|
|
if (ed->file)
|
|
{
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if (rp->part->type != EDJE_PART_TYPE_BOX) return ret;
|
|
}
|
|
|
|
if ((!ed->file) || _edje_real_part_box_prepend(ed, rp, child))
|
|
{
|
|
Edje_User_Defined *eud;
|
|
|
|
eud = _edje_user_definition_new(EDJE_USER_BOX_PACK, part, ed);
|
|
if (!eud) return ret;
|
|
eud->u.box.child = child;
|
|
|
|
evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
|
|
ret = EINA_TRUE;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_part_box_insert_before(Edje *ed, const char *part, Evas_Object *child, const Evas_Object *reference)
|
|
{
|
|
Eina_Bool ret;
|
|
Edje_Real_Part *rp = NULL;
|
|
ret = EINA_FALSE;
|
|
|
|
if ((!ed) || (!part)) return ret;
|
|
|
|
if (ed->file)
|
|
{
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if (rp->part->type != EDJE_PART_TYPE_BOX) return ret;
|
|
}
|
|
|
|
if ((!ed->file) || _edje_real_part_box_insert_before(ed, rp, child, reference))
|
|
{
|
|
Edje_User_Defined *eud;
|
|
|
|
eud = _edje_user_definition_new(EDJE_USER_BOX_PACK, part, ed);
|
|
if (!eud) return ret;
|
|
eud->u.box.child = child;
|
|
|
|
evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
|
|
ret = EINA_TRUE;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_part_box_insert_after(Edje *ed, const char *part, Evas_Object *child, const Evas_Object *reference)
|
|
{
|
|
Eina_Bool ret;
|
|
Edje_Real_Part *rp = NULL;
|
|
ret = EINA_FALSE;
|
|
|
|
if ((!ed) || (!part)) return ret;
|
|
|
|
if (ed->file)
|
|
{
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if (rp->part->type != EDJE_PART_TYPE_BOX) return ret;
|
|
}
|
|
|
|
if ((!ed->file) || _edje_real_part_box_insert_after(ed, rp, child, reference))
|
|
{
|
|
Edje_User_Defined *eud;
|
|
|
|
eud = _edje_user_definition_new(EDJE_USER_BOX_PACK, part, ed);
|
|
if (!eud) return ret;
|
|
eud->u.box.child = child;
|
|
|
|
evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
|
|
ret = EINA_TRUE;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_part_box_insert_at(Edje *ed, const char *part, Evas_Object *child, unsigned int pos)
|
|
{
|
|
Eina_Bool ret;
|
|
Edje_Real_Part *rp = NULL;
|
|
ret = EINA_FALSE;
|
|
|
|
if ((!ed) || (!part)) return ret;
|
|
|
|
if (ed->file)
|
|
{
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if (rp->part->type != EDJE_PART_TYPE_BOX) return ret;
|
|
}
|
|
|
|
if ((!ed->file) || _edje_real_part_box_insert_at(ed, rp, child, pos))
|
|
{
|
|
Edje_User_Defined *eud;
|
|
|
|
eud = _edje_user_definition_new(EDJE_USER_BOX_PACK, part, ed);
|
|
if (!eud) return ret;
|
|
eud->u.box.child = child;
|
|
|
|
evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
|
|
ret = EINA_TRUE;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void
|
|
_edje_part_box_remove_user_definition(Edje *ed, Eina_Stringshare *part, Evas_Object *child)
|
|
{
|
|
Edje_User_Defined *eud;
|
|
Eina_List *l, *ll;
|
|
|
|
l = eina_hash_find(ed->user_defined, part);
|
|
EINA_LIST_FOREACH(l, ll, eud)
|
|
if (eud->type == EDJE_USER_BOX_PACK && eud->u.box.child == child)
|
|
{
|
|
_edje_user_definition_free(eud);
|
|
return;
|
|
}
|
|
}
|
|
|
|
Evas_Object *
|
|
_edje_part_box_remove(Edje *ed, const char *part, Evas_Object *child)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Evas_Object *r;
|
|
|
|
if ((!ed) || (!part)) return NULL;
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return NULL;
|
|
if (rp->part->type != EDJE_PART_TYPE_BOX) return NULL;
|
|
|
|
r = _edje_real_part_box_remove(ed, rp, child);
|
|
|
|
if (r) _edje_part_box_remove_user_definition(ed, part, r);
|
|
return r;
|
|
}
|
|
|
|
Evas_Object *
|
|
_edje_part_box_remove_at(Edje *ed, const char *part, unsigned int pos)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Evas_Object *r;
|
|
|
|
if ((!ed) || (!part)) return NULL;
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return NULL;
|
|
if (rp->part->type != EDJE_PART_TYPE_BOX) return NULL;
|
|
|
|
r = _edje_real_part_box_remove_at(ed, rp, pos);
|
|
|
|
if (r) _edje_part_box_remove_user_definition(ed, part, r);
|
|
return r;
|
|
}
|
|
|
|
Evas_Object *
|
|
_edje_part_box_content_at(Edje *ed, const char *part, unsigned int pos)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Evas_Object *r;
|
|
|
|
if ((!ed) || (!part)) return NULL;
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return NULL;
|
|
if (rp->part->type != EDJE_PART_TYPE_BOX) return NULL;
|
|
|
|
r = _edje_real_part_box_content_at(ed, rp, pos);
|
|
return r;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_part_box_remove_all(Edje *ed, const char *part, Eina_Bool clear)
|
|
{
|
|
Eina_Bool ret;
|
|
Edje_Real_Part *rp;
|
|
ret = EINA_FALSE;
|
|
|
|
if ((!ed) || (!part)) return ret;
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if (rp->part->type != EDJE_PART_TYPE_BOX) return ret;
|
|
|
|
if (_edje_real_part_box_remove_all(ed, rp, clear))
|
|
{
|
|
ret = EINA_TRUE;
|
|
eina_hash_del_by_key(ed->user_defined, part);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
typedef struct _Part_Iterator Part_Iterator;
|
|
struct _Part_Iterator
|
|
{
|
|
Eina_Iterator iterator;
|
|
Eo *object;
|
|
Edje *ed;
|
|
unsigned index;
|
|
};
|
|
|
|
static Eina_Bool
|
|
_part_iterator_next(Part_Iterator *it, void **data)
|
|
{
|
|
for (; it->index < it->ed->table_parts_size; it->index++)
|
|
{
|
|
Edje_Real_Part *rp = it->ed->table_parts[it->index];
|
|
if (rp->part->access)
|
|
{
|
|
if (data) *data = (void*) rp->part->name;
|
|
it->index++;
|
|
return EINA_TRUE;
|
|
}
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
static Eo *
|
|
_part_iterator_get_container(Part_Iterator *it)
|
|
{
|
|
return it->object;
|
|
}
|
|
|
|
static void
|
|
_part_iterator_free(Part_Iterator *it)
|
|
{
|
|
free(it);
|
|
}
|
|
|
|
EOLIAN Eina_Iterator *
|
|
_efl_canvas_layout_access_part_iterate(Eo *obj EINA_UNUSED, Edje *ed)
|
|
{
|
|
Part_Iterator *it;
|
|
|
|
it = calloc(1, sizeof(*it));
|
|
if (!it) return NULL;
|
|
|
|
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
|
|
|
|
it->iterator.version = EINA_ITERATOR_VERSION;
|
|
it->iterator.next = FUNC_ITERATOR_NEXT(_part_iterator_next);
|
|
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_part_iterator_get_container);
|
|
it->iterator.free = FUNC_ITERATOR_FREE(_part_iterator_free);
|
|
it->object = obj;
|
|
it->ed = ed;
|
|
it->index = 0;
|
|
|
|
return &it->iterator;
|
|
}
|
|
|
|
EAPI Eina_List *
|
|
edje_object_access_part_list_get(const Edje_Object *obj)
|
|
{
|
|
Eina_List *access_parts = NULL;
|
|
Eina_Iterator *it;
|
|
const char *str;
|
|
|
|
it = efl_canvas_layout_access_part_iterate((Eo *) obj);
|
|
EINA_ITERATOR_FOREACH(it, str)
|
|
access_parts = eina_list_append(access_parts, str);
|
|
eina_iterator_free(it);
|
|
|
|
return access_parts;
|
|
}
|
|
|
|
static void
|
|
_edje_child_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *child, void *einfo EINA_UNUSED)
|
|
{
|
|
Edje_Real_Part *rp = data;
|
|
Edje_User_Defined *eud;
|
|
Eina_List *l, *ll;
|
|
Edje *ed = evas_object_data_get(child, ".edje");
|
|
|
|
if (!ed) return;
|
|
l = eina_hash_find(ed->user_defined, rp->part->name);
|
|
EINA_LIST_FOREACH(l, ll, eud)
|
|
if (rp->part->type == EDJE_PART_TYPE_BOX)
|
|
{
|
|
if (eud->type == EDJE_USER_BOX_PACK &&
|
|
eud->u.box.child == child)
|
|
{
|
|
_edje_user_definition_free(eud);
|
|
break;
|
|
}
|
|
}
|
|
else if (rp->part->type == EDJE_PART_TYPE_TABLE)
|
|
{
|
|
if (eud->type == EDJE_USER_TABLE_PACK &&
|
|
eud->u.table.child == child)
|
|
{
|
|
_edje_user_definition_free(eud);
|
|
break;
|
|
}
|
|
}
|
|
|
|
ed->dirty = EINA_TRUE;
|
|
ed->recalc_call = EINA_TRUE;
|
|
#ifdef EDJE_CALC_CACHE
|
|
rp->invalidate = EINA_TRUE;
|
|
#endif
|
|
_edje_recalc(ed);
|
|
}
|
|
|
|
static void
|
|
_edje_child_add(Edje *ed, Edje_Real_Part *rp, Evas_Object *child)
|
|
{
|
|
evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, _edje_child_del_cb, rp);
|
|
evas_object_data_set(child, ".edje", ed);
|
|
if (!ed) return;
|
|
efl_parent_set(child, ed->obj);
|
|
ed->dirty = EINA_TRUE;
|
|
ed->recalc_call = EINA_TRUE;
|
|
#ifdef EDJE_CALC_CACHE
|
|
rp->invalidate = EINA_TRUE;
|
|
#endif
|
|
_edje_recalc(ed);
|
|
}
|
|
|
|
static void
|
|
_eo_unparent_helper(Eo *child, Eo *parent)
|
|
{
|
|
if (efl_invalidated_get(child)) return ;
|
|
if (efl_parent_get(child) == parent)
|
|
{
|
|
if (efl_invalidated_get(evas_object_evas_get(parent)))
|
|
// Temporary reparenting children to the main loop.
|
|
// They are about to die, but shouldn't just yet.
|
|
{
|
|
efl_parent_set(child, efl_main_loop_get());
|
|
}
|
|
else
|
|
{
|
|
efl_parent_set(child, evas_object_evas_get(parent));
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
_edje_child_remove(Edje *ed, Edje_Real_Part *rp, Evas_Object *child)
|
|
{
|
|
evas_object_event_callback_del_full(child, EVAS_CALLBACK_DEL, _edje_child_del_cb, rp);
|
|
evas_object_data_del(child, ".edje");
|
|
if (!ed) return;
|
|
_eo_unparent_helper(child, ed->obj);
|
|
ed->dirty = EINA_TRUE;
|
|
ed->recalc_call = EINA_TRUE;
|
|
#ifdef EDJE_CALC_CACHE
|
|
rp->invalidate = EINA_TRUE;
|
|
#endif
|
|
_edje_recalc(ed);
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_real_part_box_append(Edje *ed, Edje_Real_Part *rp, Evas_Object *child_obj)
|
|
{
|
|
Evas_Object_Box_Option *opt;
|
|
|
|
opt = evas_object_box_append(rp->object, child_obj);
|
|
if (!opt) return EINA_FALSE;
|
|
|
|
if (!_edje_box_layout_add_child(rp, child_obj))
|
|
{
|
|
evas_object_box_remove(rp->object, child_obj);
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
_edje_child_add(ed, rp, child_obj);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_real_part_box_prepend(Edje *ed, Edje_Real_Part *rp, Evas_Object *child_obj)
|
|
{
|
|
Evas_Object_Box_Option *opt;
|
|
|
|
opt = evas_object_box_prepend(rp->object, child_obj);
|
|
if (!opt) return EINA_FALSE;
|
|
|
|
if (!_edje_box_layout_add_child(rp, child_obj))
|
|
{
|
|
evas_object_box_remove(rp->object, child_obj);
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
_edje_child_add(ed, rp, child_obj);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_real_part_box_insert_before(Edje *ed, Edje_Real_Part *rp, Evas_Object *child_obj, const Evas_Object *ref)
|
|
{
|
|
Evas_Object_Box_Option *opt;
|
|
|
|
opt = evas_object_box_insert_before(rp->object, child_obj, ref);
|
|
if (!opt) return EINA_FALSE;
|
|
|
|
if (!_edje_box_layout_add_child(rp, child_obj))
|
|
{
|
|
evas_object_box_remove(rp->object, child_obj);
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
_edje_child_add(ed, rp, child_obj);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_real_part_box_insert_after(Edje *ed, Edje_Real_Part *rp, Evas_Object *child_obj, const Evas_Object *ref)
|
|
{
|
|
Evas_Object_Box_Option *opt;
|
|
|
|
opt = evas_object_box_insert_after(rp->object, child_obj, ref);
|
|
if (!opt) return EINA_FALSE;
|
|
|
|
if (!_edje_box_layout_add_child(rp, child_obj))
|
|
{
|
|
evas_object_box_remove(rp->object, child_obj);
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
_edje_child_add(ed, rp, child_obj);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_real_part_box_insert_at(Edje *ed, Edje_Real_Part *rp, Evas_Object *child_obj, unsigned int pos)
|
|
{
|
|
Evas_Object_Box_Option *opt;
|
|
|
|
opt = evas_object_box_insert_at(rp->object, child_obj, pos);
|
|
if (!opt) return EINA_FALSE;
|
|
|
|
if (!_edje_box_layout_add_child(rp, child_obj))
|
|
{
|
|
evas_object_box_remove(rp->object, child_obj);
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
_edje_child_add(ed, rp, child_obj);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Evas_Object *
|
|
_edje_real_part_box_content_at(Edje *ed EINA_UNUSED, Edje_Real_Part *rp, unsigned int pos)
|
|
{
|
|
Evas_Object_Box_Option *opt;
|
|
Evas_Object_Box_Data *priv;
|
|
|
|
priv = efl_data_scope_get(rp->object, EVAS_BOX_CLASS);
|
|
opt = eina_list_nth(priv->children, pos);
|
|
if (!opt) return NULL;
|
|
return opt->obj;
|
|
}
|
|
|
|
Evas_Object *
|
|
_edje_real_part_box_remove(Edje *ed, Edje_Real_Part *rp, Evas_Object *child_obj)
|
|
{
|
|
if (evas_object_data_get(child_obj, "\377 edje.box_item")) return NULL;
|
|
if (!evas_object_box_remove(rp->object, child_obj)) return NULL;
|
|
_edje_box_layout_remove_child(rp, child_obj);
|
|
_edje_child_remove(ed, rp, child_obj);
|
|
return child_obj;
|
|
}
|
|
|
|
Evas_Object *
|
|
_edje_real_part_box_remove_at(Edje *ed, Edje_Real_Part *rp, unsigned int pos)
|
|
{
|
|
Evas_Object_Box_Option *opt;
|
|
Evas_Object_Box_Data *priv;
|
|
Evas_Object *child_obj;
|
|
|
|
priv = efl_data_scope_get(rp->object, EVAS_BOX_CLASS);
|
|
opt = eina_list_nth(priv->children, pos);
|
|
if (!opt) return NULL;
|
|
child_obj = opt->obj;
|
|
if (evas_object_data_get(child_obj, "\377 edje.box_item")) return NULL;
|
|
if (!evas_object_box_remove_at(rp->object, pos)) return NULL;
|
|
_edje_box_layout_remove_child(rp, child_obj);
|
|
_edje_child_remove(ed, rp, child_obj);
|
|
return child_obj;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_real_part_box_remove_all(Edje *ed, Edje_Real_Part *rp, Eina_Bool clear)
|
|
{
|
|
Eina_List *children;
|
|
int i = 0;
|
|
|
|
children = evas_object_box_children_get(rp->object);
|
|
while (children)
|
|
{
|
|
Evas_Object *child_obj = children->data;
|
|
if (evas_object_data_get(child_obj, "\377 edje.box_item"))
|
|
i++;
|
|
else
|
|
{
|
|
_edje_box_layout_remove_child(rp, child_obj);
|
|
_edje_child_remove(ed, rp, child_obj);
|
|
if (!evas_object_box_remove_at(rp->object, i))
|
|
{
|
|
eina_list_free(children);
|
|
return EINA_FALSE;
|
|
}
|
|
if (clear)
|
|
evas_object_del(child_obj);
|
|
}
|
|
children = eina_list_remove_list(children, children);
|
|
}
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Evas_Object *
|
|
_edje_part_table_child_get(Edje *ed, const char *part, unsigned int col, unsigned int row)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part)) return NULL;
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return NULL;
|
|
if (rp->part->type != EDJE_PART_TYPE_TABLE) return NULL;
|
|
|
|
return evas_object_table_child_get(rp->object, col, row);
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_part_table_pack(Edje *ed, const char *part, Evas_Object *child_obj, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan)
|
|
{
|
|
Eina_Bool ret;
|
|
Edje_Real_Part *rp = NULL;
|
|
Edje_User_Defined *eud;
|
|
ret = EINA_FALSE;
|
|
|
|
if ((!ed) || (!part)) return ret;
|
|
|
|
if (ed->file)
|
|
{
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if (rp->part->type != EDJE_PART_TYPE_TABLE) return ret;
|
|
}
|
|
|
|
if ((!ed->file) || _edje_real_part_table_pack(ed, rp, child_obj, col, row, colspan, rowspan))
|
|
{
|
|
ret = EINA_TRUE;
|
|
eud = _edje_user_definition_new(EDJE_USER_TABLE_PACK, part, ed);
|
|
if (!eud) return ret;
|
|
|
|
eud->u.table.child = child_obj;
|
|
eud->u.table.col = col;
|
|
eud->u.table.row = row;
|
|
eud->u.table.colspan = colspan;
|
|
eud->u.table.rowspan = rowspan;
|
|
|
|
evas_object_event_callback_add(child_obj, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_part_table_unpack(Edje *ed, const char *part, Evas_Object *child_obj)
|
|
{
|
|
Eina_Bool ret;
|
|
Edje_Real_Part *rp;
|
|
ret = EINA_FALSE;
|
|
|
|
if ((!ed) || (!part)) return ret;
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return ret;
|
|
if (rp->part->type != EDJE_PART_TYPE_TABLE) return ret;
|
|
|
|
if (_edje_real_part_table_unpack(ed, rp, child_obj))
|
|
{
|
|
ret = EINA_TRUE;
|
|
Edje_User_Defined *eud;
|
|
Eina_List *l, *ll;
|
|
|
|
l = eina_hash_find(ed->user_defined, part);
|
|
EINA_LIST_FOREACH(l, ll, eud)
|
|
if (eud->type == EDJE_USER_TABLE_PACK &&
|
|
eud->u.table.child == child_obj)
|
|
{
|
|
_edje_user_definition_free(eud);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_part_table_col_row_size_get(Edje *ed, const char *part, int *cols, int *rows)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return EINA_FALSE;
|
|
if (rp->part->type != EDJE_PART_TYPE_TABLE) return EINA_FALSE;
|
|
|
|
evas_object_table_col_row_size_get(rp->object, cols, rows);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_part_table_clear(Edje *ed, const char *part, Eina_Bool clear)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
if ((!ed) || (!part)) return EINA_FALSE;
|
|
|
|
rp = _edje_real_part_recursive_get(&ed, part);
|
|
if (!rp) return EINA_FALSE;
|
|
if (rp->part->type != EDJE_PART_TYPE_TABLE) return EINA_FALSE;
|
|
|
|
_edje_real_part_table_clear(ed, rp, clear);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
_edje_perspective_obj_del(void *data, EINA_UNUSED Evas *e, EINA_UNUSED Evas_Object *obj, EINA_UNUSED void *event_info)
|
|
{
|
|
Edje_Perspective *ps = data;
|
|
Evas_Object *o;
|
|
|
|
EINA_LIST_FREE(ps->users, o)
|
|
{
|
|
Edje *ed;
|
|
|
|
ed = efl_data_scope_get(o, EFL_CANVAS_LAYOUT_CLASS);
|
|
if (!ed) continue;
|
|
ed->persp = NULL;
|
|
ed->dirty = EINA_TRUE;
|
|
ed->recalc_call = EINA_TRUE;
|
|
_edje_recalc_do(ed);
|
|
}
|
|
free(ps);
|
|
}
|
|
|
|
EAPI Edje_Perspective *
|
|
edje_perspective_new(Evas *e)
|
|
{
|
|
Edje_Perspective *ps;
|
|
Evas_Coord vx, vy, vw, vh;
|
|
|
|
if (!e) return NULL;
|
|
ps = calloc(1, sizeof(Edje_Perspective));
|
|
ps->obj = evas_object_rectangle_add(e);
|
|
evas_object_data_set(ps->obj, "_edje_perspective", ps);
|
|
evas_object_event_callback_add(ps->obj, EVAS_CALLBACK_DEL, _edje_perspective_obj_del, ps);
|
|
evas_output_viewport_get(e, &vx, &vy, &vw, &vh);
|
|
ps->e = e;
|
|
ps->px = vx + (vw / 2);
|
|
ps->py = vy + (vh / 2);
|
|
ps->z0 = 0;
|
|
ps->foc = 1000;
|
|
return ps;
|
|
}
|
|
|
|
EAPI void
|
|
edje_perspective_free(Edje_Perspective *ps)
|
|
{
|
|
if (!ps) return;
|
|
evas_object_del(ps->obj);
|
|
}
|
|
|
|
EAPI void
|
|
edje_perspective_set(Edje_Perspective *ps, Evas_Coord px, Evas_Coord py, Evas_Coord z0, Evas_Coord foc)
|
|
{
|
|
Eina_List *l;
|
|
Evas_Object *o;
|
|
|
|
if (!ps) return;
|
|
if ((ps->px == px) && (ps->py == py) && (ps->z0 == z0) && (ps->foc == foc)) return;
|
|
ps->px = px;
|
|
ps->py = py;
|
|
ps->z0 = z0;
|
|
ps->foc = foc;
|
|
EINA_LIST_FOREACH(ps->users, l, o)
|
|
{
|
|
Edje *ed;
|
|
|
|
ed = efl_data_scope_get(o, EFL_CANVAS_LAYOUT_CLASS);
|
|
if (!ed) continue;
|
|
if (!ed->persp)
|
|
{
|
|
ed->dirty = EINA_TRUE;
|
|
ed->recalc_call = EINA_TRUE;
|
|
_edje_recalc_do(ed);
|
|
}
|
|
}
|
|
if (ps->global)
|
|
{
|
|
Edje *ed;
|
|
|
|
EINA_INLIST_FOREACH(_edje_edjes, ed)
|
|
{
|
|
if (!ed->persp)
|
|
{
|
|
ed->dirty = EINA_TRUE;
|
|
ed->recalc_call = EINA_TRUE;
|
|
_edje_recalc_do(ed);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
EAPI void
|
|
edje_perspective_global_set(Edje_Perspective *ps, Eina_Bool global)
|
|
{
|
|
Edje *ed;
|
|
Evas_Object *o;
|
|
|
|
if (!ps) return;
|
|
if (ps->global == global) return;
|
|
if (global)
|
|
{
|
|
o = evas_object_name_find(evas_object_evas_get(ps->obj),
|
|
"_edje_perspective");
|
|
if (o) evas_object_name_set(o, NULL);
|
|
evas_object_name_set(ps->obj, "_edje_perspective");
|
|
}
|
|
else
|
|
evas_object_name_set(ps->obj, NULL);
|
|
ps->global = global;
|
|
EINA_INLIST_FOREACH(_edje_edjes, ed)
|
|
{
|
|
if (!ed->persp)
|
|
{
|
|
ed->dirty = EINA_TRUE;
|
|
ed->recalc_call = EINA_TRUE;
|
|
_edje_recalc_do(ed);
|
|
}
|
|
}
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_perspective_global_get(const Edje_Perspective *ps)
|
|
{
|
|
if (!ps) return EINA_FALSE;
|
|
return ps->global;
|
|
}
|
|
|
|
EAPI const Edje_Perspective *
|
|
edje_evas_global_perspective_get(const Evas *e)
|
|
{
|
|
Evas_Object *obj;
|
|
|
|
if (!e) return NULL;
|
|
obj = evas_object_name_find(e, "_edje_perspective");
|
|
if (!obj) return NULL;
|
|
return evas_object_data_get(obj, "_edje_perspective");
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_perspective_set(Eo *obj, Edje_Perspective *ps)
|
|
{
|
|
Edje *ed = _edje_fetch(obj);
|
|
if (!ed) return;
|
|
if (ed->persp == ps) return;
|
|
if (ed->persp != ps)
|
|
{
|
|
if (ed->persp)
|
|
ed->persp->users = eina_list_remove(ed->persp->users, obj);
|
|
}
|
|
ed->persp = ps;
|
|
if (ps) ps->users = eina_list_append(ps->users, obj);
|
|
ed->dirty = EINA_TRUE;
|
|
ed->recalc_call = EINA_TRUE;
|
|
_edje_recalc_do(ed);
|
|
}
|
|
|
|
EAPI const Edje_Perspective *
|
|
edje_object_perspective_get(const Eo *obj)
|
|
{
|
|
Edje *ed =_edje_fetch(obj);
|
|
if (!ed) return NULL;
|
|
return ed->persp;
|
|
}
|
|
|
|
#define EDJE_PRELOAD_EMISSION "preload,done"
|
|
#define EDJE_PRELOAD_SOURCE NULL
|
|
|
|
EAPI Eina_Bool
|
|
edje_object_preload(Eo *obj, Eina_Bool cancel)
|
|
{
|
|
unsigned short count;
|
|
unsigned short i;
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
if (!ed) return EINA_FALSE;
|
|
|
|
_edje_recalc_do(ed);
|
|
|
|
for (i = 0, count = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje_Part *ep;
|
|
|
|
rp = ed->table_parts[i];
|
|
ep = rp->part;
|
|
|
|
if ((ep->type == EDJE_PART_TYPE_IMAGE) ||
|
|
((ep->type == EDJE_PART_TYPE_GROUP) &&
|
|
((rp->type == EDJE_RP_TYPE_SWALLOW) &&
|
|
(rp->typedata.swallow)) &&
|
|
(rp->typedata.swallow->swallowed_object)))
|
|
count++;
|
|
}
|
|
|
|
ed->preload_count = count;
|
|
|
|
if (count > 0)
|
|
{
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje_Part *ep;
|
|
|
|
rp = ed->table_parts[i];
|
|
ep = rp->part;
|
|
|
|
if (ep->type == EDJE_PART_TYPE_IMAGE)
|
|
{
|
|
const char *file = NULL;
|
|
const char *key = NULL;
|
|
|
|
evas_object_event_callback_del_full(rp->object, EVAS_CALLBACK_IMAGE_PRELOADED, _edje_object_image_preload_cb, ed);
|
|
|
|
evas_object_image_file_get(rp->object, &file, &key);
|
|
if (!file && !key)
|
|
{
|
|
ed->preload_count--;
|
|
}
|
|
else
|
|
{
|
|
evas_object_event_callback_add(rp->object, EVAS_CALLBACK_IMAGE_PRELOADED, _edje_object_image_preload_cb, ed);
|
|
evas_object_image_preload(rp->object, cancel);
|
|
}
|
|
count--;
|
|
}
|
|
else if (ep->type == EDJE_PART_TYPE_GROUP)
|
|
{
|
|
if (((rp->type == EDJE_RP_TYPE_SWALLOW) &&
|
|
(rp->typedata.swallow)) &&
|
|
(rp->typedata.swallow->swallowed_object))
|
|
{
|
|
char *tmp;
|
|
|
|
if (rp->part->name)
|
|
{
|
|
tmp = alloca(strlen(rp->part->name) + 2);
|
|
sprintf(tmp, "%s:", rp->part->name);
|
|
|
|
edje_object_signal_callback_del(obj, EDJE_PRELOAD_EMISSION, tmp, _edje_object_signal_preload_cb);
|
|
edje_object_signal_callback_add(obj, EDJE_PRELOAD_EMISSION, tmp, _edje_object_signal_preload_cb, ed);
|
|
edje_object_preload(rp->typedata.swallow->swallowed_object, cancel);
|
|
}
|
|
else
|
|
{
|
|
ed->preload_count--;
|
|
}
|
|
count--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_edje_emit(ed, EDJE_PRELOAD_EMISSION, EDJE_PRELOAD_SOURCE);
|
|
}
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EOLIAN void
|
|
_efl_canvas_layout_efl_layout_calc_calc_auto_update_hints_set(Eo *obj EINA_UNUSED, Edje *ed, Eina_Bool update)
|
|
{
|
|
if (!ed) return;
|
|
if (ed->update_hints == !!update) return;
|
|
|
|
ed->update_hints = !!update;
|
|
if (update)
|
|
{
|
|
ed->recalc_hints = EINA_TRUE;
|
|
_edje_recalc(ed);
|
|
}
|
|
}
|
|
|
|
EOLIAN Eina_Bool
|
|
_efl_canvas_layout_efl_layout_calc_calc_auto_update_hints_get(const Eo *obj EINA_UNUSED, Edje *ed)
|
|
{
|
|
return ed->update_hints;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_real_part_table_pack(Edje *ed, Edje_Real_Part *rp, Evas_Object *child_obj, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan)
|
|
{
|
|
Eina_Bool ret =
|
|
evas_object_table_pack(rp->object, child_obj, col, row, colspan, rowspan);
|
|
|
|
_edje_child_add(ed, rp, child_obj);
|
|
|
|
return ret;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_real_part_table_unpack(Edje *ed, Edje_Real_Part *rp, Evas_Object *child_obj)
|
|
{
|
|
Eina_Bool ret = evas_object_table_unpack(rp->object, child_obj);
|
|
|
|
if (ret)
|
|
_edje_child_remove(ed, rp, child_obj);
|
|
|
|
return ret;
|
|
}
|
|
|
|
void
|
|
_edje_real_part_table_clear(Edje *ed, Edje_Real_Part *rp, Eina_Bool clear)
|
|
{
|
|
Eina_List *children;
|
|
|
|
children = evas_object_table_children_get(rp->object);
|
|
while (children)
|
|
{
|
|
Evas_Object *child_obj = children->data;
|
|
|
|
_edje_child_remove(ed, rp, child_obj);
|
|
if (!evas_object_data_get(child_obj, "\377 edje.table_item"))
|
|
{
|
|
evas_object_table_unpack(rp->object, child_obj);
|
|
if (clear)
|
|
evas_object_del(child_obj);
|
|
}
|
|
children = eina_list_remove_list(children, children);
|
|
}
|
|
}
|
|
|
|
Edje_Part_Description_Text *
|
|
_edje_real_part_text_source_description_get(Edje_Real_Part *ep, Edje_Real_Part **rp2)
|
|
{
|
|
Edje_Part_Description_Text *et;
|
|
Edje_Real_Part *rp = ep->typedata.text->source;
|
|
if (ep->typedata.text->source->type == EDJE_RP_TYPE_SWALLOW)
|
|
{
|
|
Edje *ed2;
|
|
|
|
et = (Edje_Part_Description_Text *)ep->param1.description;
|
|
ed2 = _edje_fetch(ep->typedata.text->source->typedata.swallow->swallowed_object);
|
|
if (!ed2) return NULL;
|
|
rp = _edje_real_part_recursive_get(&ed2, et->text.id_source_part);
|
|
if (!rp) return NULL;
|
|
et = (Edje_Part_Description_Text *)rp->chosen_description;
|
|
}
|
|
else
|
|
et = (Edje_Part_Description_Text *)ep->typedata.text->source->chosen_description;
|
|
if (rp2) *rp2 = rp;
|
|
return et;
|
|
}
|
|
|
|
Edje_Part_Description_Text *
|
|
_edje_real_part_text_text_source_description_get(Edje_Real_Part *ep, Edje_Real_Part **rp2)
|
|
{
|
|
Edje_Part_Description_Text *et;
|
|
Edje_Real_Part *rp = ep->typedata.text->text_source;
|
|
if (ep->typedata.text->text_source->type == EDJE_RP_TYPE_SWALLOW)
|
|
{
|
|
Edje *ed2;
|
|
|
|
et = (Edje_Part_Description_Text *)ep->param1.description;
|
|
ed2 = _edje_fetch(ep->typedata.text->text_source->typedata.swallow->swallowed_object);
|
|
if (!ed2) return NULL;
|
|
rp = _edje_real_part_recursive_get(&ed2, et->text.id_text_source_part);
|
|
if (!rp) return NULL;
|
|
et = (Edje_Part_Description_Text *)rp->chosen_description;
|
|
}
|
|
else
|
|
et = (Edje_Part_Description_Text *)ep->typedata.text->text_source->chosen_description;
|
|
if (rp2) *rp2 = rp;
|
|
return et;
|
|
}
|
|
|
|
Edje_Real_Part *
|
|
_edje_real_part_recursive_get(Edje **ed, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
char **path;
|
|
|
|
path = eina_str_split(part, EDJE_PART_PATH_SEPARATOR_STRING, 0);
|
|
if (!path) return NULL;
|
|
|
|
rp = _edje_real_part_recursive_get_helper(ed, path);
|
|
|
|
free(*path);
|
|
free(path);
|
|
return rp;
|
|
}
|
|
|
|
Evas_Object *
|
|
_edje_children_get(Edje_Real_Part *rp, const char *partid)
|
|
{
|
|
Evas_Object *child = NULL;
|
|
Eina_Iterator *it = NULL;
|
|
long int v;
|
|
char *p;
|
|
|
|
if (!partid) return NULL;
|
|
|
|
switch (rp->part->type)
|
|
{
|
|
case EDJE_PART_TYPE_EXTERNAL:
|
|
if ((rp->type != EDJE_RP_TYPE_SWALLOW) ||
|
|
(!rp->typedata.swallow)) return NULL;
|
|
return _edje_external_content_get
|
|
(rp->typedata.swallow->swallowed_object, partid);
|
|
|
|
case EDJE_PART_TYPE_BOX:
|
|
it = evas_object_box_iterator_new(rp->object);
|
|
break;
|
|
|
|
case EDJE_PART_TYPE_TABLE:
|
|
it = evas_object_table_iterator_new(rp->object);
|
|
break;
|
|
|
|
default:
|
|
return NULL;
|
|
}
|
|
|
|
v = strtol(partid, &p, 10);
|
|
if ((*p == '\0') && (v >= 0))
|
|
{
|
|
int i = 0;
|
|
EINA_ITERATOR_FOREACH(it, child)
|
|
{
|
|
if (i == v) break;
|
|
i++;
|
|
}
|
|
if (i != v) child = NULL;
|
|
}
|
|
else
|
|
{
|
|
Evas_Object *cur;
|
|
|
|
EINA_ITERATOR_FOREACH(it, cur)
|
|
{
|
|
const char *name = evas_object_name_get(cur);
|
|
if ((name) && (!strcmp(name, partid)))
|
|
{
|
|
child = cur;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
eina_iterator_free(it);
|
|
|
|
return child;
|
|
}
|
|
|
|
/* rebuild alternative path */
|
|
char *
|
|
_edje_merge_path(const char *alias, char *const *path)
|
|
{
|
|
char *tmp;
|
|
unsigned int length = 1;
|
|
unsigned int alias_length;
|
|
unsigned int i;
|
|
|
|
if (!alias) return NULL;
|
|
|
|
alias_length = strlen(alias);
|
|
|
|
for (i = 0; path[i]; i++)
|
|
length += strlen(path[i]) + 1;
|
|
|
|
tmp = malloc(sizeof (char) * (length + alias_length + 2));
|
|
memcpy(tmp, alias, alias_length);
|
|
tmp[alias_length] = '\0';
|
|
|
|
for (i = 0; path[i]; i++)
|
|
{
|
|
strcat(tmp, EDJE_PART_PATH_SEPARATOR_STRING);
|
|
strcat(tmp, path[i]);
|
|
}
|
|
|
|
return tmp;
|
|
}
|
|
|
|
Edje_Real_Part *
|
|
_edje_real_part_recursive_get_helper(Edje **ed, char **path)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Evas_Object *child;
|
|
char *idx = NULL;
|
|
|
|
if (!path[0])
|
|
return NULL;
|
|
|
|
if ((*ed)->collection && (*ed)->collection->alias)
|
|
{
|
|
char *alias;
|
|
|
|
alias = _edje_merge_path(eina_hash_find((*ed)->collection->alias, path[0]), path + 1);
|
|
if (alias)
|
|
{
|
|
rp = _edje_real_part_recursive_get(ed, alias);
|
|
free(alias);
|
|
return rp;
|
|
}
|
|
}
|
|
|
|
//printf(" lookup: %s on %s\n", path[0], ed->parent ? ed->parent : "-");
|
|
idx = strchr(path[0], EDJE_PART_PATH_SEPARATOR_INDEXL);
|
|
if (idx)
|
|
{
|
|
char *end;
|
|
|
|
end = strchr(idx + 1, EDJE_PART_PATH_SEPARATOR_INDEXR);
|
|
if (end)
|
|
{
|
|
*end = '\0';
|
|
*idx = '\0';
|
|
idx++;
|
|
}
|
|
}
|
|
|
|
rp = _edje_real_part_get(*ed, path[0]);
|
|
if (!path[1] && !idx) return rp;
|
|
if (!rp) return NULL;
|
|
|
|
switch (rp->part->type)
|
|
{
|
|
case EDJE_PART_TYPE_GROUP:
|
|
if ((rp->type != EDJE_RP_TYPE_SWALLOW) ||
|
|
(!rp->typedata.swallow)) return NULL;
|
|
if (!rp->typedata.swallow->swallowed_object) return NULL;
|
|
*ed = _edje_fetch(rp->typedata.swallow->swallowed_object);
|
|
if (!*ed) return NULL;
|
|
path++;
|
|
return _edje_real_part_recursive_get_helper(ed, path);
|
|
|
|
case EDJE_PART_TYPE_BOX:
|
|
case EDJE_PART_TYPE_TABLE:
|
|
case EDJE_PART_TYPE_EXTERNAL:
|
|
if (!idx) return rp;
|
|
path++;
|
|
|
|
child = _edje_children_get(rp, idx);
|
|
|
|
*ed = _edje_fetch(child);
|
|
|
|
if (!*ed) return NULL;
|
|
return _edje_real_part_recursive_get_helper(ed, path);
|
|
|
|
default:
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
/* Private Routines - do not call eo_do inside this one */
|
|
Edje_Real_Part *
|
|
_edje_real_part_get(const Edje *ed, const char *part)
|
|
{
|
|
unsigned short i;
|
|
|
|
if (!part) return NULL;
|
|
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
rp = ed->table_parts[i];
|
|
if ((rp->part->name) && (!strcmp(rp->part->name, part))) return rp;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void *
|
|
_edje_hash_find_helper(const Eina_Hash *hash, const char *key)
|
|
{
|
|
static const char *remember_key = NULL;
|
|
void *data;
|
|
int i, j;
|
|
char **tokens;
|
|
unsigned int tokens_count = 0;
|
|
|
|
data = eina_hash_find(hash, key);
|
|
if (data)
|
|
return data;
|
|
|
|
// We only receive pointer from Eet files as key, we can
|
|
// assume them constant over the life time of the program.
|
|
if (remember_key == key)
|
|
return NULL;
|
|
|
|
// It is usually faster to walk the string once to check
|
|
// if there will be any tokens to process, that to allocate
|
|
// an array, copy one token, and then just free it.
|
|
if (strchr(key, '/') == NULL)
|
|
{
|
|
remember_key = key;
|
|
return NULL;
|
|
}
|
|
|
|
tokens = eina_str_split_full(key, "/", 0, &tokens_count);
|
|
if ((tokens) && (tokens_count > 1))
|
|
{
|
|
Eina_Strbuf *buf = NULL;
|
|
|
|
buf = eina_strbuf_new();
|
|
|
|
for (i = tokens_count - 2; i >= 0; i--)
|
|
{
|
|
for (j = 0; j < i; j++)
|
|
{
|
|
eina_strbuf_append(buf, tokens[j]);
|
|
eina_strbuf_append(buf, "/");
|
|
}
|
|
eina_strbuf_append(buf, tokens[tokens_count - 1]);
|
|
|
|
data = eina_hash_find(hash, eina_strbuf_string_get(buf));
|
|
if (data) break;
|
|
|
|
eina_strbuf_reset(buf);
|
|
}
|
|
|
|
eina_strbuf_free(buf);
|
|
}
|
|
else
|
|
{
|
|
remember_key = key;
|
|
}
|
|
|
|
if (tokens)
|
|
{
|
|
free(tokens[0]);
|
|
free(tokens);
|
|
}
|
|
return data;
|
|
}
|
|
|
|
Edje_Color_Class *
|
|
_edje_color_class_find(const Edje *ed, const char *color_class)
|
|
{
|
|
Edje_Color_Class *cc = NULL;
|
|
|
|
if ((!ed) || (!color_class)) return NULL;
|
|
|
|
/* first look through the object scope */
|
|
cc = eina_hash_find(ed->color_classes, color_class);
|
|
if (cc) return cc;
|
|
|
|
/* next look through the global scope */
|
|
cc = eina_hash_find(_edje_color_class_hash, color_class);
|
|
if (cc) return cc;
|
|
|
|
/* finally, look through the file scope */
|
|
if (ed->file)
|
|
cc = eina_hash_find(ed->file->color_hash, color_class);
|
|
if (cc) return cc;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
Edje_Color_Class *
|
|
_edje_color_class_recursive_find_helper(const Edje *ed, Eina_Hash *hash, const char *color_class)
|
|
{
|
|
Edje_Color_Class *cc = NULL;
|
|
Edje_Color_Tree_Node *ctn = NULL;
|
|
const char *parent;
|
|
|
|
if (!eina_hash_population(hash)) return NULL;
|
|
|
|
cc = _edje_hash_find_helper(hash, color_class);
|
|
if (cc) return cc;
|
|
else if (ed->file)
|
|
{
|
|
parent = color_class;
|
|
while ((ctn = eina_hash_find(ed->file->color_tree_hash, parent)))
|
|
{
|
|
parent = ctn->name;
|
|
cc = eina_hash_find(hash, parent);
|
|
if (cc) return cc;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
Edje_Color_Class *
|
|
_edje_color_class_recursive_find(const Edje *ed, const char *color_class)
|
|
{
|
|
Edje_Color_Class *cc = NULL;
|
|
|
|
if ((!ed) || (!color_class)) return NULL;
|
|
|
|
/* first look through the object scope */
|
|
cc = _edje_color_class_recursive_find_helper(ed, ed->color_classes, color_class);
|
|
if (cc) return cc;
|
|
|
|
/* next look through the global scope */
|
|
cc = _edje_color_class_recursive_find_helper(ed, _edje_color_class_hash, color_class);
|
|
if (cc) return cc;
|
|
|
|
/* finally, look through the file scope */
|
|
if (ed->file)
|
|
cc = _edje_color_class_recursive_find_helper(ed, ed->file->color_hash, color_class);
|
|
if (cc) return cc;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static Eina_Bool
|
|
color_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
|
|
{
|
|
Edje_Color_Class *cc;
|
|
|
|
cc = data;
|
|
if (cc->name) eina_stringshare_del(cc->name);
|
|
free(cc);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
void
|
|
_edje_color_class_hash_free(void)
|
|
{
|
|
if (!_edje_color_class_hash) return;
|
|
eina_hash_foreach(_edje_color_class_hash, color_class_hash_list_free, NULL);
|
|
eina_hash_free(_edje_color_class_hash);
|
|
_edje_color_class_hash = NULL;
|
|
}
|
|
|
|
void
|
|
_edje_color_class_on_del(Edje *ed, Edje_Part *ep)
|
|
{
|
|
unsigned int i;
|
|
|
|
if ((ep->default_desc) && (ep->default_desc->color_class))
|
|
efl_observable_observer_del(_edje_color_class_member, ep->default_desc->color_class, ed->obj);
|
|
|
|
for (i = 0; i < ep->other.desc_count; ++i)
|
|
if (ep->other.desc[i]->color_class)
|
|
efl_observable_observer_del(_edje_color_class_member, ep->other.desc[i]->color_class, ed->obj);
|
|
}
|
|
|
|
Edje_Text_Class *
|
|
_edje_text_class_find(Edje *ed, const char *text_class)
|
|
{
|
|
Edje_Text_Class *tc;
|
|
|
|
if ((!ed) || (!text_class)) return NULL;
|
|
|
|
/* first look through the object scope */
|
|
tc = eina_hash_find(ed->text_classes, text_class);
|
|
if (tc) return tc;
|
|
|
|
/* next look through the global scope */
|
|
tc = eina_hash_find(_edje_text_class_hash, text_class);
|
|
if (tc) return tc;
|
|
|
|
/* finally, look through the file scope */
|
|
if (ed->file)
|
|
tc = eina_hash_find(ed->file->text_hash, text_class);
|
|
if (tc) return tc;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static Eina_Bool
|
|
text_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
|
|
{
|
|
Edje_Text_Class *tc;
|
|
|
|
tc = data;
|
|
if (tc->name) eina_stringshare_del(tc->name);
|
|
if (tc->font) eina_stringshare_del(tc->font);
|
|
free(tc);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
void
|
|
_edje_text_class_hash_free(void)
|
|
{
|
|
if (!_edje_text_class_hash) return;
|
|
eina_hash_foreach(_edje_text_class_hash, text_class_hash_list_free, NULL);
|
|
eina_hash_free(_edje_text_class_hash);
|
|
_edje_text_class_hash = NULL;
|
|
}
|
|
|
|
Edje_Size_Class *
|
|
_edje_size_class_find(Edje *ed, const char *size_class)
|
|
{
|
|
Edje_Size_Class *sc;
|
|
|
|
if ((!ed) || (!size_class)) return NULL;
|
|
|
|
/* first look through the object scope */
|
|
sc = eina_hash_find(ed->size_classes, size_class);
|
|
if (sc) return sc;
|
|
|
|
/* next look through the global scope */
|
|
sc = eina_hash_find(_edje_size_class_hash, size_class);
|
|
if (sc) return sc;
|
|
|
|
/* finally, look through the file scope */
|
|
if (ed->file)
|
|
sc = eina_hash_find(ed->file->size_hash, size_class);
|
|
if (sc) return sc;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static Eina_Bool
|
|
size_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
|
|
{
|
|
Edje_Size_Class *sc;
|
|
|
|
sc = data;
|
|
if (sc->name) eina_stringshare_del(sc->name);
|
|
free(sc);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
void
|
|
_edje_size_class_hash_free(void)
|
|
{
|
|
if (!_edje_size_class_hash) return;
|
|
eina_hash_foreach(_edje_size_class_hash, size_class_hash_list_free, NULL);
|
|
eina_hash_free(_edje_size_class_hash);
|
|
_edje_size_class_hash = NULL;
|
|
}
|
|
|
|
Edje *
|
|
_edje_fetch(const Evas_Object *obj)
|
|
{
|
|
Edje *ed;
|
|
|
|
if (!obj || !efl_isa(obj, EFL_CANVAS_LAYOUT_CLASS))
|
|
return NULL;
|
|
ed = efl_data_scope_get(obj, EFL_CANVAS_LAYOUT_CLASS);
|
|
if ((ed) && (ed->delete_me)) return NULL;
|
|
return ed;
|
|
}
|
|
|
|
int
|
|
_edje_util_freeze(Edje *ed)
|
|
{
|
|
ed->freeze++;
|
|
// printf("FREEZE %i\n", ed->freeze);
|
|
return ed->freeze;
|
|
}
|
|
|
|
int
|
|
_edje_util_thaw(Edje *ed)
|
|
{
|
|
if (ed->freeze == 0) return 0;
|
|
ed->freeze--;
|
|
if ((ed->freeze == 0) && (ed->recalc))
|
|
{
|
|
// printf("thaw recalc\n");
|
|
_edje_recalc(ed);
|
|
}
|
|
return ed->freeze;
|
|
}
|
|
|
|
int
|
|
_edje_block(Edje *ed)
|
|
{
|
|
_edje_ref(ed);
|
|
ed->block++;
|
|
return ed->block;
|
|
}
|
|
|
|
int
|
|
_edje_unblock(Edje *ed)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (!ed) return ret;
|
|
|
|
ed->block--;
|
|
if (ed->block == 0) ed->block_break = EINA_FALSE;
|
|
ret = ed->block;
|
|
_edje_unref(ed);
|
|
return ret;
|
|
}
|
|
|
|
int
|
|
_edje_block_break(Edje *ed)
|
|
{
|
|
if (ed->block_break) return 1;
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
_edje_block_violate(Edje *ed)
|
|
{
|
|
if (ed->block > 0) ed->block_break = EINA_TRUE;
|
|
}
|
|
|
|
void
|
|
_edje_object_part_swallow_free_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
{
|
|
Edje_User_Defined *eud;
|
|
Eina_List *l, *ll;
|
|
Eina_Iterator *it;
|
|
Edje *ed;
|
|
Edje_Real_Part *rp;
|
|
|
|
ed = evas_object_data_get(obj, ".edje");
|
|
if (!ed) return;
|
|
it = eina_hash_iterator_data_new(ed->user_defined);
|
|
EINA_ITERATOR_FOREACH(it, l)
|
|
{
|
|
EINA_LIST_FOREACH(l, ll, eud)
|
|
if (eud->type == EDJE_USER_SWALLOW && eud->u.swallow.child == obj)
|
|
{
|
|
_edje_user_definition_free(eud);
|
|
goto out;
|
|
}
|
|
}
|
|
out:
|
|
rp = evas_object_data_get(obj, "\377 edje.swallowing_part");
|
|
if (rp && (rp->part->type == EDJE_PART_TYPE_SWALLOW))
|
|
edje_object_part_unswallow(ed->obj, obj);
|
|
|
|
return;
|
|
}
|
|
|
|
static void
|
|
_edje_real_part_swallow_hints_update(Edje_Real_Part *rp)
|
|
{
|
|
if ((rp->type != EDJE_RP_TYPE_SWALLOW) ||
|
|
(!rp->typedata.swallow)) return;
|
|
|
|
rp->typedata.swallow->swallow_params.min.w = 0;
|
|
rp->typedata.swallow->swallow_params.min.h = 0;
|
|
rp->typedata.swallow->swallow_params.max.w = -1;
|
|
rp->typedata.swallow->swallow_params.max.h = -1;
|
|
if (efl_isa(rp->typedata.swallow->swallowed_object, EFL_CANVAS_LAYOUT_CLASS))
|
|
{
|
|
Evas_Coord w = 0, h = 0;
|
|
|
|
#if 0
|
|
edje_object_size_min_get(rp->typedata.swallow->swallowed_object, &w, &h);
|
|
rp->typedata.swallow->swallow_params.min.w = w;
|
|
rp->typedata.swallow->swallow_params.min.h = h;
|
|
#endif
|
|
edje_object_size_max_get(rp->typedata.swallow->swallowed_object, &w, &h);
|
|
rp->typedata.swallow->swallow_params.max.w = w;
|
|
rp->typedata.swallow->swallow_params.max.h = h;
|
|
}
|
|
else if (efl_isa(rp->typedata.swallow->swallowed_object, EVAS_TEXT_CLASS) ||
|
|
efl_isa(rp->typedata.swallow->swallowed_object, EFL_CANVAS_POLYGON_CLASS) ||
|
|
efl_isa(rp->typedata.swallow->swallowed_object, EVAS_LINE_CLASS))
|
|
{
|
|
Evas_Coord w = 0, h = 0;
|
|
|
|
evas_object_geometry_get(rp->typedata.swallow->swallowed_object, NULL, NULL, &w, &h);
|
|
#if 0
|
|
rp->typedata.swallow->swallow_params.min.w = w;
|
|
rp->typedata.swallow->swallow_params.min.h = h;
|
|
#endif
|
|
rp->typedata.swallow->swallow_params.max.w = w;
|
|
rp->typedata.swallow->swallow_params.max.h = h;
|
|
}
|
|
{
|
|
Evas_Coord w1 = 0, h1 = 0, w2 = 0, h2 = 0, aw = 0, ah = 0;
|
|
Evas_Aspect_Control am = EVAS_ASPECT_CONTROL_NONE;
|
|
|
|
evas_object_size_hint_combined_min_get(rp->typedata.swallow->swallowed_object, &w1, &h1);
|
|
evas_object_size_hint_combined_max_get(rp->typedata.swallow->swallowed_object, &w2, &h2);
|
|
evas_object_size_hint_aspect_get(rp->typedata.swallow->swallowed_object, &am, &aw, &ah);
|
|
rp->typedata.swallow->swallow_params.min.w = w1;
|
|
rp->typedata.swallow->swallow_params.min.h = h1;
|
|
if (w2 > 0) rp->typedata.swallow->swallow_params.max.w = w2;
|
|
if (h2 > 0) rp->typedata.swallow->swallow_params.max.h = h2;
|
|
switch (am)
|
|
{
|
|
case EVAS_ASPECT_CONTROL_NONE:
|
|
rp->typedata.swallow->swallow_params.aspect.mode = EDJE_ASPECT_CONTROL_NONE;
|
|
break;
|
|
|
|
case EVAS_ASPECT_CONTROL_NEITHER:
|
|
rp->typedata.swallow->swallow_params.aspect.mode = EDJE_ASPECT_CONTROL_NEITHER;
|
|
break;
|
|
|
|
case EVAS_ASPECT_CONTROL_HORIZONTAL:
|
|
rp->typedata.swallow->swallow_params.aspect.mode = EDJE_ASPECT_CONTROL_HORIZONTAL;
|
|
break;
|
|
|
|
case EVAS_ASPECT_CONTROL_VERTICAL:
|
|
rp->typedata.swallow->swallow_params.aspect.mode = EDJE_ASPECT_CONTROL_VERTICAL;
|
|
break;
|
|
|
|
case EVAS_ASPECT_CONTROL_BOTH:
|
|
rp->typedata.swallow->swallow_params.aspect.mode = EDJE_ASPECT_CONTROL_BOTH;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
rp->typedata.swallow->swallow_params.aspect.w = aw;
|
|
rp->typedata.swallow->swallow_params.aspect.h = ah;
|
|
evas_object_data_set(rp->typedata.swallow->swallowed_object, "\377 edje.swallowing_part", rp);
|
|
}
|
|
|
|
#ifdef EDJE_CALC_CACHE
|
|
rp->invalidate = EINA_TRUE;
|
|
#endif
|
|
}
|
|
|
|
void
|
|
_edje_object_part_swallow_changed_hints_cb(void *data, EINA_UNUSED Evas *e, Evas_Object *obj, EINA_UNUSED void *event_info)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
rp = data;
|
|
ed = evas_object_data_get(obj, ".edje");
|
|
if (!ed) return;
|
|
_edje_real_part_swallow_hints_update(rp);
|
|
ed->dirty = EINA_TRUE;
|
|
ed->recalc_call = EINA_TRUE;
|
|
ed->recalc_hints = EINA_TRUE;
|
|
|
|
_edje_recalc(ed);
|
|
return;
|
|
}
|
|
|
|
void
|
|
_edje_object_part_swallow_image_resize_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
Edje_Real_Part *rp = data;
|
|
Evas_Coord w, h;
|
|
Evas_Map *map;
|
|
|
|
if (!rp->chosen_description->map.on) return;
|
|
if (rp->type != EDJE_RP_TYPE_SWALLOW) return;
|
|
if (!rp->typedata.swallow) return;
|
|
if (evas_object_image_source_get(rp->typedata.swallow->swallowed_object))
|
|
return;
|
|
|
|
map = (Evas_Map *)evas_object_map_get(rp->typedata.swallow->swallowed_object);
|
|
if (!map) return;
|
|
|
|
evas_object_image_size_get(rp->typedata.swallow->swallowed_object, &w, &h);
|
|
evas_map_point_image_uv_set(map, 0, 0, 0);
|
|
evas_map_point_image_uv_set(map, 1, w, 0);
|
|
evas_map_point_image_uv_set(map, 2, w, h);
|
|
evas_map_point_image_uv_set(map, 3, 0, h);
|
|
|
|
evas_object_map_set(rp->typedata.swallow->swallowed_object, map);
|
|
}
|
|
|
|
void
|
|
_edje_real_part_swallow(Edje *ed,
|
|
Edje_Real_Part *rp,
|
|
Evas_Object *obj_swallow,
|
|
Eina_Bool hints_update)
|
|
{
|
|
if ((rp->type != EDJE_RP_TYPE_SWALLOW) ||
|
|
(!rp->typedata.swallow)) return;
|
|
if (rp->typedata.swallow->swallowed_object)
|
|
{
|
|
if (rp->typedata.swallow->swallowed_object != obj_swallow)
|
|
{
|
|
edje_object_part_unswallow(ed->obj, rp->typedata.swallow->swallowed_object);
|
|
}
|
|
else
|
|
{
|
|
if (hints_update)
|
|
_edje_real_part_swallow_hints_update(rp);
|
|
ed->dirty = EINA_TRUE;
|
|
ed->recalc_call = EINA_TRUE;
|
|
ed->recalc_hints = EINA_TRUE;
|
|
_edje_recalc(ed);
|
|
return;
|
|
}
|
|
}
|
|
#ifdef EDJE_CALC_CACHE
|
|
rp->invalidate = EINA_TRUE;
|
|
#endif
|
|
if (!obj_swallow) return;
|
|
rp->typedata.swallow->swallowed_object = obj_swallow;
|
|
efl_parent_set(obj_swallow, ed->obj);
|
|
evas_object_smart_member_add(rp->typedata.swallow->swallowed_object, ed->obj);
|
|
if (rp->part->clip_to_id >= 0)
|
|
{
|
|
Edje_Real_Part *clip_to;
|
|
|
|
clip_to = ed->table_parts[rp->part->clip_to_id % ed->table_parts_size];
|
|
evas_object_clip_set(rp->typedata.swallow->swallowed_object, clip_to->object);
|
|
}
|
|
else evas_object_clip_set(rp->typedata.swallow->swallowed_object, ed->base.clipper);
|
|
//FIXME: I'm not sure why Edje Nested is a parent of the rp->object here. Is it normal case?
|
|
if (evas_object_smart_parent_get(rp->object) == ed->obj)
|
|
evas_object_stack_above(rp->typedata.swallow->swallowed_object, rp->object);
|
|
evas_object_event_callback_add(rp->typedata.swallow->swallowed_object,
|
|
EVAS_CALLBACK_DEL,
|
|
_edje_object_part_swallow_free_cb,
|
|
rp);
|
|
evas_object_event_callback_add(rp->typedata.swallow->swallowed_object,
|
|
EVAS_CALLBACK_CHANGED_SIZE_HINTS,
|
|
_edje_object_part_swallow_changed_hints_cb,
|
|
rp);
|
|
evas_object_data_set(rp->typedata.swallow->swallowed_object, ".edje", ed);
|
|
|
|
//If the map is enabled, uv should be updated when image size is changed.
|
|
if (efl_isa(rp->typedata.swallow->swallowed_object, EFL_CANVAS_IMAGE_INTERNAL_CLASS))
|
|
evas_object_event_callback_add(obj_swallow, EVAS_CALLBACK_IMAGE_RESIZE,
|
|
_edje_object_part_swallow_image_resize_cb,
|
|
rp);
|
|
|
|
if (hints_update)
|
|
_edje_real_part_swallow_hints_update(rp);
|
|
|
|
if (rp->mouse_events)
|
|
{
|
|
_edje_callbacks_add(obj_swallow, ed, rp);
|
|
evas_object_repeat_events_set(obj_swallow, rp->repeat_events);
|
|
if (rp->part->pointer_mode != EVAS_OBJECT_POINTER_MODE_AUTOGRAB)
|
|
evas_object_pointer_mode_set(obj_swallow, rp->part->pointer_mode);
|
|
evas_object_pass_events_set(obj_swallow, 0);
|
|
}
|
|
else
|
|
evas_object_pass_events_set(obj_swallow, 1);
|
|
_edje_callbacks_focus_add(rp->typedata.swallow->swallowed_object, ed, rp);
|
|
efl_canvas_object_anti_alias_set(obj_swallow, rp->part->anti_alias);
|
|
efl_canvas_object_precise_is_inside_set(obj_swallow, rp->part->precise_is_inside);
|
|
|
|
ed->dirty = EINA_TRUE;
|
|
ed->recalc_call = EINA_TRUE;
|
|
ed->recalc_hints = EINA_TRUE;
|
|
_edje_recalc(ed);
|
|
}
|
|
|
|
void
|
|
_edje_real_part_swallow_clear(Edje *ed, Edje_Real_Part *rp)
|
|
{
|
|
if ((rp->type != EDJE_RP_TYPE_SWALLOW) ||
|
|
(!rp->typedata.swallow)) return;
|
|
if (!rp->typedata.swallow->swallowed_object) return;
|
|
if (rp->chosen_description->map.on ||
|
|
(rp->invalidate && rp->prev_description && rp->prev_description->map.on))
|
|
{
|
|
evas_object_map_enable_set(rp->typedata.swallow->swallowed_object, EINA_FALSE);
|
|
}
|
|
_eo_unparent_helper(rp->typedata.swallow->swallowed_object, ed->obj);
|
|
evas_object_smart_member_del(rp->typedata.swallow->swallowed_object);
|
|
evas_object_event_callback_del_full(rp->typedata.swallow->swallowed_object,
|
|
EVAS_CALLBACK_DEL,
|
|
_edje_object_part_swallow_free_cb,
|
|
rp);
|
|
evas_object_event_callback_del_full(rp->typedata.swallow->swallowed_object,
|
|
EVAS_CALLBACK_CHANGED_SIZE_HINTS,
|
|
_edje_object_part_swallow_changed_hints_cb,
|
|
rp);
|
|
if (efl_isa(rp->typedata.swallow->swallowed_object, EFL_CANVAS_IMAGE_INTERNAL_CLASS))
|
|
evas_object_event_callback_del_full(rp->typedata.swallow->swallowed_object,
|
|
EVAS_CALLBACK_IMAGE_RESIZE,
|
|
_edje_object_part_swallow_image_resize_cb,
|
|
rp);
|
|
evas_object_clip_unset(rp->typedata.swallow->swallowed_object);
|
|
evas_object_data_del(rp->typedata.swallow->swallowed_object, "\377 edje.swallowing_part");
|
|
_edje_callbacks_del(rp->typedata.swallow->swallowed_object, ed);
|
|
_edje_callbacks_focus_del(rp->typedata.swallow->swallowed_object, ed);
|
|
rp->typedata.swallow->swallowed_object = NULL;
|
|
}
|
|
|
|
static void
|
|
_edje_object_preload_helper(Edje *ed)
|
|
{
|
|
ed->preload_count--;
|
|
if (!ed->preload_count)
|
|
_edje_emit(ed, EDJE_PRELOAD_EMISSION, EDJE_PRELOAD_SOURCE);
|
|
}
|
|
|
|
static void
|
|
_edje_object_image_preload_cb(void *data, EINA_UNUSED Evas *e, Evas_Object *obj, EINA_UNUSED void *event_info)
|
|
{
|
|
Edje *ed = data;
|
|
|
|
evas_object_event_callback_del_full(obj, EVAS_CALLBACK_IMAGE_PRELOADED, _edje_object_image_preload_cb, ed);
|
|
_edje_object_preload_helper(ed);
|
|
}
|
|
|
|
static void
|
|
_edje_object_signal_preload_cb(void *data, Evas_Object *obj, EINA_UNUSED const char *emission, EINA_UNUSED const char *source)
|
|
{
|
|
Edje *ed = data;
|
|
|
|
edje_object_signal_callback_del(obj, EDJE_PRELOAD_EMISSION, EDJE_PRELOAD_SOURCE, _edje_object_signal_preload_cb);
|
|
_edje_object_preload_helper(ed);
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* for edje_cc
|
|
*/
|
|
EAPI void
|
|
_edje_program_remove(Edje_Part_Collection *edc, Edje_Program *p)
|
|
{
|
|
Edje_Program ***array;
|
|
unsigned int *count;
|
|
unsigned int i;
|
|
|
|
if (!p->signal && !p->source)
|
|
{
|
|
array = &edc->programs.nocmp;
|
|
count = &edc->programs.nocmp_count;
|
|
}
|
|
else if (p->signal && !strpbrk(p->signal, "*?[\\")
|
|
&& p->source && !strpbrk(p->source, "*?[\\"))
|
|
{
|
|
array = &edc->programs.strcmp;
|
|
count = &edc->programs.strcmp_count;
|
|
}
|
|
else if (p->signal && edje_program_is_strncmp(p->signal)
|
|
&& p->source && edje_program_is_strncmp(p->source))
|
|
{
|
|
array = &edc->programs.strncmp;
|
|
count = &edc->programs.strncmp_count;
|
|
}
|
|
else if (p->signal && edje_program_is_strrncmp(p->signal)
|
|
&& p->source && edje_program_is_strrncmp(p->source))
|
|
{
|
|
array = &edc->programs.strrncmp;
|
|
count = &edc->programs.strrncmp_count;
|
|
}
|
|
else
|
|
{
|
|
array = &edc->programs.fnmatch;
|
|
count = &edc->programs.fnmatch_count;
|
|
}
|
|
|
|
for (i = 0; i < *count; ++i)
|
|
if ((*array)[i] == p)
|
|
{
|
|
memmove(*array + i, *array + i + 1, sizeof (Edje_Program *) * (*count - i - 1));
|
|
(*count)--;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* for edje_cc
|
|
*/
|
|
EAPI void
|
|
_edje_program_insert(Edje_Part_Collection *edc, Edje_Program *p)
|
|
{
|
|
Edje_Program ***array, **temp;
|
|
unsigned int *count;
|
|
|
|
if (!p->signal && !p->source)
|
|
{
|
|
array = &edc->programs.nocmp;
|
|
count = &edc->programs.nocmp_count;
|
|
}
|
|
else if (p->signal && !strpbrk(p->signal, "*?[\\")
|
|
&& p->source && !strpbrk(p->source, "*?[\\"))
|
|
{
|
|
array = &edc->programs.strcmp;
|
|
count = &edc->programs.strcmp_count;
|
|
}
|
|
else if (p->signal && edje_program_is_strncmp(p->signal)
|
|
&& p->source && edje_program_is_strncmp(p->source))
|
|
{
|
|
array = &edc->programs.strncmp;
|
|
count = &edc->programs.strncmp_count;
|
|
}
|
|
else if (p->signal && edje_program_is_strrncmp(p->signal)
|
|
&& p->source && edje_program_is_strrncmp(p->source))
|
|
{
|
|
array = &edc->programs.strrncmp;
|
|
count = &edc->programs.strrncmp_count;
|
|
}
|
|
else
|
|
{
|
|
array = &edc->programs.fnmatch;
|
|
count = &edc->programs.fnmatch_count;
|
|
}
|
|
|
|
temp = *array;
|
|
*array = realloc(*array, sizeof (Edje_Program *) * (*count + 1));
|
|
if (*array)
|
|
{
|
|
(*array)[(*count)++] = p;
|
|
}
|
|
else
|
|
{
|
|
*array = temp;
|
|
}
|
|
}
|
|
|
|
const char *
|
|
edje_string_get(const Edje_String *es)
|
|
{
|
|
/* FIXME: Handle localization here */
|
|
if (!es) return NULL;
|
|
return es->str;
|
|
}
|
|
|
|
const char *
|
|
edje_string_id_get(const Edje_String *es)
|
|
{
|
|
/* FIXME: Handle localization here */
|
|
if (!es) return NULL;
|
|
return es->str;
|
|
}
|
|
|
|
static void
|
|
_cb_subobj_del(void *data, EINA_UNUSED Evas *e, Evas_Object *obj, EINA_UNUSED void *event_info)
|
|
{
|
|
Edje *ed = data;
|
|
_edje_subobj_unregister(ed, obj);
|
|
}
|
|
|
|
void
|
|
_edje_subobj_register(Edje *ed, Evas_Object *ob)
|
|
{
|
|
ed->subobjs = eina_list_append(ed->subobjs, ob);
|
|
evas_object_event_callback_add(ob, EVAS_CALLBACK_DEL,
|
|
_cb_subobj_del, ed);
|
|
}
|
|
|
|
void
|
|
_edje_subobj_unregister(Edje *ed, Evas_Object *obj)
|
|
{
|
|
ed->subobjs = eina_list_remove(ed->subobjs, obj);
|
|
evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL,
|
|
_cb_subobj_del, ed);
|
|
}
|
|
|
|
EAPI const char *
|
|
edje_object_part_object_name_get(const Evas_Object *obj)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
rp = evas_object_data_get(obj, "real_part");
|
|
return rp ? rp->part->name : NULL;
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_real_part_mouse_events_get(Edje *ed EINA_UNUSED, Edje_Real_Part *rp)
|
|
{
|
|
if (!rp) return EINA_FALSE;
|
|
|
|
return rp->mouse_events;
|
|
}
|
|
|
|
void
|
|
_edje_real_part_mouse_events_set(Edje *ed EINA_UNUSED, Edje_Real_Part *rp, Eina_Bool mouse_events)
|
|
{
|
|
if (!rp) return;
|
|
|
|
rp->mouse_events = !!mouse_events;
|
|
|
|
if (rp->mouse_events)
|
|
{
|
|
evas_object_pass_events_set(rp->object, 0);
|
|
_edje_callbacks_add(rp->object, ed, rp);
|
|
}
|
|
else
|
|
{
|
|
evas_object_pass_events_set(rp->object, 1);
|
|
_edje_callbacks_del(rp->object, ed);
|
|
}
|
|
}
|
|
|
|
Eina_Bool
|
|
_edje_real_part_repeat_events_get(Edje *ed EINA_UNUSED, Edje_Real_Part *rp)
|
|
{
|
|
if (!rp) return EINA_FALSE;
|
|
|
|
return rp->repeat_events;
|
|
}
|
|
|
|
void
|
|
_edje_real_part_repeat_events_set(Edje *ed EINA_UNUSED, Edje_Real_Part *rp, Eina_Bool repeat_events)
|
|
{
|
|
if (!rp) return;
|
|
|
|
rp->repeat_events = !!repeat_events;
|
|
|
|
if (rp->repeat_events)
|
|
evas_object_repeat_events_set(rp->object, 1);
|
|
else
|
|
evas_object_repeat_events_set(rp->object, 0);
|
|
}
|
|
|
|
void
|
|
_edje_real_part_pointer_mode_set(Edje *ed EINA_UNUSED, Edje_Real_Part *rp, Evas_Object_Pointer_Mode mode)
|
|
{
|
|
if (!rp) return;
|
|
|
|
rp->pointer_mode = mode;
|
|
|
|
evas_object_pointer_mode_set(rp->object, mode);
|
|
}
|
|
|
|
Evas_Event_Flags
|
|
_edje_real_part_ignore_flags_get(Edje *ed EINA_UNUSED, Edje_Real_Part *rp)
|
|
{
|
|
if (!rp) return EVAS_EVENT_FLAG_NONE;
|
|
|
|
return rp->ignore_flags;
|
|
}
|
|
|
|
void
|
|
_edje_real_part_ignore_flags_set(Edje *ed EINA_UNUSED, Edje_Real_Part *rp, Evas_Event_Flags ignore_flags)
|
|
{
|
|
if (!rp) return;
|
|
|
|
rp->ignore_flags = ignore_flags;
|
|
}
|
|
|
|
Evas_Event_Flags
|
|
_edje_real_part_mask_flags_get(Edje *ed EINA_UNUSED, Edje_Real_Part *rp)
|
|
{
|
|
if (!rp) return EVAS_EVENT_FLAG_NONE;
|
|
|
|
return rp->mask_flags;
|
|
}
|
|
|
|
void
|
|
_edje_real_part_mask_flags_set(Edje *ed EINA_UNUSED, Edje_Real_Part *rp, Evas_Event_Flags mask_flags)
|
|
{
|
|
if (!rp) return;
|
|
|
|
rp->mask_flags = mask_flags;
|
|
}
|
|
|
|
/* Legacy APIs */
|
|
|
|
static inline Eina_Bool
|
|
_edje_part_fetch(const Edje_Object *obj, const char *part, Edje **ped, Edje_Real_Part **prp)
|
|
{
|
|
if (!part) return EINA_FALSE;
|
|
|
|
*ped = _edje_fetch(obj);
|
|
if (!*ped) return EINA_FALSE;
|
|
|
|
*prp = _edje_real_part_recursive_get(ped, part);
|
|
if (!*prp) return EINA_FALSE;
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_object_part_swallow(Edje_Object *obj, const char *part, Evas_Object *obj_swallow)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
if (!_edje_part_fetch(obj, part, &ed, &rp)) return EINA_FALSE;
|
|
|
|
if (rp->part->type != EDJE_PART_TYPE_SWALLOW)
|
|
{
|
|
ERR("Invalid call on a non-swallow part: '%s' in group '%s'", part, ed->group);
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
return efl_content_set(efl_part(obj, part), obj_swallow);
|
|
}
|
|
|
|
EAPI void
|
|
edje_object_part_unswallow(Edje_Object *obj, Evas_Object *obj_swallow)
|
|
{
|
|
efl_canvas_layout_content_remove(obj, obj_swallow);
|
|
}
|
|
|
|
EAPI Evas_Object *
|
|
edje_object_part_swallow_get(const Edje_Object *obj, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
if (!_edje_part_fetch(obj, part, &ed, &rp)) return NULL;
|
|
|
|
if (rp->part->type != EDJE_PART_TYPE_SWALLOW)
|
|
{
|
|
// Legacy compatibility: return swallowed_object on non-swallow parts
|
|
if ((rp->type == EDJE_RP_TYPE_SWALLOW) && rp->typedata.swallow)
|
|
{
|
|
INF("Part is not a swallow: '%s' in group '%s'", part, ed->group);
|
|
return rp->typedata.swallow->swallowed_object;
|
|
}
|
|
|
|
ERR("Invalid call on a non-swallow part: '%s' in group '%s'", part, ed->group);
|
|
return NULL;
|
|
}
|
|
|
|
return efl_content_get(efl_part(obj, part));
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
edje_object_part_text_set(const Edje_Object *obj, const char *part, const char *text)
|
|
{
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
|
|
return _edje_efl_text_text_set((Eo *) obj, ed, part, text, EINA_TRUE, EINA_FALSE);
|
|
}
|
|
|
|
EAPI const char *
|
|
edje_object_part_text_get(const Edje_Object *obj, const char *part)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Edje *ed;
|
|
|
|
if (!_edje_part_fetch(obj, part, &ed, &rp)) return NULL;
|
|
|
|
if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
|
|
(rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
|
|
{
|
|
ERR("Invalid call on a non-text or non-textblock part: '%s' in group '%s'", part, ed->group);
|
|
return NULL;
|
|
}
|
|
|
|
ed = _edje_fetch(obj);
|
|
if (!ed)
|
|
{
|
|
ERR("Failed to get Edje data from object: '%p'", obj);
|
|
return NULL;
|
|
}
|
|
|
|
return _edje_efl_text_text_get(obj, ed, part, EINA_TRUE, EINA_FALSE);
|
|
}
|
|
|
|
/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
|