Skip to content

Commit c4e230d

Browse files
authored
Split text input padding into 2 separate properties (#7338)
Don't show in changelog
1 parent 56ab2fd commit c4e230d

File tree

4 files changed

+120
-44
lines changed

4 files changed

+120
-44
lines changed

Extensions/TextInput/JsExtension.js

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,11 @@ module.exports = {
8181
} else if (propertyName === 'maxLength') {
8282
objectContent.maxLength = newValue;
8383
return true;
84-
} else if (propertyName === 'padding') {
85-
objectContent.padding = newValue;
84+
} else if (propertyName === 'paddingX') {
85+
objectContent.paddingX = Math.max(0, parseFloat(newValue));
86+
return true;
87+
} else if (propertyName === 'paddingY') {
88+
objectContent.paddingY = Math.max(0, parseFloat(newValue));
8689
return true;
8790
} else if (propertyName === 'textAlign') {
8891
objectContent.textAlign = newValue;
@@ -210,11 +213,27 @@ module.exports = {
210213
.setGroup(_('Border appearance'));
211214

212215
objectProperties
213-
.getOrCreate('padding')
214-
.setValue((objectContent.padding || 0).toString())
216+
.getOrCreate('paddingX')
217+
.setValue(
218+
(objectContent.paddingX !== undefined
219+
? objectContent.paddingX
220+
: 2
221+
).toString()
222+
)
215223
.setType('number')
216-
.setLabel(_('Padding'))
217-
.setGroup(_('Font'));
224+
.setLabel(_('Padding (horizontal)'))
225+
.setGroup(_('Field appearance'));
226+
objectProperties
227+
.getOrCreate('paddingY')
228+
.setValue(
229+
(objectContent.paddingY !== undefined
230+
? objectContent.paddingY
231+
: 1
232+
).toString()
233+
)
234+
.setType('number')
235+
.setLabel(_('Padding (vertical)'))
236+
.setGroup(_('Field appearance'));
218237
objectProperties
219238
.getOrCreate('maxLength')
220239
.setValue((objectContent.maxLength || 0).toString())
@@ -235,7 +254,7 @@ module.exports = {
235254
.addExtraInfo('center')
236255
.addExtraInfo('right')
237256
.setLabel(_('Text alignment'))
238-
.setGroup(_('Font'));
257+
.setGroup(_('Field appearance'));
239258

240259
return objectProperties;
241260
};
@@ -253,7 +272,8 @@ module.exports = {
253272
borderWidth: 1,
254273
readOnly: false,
255274
disabled: false,
256-
padding: 0,
275+
paddingX: 2,
276+
paddingY: 1,
257277
textAlign: 'left',
258278
maxLength: 0,
259279
};
@@ -683,7 +703,6 @@ module.exports = {
683703

684704
const DEFAULT_WIDTH = 300;
685705
const DEFAULT_HEIGHT = 30;
686-
const TEXT_MASK_PADDING = 2;
687706

688707
class RenderedTextInputObjectInstance extends RenderedInstance {
689708
constructor(
@@ -797,39 +816,51 @@ module.exports = {
797816
);
798817

799818
const borderWidth = object.content.borderWidth || 0;
819+
const paddingX =
820+
object.content.paddingX !== undefined
821+
? Math.min(
822+
parseFloat(object.content.paddingX),
823+
width / 2 - borderWidth
824+
)
825+
: 2;
826+
const paddingY =
827+
object.content.paddingY !== undefined
828+
? Math.min(
829+
parseFloat(object.content.paddingY),
830+
height / 2 - borderWidth
831+
)
832+
: 1;
800833

801834
// Draw the mask for the text.
802-
const textOffset = borderWidth + TEXT_MASK_PADDING;
835+
const textOffsetX = borderWidth + paddingX;
836+
// textOffsetY does not include the paddingY because browsers display the text, even if it is supposed to be cut off by vertical padding.
837+
const textOffsetY = borderWidth;
803838
this._pixiTextMask.clear();
804839
this._pixiTextMask.beginFill(0xdddddd, 1);
805840
this._pixiTextMask.drawRect(
806-
textOffset,
807-
textOffset,
808-
width - 2 * textOffset,
809-
height - 2 * textOffset
841+
textOffsetX,
842+
textOffsetY,
843+
width - 2 * textOffsetX,
844+
height - 2 * textOffsetY
810845
);
811846
this._pixiTextMask.endFill();
812847

813848
const isTextArea = object.content.inputType === 'text area';
814849
const textAlign = object.content.textAlign
815850
? object.content.textAlign
816851
: 'left';
817-
const padding = object.content.padding
818-
? parseFloat(object.content.padding)
819-
: 0;
820852

821-
if (textAlign === 'left')
822-
this._pixiText.position.x = textOffset + padding;
853+
if (textAlign === 'left') this._pixiText.position.x = textOffsetX;
823854
else if (textAlign === 'right')
824855
this._pixiText.position.x =
825-
0 + width - this._pixiText.width - textOffset - padding;
856+
0 + width - this._pixiText.width - textOffsetX;
826857
else if (textAlign === 'center') {
827858
this._pixiText.align = 'center';
828859
this._pixiText.position.x = 0 + width / 2 - this._pixiText.width / 2;
829860
}
830861

831862
this._pixiText.position.y = isTextArea
832-
? textOffset
863+
? textOffsetY + paddingY
833864
: height / 2 - this._pixiText.height / 2;
834865

835866
// Draw the background and border.

Extensions/TextInput/tests/textinputruntimeobject.pixiruntimegamewithassets.spec.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ describe('gdjs.TextInputRuntimeObject (using a PixiJS RuntimeGame with DOM eleme
2525
borderWidth: 2,
2626
disabled: false,
2727
readOnly: false,
28-
padding: 0,
28+
paddingX: 2,
29+
paddingY: 1,
2930
textAlign: 'left',
3031
maxLength: 20,
3132
},

Extensions/TextInput/textinputruntimeobject-pixi-renderer.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,21 +57,23 @@ namespace gdjs {
5757
this._form.style.borderRadius = '0px';
5858
this._form.style.backgroundColor = 'transparent';
5959
this._form.style.position = 'absolute';
60-
this._form.style.outline = 'none';
61-
this._form.style.resize = 'none';
6260
this._form.style.pointerEvents = 'auto'; // Element can be clicked/touched.
6361
this._form.style.display = 'none'; // Hide while object is being set up.
6462
this._form.style.boxSizing = 'border-box';
6563
this._form.style.textAlign = this._object.getTextAlign();
6664

6765
this._input.autocomplete = 'off';
6866
this._input.style.backgroundColor = 'white';
67+
this._input.style.outline = 'none'; // Remove any style added by the browser to highlight the focused field in a form (:focus & :focus-visible modifiers).
68+
this._input.style.resize = 'none'; // Prevent user from resizing the input when it's a text area.
6969
this._input.style.border = '1px solid black';
7070
this._input.style.boxSizing = 'border-box';
7171
this._input.style.width = '100%';
7272
this._input.style.height = '100%';
7373
this._input.maxLength = this._object.getMaxLength();
74-
this._input.style.padding = this._object.getPadding() + 'px';
74+
this._input.style.padding = `${this._object
75+
.getPaddingY()
76+
.toFixed(2)}px ${this._object.getPaddingX().toFixed(2)}px`;
7577

7678
this._form.appendChild(this._input);
7779

@@ -240,7 +242,9 @@ namespace gdjs {
240242
'rotate3d(0,0,1,' + (this._object.getAngle() % 360) + 'deg)';
241243
this._form.style.textAlign = this._object.getTextAlign();
242244

243-
this._input.style.padding = this._object.getPadding() + 'px';
245+
this._input.style.padding = `${this._object
246+
.getPaddingY()
247+
.toFixed(2)}px ${this._object.getPaddingX().toFixed(2)}px`;
244248

245249
// Automatically adjust the font size to follow the game scale.
246250
this._input.style.fontSize =
@@ -345,7 +349,9 @@ namespace gdjs {
345349
updatePadding() {
346350
if (!this._input) return;
347351

348-
this._input.style.padding = this._object.getPadding() + 'px';
352+
this._input.style.padding = `${this._object
353+
.getPaddingY()
354+
.toFixed(2)}px ${this._object.getPaddingX().toFixed(2)}px`;
349355
}
350356

351357
updateTextAlign() {

Extensions/TextInput/textinputruntimeobject.ts

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,17 @@ namespace gdjs {
4848
textColor: string;
4949
fillColor: string;
5050
fillOpacity: float;
51-
padding?: float;
52-
textAlign?: SupportedTextAlign;
53-
maxLength?: integer;
5451
borderColor: string;
5552
borderOpacity: float;
5653
borderWidth: float;
5754
disabled: boolean;
5855
readOnly: boolean;
56+
// ---- Values can be undefined because of support for these feature was added in v5.5.222.
57+
paddingX?: float;
58+
paddingY?: float;
59+
textAlign?: SupportedTextAlign;
60+
maxLength?: integer;
61+
// ----
5962
};
6063
}
6164

@@ -84,6 +87,10 @@ namespace gdjs {
8487
const DEFAULT_WIDTH = 300;
8588
const DEFAULT_HEIGHT = 30;
8689

90+
const clampPadding = (value: float, dimension: float, borderWidth: float) => {
91+
return Math.max(0, Math.min(dimension / 2 - borderWidth, value));
92+
};
93+
8794
/**
8895
* Shows a text input on the screen the player can type text into.
8996
*/
@@ -101,7 +108,8 @@ namespace gdjs {
101108
private _textColor: [float, float, float];
102109
private _fillColor: [float, float, float];
103110
private _fillOpacity: float;
104-
private _padding: integer;
111+
private _paddingX: integer;
112+
private _paddingY: integer;
105113
private _textAlign: SupportedTextAlign;
106114
private _maxLength: integer;
107115
private _borderColor: [float, float, float];
@@ -133,9 +141,16 @@ namespace gdjs {
133141
this._borderWidth = objectData.content.borderWidth;
134142
this._disabled = objectData.content.disabled;
135143
this._readOnly = objectData.content.readOnly;
136-
this._textAlign = parseTextAlign(objectData.content.textAlign); //textAlign is defaulted to 'left' by the parser if undefined.
137-
this._maxLength = objectData.content.maxLength || 0; //maxlength and padding require a default value as they can be undefined in older projects.
138-
this._padding = objectData.content.padding || 0;
144+
this._textAlign = parseTextAlign(objectData.content.textAlign);
145+
this._maxLength = objectData.content.maxLength || 0;
146+
this._paddingX =
147+
objectData.content.paddingX !== undefined
148+
? objectData.content.paddingX
149+
: 2;
150+
this._paddingY =
151+
objectData.content.paddingY !== undefined
152+
? objectData.content.paddingY
153+
: 1;
139154
this._isSubmitted = false;
140155
this._renderer = new gdjs.TextInputRuntimeObjectRenderer(
141156
this,
@@ -213,7 +228,7 @@ namespace gdjs {
213228
this.setReadOnly(newObjectData.content.readOnly);
214229
}
215230
if (
216-
newObjectData.content.maxLength &&
231+
newObjectData.content.maxLength !== undefined &&
217232
oldObjectData.content.maxLength !== newObjectData.content.maxLength
218233
) {
219234
this.setMaxLength(newObjectData.content.maxLength);
@@ -225,10 +240,16 @@ namespace gdjs {
225240
this._textAlign = newObjectData.content.textAlign;
226241
}
227242
if (
228-
newObjectData.content.padding &&
229-
oldObjectData.content.padding !== newObjectData.content.padding
243+
newObjectData.content.paddingX !== undefined &&
244+
oldObjectData.content.paddingX !== newObjectData.content.paddingX
230245
) {
231-
this.setPadding(newObjectData.content.padding);
246+
this.setPaddingX(newObjectData.content.paddingX);
247+
}
248+
if (
249+
newObjectData.content.paddingY !== undefined &&
250+
oldObjectData.content.paddingY !== newObjectData.content.paddingY
251+
) {
252+
this.setPaddingY(newObjectData.content.paddingY);
232253
}
233254

234255
return true;
@@ -296,6 +317,7 @@ namespace gdjs {
296317
if (initialInstanceData.customSize) {
297318
this.setWidth(initialInstanceData.width);
298319
this.setHeight(initialInstanceData.height);
320+
this._renderer.updatePadding();
299321
}
300322
if (initialInstanceData.opacity !== undefined) {
301323
this.setOpacity(initialInstanceData.opacity);
@@ -331,10 +353,12 @@ namespace gdjs {
331353

332354
setWidth(width: float): void {
333355
this._width = width;
356+
this._renderer.updatePadding();
334357
}
335358

336359
setHeight(height: float): void {
337360
this._height = height;
361+
this._renderer.updatePadding();
338362
}
339363

340364
/**
@@ -560,17 +584,31 @@ namespace gdjs {
560584
this._maxLength = value;
561585
this._renderer.updateMaxLength();
562586
}
563-
getPadding(): integer {
564-
return this._padding;
587+
588+
getPaddingX(): integer {
589+
return clampPadding(this._paddingX, this._width, this._borderWidth);
590+
}
591+
setPaddingX(value: integer) {
592+
if (this._paddingX === value) return;
593+
if (value < 0) {
594+
this._paddingX = 0;
595+
return;
596+
}
597+
598+
this._paddingX = value;
599+
this._renderer.updatePadding();
600+
}
601+
getPaddingY(): integer {
602+
return clampPadding(this._paddingY, this._height, this._borderWidth);
565603
}
566-
setPadding(value: integer) {
567-
if (this._padding === value) return;
604+
setPaddingY(value: integer) {
605+
if (this._paddingY === value) return;
568606
if (value < 0) {
569-
this._padding = 0;
607+
this._paddingY = 0;
570608
return;
571609
}
572610

573-
this._padding = value;
611+
this._paddingY = value;
574612
this._renderer.updatePadding();
575613
}
576614

0 commit comments

Comments
 (0)