From 1096ee0d30e5af3e59cce9d7ad248886045651ca Mon Sep 17 00:00:00 2001 From: Neyl Date: Tue, 14 Jan 2025 16:04:41 +0100 Subject: [PATCH 01/36] WIP + NEEDTOFIX : text-align --- Extensions/TextInput/JsExtension.js | 39 ++++++++++ .../textinputruntimeobject-pixi-renderer.ts | 38 +++++++++- .../TextInput/textinputruntimeobject.ts | 71 ++++++++++++++++++- 3 files changed, 145 insertions(+), 3 deletions(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index d77a9f3d0bcb..8eff7b56f7f3 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -79,6 +79,18 @@ module.exports = { objectContent.disabled = newValue === '1'; return true; } + else if(propertyName === 'maxLength') + { + objectContent.maxLength = newValue; + } + else if (propertyName === 'padding') + { + objectContent.padding = newValue; + } + else if(propertyName === 'textAlignement') + { + objectContent.textAlignement = newValue; + } return false; }; @@ -200,6 +212,30 @@ module.exports = { .setLabel(_('Width')) .setGroup(_('Border appearance')); + objectProperties + .getOrCreate('padding') + .setValue((objectContent.padding || 0).toString()) + .setType('number') + .setLabel(_('Padding')) + .setGroup(_('Border appearance')); + + objectProperties + .getOrCreate('maxLength') + .setValue(objectContent.maxLength || 20) + .setType('number') + .setLabel(_('Max length')) + .setGroup(_('Border appearance')); + + objectProperties + .getOrCreate('textAlignement') + .setValue(objectContent.textAlignement || 'left') + .setType('choice') + .addExtraInfo('left') + .addExtraInfo('right') + .addExtraInfo('center') + .setLabel(_('text Alignement')) + .setGroup(_('Border appearance')); + return objectProperties; }; textInputObject.content = { @@ -216,6 +252,9 @@ module.exports = { borderWidth: 1, readOnly: false, disabled: false, + padding: 0, + textAlignement: 'left', + maxLength: '20', }; textInputObject.updateInitialInstanceProperty = function ( diff --git a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts index 1e49d0cbbd87..41f742782851 100644 --- a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts +++ b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts @@ -9,6 +9,13 @@ namespace gdjs { search: 'search', }; + const userFriendlyToHtmlAlignement = + { + left: 'left', + center: 'center', + right: 'right', + } + const formatRgbAndOpacityToCssRgba = ( rgbColor: [float, float, float], opacity: float @@ -59,6 +66,11 @@ namespace gdjs { this._input.style.pointerEvents = 'auto'; // Element can be clicked/touched. this._input.style.display = 'none'; // Hide while object is being set up. this._input.style.boxSizing = 'border-box'; // Important for iOS, because border is added to width/height. + this._input.maxLength = this._object.getMaxLength(); + this._input.style.padding = this._object.getPadding() + 'px'; + this._input.style.textAlign = this._object.getTextAlignement(); + + this._input.addEventListener('input', () => { if (!this._input) return; @@ -83,6 +95,9 @@ namespace gdjs { this.updateBorderWidth(); this.updateDisabled(); this.updateReadOnly(); + this.updateTextlignement(); + this.updateMaxLength(); + this.updatePadding(); this._runtimeGame .getRenderer() @@ -216,6 +231,9 @@ namespace gdjs { this._input.style.height = heightInContainer + 'px'; this._input.style.transform = 'rotate3d(0,0,1,' + (this._object.getAngle() % 360) + 'deg)'; + this._input.style.display = 'initial'; + this._input.style.padding = this._object.getPadding() + 'px'; + this._input.style.textAlign = this._object.getTextAlignement(); // Automatically adjust the font size to follow the game scale. this._input.style.fontSize = @@ -224,7 +242,6 @@ namespace gdjs { 'px'; // Display after the object is positioned. - this._input.style.display = 'initial'; } updateString() { @@ -307,6 +324,25 @@ namespace gdjs { this._input.readOnly = this._object.isReadOnly(); } + updateMaxLength() { + if(!this._input) return; + + this._input.maxLength = this._object.getMaxLength(); + } + + updatePadding() { + if(!this._input) return; + + this._input.style.padding = this._object.getPadding() + 'px'; + } + + updateTextlignement() { + if (!this._input) return; + + const newTextAlignement = userFriendlyToHtmlAlignement[this._object.getTextAlignement()] || 'right'; + this._input.style.textAlign = newTextAlignement; + } + isFocused() { return this._input === document.activeElement; } diff --git a/Extensions/TextInput/textinputruntimeobject.ts b/Extensions/TextInput/textinputruntimeobject.ts index d9c0df39c924..97294056dd15 100644 --- a/Extensions/TextInput/textinputruntimeobject.ts +++ b/Extensions/TextInput/textinputruntimeobject.ts @@ -9,9 +9,15 @@ namespace gdjs { 'search', 'text area', ] as const; + const supportedtextAlignement = [ + 'left', + 'center', + 'right', + ] as const; - type SupportedInputType = typeof supportedInputTypes[number]; + type SupportedInputType = typeof supportedInputTypes[number]; + type SupportedtextAlignement = typeof supportedtextAlignement[number]; const parseInputType = (potentialInputType: string): SupportedInputType => { const lowercasedNewInputType = potentialInputType.toLowerCase(); @@ -22,6 +28,16 @@ namespace gdjs { return 'text'; }; + const parseTextAlignement = (potentialTextAlignement: string): SupportedtextAlignement => { + const lowercasedNewTextAlignement = potentialTextAlignement.toLowerCase(); + + // @ts-ignore - we're actually checking that this value is correct. + if (supportedtextAlignement.includes(lowercasedNewTextAlignement)) + return potentialTextAlignement as SupportedtextAlignement; + + return 'left'; + }; + /** Base parameters for {@link gdjs.TextInputRuntimeObject} */ export interface TextInputObjectData extends ObjectData { /** The base parameters of the TextInput */ @@ -34,6 +50,9 @@ namespace gdjs { textColor: string; fillColor: string; fillOpacity: float; + padding : integer; + textAlign : SupportedtextAlignement; + maxLength : integer; borderColor: string; borderOpacity: float; borderWidth: float; @@ -84,6 +103,9 @@ namespace gdjs { private _textColor: [float, float, float]; private _fillColor: [float, float, float]; private _fillOpacity: float; + private _padding : integer; + private _textAlign : SupportedtextAlignement; + private _maxLength : integer; private _borderColor: [float, float, float]; private _borderOpacity: float; private _borderWidth: float; @@ -107,12 +129,15 @@ namespace gdjs { this._fillColor = gdjs.rgbOrHexToRGBColor(objectData.content.fillColor); this._fillOpacity = objectData.content.fillOpacity; this._borderColor = gdjs.rgbOrHexToRGBColor( - objectData.content.borderColor + objectData.content.borderColor ); this._borderOpacity = objectData.content.borderOpacity; this._borderWidth = objectData.content.borderWidth; this._disabled = objectData.content.disabled; this._readOnly = objectData.content.readOnly; + this._padding = objectData.content.padding; + this._textAlign = objectData.content.textAlign; + this._maxLength = objectData.content.maxLength; this._renderer = new gdjs.TextInputRuntimeObjectRenderer( this, @@ -189,6 +214,19 @@ namespace gdjs { if (oldObjectData.content.readOnly !== newObjectData.content.readOnly) { this.setReadOnly(newObjectData.content.readOnly); } + if(oldObjectData.content.maxLength !== newObjectData.content.maxLength) + { + this.SetMaxLength(newObjectData.content.maxLength); + } + if(oldObjectData.content.textAlign !== newObjectData.content.textAlign) + { + this._textAlign = newObjectData.content.textAlign; + //this.setTextAlignement(newObjectData.content.textAlign); + } + if(oldObjectData.content.padding !== newObjectData.content.padding) + { + this.SetPadding(newObjectData.content.padding); + } return true; } @@ -501,6 +539,35 @@ namespace gdjs { return this._renderer.isFocused(); } + getMaxLength() : integer { + return this._maxLength; + } + SetMaxLength(value: integer) + { + this._maxLength = value; + this._renderer.updateMaxLength(); + } + getPadding() : integer { + return this._padding; + } + SetPadding(value: integer) + { + this._padding = value; + } + + getTextAlignement() : SupportedtextAlignement + { + return this._textAlign; + } + + setTextAlignement(newTextAlignement: string) { + const lowercasedNewTextAlignement = newTextAlignement.toLowerCase(); + if (lowercasedNewTextAlignement === this._textAlign) return; + + this._textAlign = parseTextAlignement(lowercasedNewTextAlignement); + this._renderer.updateTextlignement(); + } + focus(): void { if (!this.isFocused()) { // If the input was not previously focused, reset input manager because there is From 28e578e2254a1699d88e95aea88faf2df7308e9b Mon Sep 17 00:00:00 2001 From: Neyl Date: Tue, 14 Jan 2025 16:38:09 +0100 Subject: [PATCH 02/36] small fix on missed return statements (does not change behavior) --- Extensions/TextInput/JsExtension.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index 8eff7b56f7f3..1eb6963a229f 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -82,14 +82,17 @@ module.exports = { else if(propertyName === 'maxLength') { objectContent.maxLength = newValue; + return true; } else if (propertyName === 'padding') { objectContent.padding = newValue; + return true; } else if(propertyName === 'textAlignement') { objectContent.textAlignement = newValue; + return true; } return false; From 65402bd10997590011314c6570b4944979929a94 Mon Sep 17 00:00:00 2001 From: Neyl Date: Sun, 19 Jan 2025 22:53:28 +0100 Subject: [PATCH 03/36] add form support for input, add padding and text-align support in pixi renderer for editor --- Extensions/TextInput/JsExtension.js | 39 ++++++-- .../textinputruntimeobject-pixi-renderer.ts | 97 +++++++++++-------- .../TextInput/textinputruntimeobject.ts | 38 +++++--- 3 files changed, 114 insertions(+), 60 deletions(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index 1eb6963a229f..f4c048b978b0 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -89,9 +89,9 @@ module.exports = { objectContent.padding = newValue; return true; } - else if(propertyName === 'textAlignement') + else if(propertyName === 'textAlign') { - objectContent.textAlignement = newValue; + objectContent.textAlign = newValue; return true; } @@ -230,8 +230,8 @@ module.exports = { .setGroup(_('Border appearance')); objectProperties - .getOrCreate('textAlignement') - .setValue(objectContent.textAlignement || 'left') + .getOrCreate('textAlign') + .setValue(objectContent.textAlign || 'left') .setType('choice') .addExtraInfo('left') .addExtraInfo('right') @@ -256,7 +256,7 @@ module.exports = { readOnly: false, disabled: false, padding: 0, - textAlignement: 'left', + textAlign: 'left', maxLength: '20', }; @@ -614,6 +614,21 @@ module.exports = { .getCodeExtraInformation() .setFunctionName('isFocused'); + object.addScopedCondition( + 'IsInputSubmitted', + _('Input is Submitted (Enter pressed'), + _( + 'Check if the input is submitted, which usually happens when the Enter key is pressed on a keyboard, or a specific button on mobile virtual keyboards.' + ), + _('_PARAM0_ got input submitted'), + '', + 'res/conditions/surObject24.png', + 'res/conditions/surObject.png' + ) + .addParameter('object', _('Text input'), 'TextInputObject',false) + .getCodeExtraInformation() + .setFunctionName('isSubmitted'); + object .addScopedAction( 'Focus', @@ -797,8 +812,18 @@ module.exports = { this._pixiTextMask.endFill(); const isTextArea = object.content.inputType === 'text area'; - - this._pixiText.position.x = textOffset; + const textAlign = object.content.textAlign; + console.log(this._pixiText.width); + if(textAlign === 'left') + this._pixiText.position.x = 0; + else if(textAlign === 'right') + this._pixiText.position.x = 0 + width - this._pixiText.width - textOffset; + else if (textAlign === 'center') + { + this._pixiText.align = 'center'; + this._pixiText.position.x = 0 + width/2 - this._pixiText.width/2; + } + this._pixiText.position.y = isTextArea ? textOffset : height / 2 - this._pixiText.height / 2; diff --git a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts index 41f742782851..e17608e63f65 100644 --- a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts +++ b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts @@ -38,6 +38,8 @@ namespace gdjs { private _input: HTMLInputElement | HTMLTextAreaElement | null = null; private _instanceContainer: gdjs.RuntimeInstanceContainer; private _runtimeGame: gdjs.RuntimeGame; + private _form: HTMLFormElement | null = null; + private _isSubmited: boolean; constructor( runtimeObject: gdjs.TextInputRuntimeObject, @@ -48,29 +50,36 @@ namespace gdjs { this._runtimeGame = this._instanceContainer.getGame(); this._createElement(); + this._isSubmited = false; } _createElement() { if (!!this._input) throw new Error('Tried to recreate an input while it already exists.'); + this._form = document.createElement('form'); + this._form.setAttribute('id', 'dynamicForm'); const isTextArea = this._object.getInputType() === 'text area'; this._input = document.createElement(isTextArea ? 'textarea' : 'input'); - this._input.style.border = '1px solid black'; + this._form.style.border = '0px'; this._input.autocomplete = 'off'; - this._input.style.borderRadius = '0px'; - this._input.style.backgroundColor = 'white'; - this._input.style.position = 'absolute'; - this._input.style.resize = 'none'; - this._input.style.outline = 'none'; - this._input.style.pointerEvents = 'auto'; // Element can be clicked/touched. - this._input.style.display = 'none'; // Hide while object is being set up. - this._input.style.boxSizing = 'border-box'; // Important for iOS, because border is added to width/height. + this._form.style.borderRadius = '0px'; + this._form.style.backgroundColor = 'transparent'; + this._input.style.backgroundColor = 'red'; + this._input.style.border = '1px solid black'; + this._form.style.position = 'absolute'; + this._form.style.resize = 'none'; + this._form.style.outline = 'none'; + this._form.style.pointerEvents = 'auto'; // Element can be clicked/touched. + this._form.style.display = 'none'; // Hide while object is being set up. + this._form.style.boxSizing = 'border-box'; // Important for iOS, because border is added to width/height. this._input.maxLength = this._object.getMaxLength(); this._input.style.padding = this._object.getPadding() + 'px'; - this._input.style.textAlign = this._object.getTextAlignement(); + this._form.style.textAlign = this._object.getTextAlign(); + this._form.appendChild(this._input); + this._isSubmited = false; this._input.addEventListener('input', () => { if (!this._input) return; @@ -84,6 +93,11 @@ namespace gdjs { if (document.activeElement !== this._input) this._input.focus(); }); + this._form.addEventListener('submit', (event) => { + event.preventDefault(); + this._isSubmited = true; + }) + this.updateString(); this.updateFont(); this.updatePlaceholder(); @@ -95,14 +109,14 @@ namespace gdjs { this.updateBorderWidth(); this.updateDisabled(); this.updateReadOnly(); - this.updateTextlignement(); + this.updateTextAlign(); this.updateMaxLength(); this.updatePadding(); this._runtimeGame .getRenderer() .getDomElementContainer()! - .appendChild(this._input); + .appendChild(this._form); } _destroyElement() { @@ -131,13 +145,14 @@ namespace gdjs { } updatePreRender() { - if (!this._input) return; + if (!this._input || !this._form) return; + this._isSubmited = false; // Hide the input entirely if the object is hidden. // Because this object is rendered as a DOM element (and not part of the PixiJS // scene graph), we have to do this manually. if (this._object.isHidden()) { - this._input.style.display = 'none'; + this._form.style.display = 'none'; return; } @@ -151,7 +166,7 @@ namespace gdjs { do { const layer = instanceContainer.getLayer(object.getLayer()); if (!layer.isVisible() || !object.isVisible()) { - this._input.style.display = 'none'; + this._form.style.display = 'none'; return; } // TODO Declare an interface to move up in the object tree. @@ -199,7 +214,7 @@ namespace gdjs { canvasLeft > runtimeGame.getGameResolutionWidth() || canvasTop > runtimeGame.getGameResolutionHeight(); if (isOutsideCanvas) { - this._input.style.display = 'none'; + this._form.style.display = 'none'; return; } @@ -225,18 +240,18 @@ namespace gdjs { const widthInContainer = pageRight - pageLeft; const heightInContainer = pageBottom - pageTop; - this._input.style.left = pageLeft + 'px'; - this._input.style.top = pageTop + 'px'; - this._input.style.width = widthInContainer + 'px'; - this._input.style.height = heightInContainer + 'px'; - this._input.style.transform = + this._form.style.left = pageLeft + 'px'; + this._form.style.top = pageTop + 'px'; + this._form.style.width = widthInContainer + 'px'; + this._form.style.height = heightInContainer + 'px'; + this._form.style.transform = 'rotate3d(0,0,1,' + (this._object.getAngle() % 360) + 'deg)'; - this._input.style.display = 'initial'; - this._input.style.padding = this._object.getPadding() + 'px'; - this._input.style.textAlign = this._object.getTextAlignement(); + this._form.style.display = 'initial'; + this._form.style.padding = this._object.getPadding() + 'px'; + this._form.style.textAlign = this._object.getTextAlign(); // Automatically adjust the font size to follow the game scale. - this._input.style.fontSize = + this._form.style.fontSize = this._object.getFontSize() * runtimeGameRenderer.getCanvasToDomElementContainerHeightScale() + 'px'; @@ -255,16 +270,16 @@ namespace gdjs { } updateFont() { - if (!this._input) return; - this._input.style.fontFamily = this._instanceContainer + if (!this._form) return; + this._form.style.fontFamily = this._instanceContainer .getGame() .getFontManager() .getFontFamily(this._object.getFontResourceName()); } updateOpacity() { - if (!this._input) return; - this._input.style.opacity = '' + this._object.getOpacity() / 255; + if (!this._form) return; + this._form.style.opacity = '' + this._object.getOpacity() / 255; } updateInputType() { @@ -283,9 +298,9 @@ namespace gdjs { } updateTextColor() { - if (!this._input) return; + if (!this._form) return; - this._input.style.color = formatRgbAndOpacityToCssRgba( + this._form.style.color = formatRgbAndOpacityToCssRgba( this._object._getRawTextColor(), 255 ); @@ -314,14 +329,14 @@ namespace gdjs { this._input.style.borderWidth = this._object.getBorderWidth() + 'px'; } updateDisabled() { - if (!this._input) return; + if (!this._form) return; - this._input.disabled = this._object.isDisabled(); + this._form.disabled = this._object.isDisabled(); } updateReadOnly() { - if (!this._input) return; + if (!this._form) return; - this._input.readOnly = this._object.isReadOnly(); + this._form.readOnly = this._object.isReadOnly(); } updateMaxLength() { @@ -336,16 +351,20 @@ namespace gdjs { this._input.style.padding = this._object.getPadding() + 'px'; } - updateTextlignement() { + updateTextAlign() { if (!this._input) return; - const newTextAlignement = userFriendlyToHtmlAlignement[this._object.getTextAlignement()] || 'right'; - this._input.style.textAlign = newTextAlignement; + const newTextAlign = userFriendlyToHtmlAlignement[this._object.getTextAlign()] || 'left'; + this._input.style.textAlign = newTextAlign; } - + isFocused() { return this._input === document.activeElement; } + getSubmitted() + { + return this._isSubmited; + } focus() { if (!this._input) return; diff --git a/Extensions/TextInput/textinputruntimeobject.ts b/Extensions/TextInput/textinputruntimeobject.ts index 97294056dd15..2d3f1cdf4a6b 100644 --- a/Extensions/TextInput/textinputruntimeobject.ts +++ b/Extensions/TextInput/textinputruntimeobject.ts @@ -1,3 +1,5 @@ +import { Console } from "console"; + namespace gdjs { const supportedInputTypes = [ 'text', @@ -9,7 +11,7 @@ namespace gdjs { 'search', 'text area', ] as const; - const supportedtextAlignement = [ + const supportedtextAlign = [ 'left', 'center', 'right', @@ -17,7 +19,7 @@ namespace gdjs { type SupportedInputType = typeof supportedInputTypes[number]; - type SupportedtextAlignement = typeof supportedtextAlignement[number]; + type SupportedtextAlign = typeof supportedtextAlign[number]; const parseInputType = (potentialInputType: string): SupportedInputType => { const lowercasedNewInputType = potentialInputType.toLowerCase(); @@ -28,12 +30,12 @@ namespace gdjs { return 'text'; }; - const parseTextAlignement = (potentialTextAlignement: string): SupportedtextAlignement => { - const lowercasedNewTextAlignement = potentialTextAlignement.toLowerCase(); + const parseTextAlign = (potentialTextAlign: string): SupportedtextAlign => { + const lowercasedNewTextAlign = potentialTextAlign.toLowerCase(); // @ts-ignore - we're actually checking that this value is correct. - if (supportedtextAlignement.includes(lowercasedNewTextAlignement)) - return potentialTextAlignement as SupportedtextAlignement; + if (supportedtextAlign.includes(lowercasedNewTextAlign)) + return potentialTextAlign as SupportedtextAlign; return 'left'; }; @@ -51,7 +53,7 @@ namespace gdjs { fillColor: string; fillOpacity: float; padding : integer; - textAlign : SupportedtextAlignement; + textAlign : SupportedtextAlign; maxLength : integer; borderColor: string; borderOpacity: float; @@ -104,7 +106,7 @@ namespace gdjs { private _fillColor: [float, float, float]; private _fillOpacity: float; private _padding : integer; - private _textAlign : SupportedtextAlignement; + private _textAlign : SupportedtextAlign; private _maxLength : integer; private _borderColor: [float, float, float]; private _borderOpacity: float; @@ -227,6 +229,7 @@ namespace gdjs { { this.SetPadding(newObjectData.content.padding); } + return true; } @@ -538,6 +541,12 @@ namespace gdjs { isFocused(): boolean { return this._renderer.isFocused(); } + isSubmitted() : boolean + { + console.log(this._renderer.getSubmitted()); + + return this._renderer.getSubmitted(); + } getMaxLength() : integer { return this._maxLength; @@ -555,17 +564,18 @@ namespace gdjs { this._padding = value; } - getTextAlignement() : SupportedtextAlignement + + getTextAlign() : SupportedtextAlign { return this._textAlign; } - setTextAlignement(newTextAlignement: string) { - const lowercasedNewTextAlignement = newTextAlignement.toLowerCase(); - if (lowercasedNewTextAlignement === this._textAlign) return; + setTextAlign(newTextAlign: string) { + const lowercasedNewTextAlign = newTextAlign.toLowerCase(); + if (lowercasedNewTextAlign === this._textAlign) return; - this._textAlign = parseTextAlignement(lowercasedNewTextAlignement); - this._renderer.updateTextlignement(); + this._textAlign = parseTextAlign(lowercasedNewTextAlign); + this._renderer.updateTextAlign(); } focus(): void { From 5c9debd951bb8c1c9151d94e1a2037d1d5eca85c Mon Sep 17 00:00:00 2001 From: Neyl Date: Sun, 19 Jan 2025 22:54:20 +0100 Subject: [PATCH 04/36] forgotten file in last commit --- Extensions/TextInput/JsExtension.js | 7 ++++--- .../TextInput/textinputruntimeobject-pixi-renderer.ts | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index f4c048b978b0..aa1317056de1 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -172,7 +172,7 @@ module.exports = { objectProperties .getOrCreate('fillColor') - .setValue(objectContent.fillColor || '255;255;255') + .setValue(objectContent.fillColor || '0;0;0') .setType('color') .setLabel(_('Fill color')) .setGroup(_('Field appearance')); @@ -313,6 +313,7 @@ module.exports = { // Properties expressions/conditions/actions: // Deprecated, see TextContainerCapability + object.addcon object .addExpressionAndConditionAndAction( 'string', @@ -707,7 +708,7 @@ module.exports = { this._pixiGraphics = new PIXI.Graphics(); this._pixiTextMask = new PIXI.Graphics(); this._pixiText = new PIXI.Text(' ', { - align: 'left', + align: 'right', fontSize: 20, }); this._pixiText.mask = this._pixiTextMask; @@ -800,7 +801,7 @@ module.exports = { const borderWidth = object.content.borderWidth || 0; // Draw the mask for the text. - const textOffset = borderWidth + TEXT_MASK_PADDING; + const textOffset = borderWidth + TEXT_MASK_PADDING;// + object.content.padding; this._pixiTextMask.clear(); this._pixiTextMask.beginFill(0xdddddd, 1); this._pixiTextMask.drawRect( diff --git a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts index e17608e63f65..3454b7223297 100644 --- a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts +++ b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts @@ -33,6 +33,7 @@ namespace gdjs { ); }; + class TextInputRuntimeObjectPixiRenderer { private _object: gdjs.TextInputRuntimeObject; private _input: HTMLInputElement | HTMLTextAreaElement | null = null; @@ -75,8 +76,6 @@ namespace gdjs { this._form.style.boxSizing = 'border-box'; // Important for iOS, because border is added to width/height. this._input.maxLength = this._object.getMaxLength(); this._input.style.padding = this._object.getPadding() + 'px'; - - this._form.style.textAlign = this._object.getTextAlign(); this._form.appendChild(this._input); this._isSubmited = false; @@ -313,6 +312,7 @@ namespace gdjs { this._object._getRawFillColor(), this._object.getFillOpacity() ); + } updateBorderColorAndOpacity() { @@ -372,7 +372,7 @@ namespace gdjs { this._input.focus(); } } - export const TextInputRuntimeObjectRenderer = TextInputRuntimeObjectPixiRenderer; export type TextInputRuntimeObjectRenderer = TextInputRuntimeObjectPixiRenderer; + } From 11e623a094d827b68e3c2ff2287f0323442b4abd Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 09:56:32 +0100 Subject: [PATCH 05/36] Update JsExtension.js --- Extensions/TextInput/JsExtension.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index aa1317056de1..062c410438f8 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -313,7 +313,6 @@ module.exports = { // Properties expressions/conditions/actions: // Deprecated, see TextContainerCapability - object.addcon object .addExpressionAndConditionAndAction( 'string', From 0d50de11b4bd39132c44eb9e6e37f2c01c8c6da0 Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 10:13:29 +0100 Subject: [PATCH 06/36] deleted wrong import --- .../TextInput/textinputruntimeobject.ts | 71 ++++++++----------- 1 file changed, 28 insertions(+), 43 deletions(-) diff --git a/Extensions/TextInput/textinputruntimeobject.ts b/Extensions/TextInput/textinputruntimeobject.ts index 2d3f1cdf4a6b..38f7bfb15ecc 100644 --- a/Extensions/TextInput/textinputruntimeobject.ts +++ b/Extensions/TextInput/textinputruntimeobject.ts @@ -1,5 +1,3 @@ -import { Console } from "console"; - namespace gdjs { const supportedInputTypes = [ 'text', @@ -11,15 +9,10 @@ namespace gdjs { 'search', 'text area', ] as const; - const supportedtextAlign = [ - 'left', - 'center', - 'right', - ] as const; - + const supportedtextAlign = ['left', 'center', 'right'] as const; - type SupportedInputType = typeof supportedInputTypes[number]; - type SupportedtextAlign = typeof supportedtextAlign[number]; + type SupportedInputType = typeof supportedInputTypes[number]; + type SupportedtextAlign = typeof supportedtextAlign[number]; const parseInputType = (potentialInputType: string): SupportedInputType => { const lowercasedNewInputType = potentialInputType.toLowerCase(); @@ -52,9 +45,9 @@ namespace gdjs { textColor: string; fillColor: string; fillOpacity: float; - padding : integer; - textAlign : SupportedtextAlign; - maxLength : integer; + padding: integer; + textAlign: SupportedtextAlign; + maxLength: integer; borderColor: string; borderOpacity: float; borderWidth: float; @@ -105,9 +98,9 @@ namespace gdjs { private _textColor: [float, float, float]; private _fillColor: [float, float, float]; private _fillOpacity: float; - private _padding : integer; - private _textAlign : SupportedtextAlign; - private _maxLength : integer; + private _padding: integer; + private _textAlign: SupportedtextAlign; + private _maxLength: integer; private _borderColor: [float, float, float]; private _borderOpacity: float; private _borderWidth: float; @@ -131,7 +124,7 @@ namespace gdjs { this._fillColor = gdjs.rgbOrHexToRGBColor(objectData.content.fillColor); this._fillOpacity = objectData.content.fillOpacity; this._borderColor = gdjs.rgbOrHexToRGBColor( - objectData.content.borderColor + objectData.content.borderColor ); this._borderOpacity = objectData.content.borderOpacity; this._borderWidth = objectData.content.borderWidth; @@ -216,20 +209,17 @@ namespace gdjs { if (oldObjectData.content.readOnly !== newObjectData.content.readOnly) { this.setReadOnly(newObjectData.content.readOnly); } - if(oldObjectData.content.maxLength !== newObjectData.content.maxLength) - { + if (oldObjectData.content.maxLength !== newObjectData.content.maxLength) { this.SetMaxLength(newObjectData.content.maxLength); } - if(oldObjectData.content.textAlign !== newObjectData.content.textAlign) - { - this._textAlign = newObjectData.content.textAlign; - //this.setTextAlignement(newObjectData.content.textAlign); - } - if(oldObjectData.content.padding !== newObjectData.content.padding) - { - this.SetPadding(newObjectData.content.padding); - } - + if (oldObjectData.content.textAlign !== newObjectData.content.textAlign) { + this._textAlign = newObjectData.content.textAlign; + //this.setTextAlignement(newObjectData.content.textAlign); + } + if (oldObjectData.content.padding !== newObjectData.content.padding) { + this.SetPadding(newObjectData.content.padding); + } + return true; } @@ -541,34 +531,29 @@ namespace gdjs { isFocused(): boolean { return this._renderer.isFocused(); } - isSubmitted() : boolean - { - console.log(this._renderer.getSubmitted()); - + isSubmitted(): boolean { + console.log(this._renderer.getSubmitted()); + return this._renderer.getSubmitted(); } - getMaxLength() : integer { + getMaxLength(): integer { return this._maxLength; } - SetMaxLength(value: integer) - { + SetMaxLength(value: integer) { this._maxLength = value; this._renderer.updateMaxLength(); } - getPadding() : integer { + getPadding(): integer { return this._padding; } - SetPadding(value: integer) - { + SetPadding(value: integer) { this._padding = value; } - - getTextAlign() : SupportedtextAlign - { + getTextAlign(): SupportedtextAlign { return this._textAlign; - } + } setTextAlign(newTextAlign: string) { const lowercasedNewTextAlign = newTextAlign.toLowerCase(); From 908d0a51ea7ef93085eb6f881fb9c2b84662e003 Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 10:22:05 +0100 Subject: [PATCH 07/36] Update textinputruntimeobject.pixiruntimegamewithassets.spec.js --- .../textinputruntimeobject.pixiruntimegamewithassets.spec.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js b/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js index adfe65f23a69..b47ce9e803d6 100644 --- a/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js +++ b/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js @@ -1,5 +1,7 @@ // @ts-check +const { kMaxLength } = require("buffer"); + describe('gdjs.TextInputRuntimeObject (using a PixiJS RuntimeGame with DOM elements)', function () { /** * @param {gdjs.RuntimeScene} runtimeScene @@ -25,6 +27,9 @@ describe('gdjs.TextInputRuntimeObject (using a PixiJS RuntimeGame with DOM eleme borderWidth: 2, disabled: false, readOnly: false, + padding: '0 px', + textAlign: 'left', + kMaxLength : 20, }, }); From 7e079063610e922919fb9b003e1ff70f19ba589a Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 10:28:45 +0100 Subject: [PATCH 08/36] Update textinputruntimeobject.pixiruntimegamewithassets.spec.js --- .../textinputruntimeobject.pixiruntimegamewithassets.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js b/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js index b47ce9e803d6..7aa9906df307 100644 --- a/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js +++ b/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js @@ -27,9 +27,9 @@ describe('gdjs.TextInputRuntimeObject (using a PixiJS RuntimeGame with DOM eleme borderWidth: 2, disabled: false, readOnly: false, - padding: '0 px', + padding: 0, textAlign: 'left', - kMaxLength : 20, + maxLength : 20, }, }); From ce99c0a563a7bcb92951d2caba0c9a0ac878b304 Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 10:42:43 +0100 Subject: [PATCH 09/36] Update textinputruntimeobject.pixiruntimegamewithassets.spec.js --- .../textinputruntimeobject.pixiruntimegamewithassets.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js b/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js index 7aa9906df307..34ba993fbed0 100644 --- a/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js +++ b/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js @@ -1,6 +1,6 @@ // @ts-check -const { kMaxLength } = require("buffer"); +const { MaxLength } = require("buffer"); describe('gdjs.TextInputRuntimeObject (using a PixiJS RuntimeGame with DOM elements)', function () { /** From c9849cd37313baa8d7227a827020ef888eefd6cc Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 10:48:54 +0100 Subject: [PATCH 10/36] Update textinputruntimeobject.pixiruntimegamewithassets.spec.js --- .../textinputruntimeobject.pixiruntimegamewithassets.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js b/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js index 7aa9906df307..1f7308178ec6 100644 --- a/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js +++ b/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js @@ -1,6 +1,6 @@ // @ts-check -const { kMaxLength } = require("buffer"); + describe('gdjs.TextInputRuntimeObject (using a PixiJS RuntimeGame with DOM elements)', function () { /** From ea375f4c1bee70e3c2e6d1b795eb9f9dc793ed05 Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 11:11:30 +0100 Subject: [PATCH 11/36] fixed small issue --- Extensions/TextInput/JsExtension.js | 71 +++++++++---------- .../textinputruntimeobject-pixi-renderer.ts | 28 ++++---- 2 files changed, 45 insertions(+), 54 deletions(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index 062c410438f8..2e406e07e34c 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -78,19 +78,13 @@ module.exports = { } else if (propertyName === 'disabled') { objectContent.disabled = newValue === '1'; return true; - } - else if(propertyName === 'maxLength') - { + } else if (propertyName === 'maxLength') { objectContent.maxLength = newValue; return true; - } - else if (propertyName === 'padding') - { + } else if (propertyName === 'padding') { objectContent.padding = newValue; return true; - } - else if(propertyName === 'textAlign') - { + } else if (propertyName === 'textAlign') { objectContent.textAlign = newValue; return true; } @@ -215,21 +209,21 @@ module.exports = { .setLabel(_('Width')) .setGroup(_('Border appearance')); - objectProperties + objectProperties .getOrCreate('padding') .setValue((objectContent.padding || 0).toString()) .setType('number') .setLabel(_('Padding')) .setGroup(_('Border appearance')); - objectProperties + objectProperties .getOrCreate('maxLength') .setValue(objectContent.maxLength || 20) .setType('number') .setLabel(_('Max length')) .setGroup(_('Border appearance')); - objectProperties + objectProperties .getOrCreate('textAlign') .setValue(objectContent.textAlign || 'left') .setType('choice') @@ -313,6 +307,7 @@ module.exports = { // Properties expressions/conditions/actions: // Deprecated, see TextContainerCapability + object .addExpressionAndConditionAndAction( 'string', @@ -614,21 +609,22 @@ module.exports = { .getCodeExtraInformation() .setFunctionName('isFocused'); - object.addScopedCondition( - 'IsInputSubmitted', - _('Input is Submitted (Enter pressed'), - _( - 'Check if the input is submitted, which usually happens when the Enter key is pressed on a keyboard, or a specific button on mobile virtual keyboards.' - ), - _('_PARAM0_ got input submitted'), - '', - 'res/conditions/surObject24.png', - 'res/conditions/surObject.png' - ) - .addParameter('object', _('Text input'), 'TextInputObject',false) - .getCodeExtraInformation() - .setFunctionName('isSubmitted'); - + object + .addScopedCondition( + 'IsInputSubmitted', + _('Input is Submitted (Enter pressed'), + _( + 'Check if the input is submitted, which usually happens when the Enter key is pressed on a keyboard, or a specific button on mobile virtual keyboards.' + ), + _('_PARAM0_ got input submitted'), + '', + 'res/conditions/surObject24.png', + 'res/conditions/surObject.png' + ) + .addParameter('object', _('Text input'), 'TextInputObject', false) + .getCodeExtraInformation() + .setFunctionName('isSubmitted'); + object .addScopedAction( 'Focus', @@ -800,7 +796,7 @@ module.exports = { const borderWidth = object.content.borderWidth || 0; // Draw the mask for the text. - const textOffset = borderWidth + TEXT_MASK_PADDING;// + object.content.padding; + const textOffset = borderWidth + TEXT_MASK_PADDING; // + object.content.padding; this._pixiTextMask.clear(); this._pixiTextMask.beginFill(0xdddddd, 1); this._pixiTextMask.drawRect( @@ -814,16 +810,15 @@ module.exports = { const isTextArea = object.content.inputType === 'text area'; const textAlign = object.content.textAlign; console.log(this._pixiText.width); - if(textAlign === 'left') - this._pixiText.position.x = 0; - else if(textAlign === 'right') - this._pixiText.position.x = 0 + width - this._pixiText.width - textOffset; - else if (textAlign === 'center') - { - this._pixiText.align = 'center'; - this._pixiText.position.x = 0 + width/2 - this._pixiText.width/2; - } - + if (textAlign === 'left') this._pixiText.position.x = 0; + else if (textAlign === 'right') + this._pixiText.position.x = + 0 + width - this._pixiText.width - textOffset; + else if (textAlign === 'center') { + this._pixiText.align = 'center'; + this._pixiText.position.x = 0 + width / 2 - this._pixiText.width / 2; + } + this._pixiText.position.y = isTextArea ? textOffset : height / 2 - this._pixiText.height / 2; diff --git a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts index 3454b7223297..40f68a5b1025 100644 --- a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts +++ b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts @@ -9,12 +9,11 @@ namespace gdjs { search: 'search', }; - const userFriendlyToHtmlAlignement = - { + const userFriendlyToHtmlAlignement = { left: 'left', center: 'center', right: 'right', - } + }; const formatRgbAndOpacityToCssRgba = ( rgbColor: [float, float, float], @@ -33,7 +32,6 @@ namespace gdjs { ); }; - class TextInputRuntimeObjectPixiRenderer { private _object: gdjs.TextInputRuntimeObject; private _input: HTMLInputElement | HTMLTextAreaElement | null = null; @@ -95,7 +93,7 @@ namespace gdjs { this._form.addEventListener('submit', (event) => { event.preventDefault(); this._isSubmited = true; - }) + }); this.updateString(); this.updateFont(); @@ -245,9 +243,9 @@ namespace gdjs { this._form.style.height = heightInContainer + 'px'; this._form.style.transform = 'rotate3d(0,0,1,' + (this._object.getAngle() % 360) + 'deg)'; - this._form.style.display = 'initial'; - this._form.style.padding = this._object.getPadding() + 'px'; - this._form.style.textAlign = this._object.getTextAlign(); + this._form.style.display = 'initial'; + this._form.style.padding = this._object.getPadding() + 'px'; + this._form.style.textAlign = this._object.getTextAlign(); // Automatically adjust the font size to follow the game scale. this._form.style.fontSize = @@ -312,7 +310,6 @@ namespace gdjs { this._object._getRawFillColor(), this._object.getFillOpacity() ); - } updateBorderColorAndOpacity() { @@ -340,13 +337,13 @@ namespace gdjs { } updateMaxLength() { - if(!this._input) return; + if (!this._input) return; this._input.maxLength = this._object.getMaxLength(); } updatePadding() { - if(!this._input) return; + if (!this._input) return; this._input.style.padding = this._object.getPadding() + 'px'; } @@ -354,15 +351,15 @@ namespace gdjs { updateTextAlign() { if (!this._input) return; - const newTextAlign = userFriendlyToHtmlAlignement[this._object.getTextAlign()] || 'left'; + const newTextAlign = + userFriendlyToHtmlAlignement[this._object.getTextAlign()] || 'left'; this._input.style.textAlign = newTextAlign; } - + isFocused() { return this._input === document.activeElement; } - getSubmitted() - { + getSubmitted() { return this._isSubmited; } @@ -374,5 +371,4 @@ namespace gdjs { } export const TextInputRuntimeObjectRenderer = TextInputRuntimeObjectPixiRenderer; export type TextInputRuntimeObjectRenderer = TextInputRuntimeObjectPixiRenderer; - } From 9efefa39aeb12a89d183158e0682a019dc969f42 Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 11:20:50 +0100 Subject: [PATCH 12/36] Update textinputruntimeobject.pixiruntimegamewithassets.spec.js --- .../textinputruntimeobject.pixiruntimegamewithassets.spec.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js b/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js index 1f7308178ec6..55566551d0cf 100644 --- a/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js +++ b/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js @@ -1,7 +1,5 @@ // @ts-check - - describe('gdjs.TextInputRuntimeObject (using a PixiJS RuntimeGame with DOM elements)', function () { /** * @param {gdjs.RuntimeScene} runtimeScene From 9898f2a857fb51372a21dada4604fab4f82d8fcf Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 12:07:36 +0100 Subject: [PATCH 13/36] Update textinputruntimeobject.pixiruntimegamewithassets.spec.js --- .../textinputruntimeobject.pixiruntimegamewithassets.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js b/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js index 55566551d0cf..1aaffbbf43aa 100644 --- a/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js +++ b/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js @@ -27,7 +27,7 @@ describe('gdjs.TextInputRuntimeObject (using a PixiJS RuntimeGame with DOM eleme readOnly: false, padding: 0, textAlign: 'left', - maxLength : 20, + maxLength: 20, }, }); From ec48bb4c10f08e429091370163b2c7449339d741 Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 12:29:56 +0100 Subject: [PATCH 14/36] Update textinputruntimeobject.pixiruntimegamewithassets.spec.js --- ...meobject.pixiruntimegamewithassets.spec.js | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js b/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js index 1aaffbbf43aa..0bc9b1d5c084 100644 --- a/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js +++ b/Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js @@ -169,33 +169,33 @@ describe('gdjs.TextInputRuntimeObject (using a PixiJS RuntimeGame with DOM eleme object, } = await setupObjectAndGetDomElementContainer(); - const inputElement = gameDomElementContainer.querySelector('input'); - if (!inputElement) throw new Error('Expected input element to be found'); + const formElement = gameDomElementContainer.querySelector('form'); + if (!formElement) throw new Error('Expected form element to be found'); // Check visibility of the DOM element is visible by default, if it should be visible // on the screen. runtimeScene.renderAndStep(1000 / 60); - expect(inputElement.style.display).to.be('initial'); + expect(formElement.style.display).to.be('initial'); // Check visibility of the DOM element is updated at each frame, // according to the object visibility. object.hide(true); runtimeScene.renderAndStep(1000 / 60); - expect(inputElement.style.display).to.be('none'); + expect(formElement.style.display).to.be('none'); object.hide(false); runtimeScene.renderAndStep(1000 / 60); - expect(inputElement.style.display).to.be('initial'); + expect(formElement.style.display).to.be('initial'); // Check visibility of the DOM element is updated at each frame, // according to the layer visibility. runtimeScene.getLayer('').show(false); runtimeScene.renderAndStep(1000 / 60); - expect(inputElement.style.display).to.be('none'); + expect(formElement.style.display).to.be('none'); runtimeScene.getLayer('').show(true); runtimeScene.renderAndStep(1000 / 60); - expect(inputElement.style.display).to.be('initial'); + expect(formElement.style.display).to.be('initial'); // Clean up - not mandatory but to avoid overloading the testing browser. runtimeScene.unloadScene(); @@ -208,31 +208,31 @@ describe('gdjs.TextInputRuntimeObject (using a PixiJS RuntimeGame with DOM eleme object, } = await setupObjectAndGetDomElementContainer(); - const inputElement = gameDomElementContainer.querySelector('input'); - if (!inputElement) throw new Error('Expected input element to be found'); + const formElement = gameDomElementContainer.querySelector('form'); + if (!formElement) throw new Error('Expected input element to be found'); // Check visibility of the DOM element is visible by default, if it should be visible // on the screen. runtimeScene.renderAndStep(1000 / 60); - expect(inputElement.style.display).to.be('initial'); + expect(formElement.style.display).to.be('initial'); // Check visibility of the DOM element is updated at each frame, // according to the object position of screen. object.setX(-500); // -500 + 300 (object default width) = -200, still outside the camera. runtimeScene.renderAndStep(1000 / 60); - expect(inputElement.style.display).to.be('none'); + expect(formElement.style.display).to.be('none'); object.setWidth(600); // -500 + 600 = 100, inside the camera runtimeScene.renderAndStep(1000 / 60); - expect(inputElement.style.display).to.be('initial'); + expect(formElement.style.display).to.be('initial'); runtimeScene.getLayer('').setCameraX(900); runtimeScene.renderAndStep(1000 / 60); - expect(inputElement.style.display).to.be('none'); + expect(formElement.style.display).to.be('none'); runtimeScene.getLayer('').setCameraX(400); runtimeScene.renderAndStep(1000 / 60); - expect(inputElement.style.display).to.be('initial'); + expect(formElement.style.display).to.be('initial'); // Clean up - not mandatory but to avoid overloading the testing browser. runtimeScene.unloadScene(); From 6e353394f900ee362c1cc9d73c1b5590269a14e8 Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 12:31:08 +0100 Subject: [PATCH 15/36] Update JsExtension.js --- Extensions/TextInput/JsExtension.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index 2e406e07e34c..c64032a4636c 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -809,7 +809,6 @@ module.exports = { const isTextArea = object.content.inputType === 'text area'; const textAlign = object.content.textAlign; - console.log(this._pixiText.width); if (textAlign === 'left') this._pixiText.position.x = 0; else if (textAlign === 'right') this._pixiText.position.x = From 26c09f8d1c4502b2eefde3dd1b204496c32f1777 Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 15:04:17 +0100 Subject: [PATCH 16/36] Update JsExtension.js --- Extensions/TextInput/JsExtension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index c64032a4636c..2dfb80bd8e5f 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -166,7 +166,7 @@ module.exports = { objectProperties .getOrCreate('fillColor') - .setValue(objectContent.fillColor || '0;0;0') + .setValue(objectContent.fillColor || '255;255;255') .setType('color') .setLabel(_('Fill color')) .setGroup(_('Field appearance')); From 8e9b935e66e75cd121b601c96b209b250cb1c9a0 Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 15:14:56 +0100 Subject: [PATCH 17/36] Update JsExtension.js --- Extensions/TextInput/JsExtension.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index 2dfb80bd8e5f..8c5d66f87db0 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -218,9 +218,9 @@ module.exports = { objectProperties .getOrCreate('maxLength') - .setValue(objectContent.maxLength || 20) + .setValue(objectContent.maxLength || 40) .setType('number') - .setLabel(_('Max length')) + .setLabel(_('Input value max length')) .setGroup(_('Border appearance')); objectProperties @@ -228,9 +228,9 @@ module.exports = { .setValue(objectContent.textAlign || 'left') .setType('choice') .addExtraInfo('left') - .addExtraInfo('right') .addExtraInfo('center') - .setLabel(_('text Alignement')) + .addExtraInfo('right') + .setLabel(_('Text alignement')) .setGroup(_('Border appearance')); return objectProperties; From 95d508c79c29292033913dede2eaac41f9e3442d Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 15:15:35 +0100 Subject: [PATCH 18/36] Update Extensions/TextInput/JsExtension.js Co-authored-by: AlexandreS <32449369+AlexandreSi@users.noreply.github.com> --- Extensions/TextInput/JsExtension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index 8c5d66f87db0..01a4bfe8a6ab 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -612,7 +612,7 @@ module.exports = { object .addScopedCondition( 'IsInputSubmitted', - _('Input is Submitted (Enter pressed'), + _('Input is submitted'), _( 'Check if the input is submitted, which usually happens when the Enter key is pressed on a keyboard, or a specific button on mobile virtual keyboards.' ), From c5f54e9ae6b17cc549668ec82624e9f07786d297 Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 15:15:53 +0100 Subject: [PATCH 19/36] Update Extensions/TextInput/JsExtension.js Co-authored-by: AlexandreS <32449369+AlexandreSi@users.noreply.github.com> --- Extensions/TextInput/JsExtension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index 01a4bfe8a6ab..1455f1284d64 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -616,7 +616,7 @@ module.exports = { _( 'Check if the input is submitted, which usually happens when the Enter key is pressed on a keyboard, or a specific button on mobile virtual keyboards.' ), - _('_PARAM0_ got input submitted'), + _('_PARAM0_ value was submitted'), '', 'res/conditions/surObject24.png', 'res/conditions/surObject.png' From c2e22d1f6447e573e6117924da9d31c6b66b226c Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 16:26:12 +0100 Subject: [PATCH 20/36] move logic from renderer to object --- .../textinputruntimeobject-pixi-renderer.ts | 18 ++---------------- Extensions/TextInput/textinputruntimeobject.ts | 13 ++++++++----- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts index 40f68a5b1025..ae1f978a3418 100644 --- a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts +++ b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts @@ -9,12 +9,6 @@ namespace gdjs { search: 'search', }; - const userFriendlyToHtmlAlignement = { - left: 'left', - center: 'center', - right: 'right', - }; - const formatRgbAndOpacityToCssRgba = ( rgbColor: [float, float, float], opacity: float @@ -38,7 +32,6 @@ namespace gdjs { private _instanceContainer: gdjs.RuntimeInstanceContainer; private _runtimeGame: gdjs.RuntimeGame; private _form: HTMLFormElement | null = null; - private _isSubmited: boolean; constructor( runtimeObject: gdjs.TextInputRuntimeObject, @@ -49,7 +42,6 @@ namespace gdjs { this._runtimeGame = this._instanceContainer.getGame(); this._createElement(); - this._isSubmited = false; } _createElement() { @@ -76,7 +68,6 @@ namespace gdjs { this._input.style.padding = this._object.getPadding() + 'px'; this._form.style.textAlign = this._object.getTextAlign(); this._form.appendChild(this._input); - this._isSubmited = false; this._input.addEventListener('input', () => { if (!this._input) return; @@ -92,7 +83,7 @@ namespace gdjs { this._form.addEventListener('submit', (event) => { event.preventDefault(); - this._isSubmited = true; + this._object.onRendererFormSubmitted(true); }); this.updateString(); @@ -143,8 +134,6 @@ namespace gdjs { updatePreRender() { if (!this._input || !this._form) return; - - this._isSubmited = false; // Hide the input entirely if the object is hidden. // Because this object is rendered as a DOM element (and not part of the PixiJS // scene graph), we have to do this manually. @@ -352,16 +341,13 @@ namespace gdjs { if (!this._input) return; const newTextAlign = - userFriendlyToHtmlAlignement[this._object.getTextAlign()] || 'left'; + this._object.getTextAlign() || 'left'; this._input.style.textAlign = newTextAlign; } isFocused() { return this._input === document.activeElement; } - getSubmitted() { - return this._isSubmited; - } focus() { if (!this._input) return; diff --git a/Extensions/TextInput/textinputruntimeobject.ts b/Extensions/TextInput/textinputruntimeobject.ts index 38f7bfb15ecc..964c6af0da23 100644 --- a/Extensions/TextInput/textinputruntimeobject.ts +++ b/Extensions/TextInput/textinputruntimeobject.ts @@ -106,7 +106,7 @@ namespace gdjs { private _borderWidth: float; private _disabled: boolean; private _readOnly: boolean; - + private _isSubmitted: boolean; _renderer: TextInputRuntimeObjectRenderer; constructor( @@ -133,7 +133,7 @@ namespace gdjs { this._padding = objectData.content.padding; this._textAlign = objectData.content.textAlign; this._maxLength = objectData.content.maxLength; - + this._isSubmitted = false; this._renderer = new gdjs.TextInputRuntimeObjectRenderer( this, instanceContainer @@ -267,6 +267,7 @@ namespace gdjs { } updatePreRender(instanceContainer: RuntimeInstanceContainer): void { + this._isSubmitted =false; this._renderer.updatePreRender(); } @@ -379,6 +380,10 @@ namespace gdjs { onRendererInputValueChanged(inputValue: string) { this._string = inputValue; } + + onRendererFormSubmitted(inputValue: boolean) { + this._isSubmitted = inputValue; + } getFontResourceName() { return this._fontResourceName; @@ -532,9 +537,7 @@ namespace gdjs { return this._renderer.isFocused(); } isSubmitted(): boolean { - console.log(this._renderer.getSubmitted()); - - return this._renderer.getSubmitted(); + return this._isSubmitted; } getMaxLength(): integer { From 6e86b5c92ee8483a55ebcb5ce126e708ecd38b90 Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 17:17:29 +0100 Subject: [PATCH 21/36] Update JsExtension.js --- Extensions/TextInput/JsExtension.js | 74 ++++++++++++++--------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index 1455f1284d64..e6077d72eb60 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -166,7 +166,7 @@ module.exports = { objectProperties .getOrCreate('fillColor') - .setValue(objectContent.fillColor || '255;255;255') + .setValue(objectContent.fillColor || '0;0;0') .setType('color') .setLabel(_('Fill color')) .setGroup(_('Field appearance')); @@ -209,29 +209,29 @@ module.exports = { .setLabel(_('Width')) .setGroup(_('Border appearance')); - objectProperties + objectProperties .getOrCreate('padding') .setValue((objectContent.padding || 0).toString()) .setType('number') .setLabel(_('Padding')) - .setGroup(_('Border appearance')); + .setGroup(_('Font')); - objectProperties + objectProperties .getOrCreate('maxLength') .setValue(objectContent.maxLength || 40) .setType('number') - .setLabel(_('Input value max length')) - .setGroup(_('Border appearance')); + .setLabel(_('Max length')) + .setAdvanced(true); - objectProperties + objectProperties .getOrCreate('textAlign') .setValue(objectContent.textAlign || 'left') .setType('choice') .addExtraInfo('left') - .addExtraInfo('center') .addExtraInfo('right') - .setLabel(_('Text alignement')) - .setGroup(_('Border appearance')); + .addExtraInfo('center') + .setLabel(_('text Alignement')) + .setGroup(_('Font')); return objectProperties; }; @@ -307,7 +307,6 @@ module.exports = { // Properties expressions/conditions/actions: // Deprecated, see TextContainerCapability - object .addExpressionAndConditionAndAction( 'string', @@ -609,22 +608,21 @@ module.exports = { .getCodeExtraInformation() .setFunctionName('isFocused'); - object - .addScopedCondition( - 'IsInputSubmitted', - _('Input is submitted'), - _( - 'Check if the input is submitted, which usually happens when the Enter key is pressed on a keyboard, or a specific button on mobile virtual keyboards.' - ), - _('_PARAM0_ value was submitted'), - '', - 'res/conditions/surObject24.png', - 'res/conditions/surObject.png' - ) - .addParameter('object', _('Text input'), 'TextInputObject', false) - .getCodeExtraInformation() - .setFunctionName('isSubmitted'); - + object.addScopedCondition( + 'IsInputSubmitted', + _('Input is Submitted (Enter pressed'), + _( + 'Check if the input is submitted, which usually happens when the Enter key is pressed on a keyboard, or a specific button on mobile virtual keyboards.' + ), + _('_PARAM0_ got input submitted'), + '', + 'res/conditions/surObject24.png', + 'res/conditions/surObject.png' + ) + .addParameter('object', _('Text input'), 'TextInputObject',false) + .getCodeExtraInformation() + .setFunctionName('isSubmitted'); + object .addScopedAction( 'Focus', @@ -796,7 +794,7 @@ module.exports = { const borderWidth = object.content.borderWidth || 0; // Draw the mask for the text. - const textOffset = borderWidth + TEXT_MASK_PADDING; // + object.content.padding; + const textOffset = borderWidth + TEXT_MASK_PADDING;// + object.content.padding; this._pixiTextMask.clear(); this._pixiTextMask.beginFill(0xdddddd, 1); this._pixiTextMask.drawRect( @@ -809,15 +807,17 @@ module.exports = { const isTextArea = object.content.inputType === 'text area'; const textAlign = object.content.textAlign; - if (textAlign === 'left') this._pixiText.position.x = 0; - else if (textAlign === 'right') - this._pixiText.position.x = - 0 + width - this._pixiText.width - textOffset; - else if (textAlign === 'center') { - this._pixiText.align = 'center'; - this._pixiText.position.x = 0 + width / 2 - this._pixiText.width / 2; - } - + console.log(this._pixiText.width); + if(textAlign === 'left') + this._pixiText.position.x = 0; + else if(textAlign === 'right') + this._pixiText.position.x = 0 + width - this._pixiText.width - textOffset; + else if (textAlign === 'center') + { + this._pixiText.align = 'center'; + this._pixiText.position.x = 0 + width/2 - this._pixiText.width/2; + } + this._pixiText.position.y = isTextArea ? textOffset : height / 2 - this._pixiText.height / 2; From 42930403008a970742ccf7c991c74829e99b6d14 Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 17:40:34 +0100 Subject: [PATCH 22/36] Update JsExtension.js --- Extensions/TextInput/JsExtension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index e6077d72eb60..82291621164c 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -211,7 +211,7 @@ module.exports = { objectProperties .getOrCreate('padding') - .setValue((objectContent.padding || 0).toString()) + .setValue((objectContent.padding || 0)) .setType('number') .setLabel(_('Padding')) .setGroup(_('Font')); From c62f4fd057c03562365d7a68d1bacd104283540a Mon Sep 17 00:00:00 2001 From: Neyl Date: Mon, 20 Jan 2025 17:55:07 +0100 Subject: [PATCH 23/36] update JsExtensions --- Extensions/TextInput/JsExtension.js | 4 ++-- Extensions/TextInput/textinputruntimeobject.ts | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index 82291621164c..1b84d0d8dd0d 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -218,7 +218,7 @@ module.exports = { objectProperties .getOrCreate('maxLength') - .setValue(objectContent.maxLength || 40) + .setValue(objectContent.maxLength || 0) .setType('number') .setLabel(_('Max length')) .setAdvanced(true); @@ -701,7 +701,7 @@ module.exports = { this._pixiGraphics = new PIXI.Graphics(); this._pixiTextMask = new PIXI.Graphics(); this._pixiText = new PIXI.Text(' ', { - align: 'right', + align: 'left', fontSize: 20, }); this._pixiText.mask = this._pixiTextMask; diff --git a/Extensions/TextInput/textinputruntimeobject.ts b/Extensions/TextInput/textinputruntimeobject.ts index 964c6af0da23..b52155d9d422 100644 --- a/Extensions/TextInput/textinputruntimeobject.ts +++ b/Extensions/TextInput/textinputruntimeobject.ts @@ -210,11 +210,10 @@ namespace gdjs { this.setReadOnly(newObjectData.content.readOnly); } if (oldObjectData.content.maxLength !== newObjectData.content.maxLength) { - this.SetMaxLength(newObjectData.content.maxLength); + this.setMaxLength(newObjectData.content.maxLength); } if (oldObjectData.content.textAlign !== newObjectData.content.textAlign) { this._textAlign = newObjectData.content.textAlign; - //this.setTextAlignement(newObjectData.content.textAlign); } if (oldObjectData.content.padding !== newObjectData.content.padding) { this.SetPadding(newObjectData.content.padding); @@ -543,7 +542,7 @@ namespace gdjs { getMaxLength(): integer { return this._maxLength; } - SetMaxLength(value: integer) { + setMaxLength(value: integer) { this._maxLength = value; this._renderer.updateMaxLength(); } From 0fb2efa61e0bef4ec66f19e367ce8671a523f236 Mon Sep 17 00:00:00 2001 From: Neyl Date: Tue, 21 Jan 2025 17:02:57 +0100 Subject: [PATCH 24/36] update for better maxlength support --- Extensions/TextInput/JsExtension.js | 68 +++++++++---------- .../textinputruntimeobject-pixi-renderer.ts | 38 ++++++----- .../TextInput/textinputruntimeobject.ts | 40 +++++------ 3 files changed, 77 insertions(+), 69 deletions(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index 1b84d0d8dd0d..237a09952ca4 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -166,7 +166,7 @@ module.exports = { objectProperties .getOrCreate('fillColor') - .setValue(objectContent.fillColor || '0;0;0') + .setValue(objectContent.fillColor || '255;255;255') .setType('color') .setLabel(_('Fill color')) .setGroup(_('Field appearance')); @@ -209,21 +209,22 @@ module.exports = { .setLabel(_('Width')) .setGroup(_('Border appearance')); - objectProperties + objectProperties .getOrCreate('padding') - .setValue((objectContent.padding || 0)) + .setValue((objectContent.padding || 0).toString()) .setType('number') .setLabel(_('Padding')) .setGroup(_('Font')); - - objectProperties + console.log(objectContent.maxLength); + objectProperties .getOrCreate('maxLength') - .setValue(objectContent.maxLength || 0) + .setValue((objectContent.maxLength || 0).toString()) .setType('number') .setLabel(_('Max length')) + .setDescription(_('The maximum length of the input value.')) .setAdvanced(true); - objectProperties + objectProperties .getOrCreate('textAlign') .setValue(objectContent.textAlign || 'left') .setType('choice') @@ -608,21 +609,22 @@ module.exports = { .getCodeExtraInformation() .setFunctionName('isFocused'); - object.addScopedCondition( - 'IsInputSubmitted', - _('Input is Submitted (Enter pressed'), - _( - 'Check if the input is submitted, which usually happens when the Enter key is pressed on a keyboard, or a specific button on mobile virtual keyboards.' - ), - _('_PARAM0_ got input submitted'), - '', - 'res/conditions/surObject24.png', - 'res/conditions/surObject.png' - ) - .addParameter('object', _('Text input'), 'TextInputObject',false) - .getCodeExtraInformation() - .setFunctionName('isSubmitted'); - + object + .addScopedCondition( + 'IsInputSubmitted', + _('Input is Submitted (Enter pressed'), + _( + 'Check if the input is submitted, which usually happens when the Enter key is pressed on a keyboard, or a specific button on mobile virtual keyboards.' + ), + _('_PARAM0_ got input submitted'), + '', + 'res/conditions/surObject24.png', + 'res/conditions/surObject.png' + ) + .addParameter('object', _('Text input'), 'TextInputObject', false) + .getCodeExtraInformation() + .setFunctionName('isSubmitted'); + object .addScopedAction( 'Focus', @@ -794,7 +796,7 @@ module.exports = { const borderWidth = object.content.borderWidth || 0; // Draw the mask for the text. - const textOffset = borderWidth + TEXT_MASK_PADDING;// + object.content.padding; + const textOffset = borderWidth + TEXT_MASK_PADDING; this._pixiTextMask.clear(); this._pixiTextMask.beginFill(0xdddddd, 1); this._pixiTextMask.drawRect( @@ -807,17 +809,15 @@ module.exports = { const isTextArea = object.content.inputType === 'text area'; const textAlign = object.content.textAlign; - console.log(this._pixiText.width); - if(textAlign === 'left') - this._pixiText.position.x = 0; - else if(textAlign === 'right') - this._pixiText.position.x = 0 + width - this._pixiText.width - textOffset; - else if (textAlign === 'center') - { - this._pixiText.align = 'center'; - this._pixiText.position.x = 0 + width/2 - this._pixiText.width/2; - } - + if (textAlign === 'left') this._pixiText.position.x = textOffset; + else if (textAlign === 'right') + this._pixiText.position.x = + 0 + width - this._pixiText.width - textOffset; + else if (textAlign === 'center') { + this._pixiText.align = 'center'; + this._pixiText.position.x = 0 + width / 2 - this._pixiText.width / 2; + } + this._pixiText.position.y = isTextArea ? textOffset : height / 2 - this._pixiText.height / 2; diff --git a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts index ae1f978a3418..ded4599513a9 100644 --- a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts +++ b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts @@ -49,14 +49,13 @@ namespace gdjs { throw new Error('Tried to recreate an input while it already exists.'); this._form = document.createElement('form'); - this._form.setAttribute('id', 'dynamicForm'); const isTextArea = this._object.getInputType() === 'text area'; this._input = document.createElement(isTextArea ? 'textarea' : 'input'); this._form.style.border = '0px'; this._input.autocomplete = 'off'; this._form.style.borderRadius = '0px'; this._form.style.backgroundColor = 'transparent'; - this._input.style.backgroundColor = 'red'; + this._input.style.backgroundColor = 'white'; this._input.style.border = '1px solid black'; this._form.style.position = 'absolute'; this._form.style.resize = 'none'; @@ -64,10 +63,13 @@ namespace gdjs { this._form.style.pointerEvents = 'auto'; // Element can be clicked/touched. this._form.style.display = 'none'; // Hide while object is being set up. this._form.style.boxSizing = 'border-box'; // Important for iOS, because border is added to width/height. - this._input.maxLength = this._object.getMaxLength(); + this._input.style.boxSizing = 'border-box'; + this._input.style.width = '100%'; + this._input.style.height = '100%'; this._input.style.padding = this._object.getPadding() + 'px'; this._form.style.textAlign = this._object.getTextAlign(); this._form.appendChild(this._input); + this._input.maxLength = this._object.getMaxLength(); this._input.addEventListener('input', () => { if (!this._input) return; @@ -83,7 +85,7 @@ namespace gdjs { this._form.addEventListener('submit', (event) => { event.preventDefault(); - this._object.onRendererFormSubmitted(true); + this._object.onRendererFormSubmitted(); }); this.updateString(); @@ -232,17 +234,17 @@ namespace gdjs { this._form.style.height = heightInContainer + 'px'; this._form.style.transform = 'rotate3d(0,0,1,' + (this._object.getAngle() % 360) + 'deg)'; - this._form.style.display = 'initial'; - this._form.style.padding = this._object.getPadding() + 'px'; + this._input.style.padding = this._object.getPadding() + 'px'; this._form.style.textAlign = this._object.getTextAlign(); // Automatically adjust the font size to follow the game scale. - this._form.style.fontSize = + this._input.style.fontSize = this._object.getFontSize() * runtimeGameRenderer.getCanvasToDomElementContainerHeightScale() + 'px'; // Display after the object is positioned. + this._form.style.display = 'initial'; } updateString() { @@ -256,8 +258,8 @@ namespace gdjs { } updateFont() { - if (!this._form) return; - this._form.style.fontFamily = this._instanceContainer + if (!this._input) return; + this._input.style.fontFamily = this._instanceContainer .getGame() .getFontManager() .getFontFamily(this._object.getFontResourceName()); @@ -284,9 +286,9 @@ namespace gdjs { } updateTextColor() { - if (!this._form) return; + if (!this._input) return; - this._form.style.color = formatRgbAndOpacityToCssRgba( + this._input.style.color = formatRgbAndOpacityToCssRgba( this._object._getRawTextColor(), 255 ); @@ -327,7 +329,10 @@ namespace gdjs { updateMaxLength() { if (!this._input) return; - + if (this._object.getMaxLength() <= 0) { + this._input?.removeAttribute('maxLength'); + return; + } this._input.maxLength = this._object.getMaxLength(); } @@ -340,8 +345,7 @@ namespace gdjs { updateTextAlign() { if (!this._input) return; - const newTextAlign = - this._object.getTextAlign() || 'left'; + const newTextAlign = this._object.getTextAlign() || 'left'; this._input.style.textAlign = newTextAlign; } @@ -355,6 +359,8 @@ namespace gdjs { this._input.focus(); } } - export const TextInputRuntimeObjectRenderer = TextInputRuntimeObjectPixiRenderer; - export type TextInputRuntimeObjectRenderer = TextInputRuntimeObjectPixiRenderer; + export const TextInputRuntimeObjectRenderer = + TextInputRuntimeObjectPixiRenderer; + export type TextInputRuntimeObjectRenderer = + TextInputRuntimeObjectPixiRenderer; } diff --git a/Extensions/TextInput/textinputruntimeobject.ts b/Extensions/TextInput/textinputruntimeobject.ts index b52155d9d422..4d9bf955844c 100644 --- a/Extensions/TextInput/textinputruntimeobject.ts +++ b/Extensions/TextInput/textinputruntimeobject.ts @@ -9,10 +9,10 @@ namespace gdjs { 'search', 'text area', ] as const; - const supportedtextAlign = ['left', 'center', 'right'] as const; + const supportedTextAlign = ['left', 'center', 'right'] as const; - type SupportedInputType = typeof supportedInputTypes[number]; - type SupportedtextAlign = typeof supportedtextAlign[number]; + type SupportedInputType = (typeof supportedInputTypes)[number]; + type SupportedTextAlign = (typeof supportedTextAlign)[number]; const parseInputType = (potentialInputType: string): SupportedInputType => { const lowercasedNewInputType = potentialInputType.toLowerCase(); @@ -23,12 +23,12 @@ namespace gdjs { return 'text'; }; - const parseTextAlign = (potentialTextAlign: string): SupportedtextAlign => { + const parseTextAlign = (potentialTextAlign: string): SupportedTextAlign => { const lowercasedNewTextAlign = potentialTextAlign.toLowerCase(); // @ts-ignore - we're actually checking that this value is correct. - if (supportedtextAlign.includes(lowercasedNewTextAlign)) - return potentialTextAlign as SupportedtextAlign; + if (supportedTextAlign.includes(lowercasedNewTextAlign)) + return potentialTextAlign as SupportedTextAlign; return 'left'; }; @@ -46,7 +46,7 @@ namespace gdjs { fillColor: string; fillOpacity: float; padding: integer; - textAlign: SupportedtextAlign; + textAlign: SupportedTextAlign; maxLength: integer; borderColor: string; borderOpacity: float; @@ -86,7 +86,8 @@ namespace gdjs { */ export class TextInputRuntimeObject extends gdjs.RuntimeObject - implements gdjs.TextContainer, gdjs.Resizable, gdjs.OpacityHandler { + implements gdjs.TextContainer, gdjs.Resizable, gdjs.OpacityHandler + { private _string: string; private _placeholder: string; private opacity: float = 255; @@ -99,7 +100,7 @@ namespace gdjs { private _fillColor: [float, float, float]; private _fillOpacity: float; private _padding: integer; - private _textAlign: SupportedtextAlign; + private _textAlign: SupportedTextAlign; private _maxLength: integer; private _borderColor: [float, float, float]; private _borderOpacity: float; @@ -130,9 +131,9 @@ namespace gdjs { this._borderWidth = objectData.content.borderWidth; this._disabled = objectData.content.disabled; this._readOnly = objectData.content.readOnly; - this._padding = objectData.content.padding; - this._textAlign = objectData.content.textAlign; - this._maxLength = objectData.content.maxLength; + this._padding = objectData.content.padding || 0; + this._textAlign = objectData.content.textAlign || 'left'; + this._maxLength = objectData.content.maxLength || 0; this._isSubmitted = false; this._renderer = new gdjs.TextInputRuntimeObjectRenderer( this, @@ -216,7 +217,7 @@ namespace gdjs { this._textAlign = newObjectData.content.textAlign; } if (oldObjectData.content.padding !== newObjectData.content.padding) { - this.SetPadding(newObjectData.content.padding); + this.setPadding(newObjectData.content.padding); } return true; @@ -266,7 +267,7 @@ namespace gdjs { } updatePreRender(instanceContainer: RuntimeInstanceContainer): void { - this._isSubmitted =false; + this._isSubmitted = false; this._renderer.updatePreRender(); } @@ -379,9 +380,9 @@ namespace gdjs { onRendererInputValueChanged(inputValue: string) { this._string = inputValue; } - - onRendererFormSubmitted(inputValue: boolean) { - this._isSubmitted = inputValue; + + onRendererFormSubmitted() { + this._isSubmitted = true; } getFontResourceName() { @@ -549,11 +550,12 @@ namespace gdjs { getPadding(): integer { return this._padding; } - SetPadding(value: integer) { + setPadding(value: integer) { this._padding = value; + this._renderer.updatePadding(); } - getTextAlign(): SupportedtextAlign { + getTextAlign(): SupportedTextAlign { return this._textAlign; } From 3fa2b58e4b0bef765ae7e41729313fc821b98b52 Mon Sep 17 00:00:00 2001 From: Neyl Date: Tue, 21 Jan 2025 17:06:38 +0100 Subject: [PATCH 25/36] Update JsExtension.js --- Extensions/TextInput/JsExtension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index 237a09952ca4..740055a7b334 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -231,7 +231,7 @@ module.exports = { .addExtraInfo('left') .addExtraInfo('right') .addExtraInfo('center') - .setLabel(_('text Alignement')) + .setLabel(_('Text alignment')) .setGroup(_('Font')); return objectProperties; From 76a049c5478faeb9191fc0cf3689e0cc7dda5af2 Mon Sep 17 00:00:00 2001 From: Neyl Date: Tue, 21 Jan 2025 17:23:12 +0100 Subject: [PATCH 26/36] Update JsExtension.js --- Extensions/TextInput/JsExtension.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index 237a09952ca4..34083b584c0b 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -215,7 +215,6 @@ module.exports = { .setType('number') .setLabel(_('Padding')) .setGroup(_('Font')); - console.log(objectContent.maxLength); objectProperties .getOrCreate('maxLength') .setValue((objectContent.maxLength || 0).toString()) From 484901782f244aef4324bacebf96f6df052bc20e Mon Sep 17 00:00:00 2001 From: Neyl Date: Tue, 21 Jan 2025 17:24:13 +0100 Subject: [PATCH 27/36] Update Extensions/TextInput/JsExtension.js Co-authored-by: AlexandreS <32449369+AlexandreSi@users.noreply.github.com> --- Extensions/TextInput/JsExtension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index fe588f8c8c87..e59f47f820a6 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -615,7 +615,7 @@ module.exports = { _( 'Check if the input is submitted, which usually happens when the Enter key is pressed on a keyboard, or a specific button on mobile virtual keyboards.' ), - _('_PARAM0_ got input submitted'), + _('_PARAM0_ value was submitted'), '', 'res/conditions/surObject24.png', 'res/conditions/surObject.png' From c62f41a0552380ad146240e59f4b8e3607211ae6 Mon Sep 17 00:00:00 2001 From: Neyl Date: Tue, 21 Jan 2025 17:26:43 +0100 Subject: [PATCH 28/36] Update textinputruntimeobject-pixi-renderer.ts --- .../textinputruntimeobject-pixi-renderer.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts index ded4599513a9..3a584089fae8 100644 --- a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts +++ b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts @@ -49,27 +49,31 @@ namespace gdjs { throw new Error('Tried to recreate an input while it already exists.'); this._form = document.createElement('form'); + const isTextArea = this._object.getInputType() === 'text area'; this._input = document.createElement(isTextArea ? 'textarea' : 'input'); + this._form.style.border = '0px'; - this._input.autocomplete = 'off'; this._form.style.borderRadius = '0px'; this._form.style.backgroundColor = 'transparent'; - this._input.style.backgroundColor = 'white'; - this._input.style.border = '1px solid black'; this._form.style.position = 'absolute'; - this._form.style.resize = 'none'; this._form.style.outline = 'none'; + this._form.style.resize = 'none'; this._form.style.pointerEvents = 'auto'; // Element can be clicked/touched. this._form.style.display = 'none'; // Hide while object is being set up. this._form.style.boxSizing = 'border-box'; // Important for iOS, because border is added to width/height. + this._form.style.textAlign = this._object.getTextAlign(); + + this._input.autocomplete = 'off'; + this._input.style.backgroundColor = 'white'; + this._input.style.border = '1px solid black'; this._input.style.boxSizing = 'border-box'; this._input.style.width = '100%'; this._input.style.height = '100%'; + this._input.maxLength = this._object.getMaxLength(); this._input.style.padding = this._object.getPadding() + 'px'; - this._form.style.textAlign = this._object.getTextAlign(); + this._form.appendChild(this._input); - this._input.maxLength = this._object.getMaxLength(); this._input.addEventListener('input', () => { if (!this._input) return; @@ -234,8 +238,9 @@ namespace gdjs { this._form.style.height = heightInContainer + 'px'; this._form.style.transform = 'rotate3d(0,0,1,' + (this._object.getAngle() % 360) + 'deg)'; - this._input.style.padding = this._object.getPadding() + 'px'; this._form.style.textAlign = this._object.getTextAlign(); + + this._input.style.padding = this._object.getPadding() + 'px'; // Automatically adjust the font size to follow the game scale. this._input.style.fontSize = From 7cfa661619807ff5fef6b85961d53b6aa4bf3d95 Mon Sep 17 00:00:00 2001 From: Neyl Date: Tue, 21 Jan 2025 17:58:26 +0100 Subject: [PATCH 29/36] Update textinputruntimeobject.ts --- Extensions/TextInput/textinputruntimeobject.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Extensions/TextInput/textinputruntimeobject.ts b/Extensions/TextInput/textinputruntimeobject.ts index 4d9bf955844c..f70929d10c8a 100644 --- a/Extensions/TextInput/textinputruntimeobject.ts +++ b/Extensions/TextInput/textinputruntimeobject.ts @@ -11,8 +11,8 @@ namespace gdjs { ] as const; const supportedTextAlign = ['left', 'center', 'right'] as const; - type SupportedInputType = (typeof supportedInputTypes)[number]; - type SupportedTextAlign = (typeof supportedTextAlign)[number]; + type SupportedInputType = typeof supportedInputTypes[number]; + type SupportedTextAlign = typeof supportedTextAlign[number]; const parseInputType = (potentialInputType: string): SupportedInputType => { const lowercasedNewInputType = potentialInputType.toLowerCase(); From fbddfa5cbeefde7910356139ba7abd3efceb7e4c Mon Sep 17 00:00:00 2001 From: Neyl Date: Tue, 21 Jan 2025 18:39:45 +0100 Subject: [PATCH 30/36] update typo and setTextAlign function --- Extensions/TextInput/JsExtension.js | 4 ++-- .../textinputruntimeobject-pixi-renderer.ts | 9 +++++---- Extensions/TextInput/textinputruntimeobject.ts | 14 ++++++++++---- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index e59f47f820a6..dc9ac54e738b 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -228,8 +228,8 @@ module.exports = { .setValue(objectContent.textAlign || 'left') .setType('choice') .addExtraInfo('left') - .addExtraInfo('right') .addExtraInfo('center') + .addExtraInfo('right') .setLabel(_('Text alignment')) .setGroup(_('Font')); @@ -611,7 +611,7 @@ module.exports = { object .addScopedCondition( 'IsInputSubmitted', - _('Input is Submitted (Enter pressed'), + _('Input is submitted'), _( 'Check if the input is submitted, which usually happens when the Enter key is pressed on a keyboard, or a specific button on mobile virtual keyboards.' ), diff --git a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts index 3a584089fae8..3c81639f7f05 100644 --- a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts +++ b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts @@ -61,7 +61,7 @@ namespace gdjs { this._form.style.resize = 'none'; this._form.style.pointerEvents = 'auto'; // Element can be clicked/touched. this._form.style.display = 'none'; // Hide while object is being set up. - this._form.style.boxSizing = 'border-box'; // Important for iOS, because border is added to width/height. + this._form.style.boxSizing = 'border-box'; this._form.style.textAlign = this._object.getTextAlign(); this._input.autocomplete = 'off'; @@ -333,12 +333,13 @@ namespace gdjs { } updateMaxLength() { - if (!this._input) return; + const input = this._input; + if (!input) return; if (this._object.getMaxLength() <= 0) { - this._input?.removeAttribute('maxLength'); + input.removeAttribute('maxLength'); return; } - this._input.maxLength = this._object.getMaxLength(); + input.maxLength = this._object.getMaxLength(); } updatePadding() { diff --git a/Extensions/TextInput/textinputruntimeobject.ts b/Extensions/TextInput/textinputruntimeobject.ts index f70929d10c8a..c6bbe6ec50b6 100644 --- a/Extensions/TextInput/textinputruntimeobject.ts +++ b/Extensions/TextInput/textinputruntimeobject.ts @@ -544,6 +544,9 @@ namespace gdjs { return this._maxLength; } setMaxLength(value: integer) { + if(this._maxLength === value) + return; + this._maxLength = value; this._renderer.updateMaxLength(); } @@ -551,6 +554,9 @@ namespace gdjs { return this._padding; } setPadding(value: integer) { + if(this._padding === value) + return; + this._padding = value; this._renderer.updatePadding(); } @@ -560,10 +566,10 @@ namespace gdjs { } setTextAlign(newTextAlign: string) { - const lowercasedNewTextAlign = newTextAlign.toLowerCase(); - if (lowercasedNewTextAlign === this._textAlign) return; - - this._textAlign = parseTextAlign(lowercasedNewTextAlign); + const parsedTextAlign = parseTextAlign(newTextAlign); + if (parsedTextAlign === this._textAlign) return; + + this._textAlign = parsedTextAlign; this._renderer.updateTextAlign(); } From 3a893e8a20d9d2ebc603c2aa9015aac3c315186c Mon Sep 17 00:00:00 2001 From: Neyl Date: Tue, 21 Jan 2025 18:46:40 +0100 Subject: [PATCH 31/36] update for format --- .../textinputruntimeobject-pixi-renderer.ts | 16 +++++++--------- Extensions/TextInput/textinputruntimeobject.ts | 11 ++++------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts index 3c81639f7f05..6dd65c2f6ccf 100644 --- a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts +++ b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts @@ -49,10 +49,10 @@ namespace gdjs { throw new Error('Tried to recreate an input while it already exists.'); this._form = document.createElement('form'); - + const isTextArea = this._object.getInputType() === 'text area'; this._input = document.createElement(isTextArea ? 'textarea' : 'input'); - + this._form.style.border = '0px'; this._form.style.borderRadius = '0px'; this._form.style.backgroundColor = 'transparent'; @@ -63,7 +63,7 @@ namespace gdjs { this._form.style.display = 'none'; // Hide while object is being set up. this._form.style.boxSizing = 'border-box'; this._form.style.textAlign = this._object.getTextAlign(); - + this._input.autocomplete = 'off'; this._input.style.backgroundColor = 'white'; this._input.style.border = '1px solid black'; @@ -72,7 +72,7 @@ namespace gdjs { this._input.style.height = '100%'; this._input.maxLength = this._object.getMaxLength(); this._input.style.padding = this._object.getPadding() + 'px'; - + this._form.appendChild(this._input); this._input.addEventListener('input', () => { @@ -239,7 +239,7 @@ namespace gdjs { this._form.style.transform = 'rotate3d(0,0,1,' + (this._object.getAngle() % 360) + 'deg)'; this._form.style.textAlign = this._object.getTextAlign(); - + this._input.style.padding = this._object.getPadding() + 'px'; // Automatically adjust the font size to follow the game scale. @@ -365,8 +365,6 @@ namespace gdjs { this._input.focus(); } } - export const TextInputRuntimeObjectRenderer = - TextInputRuntimeObjectPixiRenderer; - export type TextInputRuntimeObjectRenderer = - TextInputRuntimeObjectPixiRenderer; + export const TextInputRuntimeObjectRenderer = TextInputRuntimeObjectPixiRenderer; + export type TextInputRuntimeObjectRenderer = TextInputRuntimeObjectPixiRenderer; } diff --git a/Extensions/TextInput/textinputruntimeobject.ts b/Extensions/TextInput/textinputruntimeobject.ts index c6bbe6ec50b6..7bfb727cf71d 100644 --- a/Extensions/TextInput/textinputruntimeobject.ts +++ b/Extensions/TextInput/textinputruntimeobject.ts @@ -86,8 +86,7 @@ namespace gdjs { */ export class TextInputRuntimeObject extends gdjs.RuntimeObject - implements gdjs.TextContainer, gdjs.Resizable, gdjs.OpacityHandler - { + implements gdjs.TextContainer, gdjs.Resizable, gdjs.OpacityHandler { private _string: string; private _placeholder: string; private opacity: float = 255; @@ -544,8 +543,7 @@ namespace gdjs { return this._maxLength; } setMaxLength(value: integer) { - if(this._maxLength === value) - return; + if (this._maxLength === value) return; this._maxLength = value; this._renderer.updateMaxLength(); @@ -554,8 +552,7 @@ namespace gdjs { return this._padding; } setPadding(value: integer) { - if(this._padding === value) - return; + if (this._padding === value) return; this._padding = value; this._renderer.updatePadding(); @@ -568,7 +565,7 @@ namespace gdjs { setTextAlign(newTextAlign: string) { const parsedTextAlign = parseTextAlign(newTextAlign); if (parsedTextAlign === this._textAlign) return; - + this._textAlign = parsedTextAlign; this._renderer.updateTextAlign(); } From b932c91f517e818135216f3e4b09be50a6176d63 Mon Sep 17 00:00:00 2001 From: Neyl Date: Wed, 22 Jan 2025 12:30:51 +0100 Subject: [PATCH 32/36] updated parser and secured types for pading, maxlength ,and textalign value. Fixed padding issue on pixi renderer --- Extensions/TextInput/JsExtension.js | 21 +++++++++---- .../textinputruntimeobject-pixi-renderer.ts | 5 ++-- .../TextInput/textinputruntimeobject.ts | 30 +++++++++++++------ 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index dc9ac54e738b..e71e30af5229 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -220,7 +220,11 @@ module.exports = { .setValue((objectContent.maxLength || 0).toString()) .setType('number') .setLabel(_('Max length')) - .setDescription(_('The maximum length of the input value.')) + .setDescription( + _( + 'The maximum length of the input value. (this property will be ignored if the input type is a number' + ) + ) .setAdvanced(true); objectProperties @@ -251,7 +255,7 @@ module.exports = { disabled: false, padding: 0, textAlign: 'left', - maxLength: '20', + maxLength: 0, }; textInputObject.updateInitialInstanceProperty = function ( @@ -807,11 +811,18 @@ module.exports = { this._pixiTextMask.endFill(); const isTextArea = object.content.inputType === 'text area'; - const textAlign = object.content.textAlign; - if (textAlign === 'left') this._pixiText.position.x = textOffset; + const textAlign = object.content.textAlign + ? object.content.textAlign + : 'left'; + const padding = object.content.padding + ? parseFloat(object.content.padding) + : 0; + + if (textAlign === 'left') + this._pixiText.position.x = textOffset + padding; else if (textAlign === 'right') this._pixiText.position.x = - 0 + width - this._pixiText.width - textOffset; + 0 + width - this._pixiText.width - textOffset - padding; else if (textAlign === 'center') { this._pixiText.align = 'center'; this._pixiText.position.x = 0 + width / 2 - this._pixiText.width / 2; diff --git a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts index 6dd65c2f6ccf..aed2999a9321 100644 --- a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts +++ b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts @@ -272,7 +272,8 @@ namespace gdjs { updateOpacity() { if (!this._form) return; - this._form.style.opacity = '' + this._object.getOpacity() / 255; + this._form.style.opacity = + '' + (this._object.getOpacity() / 255).toFixed(3); } updateInputType() { @@ -351,7 +352,7 @@ namespace gdjs { updateTextAlign() { if (!this._input) return; - const newTextAlign = this._object.getTextAlign() || 'left'; + const newTextAlign = this._object.getTextAlign(); this._input.style.textAlign = newTextAlign; } diff --git a/Extensions/TextInput/textinputruntimeobject.ts b/Extensions/TextInput/textinputruntimeobject.ts index 7bfb727cf71d..8379ed7def69 100644 --- a/Extensions/TextInput/textinputruntimeobject.ts +++ b/Extensions/TextInput/textinputruntimeobject.ts @@ -23,7 +23,10 @@ namespace gdjs { return 'text'; }; - const parseTextAlign = (potentialTextAlign: string): SupportedTextAlign => { + const parseTextAlign = ( + potentialTextAlign: string | undefined + ): SupportedTextAlign => { + if (!potentialTextAlign) return 'left'; const lowercasedNewTextAlign = potentialTextAlign.toLowerCase(); // @ts-ignore - we're actually checking that this value is correct. @@ -45,9 +48,9 @@ namespace gdjs { textColor: string; fillColor: string; fillOpacity: float; - padding: integer; - textAlign: SupportedTextAlign; - maxLength: integer; + padding?: float; + textAlign?: SupportedTextAlign; + maxLength?: integer; borderColor: string; borderOpacity: float; borderWidth: float; @@ -130,9 +133,9 @@ namespace gdjs { this._borderWidth = objectData.content.borderWidth; this._disabled = objectData.content.disabled; this._readOnly = objectData.content.readOnly; + this._textAlign = parseTextAlign(objectData.content.textAlign); //textAlign is defaulted to 'left' by the parser if undefined. + this._maxLength = objectData.content.maxLength || 0; //maxlength and padding require a default value as they can be undefined in older projects. this._padding = objectData.content.padding || 0; - this._textAlign = objectData.content.textAlign || 'left'; - this._maxLength = objectData.content.maxLength || 0; this._isSubmitted = false; this._renderer = new gdjs.TextInputRuntimeObjectRenderer( this, @@ -209,13 +212,22 @@ namespace gdjs { if (oldObjectData.content.readOnly !== newObjectData.content.readOnly) { this.setReadOnly(newObjectData.content.readOnly); } - if (oldObjectData.content.maxLength !== newObjectData.content.maxLength) { + if ( + newObjectData.content.maxLength && + oldObjectData.content.maxLength !== newObjectData.content.maxLength + ) { this.setMaxLength(newObjectData.content.maxLength); } - if (oldObjectData.content.textAlign !== newObjectData.content.textAlign) { + if ( + newObjectData.content.textAlign && + oldObjectData.content.textAlign !== newObjectData.content.textAlign + ) { this._textAlign = newObjectData.content.textAlign; } - if (oldObjectData.content.padding !== newObjectData.content.padding) { + if ( + newObjectData.content.padding && + oldObjectData.content.padding !== newObjectData.content.padding + ) { this.setPadding(newObjectData.content.padding); } From 9c8eecce7b2c6b65d67bf1afbbd2e839e9f6fdf8 Mon Sep 17 00:00:00 2001 From: Neyl Date: Wed, 22 Jan 2025 12:36:16 +0100 Subject: [PATCH 33/36] padding cannot be < 0 --- Extensions/TextInput/textinputruntimeobject.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Extensions/TextInput/textinputruntimeobject.ts b/Extensions/TextInput/textinputruntimeobject.ts index 8379ed7def69..3520ee4d8523 100644 --- a/Extensions/TextInput/textinputruntimeobject.ts +++ b/Extensions/TextInput/textinputruntimeobject.ts @@ -565,6 +565,10 @@ namespace gdjs { } setPadding(value: integer) { if (this._padding === value) return; + if (value < 0) { + this._padding = 0; + return; + } this._padding = value; this._renderer.updatePadding(); From bb175cc2354c463b6eff095842ba7d1dea2b9caa Mon Sep 17 00:00:00 2001 From: Neyl Date: Wed, 22 Jan 2025 12:42:35 +0100 Subject: [PATCH 34/36] Update Extensions/TextInput/JsExtension.js Co-authored-by: AlexandreS <32449369+AlexandreSi@users.noreply.github.com> --- Extensions/TextInput/JsExtension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/TextInput/JsExtension.js b/Extensions/TextInput/JsExtension.js index e71e30af5229..e89167677b4c 100644 --- a/Extensions/TextInput/JsExtension.js +++ b/Extensions/TextInput/JsExtension.js @@ -222,7 +222,7 @@ module.exports = { .setLabel(_('Max length')) .setDescription( _( - 'The maximum length of the input value. (this property will be ignored if the input type is a number' + 'The maximum length of the input value (this property will be ignored if the input type is a number).' ) ) .setAdvanced(true); From 184159d74ac52cd38ebbaf70b9875ec1c0172802 Mon Sep 17 00:00:00 2001 From: Neyl Date: Wed, 22 Jan 2025 12:45:29 +0100 Subject: [PATCH 35/36] Update Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts Co-authored-by: AlexandreS <32449369+AlexandreSi@users.noreply.github.com> --- Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts index aed2999a9321..f1fb80ed4238 100644 --- a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts +++ b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts @@ -273,7 +273,7 @@ namespace gdjs { updateOpacity() { if (!this._form) return; this._form.style.opacity = - '' + (this._object.getOpacity() / 255).toFixed(3); + (this._object.getOpacity() / 255).toFixed(3); } updateInputType() { From 34b6d36f33a8b2d8852577cba049937ab367c403 Mon Sep 17 00:00:00 2001 From: Neyl Date: Wed, 22 Jan 2025 14:11:12 +0100 Subject: [PATCH 36/36] last formatting --- Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts index f1fb80ed4238..1a03b98a1336 100644 --- a/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts +++ b/Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts @@ -272,8 +272,7 @@ namespace gdjs { updateOpacity() { if (!this._form) return; - this._form.style.opacity = - (this._object.getOpacity() / 255).toFixed(3); + this._form.style.opacity = (this._object.getOpacity() / 255).toFixed(3); } updateInputType() {