Different layers in Corona/Lua - events

I've got a question about layering images/buttons with Corona/Lua. If I create one button on top of another one and then click it, both buttons' events are triggered. How do I prevent this?
Thanks, Elliot Bonneville
EDIT: Here's how I create the buttons:
button1 = display.newImage("button1.png")
button1:addEventListener("tap", Button1Call)
button2 = display.newImage("button2.png")
button2:addEventListener("tap", Button2Call)

Return true from the event handling function. Touch events keep propagating through the listeners until handled; it's explained here:
http://developer.anscamobile.com/content/events-and-listeners#Touch_Events
Note that the event listeners must be listening for the same event. In other words, both listeners must be set on either "touch" or "tap". Literally last night I was tripped up by this; I had a button listening to "touch" and another image on top listening to "tap" and was wondering why the button was still receiving events.

Use return true in the event handler where you handle the event to prevent further event propagation.
So, in your example, button2 will get the event first, since it's created last. If you handle the event in Button2Call andreturn true, Button1Call won't see the event at all. If you return false, or simply leave out the return statement altogether, Button1Call will get the event and can decide whether to handle it.

Related

Monitor Appointment Cancel Event

I am trying to run some code upon cancellation of an AppointmentItem, however two of the events that I tried to capture fire more than once (Application.Send, AppointmentItem.Write, BeforeDelete doesn't fire). This bring me to re-think my logic and find a suitable place to implement it. I couldn't find a reason why the two events are fired twice in my case as I am using inspector wrapper to register these events on a new inspector window and Un-registering them on inspector close event.
Please note that I want to monitor all possible scenario where an Appointment can be canceled/deleted.
Why do you even need any inspector events? Monitor the Application.ItemSend event, check if you get a MeetingItem object as an argument, check that the message class is "IPM.Schedule.Meeting.Resp.Neg" or Class = 55 (OlObjectClass.olMeetingResponseNegative).

Doing something during a button is pressed in Windows Phone

How can I do something (I want to increment a variable and display it on the screen) during someone pressed the button. Actually there is no event called OnPressed for a button in Windows Phone.
The Button has a Click event that you can handle and use to perform your logic.
In order to execute logic for the duration of the press, handle the ManipulationStarted and ManipulationEnded events.
In addition to the click event, you can use Tap event.
The problem is that your button will handle the event and prevent it from bubbling - if that wasn't the case you could use MouseLeftButtonDown/Up events to do this.
However there is a way to get around this and still get the event by using the more tedious UIElement.AddHandler method.
Ex:
myButton.AddHandler(UIElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler(myMouseEventHandlerMethod), true);
The last bit ('true') is important since this overrides the event bubbling. 'myMouseEventHandlerMethod' is the method that you usually would use for handling a MouseLeftButtonDown event.
Handling 'Up' is the same thing. You probably also want to handle "Leave", or use CaptureMouse() when down triggers.

WP7 controls: When to set VisualState after recovering from Tombstone?

My question is simple: WHEN (on what event?) can I be sure that a control has fully loaded and has its states and templates also?
Why am I asking:
I'm trying to restore the state of my own WP7 control after recovering from tombstone. This control looks like a calendar in a weekly view. In this calendar you can select many items displayed as colored Rectangles.
If I select any of them, and then go to tombstone and come back to the page, it seems like my control forgot which Rectangles were selected. In fact, it did NOT forget the data itself, but the Rectangles forgot their selected state.
After recovering from tombstone, I try to select the Rectangles by setting their VisualState to "Selected" (which works in any other scenario). I found out, that it fails, because VisualStateManager can't find the "Selected" state.
I know this is tricky, because when coming back from tombstone the controls do not build exactly as in any "normal" case. (for example Bindings and Templates do not apply in the same order) But up until now I could always trust, that when FrameworkElement.Loaded fired, I had my controls ready. Now it seems like VisualState is not. (I tried to set the state from Loaded event handler, but results are the same, VisualStateManager.GoToState returns with false.)
What more can I do?
This is a tricky one! I have also experienced issues where UI events fire before the UI itself is fully constructed, see this blog post for an example. My general approach to this is to handle the LayoutUpdated event, which fires each time the visual tree is updated. You will find that this event fires multiple times, both before and after the Loaded event.
When the Layoutupdated event fires, you can check whether the visual state change has worked, if so, no longer handle the event. If not, keep trying!
Within your loaded event, try the following:
// try to set the state
if (VisualStateManager.GoToState(myControl, "myState") == false)
{
// if failed, wait for the next LayoutUpdated event
EventHandler updateHandler = null;
updateHandler = (s, e2) =>
{
if (VisualStateManager.GoToState(myControl, "myState") == false)
{
myControl.LayoutUpdated -= updateHandler;
}
};
myControl.LayoutUpdated += updateHandler;
}

How to make it so events cannot occur while an event is running in DOJO?

Is there some way I can disable all events until an event is completed in DOJO? For instance I am fading elements and the user can click the event again and it will not complete the last event.
If you control all events that need to be disabled, you could try using a global variable as a "lock" - set it on when you start the animation (and have all events abort if they find this flag triggered) and unset it when it ends.
Javascript is not concurrent (so you don't need to worry about timing issues and having an "actual" lock) but perhaps the fading uses setTimeout behind the scenes (allowing other events to trigger before it is done). If this is the case, just remember that you would need to use the onEnd callback to properly detect when the anim is over
var lock = false;
function my_event_handler(evt){
if(lock) return; //someone else is using the lock;
//perhaps cancel event propagation as well?
lock = true;
dojo.anim({
...
onEnd: function(){
lock = false;
}
});
}
caveat: this is pseudocode off the top of my head. I haven't used dojo animations in a while if you didn't notice already :P
I'm not sure I understand what you mean by events here, but if you want to prevent interaction with elements on a page, you can put up a modal shield... basically a transparent DIV element to capture events, positioned over your content with a high z-index

How flash dispatchEvent really works?

It is said in the docs, that EventDispatcher's dispatchEvent "...dispatches an event into the event flow". The phrase is nice-looking and doesn't really explain anything.
Say, we have two listeners waiting for an event "A" on object "a", so what behaviour do we have to expect on calling:
a.dispatchEvent("A")?
Would both listeners be called immediately, before return from distpatchEvent? Or they will be queued in some internal flash player queue and will be processed by entering the next frame? Can we rely on some defined behaviour of flash player here or the behaviour is undefined? How one should read "dispatches an event to event flow"? The question is important since in practice it affects the control flow of the code.
It all depends on your display list hierarchy.
Flash's event structure is based on its internal event model.
The Stage will be the first object
notified, and then the event will
trickle down the display list until
it reaches its target. This phase is
called the capture phase. To enable it, set useCapture to
true on an event listener. Do note
that it's pointless to do so unless
the object listening is a parent of
the object targeting the event. This
is called event intercepting.
The next phase is the target
phase. This is the behavior most
commonly known with events. The
targeted display object (the one the
has a listener for the event) will
receive the event and carry out the
code in the listener.
The final phase is called the
bubbling phase. This is when the event bubbles up the display list
after the event has been received. Event bubbling is very important for
dispatching custom events, as you'll
need to know how to listen for
events dispatched by an object's
children.
When dispatching an event, I generally use this syntax (Event.CHANGE is just a common example):
Object.dispatchEvent(new Event("CHANGE", true, false));
The Object is the object you're dispatching from. The first parameter is the event you're dispatching. The second is the bubbles parameter. The final is the cancelable property. Event.cancelable is used to prevent the default action of an event (IE: a mouse click) via Event.preventDefault().
Reference:
Chapter 21 of Colin Moock's
Essential Actionscript 3.0
EventDispatcher.dispatchEvent()
Event.cancelable
Just use Signals instead :P
https://github.com/robertpenner/as3-signals/wiki
No but really, they're very easy to use and understand, a great addition to the AS3 toolbox.
You can also learn a lot about how native AS3 events work by reading Rob Penner's critiques (scroll down to bottom of wiki page)

Resources