Add vertical alignement for BitmapText and BBText (#7523)

This commit is contained in:
D8H
2025-03-31 21:00:58 +02:00
committed by GitHub
parent 416ef44ee1
commit a02b8dcfe0
7 changed files with 420 additions and 210 deletions

View File

@@ -81,6 +81,19 @@ module.exports = {
.setLabel(_('Base alignment'))
.setGroup(_('Appearance'));
if (!objectContent.verticalTextAlignment) {
objectContent.verticalTextAlignment = 'top';
}
objectProperties
.getOrCreate('verticalTextAlignment')
.setValue(objectContent.verticalTextAlignment)
.setType('choice')
.addExtraInfo('top')
.addExtraInfo('center')
.addExtraInfo('bottom')
.setLabel(_('Vertical alignment'))
.setGroup(_('Appearance'));
objectProperties
.getOrCreate('fontFamily')
.setValue(objectContent.fontFamily)
@@ -89,13 +102,6 @@ module.exports = {
.setLabel(_('Font'))
.setGroup(_('Font'));
objectProperties
.getOrCreate('wordWrap')
.setValue(objectContent.wordWrap ? 'true' : 'false')
.setType('boolean')
.setLabel(_('Word wrapping'))
.setGroup(_('Appearance'));
objectProperties
.getOrCreate('visible')
.setValue(objectContent.visible ? 'true' : 'false')
@@ -113,7 +119,7 @@ module.exports = {
color: '0;0;0',
fontFamily: 'Arial',
align: 'left',
wordWrap: true,
verticalTextAlignment: 'top',
};
objectBBText.updateInitialInstanceProperty = function (
@@ -371,19 +377,6 @@ module.exports = {
expressionLabel: _('Get the text alignment'),
expressionDescription: _('Get the text alignment'),
},
{
functionName: 'WordWrap',
iconPath: 'res/actions/scaleWidth24_black.png',
type: 'boolean',
instructionLabel: _('Word wrap'),
paramLabel: _('Word wrap'),
conditionDescription: _('Check if word wrap is enabled.'),
conditionSentence: _('Word wrap is enabled'),
actionDescription: _('Set word wrap'),
actionSentence: _('Activate word wrap for _PARAM0_: _PARAM1_'),
expressionLabel: '',
expressionDescription: '',
},
{
functionName: 'WrappingWidth',
iconPath: 'res/actions/scaleWidth24_black.png',
@@ -405,6 +398,35 @@ module.exports = {
addSettersAndGettersToObject(object, setterAndGetterProperties, 'BBText');
object
.addCondition(
'IsWordWrap',
_('Word wrapping'),
_('Check if word wrapping is enabled.'),
_('_PARAM0_ word wrapping is enabled'),
'',
'res/conditions/wordWrap24_black.png',
'res/conditions/wordWrap_black.png'
)
.addParameter('object', 'BBText', 'BBText', false)
.getCodeExtraInformation()
.setFunctionName('isWrapping');
object
.addAction(
'SetWordWrap',
_('Word wrapping'),
_('De/activate word wrapping.'),
_('Activate word wrapping of _PARAM0_: _PARAM1_'),
'',
'res/actions/wordWrap24_black.png',
'res/actions/wordWrap_black.png'
)
.addParameter('object', 'BBText', 'BBText', false)
.addParameter('yesorno', _('Activate word wrapping'), '', false)
.getCodeExtraInformation()
.setFunctionName('setWrapping');
object
.addAction(
`SetFontFamily2`,
@@ -502,7 +524,6 @@ module.exports = {
fontSize: '24px',
fill: '#cccccc',
tagStyle: 'bbcode',
wordWrap: true,
wordWrapWidth: 250, // This value is the default wrapping width of the runtime object.
align: 'left',
},
@@ -574,11 +595,18 @@ module.exports = {
});
}
const wordWrap = object.content.wordWrap;
const wordWrap = this._instance.hasCustomSize();
if (wordWrap !== this._pixiObject._style.wordWrap) {
this._pixiObject._style.wordWrap = wordWrap;
this._pixiObject.dirty = true;
}
if (this._instance.hasCustomSize()) {
const customWidth = this.getCustomWidth();
if (this._pixiObject._style.wordWrapWidth !== customWidth) {
this._pixiObject._style.wordWrapWidth = customWidth;
this._pixiObject.dirty = true;
}
}
const align = object.content.align;
if (align !== this._pixiObject._style.align) {
@@ -586,25 +614,42 @@ module.exports = {
this._pixiObject.dirty = true;
}
this._pixiObject.position.x =
this._instance.getX() + this._pixiObject.width / 2;
if (this._instance.hasCustomSize()) {
const alignmentX =
object.content.align === 'right'
? 1
: object.content.align === 'center'
? 0.5
: 0;
const width = this.getCustomWidth();
// A vector from the custom size center to the renderer center.
const centerToCenterX =
(width - this._pixiObject.width) * (alignmentX - 0.5);
this._pixiObject.position.x = this._instance.getX() + width / 2;
this._pixiObject.anchor.x =
0.5 - centerToCenterX / this._pixiObject.width;
} else {
this._pixiObject.position.x =
this._instance.getX() + this._pixiObject.width / 2;
this._pixiObject.anchor.x = 0.5;
}
const alignmentY =
object.content.verticalTextAlignment === 'bottom'
? 1
: object.content.verticalTextAlignment === 'center'
? 0.5
: 0;
this._pixiObject.position.y =
this._instance.getY() + this._pixiObject.height / 2;
this._instance.getY() + this._pixiObject.height * (0.5 - alignmentY);
this._pixiObject.anchor.y = 0.5;
this._pixiObject.rotation = RenderedInstance.toRad(
this._instance.getAngle()
);
if (this._instance.hasCustomSize() && this._pixiObject) {
const customWidth = this.getCustomWidth();
if (
this._pixiObject &&
this._pixiObject._style.wordWrapWidth !== customWidth
) {
this._pixiObject._style.wordWrapWidth = customWidth;
this._pixiObject.dirty = true;
}
}
// Do not hide completely an object so it can still be manipulated
const alphaForDisplay = Math.max(
this._instance.getOpacity() / 255,
@@ -626,6 +671,19 @@ module.exports = {
getDefaultHeight() {
return this._pixiObject.height;
}
getOriginY() {
const object = gd.castObject(
this._associatedObjectConfiguration,
gd.ObjectJsImplementation
);
const height = this.getHeight();
return object.content.verticalTextAlignment === 'bottom'
? height
: object.content.verticalTextAlignment === 'center'
? height / 2
: 0;
}
}
objectsRenderingService.registerInstanceRenderer(

View File

@@ -29,9 +29,9 @@ namespace gdjs {
runtimeObject._color[2]
),
tagStyle: 'bbcode',
wordWrap: runtimeObject._wordWrap,
wordWrap: runtimeObject._wrapping,
wordWrapWidth: runtimeObject._wrappingWidth,
align: runtimeObject._align as PIXI.TextStyleAlign | undefined,
align: runtimeObject._textAlign as PIXI.TextStyleAlign | undefined,
},
});
instanceContainer
@@ -39,10 +39,7 @@ namespace gdjs {
.getRenderer()
.addRendererObject(this._pixiObject, runtimeObject.getZOrder());
// Set the anchor in the center, so that the object rotates around
// its center
this._pixiObject.anchor.x = 0.5;
this._pixiObject.anchor.y = 0.5;
this.updateAlignment();
this.updateText();
this.updatePosition();
this.updateAngle();
@@ -55,7 +52,7 @@ namespace gdjs {
updateWordWrap(): void {
//@ts-ignore Private member usage.
this._pixiObject._style.wordWrap = this._object._wordWrap;
this._pixiObject._style.wordWrap = this._object._wrapping;
this._pixiObject.dirty = true;
this.updatePosition();
}
@@ -84,7 +81,7 @@ namespace gdjs {
updateAlignment(): void {
//@ts-ignore Private member usage.
this._pixiObject._style.align = this._object._align;
this._pixiObject._style.align = this._object._textAlign;
this._pixiObject.dirty = true;
}
@@ -106,9 +103,38 @@ namespace gdjs {
}
updatePosition(): void {
this._pixiObject.position.x = this._object.x + this._pixiObject.width / 2;
if (this._object.isWrapping()) {
const alignmentX =
this._object._textAlign === 'right'
? 1
: this._object._textAlign === 'center'
? 0.5
: 0;
const width = this._object.getWrappingWidth();
// A vector from the custom size center to the renderer center.
const centerToCenterX =
(width - this._pixiObject.width) * (alignmentX - 0.5);
this._pixiObject.position.x = this._object.x + width / 2;
this._pixiObject.anchor.x =
0.5 - centerToCenterX / this._pixiObject.width;
} else {
this._pixiObject.position.x =
this._object.x + this._pixiObject.width / 2;
this._pixiObject.anchor.x = 0.5;
}
const alignmentY =
this._object._verticalTextAlignment === 'bottom'
? 1
: this._object._verticalTextAlignment === 'center'
? 0.5
: 0;
this._pixiObject.position.y =
this._object.y + this._pixiObject.height / 2;
this._object.y + this._pixiObject.height * (0.5 - alignmentY);
this._pixiObject.anchor.y = 0.5;
}
updateAngle(): void {

View File

@@ -19,6 +19,7 @@ namespace gdjs {
wordWrap: boolean;
/** Alignment of the text: "left", "center" or "right" */
align: 'left' | 'center' | 'right';
verticalTextAlignment: 'top' | 'center' | 'bottom';
};
};
export type BBTextObjectData = ObjectData & BBTextObjectDataType;
@@ -32,6 +33,7 @@ namespace gdjs {
wwrap: boolean;
wwidth: float;
align: string;
vta: string;
hidden: boolean;
};
@@ -52,13 +54,14 @@ namespace gdjs {
/** color in format [r, g, b], where each component is in the range [0, 255] */
_color: integer[];
_fontFamily: string;
_fontSize: number;
_fontSize: float;
_wordWrap: boolean;
_wrapping: boolean = false;
_wrappingWidth: float = 250;
// This value is the default wrapping width of the runtime object.
_align: string;
_textAlign: string;
_verticalTextAlignment: string;
_renderer: gdjs.BBTextRuntimeObjectRenderer;
// While this should rather be exposed as a property for all objects, honor the "visible"
@@ -81,24 +84,26 @@ namespace gdjs {
this._fontFamily = objectData.content.fontFamily;
// @ts-ignore - parseFloat should not be required, but GDevelop 5.0 beta 92 and below were storing it as a string.
this._fontSize = parseFloat(objectData.content.fontSize);
this._wordWrap = objectData.content.wordWrap;
this._align = objectData.content.align;
this._textAlign = objectData.content.align;
this._verticalTextAlignment =
objectData.content.verticalTextAlignment || 'top';
this.hidden = !objectData.content.visible;
this._renderer = new gdjs.BBTextRuntimeObjectRenderer(
this,
instanceContainer
);
this.hidden = !objectData.content.visible;
// *ALWAYS* call `this.onCreated()` at the very end of your object constructor.
this.onCreated();
}
getRendererObject() {
override getRendererObject() {
return this._renderer.getRendererObject();
}
// @ts-ignore
updateFromObjectData(
override updateFromObjectData(
oldObjectData: BBTextObjectDataType,
newObjectData: BBTextObjectDataType
): boolean {
@@ -124,15 +129,23 @@ namespace gdjs {
this.setFontSize(newObjectData.content.fontSize);
}
if (oldObjectData.content.wordWrap !== newObjectData.content.wordWrap) {
this.setWordWrap(newObjectData.content.wordWrap);
this.setWrapping(newObjectData.content.wordWrap);
}
if (oldObjectData.content.align !== newObjectData.content.align) {
this.setAlignment(newObjectData.content.align);
this.setTextAlignment(newObjectData.content.align);
}
if (
oldObjectData.content.verticalTextAlignment !==
newObjectData.content.verticalTextAlignment
) {
this.setVerticalTextAlignment(
newObjectData.content.verticalTextAlignment
);
}
return true;
}
getNetworkSyncData(): BBTextObjectNetworkSyncData {
override getNetworkSyncData(): BBTextObjectNetworkSyncData {
return {
...super.getNetworkSyncData(),
text: this._text,
@@ -140,14 +153,15 @@ namespace gdjs {
c: this._color,
ff: this._fontFamily,
fs: this._fontSize,
wwrap: this._wordWrap,
wwrap: this._wrapping,
wwidth: this._wrappingWidth,
align: this._align,
align: this._textAlign,
vta: this._verticalTextAlignment,
hidden: this.hidden,
};
}
updateFromNetworkSyncData(
override updateFromNetworkSyncData(
networkSyncData: BBTextObjectNetworkSyncData
): void {
super.updateFromNetworkSyncData(networkSyncData);
@@ -167,26 +181,29 @@ namespace gdjs {
if (this._fontSize !== undefined) {
this.setFontSize(networkSyncData.fs);
}
if (this._wordWrap !== undefined) {
this.setWordWrap(networkSyncData.wwrap);
if (this._wrapping !== undefined) {
this.setWrapping(networkSyncData.wwrap);
}
if (this._wrappingWidth !== undefined) {
this.setWrappingWidth(networkSyncData.wwidth);
}
if (this._align !== undefined) {
this.setAlignment(networkSyncData.align);
if (this._textAlign !== undefined) {
this.setTextAlignment(networkSyncData.align);
}
if (this._verticalTextAlignment !== undefined) {
this.setVerticalTextAlignment(networkSyncData.vta);
}
if (this.hidden !== undefined) {
this.hide(networkSyncData.hidden);
}
}
/**
* Initialize the extra parameters that could be set for an instance.
*/
extraInitializationFromInitialInstance(initialInstanceData: InstanceData) {
override extraInitializationFromInitialInstance(
initialInstanceData: InstanceData
) {
if (initialInstanceData.customSize) {
this.setWrappingWidth(initialInstanceData.width);
this.setWrapping(true);
} else {
this.setWrappingWidth(
// This value is the default wrapping width of the runtime object.
@@ -198,7 +215,7 @@ namespace gdjs {
}
}
onDestroyed(): void {
override onDestroyed(): void {
super.onDestroyed();
this._renderer.destroy();
}
@@ -206,7 +223,7 @@ namespace gdjs {
/**
* Set the markup text to display.
*/
setBBText(text): void {
setBBText(text: string): void {
this._text = text;
this._renderer.updateText();
this.invalidateHitboxes();
@@ -219,7 +236,7 @@ namespace gdjs {
return this._text;
}
setColor(rgbColorString): void {
setColor(rgbColorString: string): void {
this._color = gdjs.rgbOrHexToRGBColor(rgbColorString);
this._renderer.updateColor();
}
@@ -232,7 +249,7 @@ namespace gdjs {
return this._color[0] + ';' + this._color[1] + ';' + this._color[2];
}
setFontSize(fontSize): void {
setFontSize(fontSize: float): void {
this._fontSize = fontSize;
this._renderer.updateFontSize();
}
@@ -241,47 +258,66 @@ namespace gdjs {
return this._fontSize;
}
setFontFamily(fontFamily): void {
setFontFamily(fontFamily: string): void {
this._fontFamily = fontFamily;
this._renderer.updateFontFamily();
}
getFontFamily() {
getFontFamily(): string {
return this._fontFamily;
}
setAlignment(align): void {
this._align = align;
/**
* @deprecated Use `setTextAlignment` instead
*/
setAlignment(align: string): void {
this.setTextAlignment(align);
}
setTextAlignment(align: string): void {
this._textAlign = align;
this._renderer.updateAlignment();
}
getAlignment() {
return this._align;
/**
* @deprecated Use `getTextAlignment` instead
*/
getAlignment(): string {
return this.getTextAlignment();
}
getTextAlignment(): string {
return this._textAlign;
}
/**
* Set object position on X axis.
* @param x The new position X of the object.
* Set the text alignment on Y axis for multiline text objects.
* @param alignment The text alignment.
*/
setX(x: float): void {
setVerticalTextAlignment(alignment: string): void {
this._verticalTextAlignment = alignment;
this._renderer.updatePosition();
}
/**
* Get the text alignment on Y axis of text object.
* @return The text alignment.
*/
getVerticalTextAlignment(): string {
return this._verticalTextAlignment;
}
override setX(x: float): void {
super.setX(x);
this._renderer.updatePosition();
}
/**
* Set object position on Y axis.
* @param y The new position Y of the object.
*/
setY(y: float): void {
override setY(y: float): void {
super.setY(y);
this._renderer.updatePosition();
}
/**
* Set the angle of the object.
* @param angle The new angle of the object.
*/
setAngle(angle: float): void {
override setAngle(angle: float): void {
super.setAngle(angle);
this._renderer.updateAngle();
}
@@ -327,31 +363,36 @@ namespace gdjs {
return this._wrappingWidth;
}
setWordWrap(wordWrap: boolean): void {
if (this._wordWrap === wordWrap) return;
setWrapping(wordWrap: boolean): void {
if (this._wrapping === wordWrap) return;
this._wordWrap = wordWrap;
this._wrapping = wordWrap;
this._renderer.updateWordWrap();
this.invalidateHitboxes();
}
getWordWrap() {
return this._wordWrap;
isWrapping() {
return this._wrapping;
}
/**
* Get the width of the object.
*/
getWidth(): float {
override getWidth(): float {
return this._renderer.getWidth();
}
/**
* Get the height of the object.
*/
getHeight(): float {
override getHeight(): float {
return this._renderer.getHeight();
}
override getDrawableY(): float {
return (
this.getY() -
(this._verticalTextAlignment === 'center'
? this.getHeight() / 2
: this._verticalTextAlignment === 'bottom'
? this.getHeight()
: 0)
);
}
}
// @ts-ignore
gdjs.registerObject('BBText::BBText', gdjs.BBTextRuntimeObject);

View File

@@ -67,6 +67,19 @@ module.exports = {
.setLabel(_('Alignment'))
.setGroup(_('Appearance'));
if (!objectContent.verticalTextAlignment) {
objectContent.verticalTextAlignment = 'top';
}
objectProperties
.getOrCreate('verticalTextAlignment')
.setValue(objectContent.verticalTextAlignment)
.setType('choice')
.addExtraInfo('top')
.addExtraInfo('center')
.addExtraInfo('bottom')
.setLabel(_('Vertical alignment'))
.setGroup(_('Appearance'));
objectProperties
.getOrCreate('bitmapFontResourceName')
.setValue(objectContent.bitmapFontResourceName)
@@ -97,13 +110,6 @@ module.exports = {
.setLabel(_('Font tint'))
.setGroup(_('Font'));
objectProperties
.getOrCreate('wordWrap')
.setValue(objectContent.wordWrap ? 'true' : 'false')
.setType('boolean')
.setLabel(_('Word wrapping'))
.setGroup(_('Appearance'));
return objectProperties;
};
bitmapTextObject.content = {
@@ -115,7 +121,7 @@ module.exports = {
bitmapFontResourceName: '',
textureAtlasResourceName: '',
align: 'left',
wordWrap: true,
verticalTextAlignment: 'top',
};
bitmapTextObject.updateInitialInstanceProperty = function (
@@ -341,7 +347,7 @@ module.exports = {
_('Alignment ("left", "right" or "center")')
)
)
.setFunctionName('getAlignment');
.setFunctionName('getTextAlignment');
object
.addAction(
@@ -361,36 +367,36 @@ module.exports = {
false
)
.getCodeExtraInformation()
.setFunctionName('setAlignment');
.setFunctionName('setTextAlignment');
object
.addCondition(
'WordWrap',
_('Word wrap'),
_('Check if word wrap is enabled.'),
_('_PARAM0_ word wrap is enabled'),
_('Word wrapping'),
_('Check if word wrapping is enabled.'),
_('_PARAM0_ word wrapping is enabled'),
'',
'res/conditions/wordWrap24_black.png',
'res/conditions/wordWrap_black.png'
)
.addParameter('object', _('Bitmap text'), 'BitmapTextObject', false)
.getCodeExtraInformation()
.setFunctionName('getWordWrap');
.setFunctionName('isWrapping');
object
.addAction(
'SetWordWrap',
_('Word wrap'),
_('Word wrapping'),
_('De/activate word wrapping.'),
_('Activate word wrap of _PARAM0_: _PARAM1_'),
_('Activate word wrapping of _PARAM0_: _PARAM1_'),
'',
'res/actions/wordWrap24_black.png',
'res/actions/wordWrap_black.png'
)
.addParameter('object', _('Bitmap text'), 'BitmapTextObject', false)
.addParameter('yesorno', _('Activate word wrap'), '', false)
.addParameter('yesorno', _('Activate word wrapping'), '', false)
.getCodeExtraInformation()
.setFunctionName('setWordWrap');
.setFunctionName('setWrapping');
object
.addExpressionAndConditionAndAction(
@@ -704,20 +710,46 @@ module.exports = {
}
// Set up the wrapping width if enabled.
const wordWrap = object.content.wordWrap;
if (wordWrap && this._instance.hasCustomSize()) {
this._pixiObject.maxWidth =
this.getCustomWidth() / this._pixiObject.scale.x;
this._pixiObject.dirty = true;
} else {
this._pixiObject.maxWidth = 0;
const oldMaxWidth = this._pixiObject.maxWidth;
this._pixiObject.maxWidth = this._instance.hasCustomSize()
? this.getCustomWidth() / this._pixiObject.scale.x
: 0;
if (oldMaxWidth !== this._pixiObject.maxWidth) {
this._pixiObject.dirty = true;
}
this._pixiObject.position.x =
this._instance.getX() + (this._pixiObject.textWidth * scale) / 2;
if (this._instance.hasCustomSize()) {
const alignmentX =
object.content.align === 'right'
? 1
: object.content.align === 'center'
? 0.5
: 0;
const width = this.getCustomWidth();
// A vector from the custom size center to the renderer center.
const centerToCenterX =
(width - this._pixiObject.width) * (alignmentX - 0.5);
this._pixiObject.position.x = this._instance.getX() + width / 2;
this._pixiObject.anchor.x =
0.5 - centerToCenterX / this._pixiObject.width;
} else {
this._pixiObject.position.x =
this._instance.getX() + this._pixiObject.width / 2;
this._pixiObject.anchor.x = 0.5;
}
const alignmentY =
object.content.verticalTextAlignment === 'bottom'
? 1
: object.content.verticalTextAlignment === 'center'
? 0.5
: 0;
this._pixiObject.position.y =
this._instance.getY() + (this._pixiObject.textHeight * scale) / 2;
this._instance.getY() + this._pixiObject.height * (0.5 - alignmentY);
this._pixiObject.anchor.y = 0.5;
this._pixiObject.rotation = RenderedInstance.toRad(
this._instance.getAngle()
);
@@ -738,19 +770,26 @@ module.exports = {
releaseBitmapFont(fontName);
}
/**
* Return the width of the instance, when it's not resized.
*/
getDefaultWidth() {
return this._pixiObject.width;
}
/**
* Return the height of the instance, when it's not resized.
*/
getDefaultHeight() {
return this._pixiObject.height;
}
getOriginY() {
const object = gd.castObject(
this._associatedObjectConfiguration,
gd.ObjectJsImplementation
);
const height = this.getHeight();
return object.content.verticalTextAlignment === 'bottom'
? height
: object.content.verticalTextAlignment === 'center'
? height / 2
: 0;
}
}
objectsRenderingService.registerInstanceRenderer(

View File

@@ -35,13 +35,6 @@ namespace gdjs {
.getRenderer()
.addRendererObject(this._pixiObject, runtimeObject.getZOrder());
// Set the anchor in the center, so that the object rotates around
// its center.
// @ts-ignore
this._pixiObject.anchor.x = 0.5;
// @ts-ignore
this._pixiObject.anchor.y = 0.5;
this.updateAlignment();
this.updateTextContent();
this.updateAngle();
@@ -130,7 +123,7 @@ namespace gdjs {
}
updateWrappingWidth(): void {
if (this._object._wordWrap) {
if (this._object._wrapping) {
this._pixiObject.maxWidth =
this._object._wrappingWidth / this._object._scaleX;
this._pixiObject.dirty = true;
@@ -148,13 +141,43 @@ namespace gdjs {
updateAlignment(): void {
// @ts-ignore - assume align is always a valid value.
this._pixiObject.align = this._object._align;
this._pixiObject.align = this._object._textAlign;
this.updatePosition();
}
updatePosition(): void {
this._pixiObject.position.x = this._object.x + this.getWidth() / 2;
this._pixiObject.position.y = this._object.y + this.getHeight() / 2;
if (this._object.isWrapping()) {
const alignmentX =
this._object._textAlign === 'right'
? 1
: this._object._textAlign === 'center'
? 0.5
: 0;
const width = this._object.getWrappingWidth();
// A vector from the custom size center to the renderer center.
const centerToCenterX =
(width - this._pixiObject.width) * (alignmentX - 0.5);
this._pixiObject.position.x = this._object.x + width / 2;
this._pixiObject.anchor.x =
0.5 - centerToCenterX / this._pixiObject.width;
} else {
this._pixiObject.position.x =
this._object.x + this._pixiObject.width / 2;
this._pixiObject.anchor.x = 0.5;
}
const alignmentY =
this._object._verticalTextAlignment === 'bottom'
? 1
: this._object._verticalTextAlignment === 'center'
? 0.5
: 0;
this._pixiObject.position.y =
this._object.y + this._pixiObject.height * (0.5 - alignmentY);
this._pixiObject.anchor.y = 0.5;
}
updateAngle(): void {

View File

@@ -15,12 +15,11 @@ namespace gdjs {
textureAtlasResourceName: string;
/** The scale of the text. */
scale: float;
/** Activate word wrap if set to true. */
wordWrap: boolean;
/** Wrapping with from custom size properties. */
wrappingWidth: float;
/** Alignment of the text. */
align: 'left' | 'center' | 'right';
verticalTextAlignment: 'top' | 'center' | 'bottom';
};
};
export type BitmapTextObjectData = ObjectData & BitmapTextObjectDataType;
@@ -35,6 +34,7 @@ namespace gdjs {
wwrap: boolean;
wwidth: float;
align: string;
vta: string;
};
export type BitmapTextObjectNetworkSyncData = ObjectNetworkSyncData &
@@ -62,9 +62,10 @@ namespace gdjs {
_textureAtlasResourceName: string;
_scaleX: number;
_scaleY: number;
_wordWrap: boolean;
_wrapping: boolean = false;
_wrappingWidth: float;
_align: string;
_textAlign: string;
_verticalTextAlignment: string;
_renderer: gdjs.BitmapTextRuntimeObjectPixiRenderer;
@@ -87,9 +88,10 @@ namespace gdjs {
objectData.content.textureAtlasResourceName; // texture file used with fnt/xml (bitmap font file)
this._scaleX = objectData.content.scale;
this._scaleY = objectData.content.scale;
this._wordWrap = objectData.content.wordWrap;
this._wrappingWidth = 0;
this._align = objectData.content.align;
this._textAlign = objectData.content.align;
this._verticalTextAlignment =
objectData.content.verticalTextAlignment || 'top';
this._renderer = new gdjs.BitmapTextRuntimeObjectRenderer(
this,
@@ -100,12 +102,12 @@ namespace gdjs {
this.onCreated();
}
getRendererObject() {
override getRendererObject() {
return this._renderer.getRendererObject();
}
// @ts-ignore
updateFromObjectData(
override updateFromObjectData(
oldObjectData: BitmapTextObjectDataType,
newObjectData: BitmapTextObjectDataType
): boolean {
@@ -138,17 +140,22 @@ namespace gdjs {
if (oldObjectData.content.scale !== newObjectData.content.scale) {
this.setScale(newObjectData.content.scale);
}
if (oldObjectData.content.wordWrap !== newObjectData.content.wordWrap) {
this.setWordWrap(newObjectData.content.wordWrap);
}
if (oldObjectData.content.align !== newObjectData.content.align) {
this.setAlignment(newObjectData.content.align);
this.setTextAlignment(newObjectData.content.align);
}
if (
oldObjectData.content.verticalTextAlignment !==
newObjectData.content.verticalTextAlignment
) {
this.setVerticalTextAlignment(
newObjectData.content.verticalTextAlignment
);
}
return true;
}
getNetworkSyncData(): BitmapTextObjectNetworkSyncData {
override getNetworkSyncData(): BitmapTextObjectNetworkSyncData {
return {
...super.getNetworkSyncData(),
text: this._text,
@@ -157,13 +164,14 @@ namespace gdjs {
bfrn: this._bitmapFontResourceName,
tarn: this._textureAtlasResourceName,
scale: this.getScale(),
wwrap: this._wordWrap,
wwrap: this._wrapping,
wwidth: this._wrappingWidth,
align: this._align,
align: this._textAlign,
vta: this._verticalTextAlignment,
};
}
updateFromNetworkSyncData(
override updateFromNetworkSyncData(
networkSyncData: BitmapTextObjectNetworkSyncData
): void {
super.updateFromNetworkSyncData(networkSyncData);
@@ -186,30 +194,36 @@ namespace gdjs {
if (this._scaleX !== undefined) {
this.setScale(networkSyncData.scale);
}
if (this._wordWrap !== undefined) {
this.setWordWrap(networkSyncData.wwrap);
if (this._wrapping !== undefined) {
this.setWrapping(networkSyncData.wwrap);
}
if (this._wrappingWidth !== undefined) {
this.setWrappingWidth(networkSyncData.wwidth);
}
if (this._align !== undefined) {
this.setAlignment(networkSyncData.align);
if (this._textAlign !== undefined) {
this.setTextAlignment(networkSyncData.align);
}
if (this._verticalTextAlignment !== undefined) {
this.setVerticalTextAlignment(networkSyncData.vta);
}
}
/**
* Initialize the extra parameters that could be set for an instance.
*/
extraInitializationFromInitialInstance(initialInstanceData: InstanceData) {
override extraInitializationFromInitialInstance(
initialInstanceData: InstanceData
) {
if (initialInstanceData.customSize) {
this.setWrappingWidth(initialInstanceData.width);
this.setWrapping(true);
}
if (initialInstanceData.opacity !== undefined) {
this.setOpacity(initialInstanceData.opacity);
}
}
onDestroyed(): void {
override onDestroyed(): void {
super.onDestroyed();
this._renderer.onDestroy();
}
@@ -314,38 +328,43 @@ namespace gdjs {
return this._textureAtlasResourceName;
}
setAlignment(align: string): void {
this._align = align;
setTextAlignment(align: string): void {
this._textAlign = align;
this._renderer.updateAlignment();
}
getAlignment(): string {
return this._align;
getTextAlignment(): string {
return this._textAlign;
}
/**
* Set object position on X axis.
* @param x The new position X of the object.
* Set the text alignment on Y axis for multiline text objects.
* @param alignment The text alignment.
*/
setX(x: float): void {
setVerticalTextAlignment(alignment: string): void {
this._verticalTextAlignment = alignment;
this._renderer.updatePosition();
}
/**
* Get the text alignment on Y axis of text object.
* @return The text alignment.
*/
getVerticalTextAlignment(): string {
return this._verticalTextAlignment;
}
override setX(x: float): void {
super.setX(x);
this._renderer.updatePosition();
}
/**
* Set object position on Y axis.
* @param y The new position Y of the object.
*/
setY(y: float): void {
override setY(y: float): void {
super.setY(y);
this._renderer.updatePosition();
}
/**
* Set the angle of the object.
* @param angle The new angle of the object.
*/
setAngle(angle: float): void {
override setAngle(angle: float): void {
super.setAngle(angle);
this._renderer.updateAngle();
}
@@ -389,29 +408,34 @@ namespace gdjs {
return this._wrappingWidth;
}
setWordWrap(wordWrap: boolean): void {
this._wordWrap = wordWrap;
setWrapping(wordWrap: boolean): void {
this._wrapping = wordWrap;
this._renderer.updateWrappingWidth();
this.invalidateHitboxes();
}
getWordWrap(): boolean {
return this._wordWrap;
isWrapping(): boolean {
return this._wrapping;
}
/**
* Get the width of the object.
*/
getWidth(): float {
override getWidth(): float {
return this._renderer.getWidth();
}
/**
* Get the height of the object.
*/
getHeight(): float {
override getHeight(): float {
return this._renderer.getHeight();
}
override getDrawableY(): float {
return (
this.getY() -
(this._verticalTextAlignment === 'center'
? this.getHeight() / 2
: this._verticalTextAlignment === 'bottom'
? this.getHeight()
: 0)
);
}
}
gdjs.registerObject(
'BitmapText::BitmapTextObject',

View File

@@ -357,8 +357,7 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
obj.AddAction("SetTextAlignment",
_("Alignment"),
_("Set the text alignment of a multiline text object (does not "
"work with single line texts)."),
_("Change the text alignment of a multiline text object."),
_("Align _PARAM0_: _PARAM1_"),
_("Style"),
"res/actions/textAlign24.png",
@@ -388,10 +387,10 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
obj.AddAction(
"SetWrapping",
_("Wrapping"),
_("Word wrapping"),
_("De/activate word wrapping. Note that word wrapping is a graphical "
"option,\nyou can't get the number of lines displayed"),
_("Activate wrapping style of _PARAM0_: _PARAM1_"),
_("Activate word wrapping of _PARAM0_: _PARAM1_"),
_("Style"),
"res/actions/wordWrap24_black.png",
"res/actions/wordWrap_black.png")
@@ -401,8 +400,8 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
obj.AddCondition("IsWrapping",
_("Wrapping"),
_("Test if the word wrapping style of an object is set."),
_("_PARAM0_ word wrapping style is activated"),
_("Check if word wrapping is enabled."),
_("_PARAM0_ word wrapping is enabled"),
_("Style"),
"res/conditions/wordWrap24_black.png",
"res/conditions/wordWrap_black.png")
@@ -411,7 +410,7 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
obj.AddAction("WrappingWidth",
_("Wrapping width"),
_("Modify the word wrapping width of a Text object."),
_("Change the word wrapping width of a Text object."),
_("the wrapping width"),
_("Style"),
"res/actions/wordWrap24_black.png",
@@ -423,7 +422,7 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
obj.AddCondition("WrappingWidth",
_("Wrapping width"),
_("Test the word wrapping width of a Text object."),
_("Compare the word wrapping width of a Text object."),
_("the wrapping width"),
_("Style"),
"res/conditions/wordWrap24_black.png",