344 lines · 12.5 KB · JavaScript
RawDownload
"use strict"; ////  tabletUI.js////  scripts/system/tablet-ui/////  Created by Seth Alves 2016-9-29//  Copyright 2016 High Fidelity, Inc.//  Copyright 2023 Overte e.V.////  Distributed under the Apache License, Version 2.0.//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html// /* global Script, HMD, WebTablet, UIWebTablet, UserActivityLogger, Settings, Entities, Messages, Tablet, Overlays,   MyAvatar, Menu, AvatarInputs, Vec3, cleanUpOldMaterialEntities */ (function() { // BEGIN LOCAL_SCOPE    var controllerStandard = Controller.Standard;     var tabletRezzed = false;    var activeHand = null;    var DEFAULT_WIDTH = 0.4375;    var DEFAULT_DESKTOP_TABLET_SCALE = 75;    var DEFAULT_HMD_TABLET_SCALE = 60;    var preMakeTime = Date.now();    var validCheckTime = Date.now();    var debugTablet = false;    var tabletScalePercentage = DEFAULT_HMD_TABLET_SCALE;    var UIWebTablet = null;    var MSECS_PER_SEC = 1000.0;    var MUTE_MICROPHONE_MENU_ITEM = "Mute Microphone";    var gTablet = null;     Script.include("../libraries/WebTablet.js");     function cleanupMaterialEntities() {        if (Window.isPhysicsEnabled()) {            cleanUpOldMaterialEntities();            return;        }        Script.setTimeout(cleanupMaterialEntities, 100);    }     function checkTablet() {        if (gTablet === null) {            gTablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");        }    }     function tabletIsValid() {        if (!UIWebTablet) {            return false;        }        if (Entities.getEntityProperties(HMD.tabletID, ["type"]).type !== "Model") {            if (debugTablet) {                print("TABLET is invalid due to frame: " + JSON.stringify(Entities.getEntityProperties(HMD.tabletID, ["type"]).type));            }            return false;        }        if (Entities.getEntityProperties(HMD.homeButtonID, ["type"]).type !== "Gizmo" ||                Entities.getEntityProperties(HMD.tabletScreenID, ["type"]).type !== "Web") {            if (debugTablet) {                print("TABLET is invalid due to other");            }            return false;        }        return true;    }     function getTabletScalePercentageFromSettings() {        checkTablet();        var toolbarMode = gTablet.toolbarMode;        var tabletScalePercentage = DEFAULT_HMD_TABLET_SCALE;        if (!toolbarMode) {            if (HMD.active) {                tabletScalePercentage = Settings.getValue("hmdTabletScale") || DEFAULT_HMD_TABLET_SCALE;            } else {                tabletScalePercentage = Settings.getValue("desktopTabletScale") || DEFAULT_DESKTOP_TABLET_SCALE;            }        }        return tabletScalePercentage;    }     function updateTabletWidthFromSettings(force) {        var newTabletScalePercentage = getTabletScalePercentageFromSettings();        if ((force || (newTabletScalePercentage !== tabletScalePercentage)) && UIWebTablet) {            tabletScalePercentage = newTabletScalePercentage;            UIWebTablet.setWidth(DEFAULT_WIDTH * (tabletScalePercentage / 100));        }    }     function onHmdChanged() {        updateTabletWidthFromSettings();    }     function onSensorToWorldScaleChanged(sensorScaleFactor) {        if (HMD.active) {            var newTabletScalePercentage = getTabletScalePercentageFromSettings();            resizeTablet(DEFAULT_WIDTH * (newTabletScalePercentage / 100), undefined, sensorScaleFactor);        }    }     function rezTablet() {        if (debugTablet) {            print("TABLET rezzing");        }        checkTablet()         tabletScalePercentage = getTabletScalePercentageFromSettings();        UIWebTablet = new WebTablet("hifi/tablet/TabletRoot.qml",                                    DEFAULT_WIDTH * (tabletScalePercentage / 100),                                    null, activeHand, null, false);        UIWebTablet.register();        HMD.tabletID = UIWebTablet.tabletEntityID;        HMD.homeButtonID = UIWebTablet.homeButtonID;        HMD.tabletScreenID = UIWebTablet.webOverlayID;        HMD.homeButtonHighlightID = UIWebTablet.homeButtonHighlightID;        HMD.displayModeChanged.connect(onHmdChanged);        MyAvatar.sensorToWorldScaleChanged.connect(onSensorToWorldScaleChanged);         tabletRezzed = true;    }     function showTabletUI() {        checkTablet();         if (!tabletRezzed || !tabletIsValid()) {            closeTabletUI();            rezTablet();        }         if (UIWebTablet && tabletRezzed) {            if (debugTablet) {                print("TABLET in showTabletUI, already rezzed");            }            var tabletProperties = {};            if (!HMD.tabletContextualMode) { // contextual mode forces tablet in place -> don't update attachment                UIWebTablet.calculateTabletAttachmentProperties(activeHand, true, tabletProperties);            }            tabletProperties.visible = true;            tabletProperties.ignorePickIntersection = false;            Entities.editEntity(HMD.tabletID, tabletProperties);            Entities.editEntity(HMD.homeButtonID, { "visible": true, "ignorePickIntersection": false });            Entities.editEntity(HMD.homeButtonHighlightID, { "visible": true, "ignorePickIntersection": false });            Entities.editEntity(HMD.tabletScreenID, { "visible": true, "ignorePickIntersection": false, "maxFPS": 90 });            updateTabletWidthFromSettings(true);        }        gTablet.tabletShown = true;    }     function hideTabletUI() {        checkTablet()        gTablet.tabletShown = false;        if (!UIWebTablet) {            return;        }         if (debugTablet) {            print("TABLET hide");        }         Entities.editEntity(HMD.tabletID, { "visible": false, "ignorePickIntersection": true });        Entities.editEntity(HMD.homeButtonID, { "visible": false, "ignorePickIntersection": true });        Entities.editEntity(HMD.homeButtonHighlightID, { "visible": false, "ignorePickIntersection": true });        Entities.editEntity(HMD.tabletScreenID, { "visible": false, "ignorePickIntersection": true, "maxFPS": 1 });    }     function closeTabletUI() {        checkTablet();        gTablet.tabletShown = false;        if (UIWebTablet) {            if (UIWebTablet.onClose) {                UIWebTablet.onClose();            }             if (debugTablet) {                print("TABLET close");            }            UIWebTablet.unregister();            UIWebTablet.destroy();            UIWebTablet = null;            HMD.tabletID = null;            HMD.homeButtonID = null;            HMD.homeButtonHighlightID = null;            HMD.tabletScreenID = null;        } else if (debugTablet) {            print("TABLET closeTabletUI, UIWebTablet is null");        }        tabletRezzed = false;        gTablet = null;    }      function updateShowTablet() {        var now = Date.now();         checkTablet();         // close the WebTablet if it we go into toolbar mode.        var tabletShown = gTablet.tabletShown;        var toolbarMode = gTablet.toolbarMode;        var landscape = gTablet.landscape;         if (tabletShown && toolbarMode) {            closeTabletUI();            HMD.closeTablet();            return;        }         var needInstantUpdate = UIWebTablet && UIWebTablet.getLandscape() !== landscape;         if ((now - validCheckTime > MSECS_PER_SEC) || needInstantUpdate) {            validCheckTime = now;             updateTabletWidthFromSettings();             if (UIWebTablet) {                UIWebTablet.setLandscape(landscape);            }            if (tabletRezzed && UIWebTablet && !tabletIsValid()) {                // when we switch domains, the tablet entity gets destroyed and recreated.  this causes                // the overlay to be deleted, but not recreated.  If the overlay is deleted for this or any                // other reason, close the tablet.                closeTabletUI();                HMD.closeTablet();                if (debugTablet) {                    print("TABLET autodestroying");                }            }        }         // check for change in tablet scale.         if (HMD.showTablet && !tabletShown && !toolbarMode) {            UserActivityLogger.openedTablet(false);            showTabletUI();        } else if (!HMD.showTablet && tabletShown) {            UserActivityLogger.closedTablet();            hideTabletUI();        }         // if the tablet is an overlay, attempt to pre-create it and then hide it so that when it's        // summoned, it will appear quickly.        if (!toolbarMode) {            if (now - preMakeTime > MSECS_PER_SEC) {                preMakeTime = now;                if (!tabletIsValid()) {                    closeTabletUI();                    rezTablet();                    tabletShown = false;                     // also cause the stylus model to be loaded                    var tmpStylusID = Entities.addEntity({                                               "type": "Model",                                               "name": "stylus",                                               "modelURL": Script.resourcesPath() + "meshes/tablet-stylus-fat.fbx",                                               "position": Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, {"x": 0, "y": 0.1, "z": -2})),                                               "dimensions": { "x": 0.01, "y": 0.01, "z": 0.2 },                                               "primitiveMode": "solid",                                               "visible": true,                                               "ignorePickIntersection": true,                                               "renderLayer": "world",                                               "fadeInMode": "disabled",                                               "fadeOutMode": "disabled",                                               "lifetime": 3                                       }, "local");                    Script.setTimeout(function() {                        Entities.deleteEntity(tmpStylusID);                    }, 300);                } else if (!tabletShown) {                    hideTabletUI();                }            }        }     }     function handleMessage(channel, hand, senderUUID, localOnly) {        if (channel === "toggleHand") {            activeHand = JSON.parse(hand);        }        if (channel === "home") {            if (UIWebTablet) {                checkTablet();                gTablet.landscape = false;            }        }    }     Messages.subscribe("toggleHand");    Messages.subscribe("home");    Messages.messageReceived.connect(handleMessage);     var clickMapping = Controller.newMapping('tabletToggle-click');    var wantsMenu = 0;    clickMapping.from(function () { return wantsMenu; }).to(Controller.Actions.ContextMenu);    clickMapping.from(controllerStandard.RightSecondaryThumb).peek().when(Controller.Hardware.Application.LeftHandDominant).to(function (clicked) {    if (clicked) {        //activeHudPoint2d(controllerStandard.RightHand);        Messages.sendLocalMessage("toggleHand", controllerStandard.RightHand);    }        wantsMenu = clicked;    });        clickMapping.from(controllerStandard.LeftSecondaryThumb).peek().when(Controller.Hardware.Application.RightHandDominant).to(function (clicked) {        if (clicked) {            //activeHudPoint2d(controllerStandard.LeftHand);            Messages.sendLocalMessage("toggleHand", controllerStandard.LeftHand);        }        wantsMenu = clicked;    });     clickMapping.from(controllerStandard.Start).peek().to(function (clicked) {    if (clicked) {        //activeHudPoint2dGamePad();        var noHands = -1;        Messages.sendLocalMessage("toggleHand", controllerStandard.LeftHand);    }         wantsMenu = clicked;    });    clickMapping.enable();     Script.setInterval(updateShowTablet, 100);     Script.scriptEnding.connect(function () {         // if we reload scripts in tablet mode make sure we close the currently open window, by calling gotoHomeScreen        var tabletProxy = Tablet.getTablet("com.highfidelity.interface.tablet.system");        if (tabletProxy && tabletProxy.toolbarMode) {            tabletProxy.gotoHomeScreen();        }         var tabletID = HMD.tabletID;        Entities.deleteEntity(tabletID);        HMD.tabletID = null;        HMD.homeButtonID = null;        HMD.homeButtonHighlightID = null;        HMD.tabletScreenID = null;    });    Script.setTimeout(cleanupMaterialEntities, 100);}()); // END LOCAL_SCOPE