ShatteredSword/src/Nodes/UIElements/Label.ts
2021-01-13 13:30:45 -05:00

132 lines
3.4 KiB
TypeScript

import Vec2 from "../../DataTypes/Vec2";
import Color from "../../Utils/Color";
import UIElement from "../UIElement";
/** A basic text-containing label */
export default class Label extends UIElement{
/** The color of the text of this UIElement */
textColor: Color;
/** The value of the text of this UIElement */
text: string;
/** The name of the font */
protected font: string;
/** The size of the font */
protected fontSize: number;
/** The horizontal alignment of the text within the label */
protected hAlign: string;
/** The vertical alignment of text within the label */
protected vAlign: string;
/** A flag for if the width of the text has been measured on the canvas for auto width assignment */
protected sizeAssigned: boolean;
constructor(position: Vec2, text: string){
super(position);
this.text = text;
this.textColor = new Color(0, 0, 0, 1);
this.font = "Arial";
this.fontSize = 30;
this.hAlign = "center";
this.vAlign = "center";
this.sizeAssigned = false;
}
// @deprecated
setText(text: string): void {
this.text = text;
}
// @deprecated
setTextColor(color: Color): void {
this.textColor = color;
}
/**
* Gets a string containg the font details for rendering
* @returns A string containing the font details
*/
getFontString(): string {
return this.fontSize + "px " + this.font;
}
/**
* Overridable method for calculating text color - useful for elements that want to be colored on different after certain events
* @returns a string containg the text color
*/
calculateTextColor(): string {
return this.textColor.toStringRGBA();
}
/**
* Uses the canvas to calculate the width of the text
* @param ctx The rendering context
* @returns A number representing the rendered text width
*/
protected calculateTextWidth(ctx: CanvasRenderingContext2D): number {
ctx.font = this.fontSize + "px " + this.font;
return ctx.measureText(this.text).width;
}
/**
* Calculate the offset of the text - this is used for rendering text with different alignments
* @param ctx The rendering context
* @returns The offset of the text in a Vec2
*/
calculateTextOffset(ctx: CanvasRenderingContext2D): Vec2 {
let textWidth = this.calculateTextWidth(ctx);
let offset = new Vec2(0, 0);
let hDiff = this.size.x - textWidth;
if(this.hAlign === "center"){
offset.x = hDiff/2;
} else if (this.hAlign === "right"){
offset.x = hDiff;
}
if(this.vAlign === "top"){
ctx.textBaseline = "top";
offset.y = 0;
} else if (this.vAlign === "bottom"){
ctx.textBaseline = "bottom";
offset.y = this.size.y;
} else {
ctx.textBaseline = "middle";
offset.y = this.size.y/2;
}
return offset;
}
protected sizeChanged(): void {
super.sizeChanged();
this.sizeAssigned = true;
}
/**
* Automatically sizes the element to the text within it
* @param ctx The rendering context
*/
protected autoSize(ctx: CanvasRenderingContext2D): void {
let width = this.calculateTextWidth(ctx);
let height = this.fontSize;
this.size.set(width + this.padding.x*2, height + this.padding.y*2);
this.sizeAssigned = true;
}
/**
* Initially assigns a size to the UIElement if none is provided
* @param ctx The rendering context
*/
handleInitialSizing(ctx: CanvasRenderingContext2D): void {
if(!this.sizeAssigned){
this.autoSize(ctx);
}
}
/** On the next render, size this element to it's current text using its current font size */
sizeToText(): void {
this.sizeAssigned = false;
}
}