mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
9 Commits
add-line-h
...
js-event-o
Author | SHA1 | Date | |
---|---|---|---|
![]() |
71f77964ce | ||
![]() |
1b3734ff6b | ||
![]() |
6288b30ac3 | ||
![]() |
ee435f7081 | ||
![]() |
d75b4eb2a9 | ||
![]() |
5eeb505807 | ||
![]() |
30566e35ce | ||
![]() |
e058b7f295 | ||
![]() |
902a30a9f8 |
@@ -18,19 +18,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAnimatableExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("AnimatableCapability",
|
||||
_("Objects with animations"),
|
||||
_("Actions and conditions for objects having animations (sprite, 3D models...)."),
|
||||
_("Animate objects."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Animatable capability"))
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Objects with animations"))
|
||||
.SetIcon("res/actions/animation24.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Animations and images"))
|
||||
.SetIcon("res/actions/animation24.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"AnimatableBehavior",
|
||||
_("Animatable capability"),
|
||||
_("Objects with animations"),
|
||||
"Animation",
|
||||
_("Actions and conditions for objects having animations (sprite, 3D models...).."),
|
||||
"",
|
||||
|
@@ -18,7 +18,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsEffectExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("EffectCapability",
|
||||
_("Effect capability"),
|
||||
_("Objects with effects"),
|
||||
_("Actions/conditions to enable/disable and change parameters of visual effects applied on objects."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
@@ -28,7 +28,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsEffectExtension(
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"EffectBehavior",
|
||||
_("Effect capability"),
|
||||
_("Objects with effects"),
|
||||
"Effect",
|
||||
_("Actions/conditions to enable/disable and change parameters of visual effects applied on objects."),
|
||||
"",
|
||||
|
@@ -18,7 +18,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFlippableExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("FlippableCapability",
|
||||
_("Flippable capability"),
|
||||
_("Flippable objects"),
|
||||
_("Actions/conditions for objects which can be flipped horizontally or vertically."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
@@ -28,7 +28,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFlippableExtension(
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"FlippableBehavior",
|
||||
_("Flippable capability"),
|
||||
_("Flippable objects"),
|
||||
"Flippable",
|
||||
_("Actions/conditions for objects which can be flipped horizontally or vertically."),
|
||||
"",
|
||||
|
@@ -18,13 +18,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsOpacityExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("OpacityCapability",
|
||||
_("Opacity capability"),
|
||||
_("Objects with opacity"),
|
||||
_("Action/condition/expression to change or "
|
||||
"check the opacity of an object (0-255)."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Opacity capability"))
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Objects with opacity"))
|
||||
.SetIcon("res/actions/opacity24.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Visibility"))
|
||||
.SetIcon("res/actions/opacity24.png");
|
||||
@@ -32,7 +32,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsOpacityExtension(
|
||||
gd::BehaviorMetadata& aut =
|
||||
extension
|
||||
.AddBehavior("OpacityBehavior",
|
||||
_("Opacity capability"),
|
||||
_("Objects with opacity"),
|
||||
"Opacity",
|
||||
_("Action/condition/expression to change or check the "
|
||||
"opacity of an object (0-255)."),
|
||||
|
@@ -18,7 +18,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsResizableExtension(
|
||||
extension
|
||||
.SetExtensionInformation(
|
||||
"ResizableCapability",
|
||||
_("Resizable capability"),
|
||||
_("Resizable objects"),
|
||||
_("Change or compare the size (width/height) of an object which can "
|
||||
"be resized (i.e: most objects)."),
|
||||
"Florian Rival",
|
||||
@@ -30,7 +30,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsResizableExtension(
|
||||
gd::BehaviorMetadata &aut =
|
||||
extension
|
||||
.AddBehavior("ResizableBehavior",
|
||||
_("Resizable capability"),
|
||||
_("Resizable objects"),
|
||||
"Resizable",
|
||||
_("Change or compare the size (width/height) of an "
|
||||
"object which can be resized (i.e: most objects)."),
|
||||
|
@@ -18,13 +18,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsScalableExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("ScalableCapability",
|
||||
_("Scalable capability"),
|
||||
_("Scalable objects"),
|
||||
_("Actions/conditions/expression to change or "
|
||||
"check the scale of an object (default: 1)."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Scalable capability"))
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Scalable objects"))
|
||||
.SetIcon("res/actions/scale24_black.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Size")).SetIcon(
|
||||
"res/actions/scale24_black.png");
|
||||
@@ -32,7 +32,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsScalableExtension(
|
||||
gd::BehaviorMetadata& aut =
|
||||
extension
|
||||
.AddBehavior("ScalableBehavior",
|
||||
_("Scalable capability"),
|
||||
_("Scalable objects"),
|
||||
"Scale",
|
||||
_("Actions/conditions/expression to change or check the "
|
||||
"scale of an object (default: 1)."),
|
||||
|
@@ -18,17 +18,17 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTextContainerExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("TextContainerCapability",
|
||||
_("Text capability"),
|
||||
_("Objects containing a text"),
|
||||
_("Allows an object to contain a text, usually shown on screen, that can be modified."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Text capability"))
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Objects containing a text"))
|
||||
.SetIcon("res/conditions/text24_black.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"TextContainerBehavior",
|
||||
_("Text capability"),
|
||||
_("Objects containing a text"),
|
||||
"Text",
|
||||
_("Allows an object to contain a text, usually shown on screen, that can be modified."),
|
||||
"",
|
||||
|
@@ -162,7 +162,12 @@ module.exports = {
|
||||
)
|
||||
.addParameter('object', _('3D object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
|
||||
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
|
||||
.useStandardParameters(
|
||||
'number',
|
||||
gd.ParameterOptions.makeNewOptions().setDescription(
|
||||
_('Angle (in degrees)')
|
||||
)
|
||||
)
|
||||
.setFunctionName('setRotationX')
|
||||
.setGetter('getRotationX');
|
||||
|
||||
@@ -178,7 +183,12 @@ module.exports = {
|
||||
)
|
||||
.addParameter('object', _('3D object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
|
||||
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
|
||||
.useStandardParameters(
|
||||
'number',
|
||||
gd.ParameterOptions.makeNewOptions().setDescription(
|
||||
_('Angle (in degrees)')
|
||||
)
|
||||
)
|
||||
.setFunctionName('setRotationY')
|
||||
.setGetter('getRotationY');
|
||||
|
||||
@@ -196,7 +206,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('object', _('3D object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
|
||||
.addParameter('number', _('Rotation angle'), '', false)
|
||||
.addParameter('number', _('Angle to add (in degrees)'), '', false)
|
||||
.markAsAdvanced()
|
||||
.setFunctionName('turnAroundX');
|
||||
|
||||
@@ -214,7 +224,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('object', _('3D object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
|
||||
.addParameter('number', _('Rotation angle'), '', false)
|
||||
.addParameter('number', _('Angle to add (in degrees)'), '', false)
|
||||
.markAsAdvanced()
|
||||
.setFunctionName('turnAroundY');
|
||||
|
||||
@@ -232,7 +242,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('object', _('3D object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
|
||||
.addParameter('number', _('Rotation angle'), '', false)
|
||||
.addParameter('number', _('Angle to add (in degrees)'), '', false)
|
||||
.markAsAdvanced()
|
||||
.setFunctionName('turnAroundZ');
|
||||
}
|
||||
@@ -594,7 +604,12 @@ module.exports = {
|
||||
'res/conditions/3d_box.svg'
|
||||
)
|
||||
.addParameter('object', _('3D model'), 'Model3DObject', false)
|
||||
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
|
||||
.useStandardParameters(
|
||||
'number',
|
||||
gd.ParameterOptions.makeNewOptions().setDescription(
|
||||
_('Angle (in degrees)')
|
||||
)
|
||||
)
|
||||
.setHidden()
|
||||
.setFunctionName('setRotationX')
|
||||
.setGetter('getRotationX');
|
||||
@@ -611,7 +626,12 @@ module.exports = {
|
||||
'res/conditions/3d_box.svg'
|
||||
)
|
||||
.addParameter('object', _('3D model'), 'Model3DObject', false)
|
||||
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
|
||||
.useStandardParameters(
|
||||
'number',
|
||||
gd.ParameterOptions.makeNewOptions().setDescription(
|
||||
_('Angle (in degrees)')
|
||||
)
|
||||
)
|
||||
.setHidden()
|
||||
.setFunctionName('setRotationY')
|
||||
.setGetter('getRotationY');
|
||||
@@ -630,7 +650,7 @@ module.exports = {
|
||||
'res/conditions/3d_box.svg'
|
||||
)
|
||||
.addParameter('object', _('3D model'), 'Model3DObject', false)
|
||||
.addParameter('number', _('Rotation angle'), '', false)
|
||||
.addParameter('number', _('Angle to add (in degrees)'), '', false)
|
||||
.markAsAdvanced()
|
||||
.setHidden()
|
||||
.setFunctionName('turnAroundX');
|
||||
@@ -649,7 +669,7 @@ module.exports = {
|
||||
'res/conditions/3d_box.svg'
|
||||
)
|
||||
.addParameter('object', _('3D model'), 'Model3DObject', false)
|
||||
.addParameter('number', _('Rotation angle'), '', false)
|
||||
.addParameter('number', _('Angle to add (in degrees)'), '', false)
|
||||
.markAsAdvanced()
|
||||
.setHidden()
|
||||
.setFunctionName('turnAroundY');
|
||||
@@ -668,7 +688,7 @@ module.exports = {
|
||||
'res/conditions/3d_box.svg'
|
||||
)
|
||||
.addParameter('object', _('3D model'), 'Model3DObject', false)
|
||||
.addParameter('number', _('Rotation angle'), '', false)
|
||||
.addParameter('number', _('Angle to add (in degrees)'), '', false)
|
||||
.markAsAdvanced()
|
||||
.setHidden()
|
||||
.setFunctionName('turnAroundZ');
|
||||
@@ -1493,7 +1513,12 @@ module.exports = {
|
||||
'res/conditions/3d_box.svg'
|
||||
)
|
||||
.addParameter('object', _('3D cube'), 'Cube3DObject', false)
|
||||
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
|
||||
.useStandardParameters(
|
||||
'number',
|
||||
gd.ParameterOptions.makeNewOptions().setDescription(
|
||||
_('Angle (in degrees)')
|
||||
)
|
||||
)
|
||||
.setFunctionName('setRotationX')
|
||||
.setHidden()
|
||||
.setGetter('getRotationX');
|
||||
@@ -1510,7 +1535,12 @@ module.exports = {
|
||||
'res/conditions/3d_box.svg'
|
||||
)
|
||||
.addParameter('object', _('3D cube'), 'Cube3DObject', false)
|
||||
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
|
||||
.useStandardParameters(
|
||||
'number',
|
||||
gd.ParameterOptions.makeNewOptions().setDescription(
|
||||
_('Angle (in degrees)')
|
||||
)
|
||||
)
|
||||
.setFunctionName('setRotationY')
|
||||
.setHidden()
|
||||
.setGetter('getRotationY');
|
||||
|
@@ -71,14 +71,6 @@ module.exports = {
|
||||
.setLabel(_('Base size'))
|
||||
.setGroup(_('Font'));
|
||||
|
||||
objectProperties
|
||||
.getOrCreate('lineHeight')
|
||||
.setValue((objectContent.lineHeight || 0).toString())
|
||||
.setType('number')
|
||||
.setLabel(_('Line height'))
|
||||
.setGroup(_('Font'))
|
||||
.setAdvanced(true);
|
||||
|
||||
objectProperties
|
||||
.getOrCreate('align')
|
||||
.setValue(objectContent.align)
|
||||
@@ -123,7 +115,6 @@ module.exports = {
|
||||
text: '[b]bold[/b] [i]italic[/i] [size=15]smaller[/size] [font=times]times[/font] font\n[spacing=12]spaced out[/spacing]\n[outline=yellow]outlined[/outline] [shadow=red]DropShadow[/shadow] ',
|
||||
opacity: 255,
|
||||
fontSize: 20,
|
||||
lineHeight: 0,
|
||||
visible: true,
|
||||
color: '0;0;0',
|
||||
fontFamily: 'Arial',
|
||||
@@ -359,19 +350,6 @@ module.exports = {
|
||||
expressionLabel: _('Get the base font size'),
|
||||
expressionDescription: _('Get the base font size'),
|
||||
},
|
||||
{
|
||||
functionName: 'LineHeight',
|
||||
iconPath: 'res/actions/textPadding24_black.png',
|
||||
type: 'number',
|
||||
instructionLabel: _('Line height'),
|
||||
paramLabel: _('Line height'),
|
||||
conditionDescription: _('Compare the line height of the text.'),
|
||||
conditionSentence: _('the line height'),
|
||||
actionDescription: _('Set line height'),
|
||||
actionSentence: _('the line height'),
|
||||
expressionLabel: _('Get the line height'),
|
||||
expressionDescription: _('Get the line height'),
|
||||
},
|
||||
{
|
||||
functionName: 'FontFamily',
|
||||
iconPath: 'res/actions/font24.png',
|
||||
@@ -550,7 +528,6 @@ module.exports = {
|
||||
tagStyle: 'bbcode',
|
||||
wordWrapWidth: 250, // This value is the default wrapping width of the runtime object.
|
||||
align: 'left',
|
||||
lineHeight: 0,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -603,12 +580,6 @@ module.exports = {
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
|
||||
const lineHeight = object.content.lineHeight || 0;
|
||||
if (lineHeight !== this._pixiObject.textStyles.default.lineHeight) {
|
||||
this._pixiObject.textStyles.default.lineHeight = lineHeight;
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
|
||||
const fontResourceName = object.content.fontFamily;
|
||||
|
||||
if (this._fontResourceName !== fontResourceName) {
|
||||
|
@@ -32,7 +32,6 @@ namespace gdjs {
|
||||
wordWrap: runtimeObject._wrapping,
|
||||
wordWrapWidth: runtimeObject._wrappingWidth,
|
||||
align: runtimeObject._textAlign as PIXI.TextStyleAlign | undefined,
|
||||
lineHeight: runtimeObject._lineHeight,
|
||||
},
|
||||
});
|
||||
instanceContainer
|
||||
@@ -45,7 +44,6 @@ namespace gdjs {
|
||||
this.updatePosition();
|
||||
this.updateAngle();
|
||||
this.updateOpacity();
|
||||
this.updateLineHeight();
|
||||
}
|
||||
|
||||
getRendererObject() {
|
||||
@@ -104,13 +102,6 @@ namespace gdjs {
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
|
||||
updateLineHeight(): void {
|
||||
//@ts-ignore Private member usage.
|
||||
this._pixiObject.textStyles.default.lineHeight = this._object._lineHeight;
|
||||
this._pixiObject.dirty = true;
|
||||
this.updatePosition();
|
||||
}
|
||||
|
||||
updatePosition(): void {
|
||||
if (this._object.isWrapping() && this._pixiObject.width !== 0) {
|
||||
const alignmentX =
|
||||
|
@@ -20,7 +20,6 @@ namespace gdjs {
|
||||
/** Alignment of the text: "left", "center" or "right" */
|
||||
align: 'left' | 'center' | 'right';
|
||||
verticalTextAlignment: 'top' | 'center' | 'bottom';
|
||||
lineHeight?: float;
|
||||
};
|
||||
};
|
||||
export type BBTextObjectData = ObjectData & BBTextObjectDataType;
|
||||
@@ -36,7 +35,6 @@ namespace gdjs {
|
||||
align: string;
|
||||
vta: string;
|
||||
hidden: boolean;
|
||||
lh: float;
|
||||
};
|
||||
|
||||
export type BBTextObjectNetworkSyncData = ObjectNetworkSyncData &
|
||||
@@ -63,7 +61,6 @@ namespace gdjs {
|
||||
|
||||
_textAlign: string;
|
||||
_verticalTextAlignment: string;
|
||||
_lineHeight: float = 0;
|
||||
|
||||
_renderer: gdjs.BBTextRuntimeObjectRenderer;
|
||||
|
||||
@@ -90,7 +87,6 @@ namespace gdjs {
|
||||
this._textAlign = objectData.content.align;
|
||||
this._verticalTextAlignment =
|
||||
objectData.content.verticalTextAlignment || 'top';
|
||||
this._lineHeight = objectData.content.lineHeight || 0;
|
||||
this.hidden = !objectData.content.visible;
|
||||
|
||||
this._renderer = new gdjs.BBTextRuntimeObjectRenderer(
|
||||
@@ -146,9 +142,6 @@ namespace gdjs {
|
||||
newObjectData.content.verticalTextAlignment
|
||||
);
|
||||
}
|
||||
if (oldObjectData.content.lineHeight !== newObjectData.content.lineHeight) {
|
||||
this.setLineHeight(newObjectData.content.lineHeight || 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -165,7 +158,6 @@ namespace gdjs {
|
||||
align: this._textAlign,
|
||||
vta: this._verticalTextAlignment,
|
||||
hidden: this.hidden,
|
||||
lh: this._lineHeight,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -204,9 +196,6 @@ namespace gdjs {
|
||||
if (this.hidden !== undefined) {
|
||||
this.hide(networkSyncData.hidden);
|
||||
}
|
||||
if (this._lineHeight !== undefined) {
|
||||
this.setLineHeight(networkSyncData.lh);
|
||||
}
|
||||
}
|
||||
|
||||
override extraInitializationFromInitialInstance(
|
||||
@@ -278,16 +267,6 @@ namespace gdjs {
|
||||
return this._fontFamily;
|
||||
}
|
||||
|
||||
getLineHeight(): number {
|
||||
return this._lineHeight;
|
||||
}
|
||||
|
||||
setLineHeight(value: float): void {
|
||||
this._lineHeight = value;
|
||||
this._renderer.updateLineHeight();
|
||||
this.invalidateHitboxes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `setTextAlignment` instead
|
||||
*/
|
||||
|
@@ -103,14 +103,6 @@ module.exports = {
|
||||
.setLabel(_('Text scale'))
|
||||
.setGroup(_('Appearance'));
|
||||
|
||||
objectProperties
|
||||
.getOrCreate('lineHeight')
|
||||
.setValue((objectContent.lineHeight || 0).toString())
|
||||
.setType('number')
|
||||
.setLabel(_('Line height'))
|
||||
.setGroup(_('Appearance'))
|
||||
.setAdvanced(true);
|
||||
|
||||
objectProperties
|
||||
.getOrCreate('tint')
|
||||
.setValue(objectContent.tint)
|
||||
@@ -125,7 +117,6 @@ module.exports = {
|
||||
opacity: 255,
|
||||
scale: 1,
|
||||
fontSize: 20,
|
||||
lineHeight: 0,
|
||||
tint: '255;255;255',
|
||||
bitmapFontResourceName: '',
|
||||
textureAtlasResourceName: '',
|
||||
@@ -422,21 +413,6 @@ module.exports = {
|
||||
.setFunctionName('setWrappingWidth')
|
||||
.setGetter('getWrappingWidth');
|
||||
|
||||
object
|
||||
.addExpressionAndConditionAndAction(
|
||||
'number',
|
||||
'LineHeight',
|
||||
_('Line height'),
|
||||
_('the line height of the text'),
|
||||
_('the line height'),
|
||||
'',
|
||||
'res/actions/textPadding24_black.png'
|
||||
)
|
||||
.addParameter('object', _('Bitmap text'), 'BitmapTextObject', false)
|
||||
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
|
||||
.setFunctionName('setLineHeight')
|
||||
.setGetter('getLineHeight');
|
||||
|
||||
return extension;
|
||||
},
|
||||
|
||||
@@ -698,12 +674,6 @@ module.exports = {
|
||||
const align = object.content.align;
|
||||
this._pixiObject.align = align;
|
||||
|
||||
const lineHeight = object.content.lineHeight || 0;
|
||||
if (this._pixiObject.lineHeight !== lineHeight) {
|
||||
this._pixiObject.lineHeight = lineHeight;
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
|
||||
const color = object.content.tint;
|
||||
this._pixiObject.tint =
|
||||
objectsRenderingService.rgbOrHexToHexNumber(color);
|
||||
|
@@ -42,7 +42,6 @@ namespace gdjs {
|
||||
this.updateScale();
|
||||
this.updateWrappingWidth();
|
||||
this.updateTint();
|
||||
this.updateLineHeight();
|
||||
}
|
||||
|
||||
getRendererObject() {
|
||||
@@ -135,13 +134,6 @@ namespace gdjs {
|
||||
this.updatePosition();
|
||||
}
|
||||
|
||||
updateLineHeight(): void {
|
||||
// @ts-ignore
|
||||
this._pixiObject.lineHeight = this._object._lineHeight;
|
||||
this._pixiObject.dirty = true;
|
||||
this.updatePosition();
|
||||
}
|
||||
|
||||
updateTextContent(): void {
|
||||
this._pixiObject.text = this._object._text;
|
||||
this.updatePosition();
|
||||
|
@@ -20,8 +20,6 @@ namespace gdjs {
|
||||
/** Alignment of the text. */
|
||||
align: 'left' | 'center' | 'right';
|
||||
verticalTextAlignment: 'top' | 'center' | 'bottom';
|
||||
/** Line height of the text. */
|
||||
lineHeight?: float;
|
||||
};
|
||||
};
|
||||
export type BitmapTextObjectData = ObjectData & BitmapTextObjectDataType;
|
||||
@@ -37,7 +35,6 @@ namespace gdjs {
|
||||
wwidth: float;
|
||||
align: string;
|
||||
vta: string;
|
||||
lh: float;
|
||||
};
|
||||
|
||||
export type BitmapTextObjectNetworkSyncData = ObjectNetworkSyncData &
|
||||
@@ -69,7 +66,6 @@ namespace gdjs {
|
||||
_wrappingWidth: float;
|
||||
_textAlign: string;
|
||||
_verticalTextAlignment: string;
|
||||
_lineHeight: float = 0;
|
||||
|
||||
_renderer: gdjs.BitmapTextRuntimeObjectPixiRenderer;
|
||||
|
||||
@@ -96,7 +92,6 @@ namespace gdjs {
|
||||
this._textAlign = objectData.content.align;
|
||||
this._verticalTextAlignment =
|
||||
objectData.content.verticalTextAlignment || 'top';
|
||||
this._lineHeight = objectData.content.lineHeight || 0;
|
||||
|
||||
this._renderer = new gdjs.BitmapTextRuntimeObjectRenderer(
|
||||
this,
|
||||
@@ -156,9 +151,6 @@ namespace gdjs {
|
||||
newObjectData.content.verticalTextAlignment
|
||||
);
|
||||
}
|
||||
if (oldObjectData.content.lineHeight !== newObjectData.content.lineHeight) {
|
||||
this.setLineHeight(newObjectData.content.lineHeight || 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -176,7 +168,6 @@ namespace gdjs {
|
||||
wwidth: this._wrappingWidth,
|
||||
align: this._textAlign,
|
||||
vta: this._verticalTextAlignment,
|
||||
lh: this._lineHeight,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -215,9 +206,6 @@ namespace gdjs {
|
||||
if (this._verticalTextAlignment !== undefined) {
|
||||
this.setVerticalTextAlignment(networkSyncData.vta);
|
||||
}
|
||||
if (this._lineHeight !== undefined) {
|
||||
this.setLineHeight(networkSyncData.lh);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -403,16 +391,6 @@ namespace gdjs {
|
||||
return this._opacity;
|
||||
}
|
||||
|
||||
getLineHeight(): number {
|
||||
return this._lineHeight;
|
||||
}
|
||||
|
||||
setLineHeight(value: float): void {
|
||||
this._lineHeight = value;
|
||||
this._renderer.updateLineHeight();
|
||||
this.invalidateHitboxes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the wrapping width.
|
||||
* @param width The new width in pixels.
|
||||
|
@@ -389,26 +389,15 @@ namespace gdjs {
|
||||
this.updatePosition();
|
||||
}
|
||||
|
||||
setColor(rgbColor): void {
|
||||
const colors = rgbColor.split(';');
|
||||
if (colors.length < 3) {
|
||||
return;
|
||||
}
|
||||
this._centerSprite.tint = gdjs.rgbToHexNumber(
|
||||
parseInt(colors[0], 10),
|
||||
parseInt(colors[1], 10),
|
||||
parseInt(colors[2], 10)
|
||||
);
|
||||
setColor(rgbOrHexColor: string): void {
|
||||
const tint = gdjs.rgbOrHexStringToNumber(rgbOrHexColor);
|
||||
this._centerSprite.tint = tint;
|
||||
for (
|
||||
let borderCounter = 0;
|
||||
borderCounter < this._borderSprites.length;
|
||||
borderCounter++
|
||||
) {
|
||||
this._borderSprites[borderCounter].tint = gdjs.rgbToHexNumber(
|
||||
parseInt(colors[0], 10),
|
||||
parseInt(colors[1], 10),
|
||||
parseInt(colors[2], 10)
|
||||
);
|
||||
this._borderSprites[borderCounter].tint = tint;
|
||||
}
|
||||
this._spritesContainer.cacheAsBitmap = false;
|
||||
}
|
||||
@@ -416,11 +405,11 @@ namespace gdjs {
|
||||
getColor() {
|
||||
const rgb = new PIXI.Color(this._centerSprite.tint).toRgbArray();
|
||||
return (
|
||||
Math.floor(rgb[0] * 255) +
|
||||
Math.round(rgb[0] * 255) +
|
||||
';' +
|
||||
Math.floor(rgb[1] * 255) +
|
||||
Math.round(rgb[1] * 255) +
|
||||
';' +
|
||||
Math.floor(rgb[2] * 255)
|
||||
Math.round(rgb[2] * 255)
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -355,18 +355,6 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
.UseStandardOperatorParameters("number",
|
||||
gd::ParameterOptions::MakeNewOptions());
|
||||
|
||||
obj.AddExpressionAndConditionAndAction("number", "LineHeight",
|
||||
_("Line height"),
|
||||
_("the line height of the text"),
|
||||
_("the line height"),
|
||||
_("Font"),
|
||||
"res/actions/textPadding24_black.png")
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.UseStandardParameters(
|
||||
"number",
|
||||
gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Line height")));
|
||||
|
||||
obj.AddAction("SetTextAlignment",
|
||||
_("Alignment"),
|
||||
_("Change the text alignment of a multiline text object."),
|
||||
@@ -461,6 +449,16 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.UseStandardParameters("number", gd::ParameterOptions::MakeNewOptions());
|
||||
|
||||
obj.AddExpressionAndConditionAndAction("number",
|
||||
"LineHeight",
|
||||
_("Line height"),
|
||||
_("the line height of a text object"),
|
||||
_("the line height"),
|
||||
"",
|
||||
"res/actions/font24.png")
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.UseStandardParameters("number", gd::ParameterOptions::MakeNewOptions());
|
||||
|
||||
// Support for deprecated "Size" actions/conditions:
|
||||
obj.AddDuplicatedAction("Size", "Text::SetFontSize").SetHidden();
|
||||
obj.AddDuplicatedCondition("Size", "Text::FontSize").SetHidden();
|
||||
|
@@ -62,14 +62,6 @@ class TextObjectJsExtension : public gd::PlatformExtension {
|
||||
GetAllConditionsForObject("TextObject::Text")["TextObject::Padding"]
|
||||
.SetFunctionName("getPadding");
|
||||
|
||||
GetAllExpressionsForObject("TextObject::Text")["LineHeight"]
|
||||
.SetFunctionName("getLineHeight");
|
||||
GetAllConditionsForObject("TextObject::Text")["TextObject::Text::LineHeight"]
|
||||
.SetFunctionName("getLineHeight");
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::Text::SetLineHeight"]
|
||||
.SetFunctionName("setLineHeight")
|
||||
.SetGetter("getLineHeight");
|
||||
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::SetTextAlignment"]
|
||||
.SetFunctionName("setTextAlignment")
|
||||
.SetGetter("getTextAlignment");
|
||||
@@ -104,6 +96,14 @@ class TextObjectJsExtension : public gd::PlatformExtension {
|
||||
.SetFunctionName("setOutlineThickness")
|
||||
.SetGetter("getOutlineThickness");
|
||||
|
||||
GetAllExpressionsForObject("TextObject::Text")["LineHeight"]
|
||||
.SetFunctionName("getLineHeight");
|
||||
GetAllConditionsForObject("TextObject::Text")["TextObject::Text::LineHeight"]
|
||||
.SetFunctionName("getLineHeight");
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::Text::SetLineHeight"]
|
||||
.SetFunctionName("setLineHeight")
|
||||
.SetGetter("getLineHeight");
|
||||
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::ShowShadow"]
|
||||
.SetFunctionName("showShadow");
|
||||
GetAllConditionsForObject("TextObject::Text")["TextObject::Text::IsShadowEnabled"]
|
||||
|
@@ -18,17 +18,31 @@ This project is released under the MIT License.
|
||||
using namespace std;
|
||||
|
||||
TextObject::TextObject()
|
||||
: text("Text"), characterSize(20), fontName(""), smoothed(true),
|
||||
bold(false), italic(false), underlined(false), color("0;0;0"),
|
||||
textAlignment("left"), verticalTextAlignment("top"),
|
||||
isOutlineEnabled(false), outlineThickness(2), outlineColor("255;255;255"),
|
||||
isShadowEnabled(false), shadowColor("0;0;0"), shadowOpacity(127),
|
||||
shadowAngle(90), shadowDistance(4), shadowBlurRadius(2), lineHeight(0) {}
|
||||
: text("Text"),
|
||||
characterSize(20),
|
||||
lineHeight(0),
|
||||
fontName(""),
|
||||
smoothed(true),
|
||||
bold(false),
|
||||
italic(false),
|
||||
underlined(false),
|
||||
color("0;0;0"),
|
||||
textAlignment("left"),
|
||||
verticalTextAlignment("top"),
|
||||
isOutlineEnabled(false),
|
||||
outlineThickness(2),
|
||||
outlineColor("255;255;255"),
|
||||
isShadowEnabled(false),
|
||||
shadowColor("0;0;0"),
|
||||
shadowOpacity(127),
|
||||
shadowAngle(90),
|
||||
shadowDistance(4),
|
||||
shadowBlurRadius(2) {}
|
||||
|
||||
TextObject::~TextObject() {};
|
||||
|
||||
bool TextObject::UpdateProperty(const gd::String &propertyName,
|
||||
const gd::String &newValue) {
|
||||
bool TextObject::UpdateProperty(const gd::String& propertyName,
|
||||
const gd::String& newValue) {
|
||||
if (propertyName == "text") {
|
||||
text = newValue;
|
||||
return true;
|
||||
@@ -37,6 +51,10 @@ bool TextObject::UpdateProperty(const gd::String &propertyName,
|
||||
characterSize = newValue.To<double>();
|
||||
return true;
|
||||
}
|
||||
if (propertyName == "lineHeight") {
|
||||
lineHeight = newValue.To<double>();
|
||||
return true;
|
||||
}
|
||||
if (propertyName == "font") {
|
||||
fontName = newValue;
|
||||
return true;
|
||||
@@ -97,10 +115,6 @@ bool TextObject::UpdateProperty(const gd::String &propertyName,
|
||||
shadowBlurRadius = newValue.To<double>();
|
||||
return true;
|
||||
}
|
||||
if (propertyName == "lineHeight") {
|
||||
lineHeight = newValue.To<double>();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -120,6 +134,13 @@ std::map<gd::String, gd::PropertyDescriptor> TextObject::GetProperties() const {
|
||||
.SetMeasurementUnit(gd::MeasurementUnit::GetPixel())
|
||||
.SetGroup(_("Font"));
|
||||
|
||||
objectProperties["lineHeight"]
|
||||
.SetValue(gd::String::From(lineHeight))
|
||||
.SetType("number")
|
||||
.SetLabel(_("Line height"))
|
||||
.SetMeasurementUnit(gd::MeasurementUnit::GetPixel())
|
||||
.SetGroup(_("Font"));
|
||||
|
||||
objectProperties["font"]
|
||||
.SetValue(fontName)
|
||||
.SetType("resource")
|
||||
@@ -155,8 +176,7 @@ std::map<gd::String, gd::PropertyDescriptor> TextObject::GetProperties() const {
|
||||
.AddChoice("center", _("Center"))
|
||||
.AddChoice("right", _("Right"))
|
||||
.SetLabel(_("Alignment"))
|
||||
.SetDescription(
|
||||
_("Alignment of the text when multiple lines are displayed"))
|
||||
.SetDescription(_("Alignment of the text when multiple lines are displayed"))
|
||||
.SetGroup(_("Font"))
|
||||
.SetQuickCustomizationVisibility(gd::QuickCustomization::Hidden);
|
||||
|
||||
@@ -170,14 +190,6 @@ std::map<gd::String, gd::PropertyDescriptor> TextObject::GetProperties() const {
|
||||
.SetGroup(_("Font"))
|
||||
.SetQuickCustomizationVisibility(gd::QuickCustomization::Hidden);
|
||||
|
||||
objectProperties["lineHeight"]
|
||||
.SetValue(gd::String::From(lineHeight))
|
||||
.SetType("number")
|
||||
.SetLabel(_("Line height"))
|
||||
.SetGroup(_("Font"))
|
||||
.SetAdvanced()
|
||||
.SetQuickCustomizationVisibility(gd::QuickCustomization::Hidden);
|
||||
|
||||
objectProperties["isOutlineEnabled"]
|
||||
.SetValue(isOutlineEnabled ? "true" : "false")
|
||||
.SetType("boolean")
|
||||
@@ -258,25 +270,24 @@ std::map<gd::String, gd::PropertyDescriptor> TextObject::GetProperties() const {
|
||||
return objectProperties;
|
||||
}
|
||||
|
||||
void TextObject::DoUnserializeFrom(gd::Project &project,
|
||||
const gd::SerializerElement &element) {
|
||||
void TextObject::DoUnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element) {
|
||||
// Compatibility with GD <= 5.3.188
|
||||
// end of compatibility code
|
||||
bool isLegacy = !element.HasChild("content");
|
||||
auto &content = isLegacy ? element : element.GetChild("content");
|
||||
auto& content = isLegacy ? element : element.GetChild("content");
|
||||
|
||||
SetFontName(content.GetChild("font", 0, "Font").GetValue().GetString());
|
||||
SetTextAlignment(content.GetChild("textAlignment").GetValue().GetString());
|
||||
SetVerticalTextAlignment(
|
||||
content.GetStringAttribute("verticalTextAlignment", "top"));
|
||||
SetVerticalTextAlignment(content.GetStringAttribute("verticalTextAlignment", "top"));
|
||||
SetCharacterSize(content.GetChild("characterSize", 0, "CharacterSize")
|
||||
.GetValue()
|
||||
.GetInt());
|
||||
SetLineHeight(content.GetDoubleAttribute("lineHeight", 0));
|
||||
smoothed = content.GetBoolAttribute("smoothed");
|
||||
bold = content.GetBoolAttribute("bold");
|
||||
italic = content.GetBoolAttribute("italic");
|
||||
underlined = content.GetBoolAttribute("underlined");
|
||||
SetLineHeight(content.GetDoubleAttribute("lineHeight", 0));
|
||||
|
||||
// Compatibility with GD <= 5.3.188
|
||||
if (isLegacy) {
|
||||
@@ -309,7 +320,7 @@ void TextObject::DoUnserializeFrom(gd::Project &project,
|
||||
}
|
||||
}
|
||||
|
||||
void TextObject::DoSerializeTo(gd::SerializerElement &element) const {
|
||||
void TextObject::DoSerializeTo(gd::SerializerElement& element) const {
|
||||
// Allow users to rollback to 5.3.188 or older releases without loosing their
|
||||
// configuration.
|
||||
// TODO Remove this in a few releases.
|
||||
@@ -325,9 +336,9 @@ void TextObject::DoSerializeTo(gd::SerializerElement &element) const {
|
||||
"r", colorComponents.size() == 3 ? colorComponents[0].To<int>() : 0)
|
||||
.SetAttribute(
|
||||
"g", colorComponents.size() == 3 ? colorComponents[1].To<int>() : 0)
|
||||
.SetAttribute("b", colorComponents.size() == 3
|
||||
? colorComponents[2].To<int>()
|
||||
: 0);
|
||||
.SetAttribute(
|
||||
"b",
|
||||
colorComponents.size() == 3 ? colorComponents[2].To<int>() : 0);
|
||||
element.SetAttribute("smoothed", smoothed);
|
||||
element.SetAttribute("bold", bold);
|
||||
element.SetAttribute("italic", italic);
|
||||
@@ -335,20 +346,19 @@ void TextObject::DoSerializeTo(gd::SerializerElement &element) const {
|
||||
}
|
||||
// end of compatibility code
|
||||
|
||||
auto &content = element.AddChild("content");
|
||||
auto& content = element.AddChild("content");
|
||||
content.AddChild("text").SetValue(GetText());
|
||||
content.AddChild("font").SetValue(GetFontName());
|
||||
content.AddChild("textAlignment").SetValue(GetTextAlignment());
|
||||
content.AddChild("verticalTextAlignment")
|
||||
.SetValue(GetVerticalTextAlignment());
|
||||
content.AddChild("verticalTextAlignment").SetValue(GetVerticalTextAlignment());
|
||||
content.AddChild("characterSize").SetValue(GetCharacterSize());
|
||||
content.AddChild("lineHeight").SetValue(GetLineHeight());
|
||||
content.AddChild("color").SetValue(GetColor());
|
||||
|
||||
content.SetAttribute("smoothed", smoothed);
|
||||
content.SetAttribute("bold", bold);
|
||||
content.SetAttribute("italic", italic);
|
||||
content.SetAttribute("underlined", underlined);
|
||||
content.SetAttribute("lineHeight", lineHeight);
|
||||
|
||||
content.SetAttribute("isOutlineEnabled", isOutlineEnabled);
|
||||
content.SetAttribute("outlineThickness", outlineThickness);
|
||||
@@ -362,6 +372,6 @@ void TextObject::DoSerializeTo(gd::SerializerElement &element) const {
|
||||
content.SetAttribute("shadowBlurRadius", shadowBlurRadius);
|
||||
}
|
||||
|
||||
void TextObject::ExposeResources(gd::ArbitraryResourceWorker &worker) {
|
||||
void TextObject::ExposeResources(gd::ArbitraryResourceWorker& worker) {
|
||||
worker.ExposeFont(fontName);
|
||||
}
|
||||
|
@@ -49,6 +49,12 @@ class GD_EXTENSION_API TextObject : public gd::ObjectConfiguration {
|
||||
*/
|
||||
inline double GetCharacterSize() const { return characterSize; };
|
||||
|
||||
/** \brief Change the line height. */
|
||||
inline void SetLineHeight(double value) { lineHeight = value; };
|
||||
|
||||
/** \brief Get the line height. */
|
||||
inline double GetLineHeight() const { return lineHeight; };
|
||||
|
||||
/** \brief Return the name of the font resource used for the text.
|
||||
*/
|
||||
inline const gd::String& GetFontName() const { return fontName; };
|
||||
@@ -67,9 +73,6 @@ class GD_EXTENSION_API TextObject : public gd::ObjectConfiguration {
|
||||
verticalTextAlignment = verticalTextAlignment_;
|
||||
};
|
||||
|
||||
void SetLineHeight(double value) { lineHeight = value; };
|
||||
double GetLineHeight() const { return lineHeight; };
|
||||
|
||||
bool IsBold() const { return bold; };
|
||||
void SetBold(bool enable) { bold = enable; };
|
||||
bool IsItalic() const { return italic; };
|
||||
@@ -123,6 +126,7 @@ class GD_EXTENSION_API TextObject : public gd::ObjectConfiguration {
|
||||
|
||||
gd::String text;
|
||||
double characterSize;
|
||||
double lineHeight;
|
||||
gd::String fontName;
|
||||
bool smoothed;
|
||||
bool bold, italic, underlined;
|
||||
@@ -140,5 +144,4 @@ class GD_EXTENSION_API TextObject : public gd::ObjectConfiguration {
|
||||
double shadowAngle;
|
||||
double shadowDistance;
|
||||
double shadowBlurRadius;
|
||||
double lineHeight;
|
||||
};
|
||||
|
@@ -64,7 +64,6 @@ namespace gdjs {
|
||||
style.wordWrap = this._object._wrapping;
|
||||
style.wordWrapWidth = this._object._wrappingWidth;
|
||||
style.breakWords = true;
|
||||
style.lineHeight = this._object._lineHeight;
|
||||
style.stroke = gdjs.rgbToHexNumber(
|
||||
this._object._outlineColor[0],
|
||||
this._object._outlineColor[1],
|
||||
@@ -87,6 +86,7 @@ namespace gdjs {
|
||||
? style.dropShadowDistance + style.dropShadowBlur
|
||||
: 0;
|
||||
style.padding = Math.ceil(this._object._padding + extraPaddingForShadow);
|
||||
style.lineHeight = this._object._lineHeight;
|
||||
|
||||
// Prevent spikey outlines by adding a miter limit
|
||||
style.miterLimit = 3;
|
||||
|
@@ -8,7 +8,6 @@ namespace gdjs {
|
||||
content: {
|
||||
/** The size of the characters */
|
||||
characterSize: number;
|
||||
lineHeight?: number;
|
||||
/** The font name */
|
||||
font: string;
|
||||
/** Is Bold? */
|
||||
@@ -23,6 +22,8 @@ namespace gdjs {
|
||||
text: string;
|
||||
textAlignment: string;
|
||||
verticalTextAlignment: string;
|
||||
/** The line height */
|
||||
lineHeight: float;
|
||||
|
||||
isOutlineEnabled: boolean;
|
||||
outlineThickness: float;
|
||||
@@ -44,7 +45,6 @@ namespace gdjs {
|
||||
str: string;
|
||||
o: float;
|
||||
cs: number;
|
||||
lh: float;
|
||||
fn: string;
|
||||
b: boolean;
|
||||
i: boolean;
|
||||
@@ -64,6 +64,7 @@ namespace gdjs {
|
||||
sha: float;
|
||||
shb: float;
|
||||
pad: integer;
|
||||
lh: float;
|
||||
};
|
||||
|
||||
export type TextObjectNetworkSyncData = ObjectNetworkSyncData &
|
||||
@@ -103,7 +104,8 @@ namespace gdjs {
|
||||
_shadowAngle: float;
|
||||
_shadowBlur: float;
|
||||
|
||||
_lineHeight: float = 0;
|
||||
_lineHeight: float;
|
||||
|
||||
_padding: integer = 5;
|
||||
_str: string;
|
||||
_renderer: gdjs.TextRuntimeObjectRenderer;
|
||||
@@ -131,7 +133,6 @@ namespace gdjs {
|
||||
this._str = content.text;
|
||||
this._textAlign = content.textAlignment || 'left';
|
||||
this._verticalTextAlignment = content.verticalTextAlignment || 'top';
|
||||
this._lineHeight = content.lineHeight || 0;
|
||||
|
||||
this._isOutlineEnabled = content.isOutlineEnabled;
|
||||
this._outlineThickness = content.outlineThickness;
|
||||
@@ -143,6 +144,7 @@ namespace gdjs {
|
||||
this._shadowDistance = content.shadowDistance;
|
||||
this._shadowBlur = content.shadowBlurRadius;
|
||||
this._shadowAngle = content.shadowAngle;
|
||||
this._lineHeight = content.lineHeight || 0;
|
||||
|
||||
this._renderer = new gdjs.TextRuntimeObjectRenderer(
|
||||
this,
|
||||
@@ -188,9 +190,6 @@ namespace gdjs {
|
||||
) {
|
||||
this.setVerticalTextAlignment(newContent.verticalTextAlignment);
|
||||
}
|
||||
if (oldContent.lineHeight !== newContent.lineHeight) {
|
||||
this.setLineHeight(newContent.lineHeight || 0);
|
||||
}
|
||||
if (oldContent.isOutlineEnabled !== newContent.isOutlineEnabled) {
|
||||
this.setOutlineEnabled(newContent.isOutlineEnabled);
|
||||
}
|
||||
@@ -218,6 +217,9 @@ namespace gdjs {
|
||||
if (oldContent.shadowBlurRadius !== newContent.shadowBlurRadius) {
|
||||
this.setShadowBlurRadius(newContent.shadowBlurRadius);
|
||||
}
|
||||
if ((oldContent.lineHeight || 0) !== (newContent.lineHeight || 0)) {
|
||||
this.setLineHeight(newContent.lineHeight || 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -227,7 +229,6 @@ namespace gdjs {
|
||||
str: this._str,
|
||||
o: this.opacity,
|
||||
cs: this._characterSize,
|
||||
lh: this._lineHeight,
|
||||
fn: this._fontName,
|
||||
b: this._bold,
|
||||
i: this._italic,
|
||||
@@ -246,6 +247,7 @@ namespace gdjs {
|
||||
shd: this._shadowDistance,
|
||||
sha: this._shadowAngle,
|
||||
shb: this._shadowBlur,
|
||||
lh: this._lineHeight,
|
||||
pad: this._padding,
|
||||
};
|
||||
}
|
||||
@@ -263,9 +265,6 @@ namespace gdjs {
|
||||
if (networkSyncData.cs !== undefined) {
|
||||
this.setCharacterSize(networkSyncData.cs);
|
||||
}
|
||||
if (networkSyncData.lh !== undefined) {
|
||||
this.setLineHeight(networkSyncData.lh);
|
||||
}
|
||||
if (networkSyncData.fn !== undefined) {
|
||||
this.setFontName(networkSyncData.fn);
|
||||
}
|
||||
@@ -323,6 +322,9 @@ namespace gdjs {
|
||||
if (networkSyncData.shb !== undefined) {
|
||||
this.setShadowBlurRadius(networkSyncData.shb);
|
||||
}
|
||||
if (networkSyncData.lh !== undefined) {
|
||||
this.setLineHeight(networkSyncData.lh);
|
||||
}
|
||||
if (networkSyncData.pad !== undefined) {
|
||||
this.setPadding(networkSyncData.pad);
|
||||
}
|
||||
@@ -455,6 +457,22 @@ namespace gdjs {
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line height of the text.
|
||||
*/
|
||||
getLineHeight(): float {
|
||||
return this._lineHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the line height of the text.
|
||||
* @param value The new line height for the text.
|
||||
*/
|
||||
setLineHeight(value: float): void {
|
||||
this._lineHeight = value;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the resource to use for the font.
|
||||
* @param fontResourceName The name of the font resource.
|
||||
@@ -584,16 +602,10 @@ namespace gdjs {
|
||||
|
||||
/**
|
||||
* Change the text color.
|
||||
* @param colorString color as a "R;G;B" string, for example: "255;0;0"
|
||||
* @param rgbOrHexColor color as a "R;G;B" string, for example: "255;0;0"
|
||||
*/
|
||||
setColor(colorString: string): void {
|
||||
const color = colorString.split(';');
|
||||
if (color.length < 3) {
|
||||
return;
|
||||
}
|
||||
this._color[0] = parseInt(color[0], 10);
|
||||
this._color[1] = parseInt(color[1], 10);
|
||||
this._color[2] = parseInt(color[2], 10);
|
||||
setColor(rgbOrHexColor: string): void {
|
||||
this._color = gdjs.rgbOrHexToRGBColor(rgbOrHexColor);
|
||||
this._useGradient = false;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
@@ -702,18 +714,12 @@ namespace gdjs {
|
||||
|
||||
/**
|
||||
* Set the outline for the text object.
|
||||
* @param str color as a "R;G;B" string, for example: "255;0;0"
|
||||
* @param rgbOrHexColor color as a "R;G;B" string, for example: "255;0;0"
|
||||
* @param thickness thickness of the outline (0 = disabled)
|
||||
* @deprecated Prefer independent setters.
|
||||
*/
|
||||
setOutline(str: string, thickness: number): void {
|
||||
const color = str.split(';');
|
||||
if (color.length < 3) {
|
||||
return;
|
||||
}
|
||||
this._outlineColor[0] = parseInt(color[0], 10);
|
||||
this._outlineColor[1] = parseInt(color[1], 10);
|
||||
this._outlineColor[2] = parseInt(color[2], 10);
|
||||
setOutline(rgbOrHexColor: string, thickness: number): void {
|
||||
this._outlineColor = gdjs.rgbOrHexToRGBColor(rgbOrHexColor);
|
||||
this._outlineThickness = thickness;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
@@ -755,25 +761,19 @@ namespace gdjs {
|
||||
|
||||
/**
|
||||
* Set the shadow for the text object.
|
||||
* @param str color as a "R;G;B" string, for example: "255;0;0"
|
||||
* @param rgbOrHexColor color as a "R;G;B" string, for example: "255;0;0"
|
||||
* @param distance distance between the shadow and the text, in pixels.
|
||||
* @param blur amount of shadow blur, in pixels.
|
||||
* @param angle shadow offset direction, in degrees.
|
||||
* @deprecated Prefer independent setters.
|
||||
*/
|
||||
setShadow(
|
||||
str: string,
|
||||
rgbOrHexColor: string,
|
||||
distance: number,
|
||||
blur: integer,
|
||||
angle: float
|
||||
): void {
|
||||
const color = str.split(';');
|
||||
if (color.length < 3) {
|
||||
return;
|
||||
}
|
||||
this._shadowColor[0] = parseInt(color[0], 10);
|
||||
this._shadowColor[1] = parseInt(color[1], 10);
|
||||
this._shadowColor[2] = parseInt(color[2], 10);
|
||||
this._shadowColor = gdjs.rgbOrHexToRGBColor(rgbOrHexColor);
|
||||
this._shadowDistance = distance;
|
||||
this._shadowBlur = blur;
|
||||
this._shadowAngle = angle;
|
||||
@@ -886,61 +886,24 @@ namespace gdjs {
|
||||
strThirdColor: string,
|
||||
strFourthColor: string
|
||||
): void {
|
||||
const colorFirst = strFirstColor.split(';');
|
||||
const colorSecond = strSecondColor.split(';');
|
||||
const colorThird = strThirdColor.split(';');
|
||||
const colorFourth = strFourthColor.split(';');
|
||||
this._gradient = [];
|
||||
if (colorFirst.length == 3) {
|
||||
this._gradient.push([
|
||||
parseInt(colorFirst[0], 10),
|
||||
parseInt(colorFirst[1], 10),
|
||||
parseInt(colorFirst[2], 10),
|
||||
]);
|
||||
if (strFirstColor) {
|
||||
this._gradient.push(gdjs.rgbOrHexToRGBColor(strFirstColor));
|
||||
}
|
||||
if (colorSecond.length == 3) {
|
||||
this._gradient.push([
|
||||
parseInt(colorSecond[0], 10),
|
||||
parseInt(colorSecond[1], 10),
|
||||
parseInt(colorSecond[2], 10),
|
||||
]);
|
||||
if (strSecondColor) {
|
||||
this._gradient.push(gdjs.rgbOrHexToRGBColor(strSecondColor));
|
||||
}
|
||||
if (colorThird.length == 3) {
|
||||
this._gradient.push([
|
||||
parseInt(colorThird[0], 10),
|
||||
parseInt(colorThird[1], 10),
|
||||
parseInt(colorThird[2], 10),
|
||||
]);
|
||||
if (strThirdColor) {
|
||||
this._gradient.push(gdjs.rgbOrHexToRGBColor(strThirdColor));
|
||||
}
|
||||
if (colorFourth.length == 3) {
|
||||
this._gradient.push([
|
||||
parseInt(colorFourth[0], 10),
|
||||
parseInt(colorFourth[1], 10),
|
||||
parseInt(colorFourth[2], 10),
|
||||
]);
|
||||
if (strFourthColor) {
|
||||
this._gradient.push(gdjs.rgbOrHexToRGBColor(strFourthColor));
|
||||
}
|
||||
this._gradientType = strGradientType;
|
||||
this._useGradient = this._gradient.length > 1 ? true : false;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get line height of the text object.
|
||||
*/
|
||||
getLineHeight(): number {
|
||||
return this._lineHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set line height of the text object.
|
||||
* @param value The new line height in pixels.
|
||||
*/
|
||||
setLineHeight(value: float): void {
|
||||
this._lineHeight = value;
|
||||
this._renderer.updateStyle();
|
||||
this.invalidateHitboxes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get padding of the text object.
|
||||
* @return number of pixels around the text before it gets cropped
|
||||
|
@@ -92,28 +92,18 @@ namespace gdjs {
|
||||
-this._object._yOffset % this._tiledSprite.texture.height;
|
||||
}
|
||||
|
||||
setColor(rgbColor: string): void {
|
||||
const colors = rgbColor.split(';');
|
||||
if (colors.length < 3) {
|
||||
return;
|
||||
}
|
||||
this._tiledSprite.tint =
|
||||
'0x' +
|
||||
gdjs.rgbToHex(
|
||||
parseInt(colors[0], 10),
|
||||
parseInt(colors[1], 10),
|
||||
parseInt(colors[2], 10)
|
||||
);
|
||||
setColor(rgbOrHexColor: string): void {
|
||||
this._tiledSprite.tint = gdjs.rgbOrHexStringToNumber(rgbOrHexColor);
|
||||
}
|
||||
|
||||
getColor() {
|
||||
const rgb = new PIXI.Color(this._tiledSprite.tint).toRgbArray();
|
||||
return (
|
||||
Math.floor(rgb[0] * 255) +
|
||||
Math.round(rgb[0] * 255) +
|
||||
';' +
|
||||
Math.floor(rgb[1] * 255) +
|
||||
Math.round(rgb[1] * 255) +
|
||||
';' +
|
||||
Math.floor(rgb[2] * 255)
|
||||
Math.round(rgb[2] * 255)
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -145,6 +145,7 @@ describe('gdjs.TweenRuntimeBehavior', () => {
|
||||
shadowDistance: 4,
|
||||
shadowAngle: 90,
|
||||
shadowBlurRadius: 2,
|
||||
lineHeight: 0,
|
||||
},
|
||||
});
|
||||
runtimeScene.addObject(object);
|
||||
|
@@ -145,6 +145,7 @@ describe('gdjs.TweenRuntimeBehavior', () => {
|
||||
shadowDistance: 4,
|
||||
shadowAngle: 90,
|
||||
shadowBlurRadius: 2,
|
||||
lineHeight: 0,
|
||||
},
|
||||
});
|
||||
runtimeScene.addObject(object);
|
||||
|
@@ -1326,11 +1326,11 @@ namespace gdjs {
|
||||
lightness
|
||||
);
|
||||
owner.setColor(
|
||||
Math.floor(rgbFromHslColor[0]) +
|
||||
Math.round(rgbFromHslColor[0]) +
|
||||
';' +
|
||||
Math.floor(rgbFromHslColor[1]) +
|
||||
Math.round(rgbFromHslColor[1]) +
|
||||
';' +
|
||||
Math.floor(rgbFromHslColor[2])
|
||||
Math.round(rgbFromHslColor[2])
|
||||
);
|
||||
};
|
||||
} else {
|
||||
@@ -1439,12 +1439,11 @@ namespace gdjs {
|
||||
if (!isColorable(this.owner)) return;
|
||||
const owner = this.owner;
|
||||
|
||||
const rgbFromColor: string[] = owner.getColor().split(';');
|
||||
if (rgbFromColor.length < 3) return;
|
||||
const rgbFromColor = gdjs.rgbOrHexToRGBColor(owner.getColor());
|
||||
const hslFromColor = gdjs.evtTools.tween.rgbToHsl(
|
||||
parseFloat(rgbFromColor[0]),
|
||||
parseFloat(rgbFromColor[1]),
|
||||
parseFloat(rgbFromColor[2])
|
||||
rgbFromColor[0],
|
||||
rgbFromColor[1],
|
||||
rgbFromColor[2]
|
||||
);
|
||||
|
||||
const toH = animateHue ? toHue : hslFromColor[0];
|
||||
@@ -1474,11 +1473,11 @@ namespace gdjs {
|
||||
);
|
||||
|
||||
owner.setColor(
|
||||
Math.floor(rgbFromHslColor[0]) +
|
||||
Math.round(rgbFromHslColor[0]) +
|
||||
';' +
|
||||
Math.floor(rgbFromHslColor[1]) +
|
||||
Math.round(rgbFromHslColor[1]) +
|
||||
';' +
|
||||
Math.floor(rgbFromHslColor[2])
|
||||
Math.round(rgbFromHslColor[2])
|
||||
);
|
||||
},
|
||||
|
||||
|
@@ -841,13 +841,23 @@ CommonInstructionsExtension::CommonInstructionsExtension() {
|
||||
event.GetParameterObjects(),
|
||||
parentContext.GetCurrentObject());
|
||||
|
||||
callingCode += "var objects = [];\n";
|
||||
for (unsigned int i = 0; i < realObjects.size(); ++i) {
|
||||
parentContext.ObjectsListNeeded(realObjects[i]);
|
||||
if (realObjects.size() == 1) {
|
||||
parentContext.ObjectsListNeeded(realObjects[0]);
|
||||
callingCode +=
|
||||
"objects.push.apply(objects," +
|
||||
codeGenerator.GetObjectListName(realObjects[i], parentContext) +
|
||||
");\n";
|
||||
"const objects = " +
|
||||
codeGenerator.GetObjectListName(realObjects[0], parentContext) +
|
||||
";\n";
|
||||
} else {
|
||||
// Groups are rarely used in JS events so it's fine to make
|
||||
// allocations.
|
||||
callingCode += "const objects = [];\n";
|
||||
for (unsigned int i = 0; i < realObjects.size(); ++i) {
|
||||
parentContext.ObjectsListNeeded(realObjects[i]);
|
||||
callingCode += "objects.push.apply(objects," +
|
||||
codeGenerator.GetObjectListName(realObjects[i],
|
||||
parentContext) +
|
||||
");\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -26,6 +26,28 @@ The game engine is in the _Runtime_ folder. If you want to work on the engine di
|
||||
|
||||
- To launch type checking with TypeScript, run `npm install` and `npm run check-types` in `GDJS` folder.
|
||||
|
||||
#### Building GDJS Runtime
|
||||
|
||||
To build the GDJS Runtime, run `npm run build` in the `GDJS` folder.
|
||||
|
||||
**Build Options:**
|
||||
|
||||
- **Production build (default)**: `npm run build` - builds with minification enabled
|
||||
- **Debug build**: `npm run build -- --debug` - builds without minification for easier debugging
|
||||
- **Custom output path**: `npm run build -- --out=/path/to/output` - specify custom output directory
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Standard production build
|
||||
npm run build
|
||||
|
||||
# Debug build for development (no minification)
|
||||
npm run build -- --debug
|
||||
|
||||
# Debug build with custom output path
|
||||
npm run build -- --debug --out=./debug-build
|
||||
```
|
||||
|
||||
### GDJS Platform (exporters, code generation...)
|
||||
|
||||
Check the [GDJS Platform](https://docs.gdevelop.io/GDJS%20Documentation/index.html) documentation or the [full GDevelop developers documentation](https://docs.gdevelop.io/).
|
||||
|
@@ -462,12 +462,12 @@ namespace gdjs {
|
||||
/**
|
||||
* @param instanceContainer the container owning the layer
|
||||
* @param layerName The lighting layer with the ambient color.
|
||||
* @param rgbColor The color, in RGB format ("128;200;255").
|
||||
* @param rgbOrHexColor The color, in RGB format ("128;200;255").
|
||||
*/
|
||||
export const setLayerAmbientLightColor = function (
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
layerName: string,
|
||||
rgbColor: string
|
||||
rgbOrHexColor: string
|
||||
) {
|
||||
if (
|
||||
!instanceContainer.hasLayer(layerName) ||
|
||||
@@ -475,17 +475,10 @@ namespace gdjs {
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const colors = rgbColor.split(';');
|
||||
if (colors.length < 3) {
|
||||
return;
|
||||
}
|
||||
const color = gdjs.rgbOrHexToRGBColor(rgbOrHexColor);
|
||||
return instanceContainer
|
||||
.getLayer(layerName)
|
||||
.setClearColor(
|
||||
parseInt(colors[0], 10),
|
||||
parseInt(colors[1], 10),
|
||||
parseInt(colors[2], 10)
|
||||
);
|
||||
.setClearColor(color[0], color[1], color[2]);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -24,19 +24,12 @@ namespace gdjs {
|
||||
|
||||
export const setBackgroundColor = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
rgbColor: string
|
||||
rgbOrHexColor: string
|
||||
) {
|
||||
const colors = rgbColor.split(';');
|
||||
if (colors.length < 3) {
|
||||
return;
|
||||
}
|
||||
const color = gdjs.rgbOrHexToRGBColor(rgbOrHexColor);
|
||||
runtimeScene
|
||||
.getScene()
|
||||
.setBackgroundColor(
|
||||
parseInt(colors[0]),
|
||||
parseInt(colors[1]),
|
||||
parseInt(colors[2])
|
||||
);
|
||||
.setBackgroundColor(color[0], color[1], color[2]);
|
||||
};
|
||||
|
||||
export const getElapsedTimeInSeconds = function (
|
||||
|
@@ -12,7 +12,6 @@ namespace gdjs {
|
||||
const logger = new gdjs.Logger('Engine runtime');
|
||||
const hexStringRegex = /^(#{0,1}[A-Fa-f0-9]{6})$/;
|
||||
const shorthandHexStringRegex = /^(#{0,1}[A-Fa-f0-9]{3})$/;
|
||||
const rgbStringRegex = /^(\d{1,3};\d{1,3};\d{1,3})/;
|
||||
|
||||
/**
|
||||
* Contains functions used by events (this is a convention only, functions can actually
|
||||
@@ -105,9 +104,9 @@ namespace gdjs {
|
||||
export const rgbOrHexToRGBColor = function (
|
||||
value: string
|
||||
): [number, number, number] {
|
||||
const rgbColor = extractRGBString(value);
|
||||
if (rgbColor) {
|
||||
const splitValue = rgbColor.split(';');
|
||||
// TODO Add a `result` parameter to allow to reuse the returned array.
|
||||
if (!value.startsWith('#')) {
|
||||
const splitValue = value.split(';');
|
||||
// If a RGB string is provided, return the RGB object.
|
||||
if (splitValue.length === 3) {
|
||||
return [
|
||||
@@ -145,11 +144,11 @@ namespace gdjs {
|
||||
* @param b Blue
|
||||
*/
|
||||
export const rgbToHexNumber = function (
|
||||
r: integer,
|
||||
g: integer,
|
||||
b: integer
|
||||
r: float,
|
||||
g: float,
|
||||
b: float
|
||||
): integer {
|
||||
return (r << 16) + (g << 8) + b;
|
||||
return (Math.round(r) << 16) + (Math.round(g) << 8) + Math.round(b);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -192,12 +191,6 @@ namespace gdjs {
|
||||
return matches[0];
|
||||
};
|
||||
|
||||
export const extractRGBString = (str: string): string | null => {
|
||||
const matches = str.match(rgbStringRegex);
|
||||
if (!matches) return null;
|
||||
return matches[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a random integer between 0 and max.
|
||||
* @param max The maximum value (inclusive).
|
||||
|
@@ -140,18 +140,18 @@ namespace gdjs {
|
||||
this._sprite.visible = !this._object.hidden;
|
||||
}
|
||||
|
||||
setColor(rgbOrHexColor): void {
|
||||
setColor(rgbOrHexColor: string): void {
|
||||
this._sprite.tint = gdjs.rgbOrHexStringToNumber(rgbOrHexColor);
|
||||
}
|
||||
|
||||
getColor() {
|
||||
const rgb = new PIXI.Color(this._sprite.tint).toRgbArray();
|
||||
return (
|
||||
Math.floor(rgb[0] * 255) +
|
||||
Math.round(rgb[0] * 255) +
|
||||
';' +
|
||||
Math.floor(rgb[1] * 255) +
|
||||
Math.round(rgb[1] * 255) +
|
||||
';' +
|
||||
Math.floor(rgb[2] * 255)
|
||||
Math.round(rgb[2] * 255)
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -7,6 +7,8 @@ const {
|
||||
} = require('./lib/runtime-files-list');
|
||||
const args = require('minimist')(process.argv.slice(2), {
|
||||
string: ['out'],
|
||||
boolean: ['debug'],
|
||||
default: { debug: false }
|
||||
});
|
||||
const fs = require('fs').promises;
|
||||
|
||||
@@ -52,7 +54,7 @@ shell.mkdir('-p', bundledOutPath);
|
||||
return build({
|
||||
sourcemap: true,
|
||||
entryPoints: [inPath],
|
||||
minify: true,
|
||||
minify: !args.debug,
|
||||
outfile: renameBuiltFile(outPath),
|
||||
}).catch(() => {
|
||||
// Error is already logged by esbuild.
|
||||
|
@@ -36,11 +36,11 @@ describe('gdjs', function () {
|
||||
expect(gdjs.rgbOrHexToRGBColor('255;255;300')).to.eql([255, 255, 255]);
|
||||
expect(gdjs.rgbOrHexToRGBColor('999;12;6')).to.eql([255, 12, 6]);
|
||||
});
|
||||
it('should cut rgb values if string too long', function () {
|
||||
it('should cap rgb values', function () {
|
||||
expect(gdjs.rgbOrHexToRGBColor('255;255;200456')).to.eql([
|
||||
255,
|
||||
255,
|
||||
200,
|
||||
255,
|
||||
]);
|
||||
});
|
||||
it('should return components for black if unrecognized input', function () {
|
||||
@@ -48,7 +48,6 @@ describe('gdjs', function () {
|
||||
expect(gdjs.rgbOrHexToRGBColor('19819830803')).to.eql([0, 0, 0]);
|
||||
expect(gdjs.rgbOrHexToRGBColor('Infinity')).to.eql([0, 0, 0]);
|
||||
expect(gdjs.rgbOrHexToRGBColor('-4564')).to.eql([0, 0, 0]);
|
||||
expect(gdjs.rgbOrHexToRGBColor('9999;12;6')).to.eql([0, 0, 0]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -3728,6 +3728,8 @@ interface TextObject {
|
||||
[Const, Ref] DOMString GetText();
|
||||
void SetCharacterSize(double size);
|
||||
double GetCharacterSize();
|
||||
void SetLineHeight(double value);
|
||||
double GetLineHeight();
|
||||
void SetFontName([Const] DOMString string);
|
||||
[Const, Ref] DOMString GetFontName();
|
||||
boolean IsBold();
|
||||
|
@@ -64,7 +64,7 @@ describe('libGD.js object serialization', function() {
|
||||
obj.delete();
|
||||
|
||||
expect(jsonObject).toBe(
|
||||
'{"bold":false,"italic":false,"smoothed":true,"underlined":false,"string":"Text of the object, with 官话 characters","font":"","textAlignment":"left","characterSize":20.0,"color":{"b":0,"g":0,"r":0},"content":{"bold":false,"isOutlineEnabled":false,"isShadowEnabled":false,"italic":false,"outlineColor":"255;255;255","outlineThickness":2.0,"shadowAngle":90.0,"shadowBlurRadius":2.0,"shadowColor":"0;0;0","shadowDistance":4.0,"shadowOpacity":127.0,"smoothed":true,"underlined":false,"text":"Text of the object, with 官话 characters","font":"","textAlignment":"left","verticalTextAlignment":"top","characterSize":20.0,"color":"0;0;0"}}'
|
||||
'{"bold":false,"italic":false,"smoothed":true,"underlined":false,"string":"Text of the object, with 官话 characters","font":"","textAlignment":"left","characterSize":20.0,"color":{"b":0,"g":0,"r":0},"content":{"bold":false,"isOutlineEnabled":false,"isShadowEnabled":false,"italic":false,"outlineColor":"255;255;255","outlineThickness":2.0,"shadowAngle":90.0,"shadowBlurRadius":2.0,"shadowColor":"0;0;0","shadowDistance":4.0,"shadowOpacity":127.0,"smoothed":true,"underlined":false,"text":"Text of the object, with 官话 characters","font":"","textAlignment":"left","verticalTextAlignment":"top","characterSize":20.0,"lineHeight":0.0,"color":"0;0;0"}}'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
2
GDevelop.js/types.d.ts
vendored
2
GDevelop.js/types.d.ts
vendored
@@ -2758,6 +2758,8 @@ export class TextObject extends ObjectConfiguration {
|
||||
getText(): string;
|
||||
setCharacterSize(size: number): void;
|
||||
getCharacterSize(): number;
|
||||
setLineHeight(value: number): void;
|
||||
getLineHeight(): number;
|
||||
setFontName(string: string): void;
|
||||
getFontName(): string;
|
||||
isBold(): boolean;
|
||||
|
@@ -5,6 +5,8 @@ declare class gdTextObject extends gdObjectConfiguration {
|
||||
getText(): string;
|
||||
setCharacterSize(size: number): void;
|
||||
getCharacterSize(): number;
|
||||
setLineHeight(value: number): void;
|
||||
getLineHeight(): number;
|
||||
setFontName(string: string): void;
|
||||
getFontName(): string;
|
||||
isBold(): boolean;
|
||||
|
@@ -19,6 +19,7 @@ import { type ExtensionItemConfigurationAttribute } from '../EventsFunctionsExte
|
||||
import SelectField from '../UI/SelectField';
|
||||
import SelectOption from '../UI/SelectOption';
|
||||
import Window from '../Utils/Window';
|
||||
import ScrollView from '../UI/ScrollView';
|
||||
|
||||
const gd: libGDevelop = global.gd;
|
||||
|
||||
@@ -67,150 +68,154 @@ export default function EventsBasedBehaviorEditor({
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<ColumnStackLayout expand noMargin>
|
||||
<DismissableAlertMessage
|
||||
identifier="events-based-behavior-explanation"
|
||||
kind="info"
|
||||
>
|
||||
<Trans>
|
||||
This is the configuration of your behavior. Make sure to choose a
|
||||
proper internal name as it's hard to change it later. Enter a
|
||||
description explaining what the behavior is doing to the object.
|
||||
</Trans>
|
||||
</DismissableAlertMessage>
|
||||
<TextField
|
||||
floatingLabelText={<Trans>Internal Name</Trans>}
|
||||
value={eventsBasedBehavior.getName()}
|
||||
disabled
|
||||
fullWidth
|
||||
/>
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
floatingLabelText={<Trans>Name displayed in editor</Trans>}
|
||||
value={eventsBasedBehavior.getFullName()}
|
||||
onChange={text => {
|
||||
eventsBasedBehavior.setFullName(text);
|
||||
onChange();
|
||||
}}
|
||||
fullWidth
|
||||
/>
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
floatingLabelText={<Trans>Description</Trans>}
|
||||
helperMarkdownText={i18n._(
|
||||
t`Explain what the behavior is doing to the object. Start with a verb when possible.`
|
||||
)}
|
||||
value={eventsBasedBehavior.getDescription()}
|
||||
onChange={text => {
|
||||
eventsBasedBehavior.setDescription(text);
|
||||
onChange();
|
||||
}}
|
||||
multiline
|
||||
fullWidth
|
||||
rows={3}
|
||||
/>
|
||||
<ObjectTypeSelector
|
||||
floatingLabelText={
|
||||
<Trans>Object on which this behavior can be used</Trans>
|
||||
}
|
||||
project={project}
|
||||
value={eventsBasedBehavior.getObjectType()}
|
||||
onChange={(objectType: string) => {
|
||||
eventsBasedBehavior.setObjectType(objectType);
|
||||
onChange();
|
||||
}}
|
||||
allowedObjectTypes={
|
||||
allObjectTypes.length === 0
|
||||
? undefined /* Allow anything as the behavior is not used */
|
||||
: allObjectTypes.length === 1
|
||||
? [
|
||||
'',
|
||||
allObjectTypes[0],
|
||||
] /* Allow only the type of the objects using the behavior */
|
||||
: [
|
||||
'',
|
||||
] /* More than one type of object are using the behavior. Only "any object" can be used on this behavior */
|
||||
}
|
||||
/>
|
||||
{allObjectTypes.length > 1 && (
|
||||
<AlertMessage kind="info">
|
||||
<Trans>
|
||||
This behavior is being used by multiple types of objects. Thus,
|
||||
you can't restrict its usage to any particular object type. All
|
||||
the object types using this behavior are listed here:
|
||||
{allObjectTypes.join(', ')}
|
||||
</Trans>
|
||||
</AlertMessage>
|
||||
)}
|
||||
{isDev && (
|
||||
<SelectField
|
||||
floatingLabelText={
|
||||
<Trans>Visibility in quick customization dialog</Trans>
|
||||
}
|
||||
value={eventsBasedBehavior.getQuickCustomizationVisibility()}
|
||||
onChange={(e, i, valueString: string) => {
|
||||
// $FlowFixMe
|
||||
const value: QuickCustomization_Visibility = valueString;
|
||||
eventsBasedBehavior.setQuickCustomizationVisibility(value);
|
||||
onChange();
|
||||
}}
|
||||
fullWidth
|
||||
>
|
||||
<SelectOption
|
||||
value={gd.QuickCustomization.Default}
|
||||
label={t`Default (visible)`}
|
||||
/>
|
||||
<SelectOption
|
||||
value={gd.QuickCustomization.Visible}
|
||||
label={t`Always visible`}
|
||||
/>
|
||||
<SelectOption
|
||||
value={gd.QuickCustomization.Hidden}
|
||||
label={t`Hidden`}
|
||||
/>
|
||||
</SelectField>
|
||||
)}
|
||||
<Checkbox
|
||||
label={<Trans>Private</Trans>}
|
||||
checked={eventsBasedBehavior.isPrivate()}
|
||||
onCheck={(e, checked) => {
|
||||
eventsBasedBehavior.setPrivate(checked);
|
||||
if (onConfigurationUpdated) onConfigurationUpdated('isPrivate');
|
||||
onChange();
|
||||
}}
|
||||
tooltipOrHelperText={
|
||||
eventsBasedBehavior.isPrivate() ? (
|
||||
<Trans>
|
||||
This behavior won't be visible in the scene and events
|
||||
editors.
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>
|
||||
This behavior will be visible in the scene and events editors.
|
||||
</Trans>
|
||||
)
|
||||
}
|
||||
/>
|
||||
{eventsBasedBehavior
|
||||
.getEventsFunctions()
|
||||
.getEventsFunctionsCount() === 0 && (
|
||||
<ScrollView>
|
||||
<ColumnStackLayout expand noMargin>
|
||||
<DismissableAlertMessage
|
||||
identifier="empty-events-based-behavior-explanation"
|
||||
identifier="events-based-behavior-explanation"
|
||||
kind="info"
|
||||
>
|
||||
<Trans>
|
||||
Once you're done, start adding some functions to the behavior.
|
||||
Then, test the behavior by adding it to an object in a scene.
|
||||
This is the configuration of your behavior. Make sure to choose
|
||||
a proper internal name as it's hard to change it later. Enter a
|
||||
description explaining what the behavior is doing to the object.
|
||||
</Trans>
|
||||
</DismissableAlertMessage>
|
||||
)}
|
||||
<Line noMargin>
|
||||
<HelpButton
|
||||
key="help"
|
||||
helpPagePath="/behaviors/events-based-behaviors"
|
||||
<TextField
|
||||
floatingLabelText={<Trans>Internal Name</Trans>}
|
||||
value={eventsBasedBehavior.getName()}
|
||||
disabled
|
||||
fullWidth
|
||||
/>
|
||||
</Line>
|
||||
</ColumnStackLayout>
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
floatingLabelText={<Trans>Name displayed in editor</Trans>}
|
||||
value={eventsBasedBehavior.getFullName()}
|
||||
onChange={text => {
|
||||
eventsBasedBehavior.setFullName(text);
|
||||
onChange();
|
||||
}}
|
||||
fullWidth
|
||||
/>
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
floatingLabelText={<Trans>Description</Trans>}
|
||||
helperMarkdownText={i18n._(
|
||||
t`Explain what the behavior is doing to the object. Start with a verb when possible.`
|
||||
)}
|
||||
value={eventsBasedBehavior.getDescription()}
|
||||
onChange={text => {
|
||||
eventsBasedBehavior.setDescription(text);
|
||||
onChange();
|
||||
}}
|
||||
multiline
|
||||
fullWidth
|
||||
rows={3}
|
||||
/>
|
||||
<ObjectTypeSelector
|
||||
floatingLabelText={
|
||||
<Trans>Object on which this behavior can be used</Trans>
|
||||
}
|
||||
project={project}
|
||||
value={eventsBasedBehavior.getObjectType()}
|
||||
onChange={(objectType: string) => {
|
||||
eventsBasedBehavior.setObjectType(objectType);
|
||||
onChange();
|
||||
}}
|
||||
allowedObjectTypes={
|
||||
allObjectTypes.length === 0
|
||||
? undefined /* Allow anything as the behavior is not used */
|
||||
: allObjectTypes.length === 1
|
||||
? [
|
||||
'',
|
||||
allObjectTypes[0],
|
||||
] /* Allow only the type of the objects using the behavior */
|
||||
: [
|
||||
'',
|
||||
] /* More than one type of object are using the behavior. Only "any object" can be used on this behavior */
|
||||
}
|
||||
/>
|
||||
{allObjectTypes.length > 1 && (
|
||||
<AlertMessage kind="info">
|
||||
<Trans>
|
||||
This behavior is being used by multiple types of objects.
|
||||
Thus, you can't restrict its usage to any particular object
|
||||
type. All the object types using this behavior are listed
|
||||
here:
|
||||
{allObjectTypes.join(', ')}
|
||||
</Trans>
|
||||
</AlertMessage>
|
||||
)}
|
||||
{isDev && (
|
||||
<SelectField
|
||||
floatingLabelText={
|
||||
<Trans>Visibility in quick customization dialog</Trans>
|
||||
}
|
||||
value={eventsBasedBehavior.getQuickCustomizationVisibility()}
|
||||
onChange={(e, i, valueString: string) => {
|
||||
// $FlowFixMe
|
||||
const value: QuickCustomization_Visibility = valueString;
|
||||
eventsBasedBehavior.setQuickCustomizationVisibility(value);
|
||||
onChange();
|
||||
}}
|
||||
fullWidth
|
||||
>
|
||||
<SelectOption
|
||||
value={gd.QuickCustomization.Default}
|
||||
label={t`Default (visible)`}
|
||||
/>
|
||||
<SelectOption
|
||||
value={gd.QuickCustomization.Visible}
|
||||
label={t`Always visible`}
|
||||
/>
|
||||
<SelectOption
|
||||
value={gd.QuickCustomization.Hidden}
|
||||
label={t`Hidden`}
|
||||
/>
|
||||
</SelectField>
|
||||
)}
|
||||
<Checkbox
|
||||
label={<Trans>Private</Trans>}
|
||||
checked={eventsBasedBehavior.isPrivate()}
|
||||
onCheck={(e, checked) => {
|
||||
eventsBasedBehavior.setPrivate(checked);
|
||||
if (onConfigurationUpdated) onConfigurationUpdated('isPrivate');
|
||||
onChange();
|
||||
}}
|
||||
tooltipOrHelperText={
|
||||
eventsBasedBehavior.isPrivate() ? (
|
||||
<Trans>
|
||||
This behavior won't be visible in the scene and events
|
||||
editors.
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>
|
||||
This behavior will be visible in the scene and events
|
||||
editors.
|
||||
</Trans>
|
||||
)
|
||||
}
|
||||
/>
|
||||
{eventsBasedBehavior
|
||||
.getEventsFunctions()
|
||||
.getEventsFunctionsCount() === 0 && (
|
||||
<DismissableAlertMessage
|
||||
identifier="empty-events-based-behavior-explanation"
|
||||
kind="info"
|
||||
>
|
||||
<Trans>
|
||||
Once you're done, start adding some functions to the behavior.
|
||||
Then, test the behavior by adding it to an object in a scene.
|
||||
</Trans>
|
||||
</DismissableAlertMessage>
|
||||
)}
|
||||
<Line noMargin>
|
||||
<HelpButton
|
||||
key="help"
|
||||
helpPagePath="/behaviors/events-based-behaviors"
|
||||
/>
|
||||
</Line>
|
||||
</ColumnStackLayout>
|
||||
</ScrollView>
|
||||
)}
|
||||
</I18n>
|
||||
);
|
||||
|
@@ -72,6 +72,7 @@ export default function EventsBasedObjectEditorPanel({
|
||||
</Line>
|
||||
{currentTab === 'configuration' && (
|
||||
<EventsBasedObjectEditor
|
||||
eventsFunctionsExtension={eventsFunctionsExtension}
|
||||
eventsBasedObject={eventsBasedObject}
|
||||
unsavedChanges={unsavedChanges}
|
||||
onOpenCustomObjectEditor={onOpenCustomObjectEditor}
|
||||
|
@@ -6,7 +6,8 @@ import * as React from 'react';
|
||||
import TextField from '../UI/TextField';
|
||||
import SemiControlledTextField from '../UI/SemiControlledTextField';
|
||||
import DismissableAlertMessage from '../UI/DismissableAlertMessage';
|
||||
import { ColumnStackLayout } from '../UI/Layout';
|
||||
import AlertMessage from '../UI/AlertMessage';
|
||||
import { ColumnStackLayout, LineStackLayout } from '../UI/Layout';
|
||||
import useForceUpdate from '../Utils/UseForceUpdate';
|
||||
import Checkbox from '../UI/Checkbox';
|
||||
import HelpButton from '../UI/HelpButton';
|
||||
@@ -14,12 +15,15 @@ import { Line } from '../UI/Grid';
|
||||
import { type UnsavedChanges } from '../MainFrame/UnsavedChangesContext';
|
||||
import RaisedButton from '../UI/RaisedButton';
|
||||
import Window from '../Utils/Window';
|
||||
import ScrollView from '../UI/ScrollView';
|
||||
import { Column } from '../UI/Grid';
|
||||
|
||||
const gd: libGDevelop = global.gd;
|
||||
|
||||
const isDev = Window.isDev();
|
||||
|
||||
type Props = {|
|
||||
eventsFunctionsExtension: gdEventsFunctionsExtension,
|
||||
eventsBasedObject: gdEventsBasedObject,
|
||||
onOpenCustomObjectEditor: () => void,
|
||||
unsavedChanges?: ?UnsavedChanges,
|
||||
@@ -29,6 +33,7 @@ type Props = {|
|
||||
|};
|
||||
|
||||
export default function EventsBasedObjectEditor({
|
||||
eventsFunctionsExtension,
|
||||
eventsBasedObject,
|
||||
onOpenCustomObjectEditor,
|
||||
unsavedChanges,
|
||||
@@ -47,135 +52,155 @@ export default function EventsBasedObjectEditor({
|
||||
);
|
||||
|
||||
return (
|
||||
<ColumnStackLayout expand noMargin>
|
||||
<DismissableAlertMessage
|
||||
identifier="events-based-object-explanation"
|
||||
kind="info"
|
||||
>
|
||||
<Trans>
|
||||
This is the configuration of your object. Make sure to choose a proper
|
||||
internal name as it's hard to change it later.
|
||||
</Trans>
|
||||
</DismissableAlertMessage>
|
||||
<TextField
|
||||
floatingLabelText={<Trans>Internal Name</Trans>}
|
||||
value={eventsBasedObject.getName()}
|
||||
disabled
|
||||
fullWidth
|
||||
/>
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
floatingLabelText={<Trans>Name displayed in editor</Trans>}
|
||||
value={eventsBasedObject.getFullName()}
|
||||
onChange={text => {
|
||||
eventsBasedObject.setFullName(text);
|
||||
onChange();
|
||||
}}
|
||||
fullWidth
|
||||
/>
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
floatingLabelText={<Trans>Description</Trans>}
|
||||
floatingLabelFixed
|
||||
translatableHintText={t`The description of the object should explain what the object is doing, and, briefly, how to use it.`}
|
||||
value={eventsBasedObject.getDescription()}
|
||||
onChange={text => {
|
||||
eventsBasedObject.setDescription(text);
|
||||
onChange();
|
||||
}}
|
||||
multiline
|
||||
fullWidth
|
||||
rows={3}
|
||||
/>
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
floatingLabelText={<Trans>Default name for created objects</Trans>}
|
||||
value={
|
||||
eventsBasedObject.getDefaultName() || eventsBasedObject.getName()
|
||||
}
|
||||
onChange={newName => {
|
||||
eventsBasedObject.setDefaultName(gd.Project.getSafeName(newName));
|
||||
onChange();
|
||||
}}
|
||||
fullWidth
|
||||
/>
|
||||
<Checkbox
|
||||
label={<Trans>Use 3D rendering</Trans>}
|
||||
checked={eventsBasedObject.isRenderedIn3D()}
|
||||
onCheck={(e, checked) => {
|
||||
eventsBasedObject.markAsRenderedIn3D(checked);
|
||||
onChange();
|
||||
}}
|
||||
/>
|
||||
<Checkbox
|
||||
label={<Trans>Has animations</Trans>}
|
||||
checked={eventsBasedObject.isAnimatable()}
|
||||
onCheck={(e, checked) => {
|
||||
eventsBasedObject.markAsAnimatable(checked);
|
||||
onChange();
|
||||
}}
|
||||
/>
|
||||
<Checkbox
|
||||
label={<Trans>Contains text</Trans>}
|
||||
checked={eventsBasedObject.isTextContainer()}
|
||||
onCheck={(e, checked) => {
|
||||
eventsBasedObject.markAsTextContainer(checked);
|
||||
onChange();
|
||||
}}
|
||||
/>
|
||||
<Checkbox
|
||||
label={<Trans>Expand inner area with parent</Trans>}
|
||||
checked={eventsBasedObject.isInnerAreaFollowingParentSize()}
|
||||
onCheck={(e, checked) => {
|
||||
eventsBasedObject.markAsInnerAreaFollowingParentSize(checked);
|
||||
onChange();
|
||||
onEventsBasedObjectChildrenEdited(eventsBasedObject);
|
||||
}}
|
||||
/>
|
||||
{isDev && (
|
||||
<ScrollView>
|
||||
<ColumnStackLayout expand noMargin>
|
||||
<DismissableAlertMessage
|
||||
identifier="events-based-object-explanation"
|
||||
kind="info"
|
||||
>
|
||||
<Trans>
|
||||
This is the configuration of your object. Make sure to choose a
|
||||
proper internal name as it's hard to change it later.
|
||||
</Trans>
|
||||
</DismissableAlertMessage>
|
||||
<TextField
|
||||
floatingLabelText={<Trans>Internal Name</Trans>}
|
||||
value={eventsBasedObject.getName()}
|
||||
disabled
|
||||
fullWidth
|
||||
/>
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
floatingLabelText={<Trans>Name displayed in editor</Trans>}
|
||||
value={eventsBasedObject.getFullName()}
|
||||
onChange={text => {
|
||||
eventsBasedObject.setFullName(text);
|
||||
onChange();
|
||||
}}
|
||||
fullWidth
|
||||
/>
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
floatingLabelText={<Trans>Description</Trans>}
|
||||
floatingLabelFixed
|
||||
translatableHintText={t`The description of the object should explain what the object is doing, and, briefly, how to use it.`}
|
||||
value={eventsBasedObject.getDescription()}
|
||||
onChange={text => {
|
||||
eventsBasedObject.setDescription(text);
|
||||
onChange();
|
||||
}}
|
||||
multiline
|
||||
fullWidth
|
||||
rows={3}
|
||||
/>
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
floatingLabelText={<Trans>Default name for created objects</Trans>}
|
||||
value={
|
||||
eventsBasedObject.getDefaultName() || eventsBasedObject.getName()
|
||||
}
|
||||
onChange={newName => {
|
||||
eventsBasedObject.setDefaultName(gd.Project.getSafeName(newName));
|
||||
onChange();
|
||||
}}
|
||||
fullWidth
|
||||
/>
|
||||
<Checkbox
|
||||
label={<Trans>Use legacy renderer</Trans>}
|
||||
checked={eventsBasedObject.isUsingLegacyInstancesRenderer()}
|
||||
label={<Trans>Use 3D rendering</Trans>}
|
||||
checked={eventsBasedObject.isRenderedIn3D()}
|
||||
onCheck={(e, checked) => {
|
||||
eventsBasedObject.makAsUsingLegacyInstancesRenderer(checked);
|
||||
eventsBasedObject.markAsRenderedIn3D(checked);
|
||||
onChange();
|
||||
}}
|
||||
/>
|
||||
<Checkbox
|
||||
label={<Trans>Has animations</Trans>}
|
||||
checked={eventsBasedObject.isAnimatable()}
|
||||
onCheck={(e, checked) => {
|
||||
eventsBasedObject.markAsAnimatable(checked);
|
||||
onChange();
|
||||
}}
|
||||
/>
|
||||
<Checkbox
|
||||
label={<Trans>Contains text</Trans>}
|
||||
checked={eventsBasedObject.isTextContainer()}
|
||||
onCheck={(e, checked) => {
|
||||
eventsBasedObject.markAsTextContainer(checked);
|
||||
onChange();
|
||||
}}
|
||||
/>
|
||||
<Checkbox
|
||||
label={<Trans>Expand inner area with parent</Trans>}
|
||||
checked={eventsBasedObject.isInnerAreaFollowingParentSize()}
|
||||
onCheck={(e, checked) => {
|
||||
eventsBasedObject.markAsInnerAreaFollowingParentSize(checked);
|
||||
onChange();
|
||||
onEventsBasedObjectChildrenEdited(eventsBasedObject);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Checkbox
|
||||
label={<Trans>Private</Trans>}
|
||||
checked={eventsBasedObject.isPrivate()}
|
||||
onCheck={(e, checked) => {
|
||||
eventsBasedObject.setPrivate(checked);
|
||||
onChange();
|
||||
onEventsBasedObjectChildrenEdited(eventsBasedObject);
|
||||
}}
|
||||
tooltipOrHelperText={
|
||||
eventsBasedObject.isPrivate() ? (
|
||||
<Trans>
|
||||
This object won't be visible in the scene and events editors.
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>
|
||||
This object will be visible in the scene and events editors.
|
||||
</Trans>
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Line noMargin justifyContent="center">
|
||||
<RaisedButton
|
||||
label={<Trans>Open visual editor for the object</Trans>}
|
||||
primary
|
||||
onClick={onOpenCustomObjectEditor}
|
||||
{isDev && (
|
||||
<Checkbox
|
||||
label={<Trans>Use legacy renderer</Trans>}
|
||||
checked={eventsBasedObject.isUsingLegacyInstancesRenderer()}
|
||||
onCheck={(e, checked) => {
|
||||
eventsBasedObject.makAsUsingLegacyInstancesRenderer(checked);
|
||||
onChange();
|
||||
onEventsBasedObjectChildrenEdited(eventsBasedObject);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Checkbox
|
||||
label={<Trans>Private</Trans>}
|
||||
checked={eventsBasedObject.isPrivate()}
|
||||
onCheck={(e, checked) => {
|
||||
eventsBasedObject.setPrivate(checked);
|
||||
onChange();
|
||||
onEventsBasedObjectChildrenEdited(eventsBasedObject);
|
||||
}}
|
||||
tooltipOrHelperText={
|
||||
eventsBasedObject.isPrivate() ? (
|
||||
<Trans>
|
||||
This object won't be visible in the scene and events editors.
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>
|
||||
This object will be visible in the scene and events editors.
|
||||
</Trans>
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Line>
|
||||
<Line noMargin>
|
||||
<HelpButton
|
||||
key="help"
|
||||
helpPagePath="/objects/custom-objects-prefab-template"
|
||||
/>
|
||||
</Line>
|
||||
</ColumnStackLayout>
|
||||
{eventsFunctionsExtension.getOriginName() ===
|
||||
'gdevelop-extension-store' ? (
|
||||
<AlertMessage
|
||||
kind="error"
|
||||
renderRightButton={() => (
|
||||
<RaisedButton
|
||||
label={<Trans>Edit the default variant</Trans>}
|
||||
primary
|
||||
onClick={onOpenCustomObjectEditor}
|
||||
/>
|
||||
)}
|
||||
>
|
||||
<Trans>
|
||||
The default variant is erased when the extension is updated.
|
||||
</Trans>
|
||||
</AlertMessage>
|
||||
) : (
|
||||
<Line noMargin justifyContent="center">
|
||||
<RaisedButton
|
||||
label={<Trans>Open visual editor for the object</Trans>}
|
||||
primary
|
||||
onClick={onOpenCustomObjectEditor}
|
||||
/>
|
||||
</Line>
|
||||
)}
|
||||
<Line noMargin>
|
||||
<HelpButton
|
||||
key="help"
|
||||
helpPagePath="/objects/custom-objects-prefab-template"
|
||||
/>
|
||||
</Line>
|
||||
</ColumnStackLayout>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
@@ -33,7 +33,7 @@ describe('EnumerateInstructions', () => {
|
||||
expect.objectContaining({
|
||||
displayedName: 'Animation finished',
|
||||
fullGroupName:
|
||||
'General ❯ Animatable capability ❯ Animations and images',
|
||||
'General ❯ Objects with animations ❯ Animations and images',
|
||||
type: 'AnimatableCapability::AnimatableBehavior::HasAnimationEnded',
|
||||
})
|
||||
);
|
||||
|
@@ -545,6 +545,20 @@ const useCourses = () => {
|
||||
]
|
||||
);
|
||||
|
||||
React.useEffect(
|
||||
() => {
|
||||
if (language) {
|
||||
console.info(
|
||||
`Resetting course chapters cache as language changed to ${language}.`
|
||||
);
|
||||
setChaptersByCourseIdByUserId(() => ({
|
||||
'': noCourseChapters,
|
||||
}));
|
||||
}
|
||||
},
|
||||
[language]
|
||||
);
|
||||
|
||||
// This callback will change (triggering re-renders)
|
||||
// anytime the chapters are fetched for a course for a user.
|
||||
const getCourseChapters = React.useCallback(
|
||||
|
@@ -56,12 +56,12 @@ export default class TextEditor extends React.Component<EditorProps, void> {
|
||||
resourceManagementProps,
|
||||
renderObjectNameField,
|
||||
} = this.props;
|
||||
const textObjectConfiguration =
|
||||
gd.asTextObjectConfiguration(objectConfiguration);
|
||||
const textObjectConfiguration = gd.asTextObjectConfiguration(
|
||||
objectConfiguration
|
||||
);
|
||||
|
||||
const textAlignment = textObjectConfiguration.getTextAlignment();
|
||||
const verticalTextAlignment =
|
||||
textObjectConfiguration.getVerticalTextAlignment();
|
||||
const verticalTextAlignment = textObjectConfiguration.getVerticalTextAlignment();
|
||||
|
||||
return (
|
||||
<ColumnStackLayout noMargin>
|
||||
@@ -82,7 +82,7 @@ export default class TextEditor extends React.Component<EditorProps, void> {
|
||||
margin="none"
|
||||
style={styles.sizeTextField}
|
||||
value={textObjectConfiguration.getCharacterSize()}
|
||||
onChange={(value) => {
|
||||
onChange={value => {
|
||||
textObjectConfiguration.setCharacterSize(
|
||||
parseInt(value, 10) || 0
|
||||
);
|
||||
@@ -99,7 +99,7 @@ export default class TextEditor extends React.Component<EditorProps, void> {
|
||||
textObjectConfiguration.getColor(),
|
||||
255
|
||||
)}
|
||||
onChangeComplete={(color) => {
|
||||
onChangeComplete={color => {
|
||||
const rgbString = rgbColorToRGBString(color.rgb);
|
||||
textObjectConfiguration.setColor(rgbString);
|
||||
this.forceUpdate();
|
||||
@@ -211,23 +211,13 @@ export default class TextEditor extends React.Component<EditorProps, void> {
|
||||
fullWidth
|
||||
canBeReset
|
||||
initialResourceName={textObjectConfiguration.getFontName()}
|
||||
onChange={(resourceName) => {
|
||||
onChange={resourceName => {
|
||||
textObjectConfiguration.setFontName(resourceName);
|
||||
this.forceUpdate();
|
||||
}}
|
||||
floatingLabelText={<Trans>Choose a font</Trans>}
|
||||
hintText={<Trans>Choose a font</Trans>}
|
||||
/>
|
||||
<SemiControlledTextField
|
||||
floatingLabelText={<Trans>Line height</Trans>}
|
||||
type="number"
|
||||
fullWidth
|
||||
value={textObjectConfiguration.getLineHeight()}
|
||||
onChange={(value) => {
|
||||
textObjectConfiguration.setLineHeight(parseFloat(value) || 0);
|
||||
this.forceUpdate();
|
||||
}}
|
||||
/>
|
||||
<Line noMargin>
|
||||
<SemiControlledTextField
|
||||
floatingLabelText={<Trans>Initial text to display</Trans>}
|
||||
@@ -240,7 +230,7 @@ export default class TextEditor extends React.Component<EditorProps, void> {
|
||||
rows={8}
|
||||
rowsMax={8}
|
||||
value={textObjectConfiguration.getText()}
|
||||
onChange={(value) => {
|
||||
onChange={value => {
|
||||
textObjectConfiguration.setText(value);
|
||||
this.forceUpdate();
|
||||
this.props.onSizeUpdated();
|
||||
@@ -269,7 +259,7 @@ export default class TextEditor extends React.Component<EditorProps, void> {
|
||||
disableAlpha
|
||||
fullWidth
|
||||
color={textObjectConfiguration.getOutlineColor()}
|
||||
onChange={(color) => {
|
||||
onChange={color => {
|
||||
const rgbString =
|
||||
color.length === 0 ? '' : rgbOrHexToRGBString(color);
|
||||
textObjectConfiguration.setOutlineColor(rgbString);
|
||||
@@ -283,7 +273,7 @@ export default class TextEditor extends React.Component<EditorProps, void> {
|
||||
floatingLabelText={<Trans>Thickness</Trans>}
|
||||
type="number"
|
||||
value={textObjectConfiguration.getOutlineThickness()}
|
||||
onChange={(value) => {
|
||||
onChange={value => {
|
||||
textObjectConfiguration.setOutlineThickness(
|
||||
parseInt(value, 10) || 0
|
||||
);
|
||||
@@ -314,7 +304,7 @@ export default class TextEditor extends React.Component<EditorProps, void> {
|
||||
floatingLabelText={<Trans>Distance</Trans>}
|
||||
type="number"
|
||||
value={textObjectConfiguration.getShadowDistance()}
|
||||
onChange={(value) => {
|
||||
onChange={value => {
|
||||
textObjectConfiguration.setShadowDistance(
|
||||
parseInt(value, 10) || 0
|
||||
);
|
||||
@@ -328,7 +318,7 @@ export default class TextEditor extends React.Component<EditorProps, void> {
|
||||
floatingLabelText={<Trans>Angle</Trans>}
|
||||
type="number"
|
||||
value={textObjectConfiguration.getShadowAngle()}
|
||||
onChange={(value) => {
|
||||
onChange={value => {
|
||||
textObjectConfiguration.setShadowAngle(
|
||||
parseInt(value, 10) || 0
|
||||
);
|
||||
@@ -344,7 +334,7 @@ export default class TextEditor extends React.Component<EditorProps, void> {
|
||||
disableAlpha
|
||||
fullWidth
|
||||
color={textObjectConfiguration.getShadowColor()}
|
||||
onChange={(color) => {
|
||||
onChange={color => {
|
||||
const rgbString =
|
||||
color.length === 0 ? '' : rgbOrHexToRGBString(color);
|
||||
textObjectConfiguration.setShadowColor(rgbString);
|
||||
@@ -358,7 +348,7 @@ export default class TextEditor extends React.Component<EditorProps, void> {
|
||||
floatingLabelText={<Trans>Opacity (0 - 255)</Trans>}
|
||||
type="number"
|
||||
value={textObjectConfiguration.getShadowOpacity()}
|
||||
onChange={(value) => {
|
||||
onChange={value => {
|
||||
textObjectConfiguration.setShadowOpacity(
|
||||
parseInt(value, 10) || 0
|
||||
);
|
||||
@@ -373,7 +363,7 @@ export default class TextEditor extends React.Component<EditorProps, void> {
|
||||
floatingLabelText={<Trans>Blur radius</Trans>}
|
||||
type="number"
|
||||
value={textObjectConfiguration.getShadowBlurRadius()}
|
||||
onChange={(value) => {
|
||||
onChange={value => {
|
||||
textObjectConfiguration.setShadowBlurRadius(
|
||||
parseInt(value, 10) || 0
|
||||
);
|
||||
@@ -381,6 +371,21 @@ export default class TextEditor extends React.Component<EditorProps, void> {
|
||||
}}
|
||||
/>
|
||||
</Column>
|
||||
<Text size="block-title" noMargin>
|
||||
<Trans>Multiline</Trans>
|
||||
</Text>
|
||||
<Line noMargin>
|
||||
<SemiControlledTextField
|
||||
floatingLabelText={<Trans>Line height</Trans>}
|
||||
type="number"
|
||||
fullWidth
|
||||
value={textObjectConfiguration.getLineHeight()}
|
||||
onChange={value => {
|
||||
textObjectConfiguration.setLineHeight(parseFloat(value) || 0);
|
||||
this.forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</Line>
|
||||
</ColumnStackLayout>
|
||||
);
|
||||
}
|
||||
|
@@ -13,7 +13,6 @@ export default class RenderedTextInstance extends RenderedInstance {
|
||||
_isItalic: boolean = false;
|
||||
_isBold: boolean = false;
|
||||
_characterSize: number = 0;
|
||||
_lineHeight: number = 0;
|
||||
_wrapping: boolean = false;
|
||||
_wrappingWidth: number = 0;
|
||||
_styleFontDirty: boolean = true;
|
||||
@@ -33,6 +32,7 @@ export default class RenderedTextInstance extends RenderedInstance {
|
||||
_shadowColor = '0;0;0';
|
||||
_shadowOpacity = 127;
|
||||
_shadowBlurRadius = 2;
|
||||
_lineHeight = 0;
|
||||
|
||||
constructor(
|
||||
project: gdProject,
|
||||
@@ -170,12 +170,12 @@ export default class RenderedTextInstance extends RenderedInstance {
|
||||
style.fontSize = Math.max(1, this._characterSize);
|
||||
style.fontStyle = this._isItalic ? 'italic' : 'normal';
|
||||
style.fontWeight = this._isBold ? 'bold' : 'normal';
|
||||
style.lineHeight = this._lineHeight !== 0 ? this._lineHeight : undefined;
|
||||
style.fill = rgbStringToHexNumber(this._color);
|
||||
style.wordWrap = this._wrapping;
|
||||
style.wordWrapWidth = this._wrappingWidth <= 1 ? 1 : this._wrappingWidth;
|
||||
style.breakWords = true;
|
||||
style.align = this._textAlignment;
|
||||
style.lineHeight = this._lineHeight;
|
||||
|
||||
style.stroke = rgbStringToHexNumber(this._outlineColor);
|
||||
style.strokeThickness = this._isOutlineEnabled
|
||||
|
@@ -104,6 +104,7 @@ export class ExtensionTreeViewItemContent implements TreeViewItemContent {
|
||||
if (oldName === newName) {
|
||||
return;
|
||||
}
|
||||
this.eventsFunctionsExtension.setOrigin('', '');
|
||||
this.props.onRenameEventsFunctionsExtension(oldName, newName);
|
||||
}
|
||||
|
||||
@@ -219,6 +220,9 @@ export class ExtensionTreeViewItemContent implements TreeViewItemContent {
|
||||
project
|
||||
);
|
||||
newEventsFunctionsExtension.setName(newName); // Unserialization has overwritten the name.
|
||||
if (newName !== name) {
|
||||
newEventsFunctionsExtension.setOrigin('', '');
|
||||
}
|
||||
|
||||
this._onProjectItemModified();
|
||||
this.props.onReloadEventsFunctionsExtensions();
|
||||
|
@@ -17,6 +17,7 @@ export default {
|
||||
|
||||
export const Default = () => (
|
||||
<EventsBasedObjectEditor
|
||||
eventsFunctionsExtension={testProject.testEventsFunctionsExtension}
|
||||
eventsBasedObject={testProject.testEventsBasedObject}
|
||||
onOpenCustomObjectEditor={action('onOpenCustomObjectEditor')}
|
||||
onEventsBasedObjectChildrenEdited={action(
|
||||
|
Reference in New Issue
Block a user