From 0fb2efa61e0bef4ec66f19e367ce8671a523f236 Mon Sep 17 00:00:00 2001 From: Neyl Date: Tue, 21 Jan 2025 17:02:57 +0100 Subject: [PATCH] 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; }