mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 18:55:01 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into bugz516
This commit is contained in:
commit
790d4edb04
36 changed files with 515 additions and 177 deletions
|
@ -88,7 +88,7 @@ Rectangle {
|
|||
|
||||
Image {
|
||||
id: accent
|
||||
source: "../images/accent.svg"
|
||||
source: "images/accent.svg"
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
width: 60
|
||||
|
|
Before Width: | Height: | Size: 268 B After Width: | Height: | Size: 268 B |
|
@ -165,11 +165,21 @@ Rectangle {
|
|||
}
|
||||
|
||||
Image {
|
||||
source: "../images/accent.svg"
|
||||
source: {
|
||||
if (root.activeTabView === "generalTabView") {
|
||||
"images/accent1.svg"
|
||||
} else if (root.activeTabView === "audioTabView") {
|
||||
"images/accent2.svg"
|
||||
} else if (root.activeTabView === "vrTabView") {
|
||||
"images/accent3.svg"
|
||||
} else {
|
||||
"images/accent3.svg"
|
||||
}
|
||||
}
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
width: 94
|
||||
height: 175
|
||||
anchors.top: tabContainer.bottom
|
||||
width: 106
|
||||
height: 200
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ Flickable {
|
|||
Layout.preferredWidth: parent.width
|
||||
spacing: 0
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
HifiStylesUit.GraphikSemiBold {
|
||||
id: volumeControlsTitle
|
||||
text: "Volume Controls"
|
||||
Layout.preferredWidth: parent.width
|
||||
|
@ -154,7 +154,7 @@ Flickable {
|
|||
Layout.preferredWidth: parent.width
|
||||
spacing: 0
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
HifiStylesUit.GraphikSemiBold {
|
||||
id: micControlsTitle
|
||||
text: "Default Mute Controls"
|
||||
Layout.maximumWidth: parent.width
|
||||
|
@ -196,7 +196,7 @@ Flickable {
|
|||
Layout.preferredWidth: parent.width
|
||||
spacing: 0
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
HifiStylesUit.GraphikSemiBold {
|
||||
id: inputDeviceTitle
|
||||
text: "Which input device?"
|
||||
Layout.maximumWidth: parent.width
|
||||
|
@ -291,7 +291,7 @@ Flickable {
|
|||
Layout.preferredWidth: parent.width
|
||||
spacing: 0
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
HifiStylesUit.GraphikSemiBold {
|
||||
id: outputDeviceTitle
|
||||
text: "Which output device?"
|
||||
Layout.maximumWidth: parent.width
|
||||
|
|
|
@ -47,7 +47,7 @@ Flickable {
|
|||
Layout.preferredWidth: parent.width
|
||||
spacing: 0
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
HifiStylesUit.GraphikSemiBold {
|
||||
id: uiControlsTitle
|
||||
text: "User Interface"
|
||||
Layout.maximumWidth: parent.width
|
||||
|
|
|
@ -51,7 +51,7 @@ Flickable {
|
|||
Layout.preferredWidth: parent.width
|
||||
spacing: 0
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
HifiStylesUit.GraphikSemiBold {
|
||||
id: avatarNameTagsTitle
|
||||
text: "Avatar Name Tags"
|
||||
Layout.maximumWidth: parent.width
|
||||
|
@ -99,7 +99,7 @@ Flickable {
|
|||
Layout.preferredWidth: parent.width
|
||||
spacing: 0
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
HifiStylesUit.GraphikSemiBold {
|
||||
id: performanceTitle
|
||||
text: "Graphics Settings"
|
||||
Layout.maximumWidth: parent.width
|
||||
|
@ -147,7 +147,7 @@ Flickable {
|
|||
Layout.preferredWidth: parent.width
|
||||
spacing: 0
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
HifiStylesUit.GraphikSemiBold {
|
||||
id: cameraTitle
|
||||
text: "Camera View"
|
||||
Layout.maximumWidth: parent.width
|
||||
|
@ -199,7 +199,7 @@ Flickable {
|
|||
wrapMode: Text.Wrap
|
||||
width: paintedWidth
|
||||
height: paintedHeight
|
||||
size: 22
|
||||
size: 14
|
||||
color: simplifiedUI.colors.text.lightBlue
|
||||
|
||||
MouseArea {
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="106" height="200" viewBox="0 0 106 200" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 0L106 -9.26681e-06L83.1739 10.0481L0 0Z" fill="#FFED00"/>
|
||||
<path d="M83.1738 10.0481L106 -1.99552e-06L106 200L83.1738 10.0481Z" fill="#FF42A7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 263 B |
|
@ -0,0 +1,4 @@
|
|||
<svg width="106" height="200" viewBox="0 0 106 200" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 0L106 -9.26681e-06L83.1739 10.0481L0 0Z" fill="#FF42A7"/>
|
||||
<path d="M83.1738 10.0481L106 -1.99552e-06L106 200L83.1738 10.0481Z" fill="#009EE0"/>
|
||||
</svg>
|
After Width: | Height: | Size: 263 B |
|
@ -0,0 +1,4 @@
|
|||
<svg width="106" height="200" viewBox="0 0 106 200" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 0L106 -9.26681e-06L83.1739 10.0481L0 0Z" fill="#009EE0"/>
|
||||
<path d="M83.1738 10.0481L106 -1.99552e-06L106 200L83.1738 10.0481Z" fill="#FFED00"/>
|
||||
</svg>
|
After Width: | Height: | Size: 263 B |
|
@ -57,7 +57,7 @@ Flickable {
|
|||
Layout.preferredWidth: parent.width
|
||||
spacing: 0
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
HifiStylesUit.GraphikSemiBold {
|
||||
id: controlsTitle
|
||||
text: "VR Movement Controls"
|
||||
Layout.maximumWidth: parent.width
|
||||
|
@ -143,7 +143,7 @@ Flickable {
|
|||
Layout.preferredWidth: parent.width
|
||||
spacing: 0
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
HifiStylesUit.GraphikSemiBold {
|
||||
id: micControlsTitle
|
||||
text: "Default Mute Controls"
|
||||
Layout.maximumWidth: parent.width
|
||||
|
@ -185,7 +185,7 @@ Flickable {
|
|||
Layout.preferredWidth: parent.width
|
||||
spacing: 0
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
HifiStylesUit.GraphikSemiBold {
|
||||
id: inputDeviceTitle
|
||||
text: "Which input device?"
|
||||
Layout.maximumWidth: parent.width
|
||||
|
@ -280,7 +280,7 @@ Flickable {
|
|||
Layout.preferredWidth: parent.width
|
||||
spacing: 0
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
HifiStylesUit.GraphikSemiBold {
|
||||
id: outputDeviceTitle
|
||||
text: "Which output device?"
|
||||
Layout.maximumWidth: parent.width
|
||||
|
|
|
@ -183,7 +183,7 @@ QtObject {
|
|||
|
||||
readonly property QtObject settings: QtObject {
|
||||
property int subtitleTopMargin: 2
|
||||
property int settingsGroupTopMargin: 24
|
||||
property int settingsGroupTopMargin: 14
|
||||
property int spacingBetweenSettings: 48
|
||||
property int spacingBetweenRadiobuttons: 14
|
||||
}
|
||||
|
|
|
@ -5,6 +5,9 @@ import TabletScriptingInterface 1.0
|
|||
Item {
|
||||
id: tabletButton
|
||||
|
||||
// NOTE: These properties form part of the "TabletButtonProxy.ButtonProperties" type.
|
||||
// Keep the type's JSDoc up to date with any changes.
|
||||
|
||||
property color defaultCaptionColor: "#ffffff"
|
||||
property color captionColor: defaultCaptionColor
|
||||
|
||||
|
@ -18,15 +21,15 @@ Item {
|
|||
property string activeText: tabletButton.text
|
||||
property string activeHoverText: tabletButton.activeText
|
||||
property bool isActive: false
|
||||
property bool inDebugMode: false
|
||||
property bool inDebugMode: false // tablet only
|
||||
property bool isEntered: false
|
||||
property double sortOrder: 100
|
||||
property int stableOrder: 0
|
||||
property var tabletRoot;
|
||||
property var flickable: null
|
||||
property var gridView: null
|
||||
property var tabletRoot; // tablet only
|
||||
property var flickable: null // tablet only
|
||||
property var gridView: null // tablet only
|
||||
|
||||
property int buttonIndex: -1
|
||||
property int buttonIndex: -1 // tablet only
|
||||
|
||||
width: 129
|
||||
height: 129
|
||||
|
|
|
@ -3,6 +3,9 @@ import QtQuick 2.5
|
|||
StateImage {
|
||||
id: button
|
||||
|
||||
// NOTE: These properties form part of the "TabletButtonProxy.ButtonProperties" type.
|
||||
// Keep the type's JSDoc up to date with any changes.
|
||||
|
||||
property color defaultCaptionColor: "#ffffff"
|
||||
property color captionColor: defaultCaptionColor
|
||||
|
||||
|
|
|
@ -262,7 +262,7 @@ class Stats : public QQuickItem {
|
|||
STATS_PROPERTY(int, processing, 0)
|
||||
STATS_PROPERTY(int, processingPending, 0)
|
||||
STATS_PROPERTY(int, triangles, 0)
|
||||
STATS_PROPERTY(int, drawcalls, 0)
|
||||
STATS_PROPERTY(uint32_t, drawcalls, 0)
|
||||
STATS_PROPERTY(int, materialSwitches, 0)
|
||||
STATS_PROPERTY(int, itemConsidered, 0)
|
||||
STATS_PROPERTY(int, itemOutOfView, 0)
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="Window">
|
||||
<windowStyleMask key="styleMask" closable="YES"/>
|
||||
<rect key="contentRect" x="505" y="583" width="515" height="390"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1177"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
|
||||
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="515" height="390"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
- (void) confirmCredentials:(NSString*)username :(NSString*)password {
|
||||
|
||||
NSLog(@"web request started");
|
||||
NSString* trimmedUsername = [username stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
NSString *post = [NSString stringWithFormat:@"grant_type=password&username=%@&password=%@&scope=owner",
|
||||
[username stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]],
|
||||
[trimmedUsername stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]],
|
||||
[password stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]]];
|
||||
NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSString *postLength = [NSString stringWithFormat:@"%ld", (unsigned long)[postData length]];
|
||||
|
|
|
@ -15,6 +15,31 @@ NSString* hifiBackgroundFilename = @"hifi_window";
|
|||
forObject:self];
|
||||
fieldEditor.insertionPointColor = insertionPointColor;
|
||||
}
|
||||
|
||||
- (BOOL) performKeyEquivalent:(NSEvent *)event
|
||||
{
|
||||
if ([event type] == NSEventTypeKeyDown) {
|
||||
if ([event modifierFlags] & NSEventModifierFlagCommand) {
|
||||
if ([[event charactersIgnoringModifiers] isEqualToString:@"v"]) {
|
||||
[NSApp sendAction:(NSSelectorFromString(@"paste:")) to:nil from:self];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ([[event charactersIgnoringModifiers] isEqualToString:@"c"]) {
|
||||
[NSApp sendAction:(NSSelectorFromString(@"copy:")) to:nil from:self];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ([[event charactersIgnoringModifiers] isEqualToString:@"a"]) {
|
||||
[NSApp sendAction:(NSSelectorFromString(@"selectAll:")) to:nil from:self];
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [super performKeyEquivalent:event];
|
||||
}
|
||||
|
||||
- (void) mouseDown:(NSEvent *)event
|
||||
{
|
||||
NSColor *insertionPointColor = [NSColor whiteColor];
|
||||
|
@ -63,6 +88,30 @@ NSString* hifiBackgroundFilename = @"hifi_window";
|
|||
fieldEditor.insertionPointColor = insertionPointColor;
|
||||
return status;
|
||||
}
|
||||
|
||||
- (BOOL) performKeyEquivalent:(NSEvent *)event
|
||||
{
|
||||
if ([event type] == NSEventTypeKeyDown) {
|
||||
if ([event modifierFlags] & NSEventModifierFlagCommand) {
|
||||
if ([[event charactersIgnoringModifiers] isEqualToString:@"v"]) {
|
||||
[NSApp sendAction:(NSSelectorFromString(@"paste:")) to:nil from:self];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ([[event charactersIgnoringModifiers] isEqualToString:@"c"]) {
|
||||
[NSApp sendAction:(NSSelectorFromString(@"copy:")) to:nil from:self];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ([[event charactersIgnoringModifiers] isEqualToString:@"a"]) {
|
||||
[NSApp sendAction:(NSSelectorFromString(@"selectAll:")) to:nil from:self];
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [super performKeyEquivalent:event];
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
|
|
|
@ -54,7 +54,9 @@
|
|||
|
||||
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
|
||||
NSLog(@"completed; error: %@", error);
|
||||
if (error) {
|
||||
[[Launcher sharedLauncher] displayErrorPage];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
|
|
@ -66,6 +66,9 @@
|
|||
|
||||
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
|
||||
NSLog(@"completed; error: %@", error);
|
||||
if (error) {
|
||||
[[Launcher sharedLauncher] displayErrorPage];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
#import "Launcher.h"
|
||||
|
||||
|
||||
static NSString* const organizationURL = @"https://s3.amazonaws.com/hifi-public/huffman/organizations/";
|
||||
static NSString* const organizationURL = @"https://orgs.highfidelity.com/organizations/";
|
||||
|
||||
@implementation OrganizationRequest
|
||||
|
||||
- (void) confirmOrganization:(NSString*)aOrganization :(NSString*)aUsername {
|
||||
self.username = aUsername;
|
||||
|
||||
NSString* trimmedOrgString = [aOrganization stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
const char *cKey = LAUNCHER_HMAC_SECRET;
|
||||
const char *cData = [[aOrganization lowercaseString] cStringUsingEncoding:NSASCIIStringEncoding];
|
||||
const char *cData = [[trimmedOrgString lowercaseString] cStringUsingEncoding:NSASCIIStringEncoding];
|
||||
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
|
||||
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
|
||||
NSData *HMACData = [NSData dataWithBytes:cHMAC length:sizeof(cHMAC)];
|
||||
|
|
|
@ -41,5 +41,6 @@ int main(int argc, const char* argv[]) {
|
|||
[appMenu addItem:quitMenuItem];
|
||||
[appMenuItem setSubmenu:appMenu];
|
||||
|
||||
[[NSApplication sharedApplication] activateIgnoringOtherApps:TRUE];
|
||||
return NSApplicationMain(argc, argv);
|
||||
}
|
||||
|
|
|
@ -120,8 +120,16 @@ BOOL CLauncherDlg::OnInitDialog() {
|
|||
BOOL CLauncherDlg::PreTranslateMessage(MSG* pMsg) {
|
||||
if ((pMsg->message == WM_KEYDOWN))
|
||||
{
|
||||
if (pMsg->wParam == VK_RETURN)
|
||||
{
|
||||
if (pMsg->wParam == 'A' && GetKeyState(VK_CONTROL) < 0) {
|
||||
CWnd* wnd = GetFocus();
|
||||
CWnd* myWnd = this->GetDlgItem(IDC_ORGNAME);
|
||||
if (wnd && (wnd == this->GetDlgItem(IDC_ORGNAME) ||
|
||||
wnd == this->GetDlgItem(IDC_USERNAME) ||
|
||||
wnd == this->GetDlgItem(IDC_PASSWORD))) {
|
||||
((CEdit*)wnd)->SetSel(0, -1);
|
||||
}
|
||||
return TRUE;
|
||||
} else if (pMsg->wParam == VK_RETURN) {
|
||||
OnNextClicked();
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -140,7 +148,6 @@ void CLauncherDlg::setCustomDialog() {
|
|||
SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, lExStyle);
|
||||
|
||||
SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
|
||||
// theApp.setDialogOnFront();
|
||||
}
|
||||
|
||||
void CLauncherDlg::OnPaint()
|
||||
|
@ -210,7 +217,7 @@ BOOL CLauncherDlg::getHQInfo(const CString& orgname) {
|
|||
}
|
||||
|
||||
afx_msg void CLauncherDlg::OnTroubleClicked() {
|
||||
ShellExecute(0, NULL, TROUBLE_URL, NULL, NULL, SW_SHOWDEFAULT);
|
||||
LauncherUtils::executeOnForeground(TROUBLE_URL, _T(""));
|
||||
}
|
||||
|
||||
afx_msg void CLauncherDlg::OnNextClicked() {
|
||||
|
@ -584,10 +591,14 @@ void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) {
|
|||
} else {
|
||||
theApp._manager.addToLog(_T("Start splash screen"));
|
||||
setDrawDialog(DrawStep::DrawLogo);
|
||||
}
|
||||
}
|
||||
} else if (_splashStep > 100) {
|
||||
_showSplash = false;
|
||||
if (theApp._manager.shouldShutDown()) {
|
||||
if (_applicationWND != NULL) {
|
||||
::SetForegroundWindow(_applicationWND);
|
||||
::SetActiveWindow(_applicationWND);
|
||||
}
|
||||
if (LauncherUtils::IsProcessRunning(L"interface.exe")) {
|
||||
exit(0);
|
||||
}
|
||||
|
@ -607,6 +618,9 @@ void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) {
|
|||
exit(0);
|
||||
}
|
||||
}
|
||||
if (theApp._manager.shouldLaunch()) {
|
||||
_applicationWND = theApp._manager.launchApplication();
|
||||
}
|
||||
}
|
||||
|
||||
void CLauncherDlg::setDrawDialog(DrawStep step, BOOL isUpdate) {
|
||||
|
|
|
@ -90,6 +90,8 @@ protected:
|
|||
CStatic* m_username_banner;
|
||||
CStatic* m_password_banner;
|
||||
|
||||
HWND _applicationWND { 0 };
|
||||
|
||||
void drawBackground(CHwndRenderTarget* pRenderTarget);
|
||||
void drawLogo(CHwndRenderTarget* pRenderTarget);
|
||||
void drawSmallLogo(CHwndRenderTarget* pRenderTarget);
|
||||
|
|
|
@ -34,7 +34,7 @@ void LauncherManager::init() {
|
|||
addToLog(_T("Installed version: ") + currentVersion);
|
||||
if (_latestVersion.Compare(currentVersion) == 0) {
|
||||
addToLog(_T("Already running most recent build. Launching interface.exe"));
|
||||
launchApplication();
|
||||
_shouldLaunch = TRUE;
|
||||
_shouldShutdown = TRUE;
|
||||
} else {
|
||||
addToLog(_T("New build found. Updating"));
|
||||
|
@ -94,7 +94,7 @@ BOOL LauncherManager::installLauncher() {
|
|||
// The installer is not running on the desired location and has to be installed
|
||||
// Kill of running before self-copy
|
||||
if (LauncherUtils::IsProcessRunning(LAUNCHER_EXE_FILENAME)) {
|
||||
::ShellExecute(NULL, NULL, L"taskkill", L"/F /T /IM " + LAUNCHER_EXE_FILENAME, NULL, SW_HIDE);
|
||||
ShellExecute(NULL, NULL, L"taskkill", L"/F /T /IM " + LAUNCHER_EXE_FILENAME, NULL, SW_HIDE);
|
||||
}
|
||||
CopyFile(appPath, instalationPath, FALSE);
|
||||
}
|
||||
|
@ -218,24 +218,27 @@ BOOL LauncherManager::getInstalledVersion(const CString& path, CString& version)
|
|||
}
|
||||
|
||||
|
||||
BOOL LauncherManager::launchApplication(const CString& tokensJSON) {
|
||||
HWND LauncherManager::launchApplication() {
|
||||
CString installDir;
|
||||
LauncherManager::getAndCreatePaths(PathType::Interface_Directory, installDir);
|
||||
CString interfaceExe = installDir + _T("\\interface.exe");
|
||||
CString params1 = _T("--url \"") + _domainURL + ("\" ");
|
||||
CString urlParam = _T("--url \"") + _domainURL + ("\" ");
|
||||
CString scriptsURL = installDir + _T("\\scripts\\simplifiedUI");
|
||||
CString params2 = _T("--scripts \"") + scriptsURL + ("\" ");
|
||||
CString scriptsParam = _T("--scripts \"") + scriptsURL + ("\" ");
|
||||
CString cacheDir;
|
||||
LauncherManager::getAndCreatePaths(PathType::Content_Directory, cacheDir);
|
||||
CString params3 = _T("--cache \"") + cacheDir + ("\" ");
|
||||
CString params4 = !_displayName.IsEmpty() ? _T("--displayName \"") + _displayName + ("\" ") : _T("");
|
||||
CString parsedTokens = tokensJSON;
|
||||
parsedTokens.Replace(_T("\""), _T("\\\""));
|
||||
CString params5 = !tokensJSON.IsEmpty() ? _T("--tokens \"") + parsedTokens + ("\"") : _T("");
|
||||
CString params = params1 + params2 + params3 + params4 + params5 + EXTRA_PARAMETERS;
|
||||
|
||||
auto rs = ShellExecute(NULL, L"open", interfaceExe, params, NULL, SW_SHOW);
|
||||
return (rs != NULL);
|
||||
CString cacheParam = _T("--cache \"") + cacheDir + ("\" ");
|
||||
CString nameParam = !_displayName.IsEmpty() ? _T("--displayName \"") + _displayName + ("\" ") : _T("");
|
||||
CString tokensParam = _T("");
|
||||
if (!_tokensJSON.IsEmpty()) {
|
||||
CString parsedTokens = _tokensJSON;
|
||||
parsedTokens.Replace(_T("\""), _T("\\\""));
|
||||
tokensParam = _T("--tokens \"");
|
||||
tokensParam += parsedTokens + _T("\"");
|
||||
}
|
||||
CString params = urlParam + scriptsParam + cacheParam + nameParam + tokensParam + EXTRA_PARAMETERS;
|
||||
_shouldLaunch = FALSE;
|
||||
return LauncherUtils::executeOnForeground(interfaceExe, params);
|
||||
}
|
||||
|
||||
BOOL LauncherManager::createConfigJSON() {
|
||||
|
@ -288,8 +291,8 @@ LauncherUtils::ResponseError LauncherManager::readConfigJSON(CString& version, C
|
|||
LauncherUtils::ResponseError LauncherManager::readOrganizationJSON(const CString& hash) {
|
||||
CString contentTypeJson = L"content-type:application/json";
|
||||
CString response;
|
||||
CString url = _T("/hifi-public/huffman/organizations/") + hash + _T(".json");
|
||||
LauncherUtils::ResponseError error = LauncherUtils::makeHTTPCall(L"HQ Launcher", L"s3.amazonaws.com", url,
|
||||
CString url = _T("/organizations/") + hash + _T(".json");
|
||||
LauncherUtils::ResponseError error = LauncherUtils::makeHTTPCall(L"HQ Launcher", L"orgs.highfidelity.com", url,
|
||||
contentTypeJson, CStringA(), response, false);
|
||||
if (error != LauncherUtils::ResponseError::NoError) {
|
||||
return error;
|
||||
|
@ -407,9 +410,11 @@ void LauncherManager::onZipExtracted(ZipType type, int size) {
|
|||
addToLog(_T("Creating config.json"));
|
||||
createConfigJSON();
|
||||
addToLog(_T("Launching application."));
|
||||
launchApplication(_tokensJSON);
|
||||
addToLog(_T("Creating registry keys."));
|
||||
createApplicationRegistryKeys(size);
|
||||
_shouldLaunch = TRUE;
|
||||
if (!_shouldUpdate) {
|
||||
addToLog(_T("Creating registry keys."));
|
||||
createApplicationRegistryKeys(size);
|
||||
}
|
||||
_shouldShutdown = TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -429,7 +434,7 @@ void LauncherManager::onFileDownloaded(DownloadType type) {
|
|||
addToLog(_T("Installing content."));
|
||||
installContent();
|
||||
} else if (type == DownloadType::DownloadApplication) {
|
||||
addToLog(_T("Installing application."));
|
||||
addToLog(_T("Installing application."));
|
||||
extractApplication();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ public:
|
|||
BOOL deleteApplicationRegistryKeys();
|
||||
BOOL createShortcuts();
|
||||
BOOL deleteShortcuts();
|
||||
BOOL launchApplication(const CString& tokensJSON = _T(""));
|
||||
HWND launchApplication();
|
||||
BOOL uninstallApplication();
|
||||
BOOL installLauncher();
|
||||
|
||||
|
@ -79,6 +79,7 @@ public:
|
|||
const CString& getdomainURL() const { return _domainURL; }
|
||||
const CString& getVersion() const { return _version; }
|
||||
BOOL shouldShutDown() const { return _shouldShutdown; }
|
||||
BOOL shouldLaunch() const { return _shouldLaunch; }
|
||||
BOOL needsUpdate() { return _shouldUpdate; }
|
||||
BOOL needsUninstall() { return _shouldUninstall; }
|
||||
void setDisplayName(const CString& displayName) { _displayName = displayName; }
|
||||
|
@ -108,6 +109,7 @@ private:
|
|||
BOOL _shouldUpdate{ FALSE };
|
||||
BOOL _shouldUninstall{ FALSE };
|
||||
BOOL _shouldShutdown{ FALSE };
|
||||
BOOL _shouldLaunch{ FALSE };
|
||||
CStdioFile _logFile;
|
||||
};
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <tlhelp32.h>
|
||||
#include <strsafe.h>
|
||||
#include <winhttp.h>
|
||||
|
||||
#pragma comment(lib, "winhttp")
|
||||
|
||||
#include "LauncherUtils.h"
|
||||
|
@ -450,3 +451,38 @@ BOOL LauncherUtils::deleteDirectoriesOnThread(const CString& applicationDir,
|
|||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HWND LauncherUtils::executeOnForeground(const CString& path, const CString& params) {
|
||||
SHELLEXECUTEINFO info;
|
||||
info.cbSize = sizeof(SHELLEXECUTEINFO);
|
||||
info.lpVerb = _T("open");
|
||||
info.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOASYNC | SEE_MASK_WAITFORINPUTIDLE;
|
||||
info.hwnd = NULL;
|
||||
info.lpVerb = NULL;
|
||||
info.lpParameters = NULL;
|
||||
info.lpDirectory = NULL;
|
||||
info.nShow = SW_SHOWNORMAL;
|
||||
info.hInstApp = NULL;
|
||||
info.lpFile = path;
|
||||
info.lpParameters = params;
|
||||
HWND hwnd = NULL;
|
||||
if (!ShellExecuteEx(&info)) {
|
||||
return FALSE;
|
||||
} else {
|
||||
DWORD infopid = GetProcessId(info.hProcess);
|
||||
AllowSetForegroundWindow(infopid);
|
||||
hwnd = GetTopWindow(0);
|
||||
while (hwnd) {
|
||||
DWORD pid;
|
||||
DWORD dwTheardId = ::GetWindowThreadProcessId(hwnd, &pid);
|
||||
if (pid == infopid) {
|
||||
SetForegroundWindow(hwnd);
|
||||
SetActiveWindow(hwnd);
|
||||
break;
|
||||
}
|
||||
hwnd = ::GetNextWindow(hwnd, GW_HWNDNEXT);
|
||||
}
|
||||
CloseHandle(info.hProcess);
|
||||
}
|
||||
return hwnd;
|
||||
}
|
||||
|
|
|
@ -87,6 +87,7 @@ public:
|
|||
const CString& downloadsDir,
|
||||
std::function<void(int)> callback);
|
||||
static CString urlEncodeString(const CString& url);
|
||||
static HWND executeOnForeground(const CString& path, const CString& params);
|
||||
|
||||
private:
|
||||
// Threads
|
||||
|
|
|
@ -309,7 +309,7 @@ void GLBackend::setResourceTexture(unsigned int slot, const TexturePointer& reso
|
|||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(textureState._target, to);
|
||||
(void)CHECK_GL_ERROR();
|
||||
_stats._RSAmountTextureMemoryBounded += (int)object->size();
|
||||
_stats._RSAmountTextureMemoryBounded += (uint64_t)object->size();
|
||||
|
||||
} else {
|
||||
releaseResourceTexture(slot);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include <limits>
|
||||
#include "Context.h"
|
||||
|
||||
#include <shared/GlobalAppProperties.h>
|
||||
|
@ -18,19 +19,28 @@
|
|||
|
||||
using namespace gpu;
|
||||
|
||||
template<typename T>
|
||||
T subWrap(T endValue, T beginValue) {
|
||||
if (endValue >= beginValue) {
|
||||
return endValue - beginValue;
|
||||
} else {
|
||||
return endValue + ((std::numeric_limits<T>::max() - beginValue) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ContextStats::evalDelta(const ContextStats& begin, const ContextStats& end) {
|
||||
_ISNumFormatChanges = end._ISNumFormatChanges - begin._ISNumFormatChanges;
|
||||
_ISNumInputBufferChanges = end._ISNumInputBufferChanges - begin._ISNumInputBufferChanges;
|
||||
_ISNumIndexBufferChanges = end._ISNumIndexBufferChanges - begin._ISNumIndexBufferChanges;
|
||||
_ISNumFormatChanges = subWrap<uint32_t>(end._ISNumFormatChanges, begin._ISNumFormatChanges);
|
||||
_ISNumInputBufferChanges = subWrap<uint32_t>(end._ISNumInputBufferChanges, begin._ISNumInputBufferChanges);
|
||||
_ISNumIndexBufferChanges = subWrap<uint32_t>(end._ISNumIndexBufferChanges, begin._ISNumIndexBufferChanges);
|
||||
|
||||
_RSNumTextureBounded = end._RSNumTextureBounded - begin._RSNumTextureBounded;
|
||||
_RSAmountTextureMemoryBounded = end._RSAmountTextureMemoryBounded - begin._RSAmountTextureMemoryBounded;
|
||||
_RSNumTextureBounded = subWrap<uint32_t>(end._RSNumTextureBounded, begin._RSNumTextureBounded);
|
||||
_RSAmountTextureMemoryBounded = subWrap<uint64_t>(end._RSAmountTextureMemoryBounded, begin._RSAmountTextureMemoryBounded);
|
||||
|
||||
_DSNumAPIDrawcalls = end._DSNumAPIDrawcalls - begin._DSNumAPIDrawcalls;
|
||||
_DSNumDrawcalls = end._DSNumDrawcalls - begin._DSNumDrawcalls;
|
||||
_DSNumTriangles= end._DSNumTriangles - begin._DSNumTriangles;
|
||||
_DSNumAPIDrawcalls = subWrap<uint32_t>(end._DSNumAPIDrawcalls, begin._DSNumAPIDrawcalls);
|
||||
_DSNumDrawcalls = subWrap<uint32_t>(end._DSNumDrawcalls, begin._DSNumDrawcalls);
|
||||
_DSNumTriangles= subWrap<uint32_t>(end._DSNumTriangles, begin._DSNumTriangles);
|
||||
|
||||
_PSNumSetPipelines = end._PSNumSetPipelines - begin._PSNumSetPipelines;
|
||||
_PSNumSetPipelines = subWrap<uint32_t>(end._PSNumSetPipelines, begin._PSNumSetPipelines);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -32,19 +32,19 @@ namespace gpu {
|
|||
|
||||
struct ContextStats {
|
||||
public:
|
||||
int _ISNumFormatChanges = 0;
|
||||
int _ISNumInputBufferChanges = 0;
|
||||
int _ISNumIndexBufferChanges = 0;
|
||||
uint32_t _ISNumFormatChanges { 0 };
|
||||
uint32_t _ISNumInputBufferChanges { 0 };
|
||||
uint32_t _ISNumIndexBufferChanges { 0 };
|
||||
|
||||
int _RSNumResourceBufferBounded = 0;
|
||||
int _RSNumTextureBounded = 0;
|
||||
int _RSAmountTextureMemoryBounded = 0;
|
||||
uint32_t _RSNumResourceBufferBounded { 0 };
|
||||
uint32_t _RSNumTextureBounded { 0 };
|
||||
uint64_t _RSAmountTextureMemoryBounded { 0 };
|
||||
|
||||
int _DSNumAPIDrawcalls = 0;
|
||||
int _DSNumDrawcalls = 0;
|
||||
int _DSNumTriangles = 0;
|
||||
uint32_t _DSNumAPIDrawcalls { 0 };
|
||||
uint32_t _DSNumDrawcalls { 0 };
|
||||
uint32_t _DSNumTriangles { 0 };
|
||||
|
||||
int _PSNumSetPipelines = 0;
|
||||
uint32_t _PSNumSetPipelines { 0 };
|
||||
|
||||
ContextStats() {}
|
||||
ContextStats(const ContextStats& stats) = default;
|
||||
|
|
|
@ -256,6 +256,7 @@ qint64 Socket::writeDatagram(const QByteArray& datagram, const HifiSockAddr& soc
|
|||
}
|
||||
|
||||
Connection* Socket::findOrCreateConnection(const HifiSockAddr& sockAddr, bool filterCreate) {
|
||||
Lock connectionsLock(_connectionsHashMutex);
|
||||
auto it = _connectionsHash.find(sockAddr);
|
||||
|
||||
if (it == _connectionsHash.end()) {
|
||||
|
@ -295,6 +296,7 @@ void Socket::clearConnections() {
|
|||
return;
|
||||
}
|
||||
|
||||
Lock connectionsLock(_connectionsHashMutex);
|
||||
if (_connectionsHash.size() > 0) {
|
||||
// clear all of the current connections in the socket
|
||||
qCDebug(networking) << "Clearing all remaining connections in Socket.";
|
||||
|
@ -303,6 +305,7 @@ void Socket::clearConnections() {
|
|||
}
|
||||
|
||||
void Socket::cleanupConnection(HifiSockAddr sockAddr) {
|
||||
Lock connectionsLock(_connectionsHashMutex);
|
||||
auto numErased = _connectionsHash.erase(sockAddr);
|
||||
|
||||
if (numErased > 0) {
|
||||
|
@ -460,6 +463,7 @@ void Socket::readPendingDatagrams() {
|
|||
}
|
||||
|
||||
void Socket::connectToSendSignal(const HifiSockAddr& destinationAddr, QObject* receiver, const char* slot) {
|
||||
Lock connectionsLock(_connectionsHashMutex);
|
||||
auto it = _connectionsHash.find(destinationAddr);
|
||||
if (it != _connectionsHash.end()) {
|
||||
connect(it->second.get(), SIGNAL(packetSent()), receiver, slot);
|
||||
|
@ -476,6 +480,7 @@ void Socket::setConnectionMaxBandwidth(int maxBandwidth) {
|
|||
qInfo() << "Setting socket's maximum bandwith to" << maxBandwidth << "bps. ("
|
||||
<< _connectionsHash.size() << "live connections)";
|
||||
_maxBandwidth = maxBandwidth;
|
||||
Lock connectionsLock(_connectionsHashMutex);
|
||||
for (auto& pair : _connectionsHash) {
|
||||
auto& connection = pair.second;
|
||||
connection->setMaxBandwidth(_maxBandwidth);
|
||||
|
@ -493,6 +498,8 @@ ConnectionStats::Stats Socket::sampleStatsForConnection(const HifiSockAddr& dest
|
|||
|
||||
Socket::StatsVector Socket::sampleStatsForAllConnections() {
|
||||
StatsVector result;
|
||||
Lock connectionsLock(_connectionsHashMutex);
|
||||
|
||||
result.reserve(_connectionsHash.size());
|
||||
for (const auto& connectionPair : _connectionsHash) {
|
||||
result.emplace_back(connectionPair.first, connectionPair.second->sampleStats());
|
||||
|
@ -503,6 +510,8 @@ Socket::StatsVector Socket::sampleStatsForAllConnections() {
|
|||
|
||||
std::vector<HifiSockAddr> Socket::getConnectionSockAddrs() {
|
||||
std::vector<HifiSockAddr> addr;
|
||||
Lock connectionsLock(_connectionsHashMutex);
|
||||
|
||||
addr.reserve(_connectionsHash.size());
|
||||
|
||||
for (const auto& connectionPair : _connectionsHash) {
|
||||
|
|
|
@ -129,6 +129,7 @@ private:
|
|||
ConnectionCreationFilterOperator _connectionCreationFilterOperator;
|
||||
|
||||
Mutex _unreliableSequenceNumbersMutex;
|
||||
Mutex _connectionsHashMutex;
|
||||
|
||||
std::unordered_map<HifiSockAddr, BasePacketHandler> _unfilteredHandlers;
|
||||
std::unordered_map<HifiSockAddr, SequenceNumber> _unreliableSequenceNumbers;
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace render {
|
|||
|
||||
Q_PROPERTY(quint32 frameTextureCount MEMBER frameTextureCount NOTIFY dirty)
|
||||
Q_PROPERTY(quint32 frameTextureRate MEMBER frameTextureRate NOTIFY dirty)
|
||||
Q_PROPERTY(quint32 frameTextureMemoryUsage MEMBER frameTextureMemoryUsage NOTIFY dirty)
|
||||
Q_PROPERTY(quint64 frameTextureMemoryUsage MEMBER frameTextureMemoryUsage NOTIFY dirty)
|
||||
|
||||
Q_PROPERTY(quint32 frameSetPipelineCount MEMBER frameSetPipelineCount NOTIFY dirty)
|
||||
Q_PROPERTY(quint32 frameSetInputFormatCount MEMBER frameSetInputFormatCount NOTIFY dirty)
|
||||
|
@ -96,7 +96,7 @@ namespace render {
|
|||
|
||||
quint32 frameTextureCount{ 0 };
|
||||
quint32 frameTextureRate{ 0 };
|
||||
qint64 frameTextureMemoryUsage{ 0 };
|
||||
quint64 frameTextureMemoryUsage{ 0 };
|
||||
|
||||
quint32 frameSetPipelineCount{ 0 };
|
||||
|
||||
|
@ -124,4 +124,4 @@ namespace render {
|
|||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -969,6 +969,46 @@ const QString OBJECT_NAME_KEY = "objectName";
|
|||
const QString STABLE_ORDER_KEY = "stableOrder";
|
||||
static int s_stableOrder = 1;
|
||||
|
||||
/**jsdoc
|
||||
* Properties of a tablet button.
|
||||
*
|
||||
* @typedef {object} TabletButtonProxy.ButtonProperties
|
||||
*
|
||||
* @property {Uuid} uuid - The button ID. <em>Read-only.</em>
|
||||
* @property {Uuid} objectName - Synonym for <code>uuid</code>.
|
||||
* @property {number} stableOrder - The order in which the button was created: each button created gets a value incremented by
|
||||
* one.
|
||||
*
|
||||
* @property {string} icon - The url of the default button icon displayed. (50 x 50 pixels. SVG, PNG, or other image format.)
|
||||
* @property {string} hoverIcon - The url of the button icon displayed when the button is hovered and not active.
|
||||
* @property {string} activeIcon - The url of the button icon displayed when the button is active.
|
||||
* @property {string} activeHoverIcon - The url of the button icon displayed when the button is hovered and active.
|
||||
* @property {string} text - The button caption.
|
||||
* @property {string} hoverText - The button caption when the button is hovered and not active.
|
||||
* @property {string} activeText - The button caption when the button is active.
|
||||
* @property {string} activeHoverText - The button caption when the button is hovered and active.
|
||||
* @comment {string} defaultCaptionColor="#ffffff" - Internal property.
|
||||
* @property {string} captionColor="#ffffff" - The color of the button caption.
|
||||
|
||||
* @property {boolean} isActive=false - <code>true</code> if the button is active, <code>false</code> if it isn't.
|
||||
* @property {boolean} isEntered - <code>true</code> if the button is being hovered, <code>false</code> if it isn't.
|
||||
* @property {boolean} buttonEnabled=true - <code>true</code> if the button is enabled, <code>false</code> if it is disabled.
|
||||
* @property {number} sortOrder=100 - Determines the order of the buttons: buttons with lower numbers appear before buttons
|
||||
* with larger numbers.
|
||||
*
|
||||
* @property {boolean} inDebugMode - If <code>true</code> and the tablet is being used, the button's <code>isActive</code>
|
||||
* state toggles each time the button is clicked. <em>Tablet only.</em>
|
||||
*
|
||||
* @comment {object} tabletRoot - Internal tablet-only property.
|
||||
* @property {object} flickable - Internal tablet-only property.
|
||||
* @property {object} gridView - Internal tablet-only property.
|
||||
* @property {number} buttonIndex - Internal tablet-only property.
|
||||
*
|
||||
* @comment {number} imageOffOut - Internal toolbar-only property.
|
||||
* @comment {number} imageOffIn - Internal toolbar-only property.
|
||||
* @comment {number} imageOnOut - Internal toolbar-only property.
|
||||
* @comment {number} imageOnIn - Internal toolbar-only property.
|
||||
*/
|
||||
TabletButtonProxy::TabletButtonProxy(const QVariantMap& properties) :
|
||||
_uuid(QUuid::createUuid()),
|
||||
_stableOrder(++s_stableOrder),
|
||||
|
@ -977,6 +1017,7 @@ TabletButtonProxy::TabletButtonProxy(const QVariantMap& properties) :
|
|||
_properties[UUID_KEY] = _uuid;
|
||||
_properties[OBJECT_NAME_KEY] = _uuid.toString();
|
||||
_properties[STABLE_ORDER_KEY] = _stableOrder;
|
||||
// Other properties are defined in TabletButton.qml and ToolbarButton.qml.
|
||||
if (QThread::currentThread() != qApp->thread()) {
|
||||
qCWarning(uiLogging) << "Creating tablet button proxy on wrong thread";
|
||||
}
|
||||
|
|
|
@ -39,6 +39,10 @@ class QmlWindowClass;
|
|||
class OffscreenQmlSurface;
|
||||
|
||||
/**jsdoc
|
||||
* The <code>Tablet</code> API provides the facilities to work with the system or other tablet. In toolbar mode (Developer >
|
||||
* UI > Tablet Becomes Toolbar), the tablet's menu buttons are displayed in a toolbar and other tablet content is displayed
|
||||
* in a dialog.
|
||||
*
|
||||
* @namespace Tablet
|
||||
*
|
||||
* @hifi-interface
|
||||
|
@ -46,6 +50,8 @@ class OffscreenQmlSurface;
|
|||
* @hifi-avatar
|
||||
*/
|
||||
/**jsdoc
|
||||
* The <code>tabletInterface</code> API provides the facilities to work with the system or other tablet.
|
||||
*
|
||||
* @namespace tabletInterface
|
||||
*
|
||||
* @hifi-interface
|
||||
|
@ -53,12 +59,17 @@ class OffscreenQmlSurface;
|
|||
* @hifi-avatar
|
||||
*
|
||||
* @deprecated This API is deprecated and will be removed. Use {@link Tablet} instead.
|
||||
*
|
||||
* @borrows Tablet.getTablet as getTablet
|
||||
* @borrows Tablet.playSound as playSound
|
||||
* @borrows Tablet.tabletNotification as tabletNotification
|
||||
*/
|
||||
class TabletScriptingInterface : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
/**jsdoc
|
||||
* Standard tablet sounds.
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Description</th></tr>
|
||||
|
@ -69,7 +80,6 @@ public:
|
|||
* <tr><td><code>2</code></td><td>Tablet open.</td></tr>
|
||||
* <tr><td><code>3</code></td><td>Tablet hands in.</td></tr>
|
||||
* <tr><td><code>4</code></td><td>Tablet hands out.</td></tr>
|
||||
* <tr><td><code>5</code></td><td>Last.</td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* @typedef {number} Tablet.AudioEvents
|
||||
|
@ -88,28 +98,26 @@ public:
|
|||
void setToolbarScriptingInterface(ToolbarScriptingInterface* toolbarScriptingInterface) { _toolbarScriptingInterface = toolbarScriptingInterface; }
|
||||
|
||||
/**jsdoc
|
||||
* Creates or returns a new TabletProxy and returns it.
|
||||
* Gets an instance of a tablet. A new tablet is created if one with the specified ID doesn't already exist.
|
||||
* @function Tablet.getTablet
|
||||
* @param {string} name - Tablet name.
|
||||
* @returns {TabletProxy} Tablet instance.
|
||||
*/
|
||||
/**jsdoc
|
||||
* Creates or returns a new TabletProxy and returns it.
|
||||
* @function tabletInterface.getTablet
|
||||
* @param {string} name - Tablet name.
|
||||
* @returns {TabletProxy} Tablet instance.
|
||||
* @param {string} name - A unique name that identifies the tablet.
|
||||
* @returns {TabletProxy} The tablet instance.
|
||||
* @example <caption>Display the High Fidelity home page on the system tablet.</caption>
|
||||
* var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
* tablet.gotoWebScreen("https://highfidelity.com/");
|
||||
*/
|
||||
Q_INVOKABLE TabletProxy* getTablet(const QString& tabletId);
|
||||
|
||||
void preloadSounds();
|
||||
|
||||
/**jsdoc
|
||||
* Plays a standard tablet sound. The sound is played locally (only the user running the script hears it) without a
|
||||
* position.
|
||||
* @function Tablet.playSound
|
||||
* @param {Tablet.AudioEvents} sound
|
||||
*/
|
||||
/**jsdoc
|
||||
* @function tabletInterface.playSound
|
||||
* @param {Tablet.AudioEvents} sound
|
||||
* @param {Tablet.AudioEvents} sound - The tablet sound to play.
|
||||
* @example <caption>Play a tablet sound.</caption>
|
||||
* var TABLET_BUTTON_CLICK = 0;
|
||||
* Tablet.playSound(TABLET_BUTTON_CLICK);
|
||||
*/
|
||||
Q_INVOKABLE void playSound(TabletAudioEvents aEvent);
|
||||
|
||||
|
@ -124,15 +132,12 @@ public:
|
|||
QObject* getFlags();
|
||||
signals:
|
||||
/**jsdoc
|
||||
* Triggered when a tablet message or dialog is created.
|
||||
* Triggered when a tablet message or dialog is displayed on the tablet that needs the user's attention.
|
||||
* <p><strong>Note:</strong> Only triggered if the script is running in the same script engine as the script that created
|
||||
* the tablet. By default, this means in scripts included as part of the default scripts.</p>
|
||||
* @function Tablet.tabletNotification
|
||||
* @returns {Signal}
|
||||
*/
|
||||
/**jsdoc
|
||||
* Triggered when a tablet message or dialog is created.
|
||||
* @function tabletInterface.tabletNotification
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void tabletNotification();
|
||||
|
||||
private:
|
||||
|
@ -149,7 +154,9 @@ protected:
|
|||
};
|
||||
|
||||
/**jsdoc
|
||||
* @typedef {object} TabletProxy#ButtonList
|
||||
* Information on the buttons in the tablet main menu (toolbar in toolbar mode) for use in QML. Has properties and functions
|
||||
* per <a href="http://doc.qt.io/qt-5/qabstractlistmodel.html">http://doc.qt.io/qt-5/qabstractlistmodel.html</a>.
|
||||
* @typedef {object} TabletProxy.TabletButtonListModel
|
||||
*/
|
||||
class TabletButtonListModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
|
@ -203,18 +210,27 @@ private:
|
|||
Q_DECLARE_METATYPE(TabletButtonsProxyModel*);
|
||||
|
||||
/**jsdoc
|
||||
* An instance of a tablet. In toolbar mode (Developer >
|
||||
* UI > Tablet Becomes Toolbar), the tablet's menu buttons are displayed in a toolbar and other tablet content is displayed
|
||||
* in a dialog.
|
||||
*
|
||||
* <p>Create a new tablet or retrieve an existing tablet using {@link Tablet.getTablet}.</p>
|
||||
*
|
||||
* @class TabletProxy
|
||||
*
|
||||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {string} name - Name of this tablet. <em>Read-only.</em>
|
||||
* @property {boolean} toolbarMode - Used to transition this tablet into and out of toolbar mode.
|
||||
* When tablet is in toolbar mode, all its buttons will appear in a floating toolbar.
|
||||
* @property {boolean} landscape
|
||||
* @property {boolean} tabletShown <em>Read-only.</em>
|
||||
* @property {TabletProxy#ButtonList} buttons <em>Read-only.</em>
|
||||
* @property {string} name - A unique name that identifies the tablet. <em>Read-only.</em>
|
||||
* @property {boolean} toolbarMode - <code>true</code> if the tablet is in toolbar mode, <code>false</code> if it isn't.
|
||||
* @property {boolean} landscape - <code>true</code> if the tablet is displayed in landscape mode, <code>false</code> if it is
|
||||
* displayed in portrait mode.
|
||||
* <p>Note: This property isn't used in toolbar mode.</p>
|
||||
* @property {boolean} tabletShown - <code>true</code> if the tablet is currently displayed, <code>false</code> if it isn't.
|
||||
* <p>Note: This property isn't used in toolbar mode.</p>
|
||||
* @property {TabletProxy.TabletButtonListModel} buttons - Information on the buttons in the tablet main menu (or toolbar in
|
||||
* toolbar mode) for use in QML. <em>Read-only.</em>
|
||||
*/
|
||||
class TabletProxy : public QObject {
|
||||
Q_OBJECT
|
||||
|
@ -235,140 +251,190 @@ public:
|
|||
void unfocus();
|
||||
|
||||
/**jsdoc
|
||||
* Displays the tablet menu. The tablet is opened if it isn't already open.
|
||||
* @function TabletProxy#gotoMenuScreen
|
||||
* @param {string} [submenu=""]
|
||||
* @param {string} [submenu=""] - The name of a submenu to display, if any.
|
||||
* @example <caption>Go to the "View" menu.</caption>
|
||||
* tablet.gotoMenuScreen("View");
|
||||
*/
|
||||
Q_INVOKABLE void gotoMenuScreen(const QString& submenu = "");
|
||||
|
||||
/**jsdoc
|
||||
* @function TabletProxy#initialScreen
|
||||
* @param {string} url
|
||||
* @param {string} url - URL.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
Q_INVOKABLE void initialScreen(const QVariant& url);
|
||||
|
||||
/**jsdoc
|
||||
* Transition to the home screen.
|
||||
* Displays the tablet home screen, if the tablet is open.
|
||||
* @function TabletProxy#gotoHomeScreen
|
||||
*/
|
||||
Q_INVOKABLE void gotoHomeScreen();
|
||||
|
||||
/**jsdoc
|
||||
* Show the specified Web url on the tablet.
|
||||
* Opens a web page or app on the tablet.
|
||||
* @function TabletProxy#gotoWebScreen
|
||||
* @param {string} url - URL of web page.
|
||||
* @param {string} [injectedJavaScriptUrl=""] - URL to an additional JS script to inject into the web page.
|
||||
* @param {boolean} [loadOtherBase=false]
|
||||
* @param {string} url - The URL of the web page or app.
|
||||
* @param {string} [injectedJavaScriptUrl=""] - The URL of JavaScript to inject into the web page.
|
||||
* @param {boolean} [loadOtherBase=false] - If <code>true</code>, the web page or app is displayed in a frame with "back"
|
||||
* and "close" buttons.
|
||||
*/
|
||||
Q_INVOKABLE void gotoWebScreen(const QString& url);
|
||||
Q_INVOKABLE void gotoWebScreen(const QString& url, const QString& injectedJavaScriptUrl, bool loadOtherBase = false);
|
||||
|
||||
/**jsdoc
|
||||
* Opens a QML app or dialog on the tablet.
|
||||
* @function TabletProxy#loadQMLSource
|
||||
* @param {string} path
|
||||
* @param {boolean} [resizable=false]
|
||||
* @param {string} path - The path of the QML app or dialog.
|
||||
* @param {boolean} [resizable=false] - <code>true</code> to make the dialog resizable in toolbar mode, <code>false</code>
|
||||
* to have it not resizable.
|
||||
*/
|
||||
Q_INVOKABLE void loadQMLSource(const QVariant& path, bool resizable = false);
|
||||
// FIXME: This currently relies on a script initializing the tablet (hence the bool denoting success);
|
||||
// it should be initialized internally so it cannot fail
|
||||
|
||||
/**jsdoc
|
||||
* Displays a QML dialog over the top of the current dialog, without closing the current dialog. Use
|
||||
* {@link TabletProxy#popFromStack|popFromStack} to close the dialog.
|
||||
* <p>If the current dialog or its ancestors contain a QML <code>StackView</code> with <code>objectName: "stack"</code> and
|
||||
* function <code>pushSource(path)</code>, that function is called; otherwise,
|
||||
* {@link TabletProxy#loadQMLSource|loadQMLSource} is called. The Create app provides an example of using a QML
|
||||
* <code>StackView</code>.</p>
|
||||
* @function TabletProxy#pushOntoStack
|
||||
* @param {string} path
|
||||
* @returns {boolean}
|
||||
* @param {string} path - The path to the dialog's QML.
|
||||
* @returns {boolean} <code>true</code> if the dialog was successfully opened, <code>false</code> if it wasn't.
|
||||
*/
|
||||
// edit.js provides an example of using this outside of main menu.
|
||||
Q_INVOKABLE bool pushOntoStack(const QVariant& path);
|
||||
|
||||
/**jsdoc
|
||||
* Closes a QML dialog that was displayed using {@link Tablet#pushOntoStack|pushOntoStack} with a dialog implementing a QML
|
||||
* <code>StackView</code>; otherwise, no action is taken.
|
||||
* <p>If using a QML <code>StackView</code>, its <code>popSource()</code> function is called.</p>
|
||||
* @function TabletProxy#popFromStack
|
||||
*/
|
||||
Q_INVOKABLE void popFromStack();
|
||||
|
||||
/**jsdoc
|
||||
* Opens a QML app or dialog in addition to any current app. In tablet mode, the app or dialog is displayed over the top of
|
||||
* the current app; in toolbar mode, the app or dialog is opened in a new window. If in tablet mode, the app can be closed
|
||||
* using {@link TabletProxy#returnToPreviousApp}.
|
||||
* @function TabletProxy#loadQMLOnTop
|
||||
* @param {string} path
|
||||
* @param {string} path - The path to the app's QML.
|
||||
*/
|
||||
Q_INVOKABLE void loadQMLOnTop(const QVariant& path);
|
||||
|
||||
/**jsdoc
|
||||
* Opens a web app or page in addition to any current app. In tablet mode, the app or page is displayed over the top of the
|
||||
* current app; in toolbar mode, the app is opened in a new window. If in tablet mode, the app or page can be closed using
|
||||
* {@link TabletProxy#returnToPreviousApp}.
|
||||
* @function TabletProxy#loadWebScreenOnTop
|
||||
* @param {string} path
|
||||
* @param {string} [injectedJavaScriptURL=""]
|
||||
* @param {string} path - The URL of the web page or HTML app.
|
||||
* @param {string} [injectedJavaScriptURL=""] - The URL of JavaScript to inject into the web page.
|
||||
*/
|
||||
Q_INVOKABLE void loadWebScreenOnTop(const QVariant& url);
|
||||
Q_INVOKABLE void loadWebScreenOnTop(const QVariant& url, const QString& injectedJavaScriptUrl);
|
||||
|
||||
/**jsdoc
|
||||
* Closes the current app and returns to the previous app, if in tablet mode and the current app was loaded using
|
||||
* {@link TabletProxy#loadQMLOnTop|loadQMLOnTop} or {@link TabletProxy#loadWebScreenOnTop|loadWebScreenOnTop}.
|
||||
* @function TabletProxy#returnToPreviousApp
|
||||
*/
|
||||
Q_INVOKABLE void returnToPreviousApp();
|
||||
|
||||
/**jsdoc
|
||||
* Check if the tablet has a message dialog open.
|
||||
* Checks if the tablet has a modal, non-modal, or message dialog open.
|
||||
* @function TabletProxy#isMessageDialogOpen
|
||||
* @returns {boolean}
|
||||
* @returns {boolean} <code>true</code> if a modal, non-modal, or message dialog is open, <code>false</code> if there isn't.
|
||||
*/
|
||||
Q_INVOKABLE bool isMessageDialogOpen();
|
||||
|
||||
/**jsdoc
|
||||
* Close any open dialogs.
|
||||
* @function TabletProxy#closeDialog
|
||||
*/
|
||||
* Closes any open modal, non-modal, or message dialog, opened by {@link Window.prompt}, {@link Window.promptAsync},
|
||||
* {@link Window.openMessageBox}, or similar.
|
||||
* @function TabletProxy#closeDialog
|
||||
*/
|
||||
Q_INVOKABLE void closeDialog();
|
||||
|
||||
/**jsdoc
|
||||
* Creates a new button, adds it to this and returns it.
|
||||
* Adds a new button to the tablet menu.
|
||||
* @function TabletProxy#addButton
|
||||
* @param {object} properties - Button properties.
|
||||
* @returns {TabletButtonProxy}
|
||||
* @param {TabletButtonProxy.ButtonProperties} properties - Button properties.
|
||||
* @returns {TabletButtonProxy} The button added.
|
||||
* @example <caption>Add a menu button.</caption>
|
||||
* var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
* var button = tablet.addButton({ text: "TEST" });
|
||||
*
|
||||
* button.clicked.connect(function () {
|
||||
* print("TEST button clicked");
|
||||
* });
|
||||
*
|
||||
* Script.scriptEnding.connect(function () {
|
||||
* tablet.removeButton(button);
|
||||
* });
|
||||
*/
|
||||
//FIXME: UI_TABLET_HACK: enumerate the button properties when we figure out what they should be!
|
||||
Q_INVOKABLE TabletButtonProxy* addButton(const QVariant& properties);
|
||||
|
||||
/**jsdoc
|
||||
* Removes a button from the tablet.
|
||||
* Removes a button from the tablet menu.
|
||||
* @function TabletProxy#removeButton
|
||||
* @param {TabletButtonProxy} button - The button to be removed
|
||||
* @param {TabletButtonProxy} button - The button to remove.
|
||||
*/
|
||||
Q_INVOKABLE void removeButton(TabletButtonProxy* tabletButtonProxy);
|
||||
|
||||
/**jsdoc
|
||||
* Used to send an event to the HTML/JavaScript embedded in the tablet.
|
||||
* Sends a message to the current web page. To receive the message, the web page's script must connect to the
|
||||
* <code>EventBridge</code> that is automatically provided to the script:
|
||||
* <pre class="prettyprint"><code>EventBridge.scriptEventReceived.connect(function(message) {
|
||||
* ...
|
||||
* });</code></pre>
|
||||
* @function TabletProxy#emitScriptEvent
|
||||
* @param {object|string} message
|
||||
* @param {string|object} message - The message to send to the web page.
|
||||
*/
|
||||
Q_INVOKABLE void emitScriptEvent(const QVariant& msg);
|
||||
|
||||
/**jsdoc
|
||||
* Used to send an event to the QML embedded in the tablet.
|
||||
* Sends a message to the current QML page. To receive the message, the QML page must implement a function:
|
||||
* <pre class="prettyprint"><code>function fromScript(message) {
|
||||
* ...
|
||||
* }</code></pre>
|
||||
* @function TabletProxy#sendToQml
|
||||
* @param {object|string} message
|
||||
* @param {string|object} message - The message to send to the QML page.
|
||||
*/
|
||||
Q_INVOKABLE void sendToQml(const QVariant& msg);
|
||||
|
||||
/**jsdoc
|
||||
* Check if the tablet is on the home screen.
|
||||
* Checks if the tablet is on the home screen.
|
||||
* @function TabletProxy#onHomeScreen
|
||||
* @returns {boolean}
|
||||
* @returns {boolean} <code>true</code> if the tablet is on the home screen, <code>false</code> if it isn't.
|
||||
*/
|
||||
Q_INVOKABLE bool onHomeScreen();
|
||||
|
||||
/**jsdoc
|
||||
* Set tablet into or out of landscape mode.
|
||||
* Sets whether the tablet is displayed in landscape or portrait mode.
|
||||
* <p>Note: The setting isn't used in toolbar mode.</p>
|
||||
* @function TabletProxy#setLandscape
|
||||
* @param {boolean} landscape - <code>true</code> for landscape, <ode>false</code> for portrait.
|
||||
* @param {boolean} landscape - <code>true</code> to display the tablet in landscape mode, <code>false</code> to display it
|
||||
* in portrait mode.
|
||||
*/
|
||||
Q_INVOKABLE void setLandscape(bool landscape) { _landscape = landscape; }
|
||||
|
||||
/**jsdoc
|
||||
* Gets whether the tablet is displayed in landscape or portrait mode.
|
||||
* <p>Note: The setting isn't used in toolbar mode.</p>
|
||||
* @function TabletProxy#getLandscape
|
||||
* @returns {boolean}
|
||||
* @returns {boolean} <code>true</code> if the tablet is displayed in landscape mode, <code>false</code> if it is displayed
|
||||
* in portrait mode.
|
||||
*/
|
||||
Q_INVOKABLE bool getLandscape() { return _landscape; }
|
||||
|
||||
/**jsdoc
|
||||
* Checks if a path is the current app or dialog displayed.
|
||||
* @function TabletProxy#isPathLoaded
|
||||
* @param {string} path
|
||||
* @returns {boolean}
|
||||
* @param {string} path - The path to test.
|
||||
* @returns {boolean} <code>true</code> if <code>path</code> is the current app or dialog, <code>false</code> if it isn't.
|
||||
*/
|
||||
Q_INVOKABLE bool isPathLoaded(const QVariant& path);
|
||||
|
||||
|
@ -384,44 +450,74 @@ public:
|
|||
|
||||
signals:
|
||||
/**jsdoc
|
||||
* Signaled when this tablet receives an event from the html/js embedded in the tablet.
|
||||
* Triggered when a message from the current HTML web page displayed on the tablet is received. The HTML web page can send
|
||||
* a message by calling:
|
||||
* <pre class="prettyprint"><code>EventBridge.emitWebEvent(message);</code></pre>
|
||||
* @function TabletProxy#webEventReceived
|
||||
* @param {object|string} message
|
||||
* @param {string|object} message - The message received.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void webEventReceived(QVariant msg);
|
||||
|
||||
/**jsdoc
|
||||
* Signaled when this tablet receives an event from the qml embedded in the tablet.
|
||||
* Triggered when a message from the current QML page displayed on the tablet is received. The QML page can send a message
|
||||
* (string or object) by calling: <pre class="prettyprint"><code>sendToScript(message);</code></pre>
|
||||
* @function TabletProxy#fromQml
|
||||
* @param {object|string} message
|
||||
* @param {string|object} message - The message received.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void fromQml(QVariant msg);
|
||||
|
||||
/**jsdoc
|
||||
* Signaled when this tablet screen changes.
|
||||
* Triggered when the tablet's screen changes.
|
||||
* @function TabletProxy#screenChanged
|
||||
* @param type {string} - "Home", "Web", "Menu", "QML", "Closed".
|
||||
* @param url {string} - Only valid for Web and QML.
|
||||
* @param type {string} - The type of the new screen or change: <code>"Home"</code>, <code>"Menu"</code>,
|
||||
* <code>"QML"</code>, <code>"Web"</code>, <code>"Closed"</code>, or <code>"Unknown"</code>.
|
||||
* @param url {string} - The url of the page displayed. Only valid for Web and QML.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void screenChanged(QVariant type, QVariant url);
|
||||
|
||||
/**jsdoc
|
||||
* Signaled when the tablet becomes visible or becomes invisible.
|
||||
* @function TabletProxy#isTabletShownChanged
|
||||
* Triggered when the tablet is opened or closed.
|
||||
* <p>Note: Doesn't apply in toolbar mode.</p>
|
||||
* @function TabletProxy#tabletShownChanged
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void tabletShownChanged();
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the tablet's toolbar mode changes.
|
||||
* @function TabletProxy#toolbarModeChanged
|
||||
* @returns {Signal}
|
||||
* @example <caption>Report when the system tablet's toolbar mode changes.</caption>
|
||||
* var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
* tablet.toolbarModeChanged.connect(function () {
|
||||
* print("Tablet toolbar mode changed to: " + tablet.toolbarMode);
|
||||
* });
|
||||
* // Use Developer > UI > Tablet Becomes Toolbar to change the toolbar mode.
|
||||
*/
|
||||
void toolbarModeChanged();
|
||||
|
||||
protected slots:
|
||||
|
||||
/**jsdoc
|
||||
* @function TabletProxy#desktopWindowClosed
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
void desktopWindowClosed();
|
||||
|
||||
/**jsdoc
|
||||
* @function TabletProxy#emitWebEvent
|
||||
* @param {object|string} message - Message
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
void emitWebEvent(const QVariant& msg);
|
||||
|
||||
/**jsdoc
|
||||
* @function TabletProxy#onTabletShown
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
void onTabletShown();
|
||||
|
||||
protected:
|
||||
|
@ -452,14 +548,20 @@ private:
|
|||
Q_DECLARE_METATYPE(TabletProxy*);
|
||||
|
||||
/**jsdoc
|
||||
* A tablet button. In toolbar mode (Developer > UI > Tablet Becomes Toolbar), the tablet button is displayed on the
|
||||
* toolbar.
|
||||
*
|
||||
* <p>Create a new button using {@link TabletProxy#addButton}.</p>
|
||||
*
|
||||
* @class TabletButtonProxy
|
||||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {Uuid} uuid - Uniquely identifies this button. <em>Read-only.</em>
|
||||
* @property {TabletButtonProxy.ButtonProperties} properties
|
||||
* @property {Uuid} uuid - The ID of the button. <em>Read-only.</em>
|
||||
* @property {TabletButtonProxy.ButtonProperties} properties - The current values of the button's properties. Only properties
|
||||
* that have been set during button creation or subsequently edited are returned. <em>Read-only.</em>
|
||||
*/
|
||||
class TabletButtonProxy : public QObject {
|
||||
Q_OBJECT
|
||||
|
@ -472,28 +574,66 @@ public:
|
|||
QUuid getUuid() const { return _uuid; }
|
||||
|
||||
/**jsdoc
|
||||
* Returns the current value of this button's properties.
|
||||
* Gets the current values of the button's properties. Only properties that have been set during button creation or
|
||||
* subsequently edited are returned.
|
||||
* @function TabletButtonProxy#getProperties
|
||||
* @returns {TabletButtonProxy.ButtonProperties}
|
||||
* @returns {TabletButtonProxy.ButtonProperties} The button properties.
|
||||
* @example <caption>Report a test button's properties.</caption>
|
||||
* var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
* var button = tablet.addButton({ text: "TEST" });
|
||||
*
|
||||
* var properties = button.getProperties();
|
||||
* print("TEST button properties: " + JSON.stringify(properties));
|
||||
*
|
||||
* Script.scriptEnding.connect(function () {
|
||||
* tablet.removeButton(button);
|
||||
* });
|
||||
*/
|
||||
Q_INVOKABLE QVariantMap getProperties();
|
||||
|
||||
/**jsdoc
|
||||
* Replace the values of some of this button's properties.
|
||||
* Changes the values of the button's properties.
|
||||
* @function TabletButtonProxy#editProperties
|
||||
* @param {TabletButtonProxy.ButtonProperties} properties - Set of properties to change.
|
||||
* @param {TabletButtonProxy.ButtonProperties} properties - The properties to change.
|
||||
* @example <caption>Set a button's hover text after a delay.</caption>
|
||||
* var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
* var button = tablet.addButton({ text: "TEST" });
|
||||
*
|
||||
* button.propertiesChanged.connect(function () {
|
||||
* print("TEST button properties changed");
|
||||
* });
|
||||
*
|
||||
* Script.setTimeout(function () {
|
||||
* button.editProperties({ text: "CHANGED" });
|
||||
* }, 2000);
|
||||
*
|
||||
* Script.scriptEnding.connect(function () {
|
||||
* tablet.removeButton(button);
|
||||
* });
|
||||
*/
|
||||
Q_INVOKABLE void editProperties(const QVariantMap& properties);
|
||||
|
||||
signals:
|
||||
/**jsdoc
|
||||
* Triggered when this button has been clicked on by the user.
|
||||
* Triggered when the button is clicked.
|
||||
* @function TabletButtonProxy#clicked
|
||||
* @returns {Signal}
|
||||
* @example <caption>Report a menu button click.</caption>
|
||||
* var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
* var button = tablet.addButton({ text: "TEST" });
|
||||
*
|
||||
* button.clicked.connect(function () {
|
||||
* print("TEST button clicked");
|
||||
* });
|
||||
*
|
||||
* Script.scriptEnding.connect(function () {
|
||||
* tablet.removeButton(button);
|
||||
* });
|
||||
*/
|
||||
void clicked();
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when a button's properties are changed.
|
||||
* @function TabletButtonProxy#propertiesChanged
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
@ -503,20 +643,6 @@ protected:
|
|||
QUuid _uuid;
|
||||
int _stableOrder;
|
||||
|
||||
/**jsdoc
|
||||
* @typedef {object} TabletButtonProxy.ButtonProperties
|
||||
* @property {string} icon - URL to button icon. (50 x 50)
|
||||
* @property {string} hoverIcon - URL to button icon, displayed during mouse hover. (50 x 50)
|
||||
* @property {string} activeHoverIcon - URL to button icon used when button is active, and during mouse hover. (50 x 50)
|
||||
* @property {string} activeIcon - URL to button icon used when button is active. (50 x 50)
|
||||
* @property {string} text - Button caption.
|
||||
* @property {string} hoverText - Button caption when button is not-active but during mouse hover.
|
||||
* @property {string} activeText - Button caption when button is active.
|
||||
* @property {string} activeHoverText - Button caption when button is active and during mouse hover.
|
||||
* @property {boolean} isActive - <code>true</code> when button is active.
|
||||
* @property {number} sortOrder - Determines sort order on tablet. lower numbers will appear before larger numbers.
|
||||
* Default is 100.
|
||||
*/
|
||||
// FIXME: There are additional properties.
|
||||
QVariantMap _properties;
|
||||
};
|
||||
|
|
|
@ -457,9 +457,16 @@ function onGeometryChanged(rect) {
|
|||
}
|
||||
}
|
||||
|
||||
function ensureFirstPersonCameraInHMD(isHMDMode) {
|
||||
var TIMEOUT_BEFORE_REHIDE_TOOLBAR_MS = 700;
|
||||
function onDisplayModeChanged(isHMDMode) {
|
||||
if (isHMDMode) {
|
||||
Camera.setModeString("first person");
|
||||
} else if (Settings.getValue("simplifiedUI/keepExistingUIAndScripts", false)) {
|
||||
// works for now, but not a permanent fix by any means.
|
||||
Script.setTimeout(function () {
|
||||
var toolbar = Toolbars.getToolbar(TOOLBAR_NAME);
|
||||
toolbar.writeProperty("visible", false);
|
||||
}, TIMEOUT_BEFORE_REHIDE_TOOLBAR_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -505,7 +512,7 @@ function startup() {
|
|||
updateOutputDeviceMutedOverlay(isOutputMuted());
|
||||
Audio.mutedDesktopChanged.connect(onDesktopInputDeviceMutedChanged);
|
||||
Window.geometryChanged.connect(onGeometryChanged);
|
||||
HMD.displayModeChanged.connect(ensureFirstPersonCameraInHMD);
|
||||
HMD.displayModeChanged.connect(onDisplayModeChanged);
|
||||
Audio.avatarGainChanged.connect(maybeUpdateOutputDeviceMutedOverlay);
|
||||
Audio.localInjectorGainChanged.connect(maybeUpdateOutputDeviceMutedOverlay);
|
||||
Audio.serverInjectorGainChanged.connect(maybeUpdateOutputDeviceMutedOverlay);
|
||||
|
@ -561,7 +568,7 @@ function shutdown() {
|
|||
|
||||
Audio.mutedDesktopChanged.disconnect(onDesktopInputDeviceMutedChanged);
|
||||
Window.geometryChanged.disconnect(onGeometryChanged);
|
||||
HMD.displayModeChanged.disconnect(ensureFirstPersonCameraInHMD);
|
||||
HMD.displayModeChanged.disconnect(onDisplayModeChanged);
|
||||
Audio.avatarGainChanged.disconnect(maybeUpdateOutputDeviceMutedOverlay);
|
||||
Audio.localInjectorGainChanged.disconnect(maybeUpdateOutputDeviceMutedOverlay);
|
||||
Audio.serverInjectorGainChanged.disconnect(maybeUpdateOutputDeviceMutedOverlay);
|
||||
|
|
Loading…
Reference in a new issue