2013-06-20 03:53:29 -07:00
|
|
|
#include "evas_common_private.h"
|
2002-11-08 00:02:15 -08:00
|
|
|
#include "evas_private.h"
|
|
|
|
|
|
|
|
void
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_clip_dirty(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2013-04-10 21:21:54 -07:00
|
|
|
Evas_Object_Protected_Data *clipee;
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *l;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2013-03-12 05:58:19 -07:00
|
|
|
if (obj->cur->cache.clip.dirty) return;
|
|
|
|
|
|
|
|
EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
|
|
|
|
{
|
|
|
|
state_write->cache.clip.dirty = EINA_TRUE;
|
|
|
|
}
|
|
|
|
EINA_COW_STATE_WRITE_END(obj, state_write, cur);
|
2011-03-21 08:18:26 -07:00
|
|
|
|
2013-04-10 21:21:54 -07:00
|
|
|
EINA_LIST_FOREACH(obj->clip.clipees, l, clipee)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2013-04-10 21:21:54 -07:00
|
|
|
evas_object_clip_dirty(clipee->object, clipee);
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
2005-04-03 07:22:17 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-04-06 22:00:10 -07:00
|
|
|
evas_object_recalc_clippees(Evas_Object_Protected_Data *obj)
|
2005-04-03 07:22:17 -07:00
|
|
|
{
|
2013-04-10 21:21:54 -07:00
|
|
|
Evas_Object_Protected_Data *clipee;
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *l;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2013-03-12 05:58:19 -07:00
|
|
|
if (obj->cur->cache.clip.dirty)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2013-04-06 22:00:10 -07:00
|
|
|
evas_object_clip_recalc(obj);
|
2013-04-10 21:21:54 -07:00
|
|
|
EINA_LIST_FOREACH(obj->clip.clipees, l, clipee)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2013-04-06 22:00:10 -07:00
|
|
|
evas_object_recalc_clippees(clipee);
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-31 15:16:08 -07:00
|
|
|
/* aaaaargh (pirate voice) ... notes!
|
2012-09-11 04:43:17 -07:00
|
|
|
*
|
2010-08-31 15:16:08 -07:00
|
|
|
* we have a big problem until now that's gone undetected... until yesterday.
|
|
|
|
* that problem involves clips and maps and smart objects. hooray! 3 of the
|
|
|
|
* more complex bits of evas - and maps and smart objects being one of the
|
|
|
|
* nastiest ones.
|
2012-09-11 04:43:17 -07:00
|
|
|
*
|
2010-08-31 15:16:08 -07:00
|
|
|
* what is the problem? when a clip crosses a map boundary. that is to say
|
|
|
|
* that when the clipper and clippee are not within the child tree of the
|
|
|
|
* mapped object. in this case "bad stuff" happens. basically as clips are
|
|
|
|
* then used to render objects, but they no longer apply as you'd expect as
|
|
|
|
* the map transfomr the objects to-be-clipped separately from the objects
|
|
|
|
* that clip them and this whole relationship is broken by maps. it somehow
|
|
|
|
* managed to not break with the advent of smart objects. lucky me... but
|
|
|
|
* maps killed it. now... what do we do? that is a good question. detect
|
|
|
|
* such a broken link and "turn off clipping" in that event - sure. but this
|
|
|
|
* isn't going to be cheap as ANY addition or deletion of a map to an object
|
|
|
|
* or any change in clipper of an object or any change in smart object
|
|
|
|
* membership needs to walk the obj tree both up and down from the changed
|
|
|
|
* object and probably walk entire object trees to find these and mark them.
|
|
|
|
* thats silly-expensive and i was about to fix it that way but it has since
|
|
|
|
* dawned on me that that is just going to kill performance in some critical
|
|
|
|
* areas like during object setup and manipulation, as well as teardown.
|
2012-09-11 04:43:17 -07:00
|
|
|
*
|
2010-08-31 15:16:08 -07:00
|
|
|
* aaaaagh! best for now is to document this as a "don't do it damnit!" thing
|
|
|
|
* and have the apps avoid it. but even then - how to do this? this is not
|
|
|
|
* easy. everywhere i turn so far i come up to either expensive operations,
|
|
|
|
* breaks in logic, or nasty re-work of apps or4 the whole concept of clipping,
|
|
|
|
* smart objects and maps... and that will have to wait for evas 2.0
|
2012-09-11 04:43:17 -07:00
|
|
|
*
|
2010-09-01 14:38:34 -07:00
|
|
|
* the below does clip fixups etc. in the even a clip spans a map boundary.
|
|
|
|
* not pretty, but necessary.
|
2010-08-31 15:16:08 -07:00
|
|
|
*/
|
|
|
|
|
2010-09-01 14:37:10 -07:00
|
|
|
#define MAP_ACROSS 1
|
2010-08-31 15:16:08 -07:00
|
|
|
static void
|
2013-12-05 04:05:44 -08:00
|
|
|
evas_object_child_map_across_mark(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, Evas_Object *map_obj, Eina_Bool force, Eina_Hash *visited)
|
2010-08-31 15:16:08 -07:00
|
|
|
{
|
2010-09-01 14:37:10 -07:00
|
|
|
#ifdef MAP_ACROSS
|
2013-12-05 04:05:44 -08:00
|
|
|
Eina_Bool clear_visited = EINA_FALSE;
|
|
|
|
|
|
|
|
if (!visited)
|
|
|
|
{
|
|
|
|
visited = eina_hash_pointer_new(NULL);
|
|
|
|
clear_visited = EINA_TRUE;
|
|
|
|
}
|
2013-12-05 16:07:44 -08:00
|
|
|
if (eina_hash_find(visited, &eo_obj) == (void *)1) goto end;
|
2014-01-01 16:26:34 -08:00
|
|
|
else eina_hash_add(visited, &eo_obj, (void *)1);
|
2013-12-05 04:05:44 -08:00
|
|
|
|
2013-01-21 19:56:00 -08:00
|
|
|
if ((obj->map->cur.map_parent != map_obj) || force)
|
2010-08-31 15:16:08 -07:00
|
|
|
{
|
2013-01-21 19:56:00 -08:00
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
|
|
|
|
map_write->cur.map_parent = map_obj;
|
|
|
|
EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
|
|
|
|
|
2013-03-12 05:58:19 -07:00
|
|
|
EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
|
|
|
|
{
|
|
|
|
state_write->cache.clip.dirty = 1;
|
|
|
|
}
|
|
|
|
EINA_COW_STATE_WRITE_END(obj, state_write, cur);
|
|
|
|
|
2013-04-06 22:00:10 -07:00
|
|
|
evas_object_clip_recalc(obj);
|
2012-10-08 18:58:41 -07:00
|
|
|
if (obj->is_smart)
|
2010-09-01 14:37:10 -07:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj2;
|
2012-09-11 04:43:17 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(eo_obj), obj2)
|
2010-09-01 14:37:10 -07:00
|
|
|
{
|
|
|
|
// if obj has its own map - skip it. already done
|
2013-01-21 19:56:00 -08:00
|
|
|
if ((obj2->map->cur.map) && (obj2->map->cur.usemap)) continue;
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object *eo_obj2 = obj2->object;
|
2013-12-05 04:05:44 -08:00
|
|
|
evas_object_child_map_across_mark(eo_obj2, obj2, map_obj,
|
|
|
|
force, visited);
|
2010-09-01 14:37:10 -07:00
|
|
|
}
|
|
|
|
}
|
2010-09-02 02:40:23 -07:00
|
|
|
else if (obj->clip.clipees)
|
|
|
|
{
|
2013-04-10 21:21:54 -07:00
|
|
|
Evas_Object_Protected_Data *obj2;
|
2010-09-02 02:40:23 -07:00
|
|
|
Eina_List *l;
|
2012-09-11 04:43:17 -07:00
|
|
|
|
2013-04-10 21:21:54 -07:00
|
|
|
EINA_LIST_FOREACH(obj->clip.clipees, l, obj2)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2013-12-05 04:05:44 -08:00
|
|
|
evas_object_child_map_across_mark(obj2->object, obj2,
|
|
|
|
map_obj, force, visited);
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
2010-09-02 02:40:23 -07:00
|
|
|
}
|
2010-08-31 15:16:08 -07:00
|
|
|
}
|
2013-12-05 16:07:44 -08:00
|
|
|
end:
|
2013-12-05 04:05:44 -08:00
|
|
|
if (clear_visited) eina_hash_free(visited);
|
2012-09-11 04:43:17 -07:00
|
|
|
#endif
|
2010-08-31 15:16:08 -07:00
|
|
|
}
|
|
|
|
|
2010-09-02 02:40:23 -07:00
|
|
|
void
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_clip_across_check(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
|
2010-09-01 14:37:10 -07:00
|
|
|
{
|
2010-09-02 02:40:23 -07:00
|
|
|
#ifdef MAP_ACROSS
|
2013-03-12 05:58:19 -07:00
|
|
|
if (!obj->cur->clipper) return;
|
|
|
|
if (obj->cur->clipper->map->cur.map_parent != obj->map->cur.map_parent)
|
2013-12-05 04:05:44 -08:00
|
|
|
evas_object_child_map_across_mark(eo_obj, obj, obj->map->cur.map_parent,
|
|
|
|
1, NULL);
|
2012-09-11 04:43:17 -07:00
|
|
|
#endif
|
2010-09-02 02:40:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_clip_across_clippees_check(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
|
2010-09-02 02:40:23 -07:00
|
|
|
{
|
|
|
|
#ifdef MAP_ACROSS
|
2013-04-10 21:21:54 -07:00
|
|
|
Evas_Object_Protected_Data *obj2;
|
2010-09-02 02:40:23 -07:00
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
if (!obj->clip.clipees) return;
|
2010-09-03 01:23:38 -07:00
|
|
|
// schloooooooooooow:
|
2013-12-05 04:05:44 -08:00
|
|
|
// evas_object_child_map_across_mark(eo_obj, obj->map->cur.map_parent, 1, NULL);
|
2010-09-03 01:23:38 -07:00
|
|
|
// buggy:
|
2013-12-05 04:05:44 -08:00
|
|
|
evas_object_child_map_across_mark(eo_obj, obj, obj->map->cur.map_parent, 0,
|
|
|
|
NULL);
|
2013-03-12 05:58:19 -07:00
|
|
|
if (obj->cur->cache.clip.dirty)
|
2010-09-02 02:40:23 -07:00
|
|
|
{
|
2013-04-10 21:21:54 -07:00
|
|
|
EINA_LIST_FOREACH(obj->clip.clipees, l, obj2)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2013-04-10 21:21:54 -07:00
|
|
|
evas_object_clip_across_clippees_check(obj2->object, obj2);
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
2010-09-02 02:40:23 -07:00
|
|
|
}
|
2012-09-11 04:43:17 -07:00
|
|
|
#endif
|
2010-09-01 14:37:10 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// this function is called on an object when map is enabled or disabled on it
|
|
|
|
// thus creating a "map boundary" at that point.
|
2012-09-11 04:43:17 -07:00
|
|
|
//
|
2010-09-01 15:51:00 -07:00
|
|
|
// FIXME: flip2 test broken in elm - might be show/hide of clips
|
2010-08-31 15:16:08 -07:00
|
|
|
void
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_mapped_clip_across_mark(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
|
2010-08-31 15:16:08 -07:00
|
|
|
{
|
2010-09-01 14:37:10 -07:00
|
|
|
#ifdef MAP_ACROSS
|
2013-01-21 19:56:00 -08:00
|
|
|
if ((obj->map->cur.map) && (obj->map->cur.usemap))
|
2013-12-05 04:05:44 -08:00
|
|
|
evas_object_child_map_across_mark(eo_obj, obj, eo_obj, 0, NULL);
|
2010-08-31 15:16:08 -07:00
|
|
|
else
|
2010-09-01 14:37:10 -07:00
|
|
|
{
|
|
|
|
if (obj->smart.parent)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
|
|
|
Evas_Object_Protected_Data *smart_parent_obj =
|
2014-06-02 06:47:59 -07:00
|
|
|
eo_data_scope_get(obj->smart.parent, EVAS_OBJECT_CLASS);
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_child_map_across_mark
|
2013-12-05 04:05:44 -08:00
|
|
|
(eo_obj, obj, smart_parent_obj->map->cur.map_parent, 0, NULL);
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
2010-09-01 14:37:10 -07:00
|
|
|
else
|
2013-12-05 04:05:44 -08:00
|
|
|
evas_object_child_map_across_mark(eo_obj, obj, NULL, 0, NULL);
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
2011-06-14 17:48:38 -07:00
|
|
|
#endif
|
2010-08-31 15:16:08 -07:00
|
|
|
}
|
|
|
|
|
2014-11-12 17:40:16 -08:00
|
|
|
static void
|
|
|
|
_evas_object_clip_mask_unset(Evas_Object_Protected_Data *obj)
|
|
|
|
{
|
|
|
|
if (!obj || !obj->mask->is_mask) return;
|
|
|
|
if (obj->clip.clipees) return;
|
|
|
|
|
|
|
|
/* this frees the clip surface. is this correct? */
|
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_mask_cow, obj->mask, Evas_Object_Mask_Data, mask)
|
|
|
|
mask->is_mask = EINA_FALSE;
|
|
|
|
mask->redraw = EINA_FALSE;
|
|
|
|
mask->is_alpha = EINA_FALSE;
|
|
|
|
if (mask->surface)
|
|
|
|
{
|
2015-07-01 20:04:02 -07:00
|
|
|
obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output, mask->surface);
|
2014-11-12 17:40:16 -08:00
|
|
|
mask->surface = NULL;
|
|
|
|
}
|
|
|
|
mask->w = 0;
|
|
|
|
mask->h = 0;
|
|
|
|
EINA_COW_WRITE_END(evas_object_mask_cow, obj->mask, mask);
|
|
|
|
}
|
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
/* public functions */
|
2011-06-02 03:00:05 -07:00
|
|
|
extern const char *o_rect_type;
|
2014-11-12 17:40:16 -08:00
|
|
|
extern const char *o_image_type;
|
2008-11-01 14:50:36 -07:00
|
|
|
|
2016-01-27 19:18:34 -08:00
|
|
|
static Eina_Bool _clipper_del_cb(void *data, Eo *eo_clip, const Eo_Event_Description *desc EINA_UNUSED, void *info EINA_UNUSED);
|
|
|
|
|
2014-03-11 04:51:35 -07:00
|
|
|
EOLIAN void
|
|
|
|
_evas_object_clip_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, Evas_Object *eo_clip)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2012-10-10 00:23:00 -07:00
|
|
|
Evas_Object_Protected_Data *clip;
|
2013-04-26 11:01:44 -07:00
|
|
|
Evas_Public_Data *e;
|
2012-10-10 00:23:00 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
if (!eo_clip)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_clip_unset(eo_obj);
|
2012-09-11 04:43:17 -07:00
|
|
|
return;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2012-10-10 00:23:00 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
MAGIC_CHECK(eo_clip, Evas_Object, MAGIC_OBJ);
|
2002-11-08 00:02:15 -08:00
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
2012-10-10 00:23:00 -07:00
|
|
|
|
2015-02-10 03:44:38 -08:00
|
|
|
evas_object_async_block(obj);
|
|
|
|
|
2014-06-02 06:47:59 -07:00
|
|
|
clip = eo_data_scope_get(eo_clip, EVAS_OBJECT_CLASS);
|
2013-04-06 22:00:10 -07:00
|
|
|
if (obj->cur->clipper && obj->cur->clipper->object == eo_clip) return;
|
2012-10-08 18:58:41 -07:00
|
|
|
if (eo_obj == eo_clip)
|
2012-08-07 02:43:22 -07:00
|
|
|
{
|
2013-12-25 19:22:05 -08:00
|
|
|
CRI("Setting clip %p on itself", eo_obj);
|
2012-08-07 02:43:22 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (clip->delete_me)
|
|
|
|
{
|
2013-12-25 19:22:05 -08:00
|
|
|
CRI("Setting deleted object %p as clip obj %p", eo_clip, eo_obj);
|
2012-08-07 02:43:22 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (obj->delete_me)
|
|
|
|
{
|
2013-12-25 19:22:05 -08:00
|
|
|
CRI("Setting object %p as clip to deleted obj %p", eo_clip, eo_obj);
|
2012-08-07 02:43:22 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!obj->layer)
|
|
|
|
{
|
2013-12-25 19:22:05 -08:00
|
|
|
CRI("No evas surface associated with object (%p)", eo_obj);
|
2012-08-07 02:43:22 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ((obj->layer && clip->layer) &&
|
|
|
|
(obj->layer->evas != clip->layer->evas))
|
|
|
|
{
|
2013-12-25 19:22:05 -08:00
|
|
|
CRI("Setting object %p from Evas (%p) to another Evas (%p)", obj, obj->layer->evas, clip->layer->evas);
|
2012-08-07 02:43:22 -07:00
|
|
|
return;
|
|
|
|
}
|
2014-03-12 18:39:27 -07:00
|
|
|
if (!obj->layer || !clip->layer)
|
|
|
|
{
|
|
|
|
CRI("Object %p or clip %p layer is not set !", obj, clip);
|
|
|
|
return;
|
|
|
|
}
|
2012-08-07 02:43:22 -07:00
|
|
|
|
2015-02-10 03:44:38 -08:00
|
|
|
if (evas_object_intercept_call_clip_set(eo_obj, obj, eo_clip))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2014-11-12 17:40:16 -08:00
|
|
|
// illegal to set anything but a rect or an image as a clip
|
|
|
|
if (clip->type != o_rect_type && clip->type != o_image_type)
|
2012-08-07 02:43:22 -07:00
|
|
|
{
|
2014-11-12 17:40:16 -08:00
|
|
|
ERR("For now a clip on other object than a rectangle or an image is disabled");
|
2012-08-07 02:43:22 -07:00
|
|
|
return;
|
|
|
|
}
|
2012-10-08 18:58:41 -07:00
|
|
|
if (obj->is_smart)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
eo_do(eo_obj, evas_obj_smart_clip_set(eo_clip));
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2013-03-12 05:58:19 -07:00
|
|
|
if (obj->cur->clipper)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2016-01-27 19:18:34 -08:00
|
|
|
Evas_Object_Protected_Data *old_clip = obj->cur->clipper;
|
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
/* unclip */
|
2013-04-10 21:21:54 -07:00
|
|
|
obj->cur->clipper->clip.cache_clipees_answer = eina_list_free(obj->cur->clipper->clip.cache_clipees_answer);
|
|
|
|
obj->cur->clipper->clip.clipees = eina_list_remove(obj->cur->clipper->clip.clipees, obj);
|
2013-03-12 05:58:19 -07:00
|
|
|
if (!obj->cur->clipper->clip.clipees)
|
2012-09-11 04:43:17 -07:00
|
|
|
{
|
2013-03-12 05:58:19 -07:00
|
|
|
EINA_COW_STATE_WRITE_BEGIN(obj->cur->clipper, state_write, cur)
|
|
|
|
{
|
|
|
|
state_write->have_clipees = 0;
|
2015-09-01 00:32:46 -07:00
|
|
|
if (obj->cur->clipper->is_static_clip)
|
|
|
|
WRN("You override static clipper, it may be dangled! obj(%p) type(%s) new clip(%p)", eo_obj, obj->type, eo_clip);
|
2013-03-12 05:58:19 -07:00
|
|
|
}
|
|
|
|
EINA_COW_STATE_WRITE_END(obj->cur->clipper, state_write, cur);
|
2014-04-16 00:14:16 -07:00
|
|
|
/* i know this was to handle a case where a clip stops having children and
|
|
|
|
* becomes a solid colored box - no one ever does that... they hide the clip
|
evas/clip: If the clipper is image or has color, clipped area should be redrawn.
Summary:
If the clipper is image or has color, it affects to its clipees.
Even if we unset the clipper or change the clipper to another object,
it seems the clipper is not changed.
Test Plan:
Make two clipper objects and one clipee object.
And make clip the clipee according to following example
ex) Clipee object -> inner_clipper -> clipper
evas_object_clip_set(clipee, inner_clipper);
evas_object_clip_set(inner_clipper, clipper);
After checking the result and hide inner_clipper.
evas_object_clip_set(clipee, clipper);
evas_object_hide(inner_clipper);
See the result.
Reviewers: raster, cedric, Hermet, jpeg
Subscribers: woohyun, cedric
Differential Revision: https://phab.enlightenment.org/D2112
Signed-off-by: Jean-Philippe Andre <jp.andre@samsung.com>
Note: Technically we should not check the color of the fact that
the clipper is a mask and not a simple rect. But because of
real-life performance issues, damage_add was disabled so we're
trying to keep the perf in most cases while being correct in
cases where the clipper is visually important.
2015-03-16 19:02:04 -07:00
|
|
|
* so dont add damages.
|
|
|
|
* But, if the clipper could affect color to its clipees,
|
|
|
|
* the clipped area should be redrawn. */
|
|
|
|
if (((obj->cur->clipper->cur) && (obj->cur->clipper->cur->visible)) &&
|
|
|
|
(((obj->cur->clipper->cur->color.r != 255) || (obj->cur->clipper->cur->color.g != 255) ||
|
|
|
|
(obj->cur->clipper->cur->color.b != 255) || (obj->cur->clipper->cur->color.a != 255)) ||
|
|
|
|
(obj->cur->clipper->mask->is_mask)))
|
2014-03-15 03:55:38 -07:00
|
|
|
{
|
|
|
|
if (obj->cur->clipper->layer)
|
|
|
|
{
|
|
|
|
e = obj->cur->clipper->layer->evas;
|
|
|
|
evas_damage_rectangle_add(e->evas,
|
|
|
|
obj->cur->clipper->cur->geometry.x + e->framespace.x,
|
|
|
|
obj->cur->clipper->cur->geometry.y + e->framespace.y,
|
|
|
|
obj->cur->clipper->cur->geometry.w,
|
|
|
|
obj->cur->clipper->cur->geometry.h);
|
|
|
|
}
|
|
|
|
}
|
evas/clip: If the clipper is image or has color, clipped area should be redrawn.
Summary:
If the clipper is image or has color, it affects to its clipees.
Even if we unset the clipper or change the clipper to another object,
it seems the clipper is not changed.
Test Plan:
Make two clipper objects and one clipee object.
And make clip the clipee according to following example
ex) Clipee object -> inner_clipper -> clipper
evas_object_clip_set(clipee, inner_clipper);
evas_object_clip_set(inner_clipper, clipper);
After checking the result and hide inner_clipper.
evas_object_clip_set(clipee, clipper);
evas_object_hide(inner_clipper);
See the result.
Reviewers: raster, cedric, Hermet, jpeg
Subscribers: woohyun, cedric
Differential Revision: https://phab.enlightenment.org/D2112
Signed-off-by: Jean-Philippe Andre <jp.andre@samsung.com>
Note: Technically we should not check the color of the fact that
the clipper is a mask and not a simple rect. But because of
real-life performance issues, damage_add was disabled so we're
trying to keep the perf in most cases while being correct in
cases where the clipper is visually important.
2015-03-16 19:02:04 -07:00
|
|
|
|
2014-11-12 17:40:16 -08:00
|
|
|
_evas_object_clip_mask_unset(obj->cur->clipper);
|
2012-09-11 04:43:17 -07:00
|
|
|
}
|
2013-04-06 22:00:10 -07:00
|
|
|
evas_object_change(obj->cur->clipper->object, obj->cur->clipper);
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_change(eo_obj, obj);
|
2013-03-12 05:58:19 -07:00
|
|
|
|
|
|
|
EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
|
2016-01-27 19:18:34 -08:00
|
|
|
state_write->clipper = NULL;
|
2013-03-12 05:58:19 -07:00
|
|
|
EINA_COW_STATE_WRITE_END(obj, state_write, cur);
|
2016-01-27 19:18:34 -08:00
|
|
|
if (obj->prev->clipper != old_clip)
|
|
|
|
eo_do(old_clip->object, eo_event_callback_del(EO_BASE_EVENT_DEL, _clipper_del_cb, eo_obj));
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2014-11-12 17:40:16 -08:00
|
|
|
|
|
|
|
/* image object clipper */
|
|
|
|
if (clip->type == o_image_type)
|
|
|
|
{
|
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_mask_cow, clip->mask, Evas_Object_Mask_Data, mask)
|
|
|
|
mask->is_mask = EINA_TRUE;
|
|
|
|
EINA_COW_WRITE_END(evas_object_mask_cow, clip->mask, mask);
|
|
|
|
}
|
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
/* clip me */
|
2013-03-12 05:58:19 -07:00
|
|
|
if ((!clip->clip.clipees) && (clip->cur->visible))
|
2004-09-21 21:37:51 -07:00
|
|
|
{
|
2012-09-11 04:43:17 -07:00
|
|
|
/* Basically it just went invisible */
|
|
|
|
clip->changed = 1;
|
2013-04-26 11:01:44 -07:00
|
|
|
e = clip->layer->evas;
|
|
|
|
e->changed = 1;
|
2014-04-16 00:14:16 -07:00
|
|
|
/* i know this was to handle a case where a clip starts having children and
|
|
|
|
* stops being a solid colored box - no one ever does that... they hide the clp
|
|
|
|
* so dont add damages
|
2013-04-26 11:01:44 -07:00
|
|
|
evas_damage_rectangle_add(e->evas,
|
|
|
|
clip->cur->geometry.x + e->framespace.x,
|
|
|
|
clip->cur->geometry.y + e->framespace.y,
|
2013-03-12 05:58:19 -07:00
|
|
|
clip->cur->geometry.w, clip->cur->geometry.h);
|
2014-04-16 00:14:16 -07:00
|
|
|
*/
|
2004-09-21 21:37:51 -07:00
|
|
|
}
|
2016-01-27 19:18:34 -08:00
|
|
|
|
2013-03-12 05:58:19 -07:00
|
|
|
EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
|
2016-01-27 19:18:34 -08:00
|
|
|
state_write->clipper = clip;
|
2013-03-12 05:58:19 -07:00
|
|
|
EINA_COW_STATE_WRITE_END(obj, state_write, cur);
|
2016-01-27 19:18:34 -08:00
|
|
|
if (obj->prev->clipper != clip)
|
|
|
|
eo_do(clip->object, eo_event_callback_add(EO_BASE_EVENT_DEL, _clipper_del_cb, eo_obj));
|
2013-03-12 05:58:19 -07:00
|
|
|
|
2013-04-10 21:21:54 -07:00
|
|
|
clip->clip.cache_clipees_answer = eina_list_free(clip->clip.cache_clipees_answer);
|
|
|
|
clip->clip.clipees = eina_list_append(clip->clip.clipees, obj);
|
2012-05-01 00:31:42 -07:00
|
|
|
if (clip->clip.clipees)
|
|
|
|
{
|
2013-03-12 05:58:19 -07:00
|
|
|
EINA_COW_STATE_WRITE_BEGIN(clip, state_write, cur)
|
|
|
|
{
|
|
|
|
state_write->have_clipees = 1;
|
|
|
|
}
|
|
|
|
EINA_COW_STATE_WRITE_END(clip, state_write, cur);
|
|
|
|
|
2012-05-01 00:31:42 -07:00
|
|
|
if (clip->changed)
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_update_bounding_box(eo_clip, clip);
|
2012-05-01 00:31:42 -07:00
|
|
|
}
|
2011-04-05 22:38:38 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_change(eo_clip, clip);
|
|
|
|
evas_object_change(eo_obj, obj);
|
|
|
|
evas_object_clip_dirty(eo_obj, obj);
|
2013-04-06 22:00:10 -07:00
|
|
|
evas_object_recalc_clippees(obj);
|
2012-10-08 18:58:41 -07:00
|
|
|
if ((!obj->is_smart) &&
|
2013-01-21 19:56:00 -08:00
|
|
|
(!((obj->map->cur.map) && (obj->map->cur.usemap))))
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
if (evas_object_is_in_output_rect(eo_obj, obj,
|
2012-09-11 04:43:17 -07:00
|
|
|
obj->layer->evas->pointer.x,
|
|
|
|
obj->layer->evas->pointer.y, 1, 1))
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_event_feed_mouse_move(obj->layer->evas->evas,
|
2012-09-11 04:43:17 -07:00
|
|
|
obj->layer->evas->pointer.x,
|
|
|
|
obj->layer->evas->pointer.y,
|
|
|
|
obj->layer->evas->last_timestamp,
|
|
|
|
NULL);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_clip_across_check(eo_obj, obj);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2014-03-11 04:51:35 -07:00
|
|
|
EOLIAN Evas_Object *
|
|
|
|
_evas_object_clip_get(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2013-04-06 22:00:10 -07:00
|
|
|
if (obj->cur->clipper)
|
2014-03-11 04:51:35 -07:00
|
|
|
return obj->cur->clipper->object;
|
|
|
|
return NULL;
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
|
|
|
|
2014-03-11 04:51:35 -07:00
|
|
|
EOLIAN void
|
|
|
|
_evas_object_clip_unset(Eo *eo_obj, Evas_Object_Protected_Data *obj)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2013-03-12 05:58:19 -07:00
|
|
|
if (!obj->cur->clipper) return;
|
2015-02-10 03:44:38 -08:00
|
|
|
evas_object_async_block(obj);
|
2013-04-10 21:21:54 -07:00
|
|
|
obj->clip.cache_clipees_answer = eina_list_free(obj->clip.cache_clipees_answer);
|
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
/* unclip */
|
2013-08-28 18:53:48 -07:00
|
|
|
if (evas_object_intercept_call_clip_unset(eo_obj, obj)) return;
|
2012-10-08 18:58:41 -07:00
|
|
|
if (obj->is_smart)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
eo_do(eo_obj, evas_obj_smart_clip_unset());
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2013-03-12 05:58:19 -07:00
|
|
|
if (obj->cur->clipper)
|
2006-09-08 10:59:19 -07:00
|
|
|
{
|
2016-01-27 19:18:34 -08:00
|
|
|
Evas_Object_Protected_Data *old_clip = obj->cur->clipper;
|
|
|
|
|
2013-04-10 21:21:54 -07:00
|
|
|
obj->cur->clipper->clip.clipees = eina_list_remove(obj->cur->clipper->clip.clipees, obj);
|
2013-03-12 05:58:19 -07:00
|
|
|
if (!obj->cur->clipper->clip.clipees)
|
2012-09-11 04:43:17 -07:00
|
|
|
{
|
2013-03-12 05:58:19 -07:00
|
|
|
EINA_COW_STATE_WRITE_BEGIN(obj->cur->clipper, state_write, cur)
|
|
|
|
{
|
2013-11-03 19:23:25 -08:00
|
|
|
state_write->have_clipees = 0;
|
2013-03-12 05:58:19 -07:00
|
|
|
}
|
|
|
|
EINA_COW_STATE_WRITE_END(obj->cur->clipper, state_write, cur);
|
2014-04-16 00:14:16 -07:00
|
|
|
/* i know this was to handle a case where a clip stops having children and
|
|
|
|
* becomes a solid colored box - no one ever does that... they hide the clip
|
evas/clip: If the clipper is image or has color, clipped area should be redrawn.
Summary:
If the clipper is image or has color, it affects to its clipees.
Even if we unset the clipper or change the clipper to another object,
it seems the clipper is not changed.
Test Plan:
Make two clipper objects and one clipee object.
And make clip the clipee according to following example
ex) Clipee object -> inner_clipper -> clipper
evas_object_clip_set(clipee, inner_clipper);
evas_object_clip_set(inner_clipper, clipper);
After checking the result and hide inner_clipper.
evas_object_clip_set(clipee, clipper);
evas_object_hide(inner_clipper);
See the result.
Reviewers: raster, cedric, Hermet, jpeg
Subscribers: woohyun, cedric
Differential Revision: https://phab.enlightenment.org/D2112
Signed-off-by: Jean-Philippe Andre <jp.andre@samsung.com>
Note: Technically we should not check the color of the fact that
the clipper is a mask and not a simple rect. But because of
real-life performance issues, damage_add was disabled so we're
trying to keep the perf in most cases while being correct in
cases where the clipper is visually important.
2015-03-16 19:02:04 -07:00
|
|
|
* so dont add damages.
|
|
|
|
* But, if the clipper could affect color to its clipees,
|
|
|
|
* the clipped area should be redrawn. */
|
|
|
|
if (((obj->cur->clipper->cur) && (obj->cur->clipper->cur->visible)) &&
|
|
|
|
(((obj->cur->clipper->cur->color.r != 255) || (obj->cur->clipper->cur->color.g != 255) ||
|
|
|
|
(obj->cur->clipper->cur->color.b != 255) || (obj->cur->clipper->cur->color.a != 255)) ||
|
|
|
|
(obj->cur->clipper->mask->is_mask)))
|
2013-04-26 11:01:44 -07:00
|
|
|
{
|
2013-09-24 21:05:41 -07:00
|
|
|
if (obj->cur->clipper->layer)
|
|
|
|
{
|
|
|
|
Evas_Public_Data *e = obj->cur->clipper->layer->evas;
|
|
|
|
evas_damage_rectangle_add(e->evas,
|
|
|
|
obj->cur->clipper->cur->geometry.x + e->framespace.x,
|
|
|
|
obj->cur->clipper->cur->geometry.y + e->framespace.y,
|
|
|
|
obj->cur->clipper->cur->geometry.w,
|
|
|
|
obj->cur->clipper->cur->geometry.h);
|
|
|
|
}
|
2013-04-26 11:01:44 -07:00
|
|
|
}
|
evas/clip: If the clipper is image or has color, clipped area should be redrawn.
Summary:
If the clipper is image or has color, it affects to its clipees.
Even if we unset the clipper or change the clipper to another object,
it seems the clipper is not changed.
Test Plan:
Make two clipper objects and one clipee object.
And make clip the clipee according to following example
ex) Clipee object -> inner_clipper -> clipper
evas_object_clip_set(clipee, inner_clipper);
evas_object_clip_set(inner_clipper, clipper);
After checking the result and hide inner_clipper.
evas_object_clip_set(clipee, clipper);
evas_object_hide(inner_clipper);
See the result.
Reviewers: raster, cedric, Hermet, jpeg
Subscribers: woohyun, cedric
Differential Revision: https://phab.enlightenment.org/D2112
Signed-off-by: Jean-Philippe Andre <jp.andre@samsung.com>
Note: Technically we should not check the color of the fact that
the clipper is a mask and not a simple rect. But because of
real-life performance issues, damage_add was disabled so we're
trying to keep the perf in most cases while being correct in
cases where the clipper is visually important.
2015-03-16 19:02:04 -07:00
|
|
|
|
2014-11-12 17:40:16 -08:00
|
|
|
_evas_object_clip_mask_unset(obj->cur->clipper);
|
2012-09-11 04:43:17 -07:00
|
|
|
}
|
2013-04-06 22:00:10 -07:00
|
|
|
evas_object_change(obj->cur->clipper->object, obj->cur->clipper);
|
2016-01-27 19:18:34 -08:00
|
|
|
|
|
|
|
EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
|
|
|
|
state_write->clipper = NULL;
|
|
|
|
EINA_COW_STATE_WRITE_END(obj, state_write, cur);
|
|
|
|
if (obj->prev->clipper != old_clip)
|
|
|
|
eo_do(old_clip->object, eo_event_callback_del(EO_BASE_EVENT_DEL, _clipper_del_cb, eo_obj));
|
2006-09-08 10:59:19 -07:00
|
|
|
}
|
2013-03-12 05:58:19 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_change(eo_obj, obj);
|
|
|
|
evas_object_clip_dirty(eo_obj, obj);
|
2013-04-06 22:00:10 -07:00
|
|
|
evas_object_recalc_clippees(obj);
|
2012-10-08 18:58:41 -07:00
|
|
|
if ((!obj->is_smart) &&
|
2013-01-21 19:56:00 -08:00
|
|
|
(!((obj->map->cur.map) && (obj->map->cur.usemap))))
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2013-11-03 19:23:25 -08:00
|
|
|
if (evas_object_is_in_output_rect(eo_obj, obj,
|
2012-09-11 04:43:17 -07:00
|
|
|
obj->layer->evas->pointer.x,
|
2013-11-03 19:23:25 -08:00
|
|
|
obj->layer->evas->pointer.y, 1, 1))
|
|
|
|
evas_event_feed_mouse_move(obj->layer->evas->evas,
|
|
|
|
obj->layer->evas->pointer.x,
|
|
|
|
obj->layer->evas->pointer.y,
|
|
|
|
obj->layer->evas->last_timestamp,
|
|
|
|
NULL);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_clip_across_check(eo_obj, obj);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2016-01-27 19:18:34 -08:00
|
|
|
static Eina_Bool
|
|
|
|
_clipper_del_cb(void *data, Eo *eo_clip, const Eo_Event_Description *desc EINA_UNUSED, void *info EINA_UNUSED)
|
|
|
|
{
|
|
|
|
Evas_Object *eo_obj = data;
|
|
|
|
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
|
|
|
|
|
|
|
|
if (!obj) return EO_CALLBACK_CONTINUE;
|
|
|
|
|
|
|
|
_evas_object_clip_unset(eo_obj, obj);
|
|
|
|
if (obj->prev->clipper && (obj->prev->clipper->object == eo_clip))
|
|
|
|
{
|
|
|
|
// not removing cb since it's the del cb... it can't be called again!
|
|
|
|
EINA_COW_STATE_WRITE_BEGIN(obj, state_write, prev)
|
|
|
|
state_write->clipper = NULL;
|
|
|
|
EINA_COW_STATE_WRITE_END(obj, state_write, prev);
|
|
|
|
}
|
|
|
|
|
|
|
|
return EO_CALLBACK_CONTINUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_evas_object_clip_prev_reset(Evas_Object_Protected_Data *obj, Eina_Bool cur_prev)
|
|
|
|
{
|
|
|
|
if (obj->prev->clipper)
|
|
|
|
{
|
|
|
|
Evas_Object_Protected_Data *clip = obj->prev->clipper;
|
|
|
|
if (!cur_prev)
|
|
|
|
{
|
|
|
|
EINA_COW_STATE_WRITE_BEGIN(obj->prev->clipper, state_write, prev)
|
|
|
|
state_write->clipper = NULL;
|
|
|
|
EINA_COW_STATE_WRITE_END(obj->prev->clipper, state_write, prev);
|
|
|
|
}
|
|
|
|
if (clip != obj->cur->clipper)
|
|
|
|
eo_do(clip->object, eo_event_callback_del(EO_BASE_EVENT_DEL, _clipper_del_cb, obj->object));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-11 04:51:35 -07:00
|
|
|
EOLIAN Eina_List *
|
|
|
|
_evas_object_clipees_get(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2013-04-10 21:21:54 -07:00
|
|
|
const Evas_Object_Protected_Data *tmp;
|
|
|
|
Eina_List *l;
|
|
|
|
Eina_List *answer = NULL;
|
|
|
|
|
|
|
|
obj->clip.cache_clipees_answer = eina_list_free(obj->clip.cache_clipees_answer);
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(obj->clip.clipees, l, tmp)
|
|
|
|
answer = eina_list_append(answer, tmp);
|
|
|
|
|
|
|
|
obj->clip.cache_clipees_answer = answer;
|
2014-03-11 04:51:35 -07:00
|
|
|
return answer;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2012-09-11 04:43:17 -07:00
|
|
|
|
2014-03-11 04:51:35 -07:00
|
|
|
EOLIAN Eina_Bool
|
|
|
|
_evas_object_clipees_has(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
|
2013-04-10 21:21:54 -07:00
|
|
|
{
|
2014-03-11 04:51:35 -07:00
|
|
|
return (obj->clip.clipees ? EINA_TRUE : EINA_FALSE);
|
2013-04-10 21:21:54 -07:00
|
|
|
}
|
|
|
|
|
2015-05-12 01:37:01 -07:00
|
|
|
EOLIAN void
|
|
|
|
_evas_object_no_render_set(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj, Eina_Bool enable)
|
|
|
|
{
|
|
|
|
obj->no_render = enable;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN Eina_Bool
|
|
|
|
_evas_object_no_render_get(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
|
|
|
|
{
|
|
|
|
return obj->no_render;
|
|
|
|
}
|