Handling different input events on same objects?

edited June 2012 in Help request
I just wanted to run this by everyone and see if I have the best idea or the craziest one :)

Here's the level select screen for Equilibria: http://i.imgur.com/llLV4.jpg

In that screen, each of the little numbered cells represents a game level.

This screen has to handle both a "swipe" gesture and a "tap" gesture. If any of that space area containing the little cells is swiped left or right with the finger, the game switches between the "pages" of levels. On the other hand, if any of the cells is tapped with the finger, it starts the game on that level.

The swipe has to be recognized by a large rectangular area on the screen, so I handle the swipe gesture input (by a user defined Orx event) on a large, rectangular Orx object with alpha 0. The problem this has introduced is the "tap" event is no longer recognized by the cells because the orxObject_Pick function always finds the "swipe area" object which is topmost in Z-order.

My best idea so far is to write a orxObject_PickAll function to get a list of Orx objects sorted by Z-order under the finger when a tap event is received, then pass the input event to each of the the objects until one of them handles it.

Good idea, or crazy? :) Has anyone else done this in a better way?

Comments

  • edited June 2012
    Can't you grab the 'swipe' gesture with a 'general' EventHandler, not specified to any object (e.g. handling ALL swipe requests, at least for that page) while setting up the tap gestures to each individual objects?

    At least for this specific example?
  • edited June 2012
    Yep, I certainly could for this example. And that's an alternative I've been considering.

    There are already at least three screens in the game where I need to handle a swipe gesture, though, so I need to determine how to handle it on a screen-by-screen basis.

    Up to this point, I have had a nice system where I specify the Tap event handler actions (e.g. "DeleteObject") for each Orx object in config, and then use an event handler in code to handle each action.

    I was hoping to do this with the swipe gesture as well so everything is handled in a similar way :)
  • edited June 2012
    Considering you want to 'swipe' the 'page' - which includes all objects on the page by definition...

    Another option would be to create/use the hierarchy and if an object doesn't handle the input (the swipe in this case) go up a level, and repeat.

    That way you can define a 'page' including all the elements on that page, with a swipe input, and the elements themselves with a tap input.
  • edited June 2012
    Gemberkoekje wrote:
    Considering you want to 'swipe' the 'page' - which includes all objects on the page by definition...

    Not quite.. you swipe an area of the screen containing a bunch of objects. The entire screen shouldn't necessarily handle the swipe. So far, I've thought of the swipe area as a rectangular object on the screen, but not necessarily occupying the whole screen.
    Another option would be to create/use the hierarchy and if an object doesn't handle the input (the swipe in this case) go up a level, and repeat.

    That way you can define a 'page' including all the elements on that page, with a swipe input, and the elements themselves with a tap input.

    I think that's similar to what I concluded, too, with my idea to pick all the objects under the finger and allow them the option of handling events based on their Z-order.

    I appreciate your input. It's helping me to think it through. I'll let you know what I end up doing.
  • edited June 2012
    Yes, i think we're on a similar page, with a different actual solution XD - that's perfectly fine though.

    I was thinking something along these lines:
    [subpage]
    level1button#level2button
    
    [level1button]
    graphic =
    
    

    and then in the userdata function:
    bool eventhandler(event)
    {
    If(event.swipe) return false
    Else handle event
    Return true;
    }
    

    finally in the general static eventhandler:
    if(object->eventhandler() == false)
    {
    Object->parent->eventhandler();
    }
    

    of course, you want to do this recursively and only if the object has a valid parent, so don't copy this code, but i hope you understand my drift.
  • edited June 2012
    the usual solution for this is the delegate pattern,

    your "ScrollView" which handle the swipe gestures should be on top of your "Tappable" objects.

    since the scrollview is on top, it will be the object you retrieve with orxObject_Pick(), and your handler should be able to decide if the stream of events it gets should be used for scrolling the content or if it should be dispatched to its "tappable" objects.

    I think there is functions in orx to find out if a point (from the touch event) is inside an objects to help you dispatch the events to right object.

    or you can re-issue the orxObject_Pick() with a .fZ just under the scrollview.

    hope it will help.
  • edited June 2012
    That's the final little bit I was missing! Now it's obvious.

    If I receive a tap event, I pick the object and see if it handles the event. If it does, I handle and exit handler. If it doesn't, I pick again with a Z coord 0.001 higher than before.

    Works great and only required a tiny code modification. Thanks!
  • edited June 2012
    I used to do exactly that but I'm now using the object hierarchy to transmit events/inputs. Works in a very similar fashion though, so it's more of a personal taste matter.
  • edited June 2012
    Any details on how you use the object hierarchy? Do you do something like orxObject_GetChild and test Z-order?
  • edited June 2012
    Yes, I use the GetOwnedChild/GetOwnedSibling to traverse the hierarchy and I don't use the Z component at all.
Sign In or Register to comment.