|
@@ -0,0 +1,914 @@
|
|
|
|
+let PIXI = null;
|
|
|
|
+if (typeof module !== 'undefined') {
|
|
|
|
+ PIXI = require("pixi.js");
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Text input field for pixi.js.
|
|
|
|
+ * A simple example:
|
|
|
|
+ *
|
|
|
|
+ * // We need a container
|
|
|
|
+ * var container = new PIXI.Container();
|
|
|
|
+ *
|
|
|
|
+ * // Same style options as PIXI.Text
|
|
|
|
+ * var style={ ... };
|
|
|
|
+ *
|
|
|
|
+ * var inputField = new PixiTextInput("hello",style);
|
|
|
|
+ * container.addChild(inputField);
|
|
|
|
+ *
|
|
|
|
+ * The style definitions accepted by the constructor are the same as those accepted by
|
|
|
|
+ * [PIXI.Text](http://www.goodboydigital.com/pixijs/docs/classes/Text.html).
|
|
|
|
+ * @class PixiTextInput
|
|
|
|
+ * @constructor
|
|
|
|
+ * @param {String} [text] The initial text.
|
|
|
|
+ * @param {Object} [style] Style definition, same as for PIXI.Text
|
|
|
|
+ * @param {Boolean} [password] Indicate if field should be shown as a password field
|
|
|
|
+ * @param {Boolean} [useNativeTextInput] Indicate if the textfield should create a native fallback for mobile
|
|
|
|
+ */
|
|
|
|
+function PixiTextInput(text, style, password, useNativeTextInput) {
|
|
|
|
+ PIXI.Container.call(this);
|
|
|
|
+ window.pixiTextInputTarget = this;
|
|
|
|
+
|
|
|
|
+ if (!text)
|
|
|
|
+ text = "";
|
|
|
|
+
|
|
|
|
+ text = text.toString();
|
|
|
|
+
|
|
|
|
+ if (style && style.wordWrap)
|
|
|
|
+ throw Error("wordWrap is not supported for input fields");
|
|
|
|
+
|
|
|
|
+ this._text = text;
|
|
|
|
+ this._placeholder = "";
|
|
|
|
+
|
|
|
|
+ if (useNativeTextInput) {
|
|
|
|
+ this._nativeTextInput = this.getNativeTextInput(password);
|
|
|
|
+ this.bindNativeTextInput();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.localWidth = 100;
|
|
|
|
+ this._backgroundColor = 0xffffff;
|
|
|
|
+ this._caretColor = 0x000000;
|
|
|
|
+ this._borderColor = 0x000000;
|
|
|
|
+ this._borderWidth = 0;
|
|
|
|
+ this._background = true;
|
|
|
|
+ this._password = false;
|
|
|
|
+ this._value = text;
|
|
|
|
+
|
|
|
|
+ if ( typeof password !== "undefined" && password !== undefined && password === true ) {
|
|
|
|
+ this._password = true;
|
|
|
|
+ this.syncValue();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.style = style;
|
|
|
|
+ this.textField = new PIXI.Text(this._value, style);
|
|
|
|
+
|
|
|
|
+ this.localHeight =
|
|
|
|
+ this.textField.style.fontSize +
|
|
|
|
+ this.textField.style.strokeThickness
|
|
|
|
+ + 4;
|
|
|
|
+
|
|
|
|
+ this.textColor = this.textField.style.fill;
|
|
|
|
+
|
|
|
|
+ this.backgroundGraphics = new PIXI.Graphics();
|
|
|
|
+ this.textFieldMask = new PIXI.Graphics();
|
|
|
|
+ this.selectionGraphics = new PIXI.Graphics();
|
|
|
|
+ this.caret = new PIXI.Graphics();
|
|
|
|
+ this.drawElements();
|
|
|
|
+
|
|
|
|
+ this.addChild(this.backgroundGraphics);
|
|
|
|
+ this.addChild(this.selectionGraphics);
|
|
|
|
+ this.addChild(this.textField);
|
|
|
|
+ this.addChild(this.caret);
|
|
|
|
+ this.addChild(this.textFieldMask);
|
|
|
|
+
|
|
|
|
+ this.scrollIndex = 0;
|
|
|
|
+ this._caretIndex = 0;
|
|
|
|
+ this.caretFlashInterval = null;
|
|
|
|
+ this._secondCaretIndex = 0;
|
|
|
|
+ this.blur();
|
|
|
|
+ this.updateCaretPosition();
|
|
|
|
+
|
|
|
|
+ this.backgroundGraphics.interactive = true;
|
|
|
|
+ this.backgroundGraphics.buttonMode = true;
|
|
|
|
+ this.backgroundGraphics.defaultCursor = "text";
|
|
|
|
+
|
|
|
|
+ this.backgroundGraphics.mousedown = this.onBackgroundMouseDown.bind(this);
|
|
|
|
+ this.keyEventClosure = this.onKeyEvent.bind(this);
|
|
|
|
+ this.windowBlurClosure = this.onWindowBlur.bind(this);
|
|
|
|
+ this.documentMouseDownClosure = this.onDocumentMouseDown.bind(this);
|
|
|
|
+ this.isFocusClick = false;
|
|
|
|
+
|
|
|
|
+ this.updateText();
|
|
|
|
+
|
|
|
|
+ this.textField.mask = this.textFieldMask;
|
|
|
|
+
|
|
|
|
+ this.keypress = null;
|
|
|
|
+ this.keydown = null;
|
|
|
|
+ this.change = null;
|
|
|
|
+
|
|
|
|
+ this.ctrlDown = false;
|
|
|
|
+ this.shiftDown = false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+PixiTextInput.prototype = Object.create(PIXI.Container.prototype);
|
|
|
|
+PixiTextInput.prototype.constructor = PixiTextInput;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Someone clicked.
|
|
|
|
+ * @method onBackgroundMouseDown
|
|
|
|
+ * @private
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.onBackgroundMouseDown = function(e) {
|
|
|
|
+ if (this._nativeTextInput) {
|
|
|
|
+ this._nativeTextInput.focus();
|
|
|
|
+ }
|
|
|
|
+ var x = this.toLocal(e.data.global).x;
|
|
|
|
+ this._caretIndex = this.getCaretIndexByCoord(x);
|
|
|
|
+ this.updateCaretPosition();
|
|
|
|
+
|
|
|
|
+ this.focus();
|
|
|
|
+
|
|
|
|
+ this.isFocusClick = true;
|
|
|
|
+ var scope = this;
|
|
|
|
+ setTimeout(function() {
|
|
|
|
+ scope.isFocusClick = false;
|
|
|
|
+ }, 0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Focus this input field.
|
|
|
|
+ * @method focus
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.focus = function() {
|
|
|
|
+ window.pixiTextInputTarget = this;
|
|
|
|
+ this.blur();
|
|
|
|
+
|
|
|
|
+ this.handleCopyReference = this.handleCopy.bind(this);
|
|
|
|
+ document.addEventListener("copy", this.handleCopyReference);
|
|
|
|
+ this.handleCutReference = this.handleCut.bind(this);
|
|
|
|
+ document.addEventListener("cut", this.handleCutReference);
|
|
|
|
+ this.handlePasteReference = this.handlePaste.bind(this);
|
|
|
|
+ document.addEventListener("paste", this.handlePasteReference);
|
|
|
|
+
|
|
|
|
+ document.addEventListener("keydown", this.keyEventClosure);
|
|
|
|
+ document.addEventListener("keypress", this.keyEventClosure);
|
|
|
|
+ document.addEventListener("keyup", this.keyEventClosure);
|
|
|
|
+ document.addEventListener("mousedown", this.documentMouseDownClosure);
|
|
|
|
+
|
|
|
|
+ window.addEventListener("blur", this.windowBlurClosure);
|
|
|
|
+
|
|
|
|
+ if(this._nativeTextInput) {
|
|
|
|
+ this._nativeTextInput.focus();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.showCaret();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Handle key event.
|
|
|
|
+ * @method onKeyEvent
|
|
|
|
+ * @private
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.onKeyEvent = function(e) {
|
|
|
|
+ //console.log("key event");
|
|
|
|
+ //console.log(e);
|
|
|
|
+ //console.log(this.scrollIndex);
|
|
|
|
+
|
|
|
|
+ if (e.type === "keypress") {
|
|
|
|
+ if (e.charCode < 32){
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if(e.charCode===32){
|
|
|
|
+ e.preventDefault();
|
|
|
|
+ }
|
|
|
|
+ if(this.ctrlDown && (e.charCode===67 ||
|
|
|
|
+ e.charCode===99 ||
|
|
|
|
+ e.charCode===86 ||
|
|
|
|
+ e.charCode===118 ||
|
|
|
|
+ e.charCode===88 ||
|
|
|
|
+ e.charCode===120) ){
|
|
|
|
+ //console.log("ctrl+c|v|x");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(this._selection){
|
|
|
|
+ this.deleteSelectedText();
|
|
|
|
+ this.moveCarretRight();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this._text =
|
|
|
|
+ this._text.substring(0, this._caretIndex) +
|
|
|
|
+ String.fromCharCode(e.charCode) +
|
|
|
|
+ this._text.substring(this._caretIndex);
|
|
|
|
+
|
|
|
|
+ this._selection = false;
|
|
|
|
+ this.syncValue();
|
|
|
|
+
|
|
|
|
+ this._caretIndex++;
|
|
|
|
+ this.ensureCaretInView();
|
|
|
|
+ this.showCaret();
|
|
|
|
+ this.updateText();
|
|
|
|
+ this.drawElements();
|
|
|
|
+ this.trigger(this.keypress, e);
|
|
|
|
+ this.trigger(this.change);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (e.type === "keydown") {
|
|
|
|
+ switch (e.keyCode) {
|
|
|
|
+ case 8: //backspace
|
|
|
|
+ if(this._selection){
|
|
|
|
+ this.deleteSelectedText();
|
|
|
|
+ } else if (this._caretIndex > 0) {
|
|
|
|
+ this._text =
|
|
|
|
+ this._text.substring(0, this._caretIndex - 1) +
|
|
|
|
+ this._text.substring(this._caretIndex);
|
|
|
|
+
|
|
|
|
+ this.syncValue();
|
|
|
|
+
|
|
|
|
+ this._caretIndex--;
|
|
|
|
+ this.ensureCaretInView();
|
|
|
|
+ this.showCaret();
|
|
|
|
+ this.updateText();
|
|
|
|
+ }
|
|
|
|
+ e.preventDefault();
|
|
|
|
+ this.trigger(this.change);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case 16://shift
|
|
|
|
+ this.shiftDown = true;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case 17:
|
|
|
|
+ this.ctrlDown = true;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case 35:
|
|
|
|
+ this._caretIndex = this._text.length;
|
|
|
|
+ e.preventDefault();
|
|
|
|
+
|
|
|
|
+ this.ensureCaretInView();
|
|
|
|
+ this.updateCaretPosition();
|
|
|
|
+ this.showCaret();
|
|
|
|
+ this.updateText();
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case 36:
|
|
|
|
+ this._caretIndex = 0;
|
|
|
|
+ e.preventDefault();
|
|
|
|
+
|
|
|
|
+ this.ensureCaretInView();
|
|
|
|
+ this.updateCaretPosition();
|
|
|
|
+ this.showCaret();
|
|
|
|
+ this.updateText();
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case 46:
|
|
|
|
+ this._text =
|
|
|
|
+ this._text.substring(0, this._caretIndex) +
|
|
|
|
+ this._text.substring(this._caretIndex + 1);
|
|
|
|
+
|
|
|
|
+ this.syncValue();
|
|
|
|
+
|
|
|
|
+ this.ensureCaretInView();
|
|
|
|
+ this.updateCaretPosition();
|
|
|
|
+ this.showCaret();
|
|
|
|
+ this.updateText();
|
|
|
|
+ e.preventDefault();
|
|
|
|
+ this.trigger(this.change);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case 39://right arrow
|
|
|
|
+ if(this.shiftDown && !this._selection){
|
|
|
|
+ this._selection=true;
|
|
|
|
+ this._secondCaretIndex = this._caretIndex;
|
|
|
|
+ }
|
|
|
|
+ /*if(this.shiftDown && this._selection){
|
|
|
|
+ if(this._secondCaretIndex+1<this._text.length){
|
|
|
|
+ this._secondCaretIndex++;
|
|
|
|
+ }
|
|
|
|
+ } else {*/
|
|
|
|
+ if(this.ctrlDown && this._caretIndex+1 < this._text.length){
|
|
|
|
+ let nextPosition = this._text.indexOf(" ", this._caretIndex);
|
|
|
|
+ if(nextPosition!==this._caretIndex){
|
|
|
|
+ this._caretIndex = (nextPosition!==-1)?nextPosition:this._text.length;
|
|
|
|
+ } else this.moveCarretRight();
|
|
|
|
+ } else this.moveCarretRight();
|
|
|
|
+ //}
|
|
|
|
+ if(!this.shiftDown){
|
|
|
|
+ this._selection = false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.ensureCaretInView();
|
|
|
|
+ this.updateCaretPosition();
|
|
|
|
+ this.showCaret();
|
|
|
|
+ this.updateText();
|
|
|
|
+ this.drawElements();
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case 37://left arrow
|
|
|
|
+ if(this.shiftDown && !this._selection){
|
|
|
|
+ this._selection=true;
|
|
|
|
+ this._secondCaretIndex = this._caretIndex;
|
|
|
|
+ }
|
|
|
|
+ /*if(this.shiftDown && this._selection){
|
|
|
|
+ if(this._secondCaretIndex+1>0){
|
|
|
|
+ this._secondCaretIndex--;
|
|
|
|
+ }
|
|
|
|
+ } else {*/
|
|
|
|
+ if(this.ctrlDown && this._caretIndex+1 > 0){
|
|
|
|
+ let nextPosition = this._text.lastIndexOf(" ", this._caretIndex-1);
|
|
|
|
+ if(nextPosition!==this._caretIndex){
|
|
|
|
+ this._caretIndex = (nextPosition!==-1)?nextPosition:0;
|
|
|
|
+ } else this.moveCarretLeft();
|
|
|
|
+ } else this.moveCarretLeft();
|
|
|
|
+ //}
|
|
|
|
+ if(!this.shiftDown){
|
|
|
|
+ this._selection = false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.ensureCaretInView();
|
|
|
|
+ this.updateCaretPosition();
|
|
|
|
+ this.showCaret();
|
|
|
|
+ this.updateText();
|
|
|
|
+ this.drawElements();
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case 65://A
|
|
|
|
+ if(this.ctrlDown){
|
|
|
|
+ this._selection = true;
|
|
|
|
+ this._caretIndex = 0;
|
|
|
|
+ this._secondCaretIndex = this._text.length;
|
|
|
|
+ this.drawElements();
|
|
|
|
+ e.preventDefault();
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ default:break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.trigger(this.keydown, e);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(e.type === "keyup"){
|
|
|
|
+ switch (e.keyCode) {
|
|
|
|
+ case 16:
|
|
|
|
+ this.shiftDown = false;
|
|
|
|
+ break;
|
|
|
|
+ case 17:
|
|
|
|
+ this.ctrlDown = false;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+PixiTextInput.prototype.handleCopy = function(e){
|
|
|
|
+ e.clipboardData.setData('text/plain', this.getSelectedText());
|
|
|
|
+ e.preventDefault();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+PixiTextInput.prototype.handleCut = function(e){
|
|
|
|
+ e.clipboardData.setData('text/plain', this.getSelectedText());
|
|
|
|
+ if(this._selection){
|
|
|
|
+ this.deleteSelectedText();
|
|
|
|
+ this.moveCarretRight();
|
|
|
|
+ }
|
|
|
|
+ e.preventDefault();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+PixiTextInput.prototype.handlePaste = function(e){
|
|
|
|
+ var txtToInsert = e.clipboardData.getData('text/plain');
|
|
|
|
+ if(this._selection){
|
|
|
|
+ this.deleteSelectedText();
|
|
|
|
+ this.moveCarretRight();
|
|
|
|
+ }
|
|
|
|
+ this.insertText(txtToInsert);
|
|
|
|
+ e.preventDefault();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+PixiTextInput.prototype.deleteSelectedText = function(e){
|
|
|
|
+ var startPosition;
|
|
|
|
+ var endPosition;
|
|
|
|
+ if(this._caretIndex>this._secondCaretIndex){
|
|
|
|
+ startPosition = this._secondCaretIndex;
|
|
|
|
+ endPosition = this._caretIndex;
|
|
|
|
+ } else {
|
|
|
|
+ startPosition = this._caretIndex;
|
|
|
|
+ endPosition = this._secondCaretIndex;
|
|
|
|
+ }
|
|
|
|
+ if(startPosition===0 && endPosition===this._text.length){
|
|
|
|
+ this._text = "";
|
|
|
|
+ } else {
|
|
|
|
+ this._text =
|
|
|
|
+ this._text.substring(0, startPosition) +
|
|
|
|
+ this._text.substring(endPosition);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this._selection = false;
|
|
|
|
+
|
|
|
|
+ this.syncValue();
|
|
|
|
+
|
|
|
|
+ this._caretIndex=startPosition;
|
|
|
|
+ if(this._caretIndex<0){
|
|
|
|
+ this._caretIndex=0;
|
|
|
|
+ }
|
|
|
|
+ this.ensureCaretInView();
|
|
|
|
+ this.showCaret();
|
|
|
|
+ this.updateText();
|
|
|
|
+ this.drawElements();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+PixiTextInput.prototype.insertText = function(txt){
|
|
|
|
+ this._text = this._text.substring(0, this._caretIndex)
|
|
|
|
+ + txt
|
|
|
|
+ + this._text.substring(this._caretIndex);
|
|
|
|
+
|
|
|
|
+ this._selection = false;
|
|
|
|
+ this._caretIndex += txt.length;
|
|
|
|
+ this.updateCaretPosition();
|
|
|
|
+ this.syncValue();
|
|
|
|
+ this.ensureCaretInView();
|
|
|
|
+ this.showCaret();
|
|
|
|
+ this.updateText();
|
|
|
|
+ this.drawElements();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+PixiTextInput.prototype.moveCarretRight = function(){
|
|
|
|
+ if(this._selection && !this.shiftDown){
|
|
|
|
+ if(this._caretIndex<this._secondCaretIndex){
|
|
|
|
+ this._caretIndex = this._secondCaretIndex;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ this._caretIndex++;
|
|
|
|
+ if (this._caretIndex > this._text.length){
|
|
|
|
+ this._caretIndex = this._text.length;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+PixiTextInput.prototype.moveCarretLeft = function(){
|
|
|
|
+ if(this._selection && !this.shiftDown){
|
|
|
|
+ if(this._caretIndex>this._secondCaretIndex){
|
|
|
|
+ this._caretIndex = this._secondCaretIndex;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ this._caretIndex--;
|
|
|
|
+ if (this._caretIndex < 0){
|
|
|
|
+ this._caretIndex = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Ensure the caret is not outside the bounds.
|
|
|
|
+ * @method ensureCaretInView
|
|
|
|
+ * @private
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.ensureCaretInView = function() {
|
|
|
|
+ this.updateCaretPosition();
|
|
|
|
+
|
|
|
|
+ while (this.caret.position.x >= this.localWidth - 1) {
|
|
|
|
+ this.scrollIndex++;
|
|
|
|
+ this.updateCaretPosition();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ while (this.caret.position.x < 0) {
|
|
|
|
+ this.scrollIndex -= 2;
|
|
|
|
+ if (this.scrollIndex < 0)
|
|
|
|
+ this.scrollIndex = 0;
|
|
|
|
+ this.updateCaretPosition();
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Blur ourself.
|
|
|
|
+ * @method blur
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.blur = function() {
|
|
|
|
+ document.removeEventListener("copy", this.handleCopyReference);
|
|
|
|
+ document.removeEventListener("cut", this.handleCutReference);
|
|
|
|
+ document.removeEventListener("paste", this.handlePasteReference);
|
|
|
|
+
|
|
|
|
+ document.removeEventListener("keydown", this.keyEventClosure);
|
|
|
|
+ document.removeEventListener("keypress", this.keyEventClosure);
|
|
|
|
+ document.removeEventListener("keyup", this.keyEventClosure);
|
|
|
|
+ document.removeEventListener("mousedown", this.documentMouseDownClosure);
|
|
|
|
+ window.removeEventListener("blur", this.windowBlurClosure);
|
|
|
|
+
|
|
|
|
+ this.hideCaret();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Window blur.
|
|
|
|
+ * @method onDocumentMouseDown
|
|
|
|
+ * @private
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.onDocumentMouseDown = function() {
|
|
|
|
+ if (this._nativeTextInput) {
|
|
|
|
+ this._nativeTextInput.blur();
|
|
|
|
+ }
|
|
|
|
+ if (!this.isFocusClick)
|
|
|
|
+ this.blur();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Window blur.
|
|
|
|
+ * @method onWindowBlur
|
|
|
|
+ * @private
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.onWindowBlur = function() {
|
|
|
|
+ if (this._nativeTextInput) {
|
|
|
|
+ this._nativeTextInput.blur();
|
|
|
|
+ }
|
|
|
|
+ this.blur();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Update caret Position.
|
|
|
|
+ * @method updateCaretPosition
|
|
|
|
+ * @private
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.updateCaretPosition = function() {
|
|
|
|
+ if (this._caretIndex < this.scrollIndex) {
|
|
|
|
+ this.caret.position.x = -1;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var sub = this._value.substring(0, this._caretIndex).substring(this.scrollIndex);
|
|
|
|
+ this.caret.position.x = this.textField.context.measureText(sub).width;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Update text.
|
|
|
|
+ * @method updateText
|
|
|
|
+ * @private
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.updateText = function() {
|
|
|
|
+ this.textField.text = this._value.substring(this.scrollIndex);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Sync the password field value
|
|
|
|
+ * @method syncValue
|
|
|
|
+ * @private
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.syncValue = function() {
|
|
|
|
+ if(this.textField && this.textField.style.fill!==this.textColor){
|
|
|
|
+ this.textField.style.fill = this.textColor;
|
|
|
|
+ this.textField.alpha = 1;
|
|
|
|
+ }
|
|
|
|
+ if (this._password) {
|
|
|
|
+ this._value = this._text.replace(/./g,"*");
|
|
|
|
+ } else if(this._text.length===0 && this._placeholder) {
|
|
|
|
+ this._value = this._placeholder;
|
|
|
|
+ if(this.textField){
|
|
|
|
+ this.textField.style.fill = 0xCCCCCC;
|
|
|
|
+ this.textField.alpha = 0.5;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ this._value = this._text;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Draw the background and caret.
|
|
|
|
+ * @method drawElements
|
|
|
|
+ * @private
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.drawElements = function() {
|
|
|
|
+ this.backgroundGraphics.clear();
|
|
|
|
+ this.backgroundGraphics.beginFill(this._backgroundColor);
|
|
|
|
+
|
|
|
|
+ if (this._borderWidth > 0) {
|
|
|
|
+ this.backgroundGraphics.lineStyle( this._borderWidth, this._borderColor );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this._background) {
|
|
|
|
+ this.backgroundGraphics.drawRect(0, 0, this.localWidth, this.localHeight);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.selectionGraphics.clear();
|
|
|
|
+ if(this._selection && this._caretIndex!==this._secondCaretIndex){
|
|
|
|
+ var selectionStart;
|
|
|
|
+ var selectionEnd;
|
|
|
|
+ var offset = 0;
|
|
|
|
+ if(this._caretIndex>this._secondCaretIndex){
|
|
|
|
+ selectionStart = this._secondCaretIndex;
|
|
|
|
+ selectionEnd = this._caretIndex;
|
|
|
|
+ } else {
|
|
|
|
+ selectionStart = this._caretIndex;
|
|
|
|
+ selectionEnd = this._secondCaretIndex;
|
|
|
|
+ }
|
|
|
|
+ if(selectionStart>0){
|
|
|
|
+ offset = this.textField.context.measureText(this._text.substring(0, selectionStart)).width;
|
|
|
|
+ if(this.scrollIndex){
|
|
|
|
+ offset -= this.textField.context.measureText(this._text.substring(0, this.scrollIndex)).width;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ var sub = this._text.substring(selectionStart, selectionEnd);
|
|
|
|
+ var selectedWidth = this.textField.context.measureText(sub).width;
|
|
|
|
+ if(offset+selectedWidth>this.localWidth){
|
|
|
|
+ selectedWidth = this.localWidth-offset;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ var sub = this._value.substring(0, this._caretIndex).substring(this.scrollIndex);
|
|
|
|
+ this.caret.position.x = this.textField.context.measureText(sub).width;
|
|
|
|
+ */
|
|
|
|
+ this.selectionGraphics.beginFill(0xDDDDDD, 0.3);
|
|
|
|
+ this.selectionGraphics.drawRect(offset, 0, selectedWidth, this.localHeight)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.backgroundGraphics.endFill();
|
|
|
|
+ this.backgroundGraphics.hitArea = new PIXI.Rectangle(0, 0, this.localWidth, this.localHeight);
|
|
|
|
+
|
|
|
|
+ this.textFieldMask.clear();
|
|
|
|
+ this.textFieldMask.beginFill(this._backgroundColor);
|
|
|
|
+ this.textFieldMask.drawRect(0, 0, this.localWidth, this.localHeight);
|
|
|
|
+ this.textFieldMask.endFill();
|
|
|
|
+
|
|
|
|
+ this.caret.clear();
|
|
|
|
+ this.caret.beginFill(this._caretColor);
|
|
|
|
+ this.caret.drawRect(1, 1, 1, this.localHeight - 2);
|
|
|
|
+ this.caret.endFill();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Show caret.
|
|
|
|
+ * @method showCaret
|
|
|
|
+ * @private
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.showCaret = function() {
|
|
|
|
+ if (this.caretFlashInterval) {
|
|
|
|
+ clearInterval(this.caretFlashInterval);
|
|
|
|
+ this.caretFlashInterval = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.caret.visible = true;
|
|
|
|
+ this.caretFlashInterval = setInterval(this.onCaretFlashInterval.bind(this), 500);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Hide caret.
|
|
|
|
+ * @method hideCaret
|
|
|
|
+ * @private
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.hideCaret = function() {
|
|
|
|
+ if (this.caretFlashInterval) {
|
|
|
|
+ clearInterval(this.caretFlashInterval);
|
|
|
|
+ this.caretFlashInterval = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.caret.visible = false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Caret flash interval.
|
|
|
|
+ * @method onCaretFlashInterval
|
|
|
|
+ * @private
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.onCaretFlashInterval = function() {
|
|
|
|
+ this.caret.visible = !this.caret.visible;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Map position to caret index.
|
|
|
|
+ * @method getCaretIndexByCoord
|
|
|
|
+ * @private
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.getCaretIndexByCoord = function(x) {
|
|
|
|
+ var smallest = 10000;
|
|
|
|
+ var cand = 0;
|
|
|
|
+ var visible = this._text.substring(this.scrollIndex);
|
|
|
|
+
|
|
|
|
+ for (let i = 0; i < visible.length + 1; i++) {
|
|
|
|
+ var sub = visible.substring(0, i);
|
|
|
|
+ var w = this.textField.context.measureText(sub).width;
|
|
|
|
+
|
|
|
|
+ if (Math.abs(w - x) < smallest) {
|
|
|
|
+ smallest = Math.abs(w - x);
|
|
|
|
+ cand = i;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return this.scrollIndex + cand;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+PixiTextInput.prototype.getSelectedText = function(){
|
|
|
|
+ if(this._selection){
|
|
|
|
+ if(this._caretIndex<this._secondCaretIndex){
|
|
|
|
+ return this._text.substring(this._caretIndex, this._secondCaretIndex);
|
|
|
|
+ } else if(this._caretIndex>this._secondCaretIndex){
|
|
|
|
+ return this._text.substring(this._secondCaretIndex, this._caretIndex);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return "";
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * The width of the PixiTextInput. This is overridden to have a slightly
|
|
|
|
+ * different behaivour than the other DisplayObjects. Setting the
|
|
|
|
+ * width of the PixiTextInput does not change the scale, but it rather
|
|
|
|
+ * makes the field larger. If you actually want to scale it,
|
|
|
|
+ * use the scale property.
|
|
|
|
+ * @property width
|
|
|
|
+ * @type Number
|
|
|
|
+ */
|
|
|
|
+Object.defineProperty(PixiTextInput.prototype, "width", {
|
|
|
|
+ get: function() {
|
|
|
|
+ return this.scale.x * this.getLocalBounds().width;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ set: function(v) {
|
|
|
|
+ this.localWidth = v;
|
|
|
|
+ this.drawElements();
|
|
|
|
+ this.ensureCaretInView();
|
|
|
|
+ this.updateText();
|
|
|
|
+ }
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * The text in the input field. Setting will have the implicit function of resetting the scroll
|
|
|
|
+ * of the input field and removing focus.
|
|
|
|
+ * @property text
|
|
|
|
+ * @type String
|
|
|
|
+ */
|
|
|
|
+Object.defineProperty(PixiTextInput.prototype, "text", {
|
|
|
|
+ get: function() {
|
|
|
|
+ return this._text;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ set: function(v) {
|
|
|
|
+ this._text = v.toString();
|
|
|
|
+ this.syncValue();
|
|
|
|
+ this.scrollIndex = 0;
|
|
|
|
+ this.caretIndex = 0;
|
|
|
|
+ this.blur();
|
|
|
|
+ this.updateText();
|
|
|
|
+ }
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * The color of the background for the input field.
|
|
|
|
+ * This needs to be specified as an integer, not using HTML
|
|
|
|
+ * notation, e.g. for red background:
|
|
|
|
+ *
|
|
|
|
+ * myInputText.backgroundColor = 0xff0000;
|
|
|
|
+ *
|
|
|
|
+ * In order for the background to be drawn, the `background`
|
|
|
|
+ * property needs to be true. If not, this property will have
|
|
|
|
+ * no effect.
|
|
|
|
+ * @property backgroundColor
|
|
|
|
+ * @type Integer
|
|
|
|
+ */
|
|
|
|
+Object.defineProperty(PixiTextInput.prototype, "backgroundColor", {
|
|
|
|
+ get: function() {
|
|
|
|
+ return this._backgroundColor;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ set: function(v) {
|
|
|
|
+ this._backgroundColor = v;
|
|
|
|
+ this.drawElements();
|
|
|
|
+ }
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+Object.defineProperty(PixiTextInput.prototype, "borderColor", {
|
|
|
|
+ get: function() {
|
|
|
|
+ return this._borderColor;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ set: function(v) {
|
|
|
|
+ this._borderColor = v;
|
|
|
|
+ this.drawElements();
|
|
|
|
+ }
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+Object.defineProperty(PixiTextInput.prototype, "borderWidth", {
|
|
|
|
+ get: function() {
|
|
|
|
+ return this._borderWidth;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ set: function(v) {
|
|
|
|
+ this._borderWidth = v;
|
|
|
|
+ this.drawElements();
|
|
|
|
+ }
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * The color of the caret.
|
|
|
|
+ * @property caretColor
|
|
|
|
+ * @type Integer
|
|
|
|
+ */
|
|
|
|
+Object.defineProperty(PixiTextInput.prototype, "caretColor", {
|
|
|
|
+ get: function() {
|
|
|
|
+ return this._caretColor;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ set: function(v) {
|
|
|
|
+ this._caretColor = v;
|
|
|
|
+ this.drawElements();
|
|
|
|
+ }
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Determines if the background should be drawn behind the text.
|
|
|
|
+ * The color of the background is specified using the backgroundColor
|
|
|
|
+ * property.
|
|
|
|
+ * @property background
|
|
|
|
+ * @type Boolean
|
|
|
|
+ */
|
|
|
|
+Object.defineProperty(PixiTextInput.prototype, "background", {
|
|
|
|
+ get: function() {
|
|
|
|
+ return this._background;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ set: function(v) {
|
|
|
|
+ this._background = v;
|
|
|
|
+ this.drawElements();
|
|
|
|
+ }
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Determines if the background should be drawn behind the text.
|
|
|
|
+ * The color of the background is specified using the backgroundColor
|
|
|
|
+ * property.
|
|
|
|
+ * @property background
|
|
|
|
+ * @type Boolean
|
|
|
|
+ */
|
|
|
|
+Object.defineProperty(PixiTextInput.prototype, "placeholder", {
|
|
|
|
+ get: function() {
|
|
|
|
+ return this._placeholder;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ set: function(v) {
|
|
|
|
+ this._placeholder = v;
|
|
|
|
+ this.syncValue();
|
|
|
|
+ }
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Set text.
|
|
|
|
+ * @method setText
|
|
|
|
+ * @param {String} text The new text.
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.setText = function(v) {
|
|
|
|
+ if(this._nativeTextInput) {
|
|
|
|
+ this._nativeTextInput.value = v;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.text = v;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Trigger an event function if it exists.
|
|
|
|
+ * @method trigger
|
|
|
|
+ * @private
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.trigger = function(fn, e) {
|
|
|
|
+ if (fn)
|
|
|
|
+ fn(e);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Get or create a native text input for mobile support
|
|
|
|
+ * @method getNativeTextInput
|
|
|
|
+ * @private
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.getNativeTextInput = function(pw) {
|
|
|
|
+ var elmName = "PixiTextInput";
|
|
|
|
+ var elm = document.getElementById( elmName );
|
|
|
|
+
|
|
|
|
+ if ( !elm ) {
|
|
|
|
+ elm = document.createElement( "input" );
|
|
|
|
+ document.body.appendChild( elm );
|
|
|
|
+ elm.style.position = "fixed";
|
|
|
|
+ elm.style.top = "-100px";
|
|
|
|
+ elm.style.left = "-100px";
|
|
|
|
+
|
|
|
|
+ if ( pw ) {
|
|
|
|
+ elm.type = "password";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return elm;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Bind events for the native text input
|
|
|
|
+ * @method bindNativeTextInput
|
|
|
|
+ * @private
|
|
|
|
+ */
|
|
|
|
+PixiTextInput.prototype.bindNativeTextInput = function() {
|
|
|
|
+
|
|
|
|
+ if(this._nativeTextInput) {
|
|
|
|
+ this._nativeTextInput.addEventListener("keyup", function(e) {
|
|
|
|
+ window.pixiTextInputTarget.text = this.value;
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+if (typeof module !== 'undefined') {
|
|
|
|
+ module.exports = PixiTextInput;
|
|
|
|
+}
|