2
* This file is part of the dis-Emi-A HaXe Library. Copyright © edA-qa mort-ora-y
3
* For full copyright and license information please refer to doc/license.txt.
11
import neash.display.DisplayObject;
12
import neash.events.Event;
13
import neash.events.MouseEvent;
14
import neash.events.KeyboardEvent;
16
import flash.display.DisplayObject;
17
import flash.events.Event;
18
import flash.events.MouseEvent;
19
import flash.events.KeyboardEvent;
23
* Executes an display as a modal display. This will be modal to the
24
* program as a whole (the stage) such that no other window, other
25
* than what is provided here, can be accessed.
27
* Note that exactly when the completionAction is sent cannot be guaranteed as there
28
* are many minor paths by which the modal can end. In particular you cannot assume
29
* that when it is done that something like a Popup menu has processed, or even yet
30
* dispatched the associated menu event. Though other classes may choose to provide
31
* guarantees (like Dialog)
35
// Parent will be covered with a gray box during processing (only makes sense when Stage is parent)
36
var grayParent : Bool;
37
var grayParentObj : Box;
39
static var modalEvents = [
40
MouseEvent.MOUSE_DOWN, MouseEvent.MOUSE_UP,
41
MouseEvent.CLICK, MouseEvent.DOUBLE_CLICK,
42
MouseEvent.MOUSE_WHEEL,
44
//In a decent system these should be fine since they shouldn't change the display tree
45
//MouseEvent.MOUSE_MOVE, MouseEvent.MOUSE_OVER, MouseEvent.MOUSE_OUT,
46
//MouseEvent.ROLL_OUT, MouseEvent.ROLL_OVER,
48
KeyboardEvent.KEY_DOWN, KeyboardEvent.KEY_UP
52
* Constructs a default Modal handler.
59
grayParentObj = Box.plain( Brush.solid(Color.rgb(0.5,0.5,0.5)) );
60
//grayParentObj.alpha = 0.5;
61
grayParentObj.blendMode = flash.display.BlendMode.MULTIPLY;
65
var dParent : NativeObject;
69
* A standard execution path to execute the window as modal against the
72
static public function asStageModal( obj : Window, ?onCompletion : ui.Action,
73
?grayParent : Bool = true ) : Modal
76
m.setCompletionAction( onCompletion );
77
m.grayParent = grayParent;
83
* Executres the obj in a Modal faction.
85
* @param parent [in] of which object this will be a child, 0 indicates to use the stage
86
* @param obj [in] which window to display
88
public function exec( parent : NativeObject, obj : Window )
90
Assert.isTrue( !active );
93
dParent = if( parent == null ) flash.Lib.current.stage else parent;
95
//setup listeners to know when we are (planned or otherwise)
96
dObject.getNative().addEventListener( Event.REMOVED, onRemoved );
97
dObject.setCloseListener( Action.bind( onClose ) );
99
//gray of parent if desired
102
grayParentObj.resize( dParent.width, dParent.height );
103
dParent.addChild( grayParentObj );
106
//finally add target window to parent, or run FX
107
dParent.addChild( dObject.getNative() );
108
if( __beginFX != null )
110
ui.anim.FXBuilder.beginWidget( dObject.getWidget(), __beginFX, Action.bind( __endBeginFX ) );
114
dObject.exec( dParent );
118
//then setup the events to make use Modal in nature
119
//just guess that 100 is a high enough priority to override other events...?
120
for( evt in modalEvents )
121
flash.Lib.current.stage.addEventListener( evt, capturePhase, true, 100 );
123
/*as nothing has the focus often the keyboard events start at the stage, and thus
124
*do not go through a capture stage (as they are at their target). For this reason
125
* we also need to listen in non-capture mode as well.
126
* NOTE: as we assume the stage is never empty this is not true for mouse events
128
flash.Lib.current.stage.addEventListener( KeyboardEvent.KEY_DOWN, capturePhase, false, 100 );
129
flash.Lib.current.stage.addEventListener( KeyboardEvent.KEY_UP, capturePhase, false, 100 );
132
/*hidden*/ function __endBeginFX()
134
dObject.exec( dParent );
138
/*hidden*/ function capturePhase( evt : Event )
140
//do before further propogation (so that focus in modal doesn't block the escape)
141
if( evt.type == KeyboardEvent.KEY_UP )
143
if( cast( evt, KeyboardEvent ).keyCode == flash.ui.Keyboard.ESCAPE )
145
evt.stopPropagation();
146
goEnd(false); //cancel the menu
151
//children of the display object can process such items
152
if( dObject.getNative().contains( cast( evt.target, DisplayObject ) ) )
156
evt.stopPropagation();
159
function onRemoved( evt : Event )
161
if( evt.target != dObject )
164
//in case something else removes us
169
* Ends the Modal state and closes the widget.
171
public function endClose()
181
function goEnd( removed : Bool )
183
//active applies both during startup and shutdown if FX are being applied
188
dParent.removeChild( grayParentObj );
190
//set active first to false to prevent removal recursion
193
for( evt in modalEvents )
194
flash.Lib.current.stage.removeEventListener( evt, capturePhase, true );
195
flash.Lib.current.stage.removeEventListener( KeyboardEvent.KEY_DOWN, capturePhase, false );
196
flash.Lib.current.stage.removeEventListener( KeyboardEvent.KEY_UP, capturePhase, false );
197
dObject.getNative().removeEventListener( Event.REMOVED, onRemoved );
199
//root popup needs to remove itself (ensure parent hasn't changed however)
200
if( !removed && dObject.getNative().parent == dParent )
202
if( __endFX != null )
203
ui.anim.FXBuilder.endWidget( dObject.getWidget(), __endFX );
205
dParent.removeChild( dObject.getNative() );
212
//signal completion (NOTE: Do absolutely last so this modal could technically be used again)
213
if( completionAction != null )
214
Action.handle( p, completionAction );
217
/*hidden*/ var __endFX : ui.anim.FXDescriptor;
218
/*hidden*/ var __beginFX : ui.anim.FXDescriptor;
221
* Sets the effect to use on completion of the Modal item
223
public function setEndFX( fx : ui.anim.FXDescriptor )
228
public function setBeginFX( fx : ui.anim.FXDescriptor )
234
* Allows an action to be executed when the Modal is completed.
236
* @action [in] action to fire when done, may be null to indicate none (which
239
var completionAction : Dynamic;
240
public function setCompletionAction( action : Dynamic )
242
completionAction = action;
b'\\ No newline at end of file'