David Catuhe 8 jaren geleden
bovenliggende
commit
69d684e7ba
27 gewijzigde bestanden met toevoegingen van 31798 en 31428 verwijderingen
  1. 2 1
      Tools/Gulp/config.json
  2. 8724 8724
      dist/preview release/babylon.d.ts
  3. 39 39
      dist/preview release/babylon.js
  4. 8724 8724
      dist/preview release/babylon.module.d.ts
  5. 40 40
      dist/preview release/babylon.worker.js
  6. 6779 6779
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  7. 42 42
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  8. 6779 6779
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts
  9. 39 0
      dist/preview release/gui/babylon.gui.d.ts
  10. 148 10
      dist/preview release/gui/babylon.gui.js
  11. 3 3
      dist/preview release/gui/babylon.gui.min.js
  12. 39 0
      dist/preview release/gui/babylon.gui.module.d.ts
  13. 263 263
      dist/preview release/inspector/babylon.inspector.bundle.js
  14. 3 3
      dist/preview release/inspector/babylon.inspector.min.js
  15. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  16. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  17. 2 2
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  18. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  19. 1 1
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  20. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js
  21. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  22. 1 1
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js
  23. 1 1
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js
  24. 4 0
      gui/src/advancedDynamicTexture.ts
  25. 1 0
      gui/src/controls/control.ts
  26. 23 10
      gui/src/controls/inputText.ts
  27. 135 0
      gui/src/controls/virtualKeyboard.ts

+ 2 - 1
Tools/Gulp/config.json

@@ -1447,7 +1447,8 @@
                     "../../gui/src/controls/image.ts",
                     "../../gui/src/controls/button.ts",
                     "../../gui/src/controls/colorPicker.ts",
-                    "../../gui/src/controls/inputText.ts"
+                    "../../gui/src/controls/inputText.ts",
+                    "../../gui/src/controls/virtualKeyboard.ts"
                 ],
                 "output": "babylon.gui.js",
                 "buildAsModule": "true",

File diff suppressed because it is too large
+ 8724 - 8724
dist/preview release/babylon.d.ts


File diff suppressed because it is too large
+ 39 - 39
dist/preview release/babylon.js


File diff suppressed because it is too large
+ 8724 - 8724
dist/preview release/babylon.module.d.ts


File diff suppressed because it is too large
+ 40 - 40
dist/preview release/babylon.worker.js


File diff suppressed because it is too large
+ 6779 - 6779
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


File diff suppressed because it is too large
+ 42 - 42
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


File diff suppressed because it is too large
+ 6779 - 6779
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts


+ 39 - 0
dist/preview release/gui/babylon.gui.d.ts

