/* * GDevelop JS Platform * 2013-2016 Florian Rival (Florian.Rival@gmail.com) */ namespace gdjs { /** Base parameters for gdjs.TextRuntimeObject */ export type TextObjectDataType = { /** The size of the characters */ characterSize: number; /** The font name */ font: string; /** Is Bold? */ bold: boolean; /** Is Italic? */ italic: boolean; /** Is Underlined? */ underlined: boolean; /** The text color in an RGB representation */ color: { /** The Red level from 0 to 255 */ r: number; /** The Green level from 0 to 255 */ g: number; /** The Blue level from 0 to 255 */ b: number; }; /** The text of the object */ string: string; textAlignment: string; }; export type TextObjectData = ObjectData & TextObjectDataType; /** * Displays a text. */ export class TextRuntimeObject extends gdjs.RuntimeObject { _characterSize: number; _fontName: string; _bold: boolean; _italic: boolean; _underlined: boolean; _color: integer[]; _useGradient: boolean = false; _gradient: Array> = []; _gradientType: string = ''; opacity: float = 255; _textAlign: string = 'left'; _wrapping: boolean = false; _wrappingWidth: float = 1; _outlineThickness: number = 0; _outlineColor: integer[] = [255, 255, 255]; _shadow: boolean = false; _shadowColor: integer[] = [0, 0, 0]; _shadowDistance: number = 1; _shadowBlur: integer = 1; _shadowAngle: float = 0; _padding: integer = 5; _str: string; _renderer: gdjs.TextRuntimeObjectRenderer; // We can store the scale as nothing else can change it. _scaleX: number = 1; _scaleY: number = 1; /** * @param instanceContainer The container the object belongs to. * @param textObjectData The initial properties of the object */ constructor( instanceContainer: gdjs.RuntimeInstanceContainer, textObjectData: TextObjectData ) { super(instanceContainer, textObjectData); this._characterSize = Math.max(1, textObjectData.characterSize); this._fontName = textObjectData.font; this._bold = textObjectData.bold; this._italic = textObjectData.italic; this._underlined = textObjectData.underlined; this._color = [ textObjectData.color.r, textObjectData.color.g, textObjectData.color.b, ]; this._str = textObjectData.string; this._textAlign = textObjectData.textAlignment; this._renderer = new gdjs.TextRuntimeObjectRenderer( this, instanceContainer ); // *ALWAYS* call `this.onCreated()` at the very end of your object constructor. this.onCreated(); } updateFromObjectData( oldObjectData: TextObjectData, newObjectData: TextObjectData ): boolean { if (oldObjectData.characterSize !== newObjectData.characterSize) { this.setCharacterSize(newObjectData.characterSize); } if (oldObjectData.font !== newObjectData.font) { this.setFontName(newObjectData.font); } if (oldObjectData.bold !== newObjectData.bold) { this.setBold(newObjectData.bold); } if (oldObjectData.italic !== newObjectData.italic) { this.setItalic(newObjectData.italic); } if ( oldObjectData.color.r !== newObjectData.color.r || oldObjectData.color.g !== newObjectData.color.g || oldObjectData.color.b !== newObjectData.color.b ) { this.setColor( '' + newObjectData.color.r + ';' + newObjectData.color.g + ';' + newObjectData.color.b ); } if (oldObjectData.string !== newObjectData.string) { this.setString(newObjectData.string); } if (oldObjectData.underlined !== newObjectData.underlined) { return false; } if (oldObjectData.textAlignment !== newObjectData.textAlignment) { this.setTextAlignment(newObjectData.textAlignment); } return true; } getRendererObject() { return this._renderer.getRendererObject(); } update(instanceContainer: gdjs.RuntimeInstanceContainer): void { this._renderer.ensureUpToDate(); } /** * Initialize the extra parameters that could be set for an instance. */ extraInitializationFromInitialInstance(initialInstanceData: InstanceData) { if (initialInstanceData.customSize) { this.setWrapping(true); this.setWrappingWidth(initialInstanceData.width); } else { this.setWrapping(false); } } /** * Update the rendered object position. */ private _updateTextPosition() { this.invalidateHitboxes(); this._renderer.updatePosition(); } /** * Set object position on X axis. */ setX(x): void { super.setX(x); this._updateTextPosition(); } /** * Set object position on Y axis. */ setY(y): void { super.setY(y); this._updateTextPosition(); } /** * Set the angle of the object. * @param angle The new angle of the object */ setAngle(angle: float): void { super.setAngle(angle); this._renderer.updateAngle(); } /** * Set object opacity. */ setOpacity(opacity): void { if (opacity < 0) { opacity = 0; } if (opacity > 255) { opacity = 255; } this.opacity = opacity; this._renderer.updateOpacity(); } /** * Get object opacity. */ getOpacity() { return this.opacity; } /** * Get the string displayed by the object. */ getString(): string { return this._str; } /** * Set the string displayed by the object. * @param str The new text */ setString(str: string): void { if (str === this._str) { return; } this._str = str; this._renderer.updateString(); this._updateTextPosition(); } /** * Get the font size of the characters of the object. */ getCharacterSize(): number { return this._characterSize; } /** * Set the font size for characters of the object. * @param newSize The new font size for the text. */ setCharacterSize(newSize: number): void { if (newSize <= 1) { newSize = 1; } this._characterSize = newSize; this._renderer.updateStyle(); } /** * Set the name of the resource to use for the font. * @param fontResourceName The name of the font resource. */ setFontName(fontResourceName: string): void { this._fontName = fontResourceName; this._renderer.updateStyle(); } /** * Return true if the text is bold. */ isBold(): boolean { return this._bold; } /** * Set bold for the object text. * @param enable {boolean} true to have a bold text, false otherwise. */ setBold(enable): void { this._bold = enable; this._renderer.updateStyle(); } /** * Return true if the text is italic. */ isItalic(): boolean { return this._italic; } /** * Set italic for the object text. * @param enable {boolean} true to have an italic text, false otherwise. */ setItalic(enable): void { this._italic = enable; this._renderer.updateStyle(); } /** * Get width of the text. */ getWidth(): float { return this._wrapping ? this._wrappingWidth : this._renderer.getWidth(); } /** * Get height of the text. */ getHeight(): float { return this._renderer.getHeight(); } /** * Get scale of the text. */ getScale(): float { return (Math.abs(this._scaleX) + Math.abs(this._scaleY)) / 2.0; } /** * Get x-scale of the text. */ getScaleX(): float { return this._scaleX; } /** * Get y-scale of the text. */ getScaleY(): float { return this._scaleY; } /** * Set the text object scale. * @param newScale The new scale for the text object. */ setScale(newScale: float): void { if (this._scaleX === newScale && this._scaleY === newScale) return; this._scaleX = newScale; this._scaleY = newScale; this._renderer.setScale(newScale); this.invalidateHitboxes(); } /** * Set the text object x-scale. * @param newScale The new x-scale for the text object. */ setScaleX(newScale: float): void { if (this._scaleX === newScale) return; this._scaleX = newScale; this._renderer.setScaleX(newScale); this.invalidateHitboxes(); } /** * Set the text object y-scale. * @param newScale The new y-scale for the text object. */ setScaleY(newScale: float): void { if (this._scaleY === newScale) return; this._scaleY = newScale; this._renderer.setScaleY(newScale); this.invalidateHitboxes(); } /** * Change the text color. * @param color color as a "R;G;B" string, for example: "255;0;0" */ setColor(str: string): void { const color = str.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); this._useGradient = false; this._renderer.updateStyle(); } /** * Get the text color. * @return The color as a "R;G;B" string, for example: "255;0;0" */ getColor(): string { return this._color[0] + ';' + this._color[1] + ';' + this._color[2]; } /** * Set the text alignment for multiline text objects. * @param alignment The text alignment. */ setTextAlignment(alignment: string): void { this._textAlign = alignment; this._renderer.updateStyle(); } /** * Get the text alignment of text object. * @return The text alignment. */ getTextAlignment(): string { return this._textAlign; } /** * Return true if word wrapping is enabled for the text. */ isWrapping(): boolean { return this._wrapping; } /** * Set word wrapping for the object text. * @param enable true to enable word wrapping, false to disable it. */ setWrapping(enable: boolean): void { if (this._wrapping === enable) return; this._wrapping = enable; this._renderer.updateStyle(); this.invalidateHitboxes(); } /** * Get the word wrapping width for the text object. */ getWrappingWidth(): float { return this._wrappingWidth; } /** * Set the word wrapping width for the text object. * @param width The new width to set. */ setWrappingWidth(width: float): void { if (width <= 1) { width = 1; } if (this._wrappingWidth === width) return; this._wrappingWidth = width; this._renderer.updateStyle(); this.invalidateHitboxes(); } /** * Set the outline for the text object. * @param str color as a "R;G;B" string, for example: "255;0;0" * @param thickness thickness of the outline (0 = disabled) */ 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); this._outlineThickness = thickness; this._renderer.updateStyle(); } /** * Set the shadow for the text object. * @param str 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. */ setShadow( str: 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._shadowDistance = distance; this._shadowBlur = blur; this._shadowAngle = angle; this._shadow = true; this._renderer.updateStyle(); } /** * Set the gradient for the text object. * @param strFirstColor color as a "R;G;B" string, for example: "255;0;0" * @param strSecondColor color as a "R;G;B" string, for example: "255;0;0" * @param strThirdColor color as a "R;G;B" string, for example: "255;0;0" * @param strFourthColor color as a "R;G;B" string, for example: "255;0;0" * @param strGradientType gradient type */ setGradient( strGradientType: string, strFirstColor: string, strSecondColor: string, 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 (colorSecond.length == 3) { this._gradient.push([ parseInt(colorSecond[0], 10), parseInt(colorSecond[1], 10), parseInt(colorSecond[2], 10), ]); } if (colorThird.length == 3) { this._gradient.push([ parseInt(colorThird[0], 10), parseInt(colorThird[1], 10), parseInt(colorThird[2], 10), ]); } if (colorFourth.length == 3) { this._gradient.push([ parseInt(colorFourth[0], 10), parseInt(colorFourth[1], 10), parseInt(colorFourth[2], 10), ]); } this._gradientType = strGradientType; this._useGradient = this._gradient.length > 1 ? true : false; this._renderer.updateStyle(); } /** * Show the shadow of the text object. * @param enable true to show the shadow, false to hide it */ showShadow(enable: boolean): void { this._shadow = enable; this._renderer.updateStyle(); } /** * Get padding of the text object. * @return number of pixels around the text before it gets cropped */ getPadding(): number { return this._padding; } /** * Set padding of the text object. * @param value number of pixels around the text before it gets cropped */ setPadding(value: float): void { this._padding = value; this._renderer.updateStyle(); } } gdjs.registerObject('TextObject::Text', gdjs.TextRuntimeObject); }