Problem with qwerty keyboard in my application
Our application will be mainly installed on a windows 7 tablet. The main problem our client faced during a demo was the lack of a soft keyboard. Hence, I begun my process of adding a soft keyboard and made a POC with the following code in it.
private var p:NativeProcess;
private var npInfo:NativeProcessStartupInfo;
private var f:File;
private function invokeKB():void{
p = new NativeProcess();
npInfo = new NativeProcessStartupInfo();
f = new File("C:\Windows\System32\osk.exe");
npInfo.executable = f;
p.start(npInfo);
}
I invoked the above, as soon as a textinput received focus. To my disappointment, this did not work. I even made the installer a native installer, as per the ADT guidelines, but nothing worked.
So, the next move was to open up a simple QWERTY keyboard in a nativewindow. Got a 3rd party qwerty, loaded it in a new nativewindow as below :
private var popupWindow:ExtendedNativeWindow;
protected function showWindowButton_clickHandler(e:FocusEvent):void
{
//* Set up the NativeWindow options
var options:NativeWindowInitOptions = new NativeWindowInitOptions();
options.type = "utility";
//* Create the NativeWindow
popupWindow = new ExtendedNativeWindow(options);
//* Set the height, width and position
popupWindow.width = 610;
popupWindow.height = 215;
popupWindow.x = ( Screen.mainScreen.bounds.width - 400) / 2;
popupWindow.y = ( Screen.mainScreen.bounds.height - 300) / 2;
popupWindow.stage.scaleMode = StageScaleMode.NO_SCALE;
popupWindow.stage.align = StageAlign.TOP_LEFT;
//* Create an instance of the qwerty keyboard component
var content:qwerty = new qwerty();
content.inputControl = e.currentTarget; // assign the current textinput control to the inputcontrol property of qwerty
//* Pass the content into the native window
popupWindow.addChildControls(content);
//* Activate the window
popupWindow.activate();
}
This, obviously works, except for one exception, which occurs everytime I press a key. The key value, does, pass on to the textinput, but throws a null reference error along with it. I've pasted the qwerty component code below, highlighting the line where the exception is thrown. Any guidance or help to remove that exception will be appreciated.
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.controls.Button;
import mx.core.UIComponent;
import mx.events.FlexEvent;
import mx.managers.IFocusManagerComponent;
[Bindable]
public var inputControl:Object;
public var isShifted:Boolean = false;
private var _tabOrder:Array = new Array();
public var currentTab:Number = 0;
public function get tabOrder():Array
{
return this._tabOrder;
}
public function set tabOrder(value:Array):void
{
this._tabOrder = value;
}
private var keysRowA:Array = [
{label:'1'},{label:'2'},{label:'3'},{label:'4'},{label:'5'},{label:'6'},{label:'7'},{label:'8'},
{label:'9'},{label:'0'},{label:'Delete',w:90}
];
private var keysRowB:Array = [
{label:'q'},{label:'w'},{label:'e'},{label:'r'},{label:'t'},{label:'y'},{label:'u'},{label:'i'},
{label:'o'},{label:'p'}
];
private var keysRowC:Array = [
{label:'a'},{label:'s'},{label:'d'},{label:'f'},{label:'g'},{label:'h'},
{label:'j'},{label:'k'},{label:'l'}
];
private var keysRowD:Array = [
{label:'Tab',flex:true},{label:'z'},{label:'x'},{label:'c'},{label:'v'},{label:'b'},
{label:'n'},{label:'m'},{label:'shift',flex:true}
];
private var keysRowE:Array = [
{label:'CAPS LOCK',w:130},{label:'Space',flex:true},{label:'.'},{label:'_'},{label:'-'}
];// {label:'.com',w:70},{label:'.ca',w:65},{label:'@'},
private function init():void
{
var o:Object;
var k:UIComponent;
// Build Row A
for each ( o in this.keysRowA )
{
k = buildKey(o);
rowA.addChild(k);
}
for each ( o in this.keysRowB )
{
k = buildKey(o);
rowB.addChild(k);
}
for each ( o in this.keysRowC )
{
k = buildKey(o);
rowC.addChild(k);
}
for each ( o in this.keysRowD )
{
k = buildKey(o);
rowD.addChild(k);
}
for each ( o in this.keysRowE )
{
k = buildKey(o);
rowE.addChild(k);
}
this.toggleCapsKey(false);
}
public function newFocus(o:UIComponent):void
{
//this.inputControl = o;
}
public function focusNext():void
{
var n:Number = this.currentTab + 1;
if ( n >= this.tabOrder.length ) n = 0;
this.currentTab = n;
this.newFocus( this.tabOrder
}
private function buildKey(o:Object):UIComponent
{
var key:Button = new Button();
key.label = o.label;
//key.setStyle('textAlign','center');
if(key.label == "CAPS LOCK"){
key.styleName = 'kbCaps';
}else{
key.styleName = 'kbKeys';
}
if ( o.flex ) key.percentWidth = 100;
if ( o.w ) {
key.width = o.w;
} else if ( ! o.flex ) {
key.width = 50;
}
key.height = 50;
key.addEventListener(MouseEvent.CLICK, handleKeyClick, false, 0, true);
return key;
}
private function handleKeyClick(event:Event):void
{
if(this.inputControl != null){
switch ( Button(event.target).label )
{
case 'shift':
this.toggleCapsKey(false);
this.isShifted = true;
break;
case 'SHIFT':
this.toggleCapsKey(true);
this.isShifted = false;
break;
case 'caps lock':
this.toggleCapsKey(false);
Button(event.target).setStyle('color',0xcd5353);
break;
case 'CAPS LOCK':
this.toggleCapsKey(true);
Button(event.target).setStyle('color',0x3e3e3e);
break;
case 'Clear':
this.inputControl.text = '';
this.inputControl.dispatchEvent(new Event(flash.events.Event.CHANGE,true));
break;
case 'Space':
this.inputControl.text += ' ';
this.inputControl.dispatchEvent(new Event(flash.events.Event.CHANGE,true));
break;
case 'Delete':
var value:String = this.inputControl.text;
this.inputControl.text = value.substr(0,value.length-1);
this.inputControl.dispatchEvent(new Event(flash.events.Event.CHANGE,true));
break;
case 'Tab':
this.focusNext();
break;
default:
this.addToString( Button(event.target).label );
if ( this.isShifted ) this.toggleCapsKey(true);
this.isShifted = false;
break;
}
returnFocus();
}
}
private function addToString( text:String ):void
{
this.inputControl.text += text;
//this.inputControl.dispatchEvent(new Event(flash.events.Event.CHANGE,true));
}
private function toggleCapsKey(toLower:Boolean):void
{
this.toggleUpperLower(rowA,toLower);
this.toggleUpperLower(rowB,toLower);
this.toggleUpperLower(rowC,toLower);
this.toggleUpperLower(rowD,toLower);
this.toggleUpperLower(rowE,toLower);
}
private function toggleUpperLower(row:Object,toLower:Boolean):void
{
var kid:Object;
var kidLabel:String;
for (var i:Number=0;i<row.getChildren().length;i++) {
kid = row.getChildAt(i);
kidLabel = kid.label;
if ( kidLabel == 'Tab' || kidLabel == 'Delete' || kidLabel == 'Space'
|| kidLabel == '.' || kidLabel == '_' || kidLabel == '-') continue;
if ( toLower ){
kid.label = kidLabel.toLowerCase();
} else {
kid.label = kidLabel.toUpperCase();
}
}
}
private function returnFocus():void
{
//error occurs on this line --> focusManager.setFocus( inputControl as IFocusManagerComponent );
inputControl.setSelection(inputControl.length, inputControl.length);
}
private function closeKB():void{
/* var closeKBev:TangoEvent = new TangoEvent(ApplicationController.SHOW_KEYPAD,true);
ApplicationController.dispatchEvent(closeKBev); */
}
]]>
</mx:Script>
<mx:VBox id="keyContainer"
paddingTop="5" paddingLeft="5" paddingBottom="5" paddingRight="5"
cornerRadius="5" borderStyle="solid" backgroundColor="#212121">
<!--<mx:HBox width="100%" id="headRow">
<mx:Spacer width="100%" />
<mx:Button id="closeBtn" width="16" height="16"
click="closeKB()" styleName="closeBtn" />
</mx:HBox>-->
<mx:HBox width="100%" id="rowA" horizontalAlign="center" horizontalGap="2"/>
<mx:HBox width="100%" id="rowB" horizontalAlign="center" horizontalGap="2"/>
<mx:HBox width="100%" id="rowC" horizontalAlign="center" horizontalGap="2"/>
<mx:HBox width="100%" id="rowD" horizontalAlign="center" horizontalGap="2"/>
<mx:HBox width="100%" id="rowE" horizontalAlign="center" horizontalGap="2"/>
</mx:VBox>
</mx:Canvas>
Thanks in advance,
Robi.
