@@ -1193,20 +1193,37 @@ bool scene_obj_within(const struct scene *scn, struct scene_obj *obj, int x,
return within;
}
-struct scene_obj *scene_find_obj_within(const struct scene *scn, int x, int y)
+struct scene_obj *scene_find_obj_within(const struct scene *scn, int x, int y,
+ bool reverse)
{
struct scene_obj *obj;
- log_debug("within: x %d y %d\n", x, y);
- list_for_each_entry(obj, &scn->obj_head, sibling) {
- log_debug(" - obj %d '%s' can_highlight %d within %d\n",
- obj->id, obj->name, scene_obj_can_highlight(obj),
- scene_obj_within(scn, obj, x, y));
- if (scene_obj_can_highlight(obj) &&
- scene_obj_within(scn, obj, x, y)) {
- log_debug("- returning obj %d '%s'\n", obj->id,
- obj->name);
- return obj;
+ log_debug("within: x %d y %d reverse %d\n", x, y, reverse);
+ if (reverse) {
+ list_for_each_entry_reverse(obj, &scn->obj_head, sibling) {
+ log_debug(" - obj %d '%s' can_highlight %d within %d\n",
+ obj->id, obj->name,
+ scene_obj_can_highlight(obj),
+ scene_obj_within(scn, obj, x, y));
+ if (scene_obj_can_highlight(obj) &&
+ scene_obj_within(scn, obj, x, y)) {
+ log_debug("- returning obj %d '%s'\n", obj->id,
+ obj->name);
+ return obj;
+ }
+ }
+ } else {
+ list_for_each_entry(obj, &scn->obj_head, sibling) {
+ log_debug(" - obj %d '%s' can_highlight %d within %d\n",
+ obj->id, obj->name,
+ scene_obj_can_highlight(obj),
+ scene_obj_within(scn, obj, x, y));
+ if (scene_obj_can_highlight(obj) &&
+ scene_obj_within(scn, obj, x, y)) {
+ log_debug("- returning obj %d '%s'\n", obj->id,
+ obj->name);
+ return obj;
+ }
}
}
log_debug("- no object\n");
@@ -1238,7 +1255,7 @@ static void send_click_obj(struct scene *scn, struct scene_obj *obj, int x,
}
log_debug("no object; finding...\n");
- obj = scene_find_obj_within(scn, x, y);
+ obj = scene_find_obj_within(scn, x, y, false);
if (obj) {
event->type = EXPOACT_POINT_OPEN;
event->select.id = obj->id;
@@ -1264,7 +1281,7 @@ static int scene_click_popup(struct scene *scn, int x, int y,
}
/* check that the click is within our object */
- chk = scene_find_obj_within(scn, x, y);
+ chk = scene_find_obj_within(scn, x, y, false);
log_debug("chk %d '%s' (obj %d '%s')\n", chk ? chk->id : -1,
chk ? chk->name : "(none)", obj->id, obj->name);
if (!chk) {
@@ -1323,7 +1340,7 @@ int scene_send_click(struct scene *scn, int x, int y, struct expo_action *event)
return 0;
}
- obj = scene_find_obj_within(scn, x, y);
+ obj = scene_find_obj_within(scn, x, y, false);
log_debug("non-popup obj %d '%s'\n", obj ? obj->id : -1,
obj ? obj->name : "(none)");
if (!obj)
@@ -562,8 +562,11 @@ const char *scene_obj_type_name(enum scene_obj_t type);
* @scn: Scene to check
* @x: X coordinates of the click
* @y: Y coordinate of the click
+ * @reverse: true to search from top to bottom (reverse order), false for
+ * bottom to top
* Return: object that is being clicked on, NULL if none
*/
-struct scene_obj *scene_find_obj_within(const struct scene *scn, int x, int y);
+struct scene_obj *scene_find_obj_within(const struct scene *scn, int x, int y,
+ bool reverse);
#endif /* __SCENE_INTERNAL_H */
@@ -1289,19 +1289,19 @@ static int expo_find_obj_within(struct unit_test_state *uts)
* Check finding a menu by 'clicking' on a menu item label - menu items
* are at (50,436) for ITEM1 and (50,454) for ITEM2
*/
- obj = scene_find_obj_within(scn, 60, 440);
+ obj = scene_find_obj_within(scn, 60, 440, false);
ut_assertnonnull(obj);
ut_asserteq(OBJ_MENU, obj->id);
/* logo and text are not highlightable, so they should not be found */
- ut_assertnull(scene_find_obj_within(scn, 60, 30));
- ut_assertnull(scene_find_obj_within(scn, 410, 110));
+ ut_assertnull(scene_find_obj_within(scn, 60, 30, false));
+ ut_assertnull(scene_find_obj_within(scn, 410, 110, false));
/* empty space */
- ut_assertnull(scene_find_obj_within(scn, 10, 10));
+ ut_assertnull(scene_find_obj_within(scn, 10, 10, false));
/* way outside bounds */
- ut_assertnull(scene_find_obj_within(scn, 9999, 9999));
+ ut_assertnull(scene_find_obj_within(scn, 9999, 9999, false));
abuf_uninit(&buf);
abuf_uninit(&logo_copy);