This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository efl.
View the commit online.
commit 60b97bbe66cff8a5ab9e3975da2b4e92d80873f9
Author: Carsten Haitzler <ras...@rasterman.com>
AuthorDate: Mon Feb 10 14:08:02 2025 +0000
evas - object - add event regions to objects
@feat
---
src/lib/evas/canvas/efl_canvas_object.eo | 20 ++++++++
src/lib/evas/canvas/efl_canvas_object_eo.legacy.c | 12 +++++
src/lib/evas/canvas/efl_canvas_object_eo.legacy.h | 32 +++++++++++++
src/lib/evas/canvas/evas_events.c | 58 ++++++++++++++++++++---
src/lib/evas/canvas/evas_object_main.c | 27 +++++++++++
src/lib/evas/include/evas_private.h | 2 +
6 files changed, 144 insertions(+), 7 deletions(-)
diff --git a/src/lib/evas/canvas/efl_canvas_object.eo b/src/lib/evas/canvas/efl_canvas_object.eo
index 64aad581ea..8e90ab99f2 100644
--- a/src/lib/evas/canvas/efl_canvas_object.eo
+++ b/src/lib/evas/canvas/efl_canvas_object.eo
@@ -321,6 +321,26 @@ abstract Efl.Canvas.Object extends Efl.Loop_Consumer implements Efl.Gfx.Entity,
($false).]]
}
}
+ @property event_rects @beta {
+ [[ A series of rectangles relative to object top-left that define
+ the input seriface area of the object instead of the normal
+ full object geometry itself. The object geometry itself acts
+ implicitly as a master clip to this set of rects if they are
+ outside the bounds of the object geometry. If set to a NULL
+ array, the rectangle region set is cleared and normal behavior
+ resumes.
+
+ The array of rectangles is terminated by a rectangle of geometry
+ 0,0 0x0.
+ ]]
+ set {
+ }
+ get {
+ }
+ values {
+ region: ptr(const(Eina.Rect)); [[ The rects in the region ]]
+ }
+ }
@property anti_alias {
[[Whether or not the given Evas object is to be drawn
anti-aliased.
diff --git a/src/lib/evas/canvas/efl_canvas_object_eo.legacy.c b/src/lib/evas/canvas/efl_canvas_object_eo.legacy.c
index 2d9a5a0682..e4a272a329 100644
--- a/src/lib/evas/canvas/efl_canvas_object_eo.legacy.c
+++ b/src/lib/evas/canvas/efl_canvas_object_eo.legacy.c
@@ -84,6 +84,18 @@ evas_object_pass_events_get(const Efl_Canvas_Object *obj)
return efl_canvas_object_pass_events_get(obj);
}
+EVAS_API void
+evas_object_event_rects_set(Efl_Canvas_Object *obj, const Eina_Rect *region)
+{
+ efl_canvas_object_event_rects_set(obj, region);
+}
+
+EVAS_API const Eina_Rect *
+evas_object_event_rects_get(const Efl_Canvas_Object *obj)
+{
+ return efl_canvas_object_event_rects_get(obj);
+}
+
EVAS_API void
evas_object_anti_alias_set(Efl_Canvas_Object *obj, Eina_Bool anti_alias)
{
diff --git a/src/lib/evas/canvas/efl_canvas_object_eo.legacy.h b/src/lib/evas/canvas/efl_canvas_object_eo.legacy.h
index c78d89d48c..524b64208f 100644
--- a/src/lib/evas/canvas/efl_canvas_object_eo.legacy.h
+++ b/src/lib/evas/canvas/efl_canvas_object_eo.legacy.h
@@ -320,6 +320,38 @@ EVAS_API void evas_object_pass_events_set(Efl_Canvas_Object *obj, Eina_Bool pass
*/
EVAS_API Eina_Bool evas_object_pass_events_get(const Efl_Canvas_Object *obj);
+/**
+ * @brief Set the event region in rects of an object
+ *
+ * @param[in] obj The object.
+ * @param[in] region The rectangles (Eina_Rect) or NULL to reset.
+ *
+ * The region is an array of rectangles which is "null" terminated by a
+ * rectangkle at the end being 0, 0 0x0 (all 0's).
+ *
+ * @since 1.29
+ *
+ * @see evas_object_event_rects_get()
+ *
+ * @ingroup Evas_Object_Group
+ */
+EVAS_API void evas_object_event_rects_set(Efl_Canvas_Object *obj, const Eina_Rect *region);
+
+/**
+ * @brief Get the event region in rects of an object
+ *
+ * @param[in] obj The object.
+ *
+ * @return The rectangles (Eina_Rect) or NULL when default object area used
+ *
+ * @since 1.29
+ *
+ * @see evas_object_event_rects_set()
+ *
+ * @ingroup Evas_Object_Group
+ */
+EVAS_API const Eina_Rect *evas_object_event_rects_get(const Efl_Canvas_Object *obj);
+
/**
* @brief Sets whether or not the given Evas object is to be drawn
* anti-aliased.
diff --git a/src/lib/evas/canvas/evas_events.c b/src/lib/evas/canvas/evas_events.c
index c76fb52de1..29a6c9f02a 100644
--- a/src/lib/evas/canvas/evas_events.c
+++ b/src/lib/evas/canvas/evas_events.c
@@ -49,7 +49,8 @@ static inline Eina_Bool
_evas_event_object_pointer_allow_precise(Eo *eo_obj, Evas_Object_Protected_Data *obj, int x, int y, const Eina_List *ins)
{
return eina_list_data_find(ins, eo_obj) &&
- ((!obj->precise_is_inside) || evas_object_is_inside(eo_obj, obj, x, y));
+ (((!obj->precise_is_inside) && (!obj->event_rects)) ||
+ evas_object_is_inside(eo_obj, obj, x, y));
}
#define EVAS_EVENT_FEED_SAFETY_CHECK(evas) _evas_event_feed_check(evas)
@@ -260,7 +261,8 @@ _evas_event_object_list_raw_in_get_single(Evas *eo_e, Evas_Object_Protected_Data
Evas_Object_Protected_Data *clip = obj->cur->clipper;
int norep = 0;
- if (clip && clip->mask->is_mask && clip->precise_is_inside)
+ if (clip && clip->mask->is_mask && clip->precise_is_inside &&
+ (!clip->event_rects))
if (!evas_object_is_inside(clip->object, clip, x, y))
return in;
@@ -339,7 +341,8 @@ _evas_event_object_list_raw_in_get_single(Evas *eo_e, Evas_Object_Protected_Data
else
{
Evas_Object_Protected_Data *clip = obj->cur->clipper;
- if (clip && clip->mask->is_mask && clip->precise_is_inside)
+ if (clip && clip->mask->is_mask && clip->precise_is_inside &&
+ (!clip->event_rects))
inside = evas_object_is_inside(clip->object, clip, x, y);
else
inside = evas_object_is_in_output_rect(eo_obj, obj, x, y, 1, 1);
@@ -356,7 +359,7 @@ _evas_event_object_list_raw_in_get_single(Evas *eo_e, Evas_Object_Protected_Data
}
}
}
- if (inside && ((!obj->precise_is_inside) ||
+ if (inside && (((!obj->precise_is_inside) && (!obj->event_rects)) ||
(evas_object_is_inside(eo_obj, obj, x, y))))
{
if (!evas_event_freezes_through(eo_obj, obj))
@@ -3970,9 +3973,10 @@ _feed_mouse_move_eval_internal(Eo *eo_obj, Evas_Object_Protected_Data *obj)
in_output_rect = evas_object_is_in_output_rect(eo_obj, obj, pdata->seat->x,
pdata->seat->y, 1, 1);
if ((in_output_rect) &&
- ((!obj->precise_is_inside) || (evas_object_is_inside(eo_obj, obj,
- pdata->seat->x,
- pdata->seat->y))))
+ (((!obj->precise_is_inside) && (!obj->event_rects)) ||
+ (evas_object_is_inside(eo_obj, obj,
+ pdata->seat->x,
+ pdata->seat->y))))
{
_canvas_event_feed_mouse_move_legacy(evas->evas, evas,
pdata->seat->x, pdata->seat->y,
@@ -4044,6 +4048,46 @@ _efl_canvas_object_pass_events_get(const Eo *eo_obj EINA_UNUSED, Evas_Object_Pro
return obj->pass_events;
}
+EOLIAN void
+_efl_canvas_object_event_rects_set(Eo *obj, Evas_Object_Protected_Data *pd, const Eina_Rect *region)
+{
+ Eina_Rect *new_rects;
+ const Eina_Rect *r;
+ int n = 0;
+
+ if ((!region) && (!pd->event_rects)) return;
+ if (pd->event_rects)
+ {
+ free(pd->event_rects);
+ pd->event_rects = NULL;
+ }
+ if (region)
+ {
+ // count rects
+ for (r = region; ; r++, n++)
+ {
+ if ((r->x | r->y | r->w | r->h) == 0) break;
+ }
+ n++; // need 1 more slot for 0 0 0x0 rect
+ // alloc new rects
+ new_rects = malloc(n * sizeof(Eina_Rect));
+ if (!new_rects) return; // EEK
+ // fll it in
+ memcpy(new_rects, region, n * sizeof(Eina_Rect));
+ // nuke old ones
+ // store new rects
+ pd->event_rects = new_rects;
+ }
+ // reprocess in/out mouse and events
+ _feed_mouse_move_eval_internal(obj, pd);
+}
+
+EOLIAN const Eina_Rect *
+_efl_canvas_object_event_rects_get(const Eo *obj EINA_UNUSED, Evas_Object_Protected_Data *pd)
+{
+ return pd->event_rects;
+}
+
EOLIAN void
_efl_canvas_object_repeat_events_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, Eina_Bool repeat)
{
diff --git a/src/lib/evas/canvas/evas_object_main.c b/src/lib/evas/canvas/evas_object_main.c
index e1b5839957..4f16a9540a 100644
--- a/src/lib/evas/canvas/evas_object_main.c
+++ b/src/lib/evas/canvas/evas_object_main.c
@@ -510,6 +510,11 @@ evas_object_free(Evas_Object_Protected_Data *obj, Eina_Bool clean_layer)
{
EVAS_MEMPOOL_FREE(_mp_sh, obj->size_hints);
}
+ if (obj->event_rects)
+ {
+ free(obj->event_rects);
+ obj->event_rects = NULL;
+ }
eina_cow_free(evas_object_proxy_cow, (const Eina_Cow_Data**) &obj->proxy);
eina_cow_free(evas_object_map_cow, (const Eina_Cow_Data**) &obj->map);
eina_cow_free(evas_object_state_cow, (const Eina_Cow_Data**) &obj->cur);
@@ -862,10 +867,29 @@ evas_object_was_opaque(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
return 0;
}
+static int
+evas_object_is_inside_event_rects(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj, Evas_Coord x, Evas_Coord y)
+{
+ Evas_Coord rx, ry;
+ const Eina_Rect *r;
+
+ rx = x - obj->cur->geometry.x;
+ ry = y - obj->cur->geometry.y;
+ for (r = obj->event_rects;; r++)
+ {
+ if ((r->x | r->y | r->w | r->h) == 0) break;
+ if (eina_rectangle_coords_inside(&(r->rect), rx, ry)) return 1;
+ }
+ return 0;
+}
+
int
evas_object_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, Evas_Coord x, Evas_Coord y)
{
if (obj->is_smart) return 0;
+ if ((obj->event_rects) &&
+ (!evas_object_is_inside_event_rects(eo_obj, obj, x, y)))
+ return 0;
if (obj->func->is_inside)
return obj->func->is_inside(eo_obj, obj, obj->private_data, x, y);
return 0;
@@ -875,6 +899,9 @@ int
evas_object_was_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, Evas_Coord x, Evas_Coord y)
{
if (obj->is_smart) return 0;
+ if ((obj->event_rects) &&
+ (!evas_object_is_inside_event_rects(eo_obj, obj, x, y)))
+ return 0;
if (obj->func->was_inside)
return obj->func->was_inside(eo_obj, obj, obj->private_data, x, y);
return 0;
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 3af4addc57..5a4b447ee9 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -724,6 +724,8 @@ struct _Evas_Object_Protected_Data
Evas_Size_Hints *size_hints;
+ Eina_Rect *event_rects;
+
int last_mouse_down_counter;
int last_mouse_up_counter;
int last_event_id;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.