![JAR search and dependency download from the Maven repository](/logo.png)
rwt.widgets.util.MnemonicHandler.js Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2013, 2014 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
(function() {
var EventHandlerUtil = rwt.event.EventHandlerUtil;
var WidgetUtil = rwt.widgets.util.WidgetUtil;
rwt.qx.Class.define( "rwt.widgets.util.MnemonicHandler", {
extend : rwt.qx.Object,
statics : {
getInstance : function() {
return rwt.runtime.Singletons.get( rwt.widgets.util.MnemonicHandler );
}
},
construct : function() {
this.base( arguments );
this._map = {};
this._activator = null;
this._active = null;
this._activeMenu = null;
this._allowMenuActivate = false;
},
members : {
add : function( widget, listener ) {
var shell = WidgetUtil.getShell( widget );
if( shell != null ) { // TODO [tb] : this is for MenuBar items, handle them like Menu items
this._registerFocusRoot( shell );
var handlers = this._map[ shell.toHashCode() ];
if( widget instanceof rwt.widgets.MenuItem ) {
handlers.menu[ widget.toHashCode() ] = [ widget, listener ];
} else {
handlers.controls[ widget.toHashCode() ] = [ widget, listener ];
}
}
},
remove : function( widget ) {
// NOTE: The shell may be gone if the widget is in dispose, therefore we have to search:
var hash = widget.toHashCode();
if( widget instanceof rwt.widgets.MenuItem ) {
for( var key in this._map ) {
if( this._map[ key ].menu[ widget.toHashCode() ] ) {
delete this._map[ key ].menu[ hash ];
return;
}
}
} else {
for( var key in this._map ) {
if( this._map[ key ].controls[ widget.toHashCode() ] ) {
delete this._map[ key ].controls[ hash ];
return;
}
}
}
},
setActivator : function( str ) {
if( str ) {
this._activator = {};
this._activator.ctrlKey = str.indexOf( "CTRL" ) !== -1;
this._activator.altKey = str.indexOf( "ALT" ) !== -1;
this._activator.shiftKey = str.indexOf( "SHIFT" ) !== -1;
} else {
this._activator = null;
}
},
isActive : function() {
return this._active != null;
},
handleKeyEvent : function( eventType, keyCode, charCode, domEvent ) {
var result = false;
this._checkActiveMenu();
// Some browser fire multiple keydown for modifier keys:
if( eventType !== "keydown" || rwt.event.EventHandlerUtil.isFirstKeyDown( keyCode ) ) {
if( this._isActivation( eventType, keyCode, charCode, domEvent ) ) {
this.activate();
} else if( this._isDeactivation( eventType, keyCode, charCode, domEvent ) ) {
this.deactivate( this._allowMenuActivate || this._activeMenu );
} else if( this._isTrigger( eventType, keyCode, charCode, domEvent ) ) {
result = this.trigger( keyCode );
this._allowMenuActivate = false;
} else if( this.isActive() && !this._isActivatorCombo( domEvent ) ) {
this._allowMenuActivate = false;
}
}
return result;
},
activate : function() {
if( this._noMenuOpen() ) {
var root = rwt.widgets.base.Window.getDefaultWindowManager().getActiveWindow();
if( root == null ) {
root = rwt.widgets.base.ClientDocument.getInstance();
}
this._active = root.toHashCode();
this._allowMenuActivate = true;
this._fire( { "type" : "show" } );
}
},
deactivate : function( allowMenuToggle ) {
if( this._activeMenu && allowMenuToggle ) {
this._activeMenu.setActive( false );
this._activeMenu = null;
}
if( this._active ) {
this._fire( { "type" : "hide" } );
if( allowMenuToggle ) {
this._activateMenuBar();
}
this._active = null;
}
},
trigger : function( charCode ) {
var event = {
"type" : "trigger",
"charCode" : charCode,
"success" : false
};
this._fire( event, true );
return event.success;
},
_registerFocusRoot : function( root ) {
if( !this._map[ root.toHashCode() ] ) {
this._map[ root.toHashCode() ] = { "menu" : {}, "controls" : {} };
root.addEventListener( "dispose", function() {
this.deactivate();
delete this._map[ root.toHashCode() ];
}, this );
root.addEventListener( "changeActive", this._onRootChangeActive, this );
}
},
_onRootChangeActive : function( event ) {
if( event.getValue() === false ) {
this.deactivate();
}
},
_fire : function( event, onlyVisible ) {
if( this._map[ this._active ] ) {
this._doFire( event, onlyVisible, this._map[ this._active ].controls );
if( !event.success ) {
this._doFire( event, onlyVisible, this._map[ this._active ].menu );
}
}
},
_doFire : function( event, onlyVisible, handlers ) {
for( var key in handlers ) {
var entry = handlers[ key ];
if( ( !onlyVisible || entry[ 0 ].isSeeable() ) && entry[ 0 ].getEnabled() ) {
try{
entry[ 1 ].call( entry[ 0 ], event );
if( event.success ) {
break;
}
} catch( ex ) {
var msg = "Could not handle mnemonic " + event.type + ". ";
if( entry[ 0 ].isDisposed() ) {
msg += entry[ 0 ].classname + " is disposed. ";
}
msg += ex.message;
throw new Error( msg );
}
}
}
},
_activateMenuBar : function() {
// Accepted limitation: MenuBars without mnemonics can not be activated by mnemonic keys
if( this._map[ this._active ] ) {
var items = this._map[ this._active ].menu;
for( var key in items ) {
var bar = items[ key ][ 0 ].getParentMenu();
bar.setMnemonics( true );
bar.setActive( true );
this._activeMenu = bar;
break;
}
}
},
_checkActiveMenu : function() {
if( this._activeMenu && !this._activeMenu.getActive() ) {
this._activeMenu = null;
}
},
/////////
// Helper
_isActivation : function( eventType, keyCode, charCode, domEvent ) {
return this._activator
&& this._active == null && this._activeMenu == null
&& eventType === "keydown"
&& EventHandlerUtil.isModifier( keyCode )
&& this._isActivatorCombo( domEvent );
},
_isDeactivation : function( eventType, keyCode, charCode, domEvent ) {
return this._isGlobalDeactivation( eventType, keyCode, charCode, domEvent )
|| this._isMenuDeactivation( eventType, keyCode, charCode, domEvent );
},
_isMenuDeactivation : function( eventType, keyCode, charCode, domEvent ) {
return this._activator != null
&& this._activeMenu != null
&& EventHandlerUtil.isModifier( keyCode )
&& this._isActivatorCombo( domEvent );
},
_isGlobalDeactivation : function( eventType, keyCode, charCode, domEvent ) {
return this._activator != null
&& this._active != null
&& eventType != "keypress"
&& !this._isActivatorCombo( domEvent );
},
_isActivatorCombo : function( domEvent ) {
return this._activator.ctrlKey === domEvent.ctrlKey
&& this._activator.altKey === domEvent.altKey
&& this._activator.shiftKey === domEvent.shiftKey;
},
_isTrigger : function( eventType, keyCode ) {
var isChar = !isNaN( keyCode ) && rwt.event.EventHandlerUtil.isAlphaNumericKeyCode( keyCode );
return this._active != null && eventType === "keydown" && isChar;
},
_noMenuOpen : function() {
return rwt.util.Objects.isEmpty( rwt.widgets.util.MenuManager.getInstance().getAll() );
}
}
} );
}() );
© 2015 - 2025 Weber Informatics LLC | Privacy Policy