@@ -168,6 +168,7 @@ declare module BABYLON.GUI {
         private _doNotRender;
         isHitTestVisible: boolean;
         isPointerBlocker: boolean;
+        isFocusInvisible: boolean;
         protected _linkOffsetX: ValueAndUnit;
         protected _linkOffsetY: ValueAndUnit;
         readonly typeName: string;
@@ -609,6 +610,7 @@ declare module BABYLON.GUI {
         private _blinkIsEven;
         private _cursorOffset;
         private _scrollLeft;
+        promptMessage: string;
         onTextChangedObservable: Observable<InputText>;
         onFocusObservable: Observable<InputText>;
         onBlurObservable: Observable<InputText>;
@@ -623,6 +625,7 @@ declare module BABYLON.GUI {
         onBlur(): void;
         onFocus(): void;
         protected _getTypeName(): string;
+        processKey(keyCode: number, key?: string): void;
         processKeyboard(evt: KeyboardEvent): void;
         _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
         protected _onPointerDown(coordinates: Vector2): boolean;
@@ -630,3 +633,39 @@ declare module BABYLON.GUI {
         dispose(): void;
     }
 }
+
+
+declare module BABYLON.GUI {
+    class KeyOptions {
+        width?: string;
+        height?: string;
+        paddingLeft?: string;
+        paddingRight?: string;
+        paddingTop?: string;
+        paddingBottom?: string;
+        color?: string;
+        background?: string;
+    }
+    class VirtualKeyboard extends StackPanel {
+        onKeyPressObservable: Observable<string>;
+        defaultButtonWidth: string;
+        defaultButtonHeight: string;
+        defaultButtonPaddingLeft: string;
+        defaultButtonPaddingRight: string;
+        defaultButtonPaddingTop: string;
+        defaultButtonPaddingBottom: string;
+        defaultButtonColor: string;
+        defaultButtonBackground: string;
+        protected _getTypeName(): string;
+        private _createKey(key, options?);
+        addKeysRow(keys: Array<string>, options?: Array<KeyOptions>): void;
+        private _connectedInputText;
+        private _onFocusObserver;
+        private _onBlurObserver;
+        private _onKeyPressObserver;
+        readonly connectedInputText: InputText;
+        connect(input: InputText): void;
+        disconnect(): void;
+        static CreateDefaultLayout(): VirtualKeyboard;
+    }
+}

+ 148 - 10
dist/preview release/gui/babylon.gui.js

@@ -294,6 +294,9 @@ var BABYLON;
                 // Focus management
                 if (this._focusedControl) {
                     if (this._focusedControl !== this._lastPickedControl) {
+                        if (this._lastPickedControl.isFocusInvisible) {
+                            return;
+                        }
                         this.focusedControl = null;
                     }
                 }
@@ -727,6 +730,7 @@ var BABYLON;
                 this._doNotRender = false;
                 this.isHitTestVisible = true;
                 this.isPointerBlocker = false;
+                this.isFocusInvisible = false;
                 this._linkOffsetX = new GUI.ValueAndUnit(0);
                 this._linkOffsetY = new GUI.ValueAndUnit(0);
                 /**
@@ -3779,6 +3783,7 @@ var BABYLON;
                 _this._isFocused = false;
                 _this._blinkIsEven = false;
                 _this._cursorOffset = 0;
+                _this.promptMessage = "Please enter text:";
                 _this.onTextChangedObservable = new BABYLON.Observable();
                 _this.onFocusObservable = new BABYLON.Observable();
                 _this.onBlurObservable = new BABYLON.Observable();
@@ -3901,13 +3906,18 @@ var BABYLON;
                 this._cursorOffset = 0;
                 this._markAsDirty();
                 this.onFocusObservable.notifyObservers(this);
+                if (navigator.userAgent.indexOf("Mobile") !== -1) {
+                    this.text = prompt(this.promptMessage);
+                    this._host.focusedControl = null;
+                    return;
+                }
             };
             InputText.prototype._getTypeName = function () {
                 return "InputText";
             };
-            InputText.prototype.processKeyboard = function (evt) {
+            InputText.prototype.processKey = function (keyCode, key) {
                 // Specific cases
-                switch (evt.keyCode) {
+                switch (keyCode) {
                     case 8:// BACKSPACE
                         if (this._text && this._text.length > 0) {
                             if (this._cursorOffset === 0) {
@@ -3959,21 +3969,25 @@ var BABYLON;
                         return;
                 }
                 // Printable characters
-                if ((evt.keyCode === 32) ||
-                    (evt.keyCode > 47 && evt.keyCode < 58) ||
-                    (evt.keyCode > 64 && evt.keyCode < 91) ||
-                    (evt.keyCode > 185 && evt.keyCode < 193) ||
-                    (evt.keyCode > 218 && evt.keyCode < 223) ||
-                    (evt.keyCode > 95 && evt.keyCode < 112)) {
+                if ((keyCode === -1) ||
+                    (keyCode === 32) ||
+                    (keyCode > 47 && keyCode < 58) ||
+                    (keyCode > 64 && keyCode < 91) ||
+                    (keyCode > 185 && keyCode < 193) ||
+                    (keyCode > 218 && keyCode < 223) ||
+                    (keyCode > 95 && keyCode < 112)) {
                     if (this._cursorOffset === 0) {
-                        this.text += evt.key;
+                        this.text += key;
                     }
                     else {
                         var insertPosition = this._text.length - this._cursorOffset;
-                        this.text = this._text.slice(0, insertPosition) + evt.key + this._text.slice(insertPosition);
+                        this.text = this._text.slice(0, insertPosition) + key + this._text.slice(insertPosition);
                     }
                 }
             };
+            InputText.prototype.processKeyboard = function (evt) {
+                this.processKey(evt.keyCode, evt.key);
+            };
             InputText.prototype._draw = function (parentMeasure, context) {
                 var _this = this;
                 context.save();
@@ -4076,3 +4090,127 @@ var BABYLON;
         GUI.InputText = InputText;
     })(GUI = BABYLON.GUI || (BABYLON.GUI = {}));
 })(BABYLON || (BABYLON = {}));
+
+/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+var BABYLON;
+(function (BABYLON) {
+    var GUI;
+    (function (GUI) {
+        var KeyOptions = (function () {
+            function KeyOptions() {
+            }
+            return KeyOptions;
+        }());
+        GUI.KeyOptions = KeyOptions;
+        var VirtualKeyboard = (function (_super) {
+            __extends(VirtualKeyboard, _super);
+            function VirtualKeyboard() {
+                var _this = _super !== null && _super.apply(this, arguments) || this;
+                _this.onKeyPressObservable = new BABYLON.Observable();
+                _this.defaultButtonWidth = "40px";
+                _this.defaultButtonHeight = "40px";
+                _this.defaultButtonPaddingLeft = "2px";
+                _this.defaultButtonPaddingRight = "2px";
+                _this.defaultButtonPaddingTop = "2px";
+                _this.defaultButtonPaddingBottom = "2px";
+                _this.defaultButtonColor = "#DDD";
+                _this.defaultButtonBackground = "#070707";
+                return _this;
+            }
+            VirtualKeyboard.prototype._getTypeName = function () {
+                return "VirtualKeyboard";
+            };
+            VirtualKeyboard.prototype._createKey = function (key, options) {
+                var _this = this;
+                var button = GUI.Button.CreateSimpleButton(key, key);
+                button.width = options && options.width ? options.width : this.defaultButtonWidth;
+                button.height = options && options.height ? options.height : this.defaultButtonHeight;
+                button.color = options && options.color ? options.color : this.defaultButtonColor;
+                button.background = options && options.background ? options.background : this.defaultButtonBackground;
+                button.paddingLeft = options && options.paddingLeft ? options.paddingLeft : this.defaultButtonPaddingLeft;
+                button.paddingRight = options && options.paddingRight ? options.paddingRight : this.defaultButtonPaddingRight;
+                button.paddingTop = options && options.paddingTop ? options.paddingTop : this.defaultButtonPaddingTop;
+                button.paddingBottom = options && options.paddingBottom ? options.paddingBottom : this.defaultButtonPaddingBottom;
+                button.thickness = 0;
+                button.isFocusInvisible = true;
+                button.onPointerUpObservable.add(function () {
+                    _this.onKeyPressObservable.notifyObservers(key);
+                });
+                return button;
+            };
+            VirtualKeyboard.prototype.addKeysRow = function (keys, options) {
+                var panel = new GUI.StackPanel();
+                panel.isVertical = false;
+                for (var i = 0; i < keys.length; i++) {
+                    var keyOptions = null;
+                    if (options && options.length === keys.length) {
+                        keyOptions = options[i];
+                    }
+                    panel.addControl(this._createKey(keys[i], keyOptions));
+                }
+                this.addControl(panel);
+            };
+            Object.defineProperty(VirtualKeyboard.prototype, "connectedInputText", {
+                get: function () {
+                    return this._connectedInputText;
+                },
+                enumerable: true,
+                configurable: true
+            });
+            VirtualKeyboard.prototype.connect = function (input) {
+                var _this = this;
+                this.isVisible = false;
+                this._connectedInputText = input;
+                // Events hooking
+                this._onFocusObserver = input.onFocusObservable.add(function () {
+                    _this.isVisible = true;
+                });
+                this._onBlurObserver = input.onBlurObservable.add(function () {
+                    _this.isVisible = false;
+                });
+                this._onKeyPressObserver = this.onKeyPressObservable.add(function (key) {
+                    switch (key) {
+                        case "\u2190":
+                            _this._connectedInputText.processKey(8);
+                            return;
+                        case "\u21B5":
+                            _this._connectedInputText.processKey(13);
+                            return;
+                    }
+                    _this._connectedInputText.processKey(-1, key);
+                });
+            };
+            VirtualKeyboard.prototype.disconnect = function () {
+                if (!this._connectedInputText) {
+                    return;
+                }
+                this._connectedInputText.onFocusObservable.remove(this._onFocusObserver);
+                this._connectedInputText.onBlurObservable.remove(this._onBlurObserver);
+                this.onKeyPressObservable.remove(this._onKeyPressObserver);
+                this._connectedInputText = null;
+            };
+            // Statics
+            VirtualKeyboard.CreateDefaultLayout = function () {
+                var returnValue = new VirtualKeyboard();
+                returnValue.addKeysRow(["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "\u2190"]);
+                returnValue.addKeysRow(["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"]);
+                returnValue.addKeysRow(["a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "\u21B5"]);
+                returnValue.addKeysRow(["z", "x", "c", "v", "b", "n", "m", ",", ".", "/"]);
+                returnValue.addKeysRow([" "], [{ width: "200px" }]);
+                return returnValue;
+            };
+            return VirtualKeyboard;
+        }(GUI.StackPanel));
+        GUI.VirtualKeyboard = VirtualKeyboard;
+    })(GUI = BABYLON.GUI || (BABYLON.GUI = {}));
+})(BABYLON || (BABYLON = {}));

File diff suppressed because it is too large
+ 3 - 3
dist/preview release/gui/babylon.gui.min.js


+ 39 - 0
dist/preview release/gui/babylon.gui.module.d.ts

@@ -168,6 +168,7 @@ declare module BABYLON.GUI {
         private _doNotRender;
         isHitTestVisible: boolean;
         isPointerBlocker: boolean;
+        isFocusInvisible: boolean;
         protected _linkOffsetX: ValueAndUnit;
         protected _linkOffsetY: ValueAndUnit;
         readonly typeName: string;
@@ -609,6 +610,7 @@ declare module BABYLON.GUI {
         private _blinkIsEven;
         private _cursorOffset;
         private _scrollLeft;
+        promptMessage: string;
         onTextChangedObservable: Observable<InputText>;
         onFocusObservable: Observable<InputText>;
         onBlurObservable: Observable<InputText>;
@@ -623,6 +625,7 @@ declare module BABYLON.GUI {
         onBlur(): void;
         onFocus(): void;
         protected _getTypeName(): string;
+        processKey(keyCode: number, key?: string): void;
         processKeyboard(evt: KeyboardEvent): void;
         _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
         protected _onPointerDown(coordinates: Vector2): boolean;
@@ -631,4 +634,40 @@ declare module BABYLON.GUI {
     }
 }
 
+/// <reference path="../../../dist/preview release/babylon.d.ts" />
+declare module BABYLON.GUI {
+    class KeyOptions {
+        width?: string;
+        height?: string;
+        paddingLeft?: string;
+        paddingRight?: string;
+        paddingTop?: string;
+        paddingBottom?: string;
+        color?: string;
+        background?: string;
+    }
+    class VirtualKeyboard extends StackPanel {
+        onKeyPressObservable: Observable<string>;
+        defaultButtonWidth: string;
+        defaultButtonHeight: string;
+        defaultButtonPaddingLeft: string;
+        defaultButtonPaddingRight: string;
+        defaultButtonPaddingTop: string;
+        defaultButtonPaddingBottom: string;
+        defaultButtonColor: string;
+        defaultButtonBackground: string;
+        protected _getTypeName(): string;
+        private _createKey(key, options?);
+        addKeysRow(keys: Array<string>, options?: Array<KeyOptions>): void;
+        private _connectedInputText;
+        private _onFocusObserver;
+        private _onBlurObserver;
+        private _onKeyPressObserver;
+        readonly connectedInputText: InputText;
+        connect(input: InputText): void;
+        disconnect(): void;
+        static CreateDefaultLayout(): VirtualKeyboard;
+    }
+}
+
 export = BABYLON.GUI;

File diff suppressed because it is too large
+ 263 - 263
dist/preview release/inspector/babylon.inspector.bundle.js


File diff suppressed because it is too large
+ 3 - 3
dist/preview release/inspector/babylon.inspector.min.js


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/loaders/babylon.glTFFileLoader.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js


+ 4 - 0
gui/src/advancedDynamicTexture.ts

@@ -330,6 +330,10 @@ module BABYLON.GUI {
             // Focus management
             if (this._focusedControl) {
                 if (this._focusedControl !== (<any>this._lastPickedControl)) {
+                    if (this._lastPickedControl.isFocusInvisible) {
+                        return;
+                    }
+
                     this.focusedControl = null;
                 }
             }

+ 1 - 0
gui/src/controls/control.ts

@@ -47,6 +47,7 @@ module BABYLON.GUI {
 
         public isHitTestVisible = true;
         public isPointerBlocker = false;
+        public isFocusInvisible = false;
 
         protected _linkOffsetX = new ValueAndUnit(0);
         protected _linkOffsetY = new ValueAndUnit(0);

+ 23 - 10
gui/src/controls/inputText.ts

@@ -15,6 +15,8 @@ module BABYLON.GUI {
         private _cursorOffset = 0;        
         private _scrollLeft: number;
 
+        public promptMessage = "Please enter text:";
+
         public onTextChangedObservable = new Observable<InputText>();
         public onFocusObservable = new Observable<InputText>();
         public onBlurObservable = new Observable<InputText>();
@@ -137,15 +139,21 @@ module BABYLON.GUI {
             this._markAsDirty();
 
             this.onFocusObservable.notifyObservers(this);
+
+            if (navigator.userAgent.indexOf("Mobile") !== -1) {
+                this.text = prompt(this.promptMessage);
+                this._host.focusedControl = null;
+                return;
+            }
         }
 
         protected _getTypeName(): string {
             return "InputText";
         }
 
-        public processKeyboard(evt: KeyboardEvent): void {
+        public processKey(keyCode: number, key?: string) {
             // Specific cases
-            switch (evt.keyCode) {
+            switch (keyCode) {
                 case 8: // BACKSPACE
                     if (this._text && this._text.length > 0) {
                         if (this._cursorOffset === 0) {
@@ -198,22 +206,27 @@ module BABYLON.GUI {
 
             // Printable characters
             if (
-                (evt.keyCode === 32) ||                         // Space
-                (evt.keyCode > 47 && evt.keyCode < 58) ||       // Numbers
-                (evt.keyCode > 64 && evt.keyCode < 91) ||       // Letters
-                (evt.keyCode > 185 && evt.keyCode < 193) ||     // Special characters
-                (evt.keyCode > 218  && evt.keyCode < 223) ||    // Special characters
-                (evt.keyCode > 95 && evt.keyCode < 112)) {      // Numpad
+                (keyCode === -1) ||                     // Direct access
+                (keyCode === 32) ||                     // Space
+                (keyCode > 47 && keyCode < 58) ||       // Numbers
+                (keyCode > 64 && keyCode < 91) ||       // Letters
+                (keyCode > 185 && keyCode < 193) ||     // Special characters
+                (keyCode > 218  && keyCode < 223) ||    // Special characters
+                (keyCode > 95 && keyCode < 112)) {      // Numpad
                     if (this._cursorOffset === 0) {
-                        this.text += evt.key;
+                        this.text += key;
                     } else {
                         let insertPosition = this._text.length - this._cursorOffset;
 
-                        this.text = this._text.slice(0, insertPosition) + evt.key + this._text.slice(insertPosition);
+                        this.text = this._text.slice(0, insertPosition) + key + this._text.slice(insertPosition);
                     }
                 }
         }
 
+        public processKeyboard(evt: KeyboardEvent): void {
+            this.processKey(evt.keyCode, evt.key);
+        }
+
         public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
             context.save();
 

+ 135 - 0
gui/src/controls/virtualKeyboard.ts

@@ -0,0 +1,135 @@
+/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+
+module BABYLON.GUI {
+
+    export class KeyOptions {
+        width?: string;
+        height?: string;
+        paddingLeft?: string;
+        paddingRight?: string;
+        paddingTop?: string;
+        paddingBottom?: string;
+        color?: string;
+        background?: string;
+    }
+
+    export class VirtualKeyboard extends StackPanel {
+        public onKeyPressObservable = new Observable<string>();
+
+        public defaultButtonWidth = "40px";
+        public defaultButtonHeight = "40px";
+
+        public defaultButtonPaddingLeft= "2px";
+        public defaultButtonPaddingRight = "2px";
+        public defaultButtonPaddingTop = "2px";
+        public defaultButtonPaddingBottom = "2px";    
+        
+        public defaultButtonColor = "#DDD";
+        public defaultButtonBackground = "#070707";    
+        
+        protected _getTypeName(): string {
+            return "VirtualKeyboard";
+        }
+
+        private _createKey(key: string, options?: KeyOptions) {
+            var button = Button.CreateSimpleButton(key, key);
+            
+           
+            button.width = options && options.width ? options.width : this.defaultButtonWidth;
+            button.height = options && options.height ? options.height : this.defaultButtonHeight;
+            button.color = options && options.color ? options.color : this.defaultButtonColor;
+            button.background = options && options.background ? options.background : this.defaultButtonBackground;
+            button.paddingLeft = options && options.paddingLeft ? options.paddingLeft : this.defaultButtonPaddingLeft;
+            button.paddingRight = options && options.paddingRight ? options.paddingRight : this.defaultButtonPaddingRight;
+            button.paddingTop = options && options.paddingTop ? options.paddingTop : this.defaultButtonPaddingTop;
+            button.paddingBottom = options && options.paddingBottom ? options.paddingBottom : this.defaultButtonPaddingBottom;
+        
+            button.thickness = 0;
+            button.isFocusInvisible = true;
+        
+            button.onPointerUpObservable.add(() => {
+                this.onKeyPressObservable.notifyObservers(key);
+            });
+    
+            return button;
+        }
+
+        public addKeysRow(keys: Array<string>, options?: Array<KeyOptions>): void {
+            let panel = new StackPanel();
+            panel.isVertical = false;
+        
+            for(var i = 0; i < keys.length; i++) {
+                let keyOptions = null;
+
+                if (options && options.length === keys.length) {
+                    keyOptions = options[i];
+                }
+
+                panel.addControl(this._createKey(keys[i], keyOptions));
+            }
+        
+            this.addControl(panel);
+        }
+
+        private _connectedInputText: InputText;
+        private _onFocusObserver: Observer<InputText>;
+        private _onBlurObserver: Observer<InputText>;
+        private _onKeyPressObserver: Observer<string>;
+
+        public get connectedInputText(): InputText {
+            return this._connectedInputText;
+        }
+
+        public connect(input: InputText): void {
+            this.isVisible = false;
+            this._connectedInputText = input;
+            
+            // Events hooking
+            this._onFocusObserver = input.onFocusObservable.add(() => {
+                this.isVisible = true;
+            });
+    
+            this._onBlurObserver = input.onBlurObservable.add(() => {
+                this.isVisible = false;
+            });		
+
+            this._onKeyPressObserver = this.onKeyPressObservable.add((key) => {
+                switch (key) {
+                    case "\u2190":
+                        this._connectedInputText.processKey(8);
+                        return;
+                    case "\u21B5":
+                        this._connectedInputText.processKey(13);
+                        return;                        
+                }
+
+                this._connectedInputText.processKey(-1, key);
+            });
+        }
+
+        public disconnect(): void {
+            if (!this._connectedInputText) {
+                return;
+            }
+
+            this._connectedInputText.onFocusObservable.remove(this._onFocusObserver);
+            this._connectedInputText.onBlurObservable.remove(this._onBlurObserver);
+            this.onKeyPressObservable.remove(this._onKeyPressObserver);
+
+            this._connectedInputText = null;
+        }
+
+        // Statics
+        public static CreateDefaultLayout(): VirtualKeyboard {
+            let returnValue = new VirtualKeyboard();
+
+            returnValue.addKeysRow(["1", "2", "3", "4", "5", "6", "7", "8", "9", "0","\u2190"]);
+            returnValue.addKeysRow(["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"]);
+            returnValue.addKeysRow(["a", "s", "d", "f", "g", "h", "j", "k", "l",";","'","\u21B5"]);
+            returnValue.addKeysRow(["z", "x", "c", "v", "b", "n", "m", ",", ".", "/"]);
+            returnValue.addKeysRow([" "], [{ width: "200px"}]);
+        
+            return returnValue;
+        }
+    }
+}