475 lines
11 KiB
C
475 lines
11 KiB
C
#include "evas_common.h"
|
|
#include "evas_private.h"
|
|
|
|
static Evas_Object *
|
|
evas_object_above_get_internal(const Evas_Object *obj)
|
|
{
|
|
if ((EINA_INLIST_GET(obj))->next)
|
|
return (Evas_Object *)((EINA_INLIST_GET(obj))->next);
|
|
else
|
|
{
|
|
if ((EINA_INLIST_GET(((Evas_Object*)(obj))->layer))->next)
|
|
{
|
|
Evas_Layer *l;
|
|
|
|
l = (Evas_Layer *)((EINA_INLIST_GET((((Evas_Object *)obj)->layer)))->next);
|
|
return l->objects;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static Evas_Object *
|
|
evas_object_below_get_internal(const Evas_Object *obj)
|
|
{
|
|
if ((EINA_INLIST_GET(obj))->prev)
|
|
return (Evas_Object *)((EINA_INLIST_GET(obj))->prev);
|
|
else
|
|
{
|
|
if ((EINA_INLIST_GET((((Evas_Object *)obj)->layer)))->prev)
|
|
{
|
|
Evas_Layer *l;
|
|
|
|
l = (Evas_Layer *)((EINA_INLIST_GET((((Evas_Object *)obj)->layer)))->prev);
|
|
return (Evas_Object *)((EINA_INLIST_GET((l->objects)))->last);
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* @addtogroup Evas_Object_Group_Basic
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* Raise @p obj to the top of its layer.
|
|
*
|
|
* @param obj the object to raise
|
|
*/
|
|
EAPI void
|
|
evas_object_raise(Evas_Object *obj)
|
|
{
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
return;
|
|
MAGIC_CHECK_END();
|
|
if (evas_object_intercept_call_raise(obj)) return;
|
|
if (!((EINA_INLIST_GET(obj))->next))
|
|
{
|
|
evas_object_inform_call_restack(obj);
|
|
return;
|
|
}
|
|
if (obj->smart.parent)
|
|
evas_object_smart_member_raise(obj);
|
|
else
|
|
{
|
|
if (obj->in_layer)
|
|
obj->layer->objects = (Evas_Object *)eina_inlist_demote(EINA_INLIST_GET(obj->layer->objects),
|
|
EINA_INLIST_GET(obj));
|
|
}
|
|
if (obj->clip.clipees)
|
|
{
|
|
evas_object_inform_call_restack(obj);
|
|
return;
|
|
}
|
|
if (obj->layer) evas_render_invalidate(obj->layer->evas);
|
|
obj->restack = 1;
|
|
evas_object_change(obj);
|
|
evas_object_inform_call_restack(obj);
|
|
if (obj->layer->evas->events_frozen <= 0)
|
|
{
|
|
if (!evas_event_passes_through(obj))
|
|
{
|
|
if (!obj->smart.smart)
|
|
{
|
|
if (evas_object_is_in_output_rect(obj,
|
|
obj->layer->evas->pointer.x,
|
|
obj->layer->evas->pointer.y, 1, 1) &&
|
|
obj->cur.visible)
|
|
evas_event_feed_mouse_move(obj->layer->evas,
|
|
obj->layer->evas->pointer.x,
|
|
obj->layer->evas->pointer.y,
|
|
obj->layer->evas->last_timestamp,
|
|
NULL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Lower @p obj to the bottom of its layer.
|
|
*
|
|
* @param obj the object to lower
|
|
*/
|
|
EAPI void
|
|
evas_object_lower(Evas_Object *obj)
|
|
{
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
return;
|
|
MAGIC_CHECK_END();
|
|
if (evas_object_intercept_call_lower(obj)) return;
|
|
if (!((EINA_INLIST_GET(obj))->prev))
|
|
{
|
|
evas_object_inform_call_restack(obj);
|
|
return;
|
|
}
|
|
if (obj->smart.parent)
|
|
evas_object_smart_member_lower(obj);
|
|
else
|
|
{
|
|
if (obj->in_layer)
|
|
obj->layer->objects = (Evas_Object *)eina_inlist_promote(EINA_INLIST_GET(obj->layer->objects),
|
|
EINA_INLIST_GET(obj));
|
|
}
|
|
if (obj->clip.clipees)
|
|
{
|
|
evas_object_inform_call_restack(obj);
|
|
return;
|
|
}
|
|
if (obj->layer) evas_render_invalidate(obj->layer->evas);
|
|
obj->restack = 1;
|
|
evas_object_change(obj);
|
|
evas_object_inform_call_restack(obj);
|
|
if (obj->layer->evas->events_frozen <= 0)
|
|
{
|
|
if (!evas_event_passes_through(obj))
|
|
{
|
|
if (!obj->smart.smart)
|
|
{
|
|
if (evas_object_is_in_output_rect(obj,
|
|
obj->layer->evas->pointer.x,
|
|
obj->layer->evas->pointer.y, 1, 1) &&
|
|
obj->cur.visible)
|
|
evas_event_feed_mouse_move(obj->layer->evas,
|
|
obj->layer->evas->pointer.x,
|
|
obj->layer->evas->pointer.y,
|
|
obj->layer->evas->last_timestamp,
|
|
NULL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Stack @p obj immediately above @p above
|
|
*
|
|
* If @p obj is a member of a smart object, then @p above must also be
|
|
* a member of the same smart object.
|
|
*
|
|
* Similarly, if @p obj is not a member of smart object, @p above may
|
|
* not either.
|
|
*
|
|
* @param obj the object to stack
|
|
* @param above the object above which to stack
|
|
*/
|
|
EAPI void
|
|
evas_object_stack_above(Evas_Object *obj, Evas_Object *above)
|
|
{
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
return;
|
|
MAGIC_CHECK_END();
|
|
MAGIC_CHECK(above, Evas_Object, MAGIC_OBJ);
|
|
return;
|
|
MAGIC_CHECK_END();
|
|
if (obj == above) return;
|
|
if (evas_object_intercept_call_stack_above(obj, above)) return;
|
|
if (!above)
|
|
{
|
|
evas_object_raise(obj);
|
|
return;
|
|
}
|
|
if ((EINA_INLIST_GET(obj))->prev == EINA_INLIST_GET(above))
|
|
{
|
|
evas_object_inform_call_restack(obj);
|
|
return;
|
|
}
|
|
if (obj->smart.parent)
|
|
{
|
|
if (obj->smart.parent != above->smart.parent)
|
|
{
|
|
ERR("BITCH! evas_object_stack_above(), %p not inside same smart as %p!", obj, above);
|
|
return;
|
|
}
|
|
evas_object_smart_member_stack_above(obj, above);
|
|
}
|
|
else
|
|
{
|
|
if (above->smart.parent)
|
|
{
|
|
ERR("BITCH! evas_object_stack_above(), %p stack above %p, but above has smart parent, obj does not\n", obj, above);
|
|
return;
|
|
}
|
|
if (obj->layer != above->layer)
|
|
{
|
|
ERR("BITCH! evas_object_stack_above(), %p stack above %p, not matching layers\n", obj, above);
|
|
return;
|
|
}
|
|
if (obj->in_layer)
|
|
{
|
|
obj->layer->objects = (Evas_Object *)eina_inlist_remove(EINA_INLIST_GET(obj->layer->objects),
|
|
EINA_INLIST_GET(obj));
|
|
obj->layer->objects = (Evas_Object *)eina_inlist_append_relative(EINA_INLIST_GET(obj->layer->objects),
|
|
EINA_INLIST_GET(obj),
|
|
EINA_INLIST_GET(above));
|
|
}
|
|
}
|
|
if (obj->clip.clipees)
|
|
{
|
|
evas_object_inform_call_restack(obj);
|
|
return;
|
|
}
|
|
if (obj->layer) evas_render_invalidate(obj->layer->evas);
|
|
obj->restack = 1;
|
|
evas_object_change(obj);
|
|
evas_object_inform_call_restack(obj);
|
|
if (obj->layer->evas->events_frozen <= 0)
|
|
{
|
|
if (!evas_event_passes_through(obj))
|
|
{
|
|
if (!obj->smart.smart)
|
|
{
|
|
if (evas_object_is_in_output_rect(obj,
|
|
obj->layer->evas->pointer.x,
|
|
obj->layer->evas->pointer.y, 1, 1) &&
|
|
obj->cur.visible)
|
|
evas_event_feed_mouse_move(obj->layer->evas,
|
|
obj->layer->evas->pointer.x,
|
|
obj->layer->evas->pointer.y,
|
|
obj->layer->evas->last_timestamp,
|
|
NULL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Stack @p obj immediately below @p below
|
|
*
|
|
* If @p obj is a member of a smart object, then @p below must also be
|
|
* a member of the same smart object.
|
|
*
|
|
* Similarly, if @p obj is not a member of smart object, @p below may
|
|
* not either.
|
|
*
|
|
* @param obj the object to stack
|
|
* @param below the object below which to stack
|
|
*/
|
|
EAPI void
|
|
evas_object_stack_below(Evas_Object *obj, Evas_Object *below)
|
|
{
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
return;
|
|
MAGIC_CHECK_END();
|
|
MAGIC_CHECK(below, Evas_Object, MAGIC_OBJ);
|
|
return;
|
|
MAGIC_CHECK_END();
|
|
if (obj == below) return;
|
|
if (evas_object_intercept_call_stack_below(obj, below)) return;
|
|
if (!below)
|
|
{
|
|
evas_object_lower(obj);
|
|
return;
|
|
}
|
|
if ((EINA_INLIST_GET(obj))->next == EINA_INLIST_GET(below))
|
|
{
|
|
evas_object_inform_call_restack(obj);
|
|
return;
|
|
}
|
|
if (obj->smart.parent)
|
|
{
|
|
if (obj->smart.parent != below->smart.parent)
|
|
{
|
|
ERR("BITCH! evas_object_stack_below(), %p not inside same smart as %p!", obj, below);
|
|
return;
|
|
}
|
|
evas_object_smart_member_stack_below(obj, below);
|
|
}
|
|
else
|
|
{
|
|
if (below->smart.parent)
|
|
{
|
|
ERR("BITCH! evas_object_stack_below(), %p stack below %p, but below has smart parent, obj does not\n", obj, below);
|
|
return;
|
|
}
|
|
if (obj->layer != below->layer)
|
|
{
|
|
ERR("BITCH! evas_object_stack_below(), %p stack below %p, not matching layers\n", obj, below);
|
|
return;
|
|
}
|
|
if (obj->in_layer)
|
|
{
|
|
obj->layer->objects = (Evas_Object *)eina_inlist_remove(EINA_INLIST_GET(obj->layer->objects),
|
|
EINA_INLIST_GET(obj));
|
|
obj->layer->objects = (Evas_Object *)eina_inlist_prepend_relative(EINA_INLIST_GET(obj->layer->objects),
|
|
EINA_INLIST_GET(obj),
|
|
EINA_INLIST_GET(below));
|
|
}
|
|
}
|
|
if (obj->clip.clipees)
|
|
{
|
|
evas_object_inform_call_restack(obj);
|
|
return;
|
|
}
|
|
if (obj->layer) evas_render_invalidate(obj->layer->evas);
|
|
obj->restack = 1;
|
|
evas_object_change(obj);
|
|
evas_object_inform_call_restack(obj);
|
|
if (obj->layer->evas->events_frozen <= 0)
|
|
{
|
|
if (!evas_event_passes_through(obj))
|
|
{
|
|
if (!obj->smart.smart)
|
|
{
|
|
if (evas_object_is_in_output_rect(obj,
|
|
obj->layer->evas->pointer.x,
|
|
obj->layer->evas->pointer.y, 1, 1) &&
|
|
obj->cur.visible)
|
|
evas_event_feed_mouse_move(obj->layer->evas,
|
|
obj->layer->evas->pointer.x,
|
|
obj->layer->evas->pointer.y,
|
|
obj->layer->evas->last_timestamp,
|
|
NULL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the evas object above @p obj
|
|
*
|
|
* @param obj an Evas_Object
|
|
* @return the Evas_Object directly above
|
|
*/
|
|
EAPI Evas_Object *
|
|
evas_object_above_get(const Evas_Object *obj)
|
|
{
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
return NULL;
|
|
MAGIC_CHECK_END();
|
|
if (obj->smart.parent)
|
|
{
|
|
do
|
|
{
|
|
obj = (Evas_Object *)((EINA_INLIST_GET(obj))->next);
|
|
if ((obj) && (!obj->delete_me)) return (Evas_Object *)obj;
|
|
}
|
|
while (obj);
|
|
return NULL;
|
|
}
|
|
obj = evas_object_above_get_internal(obj);
|
|
while (obj)
|
|
{
|
|
if (!obj->delete_me) return (Evas_Object *)obj;
|
|
obj = evas_object_above_get_internal(obj);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* Get the evas object below @p obj
|
|
*
|
|
* @param obj an Evas_Object
|
|
* @return the Evas_Object directly below
|
|
*/
|
|
EAPI Evas_Object *
|
|
evas_object_below_get(const Evas_Object *obj)
|
|
{
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
return NULL;
|
|
MAGIC_CHECK_END();
|
|
if (obj->smart.parent)
|
|
{
|
|
do
|
|
{
|
|
obj = (Evas_Object *)((EINA_INLIST_GET(obj))->prev);
|
|
if ((obj) && (!obj->delete_me)) return (Evas_Object *)obj;
|
|
}
|
|
while (obj);
|
|
return NULL;
|
|
}
|
|
obj = evas_object_below_get_internal(obj);
|
|
while (obj)
|
|
{
|
|
if (!obj->delete_me) return (Evas_Object *)obj;
|
|
obj = evas_object_below_get_internal(obj);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @addtogroup Evas_Object_Group_Find
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* Get the lowest evas object on the Evas @p e
|
|
*
|
|
* @param e an Evas
|
|
* @return the lowest object
|
|
*/
|
|
EAPI Evas_Object *
|
|
evas_object_bottom_get(const Evas *e)
|
|
{
|
|
MAGIC_CHECK(e, Evas, MAGIC_EVAS);
|
|
return NULL;
|
|
MAGIC_CHECK_END();
|
|
if (e->layers)
|
|
{
|
|
Evas_Object *obj;
|
|
|
|
obj = e->layers->objects;
|
|
while (obj)
|
|
{
|
|
if (!obj->delete_me) return obj;
|
|
obj = evas_object_above_get_internal(obj);
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* Get the highest evas object on the Evas @p e
|
|
*
|
|
* @param e an Evas
|
|
* @return the highest object
|
|
*/
|
|
EAPI Evas_Object *
|
|
evas_object_top_get(const Evas *e)
|
|
{
|
|
Evas_Object *obj = NULL;
|
|
Eina_Inlist *list;
|
|
Evas_Layer *layer;
|
|
|
|
MAGIC_CHECK(e, Evas, MAGIC_EVAS);
|
|
return NULL;
|
|
MAGIC_CHECK_END();
|
|
|
|
list = EINA_INLIST_GET(e->layers);
|
|
if (!list) return NULL;
|
|
|
|
layer = (Evas_Layer *) list->last;
|
|
if (!layer) return NULL;
|
|
|
|
list = EINA_INLIST_GET(layer->objects);
|
|
if (!list) return NULL;
|
|
|
|
obj = (Evas_Object *) list->last;
|
|
if (!obj) return NULL;
|
|
|
|
while (obj)
|
|
{
|
|
if (!obj->delete_me) return obj;
|
|
obj = evas_object_below_get_internal(obj);
|
|
}
|
|
|
|
return obj;
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|