import {AbstractMesh, MeshBuilder, Observable, Scene, TransformNode, Vector3} from "@babylonjs/core"; import log, {Logger} from "loglevel"; import {AdvancedDynamicTexture, Control, InputText, VirtualKeyboard} from "@babylonjs/gui"; import {Handle} from "../objects/handle"; import {DefaultScene} from "../defaultScene"; import {ControllerEvent} from "../controllers/types/controllerEvent"; import {ControllerEventType} from "../controllers/types/controllerEventType"; export type TextEvent = { id: string; text: string; } export class InputTextView { private logger: Logger = log.getLogger('InputTextView'); public readonly onTextObservable: Observable = new Observable(); private readonly scene: Scene; private readonly inputMesh: AbstractMesh; private readonly controllerObservable: Observable; private readonly handle: Handle; private inputText: InputText; private diagramMesh: AbstractMesh; private keyboard: VirtualKeyboard; constructor(controllerObservable: Observable) { this.controllerObservable = controllerObservable; this.scene = DefaultScene.Scene; this.inputMesh = MeshBuilder.CreatePlane("input", {width: 1, height: .5}, this.scene); this.handle = new Handle({ contentMesh: this.inputMesh, label: 'Input', defaultPosition: new Vector3(0, .4, .5), defaultRotation: new Vector3(0, 0, 0) }); // Position is now controlled by Handle class this.createKeyboard(); } public get handleMesh(): TransformNode { return this.handle.transformNode; } public show(mesh: AbstractMesh) { this.handle.transformNode.setEnabled(true); if (mesh.metadata?.text) { this.inputText.text = mesh.metadata?.text; } else { this.inputText.text = ""; } this.diagramMesh = mesh; this.keyboard.isVisible = true; this.inputText.focus(); this.logger.debug(mesh.metadata); } public createKeyboard() { const advancedTexture = AdvancedDynamicTexture.CreateForMesh(this.inputMesh, 2048, 1024, false); const input = new InputText(); input.width = 0.5; input.maxWidth = 0.5; input.height = "64px"; input.text = ""; input.fontSize = "32px"; input.color = "white"; input.background = "black"; input.thickness = 3; input.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP; this.inputText = input; advancedTexture.addControl(this.inputText); const keyboard = VirtualKeyboard.CreateDefaultLayout(); keyboard.scaleY = 2; keyboard.scaleX = 2; keyboard.transformCenterY = 0; keyboard.transformCenterX = .5; keyboard.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP; keyboard.paddingTop = "70px" keyboard.height = "768px"; keyboard.fontSizeInPixels = 24; advancedTexture.addControl(keyboard); keyboard.connect(input); keyboard.isVisible = true; keyboard.isEnabled = true; keyboard.children.forEach((key) => { key.onPointerEnterObservable.add((eventData, eventState) => { this.logger.debug(eventData); const gripId = eventState?.userInfo?.pickInfo?.gripTransform?.id; if (gripId) { this.controllerObservable.notifyObservers({ type: ControllerEventType.PULSE, gripId: gripId }); } }, -1, false, this, false); }); keyboard.onPointerDownObservable.add(() => { /*this.sounds.tick.play();*/ }); keyboard.onKeyPressObservable.add((key) => { if (key === '↵') { if (this.inputText.text && this.inputText.text.length > 0) { this.logger.error(this.inputText.text); this.onTextObservable.notifyObservers({id: this.diagramMesh.id, text: this.inputText.text}); } else { this.onTextObservable.notifyObservers({id: this.diagramMesh.id, text: null}); } this.hide(); } }, -1, false, this, false); this.keyboard = keyboard; this.handle.transformNode.setEnabled(false); } private hide() { this.handle.transformNode.setEnabled(false); this.diagramMesh = null; } }