This should now fix the part API usage once and for all.
EFL should have no part name in any of its APIs beyond
the Efl.Part interface.
Part proxy objects (may be real objects) have a lifetime
of only one function call, in a fashion similar to eo_super.
@feature
lib/efl/interfaces/efl_control.eo \
lib/efl/interfaces/efl_file.eo \
lib/efl/interfaces/efl_image_load.eo \
+ lib/efl/interfaces/efl_part.eo \
lib/efl/interfaces/efl_player.eo \
lib/efl/interfaces/efl_text.eo \
lib/efl/interfaces/efl_text_properties.eo \
Edje *ed;
Edje_Real_Part *rp;
const char *part;
+ Eina_Bool temp;
};
struct _Part_Item_Iterator
Eo *object;
};
-static Eina_Bool
-_del_cb(void *data, const Eo_Event *event EINA_UNUSED)
-{
- Edje_Real_Part *rp = data;
- rp->typedata.container->eo_proxy = NULL;
- return EO_CALLBACK_CONTINUE;
-}
-
Eo *
_edje_box_internal_proxy_get(Edje_Object *obj, Edje *ed, Edje_Real_Part *rp)
{
- Efl_Canvas_Layout_Internal_Box *eo = rp->typedata.container->eo_proxy;
-
- if (eo) return eo;
-
- eo = eo_add(BOX_CLASS, obj, efl_canvas_layout_internal_box_real_part_set(eo_self, ed, rp, rp->part->name));
- eo_event_callback_add(eo, EO_EVENT_DEL, _del_cb, rp);
-
- rp->typedata.container->eo_proxy = eo;
- return eo;
+ // TODO: optimize (cache)
+ return eo_add(BOX_CLASS, obj,
+ efl_canvas_layout_internal_box_real_part_set(eo_self, ed, rp, rp->part->name));
}
EOLIAN static void
pd->ed = ed;
pd->rp = rp;
pd->part = part;
+ pd->temp = EINA_TRUE;
}
EOLIAN static Eo_Base *
Eo *
_edje_table_internal_proxy_get(Edje_Object *obj, Edje *ed, Edje_Real_Part *rp)
{
- Efl_Canvas_Layout_Internal_Box *eo = rp->typedata.container->eo_proxy;
-
- if (eo) return eo;
-
- eo = eo_add(TABLE_CLASS, obj, efl_canvas_layout_internal_table_real_part_set(eo_self, ed, rp, rp->part->name));
- eo_event_callback_add(eo, EO_EVENT_DEL, _del_cb, rp);
-
- rp->typedata.container->eo_proxy = eo;
- return eo;
+ // TODO: optimize (cache)
+ return eo_add(TABLE_CLASS, obj,
+ efl_canvas_layout_internal_table_real_part_set(eo_self, ed, rp, rp->part->name));
}
EOLIAN static void
pd->ed = ed;
pd->rp = rp;
pd->part = part;
+ pd->temp = EINA_TRUE;
}
EOLIAN static Eo_Base *
#ifdef DEGUG
#define PART_BOX_GET(obj, part, ...) ({ \
- Eo *__box = efl_content_get(obj, part); \
+ Eo *__box = efl_part(obj, part); \
if (!__box || !eo_isa(__box, EFL_CANVAS_LAYOUT_INTERNAL_BOX_CLASS)) \
{ \
ERR("No such box part '%s' in layout %p", part, obj); \
__box; })
#else
#define PART_BOX_GET(obj, part, ...) ({ \
- Eo *__box = efl_content_get(obj, part); \
+ Eo *__box = efl_part(obj, part); \
if (!__box) return __VA_ARGS__; \
__box; })
#endif
#ifdef DEBUG
#define PART_TABLE_GET(obj, part, ...) ({ \
- Eo *__table = efl_content_get(obj, part); \
+ Eo *__table = efl_part(obj, part); \
if (!__table || !eo_isa(__table, EFL_CANVAS_LAYOUT_INTERNAL_TABLE_CLASS)) \
{ \
ERR("No such table part '%s' in layout %p", part, obj); \
__table; })
#else
#define PART_TABLE_GET(obj, part, ...) ({ \
- Eo *__table = efl_content_get(obj, part); \
+ Eo *__table = efl_part(obj, part); \
if (!__table) return __VA_ARGS__; \
__table; })
#endif
_edje_box_layout_free_data(rp->typedata.container->anim);
rp->typedata.container->anim = NULL;
}
- eo_unref(rp->typedata.container->eo_proxy);
free(rp->typedata.container);
}
else if ((rp->type == EDJE_RP_TYPE_TEXT) &&
import edje_types;
-class Edje.Object (Evas.Smart.Clipped, Efl.File, Efl.Container)
+class Edje.Object (Evas.Smart.Clipped, Efl.File, Efl.Container, Efl.Part)
{
legacy_prefix: edje_object;
eo_prefix: edje_obj;
Efl.Container.content_unset;
Efl.Container.content_remove;
Efl.Container.content_part_name.get;
+ Efl.Part.part;
}
events {
recalc; [[Edje re-calculated the object.]]
{
Eina_List *items; // 4 //FIXME: only if table/box
Edje_Part_Box_Animation *anim; // 4 //FIXME: Used only if box
- Eo *eo_proxy;
};
struct _Edje_Real_Part_Swallow
rp = _edje_real_part_recursive_get(&ed, part);
if (!rp) return NULL;
- switch (rp->type)
- {
- case EDJE_RP_TYPE_SWALLOW:
- if (!rp->typedata.swallow) return NULL;
- return rp->typedata.swallow->swallowed_object;
- case EDJE_RP_TYPE_CONTAINER:
- if (rp->part->type == EDJE_PART_TYPE_BOX)
- return _edje_box_internal_proxy_get(obj, ed, rp);
- else if (rp->part->type == EDJE_PART_TYPE_TABLE)
- return _edje_table_internal_proxy_get(obj, ed, rp);
- else return NULL;
- case EDJE_RP_TYPE_TEXT:
- WRN("not implemented yet");
- return NULL;
- default:
+ 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;
}
/* new in eo */
return rp->part->name;
}
+EOLIAN Eo *
+_edje_object_efl_part_part(Eo *obj, Edje *ed, const char *part)
+{
+ Edje_Real_Part *rp;
+
+ if ((!ed) || (!part)) return NULL;
+
+ /* Need to recalc before providing the object. */
+ _edje_recalc_do(ed);
+
+ rp = _edje_real_part_recursive_get(&ed, part);
+ if (!rp) return NULL;
+
+ if (rp->part->type == EDJE_PART_TYPE_BOX)
+ return _edje_box_internal_proxy_get(obj, ed, rp);
+ else if (rp->part->type == EDJE_PART_TYPE_TABLE)
+ return _edje_table_internal_proxy_get(obj, ed, rp);
+ else return NULL; /* FIXME/TODO: text & others (color, ...) */
+}
+
EOLIAN void
_edje_object_size_min_get(Eo *obj EINA_UNUSED, Edje *ed, Evas_Coord *minw, Evas_Coord *minh)
{
#include "interfaces/efl_image.eo.h"
#include "interfaces/efl_image_animated.eo.h"
#include "interfaces/efl_image_load.eo.h"
+#include "interfaces/efl_part.eo.h"
#include "interfaces/efl_player.eo.h"
#include "interfaces/efl_text.eo.h"
#include "interfaces/efl_text_properties.eo.h"
#include "interfaces/efl_image.eo.c"
#include "interfaces/efl_image_animated.eo.c"
#include "interfaces/efl_image_load.eo.c"
+#include "interfaces/efl_part.eo.c"
#include "interfaces/efl_player.eo.c"
#include "interfaces/efl_text.eo.c"
#include "interfaces/efl_text_properties.eo.c"
--- /dev/null
+import eo_base;
+
+interface Efl.Part
+{
+ [[Interface for objects supporting named parts.
+
+ An object implementing this interface will be able to
+ provide access to some of its sub-objects by name.
+ This gives access to parts as defined in a widget's
+ theme.
+
+ Part proxy objects have a special lifetime that
+ is limited to one and only one function call.
+
+ In other words, the caller does not hold a reference
+ to this proxy object. It may be possible, in languages
+ that allow it, to get an extra reference to this part
+ object and extend its lifetime to more than a single
+ function call.
+
+ In pseudo-code, this means only the following two
+ use cases are supported:
+
+ obj.func(part(obj, "part"), args)
+
+ And:
+
+ part = ref(part(obj, "part"))
+ func1(part, args)
+ func2(part, args)
+ func3(part, args)
+ unref(part)
+ ]]
+ methods {
+ part @const {
+ [[Get a proxy object referring to a part of an object.
+
+ The returned object is valid for only a single function call.
+ ]]
+ params {
+ name: const(char)*; [[The part name.]]
+ }
+ return: Eo.Base; [[A (proxy) object, valid for a single call.]]
+ }
+ }
+}