This is controlled by the two added API functions.
The changes in Elementary that utilize these functions will be committed soon.
SVN revision: 56635
Tiago Falcão <tiago@profusion.mobi>
Davide Andreoli <dave@gurumeditation.it>
Sebastian Dransfeld <sd@tango.flipp.net>
+Tom Hacohen <tom@stosb.com>
+Aharon Hillel <a.hillel@partner.samsung.com>
static void st_collections_group_min(void);
static void st_collections_group_max(void);
static void st_collections_group_data_item(void);
+static void st_collections_group_orientation(void);
static void ob_collections_group_script(void);
static void ob_collections_group_lua_script(void);
{"collections.group.alias", st_collections_group_alias},
{"collections.group.min", st_collections_group_min},
{"collections.group.max", st_collections_group_max},
+ {"collections.group.orientation", st_collections_group_orientation},
{"collections.group.data.item", st_collections_group_data_item},
{"collections.group.externals.external", st_externals_external}, /* dup */
{"collections.group.image", st_images_image}, /* dup */
/**
@page edcref
+ @property
+ orientation
+ @parameters
+ enum AUTO, LTR, RTL
+ @effect
+ This defines GROUP orientation.
+ This is useful if you want match interface orientation with language.
+ AUTO - Follow system defs.
+ LTR - suitable for Left To Right Languages (latin)
+ RTL - suitable for Right To Left Languages (Hebrew, Arabic interface)
+ @endproperty
+*/
+static void
+st_collections_group_orientation(void)
+{
+ Edje_Part_Collection *pc;
+
+ check_arg_count(1);
+
+ pc = eina_list_data_get(eina_list_last(edje_collections));
+ pc->prop.orientation = parse_enum(0,
+ "AUTO", EDJE_ORIENTATION_AUTO,
+ "LTR", EDJE_ORIENTATION_LTR,
+ "RTL", EDJE_ORIENTATION_RTL,
+ NULL);
+}
+
+/**
+ @page edcref
@block
parts
@context
EAPI double edje_scale_get (void);
EAPI Eina_Bool edje_object_scale_set (Evas_Object *obj, double scale);
EAPI double edje_object_scale_get (const Evas_Object *obj);
+ EAPI void edje_object_mirrored_set (Evas_Object *obj, Eina_Bool rtl);
+ EAPI Eina_Bool edje_object_mirrored_get (const Evas_Object *obj);
/* edje_load.c */
EAPI Eina_List *edje_file_collection_list (const char *file);
id = ce->id;
if (id < 0) return NULL;
-#define INIT_EMP(Tp, Sz, Ce) \
- buffer = alloca(strlen(ce->entry) + strlen(#Tp) + 2); \
- sprintf(buffer, "%s/%s", ce->entry, #Tp); \
+#define INIT_EMP(Tp, Sz, Ce) \
+ buffer = alloca(strlen(ce->entry) + strlen(#Tp) + 2); \
+ sprintf(buffer, "%s/%s", ce->entry, #Tp); \
Ce->mp.Tp = eina_mempool_add("one_big", buffer, NULL, sizeof (Sz), Ce->count.Tp); \
_emp_##Tp = Ce->mp.Tp;
- INIT_EMP(RECTANGLE, Edje_Part_Description_Common, ce);
- INIT_EMP(TEXT, Edje_Part_Description_Text, ce);
- INIT_EMP(IMAGE, Edje_Part_Description_Image, ce);
- INIT_EMP(SWALLOW, Edje_Part_Description_Common, ce);
- INIT_EMP(TEXTBLOCK, Edje_Part_Description_Text, ce);
- INIT_EMP(GROUP, Edje_Part_Description_Common, ce);
- INIT_EMP(BOX, Edje_Part_Description_Box, ce);
- INIT_EMP(TABLE, Edje_Part_Description_Table, ce);
- INIT_EMP(EXTERNAL, Edje_Part_Description_External, ce);
+#define INIT_EMP_BOTH(Tp, Sz, Ce) \
+ INIT_EMP(Tp, Sz, Ce) \
+ Ce->mp_rtl.Tp = eina_mempool_add("one_big", buffer, NULL, \
+ sizeof (Sz), Ce->count.Tp);
+
+ INIT_EMP_BOTH(RECTANGLE, Edje_Part_Description_Common, ce);
+ INIT_EMP_BOTH(TEXT, Edje_Part_Description_Text, ce);
+ INIT_EMP_BOTH(IMAGE, Edje_Part_Description_Image, ce);
+ INIT_EMP_BOTH(SWALLOW, Edje_Part_Description_Common, ce);
+ INIT_EMP_BOTH(TEXTBLOCK, Edje_Part_Description_Text, ce);
+ INIT_EMP_BOTH(GROUP, Edje_Part_Description_Common, ce);
+ INIT_EMP_BOTH(BOX, Edje_Part_Description_Box, ce);
+ INIT_EMP_BOTH(TABLE, Edje_Part_Description_Table, ce);
+ INIT_EMP_BOTH(EXTERNAL, Edje_Part_Description_External, ce);
INIT_EMP(part, Edje_Part, ce);
snprintf(buf, sizeof(buf), "edje/collections/%i", id);
#define FLAG_Y 0x02
#define FLAG_XY (FLAG_X | FLAG_Y)
+static void _edje_part_make_rtl(Edje_Part_Description_Common *desc);
+static Edje_Part_Description_Common *_edje_get_description_by_orientation(Edje *ed, Edje_Part_Description_Common *src, Edje_Part_Description_Common **dst, unsigned char type);
+
static void _edje_part_recalc_single(Edje *ed, Edje_Real_Part *ep,
Edje_Part_Description_Common *desc, Edje_Part_Description_Common *chosen_desc,
Edje_Real_Part *rel1_to_x, Edje_Real_Part *rel1_to_y,
#endif
}
+
+/**
+ * Returns part description
+ *
+ * @internal
+ *
+ * Converts part description to RTL-desc.
+ *
+ * @param desc Pointer to desc buffer.
+ *
+ **/
+static void
+_edje_part_make_rtl(Edje_Part_Description_Common *desc)
+{
+ double t;
+ int i;
+
+ if(!desc)
+ return;
+
+ /* This makes alignment right-oriented */
+ desc->align.x = 1.0 - desc->align.x;
+
+ /* same as above for relative components */
+ t = desc->rel1.relative_x;
+ desc->rel1.relative_x = 1.0 - desc->rel2.relative_x;
+ desc->rel2.relative_x = 1.0 - t;
+
+ /* +1 and +1 are because how edje works with right
+ * side borders - nothing is printed beyond that limit
+ *
+ * rel2 is now to the left of rel1, and Edje assumes
+ * the opposite so we switch corners on x-axis to define
+ * offset from right to left */
+ i = desc->rel1.offset_x;
+ desc->rel1.offset_x = -(desc->rel2.offset_x + 1);
+ desc->rel2.offset_x = -(i + 1);
+
+ i = desc->rel1.id_x;
+ desc->rel1.id_x = desc->rel2.id_x;
+ desc->rel2.id_x = i;
+}
+
+/**
+ * Returns part description
+ *
+ * @internal
+ *
+ * Returns part description according to object orientation.
+ * When object is in RTL-orientation (RTL flag is set)
+ * this returns the RTL-desc of it.
+ * RTL-desc would be allocated if was not created by a previous call.
+ * The dst pointer is updated in case of an allocation.
+ *
+ * @param ed Edje object.
+ * @param src The Left To Right (LTR), original desc.
+ * @param dst Pointer to Right To Left (RTL) desc-list.
+ * @param type name of dec type. Example: "default".
+ *
+ * @return Edje part description.
+ *
+ **/
+static Edje_Part_Description_Common *
+_edje_get_description_by_orientation(Edje *ed, Edje_Part_Description_Common *src, Edje_Part_Description_Common **dst, unsigned char type)
+{
+ Edje_Part_Description_Common *desc_rtl = NULL;
+ Edje_Part_Collection_Directory_Entry *ce;
+ size_t memsize = 0;
+
+ /* RTL flag is not set, return original description */
+ if(!edje_object_mirrored_get(ed->obj))
+ return src;
+
+ if(*dst)
+ return *dst; /* Was allocated before and we should use it */
+
+#define EDIT_ALLOC_POOL_RTL(Short, Type, Name) \
+ case EDJE_PART_TYPE_##Short: \
+ { \
+ Edje_Part_Description_##Type *Name; \
+ Name = eina_mempool_malloc(ce->mp_rtl.Short, \
+ sizeof (Edje_Part_Description_##Type)); \
+ memset(Name, 0, sizeof(Edje_Part_Description_##Type)); \
+ desc_rtl = &Name->common; \
+ memsize = sizeof(Edje_Part_Description_##Type); \
+ break; \
+ }
+
+ ce = eina_hash_find(ed->file->collection, ed->group);
+
+ switch (type)
+ {
+ case EDJE_PART_TYPE_RECTANGLE:
+ desc_rtl = eina_mempool_malloc(ce->mp_rtl.RECTANGLE,
+ sizeof (Edje_Part_Description_Common));
+ ce->count.RECTANGLE++;
+ memsize = sizeof(Edje_Part_Description_Common);
+ break;
+ case EDJE_PART_TYPE_SWALLOW:
+ desc_rtl = eina_mempool_malloc(ce->mp_rtl.SWALLOW,
+ sizeof (Edje_Part_Description_Common));
+ ce->count.SWALLOW++;
+ memsize = sizeof(Edje_Part_Description_Common);
+ break;
+ case EDJE_PART_TYPE_GROUP:
+ desc_rtl = eina_mempool_malloc(ce->mp_rtl.GROUP,
+ sizeof (Edje_Part_Description_Common));
+ ce->count.GROUP++;
+ memsize = sizeof(Edje_Part_Description_Common);
+ break;
+ EDIT_ALLOC_POOL_RTL(TEXT, Text, text);
+ EDIT_ALLOC_POOL_RTL(TEXTBLOCK, Text, text);
+ EDIT_ALLOC_POOL_RTL(IMAGE, Image, image);
+ EDIT_ALLOC_POOL_RTL(BOX, Box, box);
+ EDIT_ALLOC_POOL_RTL(TABLE, Table, table);
+ EDIT_ALLOC_POOL_RTL(EXTERNAL, External, external_params);
+ }
+
+ if(desc_rtl)
+ memcpy(desc_rtl, src, memsize);
+
+ _edje_part_make_rtl(desc_rtl);
+
+ *dst = desc_rtl;
+ return desc_rtl;
+}
+
Edje_Part_Description_Common *
-_edje_part_description_find(Edje *ed __UNUSED__, Edje_Real_Part *rp, const char *name,
+_edje_part_description_find(Edje *ed, Edje_Real_Part *rp, const char *name,
double val)
{
Edje_Part *ep = rp->part;
Edje_Part_Description_Common *ret = NULL;
Edje_Part_Description_Common *d;
+
double min_dst = 99999.0;
unsigned int i;
+ /* RTL flag is set, return RTL description */
+ if(edje_object_mirrored_get(ed->obj))
+ if(!ep->other.desc_rtl)
+ ep->other.desc_rtl = (Edje_Part_Description_Common **)
+ calloc(ep->other.desc_count,
+ sizeof (Edje_Part_Description_Common *));
+
if (!strcmp(name, "default") && val == 0.0)
- return ep->default_desc;
+ return _edje_get_description_by_orientation(ed,
+ ep->default_desc, &ep->default_desc_rtl, ep->type);
if (!strcmp(name, "custom"))
- return rp->custom ? rp->custom->description : NULL;
+ return rp->custom ?
+ _edje_get_description_by_orientation(ed, rp->custom->description,
+ &rp->custom->description_rtl, ep->type) : NULL;
if (!strcmp(name, "default"))
{
- ret = ep->default_desc;
+ ret = _edje_get_description_by_orientation(ed, ep->default_desc,
+ &ep->default_desc_rtl, ep->type);
+
min_dst = ABS(ep->default_desc->state.value - val);
}
+
for (i = 0; i < ep->other.desc_count; ++i)
{
d = ep->other.desc[i];
-
+
if (d->state.name && !strcmp(d->state.name, name))
{
double dst;
dst = ABS(d->state.value - val);
if (dst < min_dst)
{
- ret = d;
+ ret = _edje_get_description_by_orientation(ed, d,
+ &ep->other.desc_rtl[i], ep->type);
min_dst = dst;
}
}
ep = ed->table_parts[i];
if (ep->calculated != FLAG_XY)
- _edje_part_recalc(ed, ep, (~ep->calculated) & FLAG_XY);
+ _edje_part_recalc(ed, ep, (~ep->calculated) & FLAG_XY);
}
if (!ed->calc_only) ed->recalc = 0;
#ifdef EDJE_CALC_CACHE
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection, Edje_Part_Collection, "part", part, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection, Edje_Part_Collection, "script_only", script_only, EET_T_UCHAR);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection, Edje_Part_Collection, "lua_script_only", lua_script_only, EET_T_UCHAR);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection, Edje_Part_Collection, "prop.orientation", prop.orientation, EET_T_INT);
}
EAPI Eina_Bool
edje_object_file_set(Evas_Object *obj, const char *file, const char *group)
{
+ Eina_Bool ret;
Edje *ed;
ed = _edje_fetch(obj);
if (!ed)
return EINA_FALSE;
- return ed->api->file_set(obj, file, group);
+ ret = ed->api->file_set(obj, file, group);
+ _edje_object_orientation_inform(obj);
+ return ret;
}
/* FIXDOC: Verify/expand doc. */
if (ed->collection)
{
+ if (ed->collection->prop.orientation != EDJE_ORIENTATION_AUTO)
+ ed->is_rtl = (ed->collection->prop.orientation ==
+ EDJE_ORIENTATION_RTL);
+
if (ed->collection->script_only)
{
ed->load_error = EDJE_LOAD_ERROR_NONE;
_edje_ref(rp->edje);
rp->part = ep;
parts = eina_list_append(parts, rp);
- rp->param1.description = ep->default_desc;
+ rp->param1.description = _edje_part_description_find(ed,
+ rp, "default", 0.0);
rp->chosen_description = rp->param1.description;
if (!rp->param1.description)
ERR("no default part description!");
_edje_collection_free_part_description_clean(ep->type, ep->other.desc[j], edf->free_strings);
free(ep->other.desc);
+ /* Alloc for RTL objects in edje_calc.c:_edje_part_description_find() */
+ if(ep->other.desc_rtl)
+ free(ep->other.desc_rtl);
+
free(ep->items);
// technically need this - but we ASSUME we use "one_big" so everything gets
// freed in one go lower down when we del the mempool... but what if pool goes
eina_mempool_del(ce->mp.part);
memset(&ce->mp, 0, sizeof (ce->mp));
+ eina_mempool_del(ce->mp_rtl.RECTANGLE);
+ eina_mempool_del(ce->mp_rtl.TEXT);
+ eina_mempool_del(ce->mp_rtl.IMAGE);
+ eina_mempool_del(ce->mp_rtl.SWALLOW);
+ eina_mempool_del(ce->mp_rtl.TEXTBLOCK);
+ eina_mempool_del(ce->mp_rtl.GROUP);
+ eina_mempool_del(ce->mp_rtl.BOX);
+ eina_mempool_del(ce->mp_rtl.TABLE);
+ eina_mempool_del(ce->mp_rtl.EXTERNAL);
+ memset(&ce->mp_rtl, 0, sizeof (ce->mp_rtl));
free(ec);
ce->ref = NULL;
}
#define EDJE_ENTRY_CURSOR_MODE_UNDER 0
#define EDJE_ENTRY_CURSOR_MODE_BEFORE 1
+#define EDJE_ORIENTATION_AUTO 0
+#define EDJE_ORIENTATION_LTR 1
+#define EDJE_ORIENTATION_RTL 2
+
#define EDJE_PART_PATH_SEPARATOR ':'
#define EDJE_PART_PATH_SEPARATOR_STRING ":"
#define EDJE_PART_PATH_SEPARATOR_INDEXL '['
};
/*----------*/
+#define PART_TYPE_FIELDS(TYPE) \
+ TYPE RECTANGLE; \
+ TYPE TEXT; \
+ TYPE IMAGE; \
+ TYPE SWALLOW; \
+ TYPE TEXTBLOCK; \
+ TYPE GROUP; \
+ TYPE BOX; \
+ TYPE TABLE; \
+ TYPE EXTERNAL;
struct _Edje_Part_Collection_Directory_Entry
{
struct
{
- int RECTANGLE;
- int TEXT;
- int IMAGE;
- int SWALLOW;
- int TEXTBLOCK;
- int GROUP;
- int BOX;
- int TABLE;
- int EXTERNAL;
+ PART_TYPE_FIELDS(int)
int part;
} count;
struct
{
- Eina_Mempool *RECTANGLE;
- Eina_Mempool *TEXT;
- Eina_Mempool *IMAGE;
- Eina_Mempool *SWALLOW;
- Eina_Mempool *TEXTBLOCK;
- Eina_Mempool *GROUP;
- Eina_Mempool *BOX;
- Eina_Mempool *TABLE;
- Eina_Mempool *EXTERNAL;
+ PART_TYPE_FIELDS(Eina_Mempool *)
Eina_Mempool *part;
} mp;
+ struct
+ {
+ PART_TYPE_FIELDS(Eina_Mempool *)
+ } mp_rtl; /* For Right To Left interface */
+
Edje_Part_Collection *ref;
};
struct {
Edje_Size min, max;
+ unsigned char orientation;
} prop;
int references;
struct _Edje_Part_Description_List
{
Edje_Part_Description_Common **desc;
+ Edje_Part_Description_Common **desc_rtl; /* desc for Right To Left interface */
unsigned int desc_count;
};
{
const char *name; /* the name if any of the part */
Edje_Part_Description_Common *default_desc; /* the part descriptor for default */
+ Edje_Part_Description_Common *default_desc_rtl; /* default desc for Right To Left interface */
Edje_Part_Description_List other; /* other possible descriptors */
int load_error;
int freeze;
FLOAT_T scale;
+ Eina_Bool is_rtl : 1;
struct {
Edje_Text_Change_Cb func;
struct _Edje_Real_Part_State
{
Edje_Part_Description_Common *description; // 4
+ Edje_Part_Description_Common *description_rtl; // 4
Edje_Real_Part *rel1_to_x; // 4
Edje_Real_Part *rel1_to_y; // 4
Edje_Real_Part *rel2_to_x; // 4
#endif
void *external_params; // 4
Edje_Real_Part_Set *set; // 4
-}; // 28
-// WITH EDJE_CALC_CACHE 128
+}; // 32
+// WITH EDJE_CALC_CACHE 132
struct _Edje_Real_Part_Drag
{
const char *edje_string_get(const Edje_String *es);
const char *edje_string_id_get(const Edje_String *es);
+void _edje_object_orientation_inform(Evas_Object *obj);
+
#endif
EAPI Evas_Object *
edje_object_add(Evas *evas)
{
+ Edje *ed;
+ Evas_Object *e;
if (!_edje_smart)
{
_edje_object_smart_set(&_edje_smart_class);
_edje_smart = evas_smart_class_new((Evas_Smart_Class *)&_edje_smart_class);
}
- return evas_object_smart_add(evas, _edje_smart);
+
+ e = evas_object_smart_add(evas, _edje_smart);
+ ed = _edje_fetch(e);
+
+ return e;
}
void
evas_object_move(ed->clipper, -10000, -10000);
evas_object_resize(ed->clipper, 20000, 20000);
evas_object_pass_events_set(ed->clipper, 1);
+ ed->is_rtl = EINA_FALSE;
ed->have_objects = 1;
ed->references = 1;
}
/**
+ * Get the RTL orientation for this object.
+ *
+ * You can RTL orientation explicitly with edje_object_mirrored_set.
+ *
+ * @param obj the smart object
+ * @return if flag is set or not.
+ *
+ **/
+EAPI Eina_Bool
+edje_object_mirrored_get(const Evas_Object *obj)
+{
+ Edje *ed;
+
+ ed = _edje_fetch(obj);
+ if (!ed) return EINA_FALSE;
+
+ return ed->is_rtl;
+}
+
+void
+_edje_object_orientation_inform(Evas_Object *obj)
+{
+ 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");
+}
+
+/**
+ * Set the RTL orientation for this object.
+ *
+ * @param obj the smart object
+ * @rtl new value of flag EINA_TRUE/EINA_FALSE
+ *
+ **/
+EAPI void
+edje_object_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
+{
+ Edje *ed;
+ int i;
+
+ ed = _edje_fetch(obj);
+ if (!ed) return;
+ 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;
+ }
+ _edje_recalc_do(ed);
+
+ _edje_object_orientation_inform(obj);
+
+ return;
+}
+
+/**
* @brief Get Edje object data.
*
* @param obj A valid Evas_Object handle