import {GameElement} from "./GameElement.js";
import {Point, randomColor} from "../Misc.js";
import {GameShape} from "../drawables/GameShape.js";
import {GameText} from "../drawables/GameText.js";
/**
* Text Input class
* @extends GameElement
*
* @property {number} width Width of the text input element
* @property {number} height Height of the text input element
* @property {string} color Background color of the element (default 'aliceblue')
* @property {string} text Text displayed/entered on the element
* @property {string} message Text displayed on the popup. Default 'Enter text'
* @property {Array<function>} onEnter Array of [callback,attribute_object] called on enter text (on popup)
*
*/
class GameTextInput extends GameElement {
#width = undefined
set width(newWidth) {
if (newWidth === undefined) {
this.#width = 150
}
else if (isNaN(newWidth)) {
throw new Error("Entered width value is not a number!")
} else {
this.#width = newWidth
}
//set text width
const text = this.getChildByName("text")
text.maxWidth = this.#width
//set rect width
const rect = this.getChildByName("rect")
rect.width = this.#width
}
get width() {
return this.#width
}
#height = undefined
set height(newHeight) {
if (newHeight === undefined) {
this.#height = 30
}
else if (isNaN(newHeight)) {
throw new Error("Entered height value is not a number!")
}
else {
this.#height = newHeight
}
//set rect height
const rect = this.getChildByName("rect")
rect.height = this.#height
}
get height() {
return this.#height
}
#color = undefined
set color(newColor) {
if (newColor === undefined) {
this.#color = 'aliceblue'
}
else if (newColor === "random") {
this.#color = randomColor()
}
else {
this.#color = newColor
}
//set rect color
const rect = this.getChildByName("rect")
rect.fill = this.#color
}
get color() {
return this.#color
}
#text = undefined
set text(newText) {
this.#text = (newText === undefined) ? "" : newText;
//pass text to element
const text = this.getChildByName("text")
text.text = this.#text
}
get text() {
return this.#text
}
#onEnter = []
get onEnter() {return [...this.#onEnter]}
#clickOnInput = (event) => {
const entered = window.prompt(this.message, this.text);
if (entered === null) {
return
}
this.text = entered
for (const callback of this.#onEnter) {
callback.call(this,event)
}
}
/**
* Constructor for Text Input element
* @param {Point} center Center point of the element
* @param {Object} attrs Attribute object
*/
constructor(center,attrs={}) {
super(center,[],attrs)
// init elements
this.#onEnter = (Array.isArray(attrs.onEnter)) ? attrs.onEnter : []
const text = new GameText("",{level:0,name:"text"})
this.addChild(text)
const rectangle = new GameShape('rectangle',{
width:0,
height:0,
level:-1,
stroke: 'black',
lineWidth: 1,
name: "rect"
}
)
this.addChild(rectangle)
//init attributes
this.text = attrs.text
this.width = attrs.width
this.height = attrs.height
this.color = attrs.color;
this.message = (attrs.message === undefined) ? 'Enter text' : attrs.message;
this.clickable = true
this.addOnClickListener(this.#clickOnInput)
}
/**
* Adds a listener to the array of listeners for onEnter
* @param {function} callback function to be called
*/
addOnEnterTextListener(callback) {
this.#onEnter.push(callback)
}
/**
* Removes listener for the onEnterText event
* @param {function} callback function you want to remove
*/
removeOnEnterTextListener(callback) {
this.#onEnter = this.#onEnter.filter(item=>item!==callback)
}
/**
* Returns object of attributes of current instance.
* @returns {Object} Attribute object.
*/
getAttrs() {
return Object.assign({
width: this.width,
height: this.height,
color: this.color,
text: this.text,
message: this.message,
},super.getAttrs())
}
/**
* Returns copy of current instance.
* @param {string} newName Name of the newly created instance. Names have to be unique.
* @returns {GameTextInput} New instance with the same attributes.
*/
copy(newName) {
const attrs = this.getAttrs()
if (newName === undefined) {
attrs.name = (attrs.name === undefined) ? undefined : attrs.name + "_copy"
} else {
attrs.name = newName
}
return new GameTextInput(attrs.center,attrs)
}
}
export {GameTextInput}