mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Add vertical alignement for BitmapText and BBText (#7523)
This commit is contained in:
@@ -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(
|
||||
|
@@ -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 {
|
||||
|
@@ -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);
|
||||
|
@@ -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(
|
||||
|
@@ -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 {
|
||||
|
@@ -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',
|
||||
|
@@ -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",
|
||||
|
Reference in New Issue
Block a user