156 lines
5.5 KiB
TypeScript
156 lines
5.5 KiB
TypeScript
import {MeshBuilder, Observable, Scene, Vector3, WebXRDefaultExperience} from "@babylonjs/core";
|
|
import log, {Logger} from "loglevel";
|
|
import {AdvancedDynamicTexture, Control, InputText, VirtualKeyboard} from "@babylonjs/gui";
|
|
import {ControllerEventType, Controllers} from "../controllers/controllers";
|
|
import {setMenuPosition} from "../util/functions/setMenuPosition";
|
|
import {DiaSounds} from "../util/diaSounds";
|
|
|
|
export type TextEvent = {
|
|
text: string;
|
|
}
|
|
|
|
export class InputTextView {
|
|
public readonly onTextObservable: Observable<TextEvent> = new Observable<TextEvent>();
|
|
private readonly text: string = "";
|
|
private readonly scene: Scene;
|
|
private sounds: DiaSounds;
|
|
private readonly controllers: Controllers;
|
|
private readonly xr: WebXRDefaultExperience;
|
|
private readonly logger: Logger = log.getLogger('InputTextView');
|
|
|
|
constructor(text: string, xr: WebXRDefaultExperience, scene: Scene, controllers: Controllers) {
|
|
this.text = text ? text : "";
|
|
this.xr = xr;
|
|
this.controllers = controllers;
|
|
this.scene = scene;
|
|
this.sounds = new DiaSounds(scene);
|
|
}
|
|
|
|
public show() {
|
|
this.showVirtualKeyboard();
|
|
/*if ((this.xr as WebXRDefaultExperience).baseExperience?.sessionManager?.inXRSession) {
|
|
this.showXr();
|
|
} else {
|
|
this.showWeb();
|
|
}*/
|
|
}
|
|
|
|
public showVirtualKeyboard() {
|
|
|
|
|
|
const inputMesh = MeshBuilder.CreatePlane("input", {width: 1, height: .5}, this.scene);
|
|
const advancedTexture = AdvancedDynamicTexture.CreateForMesh(inputMesh, 2048, 1024, false);
|
|
|
|
const input = new InputText();
|
|
|
|
input.width = 0.5;
|
|
input.maxWidth = 0.5;
|
|
input.height = "64px";
|
|
input.text = this.text;
|
|
|
|
input.fontSize = "32px";
|
|
input.color = "white";
|
|
input.background = "black";
|
|
input.thickness = 3;
|
|
input.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
|
|
advancedTexture.addControl(input);
|
|
|
|
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.controllers.controllerObserver.notifyObservers({
|
|
type: ControllerEventType.PULSE,
|
|
gripId: gripId
|
|
});
|
|
}
|
|
|
|
}, -1, false, this, false);
|
|
});
|
|
|
|
|
|
keyboard.onPointerDownObservable.add(() => {
|
|
this.sounds.tick.play();
|
|
});
|
|
keyboard.onKeyPressObservable.add((key) => {
|
|
if (key === '↵') {
|
|
this.onTextObservable.notifyObservers({text: input.text});
|
|
input.dispose();
|
|
keyboard.dispose();
|
|
advancedTexture.dispose();
|
|
inputMesh.dispose();
|
|
this.sounds.exit.play();
|
|
}
|
|
});
|
|
setMenuPosition(inputMesh, this.scene, new Vector3(0, .4, 0));
|
|
this.sounds.enter.play();
|
|
}
|
|
|
|
public showWeb() {
|
|
const textInput = new InputText('identity', this.text);
|
|
textInput.width = 0.2;
|
|
textInput.height = "40px";
|
|
textInput.color = "white";
|
|
textInput.background = "black";
|
|
textInput.focusedBackground = "black";
|
|
|
|
const advancedTexture = AdvancedDynamicTexture.CreateFullscreenUI("myUI");
|
|
advancedTexture.addControl(textInput);
|
|
textInput.onKeyboardEventProcessedObservable.add((evt) => {
|
|
if (evt.key === 'Enter') {
|
|
this.onTextObservable.notifyObservers({text: textInput.text});
|
|
textInput.dispose();
|
|
advancedTexture.dispose();
|
|
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
private showXr() {
|
|
const textInput = document.createElement("input");
|
|
textInput.type = "text";
|
|
document.body.appendChild(textInput);
|
|
textInput.value = this.text;
|
|
this.controllers.controllerObserver.notifyObservers({type: ControllerEventType.HIDE});
|
|
|
|
/*if (this.xr?.baseExperience?.sessionManager?.inXRSession) {
|
|
this.xr.input.controllers.forEach((controller) => {
|
|
controller.motionController.rootMesh.setEnabled(false);
|
|
controller.pointer.setEnabled(false);
|
|
});
|
|
|
|
}*/
|
|
|
|
textInput.addEventListener('blur', () => {
|
|
log.getLogger('bmenu').debug("blur");
|
|
this.onTextObservable.notifyObservers({text: textInput.value});
|
|
this.controllers.controllerObserver.notifyObservers({type: ControllerEventType.SHOW});
|
|
|
|
/*if (this.xr?.baseExperience?.sessionManager?.inXRSession) {
|
|
this.xr.input.controllers.forEach((controller) => {
|
|
controller.motionController.rootMesh.setEnabled(true);
|
|
controller.pointer.setEnabled(true);
|
|
});
|
|
}*/
|
|
textInput.blur();
|
|
textInput.remove();
|
|
});
|
|
|
|
textInput.focus();
|
|
}
|
|
} |