PDA

View Full Version : Disabling keyboard and mouse input



dzhedzho
April 25th, 2008, 02:50 PM
Hello guys, I am trying to display a modal dialog. What this means is that I need to disable mouse and keyboard input from anything else but that MovieClip. Any Ideas? Currently what I was trying was to is loop through all children in the stage and set mouseEnabled to false for all byt the dialog. I have no idea how to disable keyboard imput though. I tried

ActionScript Code:

this.stage.addEventListener(KeyboardEvent.KEY_DOWN ,preventKey,true);
this.stage.addEventListener(KeyboardEvent.KEY_UP,p reventKey,true);
function preventKey (evt):void {
evt.stopImmediatePropagation();
}





thought that did not work...
Any idea how to do that?

Felixz
April 25th, 2008, 02:59 PM
maybe change priority.
Propagation is for bubbling events (propably)

skineh
April 25th, 2008, 03:10 PM
Why do you need to disable key presses in the first place? If you've turned off mouseEnabled on all the other items, the user shouldn't be able to give them focus.

Otherwise, any other keypresses that could potentially interfere (I'm assuming) would be from event listeners you set up for keypresses earlier. In that case, just remove those listeners while your modal is up.

How do key presses interfere when your modal is up? It would help to better understand why you're trying to prevent them.

dzhedzho
April 25th, 2008, 03:31 PM
Why do you need to disable key presses in the first place? If you've turned off mouseEnabled on all the other items, the user shouldn't be able to give them focus.

Otherwise, any other keypresses that could potentially interfere (I'm assuming) would be from event listeners you set up for keypresses earlier. In that case, just remove those listeners while your modal is up.

How do key presses interfere when your modal is up? It would help to better understand why you're trying to prevent them.
Ok...
As you mentioned objects won't get the key events if thay do not have focus. I guess I should just set the focus to my modal and disable tabbing...

skineh
April 25th, 2008, 03:49 PM
Ok...
As you mentioned objects won't get the key events if thay do not have focus. I guess I should just set the focus to my modal and disable tabbing...

Hopefully that would prove to be quicker and less of a hassle for you. :)

dzhedzho
April 25th, 2008, 05:52 PM
I almost got it working, but for some reason I do not remember how to set the focus to the added modal.. Anyone has an idea?

magcius
April 25th, 2008, 05:56 PM
Are you using Flex or CS3? I do not believe there is built-in focus management in the Flash Player. That's Flex capabilities.

dzhedzho
April 25th, 2008, 06:03 PM
Are you using Flex or CS3? I do not believe there is built-in focus management in the Flash Player. That's Flex capabilities.

Flash
Anyway, there is something for components, but hmm
Used to be in AS2 but dunno for AS3

dzhedzho
April 25th, 2008, 06:33 PM
lol
ActionScript Code:

stage.focus=this;





Ok I think now it works...
ActionScript Code:

package{
import flash.display.Sprite;
import flash.display.*;
import flash.events.Event;
public class Modal extends Sprite{
protected var moused:Array;
protected var childrenMoused:Array;
protected var tabbed:Array;
protected var rootRef;
protected var childrenTabbed:Array;
protected var stageTabsChildren:Boolean;
public function Modal () {
addEventListener(Event.ADDED_TO_STAGE,disableInput );
}
protected function disableInput (evt:Event):void {
removeEventListener(Event.ADDED_TO_STAGE,disableIn put);
var item:*;
rootRef = this.root;
moused = [];
childrenMoused = [];
tabbed = [];
childrenTabbed = [];
for (var i:Number=0;i<rootRef.numChildren-1;i++) {
item = rootRef.getChildAt(i);
if (item!=this) {
try{
if (item.mouseEnabled==true) {
item.mouseEnabled=false;
moused.push(item);
}
}catch (e){}
try{
if (item.mouseChildren==true) {
item.mouseChildren=false;
childrenMoused.push(item);
}
}catch (e){}
try{
if (item.tabEnabled==true) {
item.tabEnabled=false;
tabbed.push(item);
}
}catch (e){}
try{
if (item.tabChildren==true) {
item.tabChildren=false;
childrenTabbed.push(item);
}
}catch (e){}
}
}
stage.focus=this;
addEventListener(Event.REMOVED_FROM_STAGE,enableIn put);
}
protected function enableInput (evt:Event):void {
var item:*;
removeEventListener(Event.ADDED_TO_STAGE,disableIn put);
for each(item in moused) {
item.mouseEnabled = true;
}
for each(item in childrenMoused) {
item.mouseChildren = true;
}
for each(item in tabbed) {
item.tabEnabled = true;
}
for each(item in childrenTabbed) {
item.tabChildren = true;
}
moused = [];
childrenMoused = [];
tabbed = [];
childrenTabbed = [];
addEventListener(Event.ADDED_TO_STAGE,disableInput );
}
}
}

magcius
April 25th, 2008, 07:34 PM
Here's a simple class for focus management.

All you need to do on the initial timeline is this:

var modalManager:ModalManager = new ModalManager ( stage );


And when you make a modal dialog:

modalManager.setModal ( modalDialog );


Here's the class:

package {
import flash.display.Stage;
import flash.display.MovieClip;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;

import flash.events.Event;
import flash.events.EventPhase;
import flash.events.EventDispatcher;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;

/**
* A "hack" to stop all interactivity
* during a modal popup.
*/
public class ModalManager extends MovieClip {

protected var focus:DisplayObject;

public var isModalUp:Boolean = false;

/**
* Constructor.
* @param stage The stage instance.
*/
public function ModalManager ( stage:Stage ):void {
// Add all elements on the stage already.
traverseTree ( stage );
// Use event bubbling to find all elements
// added to the stage dynamically.
stage.addEventListener ( Event.ADDED, addedHandler );
}

/**
* Find all elements added on the stage.
*/
protected function traverseTree ( p:DisplayObjectContainer ):void {
// Add all children on the stage at init.
for ( var i:int = 0; i < p.numChildren; i ++ ) {
if ( p.getChildAt ( i ) is DisplayObjectContainer ) {
traverseTree ( DisplayObjectContainer ( p.getChildAt ( i ) ) );
}
addObject ( p );
}
}

/**
*
*/
public function setModal ( modal:DisplayObject ):void {
modal.addEventListener ( Event.REMOVED, clearModal );
isModalUp = true;
focus = modal;
}

/**
* Clears the current modal.
*/
public function clearModal ( event:Event = null ):void {
isModalUp = false;
focus.removeEventListener ( Event.REMOVED, clearModal );
focus = null;
}

/**
* Takes care of objects added dynamically.
*/
protected function addedHandler ( event:Event ):void {
// Thank you, event bubbling!
addObject ( DisplayObject ( event.target ) );
}

/**
* Adds an object to the system.
* Don't need to worry about this; taken care of automatically.
*/
protected function addObject ( t:DisplayObject ):void {
// HERE STARS THE SPAGHETTI CODE
// Mouse Events
t.addEventListener ( MouseEvent.CLICK, checkEvent );
t.addEventListener ( MouseEvent.DOUBLE_CLICK, checkEvent );
t.addEventListener ( MouseEvent.MOUSE_DOWN, checkEvent );
t.addEventListener ( MouseEvent.MOUSE_MOVE, checkEvent );
t.addEventListener ( MouseEvent.MOUSE_OUT, checkEvent );
t.addEventListener ( MouseEvent.MOUSE_OVER, checkEvent );
t.addEventListener ( MouseEvent.MOUSE_UP, checkEvent );
t.addEventListener ( MouseEvent.MOUSE_WHEEL, checkEvent );
t.addEventListener ( MouseEvent.ROLL_OVER, checkEvent );
t.addEventListener ( MouseEvent.ROLL_OUT, checkEvent );

// Keyboard Events
t.addEventListener ( KeyboardEvent.KEY_DOWN, checkEvent );
t.addEventListener ( KeyboardEvent.KEY_UP, checkEvent );
t.addEventListener ( Event.REMOVED, removeObject );
}

/**
* Removes an object from the system.
* Don't need to worry about this; taken care of automatically.
*/
protected function removeObject ( event:Event ):void {
var t:DisplayObject = DisplayObject ( event.target );
// HERE STARS THE SPAGHETTI CODE
// Mouse Events
t.removeEventListener ( MouseEvent.CLICK, checkEvent );
t.removeEventListener ( MouseEvent.DOUBLE_CLICK, checkEvent );
t.removeEventListener ( MouseEvent.MOUSE_DOWN, checkEvent );
t.removeEventListener ( MouseEvent.MOUSE_MOVE, checkEvent );
t.removeEventListener ( MouseEvent.MOUSE_OUT, checkEvent );
t.removeEventListener ( MouseEvent.MOUSE_OVER, checkEvent );
t.removeEventListener ( MouseEvent.MOUSE_UP, checkEvent );
t.removeEventListener ( MouseEvent.MOUSE_WHEEL, checkEvent );
t.removeEventListener ( MouseEvent.ROLL_OVER, checkEvent );
t.removeEventListener ( MouseEvent.ROLL_OUT, checkEvent );

// Keyboard Events
t.removeEventListener ( KeyboardEvent.KEY_DOWN, checkEvent );
t.removeEventListener ( KeyboardEvent.KEY_UP, checkEvent );
t.removeEventListener ( Event.REMOVED, removeObject );
}

/**
* Check for a trace of interactivity.
*/
protected function checkEvent ( event:Event ):void {
// Uses event capturing.
// If there is a modal dialog, and we got a click that's not a child
// of the modal, stop the event.
if ( isModalUp && !isAncestor ( focus, DisplayObject ( event.target ) ) ) {
event.stopImmediatePropagation ( );
}
}

/**
* Simple recursive test to check for an ancestor.
*/
protected function isAncestor ( lookingFor:DisplayObject, start:DisplayObject ):Boolean {
if ( lookingFor === start ) {
return true;
}
if ( start.parent ) {
return isAncestor ( lookingFor, start.parent );
}
return false;
}

}

}

dzhedzho
April 25th, 2008, 08:15 PM
Hmm that does not seem to work

dzhedzho
April 26th, 2008, 05:22 PM
Seems like setting tabCheldren to false and then to true, has a glitch. Children are no longer tabbable, ughh... why oh why:cantlook: