diff --git a/interface/resources/qml/hifi/SpectatorCamera.qml b/interface/resources/qml/hifi/SpectatorCamera.qml index 1e8072c472..8dfea22e2e 100644 --- a/interface/resources/qml/hifi/SpectatorCamera.qml +++ b/interface/resources/qml/hifi/SpectatorCamera.qml @@ -22,14 +22,209 @@ import "../controls" as HifiControls Rectangle { id: spectatorCamera; // Size - width: parent.width; - height: parent.height; // Style - color: "#E3E3E3"; + color: "#FFFFFF"; // Properties HifiConstants { id: hifi; } + + // + // TITLE BAR START + // + Item { + id: titleBarContainer; + // Size + width: spectatorCamera.width; + height: 50; + // Anchors + anchors.left: parent.left; + anchors.top: parent.top; + // "Spectator" text + RalewayRegular { + id: titleBarText; + text: "Spectator"; + // Text size + size: hifi.fontSizes.overlayTitle; + // Anchors + anchors.fill: parent; + anchors.leftMargin: 16; + // Style + color: hifi.colors.darkGray; + // Alignment + horizontalAlignment: Text.AlignHLeft; + verticalAlignment: Text.AlignVCenter; + } + + // Separator + Rectangle { + // Size + width: parent.width; + height: 1; + // Anchors + anchors.left: parent.left; + anchors.bottom: parent.bottom; + // Style + color: hifi.colors.faintGray; + } + } + // + // TITLE BAR END + // + + // + // SPECTATOR APP DESCRIPTION START + // + Item { + id: spectatorDescriptionContainer; + // Size + width: spectatorCamera.width; + height: childrenRect.height; + // Anchors + anchors.left: parent.left; + anchors.top: titleBarContainer.bottom; + + // (i) Glyph + HiFiGlyphs { + id: spectatorDescriptionGlyph; + text: hifi.glyphs.info; + // Size + width: 20; + height: parent.height; + size: 48; + // Anchors + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.top: parent.top; + anchors.topMargin: 0; + // Style + color: hifi.colors.blueAccent; + horizontalAlignment: Text.AlignHLeft; + verticalAlignment: Text.AlignVCenter; + } + + // "Spectator" app description text + RalewaySemiBold { + id: spectatorDescriptionText; + text: "Spectator lets you switch what your monitor displays while you're using an HMD."; + // Text size + size: 14; + // Size + width: parent.width - 40 - 60; + height: paintedHeight; + // Anchors + anchors.top: parent.top; + anchors.topMargin: 10; + anchors.left: spectatorDescriptionGlyph.right; + anchors.leftMargin: 30; + // Style + color: hifi.colors.darkGray; + wrapMode: Text.WordWrap; + // Alignment + horizontalAlignment: Text.AlignHLeft; + verticalAlignment: Text.AlignVCenter; + } + + // "Learn More" text + RalewayRegular { + id: spectatorLearnMoreText; + text: "Learn More About Spectator"; + // Text size + size: 14; + // Size + width: paintedWidth; + height: paintedHeight; + // Anchors + anchors.top: spectatorDescriptionText.bottom; + anchors.topMargin: 10; + anchors.left: spectatorDescriptionText.anchors.left; + anchors.leftMargin: spectatorDescriptionText.anchors.leftMargin; + // Style + color: hifi.colors.blueAccent; + wrapMode: Text.WordWrap; + font.underline: true; + // Alignment + horizontalAlignment: Text.AlignHLeft; + verticalAlignment: Text.AlignVCenter; + + MouseArea { + anchors.fill: parent; + hoverEnabled: enabled; + onClicked: { + console.log("FIXME! Add popup pointing to 'Learn More' page"); + } + onEntered: parent.color = hifi.colors.blueHighlight; + onExited: parent.color = hifi.colors.blueAccent; + } + } + + // Separator + Rectangle { + // Size + width: parent.width; + height: 1; + // Anchors + anchors.left: parent.left; + anchors.top: spectatorLearnMoreText.bottom; + anchors.topMargin: spectatorDescriptionText.anchors.topMargin; + // Style + color: hifi.colors.faintGray; + } + } + // + // SPECTATOR APP DESCRIPTION END + // + + + // + // SPECTATOR CONTROLS START + // + Item { + id: spectatorControlsContainer; + // Size + width: spectatorCamera.width; + height: spectatorCamera.height - spectatorDescriptionContainer.height - titleBarContainer.height; + // Anchors + anchors.top: spectatorDescriptionContainer.bottom; + anchors.topMargin: 12; + anchors.left: parent.left; + anchors.leftMargin: 20; + + // "Camera On" Checkbox + HifiControlsUit.CheckBox { + id: cameraToggleCheckBox; + anchors.left: parent.left; + anchors.top: parent.top; + //checked: true; // FIXME + text: "Camera On"; + boxSize: 32; + onCheckedChanged: { + console.log("CAMERA ON: " + checked); + } + } + + // Preview + } + // + // SPECTATOR CONTROLS END + // + + // + // FUNCTION DEFINITIONS START + // + // + // Function Name: fromScript() + // + // Relevant Variables: + // None + // + // Arguments: + // message: The message sent from the SpectatorCamera JavaScript. + // Messages are in format "{method, params}", like json-rpc. + // + // Description: + // Called when a message is received from spectatorCamera.js. + // function fromScript(message) { switch (message.method) { case 'XXX': @@ -38,4 +233,9 @@ Rectangle { console.log('Unrecognized message from spectatorCamera.js:', JSON.stringify(message)); } } + signal sendToScript(var message); + + // + // FUNCTION DEFINITIONS END + // } diff --git a/scripts/system/spectatorCamera.js b/scripts/system/spectatorCamera.js index 7316ead1be..5a226d4eeb 100644 --- a/scripts/system/spectatorCamera.js +++ b/scripts/system/spectatorCamera.js @@ -1,6 +1,6 @@ "use strict"; /*jslint vars:true, plusplus:true, forin:true*/ -/*global Tablet, */ +/*global Tablet, Script, */ /* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ // // spectatorCamera.js @@ -14,44 +14,61 @@ (function () { // BEGIN LOCAL_SCOPE + // + // FUNCTION VAR DECLARATIONS + // + var sendToQml, onTabletScreenChanged, fromQml, onTabletButtonClicked, wireEventBridge, startup, shutdown; // - // Function Name: sendToQml() + // Function Name: startup() // // Relevant Variables: - // None + // button: The tablet button. + // buttonName: The name of the button. + // tablet: The tablet instance to be modified. // // Arguments: - // message: The message to send to the SpectatorCamera QML. - // Messages are in format "{method, params}", like json-rpc. See also fromQml(). + // None // // Description: - // Use this function to send a message to the QML (i.e. to change appearances). + // startup() will be called when the script is loaded. // - function sendToQml(message) { - tablet.sendToQml(message); + var button; + var buttonName = "SPECTATOR"; + var tablet = null; + function startup() { + tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); + button = tablet.addButton({ + text: buttonName + }); + button.clicked.connect(onTabletButtonClicked); + tablet.screenChanged.connect(onTabletScreenChanged); } // - // Function Name: fromQml() + // Function Name: wireEventBridge() // // Relevant Variables: - // None + // hasEventBridge: true/false depending on whether we've already connected the event bridge // // Arguments: - // message: The message sent from the SpectatorCamera QML. - // Messages are in format "{method, params}", like json-rpc. See also sendToQml(). + // on: Enable or disable the event bridge // // Description: - // Called when a message is received from SpectatorCamera.qml. + // Used to connect/disconnect the script's response to the tablet's "fromQml" signal. // - function fromQml(message) { // - var data; - switch (message.method) { - case 'XXX': - break; - default: - print('Unrecognized message from SpectatorCamera.qml:', JSON.stringify(message)); + var hasEventBridge = false; + function wireEventBridge(on) { + if (on) { + if (!hasEventBridge) { + tablet.fromQml.connect(fromQml); + hasEventBridge = true; + } + } else { + if (hasEventBridge) { + tablet.fromQml.disconnect(fromQml); + hasEventBridge = false; + } } } @@ -82,33 +99,6 @@ } } - // - // Function Name: wireEventBridge() - // - // Relevant Variables: - // hasEventBridge: true/false depending on whether we've already connected the event bridge - // - // Arguments: - // on: Enable or disable the event bridge - // - // Description: - // Used to connect/disconnect the script's response to the tablet's "fromQml" signal. - // - var hasEventBridge = false; - function wireEventBridge(on) { - if (on) { - if (!hasEventBridge) { - tablet.fromQml.connect(fromQml); - hasEventBridge = true; - } - } else { - if (hasEventBridge) { - tablet.fromQml.disconnect(fromQml); - hasEventBridge = false; - } - } - } - // // Function Name: onTabletScreenChanged() // @@ -131,29 +121,42 @@ } // - // Function Name: shutdown() + // Function Name: sendToQml() // // Relevant Variables: - // button: The tablet button. - // buttonName: The name of the button. - // tablet: The tablet instance to be modified. - // - // Arguments: // None // + // Arguments: + // message: The message to send to the SpectatorCamera QML. + // Messages are in format "{method, params}", like json-rpc. See also fromQml(). + // // Description: - // startup() will be called when the script is loaded. + // Use this function to send a message to the QML (i.e. to change appearances). // - var button; - var buttonName = "Spectator"; - var tablet = null; - function startup() { - tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); - button = tablet.addButton({ - text: buttonName - }); - button.clicked.connect(onTabletButtonClicked); - tablet.screenChanged.connect(onTabletScreenChanged); + function sendToQml(message) { + tablet.sendToQml(message); + } + + // + // Function Name: fromQml() + // + // Relevant Variables: + // None + // + // Arguments: + // message: The message sent from the SpectatorCamera QML. + // Messages are in format "{method, params}", like json-rpc. See also sendToQml(). + // + // Description: + // Called when a message is received from SpectatorCamera.qml. + // + function fromQml(message) { + switch (message.method) { + case 'XXX': + break; + default: + print('Unrecognized message from SpectatorCamera.qml:', JSON.stringify(message)); + } } //