4

In an AS3 game (using Flex 4.10.0) I would like to allow players to chat, even when they are in fullscreen mode.

So I am using the following ActionScript code (the _fullBox checkbox triggers fullscreen mode in my web application):

public function init():void {
    if (stage.allowsFullScreenInteractive)
        stage.addEventListener(FullScreenEvent.FULL_SCREEN, handleFullScreen, false, 0, true);
}

private function toggleFullScreen(event:MouseEvent):void {
    stage.displayState = 
        stage.displayState == StageDisplayState.NORMAL ?
        StageDisplayState.FULL_SCREEN_INTERACTIVE :
        StageDisplayState.NORMAL;
}

private function handleFullScreen(event:FullScreenEvent):void {
    _fullBox.selected = event.fullScreen;
}

<s:CheckBox id="_fullBox" click="toggleFullScreen(event)" label="Full Screen" />

This works in the sense that the fullscreen mode is entered successfully and users can use the keyboard to chat too.

Unfortunately, the click at the "Allow" button in the dialog (displaying "Allow full screen with keyboard controls?") is being passed down to the web application.

And in my case it resuls in the click at a playing table in the lobby as you can see in the screenshot and thus (unwanted) joining a game:

enter image description here

This (bug?) has been seen with Windows 7 / 64 bit and Flash Player 11,8,800,115.

Can anybody please share a good workaround for this?

I was thinking of adding a transparent Sprite or UIComponent above my web application, but the question is when (i.e. in which methods) to display/hide it?

UPDATE:

Calling event.stopPropagation() from handleFullScreen() doesn't help anything.

UPDATE 2:

I've submitted Bug #3623333 at Adobe.

UPDATE 3: A note to myself - stage.allowsFullScreenInteractive is useless, because only set when allready in fullscreen mode.

Alexander Farber
  • 21,519
  • 75
  • 241
  • 416

2 Answers2

2

As you mentioned, you need to create transparent layer to avoid undesired click events. you can hide this layer when screen returned to normal state or user accepted fullscreen state (FULL_SCREEN_INTERACTIVE_ACCEPTED event will fired).

Demo (flashplayer 11.3 required)

var transparentLayer:Sprite=new Sprite();
var timer:Timer = new Timer(50, 1);
init();
function init():void {
    transparentLayer.graphics.beginFill(0,0.1);
    transparentLayer.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
    transparentLayer.graphics.endFill();
    transparentLayer.visible=false;
    addChild(transparentLayer);
    timer.addEventListener(TimerEvent.TIMER_COMPLETE,handleTimerComplete);
    stage.addEventListener(FullScreenEvent.FULL_SCREEN_INTERACTIVE_ACCEPTED,handleFSIA);
    _fullBox.addEventListener(MouseEvent.CLICK,toggleFullScreen);
    stage.addEventListener(FullScreenEvent.FULL_SCREEN, handleFullScreen);
}
function toggleFullScreen(e:MouseEvent):void {
    if(stage.displayState == StageDisplayState.NORMAL){
        stage.displayState=StageDisplayState.FULL_SCREEN_INTERACTIVE;

        transparentLayer.visible=ExternalInterface.available;

    }else
        stage.displayState=StageDisplayState.NORMAL;
}
function handleFullScreen(e:FullScreenEvent):void {
    _fullBox.selected = e.fullScreen;
    if(stage.displayState == StageDisplayState.NORMAL)
        transparentLayer.visible=false;
}
function handleFSIA(e:FullScreenEvent):void{
    timer.reset();
    timer.start();
}
function handleTimerComplete(e:TimerEvent):void{
    transparentLayer.visible=false;
}
null.point3r
  • 1,053
  • 2
  • 9
  • 17
  • 1
    I never worked with Flex, this post maybe help you: http://stackoverflow.com/a/2996101/1696720 – null.point3r Sep 05 '13 at 06:47
  • 1
    @AlexanderFarber, I updated my flash pro and build a demo for you. also i made changes in the code. – null.point3r Sep 05 '13 at 16:44
  • Awesome demo thanks. Too bad there is no FlexFiddle - similar to JSFiddle or SQLFiddle – Alexander Farber Sep 05 '13 at 19:28
  • This works great when your SWF is displayed in a browser with an HTML wrapper. But if someone uses a standalone SWF player, then the "Allow full screen with keyboard controls" never appears and your handleFSIA never gets called to remove the transparent layer. Is there a way to make it work whether your SWF is being displayed in an HTML or a standalone player? – BladePoint Feb 17 '14 at 11:00
  • Hi @BladePoint. you can use [`ExternalInterface.available`](http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html?filter_flash=cs5&filter_flashplayer=10.2&filter_air=2.6#available) to check if the SWF is being displayed in an HTML or a standalone player – null.point3r Feb 17 '14 at 17:33
  • 1
    Maybe using `stage.allowsFullScreen` would be more straightforward than `ExternalInterface.available`? Also I wonder, why is `Timer` needed in the above source code? – Alexander Farber Feb 21 '14 at 14:00
  • 1
    @AlexanderFarber, `stage.allowsFullScreen` property is true in both cases(if the swf is being displayed in a standalone player or an HTML wrapper with `` param). so you can't use this property to determine whether the transparentLayer must be shown or not. – null.point3r Feb 21 '14 at 16:24
  • +1 true, thanks and I've finally (6 months passed :-)) added your code to my Flex application here: https://www.facebook.com/appcenter/video-preferans (I've used a `Group` and a `Rect` instead of the translucent `Sprite`). And yes - the `Timer` is necessary. – Alexander Farber Feb 21 '14 at 17:39
1

Found one workaround.

Allow and Cancel buttons are not the parts of the application, so when you hover one of those buttons you receive rollOut event for application.

<s:Application
    rollOut="application_rollOutHandler(event)"
    rollOver="application_rollOverHandler(event)">


Inside event handler you can disable mouse events for child objects. Don't disable for application as you won't get rollOver event after that.

private function application_rollOutHandler(event:MouseEvent):void
{
    this.mouseChildren = false;
}

private function application_rollOverHandler(event:MouseEvent):void
{
    this.mouseChildren = true;
}
Andrei
  • 571
  • 6
  • 15