Events are the principal way in which you create interactive applications. They are a way of triggering responses in your program. For example, you can turn any display object into an interactive button. This flexibility is of the most unique things about the Corona SDK.
Some events are broadcast, such as "enterFrame", "system", "orientation", etc. These events are global in nature because they are not directed at any particular object. Rather, they are broadcast to all interested listeners. The following is from the Orientation sample code. It demonstrates how your app can respond to orientation changes:
local label = display.newText( "portrait", 0, 0, nil, 30 ) label:setTextColor( 255,255,255 ) label.x = display.stageWidth/2; label.y = display.stageHeight/2 local function onOrientationChange( event ) label.text = event.type -- change text to reflect current orientation -- rotate text so it remains upright local newAngle = label.rotation - event.delta transition.to( label, { time=150, rotation=newAngle } ) end Runtime:addEventListener( "orientation", onOrientationChange )
Local events are sent to a single listener and are not broadcast.
When the user’s finger touches the screen, a hit event is generated and dispatched to display objects in the display hierarchy. By default, only those objects that intersect the hit location (the location of the finger on the screen) will be dispatched the event.
The events propagate through these objects in a particular order. By default, the first object in the display hierarchy to receive the event is the top-most display object that intersects the hit location; the next object is the next top-most object intersecting the hit location; and so on.
Hit events propagate until they are handled. You can stop propagation to the next object (all listeners of the current object still get the event) by telling the system that the event was handled. This boils down to making a listener return true. If at least one of the listeners of the current object returns true, event propagation ends; the next object will not get the event. If the event is still unhandled at the end of this traversal, it is broadcast as a global event to the global Runtime object.
Hit events are kind of a hybrid of local and global events. They are dispatched to a single display object at a time, but any listener of that object will be dispatched the event if it registered to receive that event.
You can redirect future hit events to go to a specific display object by setting the focus. Consider the situation of a rollover button. When a user presses on a button, the button should change its appearance in some way to indicate that the user is touching the button. If the user initially presses on the button and (without lifting) moves the finger off the button, the button should change to its original appearance.
This is very difficult to achieve using the default dispatch behavior and propagation rules of hit events. When a display object representing a rollover button is initially “hit”, we would like future events to go to it until the user lifts their finger off the screen. The way to achieve this is to set the focus on the display object. This instructs the system to deliver all future hit events to that display object:
function button:touch( event ) local phase = event.phase if "began" == phase then -- Subsequent touch events will target button even if they are -- outside the stageBounds of button display.getCurrentStage():setFocus( self ) else ... end return true end
See the Button sample code for a complete example.
Listener can be either functions or a table (objects). In either case an event argument is always passed to the listener. Each kind of event stores different properties available for use.
| Function Listener | Table Listener |
|---|---|
local function listener( event ) print("Call #"..event.count ) end timer.performWithDelay( 1000, listener, 5 ) |
local listener = {} function listener:timer( event ) print("Call #"..event.count ) end timer.performWithDelay( 1000, listener, 5 ) |
Events are registered with the target using the addEventListener object method. You pass the string name of the event you want to be notified of and the listener (function or table) that should handle that event. Often, the listener will be the same as the object as in the examples shown in Basic Interactivity.
All events have a name property that corresponds to the name you use to register the event.
Heya,
I was hunting around in the documentation for a description of what might happen if I assign multiple handlers for the same event to the same listener.
For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | man = display.newImage("man.png") local function punched (event) print ("punched") return false end man:addEventListener("touch",poke) local function pinch (event) print ("pinched") return false end man:addEventListener("touch",pinch) |
Is there any agreed way on that will behave? What will happen if I define a new method "pinch" in a different scope and add that to the "man" table to listen for touches?
If they all fire (as none intercepts the touch event) is there a agreed orderer in which the functions will be visited by the event?
Thanks,
This page could be explained a bit more clearly with the aid of a diagram showing the path of an event in relation to objects.
I could use some help on this from someone with more experience.
I'm finding that even though I am indicating that an event has been handled by having the listener return true, the event is still getting propagated to the next object.
For example, I have a touch listener on a (button) image. When the button is pressed I remove the image completely and display a different image in the same place with the same size and setup a listener on it, and then return true. When this new button is touched I remove it, re-display the previous image and setup a listener on it, and return true. Basically this is a button that toggles its look and functionality.
What happens in both cases though is that the event propagates through to the new button and its listener, which is not the desired behavior.
BTW - if the images (buttons) are displayed in different locations the events are not propagated.
Any help would be greatly appreciated.
Thanks.
The English in the last sentence of the paragraph below is clear....
"Hit events are kind of a hybrid of local and global events. They are dispatched to a single display object at a time, but any listener of that object will be dispatched the event if it registered to receive that event."
but the intended meaning eludes me.
the "any listener" phrase implies that I can have MULTIPLE touch events registered to the same object (and that may be true) but I've not seen that clearly documented anywhere. Also implied is that all such listeners get called at (roughly) the same time...can you clarify?
Next, this http://developer.anscamobile.com/content/events-and-listeners says that "touch events are not broadcast globally" which seems to (kind of) contradict that runtime CAN be given a touch listener.
Finally, if you setfocus on an object, but DO NOT return true from the listener, does the event get propagated to any (if one exists) runtime touch listener?? The docs say clearly that it won't get propagated to other objects at the hit coordinates but it's not as clear about whether runtime will get it or not?