Reputation: 6215
So I'm trying to build a tool that will allow me and other users to all open the same .swf, and then I as the Admin user am able to interact with mine while they all see my mouse movements and button clicks etc on theirs.
I'm using BlazeDS to manage this and I'm getting data sent back and forth etc - no difficulties there. The issue I'm running into is this:
In an "Admin" instance, I click a button. I capture that X and Y, then tell Blaze to tell my clients to dispatch a Click event at that X and Y. On my client side, I get that data and dispatch a Click event at that X and Y - but the click is actually caught at the stage level. The click on my client side takes place UNDER all of my buttons and other content - so the whole thing fails.
Does this make sense? Is there a way to tell it to start the click event at the top?
Upvotes: 0
Views: 981
Reputation: 41054
If you are unable to architect the loaded swf's to use a better architecture you could try something a little more hackish to get buttons working.
Have a look at the methods getObjectsUnderPoint
and areInaccessibleObjectsUnderPoint
of the DisplayObjectContainer. Combined with hasEventListener
you should be able to emulate what you want.
Here is some untested pseudo-code:
function detectClick(pt:Point):void
{
var objsUnderPoint:Array = containerStage.getObjectsUnderPoint(pt);
var clickable:Array = [];
for each(dispObj:DisplayObject in objsUnderPoint)
{
if(dispObj.hasEventListener(MouseEvent.CLICK))
{
clickable.push(dispObj);
}
}
if(clickable.length)
{
// sort on depth here
// that might be tricky since you'll be looking at grandchildren
// and not just children but it is doable.
var topMostClickable:DisplayObject = ???
topMostClickable.dispatchEvent(new MouseEvent(MouseEvent.CLICK, true, false));
}
}
areInaccessibleObjectsUnderPoint
is important if you think their might be security restrictions (e.g. cross-domain issues) so you can debug if things go wrong.
Also note that you may want to (or need to) fill in more details of the MouseEvent (like the proper target, localX, localyY etc.)
Upvotes: 1
Reputation: 41054
This seems like a poor way to implement what you are trying to do. If you "click" in the admin tool you are probably actually triggering some event. Why not trigger that event instead of sending the mouse click?
I'd just keep a map of actions and then when something happens in the Admin interface send the key to the action.
e.g.
In the admin:
myButton.addEventListener(MouseEvent.CLICK, handleClickButton);
function handleClickButton(event:MouseEvent):void
{
doSomeAction();
sendTriggerToClient(MyActions.SOME_TRIGGER);
}
In the client:
var actionMap:Object = {};
actionMap[MyActions.SOME_TRIGGER] = doSomeAction;
function receiveTriggerFromAdmin(trigger:String):void
{
var responseFunc:Function = actionMap[trigger];
responseFunc();
}
I hope that pseudo-code makes sense. Just abstract what happens as a result of a click into a separate function (doSomeAction
) and then have the admin send a message before calling that function. In the client wait for any trigger that comes through and map it to the same function.
Upvotes: 0
Reputation: 39408
Sounds like you need to set focus to the top most component of the x and y positions before dispatching the click event.
That said, I wonder what the use case is for something like this; as opposed to using a screen sharing tool such as Connect.
Upvotes: 0