mirror of
https://github.com/overte-org/overte.git
synced 2025-08-05 00:59:56 +02:00
Merge branch 'master' into tablet_extended_sounds
This commit is contained in:
commit
145149fedd
345 changed files with 16917 additions and 5389 deletions
9
.gitignore
vendored
9
.gitignore
vendored
|
@ -17,6 +17,15 @@ Makefile
|
|||
local.properties
|
||||
android/libraries
|
||||
|
||||
# VSCode
|
||||
# List taken from Github Global Ignores master@435c4d92
|
||||
# https://github.com/github/gitignore/commits/master/Global/VisualStudioCode.gitignore
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
||||
# Xcode
|
||||
*.xcodeproj
|
||||
*.xcworkspace
|
||||
|
|
17
BUILD_OSX.md
17
BUILD_OSX.md
|
@ -1,29 +1,28 @@
|
|||
Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only OS X specific instructions are found in this file.
|
||||
Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only macOS specific instructions are found in this file.
|
||||
|
||||
### Homebrew
|
||||
|
||||
[Homebrew](https://brew.sh/) is an excellent package manager for OS X. It makes install of some High Fidelity dependencies very simple.
|
||||
[Homebrew](https://brew.sh/) is an excellent package manager for macOS. It makes install of some High Fidelity dependencies very simple.
|
||||
|
||||
brew tap homebrew/versions
|
||||
brew install cmake openssl
|
||||
brew install cmake openssl qt
|
||||
|
||||
### OpenSSL
|
||||
|
||||
Assuming you've installed OpenSSL using the homebrew instructions above, you'll need to set OPENSSL_ROOT_DIR so CMake can find your installations.
|
||||
For OpenSSL installed via homebrew, set OPENSSL_ROOT_DIR:
|
||||
|
||||
export OPENSSL_ROOT_DIR=/usr/local/Cellar/openssl/1.0.2h_1/
|
||||
export OPENSSL_ROOT_DIR=/usr/local/Cellar/openssl/1.0.2l
|
||||
|
||||
Note that this uses the version from the homebrew formula at the time of this writing, and the version in the path will likely change.
|
||||
|
||||
### Qt
|
||||
|
||||
Download and install the [Qt 5.6.2 for macOS](http://download.qt.io/official_releases/qt/5.6/5.6.2/qt-opensource-mac-x64-clang-5.6.2.dmg).
|
||||
Assuming you've installed Qt using the homebrew instructions above, you'll need to set QT_CMAKE_PREFIX_PATH so CMake can find your installations.
|
||||
For Qt installed via homebrew, set QT_CMAKE_PREFIX_PATH:
|
||||
|
||||
Keep the default components checked when going through the installer.
|
||||
export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt/5.9.1/lib/cmake
|
||||
|
||||
Once Qt is installed, you need to manually configure the following:
|
||||
* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt5.6.2/5.6/clang_64/lib/cmake/` directory.
|
||||
Note that this uses the version from the homebrew formula at the time of this writing, and the version in the path will likely change.
|
||||
|
||||
### Xcode
|
||||
|
||||
|
|
|
@ -112,9 +112,8 @@ if (BUILD_CLIENT OR BUILD_SERVER)
|
|||
add_subdirectory(plugins)
|
||||
endif()
|
||||
|
||||
if (BUILD_TOOLS)
|
||||
add_subdirectory(tools)
|
||||
endif()
|
||||
# BUILD_TOOLS option will be handled inside the tools's CMakeLists.txt because 'scribe' tool is required for build anyway
|
||||
add_subdirectory(tools)
|
||||
|
||||
if (BUILD_TESTS)
|
||||
add_subdirectory(tests)
|
||||
|
|
|
@ -1162,7 +1162,8 @@ void AssetServer::handleFailedBake(QString originalAssetHash, QString assetPath,
|
|||
_pendingBakes.remove(originalAssetHash);
|
||||
}
|
||||
|
||||
void AssetServer::handleCompletedBake(QString originalAssetHash, QString originalAssetPath, QVector<QString> bakedFilePaths) {
|
||||
void AssetServer::handleCompletedBake(QString originalAssetHash, QString originalAssetPath,
|
||||
QString bakedTempOutputDir, QVector<QString> bakedFilePaths) {
|
||||
bool errorCompletingBake { false };
|
||||
QString errorReason;
|
||||
|
||||
|
@ -1234,6 +1235,16 @@ void AssetServer::handleCompletedBake(QString originalAssetHash, QString origina
|
|||
}
|
||||
}
|
||||
|
||||
for (auto& filePath : bakedFilePaths) {
|
||||
QFile file(filePath);
|
||||
if (!file.remove()) {
|
||||
qWarning() << "Failed to remove temporary file:" << filePath;
|
||||
}
|
||||
}
|
||||
if (!QDir(bakedTempOutputDir).rmdir(".")) {
|
||||
qWarning() << "Failed to remove temporary directory:" << bakedTempOutputDir;
|
||||
}
|
||||
|
||||
if (!errorCompletingBake) {
|
||||
// create the meta file to store which version of the baking process we just completed
|
||||
writeMetaFile(originalAssetHash);
|
||||
|
|
|
@ -100,7 +100,8 @@ private:
|
|||
void bakeAsset(const AssetHash& assetHash, const AssetPath& assetPath, const QString& filePath);
|
||||
|
||||
/// Move baked content for asset to baked directory and update baked status
|
||||
void handleCompletedBake(QString originalAssetHash, QString assetPath, QVector<QString> bakedFilePaths);
|
||||
void handleCompletedBake(QString originalAssetHash, QString assetPath, QString bakedTempOutputDir,
|
||||
QVector<QString> bakedFilePaths);
|
||||
void handleFailedBake(QString originalAssetHash, QString assetPath, QString errors);
|
||||
void handleAbortedBake(QString originalAssetHash, QString assetPath);
|
||||
|
||||
|
|
|
@ -24,20 +24,39 @@ BakeAssetTask::BakeAssetTask(const AssetHash& assetHash, const AssetPath& assetP
|
|||
|
||||
}
|
||||
|
||||
void cleanupTempFiles(QString tempOutputDir, std::vector<QString> files) {
|
||||
for (const auto& filename : files) {
|
||||
QFile f { filename };
|
||||
if (!f.remove()) {
|
||||
qDebug() << "Failed to remove:" << filename;
|
||||
}
|
||||
}
|
||||
if (!tempOutputDir.isEmpty()) {
|
||||
QDir dir { tempOutputDir };
|
||||
if (!dir.rmdir(".")) {
|
||||
qDebug() << "Failed to remove temporary directory:" << tempOutputDir;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void BakeAssetTask::run() {
|
||||
_isBaking.store(true);
|
||||
|
||||
qRegisterMetaType<QVector<QString> >("QVector<QString>");
|
||||
TextureBakerThreadGetter fn = []() -> QThread* { return QThread::currentThread(); };
|
||||
|
||||
QString tempOutputDir;
|
||||
|
||||
if (_assetPath.endsWith(".fbx")) {
|
||||
tempOutputDir = PathUtils::generateTemporaryDir();
|
||||
_baker = std::unique_ptr<FBXBaker> {
|
||||
new FBXBaker(QUrl("file:///" + _filePath), fn, PathUtils::generateTemporaryDir())
|
||||
new FBXBaker(QUrl("file:///" + _filePath), fn, tempOutputDir)
|
||||
};
|
||||
} else {
|
||||
tempOutputDir = PathUtils::generateTemporaryDir();
|
||||
_baker = std::unique_ptr<TextureBaker> {
|
||||
new TextureBaker(QUrl("file:///" + _filePath), image::TextureUsage::CUBE_TEXTURE,
|
||||
PathUtils::generateTemporaryDir())
|
||||
tempOutputDir)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -52,6 +71,8 @@ void BakeAssetTask::run() {
|
|||
|
||||
_wasAborted.store(true);
|
||||
|
||||
cleanupTempFiles(tempOutputDir, _baker->getOutputFiles());
|
||||
|
||||
emit bakeAborted(_assetHash, _assetPath);
|
||||
} else if (_baker->hasErrors()) {
|
||||
qDebug() << "Failed to bake: " << _assetHash << _assetPath << _baker->getErrors();
|
||||
|
@ -60,6 +81,8 @@ void BakeAssetTask::run() {
|
|||
|
||||
_didFinish.store(true);
|
||||
|
||||
cleanupTempFiles(tempOutputDir, _baker->getOutputFiles());
|
||||
|
||||
emit bakeFailed(_assetHash, _assetPath, errors);
|
||||
} else {
|
||||
auto vectorOutputFiles = QVector<QString>::fromStdVector(_baker->getOutputFiles());
|
||||
|
@ -68,7 +91,7 @@ void BakeAssetTask::run() {
|
|||
|
||||
_didFinish.store(true);
|
||||
|
||||
emit bakeComplete(_assetHash, _assetPath, vectorOutputFiles);
|
||||
emit bakeComplete(_assetHash, _assetPath, tempOutputDir, vectorOutputFiles);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ public:
|
|||
bool didFinish() const { return _didFinish.load(); }
|
||||
|
||||
signals:
|
||||
void bakeComplete(QString assetHash, QString assetPath, QVector<QString> outputFiles);
|
||||
void bakeComplete(QString assetHash, QString assetPath, QString tempOutputDir, QVector<QString> outputFiles);
|
||||
void bakeFailed(QString assetHash, QString assetPath, QString errors);
|
||||
void bakeAborted(QString assetHash, QString assetPath);
|
||||
|
||||
|
|
|
@ -97,7 +97,11 @@ void AudioMixerSlavePool::run(ConstIter begin, ConstIter end) {
|
|||
#else
|
||||
// fill the queue
|
||||
std::for_each(_begin, _end, [&](const SharedNodePointer& node) {
|
||||
#if defined(__clang__) && defined(Q_OS_LINUX)
|
||||
_queue.push(node);
|
||||
#else
|
||||
_queue.emplace(node);
|
||||
#endif
|
||||
});
|
||||
|
||||
{
|
||||
|
|
|
@ -97,7 +97,11 @@ void AvatarMixerSlavePool::run(ConstIter begin, ConstIter end) {
|
|||
#else
|
||||
// fill the queue
|
||||
std::for_each(_begin, _end, [&](const SharedNodePointer& node) {
|
||||
#if defined(__clang__) && defined(Q_OS_LINUX)
|
||||
_queue.push(node);
|
||||
#else
|
||||
_queue.emplace(node);
|
||||
#endif
|
||||
});
|
||||
|
||||
{
|
||||
|
|
2
cmake/externals/glew/CMakeLists.txt
vendored
2
cmake/externals/glew/CMakeLists.txt
vendored
|
@ -9,7 +9,7 @@ ExternalProject_Add(
|
|||
${EXTERNAL_NAME}
|
||||
URL http://hifi-public.s3.amazonaws.com/dependencies/glew_simple_1.13.0.zip
|
||||
URL_MD5 73f833649e904257b35bf4e84f8bdfb5
|
||||
CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
|
||||
CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_POSITION_INDEPENDENT_CODE=ON
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
|
|
2
cmake/externals/nvtt/CMakeLists.txt
vendored
2
cmake/externals/nvtt/CMakeLists.txt
vendored
|
@ -31,7 +31,7 @@ else ()
|
|||
${EXTERNAL_NAME}
|
||||
URL http://hifi-public.s3.amazonaws.com/dependencies/nvidia-texture-tools-2.1.0.hifi.zip
|
||||
URL_MD5 5794b950f8b265a9a41b2839b3bf7ebb
|
||||
CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DNVTT_SHARED=1 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
|
||||
CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DNVTT_SHARED=1 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_POSITION_INDEPENDENT_CODE=ON
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
|
|
|
@ -14,9 +14,17 @@ endif ()
|
|||
|
||||
if (HIFI_MEMORY_DEBUGGING)
|
||||
if (UNIX)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -U_FORTIFY_SOURCE -fno-stack-protector -fno-omit-frame-pointer")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libasan -static-libstdc++ -fsanitize=address")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libasan -static-libstdc++ -fsanitize=address")
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
# for clang on Linux
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=address -fsanitize-recover=address")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fsanitize=address -fsanitize-recover=address")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fsanitize=address -fsanitize-recover=address")
|
||||
else ()
|
||||
# for gcc on Linux
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fsanitize=address -U_FORTIFY_SOURCE -fno-stack-protector -fno-omit-frame-pointer")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libasan -static-libstdc++ -fsanitize=undefined -fsanitize=address")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libasan -static-libstdc++ -fsanitize=undefined -fsanitize=address")
|
||||
endif()
|
||||
endif (UNIX)
|
||||
endif ()
|
||||
endmacro(SETUP_MEMORY_DEBUGGER)
|
||||
|
|
|
@ -44,7 +44,11 @@ endfunction()
|
|||
# Sets the QT_CMAKE_PREFIX_PATH and QT_DIR variables
|
||||
# Also enables CMAKE_AUTOMOC and CMAKE_AUTORCC
|
||||
macro(setup_qt)
|
||||
set(QT_CMAKE_PREFIX_PATH "$ENV{QT_CMAKE_PREFIX_PATH}")
|
||||
# if QT_CMAKE_PREFIX_PATH was not specified before hand,
|
||||
# try to use the environment variable
|
||||
if (NOT QT_CMAKE_PREFIX_PATH)
|
||||
set(QT_CMAKE_PREFIX_PATH "$ENV{QT_CMAKE_PREFIX_PATH}")
|
||||
endif()
|
||||
if (("QT_CMAKE_PREFIX_PATH" STREQUAL "") OR (NOT EXISTS "${QT_CMAKE_PREFIX_PATH}"))
|
||||
calculate_default_qt_dir(QT_DIR)
|
||||
set(QT_CMAKE_PREFIX_PATH "${QT_DIR}/lib/cmake")
|
||||
|
@ -81,4 +85,4 @@ macro(setup_qt)
|
|||
add_paths_to_fixup_libs("${QT_DIR}/bin")
|
||||
endif ()
|
||||
|
||||
endmacro()
|
||||
endmacro()
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
// Here you can put a script that will be run by an assignment-client (AC)
|
||||
// For examples, please go to http://public.highfidelity.io/scripts
|
||||
// For examples, please go to https://github.com/highfidelity/hifi/tree/master/script-archive/acScripts
|
||||
// The directory named acScripts contains assignment-client specific scripts you can try.
|
||||
|
|
|
@ -262,7 +262,13 @@ target_link_libraries(
|
|||
)
|
||||
|
||||
if (UNIX)
|
||||
target_link_libraries(${TARGET_NAME} pthread)
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
# Linux
|
||||
target_link_libraries(${TARGET_NAME} pthread atomic)
|
||||
else ()
|
||||
# OSX
|
||||
target_link_libraries(${TARGET_NAME} pthread)
|
||||
endif ()
|
||||
endif(UNIX)
|
||||
|
||||
# assume we are using a Qt build without bearer management
|
||||
|
|
609
interface/resources/html/commerce/backup_instructions.html
Normal file
609
interface/resources/html/commerce/backup_instructions.html
Normal file
|
@ -0,0 +1,609 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
|
||||
body
|
||||
{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #333;
|
||||
background-color: #eee;
|
||||
font: 300 16px/22px "Lato", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
background: rgba(74,219,255,1);
|
||||
background: -moz-linear-gradient(-45deg, rgba(74,219,255,1) 0%, rgba(61,171,255,1) 41%, rgba(54,124,209,1) 100%);
|
||||
background: -webkit-gradient(left top, right bottom, color-stop(0%, rgba(74,219,255,1)), color-stop(41%, rgba(61,171,255,1)), color-stop(100%, rgba(54,124,209,1)));
|
||||
background: -webkit-linear-gradient(-45deg, rgba(74,219,255,1) 0%, rgba(61,171,255,1) 41%, rgba(54,124,209,1) 100%);
|
||||
background: -o-linear-gradient(-45deg, rgba(74,219,255,1) 0%, rgba(61,171,255,1) 41%, rgba(54,124,209,1) 100%);
|
||||
background: -ms-linear-gradient(-45deg, rgba(74,219,255,1) 0%, rgba(61,171,255,1) 41%, rgba(54,124,209,1) 100%);
|
||||
background: linear-gradient(135deg, rgba(74,219,255,1) 0%, rgba(61,171,255,1) 41%, rgba(54,124,209,1) 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4adbff', endColorstr='#367cd1', GradientType=1 );
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6
|
||||
{
|
||||
margin: 0 0 .5em;
|
||||
font-weight: 500;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
h1 { font-size: 2.25em; } /* 36px */
|
||||
h2 { font-size: 1.75em; } /* 28px */
|
||||
h3 { font-size: 1.375em; } /* 22px */
|
||||
h4 { font-size: 1.125em; } /* 18px */
|
||||
h5 { font-size: 1em; } /* 16px */
|
||||
h6 { font-size: .875em; } /* 14px */
|
||||
|
||||
p
|
||||
{
|
||||
margin: 0 0 1.5em;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
blockquote
|
||||
{
|
||||
padding: 1em 2em;
|
||||
margin: 0 0 2em;
|
||||
border-left: 5px solid #eee;
|
||||
}
|
||||
|
||||
hr
|
||||
{
|
||||
height: 0;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 2em;
|
||||
border: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
table
|
||||
{
|
||||
background-color: transparent;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
th, td
|
||||
{
|
||||
padding: .5em 1em;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
a:link { color: #0093C5; }
|
||||
a:visited { color: #0093C5; }
|
||||
a:focus { color: black; }
|
||||
a:hover { color: #00B4EF; }
|
||||
a:active { color: #00B4EF; }
|
||||
|
||||
/* -----------------------
|
||||
Layout styles
|
||||
------------------------*/
|
||||
|
||||
.container
|
||||
{
|
||||
max-width: 50em;
|
||||
margin: 0 auto;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.header
|
||||
{
|
||||
color: #fff;
|
||||
background: #333;
|
||||
padding: 1em 1.25em;
|
||||
}
|
||||
|
||||
.header-heading { margin: 0; }
|
||||
|
||||
.nav-bar
|
||||
{
|
||||
background: #000;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.content { padding: 1em 1.25em; }
|
||||
|
||||
.footer
|
||||
{
|
||||
color: #fff;
|
||||
background: #000;
|
||||
|
||||
}
|
||||
|
||||
.alert
|
||||
{
|
||||
padding: 1em 1.25em;
|
||||
border-radius: 2px;
|
||||
border-width: thin;
|
||||
border-color: #ccc;
|
||||
background: #eee;
|
||||
}
|
||||
/* -----------------------
|
||||
Nav
|
||||
------------------------*/
|
||||
|
||||
.nav
|
||||
{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.nav li
|
||||
{
|
||||
display: inline;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.nav a
|
||||
{
|
||||
display: block;
|
||||
padding: .7em 1.25em;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid gray;
|
||||
}
|
||||
|
||||
.nav a:link { color: white; }
|
||||
.nav a:visited { color: white; }
|
||||
|
||||
.nav a:focus
|
||||
{
|
||||
color: black;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.nav a:hover
|
||||
{
|
||||
color: white;
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
.nav a:active
|
||||
{
|
||||
color: white;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
/* -----------------------
|
||||
Single styles
|
||||
------------------------*/
|
||||
|
||||
.img-responsive { max-width: 100%; }
|
||||
|
||||
.btn
|
||||
{
|
||||
color: #fff !important;
|
||||
background-color: royalblue;
|
||||
border-color: #222;
|
||||
display: inline-block;
|
||||
padding: .5em 1em;
|
||||
margin-bottom: 0;
|
||||
font-weight: 400;
|
||||
line-height: 1.2;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
border: 1px solid transparent;
|
||||
border-radius: .2em;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.btn:hover
|
||||
{
|
||||
color: #fff !important;
|
||||
background-color: #0093C5;
|
||||
}
|
||||
|
||||
.btn:focus
|
||||
{
|
||||
color: #fff !important;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
.btn:active
|
||||
{
|
||||
color: #fff !important;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
.table
|
||||
{
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.list-unstyled
|
||||
{
|
||||
padding-left: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.list-inline
|
||||
{
|
||||
padding-left: 0;
|
||||
margin-left: -5px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.list-inline > li
|
||||
{
|
||||
display: inline-block;
|
||||
padding-right: 5px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* -----------------------
|
||||
Wide styles
|
||||
------------------------*/
|
||||
|
||||
@media (min-width: 42em)
|
||||
{
|
||||
.header { padding: 1.5em 3em; }
|
||||
.nav-bar { padding: 1em 3em; }
|
||||
.content { padding: 2em 3em; }
|
||||
.footer { padding: 2em 3em; }
|
||||
|
||||
.nav li
|
||||
{
|
||||
display: inline;
|
||||
margin: 0 1em 0 0;
|
||||
}
|
||||
|
||||
.nav a
|
||||
{
|
||||
display: inline;
|
||||
padding: 0;
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<title>Backing Up Your Private Keys | High Fidelity</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 1200 95" style="enable-background:new 0 0 1200 95;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st15{fill:#10bcff;}
|
||||
.st16{fill:#939598;}
|
||||
</style>
|
||||
<g id="Layer_1_1_">
|
||||
<path class="st15" d="M144,35.8v29.2h-6.3V52.3h-10.3v12.8h-6.3V35.8h6.3v11.3h10.3V35.8H144z"/>
|
||||
<path class="st15" d="M155.1,65.1h-6.3V35.8h6.3V65.1z"/>
|
||||
<path class="st15" d="M173.2,40.5c-1.5,0-2.7,0.1-3.8,0.4c-1,0.3-1.8,0.8-2.5,1.4c-0.6,0.6-1.1,1.6-1.4,2.7s-0.4,2.5-0.4,4.2v2.7
|
||||
c0,1.8,0.1,3.2,0.4,4.3c0.2,1.1,0.6,2,1.2,2.6c0.5,0.6,1.3,1.1,2.2,1.3c0.9,0.2,2,0.4,3.3,0.4c0.4,0,0.8,0,1.2-0.1
|
||||
c0.4,0,0.8-0.1,1.3-0.1v-7.9h-3.7l0.6-4.8h9v16.7c-1.1,0.4-2.5,0.7-4.3,0.9c-1.7,0.2-3.4,0.4-5.2,0.4c-2.2,0-4.1-0.3-5.7-0.8
|
||||
c-1.6-0.5-2.8-1.4-3.8-2.5c-1-1.1-1.7-2.5-2.2-4.2c-0.5-1.7-0.6-3.7-0.6-5.9v-3c0-2.1,0.2-3.9,0.6-5.6c0.5-1.7,1.2-3.1,2.3-4.3
|
||||
c1.1-1.2,2.5-2.1,4.2-2.8c1.7-0.6,3.9-1,6.5-1c1.4,0,2.8,0.1,4.2,0.4c1.4,0.2,2.5,0.5,3.4,0.8l-1,4.7c-0.8-0.2-1.7-0.4-2.6-0.6
|
||||
C175.5,40.5,174.5,40.5,173.2,40.5z"/>
|
||||
<path class="st15" d="M208.8,35.8v29.2h-6.3V52.3h-10.3v12.8H186V35.8h6.3v11.3h10.3V35.8H208.8z"/>
|
||||
<path class="st15" d="M242.2,35.8l-0.7,5.1h-10.9V47h10.1l-0.7,5.1h-9.4v13h-6.3V35.8H242.2z"/>
|
||||
<path class="st15" d="M252.3,65.1h-6.3V35.8h6.3V65.1z"/>
|
||||
<path class="st15" d="M257.4,35.8h9.6c2.5,0,4.5,0.4,6.2,1s3,1.6,4,2.7c1,1.2,1.7,2.5,2.1,4.2c0.4,1.7,0.6,3.4,0.6,5.3v2.8
|
||||
c0,1.9-0.2,3.7-0.6,5.4c-0.4,1.7-1.1,3-2.1,4.2c-1,1.2-2.3,2.1-4,2.7c-1.7,0.6-3.7,1-6.2,1h-9.5L257.4,35.8L257.4,35.8z M263.6,60
|
||||
h2.7c1.2,0,2.2-0.1,3.1-0.4c0.9-0.3,1.7-0.8,2.2-1.4s1-1.5,1.3-2.6c0.3-1.1,0.4-2.4,0.4-4.1v-2.2c0-1.7-0.1-3-0.4-4.1
|
||||
c-0.3-1.1-0.7-1.9-1.3-2.6s-1.3-1.1-2.2-1.4c-0.9-0.2-1.9-0.4-3.1-0.4h-2.7V60z"/>
|
||||
<path class="st15" d="M302,35.8l-0.6,4.9h-11.3v6.4h10.6l-0.6,4.9h-10v8.2h11.9l-0.6,4.9h-17.6V35.8H302z"/>
|
||||
<path class="st15" d="M312.4,35.8V60h11.9l-0.7,5.1h-17.4V35.8H312.4z"/>
|
||||
<path class="st15" d="M334.6,65.1h-6.3V35.8h6.3V65.1z"/>
|
||||
<path class="st15" d="M361.6,35.8l-0.7,5.1H353v24.2h-6.3V40.9h-8.6l0.7-5.1C338.8,35.8,361.6,35.8,361.6,35.8z"/>
|
||||
<path class="st15" d="M376.5,47.2l6.1-11.4h6.4l-9.6,16.5v12.8h-6.3V52.3l-9.5-16.5h6.9L376.5,47.2z"/>
|
||||
<g>
|
||||
<path class="st15" d="M58.8,92c-5.9,0-11.7-1.2-17.1-3.4c-5.3-2.2-9.9-5.4-13.9-9.4c-4-4-7.2-8.7-9.4-13.9C16,59.7,14.8,54,14.8,48
|
||||
c0-5.9,1.2-11.7,3.4-17.1c2.2-5.3,5.4-9.9,9.4-13.9s8.7-7.2,13.9-9.4C47,5.3,52.7,4.2,58.7,4.2s11.7,1.2,17.1,3.4
|
||||
C81,9.8,85.7,13,89.7,17s7.2,8.7,9.4,13.9c2.3,5.4,3.4,11.2,3.4,17.1s-1.2,11.7-3.4,17.1c-2.2,5.3-5.4,9.9-9.4,13.9
|
||||
c-4,4-8.7,7.2-13.9,9.4C70.5,90.8,64.7,92,58.8,92z M58.8,8.7C37.1,8.7,19.4,26.4,19.4,48s17.7,39.4,39.4,39.4S98.1,69.7,98.1,48
|
||||
S80.5,8.7,58.8,8.7z"/>
|
||||
<path class="st15" d="M72.2,66.7V35.9c1.9-0.6,3.3-2.5,3.3-4.6c0-2.7-2.2-4.8-4.8-4.8c-2.7,0-4.8,2.2-4.8,4.8
|
||||
c0,2.1,1.2,3.8,3.1,4.5v14.4l-20.1-9.3V29.5c1.9-0.6,3.3-2.5,3.3-4.6c0-2.7-2.2-4.8-4.8-4.8c-2.7,0-4.8,2.2-4.8,4.8
|
||||
c0,2.1,1.2,3.8,3.1,4.5v31c-1.8,0.7-3.1,2.5-3.1,4.5c0,2.7,2.2,4.8,4.8,4.8c2.7,0,4.8-2.2,4.8-4.8c0-2.1-1.4-4-3.3-4.6V44.7
|
||||
l20.1,9.3v12.7c-1.8,0.7-3.1,2.5-3.1,4.5c0,2.7,2.2,4.8,4.8,4.8c2.7,0,4.8-2.2,4.8-4.8C75.5,69.1,74.1,67.4,72.2,66.7z"/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st16" d="M418.8,34h2.6v38.6h-2.6V34z"/>
|
||||
<path class="st16" d="M471.1,35.3v29.9h-2.7V50.8h-15.6v14.4h-2.7V35.3h2.7v13h15.6v-13H471.1z"/>
|
||||
<path class="st16" d="M480.1,55.4c0,1.5,0.2,2.7,0.4,3.8c0.3,1,0.7,1.9,1.3,2.5c0.6,0.7,1.5,1.1,2.5,1.4s2.4,0.4,4,0.4
|
||||
c0.9,0,1.8-0.1,2.8-0.2c1-0.1,1.8-0.3,2.5-0.4l-0.3,2.1c-0.6,0.2-1.5,0.4-2.5,0.5c-1,0.1-2,0.2-3,0.2c-1.9,0-3.5-0.2-4.8-0.7
|
||||
c-1.3-0.4-2.4-1.1-3.2-1.9c-0.8-0.9-1.4-1.9-1.7-3.2c-0.4-1.3-0.5-2.8-0.5-4.5v-1.6c0-1.6,0.2-3,0.5-4.3c0.3-1.3,0.9-2.4,1.6-3.3
|
||||
c0.7-0.9,1.7-1.6,2.8-2.1c1.1-0.5,2.5-0.7,4.2-0.7c1.4,0,2.7,0.2,3.7,0.7c1,0.4,1.9,1,2.6,1.8c0.7,0.8,1.2,1.7,1.5,2.7
|
||||
c0.3,1,0.5,2.2,0.5,3.5v1.2c0,0.8-0.1,1.4-0.4,1.8c-0.2,0.3-0.8,0.5-1.6,0.5H480.1z M486.5,45.4c-1.1,0-2,0.1-2.8,0.4
|
||||
c-0.8,0.3-1.5,0.7-2,1.4s-0.9,1.4-1.2,2.5c-0.3,1-0.4,2.3-0.4,3.7h12.3v-1.5c0-2.2-0.5-3.8-1.4-4.9C490.1,46,488.6,45.4,486.5,45.4z
|
||||
"/>
|
||||
<path class="st16" d="M500.8,34h2.6v31.2h-2.6V34z"/>
|
||||
<path class="st16" d="M528.3,55.5c0,1.8-0.2,3.3-0.7,4.6c-0.4,1.3-1.1,2.3-1.9,3.2c-0.8,0.8-1.8,1.4-2.9,1.8
|
||||
c-1.1,0.4-2.4,0.6-3.7,0.6c-0.7,0-1.3,0-1.8-0.1c-0.5-0.1-1.1-0.1-1.6-0.3c-0.5-0.1-1-0.3-1.5-0.5c-0.5-0.2-1-0.4-1.6-0.7V75h-2.6
|
||||
V43.7h2.2l0.3,2.9c1.5-2.3,4-3.4,7.4-3.4c1.2,0,2.4,0.2,3.4,0.5c1,0.4,1.9,1,2.6,1.8c0.7,0.8,1.3,1.9,1.7,3.2
|
||||
c0.4,1.3,0.6,2.9,0.6,4.8V55.5z M525.7,54.1c0-1.3-0.1-2.5-0.3-3.6c-0.2-1.1-0.5-2-1-2.7c-0.5-0.7-1.1-1.3-2-1.7
|
||||
c-0.8-0.4-1.8-0.6-3.1-0.6c-1.3,0-2.3,0.2-3.2,0.5c-0.9,0.3-1.5,0.8-2.1,1.4c-0.5,0.6-0.9,1.4-1.1,2.3c-0.2,0.9-0.3,2-0.3,3.2v9
|
||||
c1,0.5,1.9,0.9,2.8,1.2c0.9,0.2,2,0.4,3.2,0.4c1.3,0,2.4-0.2,3.3-0.5c0.9-0.3,1.6-0.9,2.1-1.6c0.5-0.7,0.9-1.6,1.2-2.6
|
||||
c0.2-1.1,0.4-2.3,0.4-3.6V54.1z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="main">
|
||||
|
||||
<h1>Backing Up Your Private Keys</h1>
|
||||
<hr>
|
||||
|
||||
<!-- Paragraphs -->
|
||||
<h3>What are private keys?</h3>
|
||||
<p>A private key is a secret piece of text that is used to prove ownership, unlock confidential information and sign transactions.</p>
|
||||
<p>In High Fidelity, your private keys are used to securely access the contents of your Wallet and Purchases.</p>
|
||||
|
||||
<hr>
|
||||
<h3>Where are my private keys stored?"</h3>
|
||||
<p>By default, your private keys are only stored on your hard drive in High Fidelity Interface's <code>AppData</code> directory.</p>
|
||||
<p>Here is the file path of your hifikey - you can browse to it using your file explorer.</p>
|
||||
<div class="alert"> <code>HIFIKEY_PATH_REPLACEME</code> </div>
|
||||
|
||||
<hr>
|
||||
<h3>How should I make a backup of my private keys?</h3>
|
||||
<p>You should backup your <code>.hifikey</code> file above by copying it to a USB flash drive, or to a service like Dropbox or Google Drive. Restore your backup by replacing the file in Interface's AppData directory with your backed-up copy.</p>
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 497.3 186.1" style="enable-background:new 0 0 497.3 186.1;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#CECECE;}
|
||||
.st1{fill:#FFFFFF;}
|
||||
.st2{fill:#FEFEFE;}
|
||||
.st3{fill:#0DA860;}
|
||||
.st4{fill:#F9C942;}
|
||||
.st5{fill:#367CF3;}
|
||||
.st6{fill:#2D6FDC;}
|
||||
.st7{fill:#E4B83D;}
|
||||
.st8{fill:#08137C;}
|
||||
.st9{fill:#EF3B4E;}
|
||||
.st10{fill:#B8355B;}
|
||||
.st11{fill:#A7C5D1;}
|
||||
.st12{fill:#7C909B;}
|
||||
.st13{fill:#CBF2FD;}
|
||||
.st14{fill:#000222;}
|
||||
</style>
|
||||
<circle class="st0" cx="255" cy="69.5" r="61.1"/>
|
||||
<circle class="st0" cx="88" cy="69.5" r="61.1"/>
|
||||
<circle class="st1" cx="88" cy="65.5" r="61.1"/>
|
||||
<path class="st2" d="M133.4,78c0-0.1-0.1-0.2-0.1-0.3c-5-8.7-10-17.4-15-26c-4.7-8.2-9.4-16.3-14.1-24.5c-0.2-0.3-0.4-0.4-0.7-0.4
|
||||
c-10.2,0-20.4,0-30.6,0c-0.2,0-0.3,0-0.5,0c-0.1,0.1-0.2,0.2-0.2,0.3c-9.7,16.8-19.4,33.6-29.1,50.5c-0.2,0.3-0.2,0.5,0,0.8
|
||||
c4.2,7.2,8.4,14.5,12.6,21.7c1,1.7,2,3.5,3,5.2c0.1,0.1,0.3,0.1,0.5,0.1c19.4,0,38.8,0,58.2,0c0.4,0,0.6-0.1,0.8-0.4
|
||||
c4.3-7.4,8.6-14.9,12.9-22.3C131.6,81.1,132.5,79.6,133.4,78z"/>
|
||||
<path class="st3" d="M58.5,105.3c-1-1.7-2-3.4-3-5.2c-4.2-7.2-8.4-14.5-12.6-21.7c-0.2-0.3-0.2-0.5,0-0.8
|
||||
C52.6,60.8,62.3,43.9,72,27.1c0.1-0.1,0.1-0.2,0.2-0.3c0.1,0.1,0.2,0.2,0.2,0.4c5.1,8.9,10.3,17.8,15.4,26.6
|
||||
c0.1,0.1,0.2,0.2,0.2,0.4c-0.1,0.1-0.2,0.2-0.2,0.3c-3.2,5.5-6.4,11-9.6,16.5c-1.3,2.3-2.6,4.6-4,6.9c-0.1,0.1-0.2,0.2-0.2,0.3
|
||||
c-1.9,3.3-3.8,6.6-5.7,9.9c-2.7,4.7-5.5,9.4-8.2,14.2c-0.5,0.9-1.1,1.8-1.5,2.7c0,0,0,0,0,0c0,0.1-0.1,0.1-0.1,0.2
|
||||
C58.6,105.2,58.5,105.3,58.5,105.3z"/>
|
||||
<path class="st4" d="M88.1,54.2c0-0.2-0.1-0.3-0.2-0.4C82.8,44.9,77.6,36,72.5,27.2c-0.1-0.1-0.2-0.2-0.2-0.4c0.2-0.1,0.3,0,0.5,0
|
||||
c10.2,0,20.4,0,30.6,0c0.3,0,0.5,0.1,0.7,0.4c4.7,8.2,9.4,16.3,14.1,24.5c5,8.7,10,17.4,15,26c0.1,0.1,0.1,0.2,0.1,0.3
|
||||
c-0.1,0-0.1,0-0.2,0c0-0.1-0.1-0.1-0.2-0.1c-3.6-1.1-7.2-2.2-10.7-3.3c-2.5-0.8-4.9-1.5-7.4-2.3c-4.2-1.3-8.4-2.6-12.6-3.9
|
||||
c-2.3-0.7-4.6-1.4-6.8-2.1c-0.1,0-0.3-0.1-0.4,0c0,0-0.1-0.1-0.1-0.1c-1.6-2.7-3.1-5.4-4.7-8.1C89.6,56.8,88.8,55.5,88.1,54.2z"/>
|
||||
<path class="st5" d="M133.2,78c0.1,0,0.1,0,0.2,0c-0.9,1.5-1.8,3.1-2.6,4.6c-4.3,7.4-8.6,14.8-12.9,22.3c-0.2,0.3-0.4,0.4-0.8,0.4
|
||||
c-19.4,0-38.8,0-58.2,0c-0.2,0-0.3,0.1-0.5-0.1c0,0,0.1-0.1,0.1-0.1c0.1,0,0.1-0.1,0.1-0.2c0,0,0,0,0,0c0.3-0.1,0.5-0.3,0.8-0.5
|
||||
c1.1-1,2.3-2.1,3.4-3.2c1.6-1.5,3.2-3,4.8-4.5c1.1-1.1,2.3-2.1,3.4-3.2c1.6-1.5,3.3-3,4.9-4.5c1.2-1.1,2.3-2.1,3.5-3.2
|
||||
c1.8-1.7,3.6-3.4,5.4-5c0.8-0.8,1.7-1.5,2.5-2.4c0.2-0.2,0.5-0.2,0.5-0.5c1.5,0,3,0,4.5,0c3.1,0,6.2,0,9.3,0
|
||||
c0.2,0.1,0.3,0.1,0.5,0.1c10.1,0,20.3,0,30.4,0C132.9,78,133.1,78,133.2,78z"/>
|
||||
<path class="st2" d="M101.8,78c-3.1,0-6.2,0-9.3,0c-1.5,0-3,0-4.5,0c-0.2,0-0.4,0-0.5,0c-3.9,0-7.8,0-11.7,0c-0.5,0-0.9,0-1.4,0
|
||||
c1.3-2.3,2.6-4.6,4-6.9c3.2-5.5,6.4-11,9.6-16.5c0.1-0.1,0.1-0.2,0.2-0.3c0.8,1.3,1.5,2.6,2.3,3.9c1.6,2.7,3.1,5.4,4.7,8.1
|
||||
c0,0,0.1,0.1,0.1,0.1c1.2,2,2.3,4,3.5,6C99.6,74.2,100.7,76.1,101.8,78z"/>
|
||||
<path class="st6" d="M74.3,78c0.5,0,0.9,0,1.4,0c3.9,0,7.8,0,11.7,0c0.2,0,0.4,0,0.5,0c-0.1,0.3-0.3,0.4-0.5,0.5
|
||||
c-0.8,0.8-1.7,1.6-2.5,2.4c-1.8,1.7-3.6,3.4-5.4,5c-1.2,1.1-2.3,2.1-3.5,3.2c-1.6,1.5-3.2,3-4.9,4.5c-1.2,1.1-2.3,2.1-3.4,3.2
|
||||
c-1.6,1.5-3.2,3-4.8,4.5c-1.1,1.1-2.3,2.1-3.4,3.2c-0.2,0.2-0.4,0.4-0.8,0.5c0.4-0.9,1-1.8,1.5-2.7c2.7-4.7,5.4-9.4,8.2-14.2
|
||||
c1.9-3.3,3.8-6.6,5.7-9.9C74.2,78.1,74.2,78.1,74.3,78z"/>
|
||||
<path class="st6" d="M58.7,105c0,0.1,0,0.2-0.1,0.2C58.6,105.1,58.7,105.1,58.7,105z"/>
|
||||
<path class="st7" d="M101.8,78c-1.1-1.9-2.2-3.8-3.3-5.7c-1.1-2-2.3-4-3.5-6c0.1-0.2,0.3-0.1,0.4,0c2.3,0.7,4.6,1.4,6.8,2.1
|
||||
c4.2,1.3,8.4,2.6,12.6,3.9c2.5,0.8,4.9,1.5,7.4,2.3c3.6,1.1,7.2,2.2,10.7,3.3c0.1,0,0.2,0,0.2,0.1c-0.2,0-0.3,0-0.5,0
|
||||
c-10.1,0-20.3,0-30.4,0C102.1,78,101.9,78.1,101.8,78z"/>
|
||||
<g>
|
||||
<path class="st1" d="M315.5,65.6c0.1-33.6-27.3-60.9-61-61c-33.6-0.1-61,27.2-61,60.9c-0.1,33.6,27.2,61,61,61.1
|
||||
C288.1,126.6,315.5,99.3,315.5,65.6z"/>
|
||||
<path class="st1" d="M315.5,65.6c-0.1,33.7-27.4,61.1-61,61c-33.7-0.1-61-27.4-61-61.1c0.1-33.7,27.4-61,61-60.9
|
||||
C288.3,4.6,315.6,31.9,315.5,65.6z M297.6,45.8c-0.1-0.1-0.2-0.1-0.3-0.2c-7-4.4-14-8.9-20.9-13.4c-0.3-0.2-0.4-0.1-0.7,0
|
||||
c-6.9,4.4-13.9,8.8-20.8,13.3c-0.4,0.3-0.4,0.3,0,0.5c6.9,4.4,13.8,8.8,20.7,13.2c0.1,0.1,0.3,0.2,0.4,0.3
|
||||
c-7.2,4.6-14.3,9.1-21.5,13.7c0.2,0.1,0.3,0.2,0.5,0.3c6.9,4.4,13.8,8.8,20.7,13.2c0.3,0.2,0.5,0.2,0.8,0c6.7-4.3,13.3-8.5,20-12.7
|
||||
c0.4-0.2,0.8-0.5,1.2-0.8c-7.2-4.6-14.4-9.1-21.6-13.7C283.2,55,290.4,50.4,297.6,45.8z M254.5,73.3c-7.2-4.6-14.4-9.2-21.6-13.7
|
||||
c0.2-0.1,0.4-0.2,0.5-0.3c6.9-4.4,13.7-8.7,20.6-13.1c0.4-0.3,0.4-0.3,0-0.6c-6.9-4.4-13.8-8.8-20.7-13.2c-0.3-0.2-0.5-0.2-0.8,0
|
||||
c-6.9,4.4-13.8,8.8-20.7,13.2c-0.4,0.3-0.4,0.3,0,0.6c5.3,3.4,10.6,6.8,15.9,10.1c1.7,1.1,3.4,2.2,5.2,3.3
|
||||
c-7.2,4.6-14.4,9.1-21.6,13.7c0.2,0.1,0.3,0.2,0.5,0.3c6.9,4.4,13.8,8.8,20.7,13.2c0.3,0.2,0.5,0.2,0.8,0
|
||||
c5.1-3.3,10.2-6.5,15.4-9.8C250.6,75.8,252.5,74.5,254.5,73.3z M275.9,91.6c-0.1-0.1-0.2-0.2-0.3-0.2c-6.9-4.4-13.9-8.8-20.8-13.3
|
||||
c-0.2-0.2-0.4-0.2-0.7,0c-6.9,4.4-13.9,8.9-20.8,13.3c-0.1,0.1-0.2,0.2-0.4,0.3c0.2,0.1,0.3,0.2,0.4,0.3
|
||||
c6.9,4.4,13.9,8.8,20.8,13.3c0.3,0.2,0.5,0.1,0.7,0c6.9-4.4,13.8-8.8,20.7-13.2C275.7,91.8,275.8,91.7,275.9,91.6z"/>
|
||||
<path class="st8" d="M297.6,45.8c-7.2,4.6-14.4,9.1-21.6,13.7c7.2,4.6,14.4,9.1,21.6,13.7c-0.4,0.3-0.8,0.5-1.2,0.8
|
||||
c-6.7,4.2-13.3,8.5-20,12.7c-0.3,0.2-0.5,0.2-0.8,0c-6.9-4.4-13.8-8.8-20.7-13.2c-0.1-0.1-0.3-0.2-0.5-0.3
|
||||
c7.2-4.6,14.3-9.1,21.5-13.7c-0.2-0.1-0.3-0.2-0.4-0.3c-6.9-4.4-13.8-8.8-20.7-13.2c-0.4-0.3-0.4-0.3,0-0.5
|
||||
c6.9-4.4,13.9-8.8,20.8-13.3c0.2-0.2,0.4-0.2,0.7,0c7,4.5,14,8.9,20.9,13.4C297.4,45.7,297.4,45.7,297.6,45.8z"/>
|
||||
<path class="st8" d="M254.5,73.3c-2,1.3-3.9,2.5-5.8,3.7c-5.1,3.3-10.3,6.5-15.4,9.8c-0.3,0.2-0.5,0.2-0.8,0
|
||||
c-6.9-4.4-13.8-8.8-20.7-13.2c-0.1-0.1-0.3-0.2-0.5-0.3c7.2-4.6,14.3-9.1,21.6-13.7c-1.8-1.1-3.5-2.2-5.2-3.3
|
||||
c-5.3-3.4-10.6-6.8-15.9-10.1c-0.4-0.3-0.4-0.3,0-0.6c6.9-4.4,13.8-8.8,20.7-13.2c0.3-0.2,0.5-0.2,0.8,0
|
||||
c6.9,4.4,13.8,8.8,20.7,13.2c0.4,0.3,0.4,0.3,0,0.6c-6.9,4.4-13.7,8.7-20.6,13.1c-0.2,0.1-0.3,0.2-0.5,0.3
|
||||
C240.1,64.1,247.2,68.7,254.5,73.3z"/>
|
||||
<path class="st8" d="M275.9,91.6c-0.1,0.2-0.3,0.2-0.4,0.3c-6.9,4.4-13.8,8.8-20.7,13.2c-0.2,0.2-0.4,0.2-0.7,0
|
||||
c-6.9-4.4-13.9-8.9-20.8-13.3c-0.1-0.1-0.2-0.1-0.4-0.3c0.1-0.1,0.3-0.2,0.4-0.3c6.9-4.4,13.9-8.8,20.8-13.3c0.3-0.2,0.4-0.1,0.7,0
|
||||
c6.9,4.4,13.9,8.9,20.8,13.3C275.7,91.4,275.8,91.5,275.9,91.6z"/>
|
||||
</g>
|
||||
<path class="st9" d="M389.9,117c-6.8-6.8-13.7-13.6-20.5-20.5c-1.9-2-1.8-5.6,0.1-7.7c0.2-0.3,0.5-0.5,0.8-0.8
|
||||
c15.9-15.9,31.8-31.7,47.6-47.6c2.6-2.6,5.9-1.9,7.8-0.1c0.3,0.3,0.6,0.6,0.9,0.9c6.2,6.2,12.5,12.5,18.7,18.7
|
||||
c0.3,0.3,0.6,0.6,0.9,1c0.1,0.3,0.3,0.6,0.4,0.8c0.8,1.7,0.4,4-0.9,5.2c-16.4,16.3-32.7,32.7-49.1,49c-0.2,0.2-0.4,0.4-0.7,0.6
|
||||
C394,117.8,392,117.9,389.9,117z M423.3,62.2c-2,0.5-3.9,1-5.8,1.6c-1.6,0.4-1.6,0.4-0.4,1.6c0.4,0.4,0.5,0.7,0,1.1
|
||||
c-5,5-9.9,9.9-14.9,14.9c-0.1,0.1-0.3,0.4-0.5,0.2c-0.1-0.1-0.1-0.3-0.1-0.5c0-1.5-0.1-2.9-0.1-4.4c0-0.6,0.2-1.1,0.7-1.6
|
||||
c1.2-1.2,2.4-2.4,3.6-3.6c0.3-0.3,0.6-0.5,1.2-0.4c1.7,0.2,3.2-1.2,3.2-2.9c0-1.9-1.4-3.2-3.2-3.1c-1.8,0.1-3.1,1.6-2.8,3.4
|
||||
c0.1,0.4-0.1,0.7-0.4,1c-1.2,1.1-2.3,2.3-3.5,3.4c-1.2,1.1-1.7,2.4-1.6,4c0.1,2.2,0.1,4.5,0.1,6.7c0,1.3-1,2-1.7,2.7
|
||||
c-0.5,0.5-1,0-1.5-0.1c-2.2-0.5-4.4,0.7-5.3,2.7c-0.9,2.2-0.1,4.5,1.8,5.7c1.8,1.1,3.8,0.9,5.6-0.5c1.2-1,1.8-3.1,1.2-4.9
|
||||
c-0.2-0.6-0.1-1,0.3-1.4c1.7-1.6,3.3-3.3,4.9-4.9c0.5-0.5,1-0.7,1.6-0.7c2.1,0,4.2,0,6.3,0.2c1.7,0.1,3.3-0.3,4.5-1.6
|
||||
c0.4-0.5,0.9-0.9,1.4-1.4c0.5-0.6,0.9-0.6,1.3,0c0.3,0.4,0.6,0.5,1,0c1.1-1.1,2.2-2.2,3.3-3.3c0.4-0.4,0.4-0.6,0-1
|
||||
c-1.1-1.1-2.2-2.2-3.3-3.3c-0.4-0.4-0.7-0.3-1,0.1c-1,1-2,2.1-3.1,3.1c-0.5,0.5-0.7,0.8,0,1.3c0.3,0.2,0.6,0.5,0.2,0.9
|
||||
c-0.6,0.6-1.3,1.3-1.9,1.9c-0.4,0.3-0.9,0.6-1.5,0.5c-1.5-0.2-2.9-0.1-4.4-0.1c-0.2,0-0.5,0.1-0.6-0.1c0-0.1,0-0.1,0-0.2
|
||||
c3.7-3.7,7.4-7.4,11.1-11.1c0.4-0.4,0.6-0.2,0.9,0.1c1.3,1.2,1.3,1.1,1.7-0.5C422.3,66,422.8,64.1,423.3,62.2z"/>
|
||||
<path class="st10" d="M389.9,117c2.1,0.9,4.1,0.9,6-0.4c0.3-0.2,0.5-0.4,0.7-0.6c16.4-16.3,32.7-32.7,49.1-49
|
||||
c1.3-1.3,1.7-3.5,0.9-5.2c-0.1-0.3-0.2-0.6-0.4-0.8c1.4,1.4,2.7,2.7,4.1,4.1c0.6,0.6,1.3,1.2,1.8,1.9c1.7,2.2,1.5,4.8-0.5,6.8
|
||||
c-7.8,7.8-15.7,15.7-23.5,23.5c-8.3,8.3-16.5,16.5-24.8,24.8c-1,1-2.1,1.6-3.4,1.9c-1.8,0.3-3.4-0.1-4.7-1.4
|
||||
C393.5,120.5,391.7,118.8,389.9,117z"/>
|
||||
<path class="st11" d="M445.3,59.9c-6.2-6.2-12.5-12.5-18.7-18.7c5-5,10.1-10,15.1-15.1c0.6-0.6,0.8-0.6,1.4,0c6,6,12,12,18,18
|
||||
C455.9,49.4,450.6,54.7,445.3,59.9z M439.3,37.5c-0.5-0.5-0.9-1-1.4-1.4c-0.5-0.5-1.1-0.5-1.6,0c-0.4,0.4-0.8,0.8-1.2,1.2
|
||||
c-0.5,0.6-0.5,1.1,0,1.7c0.5,0.6,1.1,1.1,1.7,1.7c2,2.2,2,1.7,3.9-0.1c0,0,0,0,0.1-0.1c0.5-0.5,0.5-1.1,0-1.6
|
||||
C440.3,38.4,439.8,38,439.3,37.5z M449,47.2c-0.5-0.5-1-1-1.5-1.5c-0.7-0.6-1.1-0.5-2.5,1c-0.8,0.8-0.9,1.3-0.3,1.9
|
||||
c0.9,1,1.9,1.9,2.9,2.9c0.7,0.6,1.1,0.5,2.5-1c0.8-0.8,0.9-1.3,0.3-1.9C449.9,48.1,449.5,47.6,449,47.2z"/>
|
||||
<path class="st12" d="M445.3,59.9c5.3-5.3,10.5-10.5,15.8-15.8c1.5,1.5,3,3,4.5,4.4c0.5,0.5,0.4,0.7,0,1.1
|
||||
c-4.9,4.8-9.7,9.7-14.6,14.5c-0.2,0.2-0.5,0.5-0.7,0.7c-1.4-1.4-2.7-2.7-4.1-4.1C445.9,60.6,445.6,60.2,445.3,59.9z"/>
|
||||
<path class="st1" d="M423.3,62.2c-0.5,2-1,3.8-1.5,5.6c-0.5,1.7-0.5,1.7-1.7,0.5c-0.3-0.3-0.6-0.4-0.9-0.1
|
||||
c-3.7,3.7-7.4,7.4-11.1,11.1c0,0,0,0.1,0,0.2c0.2,0.2,0.4,0.1,0.6,0.1c1.5,0.1,2.9-0.1,4.4,0.1c0.6,0.1,1.1-0.2,1.5-0.5
|
||||
c0.7-0.6,1.3-1.2,1.9-1.9c0.4-0.4,0.1-0.7-0.2-0.9c-0.6-0.5-0.5-0.8,0-1.3c1.1-1,2.1-2,3.1-3.1c0.4-0.4,0.6-0.5,1-0.1
|
||||
c1.1,1.1,2.2,2.2,3.3,3.3c0.4,0.4,0.4,0.6,0,1c-1.1,1.1-2.2,2.2-3.3,3.3c-0.4,0.4-0.7,0.4-1,0c-0.5-0.6-0.9-0.6-1.3,0
|
||||
c-0.4,0.5-0.9,0.9-1.4,1.4c-1.2,1.4-2.7,1.7-4.5,1.6c-2.1-0.1-4.2-0.1-6.3-0.2c-0.6,0-1.2,0.3-1.6,0.7c-1.6,1.7-3.3,3.3-4.9,4.9
|
||||
c-0.4,0.4-0.6,0.8-0.3,1.4c0.6,1.7,0,3.9-1.2,4.9c-1.8,1.4-3.8,1.6-5.6,0.5c-2-1.2-2.7-3.6-1.8-5.7c0.8-2.1,3.1-3.2,5.3-2.7
|
||||
c0.5,0.1,1,0.6,1.5,0.1c0.8-0.8,1.8-1.4,1.7-2.7c-0.1-2.2-0.1-4.5-0.1-6.7c0-1.6,0.5-2.9,1.6-4c1.2-1.1,2.3-2.3,3.5-3.4
|
||||
c0.3-0.3,0.4-0.6,0.4-1c-0.2-1.8,1.1-3.3,2.8-3.4c1.8-0.1,3.2,1.3,3.2,3.1c0,1.7-1.5,3.1-3.2,2.9c-0.5-0.1-0.8,0.1-1.2,0.4
|
||||
c-1.2,1.2-2.4,2.4-3.6,3.6c-0.5,0.4-0.7,0.9-0.7,1.6c0,1.5,0.1,2.9,0.1,4.4c0,0.2,0,0.4,0.1,0.5c0.2,0.1,0.3-0.1,0.5-0.2
|
||||
c5-5,9.9-9.9,14.9-14.9c0.4-0.4,0.4-0.7,0-1.1c-1.1-1.2-1.1-1.2,0.4-1.6C419.4,63.2,421.3,62.7,423.3,62.2z"/>
|
||||
<path class="st13" d="M439.3,37.5c0.5,0.5,0.9,0.9,1.4,1.4c0.5,0.5,0.5,1,0,1.6c0,0,0,0-0.1,0.1c-1.9,1.9-1.9,2.3-3.9,0.1
|
||||
c-0.5-0.6-1.1-1.1-1.7-1.7c-0.6-0.6-0.6-1.1,0-1.7c0.4-0.4,0.8-0.8,1.2-1.2c0.5-0.5,1.1-0.5,1.6,0C438.4,36.6,438.9,37.1,439.3,37.5
|
||||
z"/>
|
||||
<path class="st13" d="M449,47.2c0.5,0.5,0.9,0.9,1.4,1.4c0.6,0.6,0.5,1.1-0.3,1.9c-1.4,1.5-1.8,1.6-2.5,1c-1-0.9-1.9-1.9-2.9-2.9
|
||||
c-0.6-0.6-0.5-1.1,0.3-1.9c1.4-1.5,1.8-1.6,2.5-1C448,46.2,448.5,46.7,449,47.2z"/>
|
||||
<g>
|
||||
<path class="st14" d="M32.1,158.8l0.2-1.2h4.2v7.7c-0.2,0.1-0.5,0.2-0.8,0.3c-0.3,0.1-0.7,0.2-1,0.2c-0.4,0.1-0.7,0.1-1.1,0.1
|
||||
s-0.7,0-1,0c-1.4,0-2.6-0.2-3.5-0.5c-0.9-0.4-1.5-0.8-2-1.5c-0.5-0.6-0.8-1.4-0.9-2.3c-0.1-0.9-0.2-1.9-0.2-2.9v-1.6
|
||||
c0-1.2,0.1-2.2,0.3-3.1c0.2-0.9,0.6-1.7,1.1-2.3s1.2-1.1,2.1-1.4c0.9-0.3,2-0.5,3.3-0.5c0.6,0,1.2,0.1,1.8,0.2
|
||||
c0.6,0.1,1.1,0.2,1.6,0.4l-0.3,1.1c-0.4-0.1-0.9-0.2-1.4-0.3c-0.5-0.1-1.1-0.1-1.7-0.1c-1,0-1.8,0.1-2.4,0.3s-1.2,0.5-1.6,1
|
||||
c-0.4,0.5-0.7,1.1-0.9,1.9s-0.3,1.8-0.3,3v1.5c0,1.2,0.1,2.1,0.3,2.9c0.2,0.8,0.5,1.4,0.9,1.8c0.4,0.5,0.9,0.8,1.6,1
|
||||
c0.7,0.2,1.5,0.3,2.4,0.3c0.5,0,0.9,0,1.4-0.1c0.4,0,0.8-0.1,1.2-0.2v-5.6H32.1z"/>
|
||||
<path class="st14" d="M44.5,154.2c1,0,1.7,0.1,2.4,0.4c0.6,0.2,1.1,0.6,1.5,1.1c0.4,0.5,0.6,1,0.8,1.7c0.2,0.7,0.2,1.4,0.2,2.2v1.2
|
||||
c0,0.8-0.1,1.5-0.3,2.2c-0.2,0.7-0.5,1.2-0.8,1.7c-0.4,0.5-0.9,0.8-1.5,1.1c-0.6,0.2-1.4,0.4-2.3,0.4c-1,0-1.7-0.1-2.4-0.4
|
||||
c-0.6-0.2-1.1-0.6-1.5-1.1s-0.6-1-0.8-1.7c-0.2-0.7-0.2-1.4-0.2-2.2v-1.2c0-0.8,0.1-1.5,0.3-2.2c0.2-0.7,0.5-1.2,0.9-1.7
|
||||
s0.9-0.8,1.5-1.1C42.8,154.3,43.6,154.2,44.5,154.2z M44.5,164.8c0.7,0,1.2-0.1,1.7-0.2s0.8-0.4,1.1-0.7c0.3-0.3,0.5-0.8,0.6-1.3
|
||||
c0.1-0.5,0.2-1.2,0.2-1.9v-1c0-0.8-0.1-1.4-0.2-2s-0.3-1-0.6-1.3c-0.3-0.3-0.6-0.6-1.1-0.7s-1-0.2-1.6-0.2c-0.7,0-1.2,0.1-1.7,0.2
|
||||
c-0.5,0.2-0.8,0.4-1.1,0.7c-0.3,0.3-0.5,0.8-0.6,1.3c-0.1,0.5-0.2,1.2-0.2,1.9v1c0,0.8,0.1,1.4,0.2,1.9c0.1,0.5,0.3,1,0.6,1.3
|
||||
c0.3,0.3,0.6,0.6,1.1,0.7C43.2,164.7,43.8,164.8,44.5,164.8z"/>
|
||||
<path class="st14" d="M57.1,154.2c1,0,1.7,0.1,2.4,0.4c0.6,0.2,1.1,0.6,1.5,1.1c0.4,0.5,0.6,1,0.8,1.7c0.2,0.7,0.2,1.4,0.2,2.2v1.2
|
||||
c0,0.8-0.1,1.5-0.3,2.2c-0.2,0.7-0.5,1.2-0.8,1.7c-0.4,0.5-0.9,0.8-1.5,1.1c-0.6,0.2-1.4,0.4-2.3,0.4c-1,0-1.7-0.1-2.4-0.4
|
||||
c-0.6-0.2-1.1-0.6-1.5-1.1s-0.6-1-0.8-1.7c-0.2-0.7-0.2-1.4-0.2-2.2v-1.2c0-0.8,0.1-1.5,0.3-2.2c0.2-0.7,0.5-1.2,0.9-1.7
|
||||
s0.9-0.8,1.5-1.1C55.4,154.3,56.2,154.2,57.1,154.2z M57.1,164.8c0.7,0,1.2-0.1,1.7-0.2s0.8-0.4,1.1-0.7c0.3-0.3,0.5-0.8,0.6-1.3
|
||||
c0.1-0.5,0.2-1.2,0.2-1.9v-1c0-0.8-0.1-1.4-0.2-2s-0.3-1-0.6-1.3c-0.3-0.3-0.6-0.6-1.1-0.7s-1-0.2-1.6-0.2c-0.7,0-1.2,0.1-1.7,0.2
|
||||
c-0.5,0.2-0.8,0.4-1.1,0.7c-0.3,0.3-0.5,0.8-0.6,1.3c-0.1,0.5-0.2,1.2-0.2,1.9v1c0,0.8,0.1,1.4,0.2,1.9c0.1,0.5,0.3,1,0.6,1.3
|
||||
c0.3,0.3,0.6,0.6,1.1,0.7C55.9,164.7,56.4,164.8,57.1,164.8z"/>
|
||||
<path class="st14" d="M74.3,165.5c0,0.8-0.1,1.6-0.3,2.3c-0.2,0.7-0.5,1.2-0.9,1.7c-0.4,0.5-0.9,0.8-1.6,1.1
|
||||
c-0.6,0.2-1.4,0.4-2.3,0.4c-1.3,0-2.7-0.2-4-0.6l0.3-1.1c0.6,0.2,1.2,0.3,1.8,0.4c0.6,0.1,1.2,0.1,1.9,0.1s1.3-0.1,1.8-0.3
|
||||
c0.5-0.2,0.8-0.5,1.1-0.9c0.3-0.4,0.5-0.9,0.6-1.4c0.1-0.6,0.2-1.2,0.2-1.9v-1.3c-0.1,0.2-0.3,0.5-0.5,0.7
|
||||
c-0.2,0.2-0.5,0.4-0.8,0.6c-0.3,0.2-0.7,0.3-1.1,0.4c-0.4,0.1-0.9,0.1-1.5,0.1c-0.6,0-1.2-0.1-1.8-0.3c-0.5-0.2-1-0.5-1.4-0.9
|
||||
c-0.4-0.4-0.7-1-0.9-1.6c-0.2-0.7-0.3-1.5-0.3-2.5v-0.7c0-0.9,0.1-1.7,0.4-2.4s0.6-1.2,1.1-1.7c0.5-0.5,1-0.8,1.6-1
|
||||
c0.6-0.2,1.3-0.3,2.1-0.3c0.8,0,1.6,0.1,2.3,0.3c0.7,0.2,1.4,0.4,2,0.8V165.5z M66.1,160.1c0,0.7,0.1,1.3,0.2,1.9s0.3,1,0.5,1.4
|
||||
c0.3,0.4,0.6,0.7,1,0.8s0.9,0.3,1.6,0.3c1.2,0,2.1-0.3,2.7-0.9c0.6-0.6,0.9-1.6,0.9-3V156c-0.4-0.2-0.8-0.4-1.3-0.5
|
||||
c-0.4-0.1-1-0.2-1.6-0.2c-1.3,0-2.3,0.3-3,1s-1,1.8-1,3.4V160.1z"/>
|
||||
<path class="st14" d="M77.8,149.3h1.3v16.3h-1.3V149.3z"/>
|
||||
<path class="st14" d="M83.6,160.5c0,0.8,0.1,1.4,0.2,2c0.1,0.5,0.4,1,0.7,1.3c0.3,0.3,0.8,0.6,1.3,0.7c0.5,0.2,1.2,0.2,2.1,0.2
|
||||
c0.5,0,0.9,0,1.5-0.1c0.5-0.1,1-0.1,1.3-0.2l-0.2,1.1c-0.3,0.1-0.8,0.2-1.3,0.3c-0.5,0.1-1.1,0.1-1.6,0.1c-1,0-1.8-0.1-2.5-0.3
|
||||
c-0.7-0.2-1.2-0.6-1.7-1s-0.7-1-0.9-1.7c-0.2-0.7-0.3-1.5-0.3-2.4v-0.9c0-0.8,0.1-1.6,0.3-2.3c0.2-0.7,0.5-1.3,0.8-1.7
|
||||
c0.4-0.5,0.9-0.9,1.5-1.1c0.6-0.3,1.3-0.4,2.2-0.4c0.7,0,1.4,0.1,1.9,0.3c0.5,0.2,1,0.5,1.3,0.9s0.6,0.9,0.8,1.4
|
||||
c0.2,0.5,0.2,1.2,0.2,1.8v0.6c0,0.4-0.1,0.7-0.2,0.9c-0.1,0.2-0.4,0.3-0.8,0.3H83.6z M86.9,155.3c-0.6,0-1,0.1-1.5,0.2
|
||||
s-0.8,0.4-1,0.7c-0.3,0.3-0.5,0.8-0.6,1.3c-0.1,0.5-0.2,1.2-0.2,2h6.5v-0.8c0-1.1-0.2-2-0.7-2.6S88,155.3,86.9,155.3z"/>
|
||||
<path class="st14" d="M100.2,150h4.9c1.3,0,2.3,0.2,3.1,0.5c0.8,0.3,1.5,0.8,2,1.4c0.5,0.6,0.8,1.3,1,2.2c0.2,0.8,0.3,1.7,0.3,2.7
|
||||
v2c0,1-0.1,1.9-0.3,2.8c-0.2,0.8-0.6,1.6-1.1,2.2c-0.5,0.6-1.1,1.1-2,1.4s-1.8,0.5-3.1,0.5h-4.8V150z M101.6,164.5h3.3
|
||||
c0.8,0,1.5-0.1,2.2-0.3c0.6-0.2,1.2-0.5,1.6-0.9c0.4-0.4,0.8-1,1-1.8c0.2-0.7,0.3-1.6,0.3-2.8V157c0-1.1-0.1-2-0.3-2.7
|
||||
c-0.2-0.7-0.5-1.3-0.9-1.8c-0.4-0.4-0.9-0.8-1.6-1c-0.6-0.2-1.4-0.3-2.2-0.3h-3.4V164.5z"/>
|
||||
<path class="st14" d="M120.7,155.6c-0.2,0-0.4-0.1-0.7-0.1c-0.2,0-0.4,0-0.6,0c-1.1,0-1.9,0.3-2.4,1c-0.5,0.7-0.8,1.7-0.8,3.2v6.1
|
||||
h-1.4v-11.2h1.1l0.2,1.8c0.7-1.3,1.9-1.9,3.5-1.9c0.2,0,0.5,0,0.7,0.1c0.2,0,0.4,0.1,0.6,0.1L120.7,155.6z"/>
|
||||
<path class="st14" d="M123.8,150.1c0.7,0,1,0.3,1,1c0,0.6-0.3,1-1,1c-0.6,0-1-0.3-1-1C122.9,150.4,123.2,150.1,123.8,150.1z
|
||||
M123.2,154.4h1.4v11.2h-1.4V154.4z"/>
|
||||
<path class="st14" d="M127.1,154.4h1.5l3.8,9.9l3.8-9.9h1.5l-4.5,11.2h-1.5L127.1,154.4z"/>
|
||||
<path class="st14" d="M140.6,160.5c0,0.8,0.1,1.4,0.2,2c0.1,0.5,0.4,1,0.7,1.3c0.3,0.3,0.8,0.6,1.3,0.7c0.5,0.2,1.2,0.2,2.1,0.2
|
||||
c0.5,0,0.9,0,1.5-0.1c0.5-0.1,1-0.1,1.3-0.2l-0.2,1.1c-0.3,0.1-0.8,0.2-1.3,0.3c-0.5,0.1-1.1,0.1-1.6,0.1c-1,0-1.8-0.1-2.5-0.3
|
||||
c-0.7-0.2-1.2-0.6-1.7-1s-0.7-1-0.9-1.7c-0.2-0.7-0.3-1.5-0.3-2.4v-0.9c0-0.8,0.1-1.6,0.3-2.3c0.2-0.7,0.5-1.3,0.8-1.7
|
||||
c0.4-0.5,0.9-0.9,1.5-1.1c0.6-0.3,1.3-0.4,2.2-0.4c0.7,0,1.4,0.1,1.9,0.3c0.5,0.2,1,0.5,1.3,0.9s0.6,0.9,0.8,1.4
|
||||
c0.2,0.5,0.2,1.2,0.2,1.8v0.6c0,0.4-0.1,0.7-0.2,0.9c-0.1,0.2-0.4,0.3-0.8,0.3H140.6z M143.9,155.3c-0.6,0-1,0.1-1.5,0.2
|
||||
s-0.8,0.4-1,0.7c-0.3,0.3-0.5,0.8-0.6,1.3c-0.1,0.5-0.2,1.2-0.2,2h6.5v-0.8c0-1.1-0.2-2-0.7-2.6S145,155.3,143.9,155.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st14" d="M217.3,150h4.9c1.3,0,2.3,0.2,3.1,0.5c0.8,0.3,1.5,0.8,2,1.4c0.5,0.6,0.8,1.3,1,2.2c0.2,0.8,0.3,1.7,0.3,2.7
|
||||
v2c0,1-0.1,1.9-0.3,2.8c-0.2,0.8-0.6,1.6-1.1,2.2c-0.5,0.6-1.1,1.1-2,1.4s-1.8,0.5-3.1,0.5h-4.8V150z M218.8,164.5h3.3
|
||||
c0.8,0,1.5-0.1,2.2-0.3c0.6-0.2,1.2-0.5,1.6-0.9c0.4-0.4,0.8-1,1-1.8c0.2-0.7,0.3-1.6,0.3-2.8V157c0-1.1-0.1-2-0.3-2.7
|
||||
c-0.2-0.7-0.5-1.3-0.9-1.8c-0.4-0.4-0.9-0.8-1.6-1c-0.6-0.2-1.4-0.3-2.2-0.3h-3.4V164.5z"/>
|
||||
<path class="st14" d="M237.9,155.6c-0.2,0-0.4-0.1-0.7-0.1c-0.2,0-0.4,0-0.6,0c-1.1,0-1.9,0.3-2.4,1c-0.5,0.7-0.8,1.7-0.8,3.2v6.1
|
||||
H232v-11.2h1.1l0.2,1.8c0.7-1.3,1.9-1.9,3.5-1.9c0.2,0,0.5,0,0.7,0.1c0.2,0,0.4,0.1,0.6,0.1L237.9,155.6z"/>
|
||||
<path class="st14" d="M244.3,154.2c1,0,1.7,0.1,2.4,0.4c0.6,0.2,1.1,0.6,1.5,1.1c0.4,0.5,0.6,1,0.8,1.7c0.2,0.7,0.2,1.4,0.2,2.2
|
||||
v1.2c0,0.8-0.1,1.5-0.3,2.2c-0.2,0.7-0.5,1.2-0.8,1.7c-0.4,0.5-0.9,0.8-1.5,1.1c-0.6,0.2-1.4,0.4-2.3,0.4c-1,0-1.7-0.1-2.4-0.4
|
||||
c-0.6-0.2-1.1-0.6-1.5-1.1s-0.6-1-0.8-1.7c-0.2-0.7-0.2-1.4-0.2-2.2v-1.2c0-0.8,0.1-1.5,0.3-2.2c0.2-0.7,0.5-1.2,0.9-1.7
|
||||
s0.9-0.8,1.5-1.1C242.7,154.3,243.4,154.2,244.3,154.2z M244.3,164.8c0.7,0,1.2-0.1,1.7-0.2s0.8-0.4,1.1-0.7
|
||||
c0.3-0.3,0.5-0.8,0.6-1.3c0.1-0.5,0.2-1.2,0.2-1.9v-1c0-0.8-0.1-1.4-0.2-2s-0.3-1-0.6-1.3c-0.3-0.3-0.6-0.6-1.1-0.7s-1-0.2-1.6-0.2
|
||||
c-0.7,0-1.2,0.1-1.7,0.2c-0.5,0.2-0.8,0.4-1.1,0.7c-0.3,0.3-0.5,0.8-0.6,1.3c-0.1,0.5-0.2,1.2-0.2,1.9v1c0,0.8,0.1,1.4,0.2,1.9
|
||||
c0.1,0.5,0.3,1,0.6,1.3c0.3,0.3,0.6,0.6,1.1,0.7C243.1,164.7,243.7,164.8,244.3,164.8z"/>
|
||||
<path class="st14" d="M261.9,160.6c0,0.9-0.1,1.7-0.4,2.4c-0.2,0.7-0.6,1.2-1,1.7s-0.9,0.8-1.5,1s-1.2,0.3-1.9,0.3
|
||||
c-0.4,0-0.7,0-1,0c-0.3,0-0.6-0.1-0.8-0.1c-0.3-0.1-0.5-0.2-0.8-0.3c-0.3-0.1-0.5-0.2-0.8-0.4v5.7h-1.3v-16.3h1.1l0.2,1.5
|
||||
c0.8-1.2,2.1-1.8,3.9-1.8c0.6,0,1.2,0.1,1.8,0.3c0.5,0.2,1,0.5,1.4,0.9c0.4,0.4,0.7,1,0.9,1.7c0.2,0.7,0.3,1.5,0.3,2.5V160.6z
|
||||
M260.5,159.9c0-0.7,0-1.3-0.1-1.9s-0.3-1-0.5-1.4c-0.3-0.4-0.6-0.7-1-0.9c-0.4-0.2-1-0.3-1.6-0.3c-0.7,0-1.2,0.1-1.7,0.3
|
||||
c-0.4,0.2-0.8,0.4-1.1,0.7s-0.5,0.7-0.6,1.2c-0.1,0.5-0.2,1-0.2,1.7v4.7c0.5,0.3,1,0.5,1.5,0.6c0.5,0.1,1,0.2,1.7,0.2
|
||||
c0.7,0,1.3-0.1,1.7-0.3s0.8-0.5,1.1-0.8c0.3-0.4,0.5-0.8,0.6-1.4s0.2-1.2,0.2-1.9V159.9z"/>
|
||||
<path class="st14" d="M269.4,165.9c-0.7,0-1.5-0.1-2.2-0.3c-0.7-0.2-1.4-0.5-2.1-0.8v-15.5h1.3v6.6c0.4-0.6,0.9-1.1,1.5-1.3
|
||||
c0.6-0.3,1.3-0.4,2.2-0.4c0.7,0,1.3,0.1,1.8,0.3c0.6,0.2,1,0.5,1.4,0.9s0.7,1,0.9,1.6c0.2,0.7,0.3,1.5,0.3,2.5v1
|
||||
c0,1.8-0.4,3.2-1.3,4.1C272.4,165.5,271.1,165.9,269.4,165.9z M269.3,164.8c0.7,0,1.3-0.1,1.8-0.3c0.5-0.2,0.9-0.4,1.2-0.8
|
||||
c0.3-0.4,0.5-0.8,0.7-1.4c0.1-0.6,0.2-1.2,0.2-2v-0.5c0-0.7-0.1-1.3-0.2-1.9c-0.1-0.6-0.3-1-0.5-1.4s-0.6-0.7-1-0.9
|
||||
c-0.4-0.2-1-0.3-1.6-0.3c-0.5,0-1,0.1-1.4,0.2s-0.8,0.4-1.1,0.7c-0.3,0.3-0.5,0.7-0.7,1.2c-0.2,0.5-0.3,1.1-0.3,1.8v4.9
|
||||
c0.4,0.2,0.9,0.4,1.3,0.5C268.2,164.7,268.7,164.8,269.3,164.8z"/>
|
||||
<path class="st14" d="M282.3,154.2c1,0,1.7,0.1,2.4,0.4c0.6,0.2,1.1,0.6,1.5,1.1c0.4,0.5,0.6,1,0.8,1.7c0.2,0.7,0.2,1.4,0.2,2.2
|
||||
v1.2c0,0.8-0.1,1.5-0.3,2.2c-0.2,0.7-0.5,1.2-0.8,1.7c-0.4,0.5-0.9,0.8-1.5,1.1c-0.6,0.2-1.4,0.4-2.3,0.4c-1,0-1.7-0.1-2.4-0.4
|
||||
c-0.6-0.2-1.1-0.6-1.5-1.1s-0.6-1-0.8-1.7c-0.2-0.7-0.2-1.4-0.2-2.2v-1.2c0-0.8,0.1-1.5,0.3-2.2c0.2-0.7,0.5-1.2,0.9-1.7
|
||||
s0.9-0.8,1.5-1.1C280.6,154.3,281.4,154.2,282.3,154.2z M282.3,164.8c0.7,0,1.2-0.1,1.7-0.2s0.8-0.4,1.1-0.7
|
||||
c0.3-0.3,0.5-0.8,0.6-1.3c0.1-0.5,0.2-1.2,0.2-1.9v-1c0-0.8-0.1-1.4-0.2-2s-0.3-1-0.6-1.3c-0.3-0.3-0.6-0.6-1.1-0.7s-1-0.2-1.6-0.2
|
||||
c-0.7,0-1.2,0.1-1.7,0.2c-0.5,0.2-0.8,0.4-1.1,0.7c-0.3,0.3-0.5,0.8-0.6,1.3c-0.1,0.5-0.2,1.2-0.2,1.9v1c0,0.8,0.1,1.4,0.2,1.9
|
||||
c0.1,0.5,0.3,1,0.6,1.3c0.3,0.3,0.6,0.6,1.1,0.7C281.1,164.7,281.6,164.8,282.3,164.8z"/>
|
||||
<path class="st14" d="M288.8,154.4h1.5l3.1,4.4l3.1-4.4h1.5l-3.9,5.4l4.2,5.8h-1.6l-3.4-4.9l-3.4,4.9h-1.5l4.2-5.9L288.8,154.4z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st14" d="M379.5,166c-1.1,0-2-0.1-2.8-0.4s-1.3-0.7-1.7-1.2c-0.4-0.6-0.7-1.2-0.9-2c-0.2-0.8-0.2-1.8-0.2-2.8V150h1.4
|
||||
v9.5c0,1,0.1,1.9,0.2,2.5c0.2,0.7,0.4,1.2,0.7,1.6c0.3,0.4,0.8,0.7,1.3,0.9c0.5,0.2,1.2,0.3,2,0.3c0.8,0,1.5-0.1,2-0.3
|
||||
c0.5-0.2,1-0.5,1.3-0.9c0.3-0.4,0.6-1,0.7-1.6s0.2-1.5,0.2-2.5V150h1.4v9.5c0,1.1-0.1,2-0.3,2.8s-0.5,1.5-0.9,2
|
||||
c-0.4,0.5-1,0.9-1.7,1.2S380.6,166,379.5,166z"/>
|
||||
<path class="st14" d="M394.4,157.1c0.7,0.1,1.3,0.3,1.8,0.5c0.5,0.2,0.9,0.5,1.2,0.9s0.5,0.8,0.6,1.2c0.1,0.5,0.2,0.9,0.2,1.5v0.3
|
||||
c0,0.6-0.1,1.2-0.3,1.8c-0.2,0.5-0.6,1-1,1.4c-0.5,0.4-1,0.7-1.8,0.9c-0.7,0.2-1.5,0.3-2.5,0.3c-0.8,0-1.6-0.1-2.4-0.2
|
||||
c-0.8-0.1-1.4-0.3-2-0.5l0.3-1.2c0.6,0.2,1.2,0.3,1.9,0.4c0.7,0.1,1.4,0.2,2.2,0.2c1.5,0,2.6-0.3,3.2-0.8c0.6-0.5,1-1.4,1-2.5
|
||||
c0-0.4,0-0.7-0.1-1c-0.1-0.3-0.2-0.6-0.4-0.9c-0.2-0.3-0.5-0.5-0.9-0.6c-0.4-0.2-0.9-0.3-1.4-0.4l-2-0.3c-1.3-0.2-2.3-0.6-2.8-1.3
|
||||
c-0.6-0.7-0.8-1.6-0.8-2.7V154c0-0.7,0.1-1.3,0.4-1.8c0.3-0.5,0.6-1,1.1-1.3c0.5-0.4,1.1-0.6,1.8-0.8c0.7-0.2,1.5-0.3,2.3-0.3
|
||||
c0.7,0,1.5,0.1,2.1,0.2c0.7,0.1,1.2,0.3,1.7,0.5l-0.3,1.1c-0.5-0.2-1.1-0.3-1.7-0.4s-1.3-0.2-2-0.2c-1.5,0-2.5,0.3-3.2,0.8
|
||||
c-0.6,0.5-1,1.3-1,2.3c0,0.8,0.2,1.4,0.6,1.8c0.4,0.4,1.1,0.7,2.2,0.8L394.4,157.1z"/>
|
||||
<path class="st14" d="M401.4,165.7V150h5.5c0.8,0,1.5,0.1,2,0.3c0.5,0.2,1,0.5,1.3,0.8c0.3,0.3,0.6,0.7,0.7,1.2
|
||||
c0.1,0.4,0.2,0.9,0.2,1.4v0.5c0,0.8-0.2,1.5-0.6,2c-0.4,0.5-0.9,0.9-1.6,1.2c0.5,0.1,0.8,0.3,1.2,0.5c0.3,0.2,0.6,0.5,0.8,0.9
|
||||
c0.2,0.3,0.4,0.7,0.5,1.1c0.1,0.4,0.2,0.8,0.2,1.3v0.5c0,0.6-0.1,1.1-0.3,1.6c-0.2,0.5-0.5,0.9-0.9,1.3c-0.4,0.4-0.9,0.6-1.5,0.8
|
||||
s-1.3,0.3-2.1,0.3H401.4z M402.8,156.9h4.2c0.9,0,1.7-0.2,2.2-0.7c0.5-0.4,0.7-1.1,0.7-1.8v-0.5c0-1.8-1-2.8-3.1-2.8h-3.9V156.9z
|
||||
M402.8,164.5h4.2c1.1,0,1.9-0.2,2.4-0.7c0.5-0.4,0.8-1.2,0.8-2.2v-0.5c0-2-1.1-3.1-3.3-3.1h-4.2V164.5z"/>
|
||||
<path class="st14" d="M421.6,150v7.1l7-7.1h1.6l-7.5,7.5l8,8.1h-1.8l-7.3-7.5v7.5h-1.3V150H421.6z"/>
|
||||
<path class="st14" d="M433.1,160.5c0,0.8,0.1,1.4,0.2,2c0.1,0.5,0.4,1,0.7,1.3c0.3,0.3,0.8,0.6,1.3,0.7c0.5,0.2,1.2,0.2,2.1,0.2
|
||||
c0.5,0,0.9,0,1.5-0.1c0.5-0.1,1-0.1,1.3-0.2l-0.2,1.1c-0.3,0.1-0.8,0.2-1.3,0.3c-0.5,0.1-1.1,0.1-1.6,0.1c-1,0-1.8-0.1-2.5-0.3
|
||||
c-0.7-0.2-1.2-0.6-1.7-1s-0.7-1-0.9-1.7c-0.2-0.7-0.3-1.5-0.3-2.4v-0.9c0-0.8,0.1-1.6,0.3-2.3c0.2-0.7,0.5-1.3,0.8-1.7
|
||||
c0.4-0.5,0.9-0.9,1.5-1.1c0.6-0.3,1.3-0.4,2.2-0.4c0.7,0,1.4,0.1,1.9,0.3c0.5,0.2,1,0.5,1.3,0.9s0.6,0.9,0.8,1.4
|
||||
c0.2,0.5,0.2,1.2,0.2,1.8v0.6c0,0.4-0.1,0.7-0.2,0.9c-0.1,0.2-0.4,0.3-0.8,0.3H433.1z M436.4,155.3c-0.6,0-1,0.1-1.5,0.2
|
||||
s-0.8,0.4-1,0.7s-0.5,0.8-0.6,1.3c-0.1,0.5-0.2,1.2-0.2,2h6.5v-0.8c0-1.1-0.2-2-0.7-2.6S437.5,155.3,436.4,155.3z"/>
|
||||
<path class="st14" d="M451.7,154.4h1.5l-4.9,12.6c-0.3,0.8-0.6,1.4-0.9,1.9c-0.3,0.5-0.6,0.9-0.9,1.2c-0.3,0.3-0.6,0.5-1,0.6
|
||||
c-0.4,0.1-0.7,0.2-1.2,0.2c-0.3,0-0.6,0-0.9-0.1c-0.3-0.1-0.5-0.1-0.8-0.2l0.2-1c0.2,0,0.4,0.1,0.6,0.1c0.2,0,0.5,0,0.7,0
|
||||
c0.3,0,0.6,0,0.9-0.1c0.3-0.1,0.5-0.2,0.7-0.4c0.2-0.2,0.4-0.5,0.6-0.8c0.2-0.4,0.4-0.9,0.6-1.5l0.4-1.2l-4.8-11.4h1.5l3.9,9.7
|
||||
L451.7,154.4z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<hr>
|
||||
|
||||
<h3>What happens if I lose my passphrase?</h3>
|
||||
<p>Your passphrase is used to encrypt your private keys. If you lose your passphrase, you will no longer be able to decrypt your private key file nor have access to the contents of your Wallet or My Purchases.</p>
|
||||
<p>In order to guarantee your privacy, nobody can help you recover your passphrase, including High Fidelity.
|
||||
|
||||
<p><b>Please write it down and store it securely.</b></p>
|
||||
<p> </p>
|
||||
<hr>
|
||||
|
||||
<h2>Want to learn more?</h2>
|
||||
<p>You can find out much more about the blockchain and about commerce in High Fidelity by visiting our Docs site:</p>
|
||||
<p><a href="http://docs.highfidelity.com" class="btn">Visit High Fidelity's Docs</a></p>
|
||||
<hr>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
High Fidelity | <a href="http://highfidelity.com" target="_blank">highfidelity.com</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -27,6 +27,8 @@ ModalWindow {
|
|||
destroyOnHidden: true
|
||||
visible: true
|
||||
|
||||
readonly property bool isTablet: false
|
||||
|
||||
property string iconText: ""
|
||||
property int iconSize: 50
|
||||
|
||||
|
@ -35,6 +37,10 @@ ModalWindow {
|
|||
|
||||
keyboardOverride: true // Disable ModalWindow's keyboard.
|
||||
|
||||
function tryDestroy() {
|
||||
root.destroy()
|
||||
}
|
||||
|
||||
LoginDialog {
|
||||
id: loginDialog
|
||||
|
||||
|
|
|
@ -29,11 +29,12 @@ Item {
|
|||
readonly property int maxHeight: 720
|
||||
|
||||
function resize() {
|
||||
var targetWidth = Math.max(titleWidth, Math.max(additionalTextContainer.contentWidth,
|
||||
termsContainer.contentWidth))
|
||||
if (root.isTablet === false) {
|
||||
var targetWidth = Math.max(titleWidth, Math.max(additionalTextContainer.contentWidth,
|
||||
termsContainer.contentWidth))
|
||||
parent.width = root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth))
|
||||
}
|
||||
var targetHeight = 5 * hifi.dimensions.contentSpacing.y + buttons.height + additionalTextContainer.height + termsContainer.height
|
||||
|
||||
parent.width = root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth))
|
||||
parent.height = root.height = Math.max(d.minHeight, Math.min(d.maxHeight, targetHeight))
|
||||
}
|
||||
}
|
||||
|
@ -61,11 +62,8 @@ Item {
|
|||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: qsTr("Cancel")
|
||||
|
||||
|
||||
onClicked: root.destroy()
|
||||
onClicked: root.tryDestroy()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,17 +94,19 @@ Item {
|
|||
id: termsContainer
|
||||
anchors {
|
||||
top: additionalTextContainer.bottom
|
||||
left: parent.left
|
||||
margins: 0
|
||||
topMargin: 2 * hifi.dimensions.contentSpacing.y
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
width: parent.width
|
||||
|
||||
text: qsTr("By creating this user profile, you agree to <a href='https://highfidelity.com/terms'>High Fidelity's Terms of Service</a>")
|
||||
wrapMode: Text.WordWrap
|
||||
color: hifi.colors.baseGrayHighlight
|
||||
lineHeight: 1
|
||||
lineHeightMode: Text.ProportionalHeight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
fontSizeMode: Text.HorizontalFit
|
||||
horizontalAlignment: Text.AlignVCenter
|
||||
|
||||
onLinkActivated: loginDialog.openUrl(link)
|
||||
}
|
||||
|
@ -128,8 +128,10 @@ Item {
|
|||
console.log("Create Failed: " + error)
|
||||
|
||||
bodyLoader.source = "UsernameCollisionBody.qml"
|
||||
bodyLoader.item.width = root.pane.width
|
||||
bodyLoader.item.height = root.pane.height
|
||||
if (!root.isTablet) {
|
||||
bodyLoader.item.width = root.pane.width
|
||||
bodyLoader.item.height = root.pane.height
|
||||
}
|
||||
}
|
||||
onHandleLoginCompleted: {
|
||||
console.log("Login Succeeded")
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
//
|
||||
|
||||
import Hifi 1.0
|
||||
import QtQuick 2.4
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4 as OriginalStyles
|
||||
|
||||
|
@ -45,8 +45,7 @@ Item {
|
|||
function resize() {
|
||||
var targetWidth = Math.max(titleWidth, form.contentWidth);
|
||||
var targetHeight = hifi.dimensions.contentSpacing.y + mainTextContainer.height +
|
||||
4 * hifi.dimensions.contentSpacing.y + form.height +
|
||||
hifi.dimensions.contentSpacing.y + buttons.height;
|
||||
4 * hifi.dimensions.contentSpacing.y + form.height;
|
||||
|
||||
if (additionalInformation.visible) {
|
||||
targetWidth = Math.max(targetWidth, additionalInformation.width);
|
||||
|
@ -66,9 +65,6 @@ Item {
|
|||
if (loginDialog.isSteamRunning()) {
|
||||
additionalInformation.visible = !isLoading
|
||||
}
|
||||
|
||||
leftButton.visible = !isLoading
|
||||
buttons.visible = !isLoading
|
||||
}
|
||||
|
||||
BusyIndicator {
|
||||
|
@ -108,30 +104,27 @@ Item {
|
|||
|
||||
Column {
|
||||
id: form
|
||||
width: parent.width
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
||||
anchors {
|
||||
top: mainTextContainer.bottom
|
||||
left: parent.left
|
||||
margins: 0
|
||||
topMargin: 2 * hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
spacing: 2 * hifi.dimensions.contentSpacing.y
|
||||
|
||||
Row {
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
|
||||
TextField {
|
||||
id: usernameField
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
width: 350
|
||||
|
||||
label: "Username or Email"
|
||||
}
|
||||
TextField {
|
||||
id: usernameField
|
||||
width: parent.width
|
||||
focus: true
|
||||
label: "Username or Email"
|
||||
|
||||
ShortcutText {
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
verticalCenter: usernameField.textFieldLabel.verticalCenter
|
||||
left: usernameField.textFieldLabel.right
|
||||
leftMargin: 10
|
||||
}
|
||||
|
||||
text: "<a href='https://highfidelity.com/users/password/new'>Forgot Username?</a>"
|
||||
|
@ -143,23 +136,19 @@ Item {
|
|||
onLinkActivated: loginDialog.openUrl(link)
|
||||
}
|
||||
}
|
||||
Row {
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
|
||||
TextField {
|
||||
id: passwordField
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
width: 350
|
||||
TextField {
|
||||
id: passwordField
|
||||
width: parent.width
|
||||
|
||||
label: "Password"
|
||||
echoMode: TextInput.Password
|
||||
}
|
||||
label: "Password"
|
||||
echoMode: showPassword.checked ? TextInput.Normal : TextInput.Password
|
||||
|
||||
ShortcutText {
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
verticalCenter: passwordField.textFieldLabel.verticalCenter
|
||||
left: passwordField.textFieldLabel.right
|
||||
leftMargin: 10
|
||||
}
|
||||
|
||||
text: "<a href='https://highfidelity.com/users/password/new'>Forgot Password?</a>"
|
||||
|
@ -172,25 +161,76 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
InfoItem {
|
||||
id: additionalInformation
|
||||
anchors {
|
||||
top: form.bottom
|
||||
left: parent.left
|
||||
margins: 0
|
||||
topMargin: hifi.dimensions.contentSpacing.y
|
||||
CheckBoxQQC2 {
|
||||
id: showPassword
|
||||
text: "Show password"
|
||||
}
|
||||
|
||||
visible: loginDialog.isSteamRunning()
|
||||
InfoItem {
|
||||
id: additionalInformation
|
||||
|
||||
text: qsTr("Your steam account informations will not be exposed to other users.")
|
||||
wrapMode: Text.WordWrap
|
||||
color: hifi.colors.baseGrayHighlight
|
||||
lineHeight: 1
|
||||
lineHeightMode: Text.ProportionalHeight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
visible: loginDialog.isSteamRunning()
|
||||
|
||||
text: qsTr("Your steam account informations will not be exposed to other users.")
|
||||
wrapMode: Text.WordWrap
|
||||
color: hifi.colors.baseGrayHighlight
|
||||
lineHeight: 1
|
||||
lineHeightMode: Text.ProportionalHeight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
Row {
|
||||
id: buttons
|
||||
spacing: hifi.dimensions.contentSpacing.y*2
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
Button {
|
||||
id: linkAccountButton
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 200
|
||||
|
||||
text: qsTr(loginDialog.isSteamRunning() ? "Link Account" : "Login")
|
||||
color: hifi.buttons.blue
|
||||
|
||||
onClicked: linkAccountBody.login()
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: qsTr("Cancel")
|
||||
onClicked: root.tryDestroy()
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: leftButton
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: hifi.dimensions.contentSpacing.y*2
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
||||
RalewaySemiBold {
|
||||
size: hifi.fontSizes.inputLabel
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: qsTr("Don't have an account?")
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: qsTr("Sign Up")
|
||||
visible: !loginDialog.isSteamRunning()
|
||||
|
||||
onClicked: {
|
||||
bodyLoader.setSource("SignUpBody.qml")
|
||||
if (!root.isTablet) {
|
||||
bodyLoader.item.width = root.pane.width
|
||||
bodyLoader.item.height = root.pane.height
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Override ScrollingWindow's keyboard that would be at very bottom of dialog.
|
||||
|
@ -200,70 +240,22 @@ Item {
|
|||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: buttons.top
|
||||
bottom: parent.bottom
|
||||
bottomMargin: keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: leftButton
|
||||
anchors {
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
bottomMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: qsTr("Sign Up")
|
||||
visible: !loginDialog.isSteamRunning()
|
||||
|
||||
onClicked: {
|
||||
bodyLoader.setSource("SignUpBody.qml")
|
||||
bodyLoader.item.width = root.pane.width
|
||||
bodyLoader.item.height = root.pane.height
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: buttons
|
||||
anchors {
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
bottomMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
||||
Button {
|
||||
id: linkAccountButton
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 200
|
||||
|
||||
text: qsTr(loginDialog.isSteamRunning() ? "Link Account" : "Login")
|
||||
color: hifi.buttons.blue
|
||||
|
||||
onClicked: linkAccountBody.login()
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: qsTr("Cancel")
|
||||
|
||||
onClicked: root.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
root.title = qsTr("Sign Into High Fidelity")
|
||||
root.iconText = "<"
|
||||
keyboardEnabled = HMD.active;
|
||||
|
||||
//dont rise local keyboard
|
||||
keyboardEnabled = !root.isTablet && HMD.active;
|
||||
//but rise Tablet's one instead for Tablet interface
|
||||
if (root.isTablet) {
|
||||
root.keyboardEnabled = HMD.active;
|
||||
root.keyboardRaised = Qt.binding( function() { return keyboardRaised; })
|
||||
}
|
||||
d.resize();
|
||||
|
||||
if (failAfterSignUp) {
|
||||
|
@ -311,11 +303,11 @@ Item {
|
|||
}
|
||||
|
||||
switch (event.key) {
|
||||
case Qt.Key_Enter:
|
||||
case Qt.Key_Return:
|
||||
event.accepted = true
|
||||
linkAccountBody.login()
|
||||
break
|
||||
case Qt.Key_Enter:
|
||||
case Qt.Key_Return:
|
||||
event.accepted = true
|
||||
linkAccountBody.login()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
//
|
||||
|
||||
import Hifi 1.0
|
||||
import QtQuick 2.4
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls.Styles 1.4 as OriginalStyles
|
||||
|
||||
import "../controls-uit"
|
||||
|
@ -18,8 +18,8 @@ import "../styles-uit"
|
|||
Item {
|
||||
id: signInBody
|
||||
clip: true
|
||||
width: root.pane.width
|
||||
height: root.pane.height
|
||||
width: root.pane.width
|
||||
|
||||
property bool required: false
|
||||
|
||||
|
@ -29,7 +29,7 @@ Item {
|
|||
}
|
||||
|
||||
function cancel() {
|
||||
root.destroy()
|
||||
root.tryDestroy()
|
||||
}
|
||||
|
||||
QtObject {
|
||||
|
@ -121,8 +121,10 @@ Item {
|
|||
console.log("Login Failed")
|
||||
|
||||
bodyLoader.source = "CompleteProfileBody.qml"
|
||||
bodyLoader.item.width = root.pane.width
|
||||
bodyLoader.item.height = root.pane.height
|
||||
if (!root.isTablet) {
|
||||
bodyLoader.item.width = root.pane.width
|
||||
bodyLoader.item.height = root.pane.height
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
//
|
||||
|
||||
import Hifi 1.0
|
||||
import QtQuick 2.4
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4 as OriginalStyles
|
||||
|
||||
|
@ -44,8 +44,7 @@ Item {
|
|||
function resize() {
|
||||
var targetWidth = Math.max(titleWidth, form.contentWidth);
|
||||
var targetHeight = hifi.dimensions.contentSpacing.y + mainTextContainer.height +
|
||||
4 * hifi.dimensions.contentSpacing.y + form.height +
|
||||
hifi.dimensions.contentSpacing.y + buttons.height;
|
||||
4 * hifi.dimensions.contentSpacing.y + form.height;
|
||||
|
||||
parent.width = root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth));
|
||||
parent.height = root.height = Math.max(d.minHeight, Math.min(d.maxHeight, targetHeight))
|
||||
|
@ -96,44 +95,31 @@ Item {
|
|||
|
||||
Column {
|
||||
id: form
|
||||
width: parent.width
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
||||
anchors {
|
||||
top: mainTextContainer.bottom
|
||||
left: parent.left
|
||||
margins: 0
|
||||
topMargin: 2 * hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
spacing: 2 * hifi.dimensions.contentSpacing.y
|
||||
|
||||
Row {
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
|
||||
TextField {
|
||||
id: emailField
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
width: 350
|
||||
|
||||
label: "Email"
|
||||
}
|
||||
TextField {
|
||||
id: emailField
|
||||
width: parent.width
|
||||
label: "Email"
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
|
||||
TextField {
|
||||
id: usernameField
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
width: 350
|
||||
|
||||
label: "Username"
|
||||
}
|
||||
TextField {
|
||||
id: usernameField
|
||||
width: parent.width
|
||||
label: "Username"
|
||||
|
||||
ShortcutText {
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
verticalCenter: parent.textFieldLabel.verticalCenter
|
||||
left: parent.textFieldLabel.right
|
||||
leftMargin: 10
|
||||
}
|
||||
|
||||
text: qsTr("No spaces / special chars.")
|
||||
|
@ -145,23 +131,17 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
|
||||
TextField {
|
||||
id: passwordField
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
width: 350
|
||||
|
||||
label: "Password"
|
||||
echoMode: TextInput.Password
|
||||
}
|
||||
TextField {
|
||||
id: passwordField
|
||||
width: parent.width
|
||||
label: "Password"
|
||||
echoMode: TextInput.Password
|
||||
|
||||
ShortcutText {
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
verticalCenter: parent.textFieldLabel.verticalCenter
|
||||
left: parent.textFieldLabel.right
|
||||
leftMargin: 10
|
||||
}
|
||||
|
||||
text: qsTr("At least 6 characters")
|
||||
|
@ -173,6 +153,53 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: leftButton
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: qsTr("Existing User")
|
||||
|
||||
onClicked: {
|
||||
bodyLoader.setSource("LinkAccountBody.qml")
|
||||
if (!root.isTablet) {
|
||||
bodyLoader.item.width = root.pane.width
|
||||
bodyLoader.item.height = root.pane.height
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: buttons
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
||||
Button {
|
||||
id: linkAccountButton
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 200
|
||||
|
||||
text: qsTr("Sign Up")
|
||||
color: hifi.buttons.blue
|
||||
|
||||
onClicked: signupBody.signup()
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: qsTr("Cancel")
|
||||
|
||||
onClicked: root.tryDestroy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Override ScrollingWindow's keyboard that would be at very bottom of dialog.
|
||||
|
@ -182,69 +209,21 @@ Item {
|
|||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: buttons.top
|
||||
bottom: parent.bottom
|
||||
bottomMargin: keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: leftButton
|
||||
anchors {
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
bottomMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: qsTr("Existing User")
|
||||
|
||||
onClicked: {
|
||||
bodyLoader.setSource("LinkAccountBody.qml")
|
||||
bodyLoader.item.width = root.pane.width
|
||||
bodyLoader.item.height = root.pane.height
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: buttons
|
||||
anchors {
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
bottomMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
||||
Button {
|
||||
id: linkAccountButton
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 200
|
||||
|
||||
text: qsTr("Sign Up")
|
||||
color: hifi.buttons.blue
|
||||
|
||||
onClicked: signupBody.signup()
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: qsTr("Cancel")
|
||||
|
||||
onClicked: root.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
root.title = qsTr("Create an Account")
|
||||
root.iconText = "<"
|
||||
keyboardEnabled = HMD.active;
|
||||
//dont rise local keyboard
|
||||
keyboardEnabled = !root.isTablet && HMD.active;
|
||||
//but rise Tablet's one instead for Tablet interface
|
||||
if (root.isTablet) {
|
||||
root.keyboardEnabled = HMD.active;
|
||||
root.keyboardRaised = Qt.binding( function() { return keyboardRaised; })
|
||||
}
|
||||
d.resize();
|
||||
|
||||
emailField.forceActiveFocus();
|
||||
|
@ -275,8 +254,10 @@ Item {
|
|||
onHandleLoginFailed: {
|
||||
// we failed to login, show the LoginDialog so the user will try again
|
||||
bodyLoader.setSource("LinkAccountBody.qml", { "failAfterSignUp": true })
|
||||
bodyLoader.item.width = root.pane.width
|
||||
bodyLoader.item.height = root.pane.height
|
||||
if (!root.isTablet) {
|
||||
bodyLoader.item.width = root.pane.width
|
||||
bodyLoader.item.height = root.pane.height
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ Item {
|
|||
margins: 0
|
||||
topMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
width: 250
|
||||
width: parent.width
|
||||
|
||||
placeholderText: "Choose your own"
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ Item {
|
|||
bottom: parent.bottom
|
||||
right: parent.right
|
||||
margins: 0
|
||||
topMargin: hifi.dimensions.contentSpacing.y
|
||||
bottomMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
@ -122,14 +122,21 @@ Item {
|
|||
|
||||
text: qsTr("Cancel")
|
||||
|
||||
onClicked: root.destroy()
|
||||
onClicked: root.tryDestroy()
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
root.title = qsTr("Complete Your Profile")
|
||||
root.iconText = "<"
|
||||
keyboardEnabled = HMD.active;
|
||||
//dont rise local keyboard
|
||||
keyboardEnabled = !root.isTablet && HMD.active;
|
||||
//but rise Tablet's one instead for Tablet interface
|
||||
if (root.isTablet) {
|
||||
root.keyboardEnabled = HMD.active;
|
||||
root.keyboardRaised = Qt.binding( function() { return keyboardRaised; })
|
||||
}
|
||||
|
||||
d.resize();
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ Item {
|
|||
|
||||
text: qsTr("Close");
|
||||
|
||||
onClicked: root.destroy()
|
||||
onClicked: root.tryDestroy()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,11 @@ Item {
|
|||
text: "Avatars: " + root.avatarCount
|
||||
}
|
||||
StatText {
|
||||
text: "Frame Rate: " + root.framerate.toFixed(2);
|
||||
text: "Game Rate: " + root.gameLoopRate
|
||||
}
|
||||
StatText {
|
||||
visible: root.expanded
|
||||
text: root.gameUpdateStats
|
||||
}
|
||||
StatText {
|
||||
text: "Render Rate: " + root.renderrate.toFixed(2);
|
||||
|
@ -64,21 +68,17 @@ Item {
|
|||
text: "Present Rate: " + root.presentrate.toFixed(2);
|
||||
}
|
||||
StatText {
|
||||
text: "Present New Rate: " + root.presentnewrate.toFixed(2);
|
||||
visible: root.expanded
|
||||
text: " Present New Rate: " + root.presentnewrate.toFixed(2);
|
||||
}
|
||||
StatText {
|
||||
text: "Present Drop Rate: " + root.presentdroprate.toFixed(2);
|
||||
visible: root.expanded
|
||||
text: " Present Drop Rate: " + root.presentdroprate.toFixed(2);
|
||||
}
|
||||
StatText {
|
||||
text: "Stutter Rate: " + root.stutterrate.toFixed(3);
|
||||
visible: root.stutterrate != -1;
|
||||
}
|
||||
StatText {
|
||||
text: "Simrate: " + root.simrate
|
||||
}
|
||||
StatText {
|
||||
text: "Avatar Simrate: " + root.avatarSimrate
|
||||
}
|
||||
StatText {
|
||||
text: "Missed Frame Count: " + root.appdropped;
|
||||
visible: root.appdropped > 0;
|
||||
|
@ -261,9 +261,6 @@ Item {
|
|||
StatText {
|
||||
text: "GPU: " + root.gpuFrameTime.toFixed(1) + " ms"
|
||||
}
|
||||
StatText {
|
||||
text: "Avatar: " + root.avatarSimulationTime.toFixed(1) + " ms"
|
||||
}
|
||||
StatText {
|
||||
text: "Triangles: " + root.triangles +
|
||||
" / Material Switches: " + root.materialSwitches
|
||||
|
|
|
@ -1,124 +0,0 @@
|
|||
//
|
||||
// CompleteProfileBody.qml
|
||||
//
|
||||
// Created by Clement on 7/18/16
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import Hifi 1.0
|
||||
import QtQuick 2.4
|
||||
import QtQuick.Controls.Styles 1.4 as OriginalStyles
|
||||
|
||||
import "../controls-uit"
|
||||
import "../styles-uit"
|
||||
|
||||
Item {
|
||||
id: completeProfileBody
|
||||
clip: true
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
function resize() {}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: buttons
|
||||
anchors {
|
||||
top: parent.top
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
margins: 0
|
||||
topMargin: 2 * hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 200
|
||||
|
||||
text: qsTr("Create your profile")
|
||||
color: hifi.buttons.blue
|
||||
|
||||
onClicked: loginDialog.createAccountFromStream()
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: qsTr("Cancel")
|
||||
|
||||
onClicked: bodyLoader.popup()
|
||||
}
|
||||
}
|
||||
|
||||
ShortcutText {
|
||||
id: additionalTextContainer
|
||||
anchors {
|
||||
top: buttons.bottom
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
margins: 0
|
||||
topMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
|
||||
text: "<a href='https://fake.link'>Already have a High Fidelity profile? Link to an existing profile here.</a>"
|
||||
|
||||
wrapMode: Text.WordWrap
|
||||
lineHeight: 2
|
||||
lineHeightMode: Text.ProportionalHeight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
||||
onLinkActivated: {
|
||||
bodyLoader.setSource("LinkAccountBody.qml")
|
||||
}
|
||||
}
|
||||
|
||||
InfoItem {
|
||||
id: termsContainer
|
||||
anchors {
|
||||
top: additionalTextContainer.bottom
|
||||
left: parent.left
|
||||
margins: 0
|
||||
topMargin: 2 * hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
|
||||
text: qsTr("By creating this user profile, you agree to <a href='https://highfidelity.com/terms'>High Fidelity's Terms of Service</a>")
|
||||
wrapMode: Text.WordWrap
|
||||
color: hifi.colors.baseGrayHighlight
|
||||
lineHeight: 1
|
||||
lineHeightMode: Text.ProportionalHeight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
||||
onLinkActivated: loginDialog.openUrl(link)
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
loginDialogRoot.title = qsTr("Complete Your Profile")
|
||||
loginDialogRoot.iconText = "<"
|
||||
d.resize();
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: loginDialog
|
||||
onHandleCreateCompleted: {
|
||||
console.log("Create Succeeded")
|
||||
|
||||
loginDialog.loginThroughSteam()
|
||||
}
|
||||
onHandleCreateFailed: {
|
||||
console.log("Create Failed: " + error)
|
||||
|
||||
bodyLoadersetSource("UsernameCollisionBody.qml")
|
||||
}
|
||||
onHandleLoginCompleted: {
|
||||
console.log("Login Succeeded")
|
||||
|
||||
bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : false })
|
||||
}
|
||||
onHandleLoginFailed: {
|
||||
console.log("Login Failed")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,296 +0,0 @@
|
|||
//
|
||||
// LinkAccountBody.qml
|
||||
//
|
||||
// Created by Clement on 7/18/16
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import Hifi 1.0
|
||||
import QtQuick 2.4
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4 as OriginalStyles
|
||||
|
||||
import "../controls-uit"
|
||||
import "../styles-uit"
|
||||
|
||||
Item {
|
||||
id: linkAccountBody
|
||||
clip: true
|
||||
height: parent.height
|
||||
width: parent.width
|
||||
property bool failAfterSignUp: false
|
||||
|
||||
function login() {
|
||||
mainTextContainer.visible = false
|
||||
toggleLoading(true)
|
||||
loginDialog.login(usernameField.text, passwordField.text)
|
||||
}
|
||||
|
||||
property bool keyboardEnabled: false
|
||||
property bool keyboardRaised: false
|
||||
property bool punctuationMode: false
|
||||
|
||||
onKeyboardRaisedChanged: d.resize();
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
function resize() {}
|
||||
}
|
||||
|
||||
function toggleLoading(isLoading) {
|
||||
linkAccountSpinner.visible = isLoading
|
||||
form.visible = !isLoading
|
||||
|
||||
if (loginDialog.isSteamRunning()) {
|
||||
additionalInformation.visible = !isLoading
|
||||
}
|
||||
|
||||
leftButton.visible = !isLoading
|
||||
buttons.visible = !isLoading
|
||||
}
|
||||
|
||||
BusyIndicator {
|
||||
id: linkAccountSpinner
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
topMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
|
||||
visible: false
|
||||
running: true
|
||||
|
||||
width: 48
|
||||
height: 48
|
||||
}
|
||||
|
||||
ShortcutText {
|
||||
id: mainTextContainer
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
margins: 0
|
||||
topMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
|
||||
visible: false
|
||||
|
||||
text: qsTr("Username or password incorrect.")
|
||||
wrapMode: Text.WordWrap
|
||||
color: hifi.colors.redAccent
|
||||
lineHeight: 1
|
||||
lineHeightMode: Text.ProportionalHeight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
Column {
|
||||
id: form
|
||||
anchors {
|
||||
top: mainTextContainer.bottom
|
||||
left: parent.left
|
||||
margins: 0
|
||||
topMargin: 2 * hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
spacing: 2 * hifi.dimensions.contentSpacing.y
|
||||
|
||||
Row {
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
|
||||
TextField {
|
||||
id: usernameField
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
width: 350
|
||||
|
||||
label: "Username or Email"
|
||||
}
|
||||
|
||||
ShortcutText {
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
text: "<a href='https://highfidelity.com/users/password/new'>Forgot Username?</a>"
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
linkColor: hifi.colors.blueAccent
|
||||
|
||||
onLinkActivated: loginDialog.openUrl(link)
|
||||
}
|
||||
}
|
||||
Row {
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
|
||||
TextField {
|
||||
id: passwordField
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
width: 350
|
||||
|
||||
label: "Password"
|
||||
echoMode: TextInput.Password
|
||||
}
|
||||
|
||||
ShortcutText {
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
text: "<a href='https://highfidelity.com/users/password/new'>Forgot Password?</a>"
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
linkColor: hifi.colors.blueAccent
|
||||
|
||||
onLinkActivated: loginDialog.openUrl(link)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
InfoItem {
|
||||
id: additionalInformation
|
||||
anchors {
|
||||
top: form.bottom
|
||||
left: parent.left
|
||||
margins: 0
|
||||
topMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
|
||||
visible: loginDialog.isSteamRunning()
|
||||
|
||||
text: qsTr("Your steam account informations will not be exposed to other users.")
|
||||
wrapMode: Text.WordWrap
|
||||
color: hifi.colors.baseGrayHighlight
|
||||
lineHeight: 1
|
||||
lineHeightMode: Text.ProportionalHeight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
// Override ScrollingWindow's keyboard that would be at very bottom of dialog.
|
||||
Keyboard {
|
||||
raised: keyboardEnabled && keyboardRaised
|
||||
numeric: punctuationMode
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: buttons.top
|
||||
bottomMargin: keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: leftButton
|
||||
anchors {
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
bottomMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: qsTr("Sign Up")
|
||||
visible: !loginDialog.isSteamRunning()
|
||||
|
||||
onClicked: {
|
||||
bodyLoader.setSource("SignUpBody.qml")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: buttons
|
||||
anchors {
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
bottomMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
||||
Button {
|
||||
id: linkAccountButton
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 200
|
||||
|
||||
text: qsTr(loginDialog.isSteamRunning() ? "Link Account" : "Login")
|
||||
color: hifi.buttons.blue
|
||||
|
||||
onClicked: linkAccountBody.login()
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: qsTr("Cancel")
|
||||
onClicked: {
|
||||
bodyLoader.popup()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
loginDialogRoot.title = qsTr("Sign Into High Fidelity")
|
||||
loginDialogRoot.iconText = "<"
|
||||
keyboardEnabled = HMD.active;
|
||||
d.resize();
|
||||
|
||||
if (failAfterSignUp) {
|
||||
mainTextContainer.text = "Account created successfully."
|
||||
mainTextContainer.visible = true
|
||||
}
|
||||
|
||||
usernameField.forceActiveFocus();
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: loginDialog
|
||||
onHandleLoginCompleted: {
|
||||
console.log("Login Succeeded, linking steam account")
|
||||
|
||||
if (loginDialog.isSteamRunning()) {
|
||||
loginDialog.linkSteam()
|
||||
} else {
|
||||
bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : true })
|
||||
}
|
||||
}
|
||||
onHandleLoginFailed: {
|
||||
console.log("Login Failed")
|
||||
mainTextContainer.visible = true
|
||||
toggleLoading(false)
|
||||
}
|
||||
onHandleLinkCompleted: {
|
||||
console.log("Link Succeeded")
|
||||
|
||||
bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : true })
|
||||
}
|
||||
onHandleLinkFailed: {
|
||||
console.log("Link Failed")
|
||||
toggleLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
if (!visible) {
|
||||
return
|
||||
}
|
||||
|
||||
switch (event.key) {
|
||||
case Qt.Key_Enter:
|
||||
case Qt.Key_Return:
|
||||
event.accepted = true
|
||||
linkAccountBody.login()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
//
|
||||
// SignInBody.qml
|
||||
//
|
||||
// Created by Clement on 7/18/16
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import Hifi 1.0
|
||||
import QtQuick 2.4
|
||||
import QtQuick.Controls.Styles 1.4 as OriginalStyles
|
||||
|
||||
import "../controls-uit"
|
||||
import "../styles-uit"
|
||||
|
||||
Item {
|
||||
id: signInBody
|
||||
clip: true
|
||||
|
||||
property bool required: false
|
||||
|
||||
function login() {
|
||||
console.log("Trying to log in")
|
||||
loginDialog.loginThroughSteam()
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
bodyLoader.popup()
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
function resize() {}
|
||||
}
|
||||
|
||||
InfoItem {
|
||||
id: mainTextContainer
|
||||
anchors {
|
||||
top: parent.top
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
margins: 0
|
||||
topMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
|
||||
text: required ? qsTr("This domain's owner requires that you sign in:")
|
||||
: qsTr("Sign in to access your user account:")
|
||||
wrapMode: Text.WordWrap
|
||||
color: hifi.colors.baseGrayHighlight
|
||||
lineHeight: 2
|
||||
lineHeightMode: Text.ProportionalHeight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
Row {
|
||||
id: buttons
|
||||
anchors {
|
||||
top: mainTextContainer.bottom
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
margins: 0
|
||||
topMargin: 2 * hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
width: undefined // invalidate so that the image's size sets the width
|
||||
height: undefined // invalidate so that the image's size sets the height
|
||||
focus: true
|
||||
|
||||
style: OriginalStyles.ButtonStyle {
|
||||
background: Image {
|
||||
id: buttonImage
|
||||
source: "../../images/steam-sign-in.png"
|
||||
}
|
||||
}
|
||||
onClicked: signInBody.login()
|
||||
}
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: qsTr("Cancel");
|
||||
|
||||
onClicked: signInBody.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
loginDialogRoot.title = required ? qsTr("Sign In Required")
|
||||
: qsTr("Sign In")
|
||||
loginDialogRoot.iconText = ""
|
||||
d.resize();
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: loginDialog
|
||||
onHandleLoginCompleted: {
|
||||
console.log("Login Succeeded")
|
||||
bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : true })
|
||||
}
|
||||
onHandleLoginFailed: {
|
||||
console.log("Login Failed")
|
||||
bodyLoader.setSource("CompleteProfileBody.qml")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,276 +0,0 @@
|
|||
//
|
||||
// SignUpBody.qml
|
||||
//
|
||||
// Created by Stephen Birarda on 7 Dec 2016
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import Hifi 1.0
|
||||
import QtQuick 2.4
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4 as OriginalStyles
|
||||
|
||||
import "../controls-uit"
|
||||
import "../styles-uit"
|
||||
|
||||
Item {
|
||||
id: signupBody
|
||||
clip: true
|
||||
// height: parent.height
|
||||
// width: parent.width
|
||||
|
||||
function signup() {
|
||||
mainTextContainer.visible = false
|
||||
toggleLoading(true)
|
||||
loginDialog.signup(emailField.text, usernameField.text, passwordField.text)
|
||||
}
|
||||
|
||||
property bool keyboardEnabled: false
|
||||
property bool keyboardRaised: false
|
||||
property bool punctuationMode: false
|
||||
|
||||
onKeyboardRaisedChanged: d.resize();
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
function resize() {}
|
||||
}
|
||||
|
||||
function toggleLoading(isLoading) {
|
||||
linkAccountSpinner.visible = isLoading
|
||||
form.visible = !isLoading
|
||||
|
||||
leftButton.visible = !isLoading
|
||||
buttons.visible = !isLoading
|
||||
}
|
||||
|
||||
BusyIndicator {
|
||||
id: linkAccountSpinner
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
topMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
|
||||
visible: false
|
||||
running: true
|
||||
|
||||
width: 48
|
||||
height: 48
|
||||
}
|
||||
|
||||
ShortcutText {
|
||||
id: mainTextContainer
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
margins: 0
|
||||
topMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
|
||||
visible: false
|
||||
|
||||
text: qsTr("There was an unknown error while creating your account.")
|
||||
wrapMode: Text.WordWrap
|
||||
color: hifi.colors.redAccent
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
}
|
||||
|
||||
Column {
|
||||
id: form
|
||||
anchors {
|
||||
top: mainTextContainer.bottom
|
||||
left: parent.left
|
||||
margins: 0
|
||||
topMargin: 2 * hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
spacing: 2 * hifi.dimensions.contentSpacing.y
|
||||
|
||||
Row {
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
|
||||
TextField {
|
||||
id: emailField
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
width: 300
|
||||
|
||||
label: "Email"
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
|
||||
TextField {
|
||||
id: usernameField
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
width: 300
|
||||
|
||||
label: "Username"
|
||||
}
|
||||
|
||||
ShortcutText {
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
text: qsTr("No spaces / special chars.")
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
||||
color: hifi.colors.blueAccent
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
|
||||
TextField {
|
||||
id: passwordField
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
width: 300
|
||||
|
||||
label: "Password"
|
||||
echoMode: TextInput.Password
|
||||
}
|
||||
|
||||
ShortcutText {
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
text: qsTr("At least 6 characters")
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
||||
color: hifi.colors.blueAccent
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Override ScrollingWindow's keyboard that would be at very bottom of dialog.
|
||||
Keyboard {
|
||||
raised: keyboardEnabled && keyboardRaised
|
||||
numeric: punctuationMode
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: buttons.top
|
||||
bottomMargin: keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: leftButton
|
||||
anchors {
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
bottomMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: qsTr("Existing User")
|
||||
|
||||
onClicked: {
|
||||
bodyLoader.setSource("LinkAccountBody.qml")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: buttons
|
||||
anchors {
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
bottomMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
||||
Button {
|
||||
id: linkAccountButton
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 200
|
||||
|
||||
text: qsTr("Sign Up")
|
||||
color: hifi.buttons.blue
|
||||
|
||||
onClicked: signupBody.signup()
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: qsTr("Cancel")
|
||||
|
||||
onClicked: bodyLoader.popup()
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
loginDialogRoot.title = qsTr("Create an Account")
|
||||
loginDialogRoot.iconText = "<"
|
||||
keyboardEnabled = HMD.active;
|
||||
d.resize();
|
||||
|
||||
emailField.forceActiveFocus();
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: loginDialog
|
||||
onHandleSignupCompleted: {
|
||||
console.log("Sign Up Succeeded");
|
||||
|
||||
// now that we have an account, login with that username and password
|
||||
loginDialog.login(usernameField.text, passwordField.text)
|
||||
}
|
||||
onHandleSignupFailed: {
|
||||
console.log("Sign Up Failed")
|
||||
toggleLoading(false)
|
||||
|
||||
mainTextContainer.text = errorString
|
||||
mainTextContainer.visible = true
|
||||
|
||||
d.resize();
|
||||
}
|
||||
onHandleLoginCompleted: {
|
||||
bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack": false })
|
||||
}
|
||||
onHandleLoginFailed: {
|
||||
// we failed to login, show the LoginDialog so the user will try again
|
||||
bodyLoader.setSource("LinkAccountBody.qml", { "failAfterSignUp": true })
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
if (!visible) {
|
||||
return
|
||||
}
|
||||
|
||||
switch (event.key) {
|
||||
case Qt.Key_Enter:
|
||||
case Qt.Key_Return:
|
||||
event.accepted = true
|
||||
signupBody.signup()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,157 +0,0 @@
|
|||
//
|
||||
// UsernameCollisionBody.qml
|
||||
//
|
||||
// Created by Clement on 7/18/16
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import Hifi 1.0
|
||||
import QtQuick 2.4
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4 as OriginalStyles
|
||||
|
||||
import "../controls-uit"
|
||||
import "../styles-uit"
|
||||
|
||||
Item {
|
||||
id: usernameCollisionBody
|
||||
clip: true
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
function create() {
|
||||
mainTextContainer.visible = false
|
||||
loginDialog.createAccountFromStream(textField.text)
|
||||
}
|
||||
|
||||
|
||||
property bool keyboardEnabled: false
|
||||
property bool keyboardRaised: false
|
||||
property bool punctuationMode: false
|
||||
|
||||
onKeyboardRaisedChanged: d.resize();
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
function resize() {}
|
||||
}
|
||||
|
||||
ShortcutText {
|
||||
id: mainTextContainer
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
margins: 0
|
||||
topMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
|
||||
text: qsTr("Your Steam username is not available.")
|
||||
wrapMode: Text.WordWrap
|
||||
color: hifi.colors.redAccent
|
||||
lineHeight: 1
|
||||
lineHeightMode: Text.ProportionalHeight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
|
||||
TextField {
|
||||
id: textField
|
||||
anchors {
|
||||
top: mainTextContainer.bottom
|
||||
left: parent.left
|
||||
margins: 0
|
||||
topMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
width: 250
|
||||
|
||||
placeholderText: "Choose your own"
|
||||
}
|
||||
|
||||
// Override ScrollingWindow's keyboard that would be at very bottom of dialog.
|
||||
Keyboard {
|
||||
raised: keyboardEnabled && keyboardRaised
|
||||
numeric: punctuationMode
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: buttons.top
|
||||
bottomMargin: keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: buttons
|
||||
anchors {
|
||||
bottom: parent.bottom
|
||||
right: parent.right
|
||||
margins: 0
|
||||
topMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 200
|
||||
|
||||
text: qsTr("Create your profile")
|
||||
color: hifi.buttons.blue
|
||||
|
||||
onClicked: usernameCollisionBody.create()
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: qsTr("Cancel")
|
||||
onClicked: bodyLoader.popup()
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
loginDialogRoot.title = qsTr("Complete Your Profile")
|
||||
loginDialogRoot.iconText = "<"
|
||||
keyboardEnabled = HMD.active;
|
||||
d.resize();
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: loginDialog
|
||||
onHandleCreateCompleted: {
|
||||
console.log("Create Succeeded")
|
||||
|
||||
loginDialog.loginThroughSteam()
|
||||
}
|
||||
onHandleCreateFailed: {
|
||||
console.log("Create Failed: " + error)
|
||||
|
||||
mainTextContainer.visible = true
|
||||
mainTextContainer.text = "\"" + textField.text + qsTr("\" is invalid or already taken.")
|
||||
}
|
||||
onHandleLoginCompleted: {
|
||||
console.log("Login Succeeded")
|
||||
|
||||
bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : false })
|
||||
}
|
||||
onHandleLoginFailed: {
|
||||
console.log("Login Failed")
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
if (!visible) {
|
||||
return
|
||||
}
|
||||
|
||||
switch (event.key) {
|
||||
case Qt.Key_Enter:
|
||||
case Qt.Key_Return:
|
||||
event.accepted = true
|
||||
usernameCollisionBody.create()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
//
|
||||
// WelcomeBody.qml
|
||||
//
|
||||
// Created by Clement on 7/18/16
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import Hifi 1.0
|
||||
import QtQuick 2.4
|
||||
|
||||
import "../controls-uit"
|
||||
import "../styles-uit"
|
||||
|
||||
Item {
|
||||
id: welcomeBody
|
||||
clip: true
|
||||
|
||||
property bool welcomeBack: false
|
||||
|
||||
function setTitle() {
|
||||
loginDialogRoot.title = (welcomeBack ? qsTr("Welcome back <b>") : qsTr("Welcome <b>")) + Account.username + qsTr("</b>!")
|
||||
loginDialogRoot.iconText = ""
|
||||
d.resize();
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
function resize() {}
|
||||
}
|
||||
|
||||
InfoItem {
|
||||
id: mainTextContainer
|
||||
anchors {
|
||||
top: parent.top
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
margins: 0
|
||||
topMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
|
||||
text: qsTr("You are now signed into High Fidelity")
|
||||
wrapMode: Text.WordWrap
|
||||
color: hifi.colors.baseGrayHighlight
|
||||
lineHeight: 2
|
||||
lineHeightMode: Text.ProportionalHeight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
Row {
|
||||
id: buttons
|
||||
anchors {
|
||||
top: mainTextContainer.bottom
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
margins: 0
|
||||
topMargin: 2 * hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||
|
||||
Button {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: qsTr("Close");
|
||||
|
||||
onClicked: bodyLoader.popup()
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
welcomeBody.setTitle()
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Account
|
||||
onUsernameChanged: welcomeBody.setTitle()
|
||||
}
|
||||
}
|
|
@ -35,6 +35,7 @@ TextField {
|
|||
font.pixelSize: hifi.fontSizes.textFieldInput
|
||||
font.italic: textField.text == ""
|
||||
height: implicitHeight + 3 // Make surrounding box higher so that highlight is vertically centered.
|
||||
property alias textFieldLabel: textFieldLabel
|
||||
|
||||
y: textFieldLabel.visible ? textFieldLabel.height + textFieldLabel.anchors.bottomMargin : 0
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ FocusScope {
|
|||
return;
|
||||
}
|
||||
var oldRecommendedRect = recommendedRect;
|
||||
var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedOverlayRect();
|
||||
var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedHUDRect();
|
||||
var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y,
|
||||
newRecommendedRectJS.width,
|
||||
newRecommendedRectJS.height);
|
||||
|
@ -271,7 +271,7 @@ FocusScope {
|
|||
|
||||
var oldRecommendedRect = recommendedRect;
|
||||
var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height };
|
||||
var newRecommendedRect = Controller.getRecommendedOverlayRect();
|
||||
var newRecommendedRect = Controller.getRecommendedHUDRect();
|
||||
var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height };
|
||||
var windows = d.getTopLevelWindows();
|
||||
for (var i = 0; i < windows.length; ++i) {
|
||||
|
@ -298,6 +298,23 @@ FocusScope {
|
|||
pinned = !pinned
|
||||
}
|
||||
|
||||
function isPointOnWindow(point) {
|
||||
for (var i = 0; i < desktop.visibleChildren.length; i++) {
|
||||
var child = desktop.visibleChildren[i];
|
||||
if (child.visible) {
|
||||
if (child.hasOwnProperty("modality")) {
|
||||
var mappedPoint = child.mapFromGlobal(point.x, point.y);
|
||||
var outLine = child.frame.children[2];
|
||||
var framePoint = outLine.mapFromGlobal(point.x, point.y);
|
||||
if (child.contains(mappedPoint) || outLine.contains(framePoint)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function setPinned(newPinned) {
|
||||
pinned = newPinned
|
||||
}
|
||||
|
@ -393,7 +410,7 @@ FocusScope {
|
|||
return;
|
||||
}
|
||||
|
||||
var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedOverlayRect();
|
||||
var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedHUDRect();
|
||||
var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y,
|
||||
newRecommendedRectJS.width,
|
||||
newRecommendedRectJS.height);
|
||||
|
@ -425,7 +442,7 @@ FocusScope {
|
|||
|
||||
var oldRecommendedRect = recommendedRect;
|
||||
var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height };
|
||||
var newRecommendedRect = Controller.getRecommendedOverlayRect();
|
||||
var newRecommendedRect = Controller.getRecommendedHUDRect();
|
||||
var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height };
|
||||
repositionWindow(targetWindow, false, oldRecommendedRect, oldRecommendedDimmensions, newRecommendedRect, newRecommendedDimmensions);
|
||||
}
|
||||
|
@ -442,7 +459,7 @@ FocusScope {
|
|||
return;
|
||||
}
|
||||
|
||||
var recommended = Controller.getRecommendedOverlayRect();
|
||||
var recommended = Controller.getRecommendedHUDRect();
|
||||
var maxX = recommended.x + recommended.width;
|
||||
var maxY = recommended.y + recommended.height;
|
||||
var newPosition = Qt.vector2d(targetWindow.x, targetWindow.y);
|
||||
|
|
|
@ -16,48 +16,66 @@ import "../controls-uit"
|
|||
import "../styles-uit"
|
||||
import "../windows"
|
||||
|
||||
import "../LoginDialog"
|
||||
|
||||
TabletModalWindow {
|
||||
id: loginDialogRoot
|
||||
id: realRoot
|
||||
objectName: "LoginDialog"
|
||||
|
||||
signal sendToScript(var message);
|
||||
property bool isHMD: false
|
||||
property bool gotoPreviousApp: false;
|
||||
color: hifi.colors.baseGray
|
||||
title: qsTr("Sign in to High Fidelity")
|
||||
property alias titleWidth: root.titleWidth
|
||||
property alias punctuationMode: root.punctuationMode
|
||||
|
||||
//fake root for shared components expecting root here
|
||||
property var root: QtObject {
|
||||
id: root
|
||||
|
||||
property bool keyboardEnabled: false
|
||||
property bool keyboardRaised: false
|
||||
property bool punctuationMode: false
|
||||
|
||||
readonly property bool isTablet: true
|
||||
|
||||
property alias title: realRoot.title
|
||||
property real width: realRoot.width
|
||||
property real height: realRoot.height
|
||||
|
||||
property int titleWidth: 0
|
||||
property string iconText: hifi.glyphs.avatar
|
||||
property int iconSize: 35
|
||||
|
||||
property var pane: QtObject {
|
||||
property real width: root.width
|
||||
property real height: root.height
|
||||
}
|
||||
|
||||
function tryDestroy() {
|
||||
canceled()
|
||||
}
|
||||
}
|
||||
|
||||
//property int colorScheme: hifi.colorSchemes.dark
|
||||
|
||||
property int colorScheme: hifi.colorSchemes.dark
|
||||
property int titleWidth: 0
|
||||
property string iconText: ""
|
||||
property int icon: hifi.icons.none
|
||||
property int iconSize: 35
|
||||
MouseArea {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
width: realRoot.width
|
||||
height: realRoot.height
|
||||
}
|
||||
|
||||
property bool keyboardOverride: true
|
||||
onIconChanged: updateIcon();
|
||||
|
||||
property var items;
|
||||
property string label: ""
|
||||
|
||||
onTitleWidthChanged: d.resize();
|
||||
//onTitleWidthChanged: d.resize();
|
||||
|
||||
property bool keyboardEnabled: false
|
||||
property bool keyboardRaised: false
|
||||
property bool punctuationMode: false
|
||||
|
||||
onKeyboardRaisedChanged: d.resize();
|
||||
//onKeyboardRaisedChanged: d.resize();
|
||||
|
||||
signal canceled();
|
||||
|
||||
function updateIcon() {
|
||||
if (!root) {
|
||||
return;
|
||||
}
|
||||
iconText = hifi.glyphForIcon(root.icon);
|
||||
}
|
||||
|
||||
property alias bodyLoader: bodyLoader
|
||||
property alias loginDialog: loginDialog
|
||||
property alias hifi: hifi
|
||||
|
@ -65,9 +83,10 @@ TabletModalWindow {
|
|||
HifiConstants { id: hifi }
|
||||
|
||||
onCanceled: {
|
||||
if (loginDialogRoot.Stack.view) {
|
||||
loginDialogRoot.Stack.view.pop();
|
||||
} else if (gotoPreviousApp) {
|
||||
if (bodyLoader.active === true) {
|
||||
//bodyLoader.active = false
|
||||
}
|
||||
if (gotoPreviousApp) {
|
||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
tablet.returnToPreviousApp();
|
||||
} else {
|
||||
|
@ -75,45 +94,81 @@ TabletModalWindow {
|
|||
}
|
||||
}
|
||||
|
||||
LoginDialog {
|
||||
id: loginDialog
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
StackView {
|
||||
id: bodyLoader
|
||||
property var item: currentItem
|
||||
property var props
|
||||
property string source: ""
|
||||
TabletModalFrame {
|
||||
id: mfRoot
|
||||
|
||||
onCurrentItemChanged: {
|
||||
//cleanup source for future usage
|
||||
source = ""
|
||||
width: root.width
|
||||
height: root.height + frameMarginTop + hifi.dimensions.contentMargin.x
|
||||
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
verticalCenter: parent.verticalCenter
|
||||
verticalCenterOffset: -loginKeyboard.height / 2
|
||||
}
|
||||
|
||||
LoginDialog {
|
||||
id: loginDialog
|
||||
|
||||
anchors {
|
||||
fill: parent
|
||||
topMargin: parent.frameMarginTop
|
||||
leftMargin: hifi.dimensions.contentMargin.x
|
||||
rightMargin: hifi.dimensions.contentMargin.x
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
function setSource(src, props) {
|
||||
source = "../TabletLoginDialog/" + src
|
||||
bodyLoader.props = props
|
||||
}
|
||||
function popup() {
|
||||
bodyLoader.pop()
|
||||
|
||||
//check if last screen, if yes, dialog is popped out
|
||||
if (depth === 1)
|
||||
loginDialogRoot.canceled()
|
||||
}
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: 10
|
||||
onSourceChanged: {
|
||||
if (source !== "") {
|
||||
bodyLoader.push(Qt.resolvedUrl(source), props)
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
setSource(loginDialog.isSteamRunning() ?
|
||||
"SignInBody.qml" :
|
||||
"LinkAccountBody.qml")
|
||||
Loader {
|
||||
id: bodyLoader
|
||||
anchors.fill: parent
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
source: loginDialog.isSteamRunning() ? "../LoginDialog/SignInBody.qml" : "../LoginDialog/LinkAccountBody.qml"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Keyboard {
|
||||
id: loginKeyboard
|
||||
raised: root.keyboardEnabled && root.keyboardRaised
|
||||
numeric: root.punctuationMode
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
if (!visible) {
|
||||
return
|
||||
}
|
||||
|
||||
if (event.modifiers === Qt.ControlModifier)
|
||||
switch (event.key) {
|
||||
case Qt.Key_A:
|
||||
event.accepted = true
|
||||
detailedText.selectAll()
|
||||
break
|
||||
case Qt.Key_C:
|
||||
event.accepted = true
|
||||
detailedText.copy()
|
||||
break
|
||||
case Qt.Key_Period:
|
||||
if (Qt.platform.os === "osx") {
|
||||
event.accepted = true
|
||||
content.reject()
|
||||
}
|
||||
break
|
||||
} else switch (event.key) {
|
||||
case Qt.Key_Escape:
|
||||
case Qt.Key_Back:
|
||||
event.accepted = true
|
||||
destroy()
|
||||
break
|
||||
|
||||
case Qt.Key_Enter:
|
||||
case Qt.Key_Return:
|
||||
event.accepted = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,10 +14,10 @@ import QtQuick.Controls.Styles 1.4
|
|||
import QtQuick.Dialogs 1.2 as OriginalDialogs
|
||||
import Qt.labs.settings 1.0
|
||||
|
||||
import "styles-uit"
|
||||
import "controls-uit" as HifiControls
|
||||
import "windows"
|
||||
import "dialogs"
|
||||
import "../styles-uit"
|
||||
import "../controls-uit" as HifiControls
|
||||
import "../windows"
|
||||
import "../dialogs"
|
||||
|
||||
ScrollingWindow {
|
||||
id: root
|
||||
|
@ -38,7 +38,7 @@ ScrollingWindow {
|
|||
property var assetMappingsModel: Assets.mappingModel;
|
||||
property var currentDirectory;
|
||||
property var selectedItems: treeView.selection.selectedIndexes.length;
|
||||
|
||||
|
||||
Settings {
|
||||
category: "Overlay.AssetServer"
|
||||
property alias x: root.x
|
||||
|
@ -58,6 +58,23 @@ ScrollingWindow {
|
|||
assetMappingsModel.autoRefreshEnabled = false;
|
||||
}
|
||||
|
||||
function letterbox(headerGlyph, headerText, message) {
|
||||
letterboxMessage.headerGlyph = headerGlyph;
|
||||
letterboxMessage.headerText = headerText;
|
||||
letterboxMessage.text = message;
|
||||
letterboxMessage.visible = true;
|
||||
letterboxMessage.popupRadius = 0;
|
||||
}
|
||||
|
||||
function errorMessageBox(message) {
|
||||
return desktop.messageBox({
|
||||
icon: hifi.icons.warning,
|
||||
defaultButton: OriginalDialogs.StandardButton.Ok,
|
||||
title: "Error",
|
||||
text: message
|
||||
});
|
||||
}
|
||||
|
||||
function doDeleteFile(path) {
|
||||
console.log("Deleting " + path);
|
||||
|
||||
|
@ -154,10 +171,7 @@ ScrollingWindow {
|
|||
}
|
||||
|
||||
function handleGetMappingsError(errorString) {
|
||||
errorMessageBox(
|
||||
"There was a problem retreiving the list of assets from your Asset Server.\n"
|
||||
+ errorString
|
||||
);
|
||||
errorMessageBox("There was a problem retrieving the list of assets from your Asset Server.\n" + errorString);
|
||||
}
|
||||
|
||||
function addToWorld() {
|
||||
|
@ -332,7 +346,7 @@ ScrollingWindow {
|
|||
if (!path) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var modalMessage = "";
|
||||
var items = selectedItems.toString();
|
||||
var isFolder = assetProxyModel.data(treeView.selection.currentIndex, 0x101);
|
||||
|
@ -448,19 +462,16 @@ ScrollingWindow {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
function errorMessageBox(message) {
|
||||
return desktop.messageBox({
|
||||
icon: hifi.icons.warning,
|
||||
defaultButton: OriginalDialogs.StandardButton.Ok,
|
||||
title: "Error",
|
||||
text: message
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Item {
|
||||
width: pane.contentWidth
|
||||
height: pane.height
|
||||
|
||||
// The letterbox used for popup messages
|
||||
LetterboxMessage {
|
||||
id: letterboxMessage;
|
||||
z: 999; // Force the popup on top of everything else
|
||||
}
|
||||
|
||||
HifiControls.ContentSection {
|
||||
id: assetDirectory
|
||||
|
@ -476,21 +487,21 @@ ScrollingWindow {
|
|||
|
||||
HifiControls.Button {
|
||||
text: "Add To World"
|
||||
color: hifi.buttons.black
|
||||
color: hifi.buttons.blue
|
||||
colorScheme: root.colorScheme
|
||||
width: 120
|
||||
|
||||
|
||||
enabled: canAddToWorld(assetProxyModel.data(treeView.selection.currentIndex, 0x100))
|
||||
|
||||
|
||||
onClicked: root.addToWorld()
|
||||
}
|
||||
|
||||
|
||||
HifiControls.Button {
|
||||
text: "Rename"
|
||||
color: hifi.buttons.black
|
||||
colorScheme: root.colorScheme
|
||||
width: 80
|
||||
|
||||
|
||||
onClicked: root.renameFile()
|
||||
enabled: canRename()
|
||||
}
|
||||
|
@ -513,6 +524,7 @@ ScrollingWindow {
|
|||
id: treeView
|
||||
anchors.top: assetDirectory.bottom
|
||||
anchors.bottom: infoRow.top
|
||||
anchors.bottomMargin: 2 * hifi.dimensions.contentSpacing.y
|
||||
anchors.margins: hifi.dimensions.contentMargin.x + 2 // Extra for border
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
@ -555,7 +567,7 @@ ScrollingWindow {
|
|||
case "Not Baked":
|
||||
return hifi.glyphs.circleSlash;
|
||||
case "Baked":
|
||||
return hifi.glyphs.check_2_01;
|
||||
return hifi.glyphs.checkmark;
|
||||
case "Error":
|
||||
return hifi.glyphs.alert;
|
||||
default:
|
||||
|
@ -584,8 +596,24 @@ ScrollingWindow {
|
|||
? (styleData.selected ? hifi.colors.black : hifi.colors.baseGrayHighlight)
|
||||
: (styleData.selected ? hifi.colors.black : hifi.colors.lightGrayText)
|
||||
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: styleData.column === 1 ? TextInput.AlignHCenter : TextInput.AlignLeft
|
||||
|
||||
elide: Text.ElideMiddle
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
|
||||
acceptedButtons: Qt.NoButton
|
||||
hoverEnabled: true
|
||||
|
||||
onEntered: {
|
||||
if (parent.truncated) {
|
||||
treeLabelToolTip.show(parent);
|
||||
}
|
||||
}
|
||||
onExited: treeLabelToolTip.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
Component {
|
||||
|
@ -668,6 +696,42 @@ ScrollingWindow {
|
|||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: treeLabelToolTip
|
||||
visible: false
|
||||
z: 100 // Render on top
|
||||
|
||||
width: toolTipText.width + 2 * hifi.dimensions.textPadding
|
||||
height: hifi.dimensions.tableRowHeight
|
||||
color: colorScheme == hifi.colorSchemes.light ? hifi.colors.tableRowLightOdd : hifi.colors.tableRowDarkOdd
|
||||
border.color: colorScheme == hifi.colorSchemes.light ? hifi.colors.black : hifi.colors.lightGrayText
|
||||
|
||||
FiraSansSemiBold {
|
||||
id: toolTipText
|
||||
anchors.centerIn: parent
|
||||
|
||||
size: hifi.fontSizes.tableText
|
||||
color: colorScheme == hifi.colorSchemes.light ? hifi.colors.black : hifi.colors.lightGrayText
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: showTimer
|
||||
interval: 1000
|
||||
onTriggered: { treeLabelToolTip.visible = true; }
|
||||
}
|
||||
function show(item) {
|
||||
var coord = item.mapToItem(parent, item.x, item.y);
|
||||
|
||||
toolTipText.text = item.text;
|
||||
treeLabelToolTip.x = coord.x - hifi.dimensions.textPadding;
|
||||
treeLabelToolTip.y = coord.y;
|
||||
showTimer.start();
|
||||
}
|
||||
function hide() {
|
||||
showTimer.stop();
|
||||
treeLabelToolTip.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
propagateComposedEvents: true
|
||||
|
@ -717,26 +781,35 @@ ScrollingWindow {
|
|||
anchors.left: treeView.left
|
||||
anchors.right: treeView.right
|
||||
anchors.bottom: uploadSection.top
|
||||
anchors.bottomMargin: hifi.dimensions.contentSpacing.y
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
|
||||
RalewayRegular {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
function makeText() {
|
||||
var numPendingBakes = assetMappingsModel.numPendingBakes;
|
||||
if (selectedItems > 1 || numPendingBakes === 0) {
|
||||
return selectedItems + " items selected";
|
||||
} else {
|
||||
return numPendingBakes + " bakes pending"
|
||||
}
|
||||
}
|
||||
|
||||
size: hifi.fontSizes.sectionName
|
||||
font.capitalization: Font.AllUppercase
|
||||
text: selectedItems + " items selected"
|
||||
text: makeText()
|
||||
color: hifi.colors.lightGrayText
|
||||
}
|
||||
|
||||
HifiControls.CheckBox {
|
||||
function isChecked() {
|
||||
var status = assetProxyModel.data(treeView.selection.currentIndex, 0x105);
|
||||
var bakingDisabled = (status === "Not Baked" || status === "--");
|
||||
return selectedItems === 1 && !bakingDisabled;
|
||||
}
|
||||
HifiControls.HorizontalSpacer { }
|
||||
|
||||
text: "Use baked (optimized) versions"
|
||||
HifiControls.CheckBox {
|
||||
id: bakingCheckbox
|
||||
anchors.leftMargin: 2 * hifi.dimensions.contentSpacing.x
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: " Use baked version"
|
||||
colorScheme: root.colorScheme
|
||||
enabled: selectedItems === 1 && assetProxyModel.data(treeView.selection.currentIndex, 0x105) !== "--"
|
||||
enabled: isEnabled()
|
||||
checked: isChecked()
|
||||
onClicked: {
|
||||
var mappings = [];
|
||||
|
@ -752,7 +825,66 @@ ScrollingWindow {
|
|||
|
||||
checked = Qt.binding(isChecked);
|
||||
}
|
||||
|
||||
function isEnabled() {
|
||||
if (!treeView.selection.hasSelection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var status = assetProxyModel.data(treeView.selection.currentIndex, 0x105);
|
||||
if (status === "--") {
|
||||
return false;
|
||||
}
|
||||
var bakingEnabled = status !== "Not Baked";
|
||||
|
||||
for (var i in treeView.selection.selectedIndexes) {
|
||||
var thisStatus = assetProxyModel.data(treeView.selection.selectedIndexes[i], 0x105);
|
||||
if (thisStatus === "--") {
|
||||
return false;
|
||||
}
|
||||
var thisBakingEnalbed = (thisStatus !== "Not Baked");
|
||||
|
||||
if (bakingEnabled !== thisBakingEnalbed) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
function isChecked() {
|
||||
if (!treeView.selection.hasSelection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var status = assetProxyModel.data(treeView.selection.currentIndex, 0x105);
|
||||
return isEnabled() && status !== "Not Baked";
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: infoGlyph.size;
|
||||
height: infoGlyph.size;
|
||||
|
||||
HiFiGlyphs {
|
||||
id: infoGlyph;
|
||||
anchors.fill: parent;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
text: hifi.glyphs.question;
|
||||
size: 35;
|
||||
color: hifi.colors.lightGrayText;
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: true;
|
||||
onEntered: infoGlyph.color = hifi.colors.blueHighlight;
|
||||
onExited: infoGlyph.color = hifi.colors.lightGrayText;
|
||||
onClicked: letterbox(hifi.glyphs.question,
|
||||
"What is baking?",
|
||||
"Baking compresses and optimizes files for faster network transfer and display. We recommend you bake your content to reduce initial load times for your visitors.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HifiControls.ContentSection {
|
||||
|
@ -790,7 +922,7 @@ ScrollingWindow {
|
|||
id: image
|
||||
width: 24
|
||||
height: 24
|
||||
source: "../images/Loading-Outer-Ring.png"
|
||||
source: "../../images/Loading-Outer-Ring.png"
|
||||
RotationAnimation on rotation {
|
||||
loops: Animation.Infinite
|
||||
from: 0
|
||||
|
@ -801,7 +933,7 @@ ScrollingWindow {
|
|||
Image {
|
||||
width: 24
|
||||
height: 24
|
||||
source: "../images/Loading-Inner-H.png"
|
||||
source: "../../images/Loading-Inner-H.png"
|
||||
}
|
||||
HifiControls.Label {
|
||||
id: uploadProgressLabel
|
||||
|
@ -811,10 +943,9 @@ ScrollingWindow {
|
|||
text: "In progress..."
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -167,6 +167,9 @@ Rectangle {
|
|||
}
|
||||
RalewayRegular {
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
width: margins.sizeText + margins.sizeLevel
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: margins.sizeCheckBox
|
||||
size: 16;
|
||||
color: hifi.colors.lightGrayText;
|
||||
text: qsTr("CHOOSE INPUT DEVICE");
|
||||
|
|
|
@ -29,12 +29,22 @@ RowLayout {
|
|||
function playSound() {
|
||||
// FIXME: MyAvatar is not properly exposed to QML; MyAvatar.qmlPosition is a stopgap
|
||||
// FIXME: Audio.playSystemSound should not require position
|
||||
sample = Audio.playSystemSound(sound, MyAvatar.qmlPosition);
|
||||
isPlaying = true;
|
||||
sample.finished.connect(function() { isPlaying = false; sample = null; });
|
||||
if (sample === null && !isPlaying) {
|
||||
sample = Audio.playSystemSound(sound, MyAvatar.qmlPosition);
|
||||
isPlaying = true;
|
||||
sample.finished.connect(reset);
|
||||
}
|
||||
}
|
||||
function stopSound() {
|
||||
sample && sample.stop();
|
||||
if (sample && isPlaying) {
|
||||
sample.stop();
|
||||
}
|
||||
}
|
||||
|
||||
function reset() {
|
||||
sample.finished.disconnect(reset);
|
||||
isPlaying = false;
|
||||
sample = null;
|
||||
}
|
||||
|
||||
Component.onCompleted: createSampleSound();
|
||||
|
|
|
@ -26,74 +26,60 @@ Rectangle {
|
|||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
objectName: "checkout"
|
||||
property string activeView: "initialize";
|
||||
property bool purchasesReceived: false;
|
||||
property bool balanceReceived: false;
|
||||
property bool securityImageResultReceived: false;
|
||||
property string itemName;
|
||||
property string itemId;
|
||||
property string itemPreviewImageUrl;
|
||||
property string itemHref;
|
||||
property double balanceAfterPurchase;
|
||||
property bool alreadyOwned: false;
|
||||
property int itemPrice: 0;
|
||||
property int itemPrice: -1;
|
||||
property bool itemIsJson: true;
|
||||
property bool shouldBuyWithControlledFailure: false;
|
||||
property bool debugCheckoutSuccess: false;
|
||||
property bool canRezCertifiedItems: false;
|
||||
property bool canRezCertifiedItems: Entities.canRezCertified || Entities.canRezTmpCertified;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onWalletStatusResult: {
|
||||
if (walletStatus === 0) {
|
||||
if (root.activeView !== "needsLogIn") {
|
||||
root.activeView = "needsLogIn";
|
||||
}
|
||||
} else if (walletStatus === 1) {
|
||||
if (root.activeView !== "notSetUp") {
|
||||
root.activeView = "notSetUp";
|
||||
notSetUpTimer.start();
|
||||
}
|
||||
} else if (walletStatus === 2) {
|
||||
if (root.activeView !== "passphraseModal") {
|
||||
root.activeView = "passphraseModal";
|
||||
}
|
||||
} else if (walletStatus === 3) {
|
||||
authSuccessStep();
|
||||
} else {
|
||||
console.log("ERROR in Checkout.qml: Unknown wallet status: " + walletStatus);
|
||||
}
|
||||
}
|
||||
|
||||
onLoginStatusResult: {
|
||||
if (!isLoggedIn && root.activeView !== "needsLogIn") {
|
||||
root.activeView = "needsLogIn";
|
||||
} else if (isLoggedIn) {
|
||||
root.activeView = "initialize";
|
||||
commerce.account();
|
||||
}
|
||||
}
|
||||
|
||||
onAccountResult: {
|
||||
if (result.status === "success") {
|
||||
commerce.getKeyFilePathIfExists();
|
||||
} else {
|
||||
// unsure how to handle a failure here. We definitely cannot proceed.
|
||||
}
|
||||
}
|
||||
|
||||
onKeyFilePathIfExistsResult: {
|
||||
if (path === "" && root.activeView !== "notSetUp") {
|
||||
root.activeView = "notSetUp";
|
||||
notSetUpTimer.start();
|
||||
} else if (path !== "" && root.activeView === "initialize") {
|
||||
commerce.getSecurityImage();
|
||||
}
|
||||
}
|
||||
|
||||
onSecurityImageResult: {
|
||||
securityImageResultReceived = true;
|
||||
if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up"
|
||||
root.activeView = "notSetUp";
|
||||
notSetUpTimer.start();
|
||||
} else if (exists && root.activeView === "initialize") {
|
||||
commerce.getWalletAuthenticatedStatus();
|
||||
}
|
||||
}
|
||||
|
||||
onWalletAuthenticatedStatusResult: {
|
||||
if (!isAuthenticated && root.activeView !== "passphraseModal") {
|
||||
root.activeView = "passphraseModal";
|
||||
} else if (isAuthenticated) {
|
||||
authSuccessStep();
|
||||
commerce.getWalletStatus();
|
||||
}
|
||||
}
|
||||
|
||||
onBuyResult: {
|
||||
if (result.status !== 'success') {
|
||||
failureErrorText.text = "Here's some more info about the error:<br><br>" + (result.message);
|
||||
failureErrorText.text = result.message;
|
||||
root.activeView = "checkoutFailure";
|
||||
} else {
|
||||
root.itemHref = result.data.download_url;
|
||||
root.activeView = "checkoutSuccess";
|
||||
}
|
||||
}
|
||||
|
@ -123,11 +109,24 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
onItemIdChanged: {
|
||||
commerce.inventory();
|
||||
itemPreviewImage.source = "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/previews/" + itemId + "/thumbnail/hifi-mp-" + itemId + ".jpg";
|
||||
}
|
||||
|
||||
onItemHrefChanged: {
|
||||
itemIsJson = root.itemHref.endsWith('.json');
|
||||
}
|
||||
|
||||
onItemPriceChanged: {
|
||||
commerce.balance();
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: notSetUpTimer;
|
||||
interval: 200;
|
||||
onTriggered: {
|
||||
sendToScript({method: 'checkout_walletNotSetUp'});
|
||||
sendToScript({method: 'checkout_walletNotSetUp', itemId: itemId});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,6 +175,13 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
enabled: titleBarContainer.usernameDropdownVisible;
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
titleBarContainer.usernameDropdownVisible = false;
|
||||
}
|
||||
}
|
||||
//
|
||||
// TITLE BAR END
|
||||
//
|
||||
|
@ -190,10 +196,9 @@ Rectangle {
|
|||
color: hifi.colors.white;
|
||||
|
||||
Component.onCompleted: {
|
||||
securityImageResultReceived = false;
|
||||
purchasesReceived = false;
|
||||
balanceReceived = false;
|
||||
commerce.getLoginStatus();
|
||||
commerce.getWalletStatus();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,7 +286,6 @@ Rectangle {
|
|||
|
||||
Image {
|
||||
id: itemPreviewImage;
|
||||
source: root.itemPreviewImageUrl;
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
@ -291,6 +295,7 @@ Rectangle {
|
|||
|
||||
RalewaySemiBold {
|
||||
id: itemNameText;
|
||||
text: root.itemName;
|
||||
// Text size
|
||||
size: 26;
|
||||
// Anchors
|
||||
|
@ -315,19 +320,19 @@ Rectangle {
|
|||
anchors.top: parent.top;
|
||||
anchors.right: parent.right;
|
||||
height: 30;
|
||||
width: childrenRect.width;
|
||||
width: itemPriceTextLabel.width + itemPriceText.width + 20;
|
||||
|
||||
// "HFC" balance label
|
||||
HiFiGlyphs {
|
||||
id: itemPriceTextLabel;
|
||||
text: hifi.glyphs.hfc;
|
||||
// Size
|
||||
size: 36;
|
||||
size: 30;
|
||||
// Anchors
|
||||
anchors.right: itemPriceText.left;
|
||||
anchors.rightMargin: 4;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: -4;
|
||||
anchors.topMargin: 0;
|
||||
width: paintedWidth;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
|
@ -335,7 +340,7 @@ Rectangle {
|
|||
}
|
||||
FiraSansSemiBold {
|
||||
id: itemPriceText;
|
||||
text: "--";
|
||||
text: (root.itemPrice === -1) ? "--" : root.itemPrice;
|
||||
// Text size
|
||||
size: 26;
|
||||
// Anchors
|
||||
|
@ -405,7 +410,7 @@ Rectangle {
|
|||
verticalAlignment: Text.AlignTop;
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
RalewayRegular {
|
||||
id: buyText;
|
||||
// Text size
|
||||
size: 18;
|
||||
|
@ -424,7 +429,7 @@ Rectangle {
|
|||
verticalAlignment: Text.AlignVCenter;
|
||||
|
||||
onLinkActivated: {
|
||||
sendToScript({method: 'checkout_goToPurchases', filterText: itemNameText.text});
|
||||
sendToScript({method: 'checkout_goToPurchases', filterText: root.itemName});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -508,7 +513,7 @@ Rectangle {
|
|||
|
||||
RalewaySemiBold {
|
||||
id: completeText2;
|
||||
text: "The item " + '<font color="' + hifi.colors.blueAccent + '"><a href="#">' + itemNameText.text + '</a></font>' +
|
||||
text: "The item " + '<font color="' + hifi.colors.blueAccent + '"><a href="#">' + root.itemName + '</a></font>' +
|
||||
" has been added to your Purchases and a receipt will appear in your Wallet's transaction history.";
|
||||
// Text size
|
||||
size: 20;
|
||||
|
@ -570,8 +575,8 @@ Rectangle {
|
|||
anchors.right: parent.right;
|
||||
text: "Rez It"
|
||||
onClicked: {
|
||||
if (urlHandler.canHandleUrl(itemHref)) {
|
||||
urlHandler.handleUrl(itemHref);
|
||||
if (urlHandler.canHandleUrl(root.itemHref)) {
|
||||
urlHandler.handleUrl(root.itemHref);
|
||||
}
|
||||
rezzedNotifContainer.visible = true;
|
||||
rezzedNotifContainerTimer.start();
|
||||
|
@ -709,7 +714,9 @@ Rectangle {
|
|||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.bottom: root.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
|
||||
RalewayRegular {
|
||||
id: failureHeaderText;
|
||||
|
@ -718,57 +725,65 @@ Rectangle {
|
|||
size: 24;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 80;
|
||||
anchors.topMargin: 40;
|
||||
height: paintedHeight;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
// Style
|
||||
color: hifi.colors.black;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
id: failureErrorText;
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
Rectangle {
|
||||
id: failureErrorTextContainer;
|
||||
anchors.top: failureHeaderText.bottom;
|
||||
anchors.topMargin: 35;
|
||||
height: paintedHeight;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
// Style
|
||||
color: hifi.colors.black;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
height: failureErrorText.height + 30;
|
||||
radius: 4;
|
||||
border.width: 2;
|
||||
border.color: "#F3808F";
|
||||
color: "#FFC3CD";
|
||||
|
||||
AnonymousProRegular {
|
||||
id: failureErrorText;
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 15;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 8;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.black;
|
||||
wrapMode: Text.Wrap;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: backToMarketplaceButtonContainer;
|
||||
// Size
|
||||
width: root.width;
|
||||
height: 130;
|
||||
height: 50;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 8;
|
||||
anchors.bottomMargin: 16;
|
||||
// "Back to Marketplace" button
|
||||
HifiControlsUit.Button {
|
||||
id: backToMarketplaceButton;
|
||||
color: hifi.buttons.black;
|
||||
color: hifi.buttons.noneBorderlessGray;
|
||||
colorScheme: hifi.colorSchemes.light;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
width: parent.width/2 - anchors.rightMargin*2;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
width: parent.width/2 - anchors.leftMargin*2;
|
||||
text: "Back to Marketplace";
|
||||
onClicked: {
|
||||
sendToScript({method: 'checkout_continueShopping', itemId: itemId});
|
||||
|
@ -814,15 +829,9 @@ Rectangle {
|
|||
switch (message.method) {
|
||||
case 'updateCheckoutQML':
|
||||
itemId = message.params.itemId;
|
||||
itemNameText.text = message.params.itemName;
|
||||
itemName = message.params.itemName;
|
||||
root.itemPrice = message.params.itemPrice;
|
||||
itemPriceText.text = root.itemPrice === 0 ? "Free" : root.itemPrice;
|
||||
itemHref = message.params.itemHref;
|
||||
itemPreviewImageUrl = "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/previews/" + itemId + "/thumbnail/hifi-mp-" + itemId + ".jpg";
|
||||
if (itemHref.indexOf('.json') === -1) {
|
||||
root.itemIsJson = false;
|
||||
}
|
||||
root.canRezCertifiedItems = message.canRezCertifiedItems;
|
||||
setBuyText();
|
||||
break;
|
||||
default:
|
||||
|
@ -845,10 +854,10 @@ Rectangle {
|
|||
if (root.purchasesReceived && root.balanceReceived) {
|
||||
if (root.balanceAfterPurchase < 0) {
|
||||
if (root.alreadyOwned) {
|
||||
buyText.text = "Your Wallet does not have sufficient funds to purchase this item again.<br>" +
|
||||
'<font color="' + hifi.colors.blueAccent + '"><a href="#">View the copy you own in My Purchases</a></font>';
|
||||
buyText.text = "<b>Your Wallet does not have sufficient funds to purchase this item again.<br>" +
|
||||
'<font color="' + hifi.colors.blueAccent + '"><a href="#">View the copy you own in My Purchases</a></font></b>';
|
||||
} else {
|
||||
buyText.text = "Your Wallet does not have sufficient funds to purchase this item.";
|
||||
buyText.text = "<b>Your Wallet does not have sufficient funds to purchase this item.</b>";
|
||||
}
|
||||
buyTextContainer.color = "#FFC3CD";
|
||||
buyTextContainer.border.color = "#F3808F";
|
||||
|
@ -856,8 +865,8 @@ Rectangle {
|
|||
buyGlyph.size = 54;
|
||||
} else {
|
||||
if (root.alreadyOwned) {
|
||||
buyText.text = 'You already own this item.<br>Purchasing it will buy another copy.<br><font color="'
|
||||
+ hifi.colors.blueAccent + '"><a href="#">View this item in My Purchases</a></font>';
|
||||
buyText.text = '<b>You already own this item.<br>Purchasing it will buy another copy.<br><font color="'
|
||||
+ hifi.colors.blueAccent + '"><a href="#">View this item in My Purchases</a></font></b>';
|
||||
buyTextContainer.color = "#FFD6AD";
|
||||
buyTextContainer.border.color = "#FAC07D";
|
||||
buyGlyph.text = hifi.glyphs.alert;
|
||||
|
@ -870,7 +879,7 @@ Rectangle {
|
|||
buyText.text = "";
|
||||
}
|
||||
} else {
|
||||
buyText.text = "This Marketplace item isn't an entity. It <b>will not</b> be added to your <b>Purchases</b>.";
|
||||
buyText.text = "This free item <b>will not</b> be added to your <b>Purchases</b>. Non-entities can't yet be purchased for HFC.";
|
||||
buyTextContainer.color = "#FFD6AD";
|
||||
buyTextContainer.border.color = "#FAC07D";
|
||||
buyGlyph.text = hifi.glyphs.alert;
|
||||
|
@ -884,12 +893,10 @@ Rectangle {
|
|||
} else {
|
||||
root.activeView = "checkoutSuccess";
|
||||
}
|
||||
if (!balanceReceived) {
|
||||
commerce.balance();
|
||||
}
|
||||
if (!purchasesReceived) {
|
||||
commerce.inventory();
|
||||
}
|
||||
root.balanceReceived = false;
|
||||
root.purchasesReceived = false;
|
||||
commerce.inventory();
|
||||
commerce.balance();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -82,6 +82,7 @@ Rectangle {
|
|||
height: 140;
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
mipmap: true;
|
||||
cache: false;
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
|
|
|
@ -27,23 +27,28 @@ Item {
|
|||
id: root;
|
||||
property string referrerURL: "https://metaverse.highfidelity.com/marketplace?";
|
||||
readonly property int additionalDropdownHeight: usernameDropdown.height - myUsernameButton.anchors.bottomMargin;
|
||||
property alias usernameDropdownVisible: usernameDropdown.visible;
|
||||
|
||||
height: mainContainer.height + additionalDropdownHeight;
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onLoginStatusResult: {
|
||||
if (!isLoggedIn) {
|
||||
onWalletStatusResult: {
|
||||
if (walletStatus === 0) {
|
||||
sendToParent({method: "needsLogIn"});
|
||||
} else if (walletStatus === 3) {
|
||||
commerce.getSecurityImage();
|
||||
} else if (walletStatus > 3) {
|
||||
console.log("ERROR in EmulatedMarketplaceHeader.qml: Unknown wallet status: " + walletStatus);
|
||||
}
|
||||
}
|
||||
|
||||
onAccountResult: {
|
||||
if (result.status === "success") {
|
||||
commerce.getKeyFilePathIfExists();
|
||||
onLoginStatusResult: {
|
||||
if (!isLoggedIn) {
|
||||
sendToParent({method: "needsLogIn"});
|
||||
} else {
|
||||
// unsure how to handle a failure here. We definitely cannot proceed.
|
||||
commerce.getWalletStatus();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,8 +61,7 @@ Item {
|
|||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
commerce.getLoginStatus();
|
||||
commerce.getSecurityImage();
|
||||
commerce.getWalletStatus();
|
||||
}
|
||||
|
||||
Connections {
|
||||
|
@ -210,6 +214,7 @@ Item {
|
|||
anchors.bottomMargin: 16;
|
||||
width: height;
|
||||
mipmap: true;
|
||||
cache: false;
|
||||
|
||||
MouseArea {
|
||||
enabled: securityImage.visible;
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
//
|
||||
// SortableListModel.qml
|
||||
// qml/hifi/commerce/common
|
||||
//
|
||||
// SortableListModel
|
||||
//
|
||||
// Created by Zach Fox on 2017-09-28
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import QtQuick 2.5
|
||||
|
||||
ListModel {
|
||||
id: root;
|
||||
property string sortColumnName: "";
|
||||
property bool isSortingDescending: true;
|
||||
|
||||
function swap(a, b) {
|
||||
if (a < b) {
|
||||
move(a, b, 1);
|
||||
move (b - 1, a, 1);
|
||||
} else if (a > b) {
|
||||
move(b, a, 1);
|
||||
move(a - 1, b, 1);
|
||||
}
|
||||
}
|
||||
|
||||
function partition(begin, end, pivot) {
|
||||
var piv = get(pivot)[sortColumnName];
|
||||
swap(pivot, end - 1);
|
||||
var store = begin;
|
||||
|
||||
for (var i = begin; i < end - 1; ++i) {
|
||||
if (isSortingDescending) {
|
||||
if (get(i)[sortColumnName] < piv) {
|
||||
swap(store, i);
|
||||
++store;
|
||||
}
|
||||
} else {
|
||||
if (get(i)[sortColumnName] > piv) {
|
||||
swap(store, i);
|
||||
++store;
|
||||
}
|
||||
}
|
||||
}
|
||||
swap(end - 1, store);
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
function qsort(begin, end) {
|
||||
if (end - 1 > begin) {
|
||||
var pivot = begin + Math.floor(Math.random() * (end - begin));
|
||||
|
||||
pivot = partition(begin, end, pivot);
|
||||
|
||||
qsort(begin, pivot);
|
||||
qsort(pivot + 1, end);
|
||||
}
|
||||
}
|
||||
|
||||
function quickSort() {
|
||||
qsort(0, count)
|
||||
}
|
||||
}
|
|
@ -25,17 +25,76 @@ Rectangle {
|
|||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property string marketplaceId: "";
|
||||
property string marketplaceUrl;
|
||||
property string certificateId;
|
||||
property string itemName: "--";
|
||||
property string itemOwner: "--";
|
||||
property string itemEdition: "--";
|
||||
property string dateOfPurchase: "";
|
||||
property bool closeGoesToPurchases: false;
|
||||
property string dateOfPurchase: "--";
|
||||
property bool isLightbox: false;
|
||||
property bool isMyCert: false;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
}
|
||||
|
||||
onCertificateInfoResult: {
|
||||
if (result.status !== 'success') {
|
||||
console.log("Failed to get certificate info", result.message);
|
||||
} else {
|
||||
root.marketplaceUrl = result.data.marketplace_item_url;
|
||||
root.isMyCert = result.isMyCert ? result.isMyCert : false;
|
||||
root.itemOwner = root.isMyCert ? Account.username :
|
||||
"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
|
||||
root.itemEdition = result.data.edition_number + "/" + (result.data.limited_run === -1 ? "\u221e" : result.data.limited_run);
|
||||
root.dateOfPurchase = getFormattedDate(result.data.transfer_created_at * 1000);
|
||||
root.itemName = result.data.marketplace_item_name;
|
||||
|
||||
if (result.data.invalid_reason || result.data.transfer_status[0] === "failed") {
|
||||
titleBarText.text = "Invalid Certificate";
|
||||
titleBarText.color = hifi.colors.redHighlight;
|
||||
popText.text = "";
|
||||
if (result.data.invalid_reason) {
|
||||
errorText.text = result.data.invalid_reason;
|
||||
}
|
||||
} else if (result.data.transfer_status[0] === "pending") {
|
||||
titleBarText.text = "Certificate Pending";
|
||||
errorText.text = "The status of this item is still pending confirmation. If the purchase is not confirmed, " +
|
||||
"this entity will be cleaned up by the domain.";
|
||||
errorText.color = hifi.colors.baseGray;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onCertificateIdChanged: {
|
||||
if (certificateId !== "") {
|
||||
commerce.certificateInfo(certificateId);
|
||||
}
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (!visible) {
|
||||
titleBarText.text = "Certificate";
|
||||
popText.text = "PROOF OF PURCHASE";
|
||||
root.certificateId = "";
|
||||
root.itemName = "--";
|
||||
root.itemOwner = "--";
|
||||
root.itemEdition = "--";
|
||||
root.dateOfPurchase = "--";
|
||||
root.marketplaceUrl = "";
|
||||
root.isMyCert = false;
|
||||
errorText.text = "";
|
||||
}
|
||||
}
|
||||
|
||||
// This object is always used in a popup.
|
||||
// This MouseArea is used to prevent a user from being
|
||||
// able to click on a button/mouseArea underneath the popup.
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
propagateComposedEvents: false;
|
||||
}
|
||||
|
||||
Image {
|
||||
anchors.fill: parent;
|
||||
|
@ -107,7 +166,7 @@ Rectangle {
|
|||
size: 28;
|
||||
// Anchors
|
||||
anchors.top: itemNameHeader.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.topMargin: 8;
|
||||
anchors.left: itemNameHeader.left;
|
||||
anchors.right: itemNameHeader.right;
|
||||
height: paintedHeight;
|
||||
|
@ -118,7 +177,7 @@ Rectangle {
|
|||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
sendToScript({method: 'inspectionCertificate_showInMarketplaceClicked', itemId: root.marketplaceId});
|
||||
sendToScript({method: 'inspectionCertificate_showInMarketplaceClicked', marketplaceUrl: root.marketplaceUrl});
|
||||
}
|
||||
onEntered: itemName.color = hifi.colors.blueHighlight;
|
||||
onExited: itemName.color = hifi.colors.blueAccent;
|
||||
|
@ -132,14 +191,20 @@ Rectangle {
|
|||
size: 16;
|
||||
// Anchors
|
||||
anchors.top: itemName.bottom;
|
||||
anchors.topMargin: 20;
|
||||
anchors.topMargin: 28;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 45;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
color: hifi.colors.lightGray;
|
||||
}
|
||||
FontLoader { id: ralewayRegular; source: "../../../../fonts/Raleway-Regular.ttf"; }
|
||||
TextMetrics {
|
||||
id: textMetrics;
|
||||
font.family: ralewayRegular.name
|
||||
text: root.itemOwner;
|
||||
}
|
||||
RalewayRegular {
|
||||
id: ownedBy;
|
||||
|
@ -148,14 +213,31 @@ Rectangle {
|
|||
size: 22;
|
||||
// Anchors
|
||||
anchors.top: ownedByHeader.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.topMargin: 8;
|
||||
anchors.left: ownedByHeader.left;
|
||||
anchors.right: ownedByHeader.right;
|
||||
height: paintedHeight;
|
||||
height: textMetrics.height;
|
||||
width: root.isMyCert ? textMetrics.width + 25 : ownedByHeader.width;
|
||||
// Style
|
||||
color: hifi.colors.darkGray;
|
||||
elide: Text.ElideRight;
|
||||
}
|
||||
AnonymousProRegular {
|
||||
id: isMyCertText;
|
||||
visible: root.isMyCert;
|
||||
text: "(Private)";
|
||||
size: 18;
|
||||
// Anchors
|
||||
anchors.top: ownedBy.top;
|
||||
anchors.topMargin: 4;
|
||||
anchors.bottom: ownedBy.bottom;
|
||||
anchors.left: ownedBy.right;
|
||||
anchors.leftMargin: 4;
|
||||
anchors.right: ownedByHeader.right;
|
||||
// Style
|
||||
color: hifi.colors.lightGray;
|
||||
elide: Text.ElideRight;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
id: editionHeader;
|
||||
|
@ -164,23 +246,23 @@ Rectangle {
|
|||
size: 16;
|
||||
// Anchors
|
||||
anchors.top: ownedBy.bottom;
|
||||
anchors.topMargin: 20;
|
||||
anchors.topMargin: 28;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 45;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
color: hifi.colors.lightGray;
|
||||
}
|
||||
AnonymousProRegular {
|
||||
id: edition;
|
||||
text: root.itemEdition;
|
||||
// Text size
|
||||
size: 22;
|
||||
size: 18;
|
||||
// Anchors
|
||||
anchors.top: editionHeader.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.topMargin: 8;
|
||||
anchors.left: editionHeader.left;
|
||||
anchors.right: editionHeader.right;
|
||||
height: paintedHeight;
|
||||
|
@ -191,31 +273,29 @@ Rectangle {
|
|||
RalewayRegular {
|
||||
id: dateOfPurchaseHeader;
|
||||
text: "DATE OF PURCHASE";
|
||||
visible: root.dateOfPurchase !== "";
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.top: ownedBy.bottom;
|
||||
anchors.topMargin: 20;
|
||||
anchors.top: edition.bottom;
|
||||
anchors.topMargin: 28;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 45;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
color: hifi.colors.lightGray;
|
||||
}
|
||||
AnonymousProRegular {
|
||||
id: dateOfPurchase;
|
||||
text: root.dateOfPurchase;
|
||||
visible: root.dateOfPurchase !== "";
|
||||
// Text size
|
||||
size: 22;
|
||||
size: 18;
|
||||
// Anchors
|
||||
anchors.top: editionHeader.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: editionHeader.left;
|
||||
anchors.right: editionHeader.right;
|
||||
anchors.top: dateOfPurchaseHeader.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.left: dateOfPurchaseHeader.left;
|
||||
anchors.right: dateOfPurchaseHeader.right;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.darkGray;
|
||||
|
@ -223,15 +303,13 @@ Rectangle {
|
|||
|
||||
RalewayRegular {
|
||||
id: errorText;
|
||||
text: "Here we will display some text if there's an <b>error</b> with the certificate " +
|
||||
"(DMCA takedown, invalid cert, location of item updated)";
|
||||
// Text size
|
||||
size: 20;
|
||||
// Anchors
|
||||
anchors.top: root.dateOfPurchase !== "" ? dateOfPurchase.bottom : edition.bottom;
|
||||
anchors.topMargin: 40;
|
||||
anchors.left: root.dateOfPurchase !== "" ? dateOfPurchase.left : edition.left;
|
||||
anchors.right: root.dateOfPurchase !== "" ? dateOfPurchase.right : edition.right;
|
||||
anchors.top: dateOfPurchase.bottom;
|
||||
anchors.topMargin: 36;
|
||||
anchors.left: dateOfPurchase.left;
|
||||
anchors.right: dateOfPurchase.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
// Style
|
||||
wrapMode: Text.WordWrap;
|
||||
|
@ -246,7 +324,7 @@ Rectangle {
|
|||
Item {
|
||||
id: buttonsContainer;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 50;
|
||||
anchors.bottomMargin: 30;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: 50;
|
||||
|
@ -262,13 +340,18 @@ Rectangle {
|
|||
height: 50;
|
||||
text: "close";
|
||||
onClicked: {
|
||||
sendToScript({method: 'inspectionCertificate_closeClicked', closeGoesToPurchases: root.closeGoesToPurchases});
|
||||
if (root.isLightbox) {
|
||||
root.visible = false;
|
||||
} else {
|
||||
sendToScript({method: 'inspectionCertificate_closeClicked', closeGoesToPurchases: root.closeGoesToPurchases});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// "Show In Marketplace" button
|
||||
HifiControlsUit.Button {
|
||||
id: showInMarketplaceButton;
|
||||
enabled: root.marketplaceUrl;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.light;
|
||||
anchors.top: parent.top;
|
||||
|
@ -278,7 +361,7 @@ Rectangle {
|
|||
height: 50;
|
||||
text: "View In Market"
|
||||
onClicked: {
|
||||
sendToScript({method: 'inspectionCertificate_showInMarketplaceClicked', itemId: root.marketplaceId});
|
||||
sendToScript({method: 'inspectionCertificate_showInMarketplaceClicked', marketplaceUrl: root.marketplaceUrl});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -301,20 +384,42 @@ Rectangle {
|
|||
//
|
||||
function fromScript(message) {
|
||||
switch (message.method) {
|
||||
case 'inspectionCertificate_setMarketplaceId':
|
||||
root.marketplaceId = message.marketplaceId;
|
||||
root.closeGoesToPurchases = message.closeGoesToPurchases;
|
||||
break;
|
||||
case 'inspectionCertificate_setItemInfo':
|
||||
root.itemName = message.itemName;
|
||||
root.itemOwner = message.itemOwner;
|
||||
root.itemEdition = message.itemEdition;
|
||||
case 'inspectionCertificate_setCertificateId':
|
||||
root.certificateId = message.certificateId;
|
||||
break;
|
||||
default:
|
||||
console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
|
||||
}
|
||||
}
|
||||
signal sendToScript(var message);
|
||||
|
||||
function getFormattedDate(timestamp) {
|
||||
function addLeadingZero(n) {
|
||||
return n < 10 ? '0' + n : '' + n;
|
||||
}
|
||||
|
||||
var a = new Date(timestamp);
|
||||
var year = a.getFullYear();
|
||||
var month = addLeadingZero(a.getMonth());
|
||||
var day = addLeadingZero(a.getDate());
|
||||
var hour = a.getHours();
|
||||
var drawnHour = hour;
|
||||
if (hour === 0) {
|
||||
drawnHour = 12;
|
||||
} else if (hour > 12) {
|
||||
drawnHour -= 12;
|
||||
}
|
||||
drawnHour = addLeadingZero(drawnHour);
|
||||
|
||||
var amOrPm = "AM";
|
||||
if (hour >= 12) {
|
||||
amOrPm = "PM";
|
||||
}
|
||||
|
||||
var min = addLeadingZero(a.getMinutes());
|
||||
var sec = addLeadingZero(a.getSeconds());
|
||||
return year + '-' + month + '-' + day + '<br>' + drawnHour + ':' + min + amOrPm;
|
||||
}
|
||||
//
|
||||
// FUNCTION DEFINITIONS END
|
||||
//
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
import Hifi 1.0 as Hifi
|
||||
import QtQuick 2.5
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick.Controls 1.4
|
||||
import "../../../styles-uit"
|
||||
import "../../../controls-uit" as HifiControlsUit
|
||||
|
@ -24,40 +25,133 @@ Rectangle {
|
|||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property string activeView: "step_1";
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
property int activeView: 1;
|
||||
|
||||
Image {
|
||||
anchors.fill: parent;
|
||||
source: "images/Purchase-First-Run-" + root.activeView + ".jpg";
|
||||
}
|
||||
|
||||
// This object is always used in a popup.
|
||||
// This MouseArea is used to prevent a user from being
|
||||
// able to click on a button/mouseArea underneath the popup.
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
propagateComposedEvents: false;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: header;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
height: childrenRect.height;
|
||||
|
||||
Image {
|
||||
id: marketplaceHeaderImage;
|
||||
source: "../common/images/marketplaceHeaderImage.png";
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 2;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 8;
|
||||
width: 140;
|
||||
height: 58;
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
visible: false;
|
||||
}
|
||||
ColorOverlay {
|
||||
anchors.fill: marketplaceHeaderImage;
|
||||
source: marketplaceHeaderImage;
|
||||
color: "#FFFFFF"
|
||||
}
|
||||
RalewayRegular {
|
||||
id: introText1;
|
||||
text: "INTRODUCTION TO";
|
||||
// Text size
|
||||
size: 15;
|
||||
// Anchors
|
||||
anchors.top: marketplaceHeaderImage.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 12;
|
||||
anchors.right: parent.right;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
}
|
||||
RalewayRegular {
|
||||
id: introText2;
|
||||
text: "My Purchases";
|
||||
// Text size
|
||||
size: 28;
|
||||
// Anchors
|
||||
anchors.top: introText1.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 12;
|
||||
anchors.right: parent.right;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// "STEP 1" START
|
||||
//
|
||||
Item {
|
||||
id: step_1;
|
||||
visible: root.activeView === "step_1";
|
||||
anchors.top: parent.top;
|
||||
visible: root.activeView === 1;
|
||||
anchors.top: header.bottom;
|
||||
anchors.topMargin: 100;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: tutorialActionButtonsContainer.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
||||
RalewayRegular {
|
||||
id: step1text;
|
||||
text: "<b>This is the first-time Purchases tutorial.</b><br><br>Here is some <b>bold text</b> " +
|
||||
"inside Step 1.";
|
||||
text: "The <b>'REZ IT'</b> button makes your purchase appear in front of you.";
|
||||
// Text size
|
||||
size: 24;
|
||||
size: 20;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
width: 180;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
wrapMode: Text.WordWrap;
|
||||
}
|
||||
|
||||
// "Next" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: step1text.bottom;
|
||||
anchors.topMargin: 16;
|
||||
anchors.left: parent.left;
|
||||
width: 150;
|
||||
height: 40;
|
||||
text: "Next";
|
||||
onClicked: {
|
||||
root.activeView++;
|
||||
}
|
||||
}
|
||||
|
||||
// "SKIP" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.noneBorderlessGray;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 32;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
width: 150;
|
||||
height: 40;
|
||||
text: "SKIP";
|
||||
onClicked: {
|
||||
sendSignalToParent({method: 'tutorial_finished'});
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
|
@ -69,127 +163,52 @@ Rectangle {
|
|||
//
|
||||
Item {
|
||||
id: step_2;
|
||||
visible: root.activeView === "step_2";
|
||||
anchors.top: parent.top;
|
||||
visible: root.activeView === 2;
|
||||
anchors.top: header.bottom;
|
||||
anchors.topMargin: 45;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: tutorialActionButtonsContainer.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
||||
RalewayRegular {
|
||||
id: step2text;
|
||||
text: "<b>STEP TWOOO!!!</b>";
|
||||
text: "If you rez an item twice, the first one will disappear.";
|
||||
// Text size
|
||||
size: 24;
|
||||
size: 20;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
width: 180;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.faintGray;
|
||||
color: hifi.colors.white;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
// "GOT IT" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: step2text.bottom;
|
||||
anchors.topMargin: 16;
|
||||
anchors.left: parent.left;
|
||||
width: 150;
|
||||
height: 40;
|
||||
text: "GOT IT";
|
||||
onClicked: {
|
||||
sendSignalToParent({method: 'tutorial_finished'});
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// "STEP 2" END
|
||||
//
|
||||
|
||||
Item {
|
||||
id: tutorialActionButtonsContainer;
|
||||
// Size
|
||||
width: root.width;
|
||||
height: 70;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 24;
|
||||
|
||||
// "Skip" or "Back" button
|
||||
HifiControlsUit.Button {
|
||||
id: skipOrBackButton;
|
||||
color: hifi.buttons.black;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: parent.width/2 - anchors.leftMargin*2;
|
||||
text: root.activeView === "step_1" ? "Skip" : "Back";
|
||||
onClicked: {
|
||||
if (root.activeView === "step_1") {
|
||||
sendSignalToParent({method: 'tutorial_skipClicked'});
|
||||
} else {
|
||||
root.activeView = "step_" + (parseInt(root.activeView.split("_")[1]) - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// "Next" or "Finish" button
|
||||
HifiControlsUit.Button {
|
||||
id: nextButton;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 3;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 3;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
width: parent.width/2 - anchors.rightMargin*2;
|
||||
text: root.activeView === "step_2" ? "Finish" : "Next";
|
||||
onClicked: {
|
||||
// If this is the final step...
|
||||
if (root.activeView === "step_2") {
|
||||
sendSignalToParent({method: 'tutorial_finished'});
|
||||
} else {
|
||||
root.activeView = "step_" + (parseInt(root.activeView.split("_")[1]) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
//
|
||||
// Function Name: fromScript()
|
||||
//
|
||||
// Relevant Variables:
|
||||
// None
|
||||
//
|
||||
// Arguments:
|
||||
// message: The message sent from the JavaScript, in this case the Marketplaces JavaScript.
|
||||
// Messages are in format "{method, params}", like json-rpc.
|
||||
//
|
||||
// Description:
|
||||
// Called when a message is received from a script.
|
||||
//
|
||||
function fromScript(message) {
|
||||
switch (message.method) {
|
||||
case 'updatePurchases':
|
||||
referrerURL = message.referrerURL;
|
||||
break;
|
||||
case 'purchases_getIsFirstUseResult':
|
||||
if (message.isFirstUseOfPurchases && root.activeView !== "firstUseTutorial") {
|
||||
root.activeView = "firstUseTutorial";
|
||||
} else if (!message.isFirstUseOfPurchases && root.activeView === "initialize") {
|
||||
root.activeView = "purchasesMain";
|
||||
commerce.inventory();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
|
||||
}
|
||||
}
|
||||
signal sendSignalToParent(var message);
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS END
|
||||
//
|
||||
|
|
|
@ -34,18 +34,25 @@ Item {
|
|||
property string itemId;
|
||||
property string itemPreviewImageUrl;
|
||||
property string itemHref;
|
||||
property int ownedItemCount;
|
||||
property string certificateId;
|
||||
property int displayedItemCount;
|
||||
property int itemEdition;
|
||||
property int numberSold;
|
||||
property int limitedRun;
|
||||
|
||||
property string originalStatusText;
|
||||
property string originalStatusColor;
|
||||
|
||||
height: 110;
|
||||
width: parent.width;
|
||||
|
||||
onPurchaseStatusChangedChanged: {
|
||||
if (root.purchaseStatusChanged === true && root.purchaseStatus === "confirmed") {
|
||||
root.originalStatusText = statusText.text;
|
||||
root.originalStatusColor = statusText.color;
|
||||
statusText.text = "CONFIRMED!";
|
||||
statusText.color = hifi.colors.blueAccent;
|
||||
confirmedTimer.start();
|
||||
root.purchaseStatusChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +60,9 @@ Item {
|
|||
id: confirmedTimer;
|
||||
interval: 3000;
|
||||
onTriggered: {
|
||||
root.purchaseStatus = "";
|
||||
statusText.text = root.originalStatusText;
|
||||
statusText.color = root.originalStatusColor;
|
||||
root.purchaseStatusChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,7 +169,7 @@ Item {
|
|||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
sendToPurchases({method: 'purchases_itemCertificateClicked', itemMarketplaceId: root.itemId});
|
||||
sendToPurchases({method: 'purchases_itemCertificateClicked', itemCertificateId: root.certificateId});
|
||||
}
|
||||
onEntered: {
|
||||
certificateIcon.color = hifi.colors.black;
|
||||
|
@ -174,9 +183,30 @@ Item {
|
|||
}
|
||||
|
||||
Item {
|
||||
id: statusContainer;
|
||||
id: editionContainer;
|
||||
visible: root.displayedItemCount > 1 && !statusContainer.visible;
|
||||
anchors.left: itemName.left;
|
||||
anchors.top: certificateContainer.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: buttonContainer.left;
|
||||
anchors.rightMargin: 2;
|
||||
|
||||
visible: root.purchaseStatus || root.ownedItemCount > 1;
|
||||
FiraSansRegular {
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
text: "#" + root.itemEdition;
|
||||
size: 15;
|
||||
color: "#cc6a6a6a";
|
||||
verticalAlignment: Text.AlignTop;
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: statusContainer;
|
||||
visible: root.purchaseStatus === "pending" || root.purchaseStatus === "invalidated" || root.purchaseStatusChanged;
|
||||
anchors.left: itemName.left;
|
||||
anchors.top: certificateContainer.bottom;
|
||||
anchors.topMargin: 8;
|
||||
|
@ -195,8 +225,8 @@ Item {
|
|||
"PENDING..."
|
||||
} else if (root.purchaseStatus === "invalidated") {
|
||||
"INVALIDATED"
|
||||
} else if (root.ownedItemCount > 1) {
|
||||
"<font color='#6a6a6a'>(#" + root.itemEdition + ")</font> <u>You own " + root.ownedItemCount + " others</u>"
|
||||
} else if (root.numberSold !== -1) {
|
||||
("Sales: " + root.numberSold + "/" + (root.limitedRun === -1 ? "\u221e" : root.limitedRun))
|
||||
} else {
|
||||
""
|
||||
}
|
||||
|
@ -207,8 +237,6 @@ Item {
|
|||
hifi.colors.blueAccent
|
||||
} else if (root.purchaseStatus === "invalidated") {
|
||||
hifi.colors.redAccent
|
||||
} else if (root.ownedItemCount > 1) {
|
||||
hifi.colors.blueAccent
|
||||
} else {
|
||||
hifi.colors.baseGray
|
||||
}
|
||||
|
@ -240,8 +268,6 @@ Item {
|
|||
hifi.colors.blueAccent
|
||||
} else if (root.purchaseStatus === "invalidated") {
|
||||
hifi.colors.redAccent
|
||||
} else if (root.ownedItemCount > 1) {
|
||||
hifi.colors.blueAccent
|
||||
} else {
|
||||
hifi.colors.baseGray
|
||||
}
|
||||
|
@ -257,8 +283,6 @@ Item {
|
|||
sendToPurchases({method: 'showPendingLightbox'});
|
||||
} else if (root.purchaseStatus === "invalidated") {
|
||||
sendToPurchases({method: 'showInvalidatedLightbox'});
|
||||
} else if (root.ownedItemCount > 1) {
|
||||
sendToPurchases({method: 'setFilterText', filterText: root.itemName});
|
||||
}
|
||||
}
|
||||
onEntered: {
|
||||
|
@ -268,9 +292,6 @@ Item {
|
|||
} else if (root.purchaseStatus === "invalidated") {
|
||||
statusText.color = hifi.colors.redAccent;
|
||||
statusIcon.color = hifi.colors.redAccent;
|
||||
} else if (root.ownedItemCount > 1) {
|
||||
statusText.color = hifi.colors.blueHighlight;
|
||||
statusIcon.color = hifi.colors.blueHighlight;
|
||||
}
|
||||
}
|
||||
onExited: {
|
||||
|
@ -280,9 +301,6 @@ Item {
|
|||
} else if (root.purchaseStatus === "invalidated") {
|
||||
statusText.color = hifi.colors.redHighlight;
|
||||
statusIcon.color = hifi.colors.redHighlight;
|
||||
} else if (root.ownedItemCount > 1) {
|
||||
statusText.color = hifi.colors.blueAccent;
|
||||
statusIcon.color = hifi.colors.blueAccent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import "../../../controls-uit" as HifiControlsUit
|
|||
import "../../../controls" as HifiControls
|
||||
import "../wallet" as HifiWallet
|
||||
import "../common" as HifiCommerceCommon
|
||||
import "../inspectionCertificate" as HifiInspectionCertificate
|
||||
|
||||
// references XXX from root context
|
||||
|
||||
|
@ -31,65 +32,63 @@ Rectangle {
|
|||
property bool securityImageResultReceived: false;
|
||||
property bool purchasesReceived: false;
|
||||
property bool punctuationMode: false;
|
||||
property bool canRezCertifiedItems: false;
|
||||
property bool canRezCertifiedItems: Entities.canRezCertified || Entities.canRezTmpCertified;
|
||||
property bool pendingInventoryReply: true;
|
||||
property bool isShowingMyItems: false;
|
||||
property bool isDebuggingFirstUseTutorial: false;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onWalletStatusResult: {
|
||||
if (walletStatus === 0) {
|
||||
if (root.activeView !== "needsLogIn") {
|
||||
root.activeView = "needsLogIn";
|
||||
}
|
||||
} else if (walletStatus === 1) {
|
||||
if (root.activeView !== "notSetUp") {
|
||||
root.activeView = "notSetUp";
|
||||
notSetUpTimer.start();
|
||||
}
|
||||
} else if (walletStatus === 2) {
|
||||
if (root.activeView !== "passphraseModal") {
|
||||
root.activeView = "passphraseModal";
|
||||
}
|
||||
} else if (walletStatus === 3) {
|
||||
if ((Settings.getValue("isFirstUseOfPurchases", true) || root.isDebuggingFirstUseTutorial) && root.activeView !== "firstUseTutorial") {
|
||||
root.activeView = "firstUseTutorial";
|
||||
} else if (!Settings.getValue("isFirstUseOfPurchases", true) && root.activeView === "initialize") {
|
||||
root.activeView = "purchasesMain";
|
||||
commerce.inventory();
|
||||
}
|
||||
} else {
|
||||
console.log("ERROR in Purchases.qml: Unknown wallet status: " + walletStatus);
|
||||
}
|
||||
}
|
||||
|
||||
onLoginStatusResult: {
|
||||
if (!isLoggedIn && root.activeView !== "needsLogIn") {
|
||||
root.activeView = "needsLogIn";
|
||||
} else if (isLoggedIn) {
|
||||
root.activeView = "initialize";
|
||||
commerce.account();
|
||||
}
|
||||
}
|
||||
|
||||
onAccountResult: {
|
||||
if (result.status === "success") {
|
||||
commerce.getKeyFilePathIfExists();
|
||||
} else {
|
||||
// unsure how to handle a failure here. We definitely cannot proceed.
|
||||
}
|
||||
}
|
||||
|
||||
onKeyFilePathIfExistsResult: {
|
||||
if (path === "" && root.activeView !== "notSetUp") {
|
||||
root.activeView = "notSetUp";
|
||||
notSetUpTimer.start();
|
||||
} else if (path !== "" && root.activeView === "initialize") {
|
||||
commerce.getSecurityImage();
|
||||
}
|
||||
}
|
||||
|
||||
onSecurityImageResult: {
|
||||
securityImageResultReceived = true;
|
||||
if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up"
|
||||
root.activeView = "notSetUp";
|
||||
notSetUpTimer.start();
|
||||
} else if (exists && root.activeView === "initialize") {
|
||||
commerce.getWalletAuthenticatedStatus();
|
||||
}
|
||||
}
|
||||
|
||||
onWalletAuthenticatedStatusResult: {
|
||||
if (!isAuthenticated && root.activeView !== "passphraseModal") {
|
||||
root.activeView = "passphraseModal";
|
||||
} else if (isAuthenticated) {
|
||||
sendToScript({method: 'purchases_getIsFirstUse'});
|
||||
commerce.getWalletStatus();
|
||||
}
|
||||
}
|
||||
|
||||
onInventoryResult: {
|
||||
purchasesReceived = true;
|
||||
|
||||
if (root.pendingInventoryReply) {
|
||||
inventoryTimer.start();
|
||||
}
|
||||
|
||||
if (result.status !== 'success') {
|
||||
console.log("Failed to get purchases", result.message);
|
||||
} else {
|
||||
var inventoryResult = processInventoryResult(result.data.assets);
|
||||
|
||||
purchasesModel.clear();
|
||||
purchasesModel.append(result.data.assets);
|
||||
purchasesModel.append(inventoryResult);
|
||||
|
||||
if (previousPurchasesModel.count !== 0) {
|
||||
checkIfAnyItemStatusChanged();
|
||||
|
@ -100,13 +99,9 @@ Rectangle {
|
|||
purchasesModel.setProperty(i, "statusChanged", false);
|
||||
}
|
||||
}
|
||||
previousPurchasesModel.append(result.data.assets);
|
||||
previousPurchasesModel.append(inventoryResult);
|
||||
|
||||
buildFilteredPurchasesModel();
|
||||
|
||||
if (root.pendingInventoryReply) {
|
||||
inventoryTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
root.pendingInventoryReply = false;
|
||||
|
@ -117,7 +112,20 @@ Rectangle {
|
|||
id: notSetUpTimer;
|
||||
interval: 200;
|
||||
onTriggered: {
|
||||
sendToScript({method: 'checkout_walletNotSetUp'});
|
||||
sendToScript({method: 'purchases_walletNotSetUp'});
|
||||
}
|
||||
}
|
||||
|
||||
HifiInspectionCertificate.InspectionCertificate {
|
||||
id: inspectionCertificate;
|
||||
z: 999;
|
||||
visible: false;
|
||||
anchors.fill: parent;
|
||||
|
||||
Connections {
|
||||
onSendToScript: {
|
||||
sendToScript(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,6 +173,13 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
enabled: titleBarContainer.usernameDropdownVisible;
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
titleBarContainer.usernameDropdownVisible = false;
|
||||
}
|
||||
}
|
||||
//
|
||||
// TITLE BAR END
|
||||
//
|
||||
|
@ -182,7 +197,7 @@ Rectangle {
|
|||
Component.onCompleted: {
|
||||
securityImageResultReceived = false;
|
||||
purchasesReceived = false;
|
||||
commerce.getLoginStatus();
|
||||
commerce.getWalletStatus();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,7 +233,7 @@ Rectangle {
|
|||
onSendSignalToParent: {
|
||||
if (msg.method === "authSuccess") {
|
||||
root.activeView = "initialize";
|
||||
sendToScript({method: 'purchases_getIsFirstUse'});
|
||||
commerce.getWalletStatus();
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
}
|
||||
|
@ -228,19 +243,16 @@ Rectangle {
|
|||
|
||||
FirstUseTutorial {
|
||||
id: firstUseTutorial;
|
||||
z: 999;
|
||||
visible: root.activeView === "firstUseTutorial";
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.topMargin: -titleBarContainer.additionalDropdownHeight;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.fill: parent;
|
||||
|
||||
Connections {
|
||||
onSendSignalToParent: {
|
||||
switch (message.method) {
|
||||
case 'tutorial_skipClicked':
|
||||
case 'tutorial_finished':
|
||||
sendToScript({method: 'purchases_setIsFirstUse'});
|
||||
Settings.setValue("isFirstUseOfPurchases", false);
|
||||
root.activeView = "purchasesMain";
|
||||
commerce.inventory();
|
||||
break;
|
||||
|
@ -278,7 +290,7 @@ Rectangle {
|
|||
anchors.topMargin: 4;
|
||||
|
||||
RalewayRegular {
|
||||
id: myPurchasesText;
|
||||
id: myText;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 10;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
@ -286,7 +298,7 @@ Rectangle {
|
|||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 4;
|
||||
width: paintedWidth;
|
||||
text: "My Purchases";
|
||||
text: isShowingMyItems ? "My Items" : "My Purchases";
|
||||
color: hifi.colors.baseGray;
|
||||
size: 28;
|
||||
}
|
||||
|
@ -296,7 +308,7 @@ Rectangle {
|
|||
colorScheme: hifi.colorSchemes.faintGray;
|
||||
hasClearButton: true;
|
||||
hasRoundedBorder: true;
|
||||
anchors.left: myPurchasesText.right;
|
||||
anchors.left: myText.right;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
@ -331,7 +343,7 @@ Rectangle {
|
|||
ListModel {
|
||||
id: previousPurchasesModel;
|
||||
}
|
||||
ListModel {
|
||||
HifiCommerceCommon.SortableListModel {
|
||||
id: filteredPurchasesModel;
|
||||
}
|
||||
|
||||
|
@ -400,7 +412,7 @@ Rectangle {
|
|||
|
||||
ListView {
|
||||
id: purchasesContentsList;
|
||||
visible: purchasesModel.count !== 0;
|
||||
visible: (root.isShowingMyItems && filteredPurchasesModel.count !== 0) || (!root.isShowingMyItems && filteredPurchasesModel.count !== 0);
|
||||
clip: true;
|
||||
model: filteredPurchasesModel;
|
||||
// Anchors
|
||||
|
@ -414,9 +426,14 @@ Rectangle {
|
|||
itemName: title;
|
||||
itemId: id;
|
||||
itemPreviewImageUrl: preview;
|
||||
itemHref: root_file_url;
|
||||
itemHref: download_url;
|
||||
certificateId: certificate_id;
|
||||
purchaseStatus: status;
|
||||
purchaseStatusChanged: statusChanged;
|
||||
itemEdition: model.edition_number;
|
||||
numberSold: model.number_sold;
|
||||
limitedRun: model.limited_run;
|
||||
displayedItemCount: model.displayedItemCount;
|
||||
anchors.topMargin: 12;
|
||||
anchors.bottomMargin: 12;
|
||||
|
||||
|
@ -425,6 +442,8 @@ Rectangle {
|
|||
if (msg.method === 'purchases_itemInfoClicked') {
|
||||
sendToScript({method: 'purchases_itemInfoClicked', itemId: itemId});
|
||||
} else if (msg.method === 'purchases_itemCertificateClicked') {
|
||||
inspectionCertificate.visible = true;
|
||||
inspectionCertificate.isLightbox = true;
|
||||
sendToScript(msg);
|
||||
} else if (msg.method === "showInvalidatedLightbox") {
|
||||
lightboxPopup.titleText = "Item Invalidated";
|
||||
|
@ -448,9 +467,55 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: noItemsAlertContainer;
|
||||
visible: !purchasesContentsList.visible && root.purchasesReceived && root.isShowingMyItems && filterBar.text === "";
|
||||
anchors.top: filterBarContainer.bottom;
|
||||
anchors.topMargin: 12;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: parent.width;
|
||||
|
||||
// Explanitory text
|
||||
RalewayRegular {
|
||||
id: noItemsYet;
|
||||
text: "<b>You haven't submitted anything to the Marketplace yet!</b><br><br>Submit an item to the Marketplace to add it to My Items.";
|
||||
// Text size
|
||||
size: 22;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 150;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 24;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 24;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.baseGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
}
|
||||
|
||||
// "Go To Marketplace" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: noItemsYet.bottom;
|
||||
anchors.topMargin: 20;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
width: parent.width * 2 / 3;
|
||||
height: 50;
|
||||
text: "Visit Marketplace";
|
||||
onClicked: {
|
||||
sendToScript({method: 'purchases_goToMarketplaceClicked'});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: noPurchasesAlertContainer;
|
||||
visible: !purchasesContentsList.visible && root.purchasesReceived;
|
||||
visible: !purchasesContentsList.visible && root.purchasesReceived && !root.isShowingMyItems && filterBar.text === "";
|
||||
anchors.top: filterBarContainer.bottom;
|
||||
anchors.topMargin: 12;
|
||||
anchors.left: parent.left;
|
||||
|
@ -478,7 +543,7 @@ Rectangle {
|
|||
horizontalAlignment: Text.AlignHCenter;
|
||||
}
|
||||
|
||||
// "Set Up" button
|
||||
// "Go To Marketplace" button
|
||||
HifiControlsUit.Button {
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
|
@ -530,17 +595,54 @@ Rectangle {
|
|||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
|
||||
function processInventoryResult(inventory) {
|
||||
for (var i = 0; i < inventory.length; i++) {
|
||||
if (inventory[i].status.length > 1) {
|
||||
console.log("WARNING: Inventory result index " + i + " has a status of length >1!")
|
||||
}
|
||||
inventory[i].status = inventory[i].status[0];
|
||||
inventory[i].categories = inventory[i].categories.join(';');
|
||||
}
|
||||
return inventory;
|
||||
}
|
||||
|
||||
function populateDisplayedItemCounts() {
|
||||
var itemCountDictionary = {};
|
||||
var currentItemId;
|
||||
for (var i = 0; i < filteredPurchasesModel.count; i++) {
|
||||
currentItemId = filteredPurchasesModel.get(i).id;
|
||||
if (itemCountDictionary[currentItemId] === undefined) {
|
||||
itemCountDictionary[currentItemId] = 1;
|
||||
} else {
|
||||
itemCountDictionary[currentItemId]++;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < filteredPurchasesModel.count; i++) {
|
||||
filteredPurchasesModel.setProperty(i, "displayedItemCount", itemCountDictionary[filteredPurchasesModel.get(i).id]);
|
||||
}
|
||||
}
|
||||
|
||||
function sortByDate() {
|
||||
filteredPurchasesModel.sortColumnName = "purchase_date";
|
||||
filteredPurchasesModel.isSortingDescending = false;
|
||||
filteredPurchasesModel.quickSort();
|
||||
}
|
||||
|
||||
function buildFilteredPurchasesModel() {
|
||||
filteredPurchasesModel.clear();
|
||||
for (var i = 0; i < purchasesModel.count; i++) {
|
||||
if (purchasesModel.get(i).title.toLowerCase().indexOf(filterBar.text.toLowerCase()) !== -1) {
|
||||
if (purchasesModel.get(i).status !== "confirmed") {
|
||||
if (purchasesModel.get(i).status !== "confirmed" && !root.isShowingMyItems) {
|
||||
filteredPurchasesModel.insert(0, purchasesModel.get(i));
|
||||
} else {
|
||||
} else if ((root.isShowingMyItems && purchasesModel.get(i).edition_number === -1) || !root.isShowingMyItems) {
|
||||
filteredPurchasesModel.append(purchasesModel.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
populateDisplayedItemCounts();
|
||||
sortByDate();
|
||||
}
|
||||
|
||||
function checkIfAnyItemStatusChanged() {
|
||||
|
@ -581,16 +683,13 @@ Rectangle {
|
|||
case 'updatePurchases':
|
||||
referrerURL = message.referrerURL;
|
||||
titleBarContainer.referrerURL = message.referrerURL;
|
||||
root.canRezCertifiedItems = message.canRezCertifiedItems;
|
||||
filterBar.text = message.filterText ? message.filterText : "";
|
||||
break;
|
||||
case 'purchases_getIsFirstUseResult':
|
||||
if (message.isFirstUseOfPurchases && root.activeView !== "firstUseTutorial") {
|
||||
root.activeView = "firstUseTutorial";
|
||||
} else if (!message.isFirstUseOfPurchases && root.activeView === "initialize") {
|
||||
root.activeView = "purchasesMain";
|
||||
commerce.inventory();
|
||||
}
|
||||
case 'inspectionCertificate_setCertificateId':
|
||||
inspectionCertificate.fromScript(message);
|
||||
break;
|
||||
case 'purchases_showMyItems':
|
||||
root.isShowingMyItems = true;
|
||||
break;
|
||||
default:
|
||||
console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 72 KiB |
Binary file not shown.
After Width: | Height: | Size: 81 KiB |
|
@ -30,12 +30,14 @@ Item {
|
|||
id: commerce;
|
||||
|
||||
onKeyFilePathIfExistsResult: {
|
||||
keyFilePath = path;
|
||||
root.keyFilePath = path;
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
commerce.getKeyFilePathIfExists();
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
commerce.getKeyFilePathIfExists();
|
||||
}
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
|
@ -103,7 +105,7 @@ Item {
|
|||
ListElement {
|
||||
isExpanded: false;
|
||||
question: "What is a 'Security Pic'?"
|
||||
answer: qsTr("Your Security Pic is an encrypted image that you selected during Wallet Setup. <b>It acts as an extra layer of Wallet security.</b><br><br>When you see your Security Pic, you know that your actions and data are securely making use of your private keys.<br><br><b>If you don't see your Security Pic on a page that is asking you for your Wallet passphrase, someone untrustworthy may be trying to gain access to your Wallet.</b><br><br>The Pic is stored on your hard drive inside the same file as your private keys.");
|
||||
answer: qsTr("Your Security Pic is an encrypted image that you selected during Wallet Setup. <b>It acts as an extra layer of Wallet security.</b><br><br>When you see your Security Pic, you know that your actions and data are securely making use of your private keys.<br><br><b>If you don't see your Security Pic on a page that is asking you for your Wallet passphrase, someone untrustworthy may be trying to gain access to your Wallet.</b><br><br>The encrypted Pic is stored on your hard drive inside the same file as your private keys.");
|
||||
}
|
||||
ListElement {
|
||||
isExpanded: false;
|
||||
|
|
|
@ -90,7 +90,7 @@ Item {
|
|||
} else {
|
||||
// Error submitting new passphrase
|
||||
resetSubmitButton();
|
||||
passphraseSelection.setErrorText("Backend error");
|
||||
passphraseSelection.setErrorText("Current passphrase incorrect - try again");
|
||||
}
|
||||
} else {
|
||||
sendSignalToWallet(msg);
|
||||
|
@ -137,9 +137,10 @@ Item {
|
|||
width: 150;
|
||||
text: "Submit";
|
||||
onClicked: {
|
||||
if (passphraseSelection.validateAndSubmitPassphrase()) {
|
||||
passphraseSubmitButton.text = "Submitting...";
|
||||
passphraseSubmitButton.enabled = false;
|
||||
passphraseSubmitButton.text = "Submitting...";
|
||||
passphraseSubmitButton.enabled = false;
|
||||
if (!passphraseSelection.validateAndSubmitPassphrase()) {
|
||||
resetSubmitButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,6 +129,7 @@ Item {
|
|||
width: height;
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
mipmap: true;
|
||||
cache: false;
|
||||
|
||||
MouseArea {
|
||||
enabled: titleBarSecurityImage.visible;
|
||||
|
@ -196,6 +197,8 @@ Item {
|
|||
height: 50;
|
||||
echoMode: TextInput.Password;
|
||||
placeholderText: "passphrase";
|
||||
activeFocusOnPress: true;
|
||||
activeFocusOnTab: true;
|
||||
|
||||
onFocusChanged: {
|
||||
root.keyboardRaised = focus;
|
||||
|
@ -205,8 +208,8 @@ Item {
|
|||
anchors.fill: parent;
|
||||
|
||||
onClicked: {
|
||||
parent.focus = true;
|
||||
root.keyboardRaised = true;
|
||||
mouse.accepted = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ Item {
|
|||
id: root;
|
||||
property bool isChangingPassphrase: false;
|
||||
property bool isShowingTip: false;
|
||||
property bool shouldImmediatelyFocus: true;
|
||||
|
||||
// This object is always used in a popup.
|
||||
// This MouseArea is used to prevent a user from being
|
||||
|
@ -42,8 +43,8 @@ Item {
|
|||
passphrasePageSecurityImage.source = "image://security/securityImage";
|
||||
}
|
||||
|
||||
onWalletAuthenticatedStatusResult: {
|
||||
sendMessageToLightbox({method: 'statusResult', status: isAuthenticated});
|
||||
onChangePassphraseStatusResult: {
|
||||
sendMessageToLightbox({method: 'statusResult', status: changeSuccess});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,10 +54,8 @@ Item {
|
|||
// TODO: Fix this unlikely bug
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
if (root.isChangingPassphrase) {
|
||||
currentPassphraseField.focus = true;
|
||||
} else {
|
||||
passphraseField.focus = true;
|
||||
if (root.shouldImmediatelyFocus) {
|
||||
focusFirstTextField();
|
||||
}
|
||||
sendMessageToLightbox({method: 'disableHmdPreview'});
|
||||
} else {
|
||||
|
@ -76,6 +75,8 @@ Item {
|
|||
height: 50;
|
||||
echoMode: TextInput.Password;
|
||||
placeholderText: "enter current passphrase";
|
||||
activeFocusOnPress: true;
|
||||
activeFocusOnTab: true;
|
||||
|
||||
onFocusChanged: {
|
||||
if (focus) {
|
||||
|
@ -87,9 +88,9 @@ Item {
|
|||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
parent.focus = true;
|
||||
onPressed: {
|
||||
sendSignalToWallet({method: 'walletSetup_raiseKeyboard'});
|
||||
mouse.accepted = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,6 +110,16 @@ Item {
|
|||
height: 50;
|
||||
echoMode: TextInput.Password;
|
||||
placeholderText: root.isShowingTip ? "" : "enter new passphrase";
|
||||
activeFocusOnPress: true;
|
||||
activeFocusOnTab: true;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
onPressed: {
|
||||
sendSignalToWallet({method: 'walletSetup_raiseKeyboard'});
|
||||
mouse.accepted = false;
|
||||
}
|
||||
}
|
||||
|
||||
onFocusChanged: {
|
||||
if (focus) {
|
||||
|
@ -118,18 +129,11 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
parent.focus = true;
|
||||
sendMessageToLightbox({method: 'walletSetup_raiseKeyboard'});
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
passphraseFieldAgain.focus = true;
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.TextField {
|
||||
id: passphraseFieldAgain;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
|
@ -140,6 +144,16 @@ Item {
|
|||
height: 50;
|
||||
echoMode: TextInput.Password;
|
||||
placeholderText: root.isShowingTip ? "" : "re-enter new passphrase";
|
||||
activeFocusOnPress: true;
|
||||
activeFocusOnTab: true;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
onPressed: {
|
||||
sendSignalToWallet({method: 'walletSetup_raiseKeyboard'});
|
||||
mouse.accepted = false;
|
||||
}
|
||||
}
|
||||
|
||||
onFocusChanged: {
|
||||
if (focus) {
|
||||
|
@ -149,14 +163,6 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
parent.focus = true;
|
||||
sendMessageToLightbox({method: 'walletSetup_raiseKeyboard'});
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
focus = false;
|
||||
}
|
||||
|
@ -304,7 +310,7 @@ Item {
|
|||
passphraseFieldAgain.error = false;
|
||||
currentPassphraseField.error = false;
|
||||
setErrorText("");
|
||||
commerce.setPassphrase(passphraseField.text);
|
||||
commerce.changePassphrase(currentPassphraseField.text, passphraseField.text);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -320,5 +326,13 @@ Item {
|
|||
setErrorText("");
|
||||
}
|
||||
|
||||
function focusFirstTextField() {
|
||||
if (root.isChangingPassphrase) {
|
||||
currentPassphraseField.focus = true;
|
||||
} else {
|
||||
passphraseField.focus = true;
|
||||
}
|
||||
}
|
||||
|
||||
signal sendMessageToLightbox(var msg);
|
||||
}
|
||||
|
|
|
@ -25,13 +25,13 @@ Item {
|
|||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property string keyFilePath: "";
|
||||
property string keyFilePath;
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onKeyFilePathIfExistsResult: {
|
||||
keyFilePath = path;
|
||||
root.keyFilePath = path;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -232,6 +232,12 @@ Item {
|
|||
anchors.rightMargin: 55;
|
||||
anchors.bottom: parent.bottom;
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
commerce.getKeyFilePathIfExists();
|
||||
}
|
||||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
id: yourPrivateKeysImage;
|
||||
text: hifi.glyphs.walletKey;
|
||||
|
@ -280,6 +286,34 @@ Item {
|
|||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: removeHmdContainer;
|
||||
z: 998;
|
||||
visible: false;
|
||||
color: hifi.colors.blueHighlight;
|
||||
anchors.fill: backupInstructionsButton;
|
||||
radius: 5;
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
propagateComposedEvents: false;
|
||||
}
|
||||
|
||||
RalewayBold {
|
||||
anchors.fill: parent;
|
||||
text: "INSTRUCTIONS OPEN ON DESKTOP";
|
||||
size: 15;
|
||||
color: hifi.colors.white;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: removeHmdContainerTimer;
|
||||
interval: 5000;
|
||||
onTriggered: removeHmdContainer.visible = false
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Button {
|
||||
id: backupInstructionsButton;
|
||||
text: "View Backup Instructions";
|
||||
|
@ -292,7 +326,11 @@ Item {
|
|||
height: 40;
|
||||
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://www.highfidelity.com/");
|
||||
var keyPath = "file:///" + root.keyFilePath.substring(0, root.keyFilePath.lastIndexOf('/'));
|
||||
Qt.openUrlExternally(keyPath + "/backup_instructions.html");
|
||||
Qt.openUrlExternally(keyPath);
|
||||
removeHmdContainer.visible = true;
|
||||
removeHmdContainerTimer.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ Item {
|
|||
anchors.verticalCenter: parent.verticalCenter;
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
mipmap: true;
|
||||
cache: false;
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
|
|
|
@ -38,48 +38,41 @@ Rectangle {
|
|||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
||||
onWalletStatusResult: {
|
||||
if (walletStatus === 0) {
|
||||
if (root.activeView !== "needsLogIn") {
|
||||
root.activeView = "needsLogIn";
|
||||
}
|
||||
} else if (walletStatus === 1) {
|
||||
if (root.activeView !== "walletSetup") {
|
||||
root.activeView = "walletSetup";
|
||||
}
|
||||
} else if (walletStatus === 2) {
|
||||
if (root.activeView !== "passphraseModal") {
|
||||
root.activeView = "passphraseModal";
|
||||
}
|
||||
} else if (walletStatus === 3) {
|
||||
root.activeView = "walletHome";
|
||||
commerce.getSecurityImage();
|
||||
} else {
|
||||
console.log("ERROR in Wallet.qml: Unknown wallet status: " + walletStatus);
|
||||
}
|
||||
}
|
||||
|
||||
onLoginStatusResult: {
|
||||
if (!isLoggedIn && root.activeView !== "needsLogIn") {
|
||||
root.activeView = "needsLogIn";
|
||||
} else if (isLoggedIn) {
|
||||
root.activeView = "initialize";
|
||||
commerce.account();
|
||||
}
|
||||
}
|
||||
|
||||
onAccountResult: {
|
||||
if (result.status === "success") {
|
||||
commerce.getKeyFilePathIfExists();
|
||||
} else {
|
||||
// unsure how to handle a failure here. We definitely cannot proceed.
|
||||
}
|
||||
}
|
||||
|
||||
onKeyFilePathIfExistsResult: {
|
||||
if (path === "" && root.activeView !== "walletSetup") {
|
||||
root.activeView = "walletSetup";
|
||||
} else if (path !== "" && root.activeView === "initialize") {
|
||||
commerce.getSecurityImage();
|
||||
commerce.getWalletStatus();
|
||||
}
|
||||
}
|
||||
|
||||
onSecurityImageResult: {
|
||||
if (!exists && root.activeView !== "walletSetup") { // "If security image is not set up"
|
||||
root.activeView = "walletSetup";
|
||||
} else if (exists && root.activeView === "initialize") {
|
||||
commerce.getWalletAuthenticatedStatus();
|
||||
if (exists) {
|
||||
titleBarSecurityImage.source = "";
|
||||
titleBarSecurityImage.source = "image://security/securityImage";
|
||||
}
|
||||
}
|
||||
|
||||
onWalletAuthenticatedStatusResult: {
|
||||
if (!isAuthenticated && passphraseModal && root.activeView !== "passphraseModal") {
|
||||
root.activeView = "passphraseModal";
|
||||
} else if (isAuthenticated) {
|
||||
root.activeView = "walletHome";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SecurityImageModel {
|
||||
|
@ -149,6 +142,7 @@ Rectangle {
|
|||
anchors.bottomMargin: 6;
|
||||
width: height;
|
||||
mipmap: true;
|
||||
cache: false;
|
||||
|
||||
MouseArea {
|
||||
enabled: titleBarSecurityImage.visible;
|
||||
|
@ -179,9 +173,11 @@ Rectangle {
|
|||
if (msg.method === 'walletSetup_finished') {
|
||||
if (msg.referrer === '') {
|
||||
root.activeView = "initialize";
|
||||
commerce.getLoginStatus();
|
||||
commerce.getWalletStatus();
|
||||
} else if (msg.referrer === 'purchases') {
|
||||
sendToScript({method: 'goToPurchases'});
|
||||
} else {
|
||||
sendToScript({method: 'goToMarketplaceItemPage', itemId: msg.referrer});
|
||||
}
|
||||
} else if (msg.method === 'walletSetup_raiseKeyboard') {
|
||||
root.keyboardRaised = true;
|
||||
|
@ -254,7 +250,7 @@ Rectangle {
|
|||
color: hifi.colors.baseGray;
|
||||
|
||||
Component.onCompleted: {
|
||||
commerce.getLoginStatus();
|
||||
commerce.getWalletStatus();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,7 +285,7 @@ Rectangle {
|
|||
Connections {
|
||||
onSendSignalToParent: {
|
||||
if (msg.method === "authSuccess") {
|
||||
root.activeView = "walletHome";
|
||||
commerce.getWalletStatus();
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ Item {
|
|||
|
||||
id: root;
|
||||
property bool historyReceived: false;
|
||||
property int pendingCount: 0;
|
||||
|
||||
Hifi.QmlCommerce {
|
||||
id: commerce;
|
||||
|
@ -39,6 +40,8 @@ Item {
|
|||
if (result.status === 'success') {
|
||||
transactionHistoryModel.clear();
|
||||
transactionHistoryModel.append(result.data.history);
|
||||
|
||||
calculatePendingAndInvalidated();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,55 +203,74 @@ Item {
|
|||
model: transactionHistoryModel;
|
||||
delegate: Item {
|
||||
width: parent.width;
|
||||
height: transactionText.height + 30;
|
||||
height: (model.transaction_type === "pendingCount" && root.pendingCount !== 0) ? 40 : ((model.status === "confirmed" || model.status === "invalidated") ? transactionText.height + 30 : 0);
|
||||
|
||||
HifiControlsUit.Separator {
|
||||
visible: index === 0;
|
||||
colorScheme: 1;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.top: parent.top;
|
||||
}
|
||||
|
||||
AnonymousProRegular {
|
||||
id: dateText;
|
||||
text: getFormattedDate(model.created_at * 1000);
|
||||
// Style
|
||||
size: 18;
|
||||
Item {
|
||||
visible: model.transaction_type === "pendingCount" && root.pendingCount !== 0;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 15;
|
||||
width: 118;
|
||||
height: paintedHeight;
|
||||
color: hifi.colors.blueAccent;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignRight;
|
||||
}
|
||||
width: parent.width;
|
||||
height: visible ? parent.height : 0;
|
||||
|
||||
AnonymousProRegular {
|
||||
id: transactionText;
|
||||
text: model.text;
|
||||
size: 18;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 15;
|
||||
anchors.left: dateText.right;
|
||||
anchors.leftMargin: 20;
|
||||
anchors.right: parent.right;
|
||||
height: paintedHeight;
|
||||
color: hifi.colors.baseGrayHighlight;
|
||||
wrapMode: Text.WordWrap;
|
||||
|
||||
onLinkActivated: {
|
||||
sendSignalToWallet({method: 'transactionHistory_linkClicked', marketplaceLink: link});
|
||||
AnonymousProRegular {
|
||||
id: pendingCountText;
|
||||
anchors.fill: parent;
|
||||
text: root.pendingCount + ' Transaction' + (root.pendingCount > 1 ? 's' : '') + ' Pending';
|
||||
size: 18;
|
||||
color: hifi.colors.blueAccent;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Separator {
|
||||
colorScheme: 1;
|
||||
Item {
|
||||
visible: model.transaction_type !== "pendingCount" && (model.status === "confirmed" || model.status === "invalidated");
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: parent.width;
|
||||
height: visible ? parent.height : 0;
|
||||
|
||||
AnonymousProRegular {
|
||||
id: dateText;
|
||||
text: model.created_at ? getFormattedDate(model.created_at * 1000) : "";
|
||||
// Style
|
||||
size: 18;
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 15;
|
||||
width: 118;
|
||||
height: paintedHeight;
|
||||
color: hifi.colors.blueAccent;
|
||||
wrapMode: Text.WordWrap;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignRight;
|
||||
}
|
||||
|
||||
AnonymousProRegular {
|
||||
id: transactionText;
|
||||
text: model.text ? (model.status === "invalidated" ? ("INVALIDATED: " + model.text) : model.text) : "";
|
||||
size: 18;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 15;
|
||||
anchors.left: dateText.right;
|
||||
anchors.leftMargin: 20;
|
||||
anchors.right: parent.right;
|
||||
height: paintedHeight;
|
||||
color: model.status === "invalidated" ? hifi.colors.redAccent : hifi.colors.baseGrayHighlight;
|
||||
wrapMode: Text.WordWrap;
|
||||
font.strikeout: model.status === "invalidated";
|
||||
|
||||
onLinkActivated: {
|
||||
sendSignalToWallet({method: 'transactionHistory_linkClicked', marketplaceLink: link});
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Separator {
|
||||
colorScheme: 1;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
onAtYEndChanged: {
|
||||
|
@ -277,10 +299,14 @@ Item {
|
|||
//
|
||||
|
||||
function getFormattedDate(timestamp) {
|
||||
function addLeadingZero(n) {
|
||||
return n < 10 ? '0' + n : '' + n;
|
||||
}
|
||||
|
||||
var a = new Date(timestamp);
|
||||
var year = a.getFullYear();
|
||||
var month = a.getMonth();
|
||||
var day = a.getDate();
|
||||
var month = addLeadingZero(a.getMonth());
|
||||
var day = addLeadingZero(a.getDate());
|
||||
var hour = a.getHours();
|
||||
var drawnHour = hour;
|
||||
if (hour === 0) {
|
||||
|
@ -288,17 +314,31 @@ Item {
|
|||
} else if (hour > 12) {
|
||||
drawnHour -= 12;
|
||||
}
|
||||
drawnHour = addLeadingZero(drawnHour);
|
||||
|
||||
var amOrPm = "AM";
|
||||
if (hour >= 12) {
|
||||
amOrPm = "PM";
|
||||
}
|
||||
|
||||
var min = a.getMinutes();
|
||||
var sec = a.getSeconds();
|
||||
var min = addLeadingZero(a.getMinutes());
|
||||
var sec = addLeadingZero(a.getSeconds());
|
||||
return year + '-' + month + '-' + day + '<br>' + drawnHour + ':' + min + amOrPm;
|
||||
}
|
||||
|
||||
|
||||
function calculatePendingAndInvalidated(startingPendingCount) {
|
||||
var pendingCount = startingPendingCount ? startingPendingCount : 0;
|
||||
for (var i = 0; i < transactionHistoryModel.count; i++) {
|
||||
if (transactionHistoryModel.get(i).status === "pending") {
|
||||
pendingCount++;
|
||||
}
|
||||
}
|
||||
|
||||
root.pendingCount = pendingCount;
|
||||
transactionHistoryModel.insert(0, {"transaction_type": "pendingCount"});
|
||||
}
|
||||
|
||||
//
|
||||
// Function Name: fromScript()
|
||||
//
|
||||
|
|
|
@ -30,6 +30,7 @@ Item {
|
|||
property string lastPage;
|
||||
property bool hasShownSecurityImageTip: false;
|
||||
property string referrer;
|
||||
property string keyFilePath;
|
||||
|
||||
Image {
|
||||
anchors.fill: parent;
|
||||
|
@ -43,7 +44,7 @@ Item {
|
|||
if (!exists && root.lastPage === "step_2") {
|
||||
// ERROR! Invalid security image.
|
||||
root.activeView = "step_2";
|
||||
} else {
|
||||
} else if (exists) {
|
||||
titleBarSecurityImage.source = "";
|
||||
titleBarSecurityImage.source = "image://security/securityImage";
|
||||
}
|
||||
|
@ -58,7 +59,7 @@ Item {
|
|||
}
|
||||
|
||||
onKeyFilePathIfExistsResult: {
|
||||
keyFilePath.text = path;
|
||||
root.keyFilePath = path;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,7 +117,7 @@ Item {
|
|||
Image {
|
||||
id: titleBarSecurityImage;
|
||||
source: "";
|
||||
visible: !securityImageTip.visible && titleBarSecurityImage.source !== "";
|
||||
visible: !securityImageTip.visible && titleBarSecurityImage.source !== "" && root.activeView !== "step_1" && root.activeView !== "step_2";
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 6;
|
||||
anchors.top: parent.top;
|
||||
|
@ -125,6 +126,7 @@ Item {
|
|||
anchors.bottomMargin: 6;
|
||||
width: height;
|
||||
mipmap: true;
|
||||
cache: false;
|
||||
|
||||
MouseArea {
|
||||
enabled: titleBarSecurityImage.visible;
|
||||
|
@ -422,6 +424,7 @@ Item {
|
|||
onClicked: {
|
||||
root.hasShownSecurityImageTip = true;
|
||||
securityImageTip.visible = false;
|
||||
passphraseSelection.focusFirstTextField();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -466,6 +469,7 @@ Item {
|
|||
|
||||
PassphraseSelection {
|
||||
id: passphraseSelection;
|
||||
shouldImmediatelyFocus: root.hasShownSecurityImageTip;
|
||||
isShowingTip: securityImageTip.visible;
|
||||
anchors.top: passphraseTitleHelper.bottom;
|
||||
anchors.topMargin: 30;
|
||||
|
@ -605,7 +609,7 @@ Item {
|
|||
anchors.fill: parent;
|
||||
|
||||
RalewaySemiBold {
|
||||
id: keyFilePathText;
|
||||
id: keyFilePathHelperText;
|
||||
text: "Private Key File Location:";
|
||||
size: 18;
|
||||
anchors.top: parent.top;
|
||||
|
@ -624,7 +628,7 @@ Item {
|
|||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.top: keyFilePathText.bottom;
|
||||
anchors.top: keyFilePathHelperText.bottom;
|
||||
anchors.topMargin: 8;
|
||||
height: 24;
|
||||
width: height;
|
||||
|
@ -640,11 +644,12 @@ Item {
|
|||
}
|
||||
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("file:///" + keyFilePath.text.substring(0, keyFilePath.text.lastIndexOf('/')));
|
||||
Qt.openUrlExternally("file:///" + keyFilePath.substring(0, keyFilePath.lastIndexOf('/')));
|
||||
}
|
||||
}
|
||||
RalewayRegular {
|
||||
id: keyFilePath;
|
||||
id: keyFilePathText;
|
||||
text: root.keyFilePath;
|
||||
size: 18;
|
||||
anchors.top: clipboardButton.top;
|
||||
anchors.left: clipboardButton.right;
|
||||
|
@ -667,7 +672,7 @@ Item {
|
|||
id: openInstructionsButton;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: keyFilePath.bottom;
|
||||
anchors.top: keyFilePathText.bottom;
|
||||
anchors.topMargin: 30;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
|
@ -679,7 +684,9 @@ Item {
|
|||
instructions01Container.visible = false;
|
||||
instructions02Container.visible = true;
|
||||
keysReadyPageFinishButton.visible = true;
|
||||
Qt.openUrlExternally("https://www.highfidelity.com/");
|
||||
var keyPath = "file:///" + root.keyFilePath.substring(0, root.keyFilePath.lastIndexOf('/'));
|
||||
Qt.openUrlExternally(keyPath + "/backup_instructions.html");
|
||||
Qt.openUrlExternally(keyPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import Qt.labs.settings 1.0
|
|||
import "../../styles-uit"
|
||||
import "../../controls-uit" as HifiControls
|
||||
import "../../windows"
|
||||
import ".."
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
@ -57,6 +58,23 @@ Rectangle {
|
|||
Component.onDestruction: {
|
||||
assetMappingsModel.autoRefreshEnabled = false;
|
||||
}
|
||||
|
||||
function letterbox(headerGlyph, headerText, message) {
|
||||
letterboxMessage.headerGlyph = headerGlyph;
|
||||
letterboxMessage.headerText = headerText;
|
||||
letterboxMessage.text = message;
|
||||
letterboxMessage.visible = true;
|
||||
letterboxMessage.popupRadius = 0;
|
||||
}
|
||||
|
||||
function errorMessageBox(message) {
|
||||
return tabletRoot.messageBox({
|
||||
icon: hifi.icons.warning,
|
||||
defaultButton: OriginalDialogs.StandardButton.Ok,
|
||||
title: "Error",
|
||||
text: message
|
||||
});
|
||||
}
|
||||
|
||||
function doDeleteFile(path) {
|
||||
console.log("Deleting " + path);
|
||||
|
@ -154,10 +172,7 @@ Rectangle {
|
|||
}
|
||||
|
||||
function handleGetMappingsError(errorString) {
|
||||
errorMessageBox(
|
||||
"There was a problem retreiving the list of assets from your Asset Server.\n"
|
||||
+ errorString
|
||||
);
|
||||
errorMessageBox("There was a problem retrieving the list of assets from your Asset Server.\n" + errorString);
|
||||
}
|
||||
|
||||
function addToWorld() {
|
||||
|
@ -448,14 +463,11 @@ Rectangle {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
function errorMessageBox(message) {
|
||||
return tabletRoot.messageBox({
|
||||
icon: hifi.icons.warning,
|
||||
defaultButton: OriginalDialogs.StandardButton.Ok,
|
||||
title: "Error",
|
||||
text: message
|
||||
});
|
||||
|
||||
// The letterbox used for popup messages
|
||||
LetterboxMessage {
|
||||
id: letterboxMessage;
|
||||
z: 999; // Force the popup on top of everything else
|
||||
}
|
||||
|
||||
Column {
|
||||
|
@ -477,7 +489,7 @@ Rectangle {
|
|||
|
||||
HifiControls.Button {
|
||||
text: "Add To World"
|
||||
color: hifi.buttons.black
|
||||
color: hifi.buttons.blue
|
||||
colorScheme: root.colorScheme
|
||||
width: 120
|
||||
|
||||
|
@ -554,7 +566,7 @@ Rectangle {
|
|||
case "Not Baked":
|
||||
return hifi.glyphs.circleSlash;
|
||||
case "Baked":
|
||||
return hifi.glyphs.check_2_01;
|
||||
return hifi.glyphs.checkmark;
|
||||
case "Error":
|
||||
return hifi.glyphs.alert;
|
||||
default:
|
||||
|
@ -583,8 +595,24 @@ Rectangle {
|
|||
? (styleData.selected ? hifi.colors.black : hifi.colors.baseGrayHighlight)
|
||||
: (styleData.selected ? hifi.colors.black : hifi.colors.lightGrayText)
|
||||
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: styleData.column === 1 ? TextInput.AlignHCenter : TextInput.AlignLeft
|
||||
|
||||
elide: Text.ElideMiddle
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
|
||||
acceptedButtons: Qt.NoButton
|
||||
hoverEnabled: true
|
||||
|
||||
onEntered: {
|
||||
if (parent.truncated) {
|
||||
treeLabelToolTip.show(parent);
|
||||
}
|
||||
}
|
||||
onExited: treeLabelToolTip.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
Component {
|
||||
|
@ -667,6 +695,42 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: treeLabelToolTip
|
||||
visible: false
|
||||
z: 100 // Render on top
|
||||
|
||||
width: toolTipText.width + 2 * hifi.dimensions.textPadding
|
||||
height: hifi.dimensions.tableRowHeight
|
||||
color: colorScheme == hifi.colorSchemes.light ? hifi.colors.tableRowLightOdd : hifi.colors.tableRowDarkOdd
|
||||
border.color: colorScheme == hifi.colorSchemes.light ? hifi.colors.black : hifi.colors.lightGrayText
|
||||
|
||||
FiraSansSemiBold {
|
||||
id: toolTipText
|
||||
anchors.centerIn: parent
|
||||
|
||||
size: hifi.fontSizes.tableText
|
||||
color: colorScheme == hifi.colorSchemes.light ? hifi.colors.black : hifi.colors.lightGrayText
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: showTimer
|
||||
interval: 1000
|
||||
onTriggered: { treeLabelToolTip.visible = true; }
|
||||
}
|
||||
function show(item) {
|
||||
var coord = item.mapToItem(parent, item.x, item.y);
|
||||
|
||||
toolTipText.text = item.text;
|
||||
treeLabelToolTip.x = coord.x - hifi.dimensions.textPadding;
|
||||
treeLabelToolTip.y = coord.y;
|
||||
showTimer.start();
|
||||
}
|
||||
function hide() {
|
||||
showTimer.stop();
|
||||
treeLabelToolTip.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
propagateComposedEvents: true
|
||||
|
@ -716,25 +780,35 @@ Rectangle {
|
|||
anchors.left: treeView.left
|
||||
anchors.right: treeView.right
|
||||
anchors.bottomMargin: hifi.dimensions.contentSpacing.y
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
|
||||
RalewayRegular {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
function makeText() {
|
||||
var numPendingBakes = assetMappingsModel.numPendingBakes;
|
||||
if (selectedItems > 1 || numPendingBakes === 0) {
|
||||
return selectedItems + " items selected";
|
||||
} else {
|
||||
return numPendingBakes + " bakes pending"
|
||||
}
|
||||
}
|
||||
|
||||
size: hifi.fontSizes.sectionName
|
||||
font.capitalization: Font.AllUppercase
|
||||
text: selectedItems + " items selected"
|
||||
text: makeText()
|
||||
color: hifi.colors.lightGrayText
|
||||
}
|
||||
|
||||
HifiControls.CheckBox {
|
||||
function isChecked() {
|
||||
var status = assetProxyModel.data(treeView.selection.currentIndex, 0x105);
|
||||
var bakingDisabled = (status === "Not Baked" || status === "--");
|
||||
return selectedItems === 1 && !bakingDisabled;
|
||||
}
|
||||
HifiControls.HorizontalSpacer { }
|
||||
|
||||
text: "Use baked (optimized) versions"
|
||||
HifiControls.CheckBox {
|
||||
id: bakingCheckbox
|
||||
anchors.leftMargin: 2 * hifi.dimensions.contentSpacing.x
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: " Use baked version"
|
||||
colorScheme: root.colorScheme
|
||||
enabled: selectedItems === 1 && assetProxyModel.data(treeView.selection.currentIndex, 0x105) !== "--"
|
||||
enabled: isEnabled()
|
||||
checked: isChecked()
|
||||
onClicked: {
|
||||
var mappings = [];
|
||||
|
@ -750,7 +824,66 @@ Rectangle {
|
|||
|
||||
checked = Qt.binding(isChecked);
|
||||
}
|
||||
|
||||
function isEnabled() {
|
||||
if (!treeView.selection.hasSelection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var status = assetProxyModel.data(treeView.selection.currentIndex, 0x105);
|
||||
if (status === "--") {
|
||||
return false;
|
||||
}
|
||||
var bakingEnabled = status !== "Not Baked";
|
||||
|
||||
for (var i in treeView.selection.selectedIndexes) {
|
||||
var thisStatus = assetProxyModel.data(treeView.selection.selectedIndexes[i], 0x105);
|
||||
if (thisStatus === "--") {
|
||||
return false;
|
||||
}
|
||||
var thisBakingEnalbed = (thisStatus !== "Not Baked");
|
||||
|
||||
if (bakingEnabled !== thisBakingEnalbed) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
function isChecked() {
|
||||
if (!treeView.selection.hasSelection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var status = assetProxyModel.data(treeView.selection.currentIndex, 0x105);
|
||||
return isEnabled() && status !== "Not Baked";
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: infoGlyph.size;
|
||||
height: infoGlyph.size;
|
||||
|
||||
HiFiGlyphs {
|
||||
id: infoGlyph;
|
||||
anchors.fill: parent;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
text: hifi.glyphs.question;
|
||||
size: 35;
|
||||
color: hifi.colors.lightGrayText;
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: true;
|
||||
onEntered: infoGlyph.color = hifi.colors.blueHighlight;
|
||||
onExited: infoGlyph.color = hifi.colors.lightGrayText;
|
||||
onClicked: letterbox(hifi.glyphs.question,
|
||||
"What is baking?",
|
||||
"Baking compresses and optimizes files for faster network transfer and display. We recommend you bake your content to reduce initial load times for your visitors.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HifiControls.TabletContentSection {
|
||||
|
|
|
@ -85,7 +85,7 @@ Item {
|
|||
}
|
||||
|
||||
function urlHelper(src) {
|
||||
if (src.match(/\bhttp/)) {
|
||||
if (src.match(/\bhttp/) || src.match(/\bfile:/)) {
|
||||
return src;
|
||||
} else {
|
||||
return "../../../" + src;
|
||||
|
@ -171,7 +171,7 @@ Item {
|
|||
|
||||
PropertyChanges {
|
||||
target: text
|
||||
color: "#ffffff"
|
||||
color: captionColorOverride !== "" ? captionColorOverride: "#ffffff"
|
||||
text: tabletButton.hoverText
|
||||
}
|
||||
|
||||
|
@ -197,7 +197,7 @@ Item {
|
|||
|
||||
PropertyChanges {
|
||||
target: text
|
||||
color: "#333333"
|
||||
color: captionColorOverride !== "" ? captionColorOverride: "#333333"
|
||||
text: tabletButton.activeText
|
||||
}
|
||||
|
||||
|
@ -228,7 +228,7 @@ Item {
|
|||
|
||||
PropertyChanges {
|
||||
target: text
|
||||
color: "#333333"
|
||||
color: captionColorOverride !== "" ? captionColorOverride: "#333333"
|
||||
text: tabletButton.activeHoverText
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ StateImage {
|
|||
}
|
||||
|
||||
function urlHelper(src) {
|
||||
if (src.match(/\bhttp/)) {
|
||||
if (src.match(/\bhttp/) || src.match(/\bfile:/)) {
|
||||
return src;
|
||||
} else {
|
||||
return "../../../" + src;
|
||||
|
|
|
@ -26,6 +26,7 @@ Item {
|
|||
readonly property int frameMarginRight: frame.decoration ? frame.decoration.frameMarginRight : 0
|
||||
readonly property int frameMarginTop: frame.decoration ? frame.decoration.frameMarginTop : 0
|
||||
readonly property int frameMarginBottom: frame.decoration ? frame.decoration.frameMarginBottom : 0
|
||||
readonly property int offsetCorrection: 20
|
||||
|
||||
// Frames always fill their parents, but their decorations may extend
|
||||
// beyond the window via negative margin sizes
|
||||
|
@ -73,7 +74,7 @@ Item {
|
|||
Rectangle {
|
||||
id: sizeOutline
|
||||
x: -frameMarginLeft
|
||||
y: -frameMarginTop
|
||||
y: -frameMarginTop - offsetCorrection
|
||||
width: window ? window.width + frameMarginLeft + frameMarginRight + 2 : 0
|
||||
height: window ? window.height + frameMarginTop + frameMarginBottom + 2 : 0
|
||||
color: hifi.colors.baseGrayHighlight15
|
||||
|
|
|
@ -15,7 +15,7 @@ import "."
|
|||
Rectangle {
|
||||
id: modalWindow
|
||||
layer.enabled: true
|
||||
property var title: "Modal"
|
||||
property var title: "Open"
|
||||
width: tabletRoot.width
|
||||
height: tabletRoot.height
|
||||
color: "#80000000"
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2016/07/11
|
||||
// Copyright 2013-2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
uniform sampler2D sampler;
|
||||
|
||||
struct OverlayData {
|
||||
mat4 mvp;
|
||||
float alpha;
|
||||
};
|
||||
|
||||
layout(std140) uniform overlayBuffer {
|
||||
OverlayData overlay;
|
||||
};
|
||||
|
||||
in vec2 vTexCoord;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
FragColor = texture(sampler, vTexCoord);
|
||||
FragColor.a *= overlay.alpha;
|
||||
if (FragColor.a <= 0.0) {
|
||||
discard;
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2016/07/11
|
||||
// Copyright 2013-2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
struct OverlayData {
|
||||
mat4 mvp;
|
||||
float alpha;
|
||||
};
|
||||
|
||||
layout(std140) uniform overlayBuffer {
|
||||
OverlayData overlay;
|
||||
};
|
||||
|
||||
mat4 mvp = overlay.mvp;
|
||||
|
||||
layout(location = 0) in vec3 Position;
|
||||
layout(location = 3) in vec2 TexCoord;
|
||||
|
||||
out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = mvp * vec4(Position, 1);
|
||||
vTexCoord = TexCoord;
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -76,6 +76,7 @@
|
|||
#include <procedural/ProceduralSkybox.h>
|
||||
#include <model/Skybox.h>
|
||||
#include <ModelScriptingInterface.h>
|
||||
#include "FrameTimingsScriptingInterface.h"
|
||||
|
||||
#include "Sound.h"
|
||||
|
||||
|
@ -147,6 +148,8 @@ public:
|
|||
|
||||
void initializeGL();
|
||||
void initializeUi();
|
||||
|
||||
void updateCamera(RenderArgs& renderArgs);
|
||||
void paintGL();
|
||||
void resizeGL();
|
||||
|
||||
|
@ -157,7 +160,7 @@ public:
|
|||
QRect getRenderingGeometry() const;
|
||||
|
||||
glm::uvec2 getUiSize() const;
|
||||
QRect getRecommendedOverlayRect() const;
|
||||
QRect getRecommendedHUDRect() const;
|
||||
QSize getDeviceSize() const;
|
||||
bool hasFocus() const;
|
||||
|
||||
|
@ -173,7 +176,6 @@ public:
|
|||
// which might be different from the viewFrustum, i.e. shadowmap
|
||||
// passes, mirror window passes, etc
|
||||
void copyDisplayViewFrustum(ViewFrustum& viewOut) const;
|
||||
void copyShadowViewFrustum(ViewFrustum& viewOut) const override;
|
||||
const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; }
|
||||
QSharedPointer<EntityTreeRenderer> getEntities() const { return DependencyManager::get<EntityTreeRenderer>(); }
|
||||
QUndoStack* getUndoStack() { return &_undoStack; }
|
||||
|
@ -192,10 +194,9 @@ public:
|
|||
|
||||
Overlays& getOverlays() { return _overlays; }
|
||||
|
||||
|
||||
size_t getFrameCount() const { return _frameCount; }
|
||||
float getFps() const { return _frameCounter.rate(); }
|
||||
float getTargetFrameRate() const; // frames/second
|
||||
size_t getRenderFrameCount() const { return _renderFrameCount; }
|
||||
float getRenderLoopRate() const { return _renderLoopCounter.rate(); }
|
||||
float getTargetRenderFrameRate() const; // frames/second
|
||||
|
||||
float getFieldOfView() { return _fieldOfView.get(); }
|
||||
void setFieldOfView(float fov);
|
||||
|
@ -266,8 +267,7 @@ public:
|
|||
|
||||
void updateMyAvatarLookAtPosition();
|
||||
|
||||
float getAvatarSimrate() const { return _avatarSimCounter.rate(); }
|
||||
float getAverageSimsPerSecond() const { return _simCounter.rate(); }
|
||||
float getGameLoopRate() const { return _gameLoopCounter.rate(); }
|
||||
|
||||
void takeSnapshot(bool notify, bool includeAnimated = false, float aspectRatio = 0.0f);
|
||||
void takeSecondaryCameraSnapshot();
|
||||
|
@ -469,8 +469,6 @@ private:
|
|||
|
||||
void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions);
|
||||
|
||||
void renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool isZoomed);
|
||||
|
||||
int sendNackPackets();
|
||||
void sendAvatarViewFrustum();
|
||||
|
||||
|
@ -480,7 +478,7 @@ private:
|
|||
|
||||
void initializeAcceptedFiles();
|
||||
|
||||
void displaySide(RenderArgs* renderArgs, Camera& whichCamera, bool selfAvatarOnly = false);
|
||||
void runRenderFrame(RenderArgs* renderArgs/*, Camera& whichCamera, bool selfAvatarOnly = false*/);
|
||||
|
||||
bool importJSONFromURL(const QString& urlString);
|
||||
bool importSVOFromURL(const QString& urlString);
|
||||
|
@ -531,12 +529,13 @@ private:
|
|||
QUndoStack _undoStack;
|
||||
UndoStackScriptingInterface _undoStackScriptingInterface;
|
||||
|
||||
uint32_t _frameCount { 0 };
|
||||
uint32_t _renderFrameCount { 0 };
|
||||
|
||||
// Frame Rate Measurement
|
||||
RateCounter<> _frameCounter;
|
||||
RateCounter<> _avatarSimCounter;
|
||||
RateCounter<> _simCounter;
|
||||
RateCounter<500> _renderLoopCounter;
|
||||
RateCounter<500> _gameLoopCounter;
|
||||
|
||||
FrameTimingsScriptingInterface _frameTimingsScriptingInterface;
|
||||
|
||||
QTimer _minimizedWindowTimer;
|
||||
QElapsedTimer _timerStart;
|
||||
|
@ -553,7 +552,6 @@ private:
|
|||
ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc.
|
||||
ViewFrustum _lastQueriedViewFrustum; /// last view frustum used to query octree servers (voxels)
|
||||
ViewFrustum _displayViewFrustum;
|
||||
ViewFrustum _shadowViewFrustum;
|
||||
quint64 _lastQueriedTime;
|
||||
|
||||
OctreeQuery _octreeQuery; // NodeData derived class for querying octee cells from octree servers
|
||||
|
@ -624,6 +622,24 @@ private:
|
|||
render::EnginePointer _renderEngine{ new render::Engine() };
|
||||
gpu::ContextPointer _gpuContext; // initialized during window creation
|
||||
|
||||
mutable QMutex _renderArgsMutex{ QMutex::Recursive };
|
||||
struct AppRenderArgs {
|
||||
render::Args _renderArgs;
|
||||
glm::mat4 _eyeToWorld;
|
||||
glm::mat4 _eyeOffsets[2];
|
||||
glm::mat4 _eyeProjections[2];
|
||||
glm::mat4 _headPose;
|
||||
glm::mat4 _sensorToWorld;
|
||||
float _sensorToWorldScale { 1.0f };
|
||||
bool _isStereo{ false };
|
||||
};
|
||||
AppRenderArgs _appRenderArgs;
|
||||
|
||||
|
||||
using RenderArgsEditor = std::function <void (AppRenderArgs&)>;
|
||||
void editRenderArgs(RenderArgsEditor editor);
|
||||
|
||||
|
||||
Overlays _overlays;
|
||||
ApplicationOverlay _applicationOverlay;
|
||||
OverlayConductor _overlayConductor;
|
||||
|
@ -650,8 +666,6 @@ private:
|
|||
Qt::CursorShape _desiredCursor{ Qt::BlankCursor };
|
||||
bool _cursorNeedsChanging { false };
|
||||
|
||||
QThread* _deadlockWatchdogThread;
|
||||
|
||||
std::map<void*, std::function<void()>> _postUpdateLambdas;
|
||||
std::mutex _postUpdateLambdasLock;
|
||||
|
||||
|
|
230
interface/src/Application_render.cpp
Normal file
230
interface/src/Application_render.cpp
Normal file
|
@ -0,0 +1,230 @@
|
|||
//
|
||||
// Application_render.cpp
|
||||
// interface/src
|
||||
//
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "Application.h"
|
||||
#include <MainWindow.h>
|
||||
|
||||
#include <display-plugins/CompositorHelper.h>
|
||||
#include <FramebufferCache.h>
|
||||
#include "ui/Stats.h"
|
||||
#include <SceneScriptingInterface.h>
|
||||
#include "Util.h"
|
||||
|
||||
|
||||
// Statically provided display and input plugins
|
||||
extern DisplayPluginList getDisplayPlugins();
|
||||
|
||||
void Application::editRenderArgs(RenderArgsEditor editor) {
|
||||
QMutexLocker renderLocker(&_renderArgsMutex);
|
||||
editor(_appRenderArgs);
|
||||
|
||||
}
|
||||
|
||||
void Application::paintGL() {
|
||||
// Some plugins process message events, allowing paintGL to be called reentrantly.
|
||||
if (_aboutToQuit || _window->isMinimized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_renderFrameCount++;
|
||||
_lastTimeRendered.start();
|
||||
|
||||
auto lastPaintBegin = usecTimestampNow();
|
||||
PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_renderFrameCount);
|
||||
PerformanceTimer perfTimer("paintGL");
|
||||
|
||||
if (nullptr == _displayPlugin) {
|
||||
return;
|
||||
}
|
||||
|
||||
DisplayPluginPointer displayPlugin;
|
||||
{
|
||||
PROFILE_RANGE(render, "/getActiveDisplayPlugin");
|
||||
displayPlugin = getActiveDisplayPlugin();
|
||||
}
|
||||
|
||||
{
|
||||
PROFILE_RANGE(render, "/pluginBeginFrameRender");
|
||||
// If a display plugin loses it's underlying support, it
|
||||
// needs to be able to signal us to not use it
|
||||
if (!displayPlugin->beginFrameRender(_renderFrameCount)) {
|
||||
updateDisplayMode();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RenderArgs renderArgs;
|
||||
glm::mat4 HMDSensorPose;
|
||||
glm::mat4 eyeToWorld;
|
||||
glm::mat4 sensorToWorld;
|
||||
|
||||
bool isStereo;
|
||||
glm::mat4 stereoEyeOffsets[2];
|
||||
glm::mat4 stereoEyeProjections[2];
|
||||
|
||||
{
|
||||
QMutexLocker viewLocker(&_renderArgsMutex);
|
||||
renderArgs = _appRenderArgs._renderArgs;
|
||||
HMDSensorPose = _appRenderArgs._headPose;
|
||||
eyeToWorld = _appRenderArgs._eyeToWorld;
|
||||
sensorToWorld = _appRenderArgs._sensorToWorld;
|
||||
isStereo = _appRenderArgs._isStereo;
|
||||
for_each_eye([&](Eye eye) {
|
||||
stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye];
|
||||
stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye];
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
PROFILE_RANGE(render, "/gpuContextReset");
|
||||
_gpuContext->beginFrame(HMDSensorPose);
|
||||
// Reset the gpu::Context Stages
|
||||
// Back to the default framebuffer;
|
||||
gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) {
|
||||
batch.resetStages();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
PROFILE_RANGE(render, "/renderOverlay");
|
||||
PerformanceTimer perfTimer("renderOverlay");
|
||||
// NOTE: There is no batch associated with this renderArgs
|
||||
// the ApplicationOverlay class assumes it's viewport is setup to be the device size
|
||||
QSize size = getDeviceSize();
|
||||
renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height());
|
||||
_applicationOverlay.renderOverlay(&renderArgs);
|
||||
}
|
||||
|
||||
{
|
||||
PROFILE_RANGE(render, "/updateCompositor");
|
||||
getApplicationCompositor().setFrameInfo(_renderFrameCount, eyeToWorld, sensorToWorld);
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer finalFramebuffer;
|
||||
QSize finalFramebufferSize;
|
||||
{
|
||||
PROFILE_RANGE(render, "/getOutputFramebuffer");
|
||||
// Primary rendering pass
|
||||
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||
finalFramebufferSize = framebufferCache->getFrameBufferSize();
|
||||
// Final framebuffer that will be handled to the display-plugin
|
||||
finalFramebuffer = framebufferCache->getFramebuffer();
|
||||
}
|
||||
|
||||
{
|
||||
if (isStereo) {
|
||||
renderArgs._context->enableStereo(true);
|
||||
renderArgs._context->setStereoProjections(stereoEyeProjections);
|
||||
renderArgs._context->setStereoViews(stereoEyeOffsets);
|
||||
}
|
||||
|
||||
renderArgs._hudOperator = displayPlugin->getHUDOperator();
|
||||
renderArgs._hudTexture = _applicationOverlay.getOverlayTexture();
|
||||
renderArgs._blitFramebuffer = finalFramebuffer;
|
||||
runRenderFrame(&renderArgs);
|
||||
}
|
||||
|
||||
auto frame = _gpuContext->endFrame();
|
||||
frame->frameIndex = _renderFrameCount;
|
||||
frame->framebuffer = finalFramebuffer;
|
||||
frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer) {
|
||||
DependencyManager::get<FramebufferCache>()->releaseFramebuffer(framebuffer);
|
||||
};
|
||||
// deliver final scene rendering commands to the display plugin
|
||||
{
|
||||
PROFILE_RANGE(render, "/pluginOutput");
|
||||
PerformanceTimer perfTimer("pluginOutput");
|
||||
_renderLoopCounter.increment();
|
||||
displayPlugin->submitFrame(frame);
|
||||
}
|
||||
|
||||
// Reset the framebuffer and stereo state
|
||||
renderArgs._blitFramebuffer.reset();
|
||||
renderArgs._context->enableStereo(false);
|
||||
|
||||
{
|
||||
Stats::getInstance()->setRenderDetails(renderArgs._details);
|
||||
}
|
||||
|
||||
uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin;
|
||||
_frameTimingsScriptingInterface.addValue(lastPaintDuration);
|
||||
}
|
||||
|
||||
|
||||
// WorldBox Render Data & rendering functions
|
||||
|
||||
class WorldBoxRenderData {
|
||||
public:
|
||||
typedef render::Payload<WorldBoxRenderData> Payload;
|
||||
typedef Payload::DataPointer Pointer;
|
||||
|
||||
int _val = 0;
|
||||
static render::ItemID _item; // unique WorldBoxRenderData
|
||||
};
|
||||
|
||||
render::ItemID WorldBoxRenderData::_item{ render::Item::INVALID_ITEM_ID };
|
||||
|
||||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const WorldBoxRenderData::Pointer& stuff) { return ItemKey::Builder::opaqueShape(); }
|
||||
template <> const Item::Bound payloadGetBound(const WorldBoxRenderData::Pointer& stuff) { return Item::Bound(); }
|
||||
template <> void payloadRender(const WorldBoxRenderData::Pointer& stuff, RenderArgs* args) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::WorldAxes)) {
|
||||
PerformanceTimer perfTimer("worldBox");
|
||||
|
||||
auto& batch = *args->_batch;
|
||||
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch);
|
||||
renderWorldBox(args, batch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Application::runRenderFrame(RenderArgs* renderArgs) {
|
||||
PROFILE_RANGE(render, __FUNCTION__);
|
||||
PerformanceTimer perfTimer("display");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()");
|
||||
|
||||
// The pending changes collecting the changes here
|
||||
render::Transaction transaction;
|
||||
|
||||
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
|
||||
// render models...
|
||||
PerformanceTimer perfTimer("entities");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::runRenderFrame() ... entities...");
|
||||
|
||||
RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE;
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) {
|
||||
renderDebugFlags = static_cast<RenderArgs::DebugFlags>(renderDebugFlags |
|
||||
static_cast<int>(RenderArgs::RENDER_DEBUG_HULLS));
|
||||
}
|
||||
renderArgs->_debugFlags = renderDebugFlags;
|
||||
}
|
||||
|
||||
// Make sure the WorldBox is in the scene
|
||||
// For the record, this one RenderItem is the first one we created and added to the scene.
|
||||
// We could meoee that code elsewhere but you know...
|
||||
if (!render::Item::isValidID(WorldBoxRenderData::_item)) {
|
||||
auto worldBoxRenderData = std::make_shared<WorldBoxRenderData>();
|
||||
auto worldBoxRenderPayload = std::make_shared<WorldBoxRenderData::Payload>(worldBoxRenderData);
|
||||
|
||||
WorldBoxRenderData::_item = _main3DScene->allocateID();
|
||||
|
||||
transaction.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload);
|
||||
_main3DScene->enqueueTransaction(transaction);
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("EngineRun");
|
||||
_renderEngine->getRenderContext()->args = renderArgs;
|
||||
_renderEngine->run();
|
||||
}
|
||||
}
|
|
@ -78,7 +78,7 @@ void ATPAssetMigrator::loadEntityServerFile() {
|
|||
request->send();
|
||||
} else {
|
||||
++_errorCount;
|
||||
qWarning() << "Count not create request for asset at" << migrationURL.toString();
|
||||
qWarning() << "Could not create request for asset at" << migrationURL.toString();
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -252,11 +252,12 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
|||
qApp->getMain3DScene()->enqueueTransaction(transaction);
|
||||
}
|
||||
|
||||
_avatarSimulationTime = (float)(usecTimestampNow() - startTime) / (float)USECS_PER_MSEC;
|
||||
_numAvatarsUpdated = numAvatarsUpdated;
|
||||
_numAvatarsNotUpdated = numAVatarsNotUpdated;
|
||||
|
||||
simulateAvatarFades(deltaTime);
|
||||
|
||||
_avatarSimulationTime = (float)(usecTimestampNow() - startTime) / (float)USECS_PER_MSEC;
|
||||
}
|
||||
|
||||
void AvatarManager::postUpdate(float deltaTime, const render::ScenePointer& scene) {
|
||||
|
|
|
@ -73,9 +73,9 @@ public:
|
|||
Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersection(const PickRay& ray,
|
||||
const QScriptValue& avatarIdsToInclude = QScriptValue(),
|
||||
const QScriptValue& avatarIdsToDiscard = QScriptValue());
|
||||
RayToAvatarIntersectionResult findRayIntersectionVector(const PickRay& ray,
|
||||
const QVector<EntityItemID>& avatarsToInclude,
|
||||
const QVector<EntityItemID>& avatarsToDiscard);
|
||||
Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersectionVector(const PickRay& ray,
|
||||
const QVector<EntityItemID>& avatarsToInclude,
|
||||
const QVector<EntityItemID>& avatarsToDiscard);
|
||||
|
||||
// TODO: remove this HACK once we settle on optimal default sort coefficients
|
||||
Q_INVOKABLE float getAvatarSortCoefficient(const QString& name);
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <QJsonArray>
|
||||
#include <QTimeZone>
|
||||
#include <QJsonDocument>
|
||||
#include "AccountManager.h"
|
||||
#include "Wallet.h"
|
||||
#include "Ledger.h"
|
||||
#include "CommerceLogging.h"
|
||||
|
@ -48,13 +47,13 @@ Handler(receiveAt)
|
|||
Handler(balance)
|
||||
Handler(inventory)
|
||||
|
||||
void Ledger::send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, QJsonObject request) {
|
||||
void Ledger::send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, AccountManagerAuth::Type authType, QJsonObject request) {
|
||||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
const QString URL = "/api/v1/commerce/";
|
||||
JSONCallbackParameters callbackParams(this, success, this, fail);
|
||||
qCInfo(commerce) << "Sending" << endpoint << QJsonDocument(request).toJson(QJsonDocument::Compact);
|
||||
accountManager->sendRequest(URL + endpoint,
|
||||
AccountManagerAuth::Required,
|
||||
authType,
|
||||
method,
|
||||
callbackParams,
|
||||
QJsonDocument(request).toJson());
|
||||
|
@ -70,14 +69,14 @@ void Ledger::signedSend(const QString& propertyName, const QByteArray& text, con
|
|||
} else {
|
||||
request["signature"] = QString("controlled failure!");
|
||||
}
|
||||
send(endpoint, success, fail, QNetworkAccessManager::PutOperation, request);
|
||||
send(endpoint, success, fail, QNetworkAccessManager::PutOperation, AccountManagerAuth::Required, request);
|
||||
}
|
||||
|
||||
void Ledger::keysQuery(const QString& endpoint, const QString& success, const QString& fail) {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
QJsonObject request;
|
||||
request["public_keys"] = QJsonArray::fromStringList(wallet->listPublicKeys());
|
||||
send(endpoint, success, fail, QNetworkAccessManager::PostOperation, request);
|
||||
send(endpoint, success, fail, QNetworkAccessManager::PostOperation, AccountManagerAuth::Required, request);
|
||||
}
|
||||
|
||||
void Ledger::buy(const QString& hfc_key, int cost, const QString& asset_id, const QString& inventory_key, const bool controlled_failure) {
|
||||
|
@ -164,11 +163,7 @@ void Ledger::historySuccess(QNetworkReply& reply) {
|
|||
// turns out on my machine, toLocalTime convert to some weird timezone, yet the
|
||||
// systemTimeZone is correct. To avoid a strange bug with other's systems too, lets
|
||||
// be explicit
|
||||
#ifdef Q_OS_MAC
|
||||
QDateTime createdAt = QDateTime::fromTime_t(valueObject["created_at"].toInt(), Qt::UTC);
|
||||
#else
|
||||
QDateTime createdAt = QDateTime::fromSecsSinceEpoch(valueObject["created_at"].toInt(), Qt::UTC);
|
||||
#endif
|
||||
QDateTime localCreatedAt = createdAt.toTimeZone(QTimeZone::systemTimeZone());
|
||||
valueObject["text"] = QString("%1 sent %2 %3 with message \"%4\"").
|
||||
arg(from, to, coloredQuantityAndAssetTitle, valueObject["message"].toString());
|
||||
|
@ -196,7 +191,7 @@ void Ledger::history(const QStringList& keys) {
|
|||
void Ledger::resetSuccess(QNetworkReply& reply) { apiResponse("reset", reply); }
|
||||
void Ledger::resetFailure(QNetworkReply& reply) { failResponse("reset", reply); }
|
||||
void Ledger::reset() {
|
||||
send("reset_user_hfc_account", "resetSuccess", "resetFailure", QNetworkAccessManager::PutOperation, QJsonObject());
|
||||
send("reset_user_hfc_account", "resetSuccess", "resetFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::Required, QJsonObject());
|
||||
}
|
||||
|
||||
void Ledger::accountSuccess(QNetworkReply& reply) {
|
||||
|
@ -221,7 +216,7 @@ void Ledger::accountFailure(QNetworkReply& reply) {
|
|||
failResponse("account", reply);
|
||||
}
|
||||
void Ledger::account() {
|
||||
send("hfc_account", "accountSuccess", "accountFailure", QNetworkAccessManager::PutOperation, QJsonObject());
|
||||
send("hfc_account", "accountSuccess", "accountFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::Required, QJsonObject());
|
||||
}
|
||||
|
||||
// The api/failResponse is called just for the side effect of logging.
|
||||
|
@ -238,3 +233,28 @@ void Ledger::updateLocation(const QString& asset_id, const QString location, con
|
|||
auto transactionString = transactionDoc.toJson(QJsonDocument::Compact);
|
||||
signedSend("transaction", transactionString, key, "location", "updateLocationSuccess", "updateLocationFailure", controlledFailure);
|
||||
}
|
||||
|
||||
void Ledger::certificateInfoSuccess(QNetworkReply& reply) {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
|
||||
QByteArray response = reply.readAll();
|
||||
QJsonObject replyObject = QJsonDocument::fromJson(response).object();
|
||||
|
||||
QStringList keys = wallet->listPublicKeys();
|
||||
if (keys.count() != 0) {
|
||||
QJsonObject data = replyObject["data"].toObject();
|
||||
if (data["transfer_recipient_key"].toString() == keys[0]) {
|
||||
replyObject.insert("isMyCert", true);
|
||||
}
|
||||
}
|
||||
qInfo(commerce) << "certificateInfo" << "response" << QJsonDocument(replyObject).toJson(QJsonDocument::Compact);
|
||||
emit certificateInfoResult(replyObject);
|
||||
}
|
||||
void Ledger::certificateInfoFailure(QNetworkReply& reply) { failResponse("certificateInfo", reply); }
|
||||
void Ledger::certificateInfo(const QString& certificateId) {
|
||||
QString endpoint = "proof_of_purchase_status/transfer";
|
||||
QJsonObject request;
|
||||
request["certificate_id"] = certificateId;
|
||||
send(endpoint, "certificateInfoSuccess", "certificateInfoFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::None, request);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <QJsonObject>
|
||||
#include <DependencyManager.h>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include "AccountManager.h"
|
||||
|
||||
|
||||
class Ledger : public QObject, public Dependency {
|
||||
|
@ -32,6 +33,7 @@ public:
|
|||
void account();
|
||||
void reset();
|
||||
void updateLocation(const QString& asset_id, const QString location, const bool controlledFailure = false);
|
||||
void certificateInfo(const QString& certificateId);
|
||||
|
||||
signals:
|
||||
void buyResult(QJsonObject result);
|
||||
|
@ -41,6 +43,7 @@ signals:
|
|||
void historyResult(QJsonObject result);
|
||||
void accountResult(QJsonObject result);
|
||||
void locationUpdateResult(QJsonObject result);
|
||||
void certificateInfoResult(QJsonObject result);
|
||||
|
||||
public slots:
|
||||
void buySuccess(QNetworkReply& reply);
|
||||
|
@ -59,11 +62,13 @@ public slots:
|
|||
void accountFailure(QNetworkReply& reply);
|
||||
void updateLocationSuccess(QNetworkReply& reply);
|
||||
void updateLocationFailure(QNetworkReply& reply);
|
||||
void certificateInfoSuccess(QNetworkReply& reply);
|
||||
void certificateInfoFailure(QNetworkReply& reply);
|
||||
|
||||
private:
|
||||
QJsonObject apiResponse(const QString& label, QNetworkReply& reply);
|
||||
QJsonObject failResponse(const QString& label, QNetworkReply& reply);
|
||||
void send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, QJsonObject request);
|
||||
void send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, AccountManagerAuth::Type authType, QJsonObject request);
|
||||
void keysQuery(const QString& endpoint, const QString& success, const QString& fail);
|
||||
void signedSend(const QString& propertyName, const QByteArray& text, const QString& key, const QString& endpoint, const QString& success, const QString& fail, const bool controlled_failure = false);
|
||||
};
|
||||
|
|
|
@ -28,6 +28,13 @@ QmlCommerce::QmlCommerce(QQuickItem* parent) : OffscreenQmlDialog(parent) {
|
|||
connect(ledger.data(), &Ledger::historyResult, this, &QmlCommerce::historyResult);
|
||||
connect(wallet.data(), &Wallet::keyFilePathIfExistsResult, this, &QmlCommerce::keyFilePathIfExistsResult);
|
||||
connect(ledger.data(), &Ledger::accountResult, this, &QmlCommerce::accountResult);
|
||||
connect(wallet.data(), &Wallet::walletStatusResult, this, &QmlCommerce::walletStatusResult);
|
||||
connect(ledger.data(), &Ledger::certificateInfoResult, this, &QmlCommerce::certificateInfoResult);
|
||||
}
|
||||
|
||||
void QmlCommerce::getWalletStatus() {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
wallet->getWalletStatus();
|
||||
}
|
||||
|
||||
void QmlCommerce::getLoginStatus() {
|
||||
|
@ -36,7 +43,7 @@ void QmlCommerce::getLoginStatus() {
|
|||
|
||||
void QmlCommerce::getKeyFilePathIfExists() {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
wallet->sendKeyFilePathIfExists();
|
||||
emit keyFilePathIfExistsResult(wallet->getKeyFilePath());
|
||||
}
|
||||
|
||||
void QmlCommerce::getWalletAuthenticatedStatus() {
|
||||
|
@ -85,13 +92,20 @@ void QmlCommerce::history() {
|
|||
ledger->history(wallet->listPublicKeys());
|
||||
}
|
||||
|
||||
void QmlCommerce::changePassphrase(const QString& oldPassphrase, const QString& newPassphrase) {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
if (wallet->getPassphrase()->isEmpty()) {
|
||||
emit changePassphraseStatusResult(wallet->setPassphrase(newPassphrase));
|
||||
} else if (wallet->getPassphrase() == oldPassphrase && !newPassphrase.isEmpty()) {
|
||||
emit changePassphraseStatusResult(wallet->changePassphrase(newPassphrase));
|
||||
} else {
|
||||
emit changePassphraseStatusResult(false);
|
||||
}
|
||||
}
|
||||
|
||||
void QmlCommerce::setPassphrase(const QString& passphrase) {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
if(wallet->getPassphrase() && !wallet->getPassphrase()->isEmpty() && !passphrase.isEmpty()) {
|
||||
wallet->changePassphrase(passphrase);
|
||||
} else {
|
||||
wallet->setPassphrase(passphrase);
|
||||
}
|
||||
wallet->setPassphrase(passphrase);
|
||||
getWalletAuthenticatedStatus();
|
||||
}
|
||||
|
||||
|
@ -112,3 +126,8 @@ void QmlCommerce::account() {
|
|||
auto ledger = DependencyManager::get<Ledger>();
|
||||
ledger->account();
|
||||
}
|
||||
|
||||
void QmlCommerce::certificateInfo(const QString& certificateId) {
|
||||
auto ledger = DependencyManager::get<Ledger>();
|
||||
ledger->certificateInfo(certificateId);
|
||||
}
|
||||
|
|
|
@ -28,10 +28,13 @@ public:
|
|||
QmlCommerce(QQuickItem* parent = nullptr);
|
||||
|
||||
signals:
|
||||
void walletStatusResult(uint walletStatus);
|
||||
|
||||
void loginStatusResult(bool isLoggedIn);
|
||||
void keyFilePathIfExistsResult(const QString& path);
|
||||
void securityImageResult(bool exists);
|
||||
void walletAuthenticatedStatusResult(bool isAuthenticated);
|
||||
void changePassphraseStatusResult(bool changeSuccess);
|
||||
|
||||
void buyResult(QJsonObject result);
|
||||
// Balance and Inventory are NOT properties, because QML can't change them (without risk of failure), and
|
||||
|
@ -40,8 +43,11 @@ signals:
|
|||
void inventoryResult(QJsonObject result);
|
||||
void historyResult(QJsonObject result);
|
||||
void accountResult(QJsonObject result);
|
||||
void certificateInfoResult(QJsonObject result);
|
||||
|
||||
protected:
|
||||
Q_INVOKABLE void getWalletStatus();
|
||||
|
||||
Q_INVOKABLE void getLoginStatus();
|
||||
Q_INVOKABLE void getKeyFilePathIfExists();
|
||||
Q_INVOKABLE void getSecurityImage();
|
||||
|
@ -49,6 +55,7 @@ protected:
|
|||
|
||||
Q_INVOKABLE void chooseSecurityImage(const QString& imageFile);
|
||||
Q_INVOKABLE void setPassphrase(const QString& passphrase);
|
||||
Q_INVOKABLE void changePassphrase(const QString& oldPassphrase, const QString& newPassphrase);
|
||||
|
||||
Q_INVOKABLE void buy(const QString& assetId, int cost, const bool controlledFailure = false);
|
||||
Q_INVOKABLE void balance();
|
||||
|
@ -57,6 +64,8 @@ protected:
|
|||
Q_INVOKABLE void generateKeyPair();
|
||||
Q_INVOKABLE void reset();
|
||||
Q_INVOKABLE void account();
|
||||
|
||||
Q_INVOKABLE void certificateInfo(const QString& certificateId);
|
||||
};
|
||||
|
||||
#endif // hifi_QmlCommerce_h
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#endif
|
||||
|
||||
static const char* KEY_FILE = "hifikey";
|
||||
static const char* INSTRUCTIONS_FILE = "backup_instructions.html";
|
||||
static const char* IMAGE_HEADER = "-----BEGIN SECURITY IMAGE-----\n";
|
||||
static const char* IMAGE_FOOTER = "-----END SECURITY IMAGE-----\n";
|
||||
|
||||
|
@ -104,6 +105,38 @@ RSA* readKeys(const char* filename) {
|
|||
return key;
|
||||
}
|
||||
|
||||
bool writeBackupInstructions() {
|
||||
QString inputFilename(PathUtils::resourcesPath() + "html/commerce/backup_instructions.html");
|
||||
QString filename = PathUtils::getAppDataFilePath(INSTRUCTIONS_FILE);
|
||||
QFile outputFile(filename);
|
||||
bool retval = false;
|
||||
|
||||
if (QFile::exists(filename))
|
||||
{
|
||||
QFile::remove(filename);
|
||||
}
|
||||
QFile::copy(inputFilename, filename);
|
||||
|
||||
if (QFile::exists(filename) && outputFile.open(QIODevice::ReadWrite)) {
|
||||
|
||||
QByteArray fileData = outputFile.readAll();
|
||||
QString text(fileData);
|
||||
|
||||
text.replace(QString("HIFIKEY_PATH_REPLACEME"), keyFilePath());
|
||||
|
||||
outputFile.seek(0); // go to the beginning of the file
|
||||
outputFile.write(text.toUtf8()); // write the new text back to the file
|
||||
|
||||
outputFile.close(); // close the file handle.
|
||||
|
||||
retval = true;
|
||||
qCDebug(commerce) << "wrote html file successfully";
|
||||
} else {
|
||||
qCDebug(commerce) << "failed to open output html file" << filename;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool writeKeys(const char* filename, RSA* keys) {
|
||||
FILE* fp;
|
||||
bool retval = false;
|
||||
|
@ -121,6 +154,8 @@ bool writeKeys(const char* filename, RSA* keys) {
|
|||
QFile(QString(filename)).remove();
|
||||
return retval;
|
||||
}
|
||||
|
||||
writeBackupInstructions();
|
||||
|
||||
retval = true;
|
||||
qCDebug(commerce) << "wrote keys successfully";
|
||||
|
@ -282,9 +317,32 @@ void initializeAESKeys(unsigned char* ivec, unsigned char* ckey, const QByteArra
|
|||
|
||||
Wallet::Wallet() {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
auto ledger = DependencyManager::get<Ledger>();
|
||||
auto& packetReceiver = nodeList->getPacketReceiver();
|
||||
|
||||
packetReceiver.registerListener(PacketType::ChallengeOwnership, this, "verifyOwnerChallenge");
|
||||
packetReceiver.registerListener(PacketType::ChallengeOwnership, this, "handleChallengeOwnershipPacket");
|
||||
|
||||
connect(ledger.data(), &Ledger::accountResult, this, [&]() {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
auto walletScriptingInterface = DependencyManager::get<WalletScriptingInterface>();
|
||||
uint status;
|
||||
|
||||
if (wallet->getKeyFilePath() == "" || !wallet->getSecurityImage()) {
|
||||
status = (uint)WalletStatus::WALLET_STATUS_NOT_SET_UP;
|
||||
} else if (!wallet->walletIsAuthenticatedWithPassphrase()) {
|
||||
status = (uint)WalletStatus::WALLET_STATUS_NOT_AUTHENTICATED;
|
||||
} else {
|
||||
status = (uint)WalletStatus::WALLET_STATUS_READY;
|
||||
}
|
||||
|
||||
walletScriptingInterface->setWalletStatus(status);
|
||||
emit walletStatusResult(status);
|
||||
});
|
||||
|
||||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() {
|
||||
getWalletStatus();
|
||||
});
|
||||
}
|
||||
|
||||
Wallet::~Wallet() {
|
||||
|
@ -293,13 +351,15 @@ Wallet::~Wallet() {
|
|||
}
|
||||
}
|
||||
|
||||
void Wallet::setPassphrase(const QString& passphrase) {
|
||||
bool Wallet::setPassphrase(const QString& passphrase) {
|
||||
if (_passphrase) {
|
||||
delete _passphrase;
|
||||
}
|
||||
_passphrase = new QString(passphrase);
|
||||
|
||||
_publicKeys.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Wallet::writeSecurityImage(const QPixmap* pixmap, const QString& outputFilePath) {
|
||||
|
@ -468,7 +528,6 @@ bool Wallet::generateKeyPair() {
|
|||
|
||||
// TODO: redo this soon -- need error checking and so on
|
||||
writeSecurityImage(_securityImage, keyFilePath());
|
||||
sendKeyFilePathIfExists();
|
||||
QString oldKey = _publicKeys.count() == 0 ? "" : _publicKeys.last();
|
||||
QString key = keyPair.first->toBase64();
|
||||
_publicKeys.push_back(key);
|
||||
|
@ -559,14 +618,14 @@ void Wallet::chooseSecurityImage(const QString& filename) {
|
|||
emit securityImageResult(success);
|
||||
}
|
||||
|
||||
void Wallet::getSecurityImage() {
|
||||
bool Wallet::getSecurityImage() {
|
||||
unsigned char* data;
|
||||
int dataLen;
|
||||
|
||||
// if already decrypted, don't do it again
|
||||
if (_securityImage) {
|
||||
emit securityImageResult(true);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
|
@ -585,14 +644,15 @@ void Wallet::getSecurityImage() {
|
|||
success = true;
|
||||
}
|
||||
emit securityImageResult(success);
|
||||
return success;
|
||||
}
|
||||
void Wallet::sendKeyFilePathIfExists() {
|
||||
QString Wallet::getKeyFilePath() {
|
||||
QString filePath(keyFilePath());
|
||||
QFileInfo fileInfo(filePath);
|
||||
if (fileInfo.exists()) {
|
||||
emit keyFilePathIfExistsResult(filePath);
|
||||
return filePath;
|
||||
} else {
|
||||
emit keyFilePathIfExistsResult("");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -625,6 +685,7 @@ bool Wallet::writeWallet(const QString& newPassphrase) {
|
|||
QFile(QString(keyFilePath())).remove();
|
||||
QFile(tempFileName).rename(QString(keyFilePath()));
|
||||
qCDebug(commerce) << "wallet written successfully";
|
||||
emit keyFilePathIfExistsResult(getKeyFilePath());
|
||||
return true;
|
||||
} else {
|
||||
qCDebug(commerce) << "couldn't write security image to temp wallet";
|
||||
|
@ -679,3 +740,23 @@ bool Wallet::verifyOwnerChallenge(const QByteArray& encryptedText, const QString
|
|||
decryptedText = QString("hello");
|
||||
return true;
|
||||
}
|
||||
|
||||
void Wallet::account() {
|
||||
auto ledger = DependencyManager::get<Ledger>();
|
||||
ledger->account();
|
||||
}
|
||||
|
||||
void Wallet::getWalletStatus() {
|
||||
auto walletScriptingInterface = DependencyManager::get<WalletScriptingInterface>();
|
||||
uint status;
|
||||
|
||||
if (DependencyManager::get<AccountManager>()->isLoggedIn()) {
|
||||
// This will set account info for the wallet, allowing us to decrypt and display the security image.
|
||||
account();
|
||||
} else {
|
||||
status = (uint)WalletStatus::WALLET_STATUS_NOT_LOGGED_IN;
|
||||
emit walletStatusResult(status);
|
||||
walletScriptingInterface->setWalletStatus(status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <DependencyManager.h>
|
||||
#include <Node.h>
|
||||
#include <ReceivedMessage.h>
|
||||
#include "scripting/WalletScriptingInterface.h"
|
||||
|
||||
#include <QPixmap>
|
||||
|
||||
|
@ -32,8 +33,8 @@ public:
|
|||
QStringList listPublicKeys();
|
||||
QString signWithKey(const QByteArray& text, const QString& key);
|
||||
void chooseSecurityImage(const QString& imageFile);
|
||||
void getSecurityImage();
|
||||
void sendKeyFilePathIfExists();
|
||||
bool getSecurityImage();
|
||||
QString getKeyFilePath();
|
||||
|
||||
void setSalt(const QByteArray& salt) { _salt = salt; }
|
||||
QByteArray getSalt() { return _salt; }
|
||||
|
@ -42,7 +43,7 @@ public:
|
|||
void setCKey(const QByteArray& ckey) { _ckey = ckey; }
|
||||
QByteArray getCKey() { return _ckey; }
|
||||
|
||||
void setPassphrase(const QString& passphrase);
|
||||
bool setPassphrase(const QString& passphrase);
|
||||
QString* getPassphrase() { return _passphrase; }
|
||||
bool getPassphraseIsCached() { return !(_passphrase->isEmpty()); }
|
||||
bool walletIsAuthenticatedWithPassphrase();
|
||||
|
@ -50,10 +51,20 @@ public:
|
|||
|
||||
void reset();
|
||||
|
||||
void getWalletStatus();
|
||||
enum WalletStatus {
|
||||
WALLET_STATUS_NOT_LOGGED_IN = 0,
|
||||
WALLET_STATUS_NOT_SET_UP,
|
||||
WALLET_STATUS_NOT_AUTHENTICATED,
|
||||
WALLET_STATUS_READY
|
||||
};
|
||||
|
||||
signals:
|
||||
void securityImageResult(bool exists);
|
||||
void keyFilePathIfExistsResult(const QString& path);
|
||||
|
||||
void walletStatusResult(uint walletStatus);
|
||||
|
||||
private slots:
|
||||
void handleChallengeOwnershipPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode);
|
||||
|
||||
|
@ -71,6 +82,8 @@ private:
|
|||
bool readSecurityImage(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferLen);
|
||||
|
||||
bool verifyOwnerChallenge(const QByteArray& encryptedText, const QString& publicKey, QString& decryptedText);
|
||||
|
||||
void account();
|
||||
};
|
||||
|
||||
#endif // hifi_Wallet_h
|
||||
|
|
|
@ -49,6 +49,10 @@ int main(int argc, const char* argv[]) {
|
|||
CrashReporter crashReporter { BUG_SPLAT_DATABASE, BUG_SPLAT_APPLICATION_NAME, BuildInfo::VERSION };
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar);
|
||||
#endif
|
||||
|
||||
disableQtBearerPoll(); // Fixes wifi ping spikes
|
||||
|
||||
QElapsedTimer startupTime;
|
||||
|
|
|
@ -49,11 +49,13 @@ LaserPointer::~LaserPointer() {
|
|||
}
|
||||
|
||||
void LaserPointer::enable() {
|
||||
QWriteLocker lock(getLock());
|
||||
DependencyManager::get<RayPickScriptingInterface>()->enableRayPick(_rayPickUID);
|
||||
_renderingEnabled = true;
|
||||
}
|
||||
|
||||
void LaserPointer::disable() {
|
||||
QWriteLocker lock(getLock());
|
||||
DependencyManager::get<RayPickScriptingInterface>()->disableRayPick(_rayPickUID);
|
||||
_renderingEnabled = false;
|
||||
if (!_currentRenderState.empty()) {
|
||||
|
@ -67,6 +69,7 @@ void LaserPointer::disable() {
|
|||
}
|
||||
|
||||
void LaserPointer::setRenderState(const std::string& state) {
|
||||
QWriteLocker lock(getLock());
|
||||
if (!_currentRenderState.empty() && state != _currentRenderState) {
|
||||
if (_renderStates.find(_currentRenderState) != _renderStates.end()) {
|
||||
disableRenderState(_renderStates[_currentRenderState]);
|
||||
|
@ -79,6 +82,7 @@ void LaserPointer::setRenderState(const std::string& state) {
|
|||
}
|
||||
|
||||
void LaserPointer::editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
|
||||
QWriteLocker lock(getLock());
|
||||
updateRenderStateOverlay(_renderStates[state].getStartID(), startProps);
|
||||
updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps);
|
||||
updateRenderStateOverlay(_renderStates[state].getEndID(), endProps);
|
||||
|
@ -92,6 +96,11 @@ void LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant&
|
|||
}
|
||||
}
|
||||
|
||||
const RayPickResult LaserPointer::getPrevRayPickResult() {
|
||||
QReadLocker lock(getLock());
|
||||
return DependencyManager::get<RayPickScriptingInterface>()->getPrevRayPickResult(_rayPickUID);
|
||||
}
|
||||
|
||||
void LaserPointer::updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState) {
|
||||
if (!renderState.getStartID().isNull()) {
|
||||
QVariantMap startProps;
|
||||
|
@ -183,6 +192,8 @@ void LaserPointer::disableRenderState(const RenderState& renderState) {
|
|||
}
|
||||
|
||||
void LaserPointer::update() {
|
||||
// This only needs to be a read lock because update won't change any of the properties that can be modified from scripts
|
||||
QReadLocker lock(getLock());
|
||||
RayPickResult prevRayPickResult = DependencyManager::get<RayPickScriptingInterface>()->getPrevRayPickResult(_rayPickUID);
|
||||
if (_renderingEnabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() &&
|
||||
(prevRayPickResult.type != IntersectionType::NONE || _laserLength > 0.0f || !_objectLockEnd.first.isNull())) {
|
||||
|
@ -198,6 +209,51 @@ void LaserPointer::update() {
|
|||
}
|
||||
}
|
||||
|
||||
void LaserPointer::setPrecisionPicking(const bool precisionPicking) {
|
||||
QWriteLocker lock(getLock());
|
||||
DependencyManager::get<RayPickScriptingInterface>()->setPrecisionPicking(_rayPickUID, precisionPicking);
|
||||
}
|
||||
|
||||
void LaserPointer::setLaserLength(const float laserLength) {
|
||||
QWriteLocker lock(getLock());
|
||||
_laserLength = laserLength;
|
||||
}
|
||||
|
||||
void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay) {
|
||||
QWriteLocker lock(getLock());
|
||||
_objectLockEnd = std::pair<QUuid, bool>(objectID, isOverlay);
|
||||
}
|
||||
|
||||
void LaserPointer::setIgnoreEntities(const QScriptValue& ignoreEntities) {
|
||||
QWriteLocker lock(getLock());
|
||||
DependencyManager::get<RayPickScriptingInterface>()->setIgnoreEntities(_rayPickUID, ignoreEntities);
|
||||
}
|
||||
|
||||
void LaserPointer::setIncludeEntities(const QScriptValue& includeEntities) {
|
||||
QWriteLocker lock(getLock());
|
||||
DependencyManager::get<RayPickScriptingInterface>()->setIncludeEntities(_rayPickUID, includeEntities);
|
||||
}
|
||||
|
||||
void LaserPointer::setIgnoreOverlays(const QScriptValue& ignoreOverlays) {
|
||||
QWriteLocker lock(getLock());
|
||||
DependencyManager::get<RayPickScriptingInterface>()->setIgnoreOverlays(_rayPickUID, ignoreOverlays);
|
||||
}
|
||||
|
||||
void LaserPointer::setIncludeOverlays(const QScriptValue& includeOverlays) {
|
||||
QWriteLocker lock(getLock());
|
||||
DependencyManager::get<RayPickScriptingInterface>()->setIncludeOverlays(_rayPickUID, includeOverlays);
|
||||
}
|
||||
|
||||
void LaserPointer::setIgnoreAvatars(const QScriptValue& ignoreAvatars) {
|
||||
QWriteLocker lock(getLock());
|
||||
DependencyManager::get<RayPickScriptingInterface>()->setIgnoreAvatars(_rayPickUID, ignoreAvatars);
|
||||
}
|
||||
|
||||
void LaserPointer::setIncludeAvatars(const QScriptValue& includeAvatars) {
|
||||
QWriteLocker lock(getLock());
|
||||
DependencyManager::get<RayPickScriptingInterface>()->setIncludeAvatars(_rayPickUID, includeAvatars);
|
||||
}
|
||||
|
||||
RenderState::RenderState(const OverlayID& startID, const OverlayID& pathID, const OverlayID& endID) :
|
||||
_startID(startID), _pathID(pathID), _endID(endID)
|
||||
{
|
||||
|
|
|
@ -58,22 +58,24 @@ public:
|
|||
QUuid getRayUID() { return _rayPickUID; }
|
||||
void enable();
|
||||
void disable();
|
||||
const RayPickResult getPrevRayPickResult() { return DependencyManager::get<RayPickScriptingInterface>()->getPrevRayPickResult(_rayPickUID); }
|
||||
const RayPickResult getPrevRayPickResult();
|
||||
|
||||
void setRenderState(const std::string& state);
|
||||
// You cannot use editRenderState to change the overlay type of any part of the laser pointer. You can only edit the properties of the existing overlays.
|
||||
void editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps);
|
||||
|
||||
void setPrecisionPicking(const bool precisionPicking) { DependencyManager::get<RayPickScriptingInterface>()->setPrecisionPicking(_rayPickUID, precisionPicking); }
|
||||
void setLaserLength(const float laserLength) { _laserLength = laserLength; }
|
||||
void setIgnoreEntities(const QScriptValue& ignoreEntities) { DependencyManager::get<RayPickScriptingInterface>()->setIgnoreEntities(_rayPickUID, ignoreEntities); }
|
||||
void setIncludeEntities(const QScriptValue& includeEntities) { DependencyManager::get<RayPickScriptingInterface>()->setIncludeEntities(_rayPickUID, includeEntities); }
|
||||
void setIgnoreOverlays(const QScriptValue& ignoreOverlays) { DependencyManager::get<RayPickScriptingInterface>()->setIgnoreOverlays(_rayPickUID, ignoreOverlays); }
|
||||
void setIncludeOverlays(const QScriptValue& includeOverlays) { DependencyManager::get<RayPickScriptingInterface>()->setIncludeOverlays(_rayPickUID, includeOverlays); }
|
||||
void setIgnoreAvatars(const QScriptValue& ignoreAvatars) { DependencyManager::get<RayPickScriptingInterface>()->setIgnoreAvatars(_rayPickUID, ignoreAvatars); }
|
||||
void setIncludeAvatars(const QScriptValue& includeAvatars) { DependencyManager::get<RayPickScriptingInterface>()->setIncludeAvatars(_rayPickUID, includeAvatars); }
|
||||
void setPrecisionPicking(const bool precisionPicking);
|
||||
void setLaserLength(const float laserLength);
|
||||
void setLockEndUUID(QUuid objectID, const bool isOverlay);
|
||||
|
||||
void setLockEndUUID(QUuid objectID, const bool isOverlay) { _objectLockEnd = std::pair<QUuid, bool>(objectID, isOverlay); }
|
||||
void setIgnoreEntities(const QScriptValue& ignoreEntities);
|
||||
void setIncludeEntities(const QScriptValue& includeEntities);
|
||||
void setIgnoreOverlays(const QScriptValue& ignoreOverlays);
|
||||
void setIncludeOverlays(const QScriptValue& includeOverlays);
|
||||
void setIgnoreAvatars(const QScriptValue& ignoreAvatars);
|
||||
void setIncludeAvatars(const QScriptValue& includeAvatars);
|
||||
|
||||
QReadWriteLock* getLock() { return &_lock; }
|
||||
|
||||
void update();
|
||||
|
||||
|
@ -89,6 +91,7 @@ private:
|
|||
std::pair<QUuid, bool> _objectLockEnd { std::pair<QUuid, bool>(QUuid(), false)};
|
||||
|
||||
QUuid _rayPickUID;
|
||||
QReadWriteLock _lock;
|
||||
|
||||
void updateRenderStateOverlay(const OverlayID& id, const QVariant& props);
|
||||
void updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState);
|
||||
|
|
|
@ -17,7 +17,6 @@ QUuid LaserPointerManager::createLaserPointer(const QVariant& rayProps, const La
|
|||
QWriteLocker containsLock(&_containsLock);
|
||||
QUuid id = QUuid::createUuid();
|
||||
_laserPointers[id] = laserPointer;
|
||||
_laserPointerLocks[id] = std::make_shared<QReadWriteLock>();
|
||||
return id;
|
||||
}
|
||||
return QUuid();
|
||||
|
@ -26,46 +25,45 @@ QUuid LaserPointerManager::createLaserPointer(const QVariant& rayProps, const La
|
|||
void LaserPointerManager::removeLaserPointer(const QUuid uid) {
|
||||
QWriteLocker lock(&_containsLock);
|
||||
_laserPointers.remove(uid);
|
||||
_laserPointerLocks.remove(uid);
|
||||
}
|
||||
|
||||
void LaserPointerManager::enableLaserPointer(const QUuid uid) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
_laserPointers[uid]->enable();
|
||||
auto laserPointer = _laserPointers.find(uid);
|
||||
if (laserPointer != _laserPointers.end()) {
|
||||
laserPointer.value()->enable();
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::disableLaserPointer(const QUuid uid) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
_laserPointers[uid]->disable();
|
||||
auto laserPointer = _laserPointers.find(uid);
|
||||
if (laserPointer != _laserPointers.end()) {
|
||||
laserPointer.value()->disable();
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setRenderState(QUuid uid, const std::string& renderState) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
_laserPointers[uid]->setRenderState(renderState);
|
||||
auto laserPointer = _laserPointers.find(uid);
|
||||
if (laserPointer != _laserPointers.end()) {
|
||||
laserPointer.value()->setRenderState(renderState);
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::editRenderState(QUuid uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
_laserPointers[uid]->editRenderState(state, startProps, pathProps, endProps);
|
||||
auto laserPointer = _laserPointers.find(uid);
|
||||
if (laserPointer != _laserPointers.end()) {
|
||||
laserPointer.value()->editRenderState(state, startProps, pathProps, endProps);
|
||||
}
|
||||
}
|
||||
|
||||
const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QReadLocker laserLock(_laserPointerLocks[uid].get());
|
||||
return _laserPointers[uid]->getPrevRayPickResult();
|
||||
auto laserPointer = _laserPointers.find(uid);
|
||||
if (laserPointer != _laserPointers.end()) {
|
||||
return laserPointer.value()->getPrevRayPickResult();
|
||||
}
|
||||
return RayPickResult();
|
||||
}
|
||||
|
@ -73,80 +71,79 @@ const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) {
|
|||
void LaserPointerManager::update() {
|
||||
QReadLocker lock(&_containsLock);
|
||||
for (QUuid& uid : _laserPointers.keys()) {
|
||||
// This only needs to be a read lock because update won't change any of the properties that can be modified from scripts
|
||||
QReadLocker laserLock(_laserPointerLocks[uid].get());
|
||||
_laserPointers[uid]->update();
|
||||
auto laserPointer = _laserPointers.find(uid);
|
||||
laserPointer.value()->update();
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
_laserPointers[uid]->setPrecisionPicking(precisionPicking);
|
||||
auto laserPointer = _laserPointers.find(uid);
|
||||
if (laserPointer != _laserPointers.end()) {
|
||||
laserPointer.value()->setPrecisionPicking(precisionPicking);
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setLaserLength(QUuid uid, const float laserLength) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
_laserPointers[uid]->setLaserLength(laserLength);
|
||||
auto laserPointer = _laserPointers.find(uid);
|
||||
if (laserPointer != _laserPointers.end()) {
|
||||
laserPointer.value()->setLaserLength(laserLength);
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
_laserPointers[uid]->setIgnoreEntities(ignoreEntities);
|
||||
auto laserPointer = _laserPointers.find(uid);
|
||||
if (laserPointer != _laserPointers.end()) {
|
||||
laserPointer.value()->setIgnoreEntities(ignoreEntities);
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
_laserPointers[uid]->setIncludeEntities(includeEntities);
|
||||
auto laserPointer = _laserPointers.find(uid);
|
||||
if (laserPointer != _laserPointers.end()) {
|
||||
laserPointer.value()->setIncludeEntities(includeEntities);
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
_laserPointers[uid]->setIgnoreOverlays(ignoreOverlays);
|
||||
auto laserPointer = _laserPointers.find(uid);
|
||||
if (laserPointer != _laserPointers.end()) {
|
||||
laserPointer.value()->setIgnoreOverlays(ignoreOverlays);
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
_laserPointers[uid]->setIncludeOverlays(includeOverlays);
|
||||
auto laserPointer = _laserPointers.find(uid);
|
||||
if (laserPointer != _laserPointers.end()) {
|
||||
laserPointer.value()->setIncludeOverlays(includeOverlays);
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
_laserPointers[uid]->setIgnoreAvatars(ignoreAvatars);
|
||||
auto laserPointer = _laserPointers.find(uid);
|
||||
if (laserPointer != _laserPointers.end()) {
|
||||
laserPointer.value()->setIgnoreAvatars(ignoreAvatars);
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
_laserPointers[uid]->setIncludeAvatars(includeAvatars);
|
||||
auto laserPointer = _laserPointers.find(uid);
|
||||
if (laserPointer != _laserPointers.end()) {
|
||||
laserPointer.value()->setIncludeAvatars(includeAvatars);
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointerManager::setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay) {
|
||||
QReadLocker lock(&_containsLock);
|
||||
if (_laserPointers.contains(uid)) {
|
||||
QWriteLocker laserLock(_laserPointerLocks[uid].get());
|
||||
_laserPointers[uid]->setLockEndUUID(objectID, isOverlay);
|
||||
auto laserPointer = _laserPointers.find(uid);
|
||||
if (laserPointer != _laserPointers.end()) {
|
||||
laserPointer.value()->setLockEndUUID(objectID, isOverlay);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
#include <memory>
|
||||
#include <glm/glm.hpp>
|
||||
#include <QReadWriteLock>
|
||||
|
||||
#include "LaserPointer.h"
|
||||
|
||||
|
@ -46,7 +45,6 @@ public:
|
|||
|
||||
private:
|
||||
QHash<QUuid, std::shared_ptr<LaserPointer>> _laserPointers;
|
||||
QHash<QUuid, std::shared_ptr<QReadWriteLock>> _laserPointerLocks;
|
||||
QReadWriteLock _containsLock;
|
||||
|
||||
};
|
||||
|
|
|
@ -16,3 +16,47 @@ RayPick::RayPick(const RayPickFilter& filter, const float maxDistance, const boo
|
|||
_enabled(enabled)
|
||||
{
|
||||
}
|
||||
void RayPick::enable() {
|
||||
QWriteLocker lock(getLock());
|
||||
_enabled = true;
|
||||
}
|
||||
|
||||
void RayPick::disable() {
|
||||
QWriteLocker lock(getLock());
|
||||
_enabled = false;
|
||||
}
|
||||
|
||||
const RayPickResult& RayPick::getPrevRayPickResult() {
|
||||
QReadLocker lock(getLock());
|
||||
return _prevResult;
|
||||
}
|
||||
|
||||
void RayPick::setIgnoreEntities(const QScriptValue& ignoreEntities) {
|
||||
QWriteLocker lock(getLock());
|
||||
_ignoreEntities = qVectorEntityItemIDFromScriptValue(ignoreEntities);
|
||||
}
|
||||
|
||||
void RayPick::setIncludeEntities(const QScriptValue& includeEntities) {
|
||||
QWriteLocker lock(getLock());
|
||||
_includeEntities = qVectorEntityItemIDFromScriptValue(includeEntities);
|
||||
}
|
||||
|
||||
void RayPick::setIgnoreOverlays(const QScriptValue& ignoreOverlays) {
|
||||
QWriteLocker lock(getLock());
|
||||
_ignoreOverlays = qVectorOverlayIDFromScriptValue(ignoreOverlays);
|
||||
}
|
||||
|
||||
void RayPick::setIncludeOverlays(const QScriptValue& includeOverlays) {
|
||||
QWriteLocker lock(getLock());
|
||||
_includeOverlays = qVectorOverlayIDFromScriptValue(includeOverlays);
|
||||
}
|
||||
|
||||
void RayPick::setIgnoreAvatars(const QScriptValue& ignoreAvatars) {
|
||||
QWriteLocker lock(getLock());
|
||||
_ignoreAvatars = qVectorEntityItemIDFromScriptValue(ignoreAvatars);
|
||||
}
|
||||
|
||||
void RayPick::setIncludeAvatars(const QScriptValue& includeAvatars) {
|
||||
QWriteLocker lock(getLock());
|
||||
_includeAvatars = qVectorEntityItemIDFromScriptValue(includeAvatars);
|
||||
}
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "EntityItemID.h"
|
||||
#include "ui/overlays/Overlay.h"
|
||||
#include <QReadWriteLock>
|
||||
|
||||
class RayPickFilter {
|
||||
public:
|
||||
|
@ -102,13 +103,13 @@ public:
|
|||
|
||||
virtual const PickRay getPickRay(bool& valid) const = 0;
|
||||
|
||||
void enable() { _enabled = true; }
|
||||
void disable() { _enabled = false; }
|
||||
void enable();
|
||||
void disable();
|
||||
|
||||
const RayPickFilter& getFilter() { return _filter; }
|
||||
float getMaxDistance() { return _maxDistance; }
|
||||
bool isEnabled() { return _enabled; }
|
||||
const RayPickResult& getPrevRayPickResult() { return _prevResult; }
|
||||
const RayPickResult& getPrevRayPickResult();
|
||||
|
||||
void setPrecisionPicking(bool precisionPicking) { _filter.setFlag(RayPickFilter::PICK_COURSE, !precisionPicking); }
|
||||
|
||||
|
@ -120,12 +121,14 @@ public:
|
|||
const QVector<OverlayID>& getIncludeOverlays() { return _includeOverlays; }
|
||||
const QVector<EntityItemID>& getIgnoreAvatars() { return _ignoreAvatars; }
|
||||
const QVector<EntityItemID>& getIncludeAvatars() { return _includeAvatars; }
|
||||
void setIgnoreEntities(const QScriptValue& ignoreEntities) { _ignoreEntities = qVectorEntityItemIDFromScriptValue(ignoreEntities); }
|
||||
void setIncludeEntities(const QScriptValue& includeEntities) { _includeEntities = qVectorEntityItemIDFromScriptValue(includeEntities); }
|
||||
void setIgnoreOverlays(const QScriptValue& ignoreOverlays) { _ignoreOverlays = qVectorOverlayIDFromScriptValue(ignoreOverlays); }
|
||||
void setIncludeOverlays(const QScriptValue& includeOverlays) { _includeOverlays = qVectorOverlayIDFromScriptValue(includeOverlays); }
|
||||
void setIgnoreAvatars(const QScriptValue& ignoreAvatars) { _ignoreAvatars = qVectorEntityItemIDFromScriptValue(ignoreAvatars); }
|
||||
void setIncludeAvatars(const QScriptValue& includeAvatars) { _includeAvatars = qVectorEntityItemIDFromScriptValue(includeAvatars); }
|
||||
void setIgnoreEntities(const QScriptValue& ignoreEntities);
|
||||
void setIncludeEntities(const QScriptValue& includeEntities);
|
||||
void setIgnoreOverlays(const QScriptValue& ignoreOverlays);
|
||||
void setIncludeOverlays(const QScriptValue& includeOverlays);
|
||||
void setIgnoreAvatars(const QScriptValue& ignoreAvatars);
|
||||
void setIncludeAvatars(const QScriptValue& includeAvatars);
|
||||
|
||||
QReadWriteLock* getLock() { return &_lock; }
|
||||
|
||||
private:
|
||||
RayPickFilter _filter;
|
||||
|
@ -139,6 +142,8 @@ private:
|
|||
QVector<OverlayID> _includeOverlays;
|
||||
QVector<EntityItemID> _ignoreAvatars;
|
||||
QVector<EntityItemID> _includeAvatars;
|
||||
|
||||
QReadWriteLock _lock;
|
||||
};
|
||||
|
||||
#endif // hifi_RayPick_h
|
||||
|
|
|
@ -47,6 +47,7 @@ void RayPickManager::update() {
|
|||
RayPickCache results;
|
||||
for (auto& uid : _rayPicks.keys()) {
|
||||
std::shared_ptr<RayPick> rayPick = _rayPicks[uid];
|
||||
QWriteLocker lock(rayPick->getLock());
|
||||
if (!rayPick->isEnabled() || rayPick->getFilter().doesPickNothing() || rayPick->getMaxDistance() < 0.0f) {
|
||||
continue;
|
||||
}
|
||||
|
@ -114,7 +115,6 @@ void RayPickManager::update() {
|
|||
}
|
||||
}
|
||||
|
||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
||||
if (rayPick->getMaxDistance() == 0.0f || (rayPick->getMaxDistance() > 0.0f && res.distance < rayPick->getMaxDistance())) {
|
||||
rayPick->setRayPickResult(res);
|
||||
} else {
|
||||
|
@ -127,7 +127,6 @@ QUuid RayPickManager::createRayPick(const std::string& jointName, const glm::vec
|
|||
QWriteLocker lock(&_containsLock);
|
||||
QUuid id = QUuid::createUuid();
|
||||
_rayPicks[id] = std::make_shared<JointRayPick>(jointName, posOffset, dirOffset, filter, maxDistance, enabled);
|
||||
_rayPickLocks[id] = std::make_shared<QReadWriteLock>();
|
||||
return id;
|
||||
}
|
||||
|
||||
|
@ -135,7 +134,6 @@ QUuid RayPickManager::createRayPick(const RayPickFilter& filter, const float max
|
|||
QWriteLocker lock(&_containsLock);
|
||||
QUuid id = QUuid::createUuid();
|
||||
_rayPicks[id] = std::make_shared<MouseRayPick>(filter, maxDistance, enabled);
|
||||
_rayPickLocks[id] = std::make_shared<QReadWriteLock>();
|
||||
return id;
|
||||
}
|
||||
|
||||
|
@ -143,93 +141,91 @@ QUuid RayPickManager::createRayPick(const glm::vec3& position, const glm::vec3&
|
|||
QWriteLocker lock(&_containsLock);
|
||||
QUuid id = QUuid::createUuid();
|
||||
_rayPicks[id] = std::make_shared<StaticRayPick>(position, direction, filter, maxDistance, enabled);
|
||||
_rayPickLocks[id] = std::make_shared<QReadWriteLock>();
|
||||
return id;
|
||||
}
|
||||
|
||||
void RayPickManager::removeRayPick(const QUuid uid) {
|
||||
QWriteLocker lock(&_containsLock);
|
||||
_rayPicks.remove(uid);
|
||||
_rayPickLocks.remove(uid);
|
||||
}
|
||||
|
||||
void RayPickManager::enableRayPick(const QUuid uid) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QWriteLocker rayPickLock(_rayPickLocks[uid].get());
|
||||
_rayPicks[uid]->enable();
|
||||
auto rayPick = _rayPicks.find(uid);
|
||||
if (rayPick != _rayPicks.end()) {
|
||||
rayPick.value()->enable();
|
||||
}
|
||||
}
|
||||
|
||||
void RayPickManager::disableRayPick(const QUuid uid) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QWriteLocker rayPickLock(_rayPickLocks[uid].get());
|
||||
_rayPicks[uid]->disable();
|
||||
auto rayPick = _rayPicks.find(uid);
|
||||
if (rayPick != _rayPicks.end()) {
|
||||
rayPick.value()->disable();
|
||||
}
|
||||
}
|
||||
|
||||
const RayPickResult RayPickManager::getPrevRayPickResult(const QUuid uid) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QReadLocker lock(_rayPickLocks[uid].get());
|
||||
return _rayPicks[uid]->getPrevRayPickResult();
|
||||
auto rayPick = _rayPicks.find(uid);
|
||||
if (rayPick != _rayPicks.end()) {
|
||||
return rayPick.value()->getPrevRayPickResult();
|
||||
}
|
||||
return RayPickResult();
|
||||
}
|
||||
|
||||
void RayPickManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
||||
_rayPicks[uid]->setPrecisionPicking(precisionPicking);
|
||||
auto rayPick = _rayPicks.find(uid);
|
||||
if (rayPick != _rayPicks.end()) {
|
||||
rayPick.value()->setPrecisionPicking(precisionPicking);
|
||||
}
|
||||
}
|
||||
|
||||
void RayPickManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
||||
_rayPicks[uid]->setIgnoreEntities(ignoreEntities);
|
||||
auto rayPick = _rayPicks.find(uid);
|
||||
if (rayPick != _rayPicks.end()) {
|
||||
rayPick.value()->setIgnoreEntities(ignoreEntities);
|
||||
}
|
||||
}
|
||||
|
||||
void RayPickManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
||||
_rayPicks[uid]->setIncludeEntities(includeEntities);
|
||||
auto rayPick = _rayPicks.find(uid);
|
||||
if (rayPick != _rayPicks.end()) {
|
||||
rayPick.value()->setIncludeEntities(includeEntities);
|
||||
}
|
||||
}
|
||||
|
||||
void RayPickManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
||||
_rayPicks[uid]->setIgnoreOverlays(ignoreOverlays);
|
||||
auto rayPick = _rayPicks.find(uid);
|
||||
if (rayPick != _rayPicks.end()) {
|
||||
rayPick.value()->setIgnoreOverlays(ignoreOverlays);
|
||||
}
|
||||
}
|
||||
|
||||
void RayPickManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
||||
_rayPicks[uid]->setIncludeOverlays(includeOverlays);
|
||||
auto rayPick = _rayPicks.find(uid);
|
||||
if (rayPick != _rayPicks.end()) {
|
||||
rayPick.value()->setIncludeOverlays(includeOverlays);
|
||||
}
|
||||
}
|
||||
|
||||
void RayPickManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
||||
_rayPicks[uid]->setIgnoreAvatars(ignoreAvatars);
|
||||
auto rayPick = _rayPicks.find(uid);
|
||||
if (rayPick != _rayPicks.end()) {
|
||||
rayPick.value()->setIgnoreAvatars(ignoreAvatars);
|
||||
}
|
||||
}
|
||||
|
||||
void RayPickManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) {
|
||||
QReadLocker containsLock(&_containsLock);
|
||||
if (_rayPicks.contains(uid)) {
|
||||
QWriteLocker lock(_rayPickLocks[uid].get());
|
||||
_rayPicks[uid]->setIncludeAvatars(includeAvatars);
|
||||
auto rayPick = _rayPicks.find(uid);
|
||||
if (rayPick != _rayPicks.end()) {
|
||||
rayPick.value()->setIncludeAvatars(includeAvatars);
|
||||
}
|
||||
}
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
#include <memory>
|
||||
#include <QtCore/QObject>
|
||||
#include <QReadWriteLock>
|
||||
|
||||
#include "RegisteredMetaTypes.h"
|
||||
|
||||
|
@ -47,7 +46,6 @@ public:
|
|||
|
||||
private:
|
||||
QHash<QUuid, std::shared_ptr<RayPick>> _rayPicks;
|
||||
QHash<QUuid, std::shared_ptr<QReadWriteLock>> _rayPickLocks;
|
||||
QReadWriteLock _containsLock;
|
||||
|
||||
typedef QHash<QPair<glm::vec3, glm::vec3>, std::unordered_map<RayPickFilter::Flags, RayPickResult>> RayPickCache;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <NetworkLogging.h>
|
||||
#include <NodeList.h>
|
||||
#include <OffscreenUi.h>
|
||||
#include <UserActivityLogger.h>
|
||||
|
||||
static const int AUTO_REFRESH_INTERVAL = 1000;
|
||||
|
||||
|
@ -104,6 +105,21 @@ void AssetMappingsScriptingInterface::uploadFile(QString path, QString mapping,
|
|||
|
||||
startedCallback.call();
|
||||
|
||||
QFileInfo fileInfo { path };
|
||||
int64_t size { fileInfo.size() };
|
||||
|
||||
QString extension = "";
|
||||
auto idx = path.lastIndexOf(".");
|
||||
if (idx >= 0) {
|
||||
extension = path.mid(idx + 1);
|
||||
}
|
||||
|
||||
UserActivityLogger::getInstance().logAction("uploading_asset", {
|
||||
{ "size", (qint64)size },
|
||||
{ "mapping", mapping },
|
||||
{ "extension", extension}
|
||||
});
|
||||
|
||||
auto upload = DependencyManager::get<AssetClient>()->createUpload(path);
|
||||
QObject::connect(upload, &AssetUpload::finished, this, [=](AssetUpload* upload, const QString& hash) mutable {
|
||||
if (upload->getError() != AssetUpload::NoError) {
|
||||
|
@ -239,6 +255,7 @@ void AssetMappingModel::refresh() {
|
|||
|
||||
connect(request, &GetAllMappingsRequest::finished, this, [this](GetAllMappingsRequest* request) mutable {
|
||||
if (request->getError() == MappingRequest::NoError) {
|
||||
int numPendingBakes = 0;
|
||||
auto mappings = request->getMappings();
|
||||
auto existingPaths = _pathToItemMap.keys();
|
||||
for (auto& mapping : mappings) {
|
||||
|
@ -287,6 +304,9 @@ void AssetMappingModel::refresh() {
|
|||
auto statusString = isFolder ? "--" : bakingStatusToString(mapping.second.status);
|
||||
lastItem->setData(statusString, Qt::UserRole + 5);
|
||||
lastItem->setData(mapping.second.bakingErrors, Qt::UserRole + 6);
|
||||
if (mapping.second.status == Pending) {
|
||||
++numPendingBakes;
|
||||
}
|
||||
}
|
||||
|
||||
Q_ASSERT(fullPath == path);
|
||||
|
@ -334,6 +354,11 @@ void AssetMappingModel::refresh() {
|
|||
item = nextItem;
|
||||
}
|
||||
}
|
||||
|
||||
if (numPendingBakes != _numPendingBakes) {
|
||||
_numPendingBakes = numPendingBakes;
|
||||
emit numPendingBakesChanged(_numPendingBakes);
|
||||
}
|
||||
} else {
|
||||
emit errorGettingMappings(request->getErrorString());
|
||||
}
|
||||
|
@ -364,4 +389,4 @@ void AssetMappingModel::setupRoles() {
|
|||
roleNames[Qt::DisplayRole] = "name";
|
||||
roleNames[Qt::UserRole + 5] = "baked";
|
||||
setItemRoleNames(roleNames);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
class AssetMappingModel : public QStandardItemModel {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool autoRefreshEnabled READ isAutoRefreshEnabled WRITE setAutoRefreshEnabled)
|
||||
Q_PROPERTY(int numPendingBakes READ getNumPendingBakes NOTIFY numPendingBakesChanged)
|
||||
|
||||
public:
|
||||
AssetMappingModel();
|
||||
|
@ -38,10 +39,13 @@ public:
|
|||
bool isKnownMapping(QString path) const { return _pathToItemMap.contains(path); }
|
||||
bool isKnownFolder(QString path) const;
|
||||
|
||||
int getNumPendingBakes() const { return _numPendingBakes; }
|
||||
|
||||
public slots:
|
||||
void clear();
|
||||
|
||||
signals:
|
||||
void numPendingBakesChanged(int newCount);
|
||||
void errorGettingMappings(QString errorString);
|
||||
void updated();
|
||||
|
||||
|
@ -50,6 +54,7 @@ private:
|
|||
|
||||
QHash<QString, QStandardItem*> _pathToItemMap;
|
||||
QTimer _autoRefreshTimer;
|
||||
int _numPendingBakes{ 0 };
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(AssetMappingModel*)
|
||||
|
|
|
@ -13,23 +13,10 @@
|
|||
|
||||
#include <avatar/AvatarManager.h>
|
||||
#include <avatar/MyAvatar.h>
|
||||
#include <HFBackEvent.h>
|
||||
#include <plugins/PluginManager.h>
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
void ControllerScriptingInterface::handleMetaEvent(HFMetaEvent* event) {
|
||||
if (event->type() == HFActionEvent::startType()) {
|
||||
emit actionStartEvent(static_cast<HFActionEvent&>(*event));
|
||||
} else if (event->type() == HFActionEvent::endType()) {
|
||||
emit actionEndEvent(static_cast<HFActionEvent&>(*event));
|
||||
} else if (event->type() == HFBackEvent::startType()) {
|
||||
emit backStartEvent();
|
||||
} else if (event->type() == HFBackEvent::endType()) {
|
||||
emit backEndEvent();
|
||||
}
|
||||
}
|
||||
|
||||
bool ControllerScriptingInterface::isKeyCaptured(QKeyEvent* event) const {
|
||||
return isKeyCaptured(KeyEvent(*event));
|
||||
}
|
||||
|
@ -91,8 +78,8 @@ glm::vec2 ControllerScriptingInterface::getViewportDimensions() const {
|
|||
return qApp->getUiSize();
|
||||
}
|
||||
|
||||
QVariant ControllerScriptingInterface::getRecommendedOverlayRect() const {
|
||||
auto rect = qApp->getRecommendedOverlayRect();
|
||||
QVariant ControllerScriptingInterface::getRecommendedHUDRect() const {
|
||||
auto rect = qApp->getRecommendedHUDRect();
|
||||
return qRectToVariant(rect);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include <controllers/UserInputMapper.h>
|
||||
#include <controllers/ScriptingInterface.h>
|
||||
|
||||
#include <HFActionEvent.h>
|
||||
#include <KeyEvent.h>
|
||||
#include <MouseEvent.h>
|
||||
#include <SpatialEvent.h>
|
||||
|
@ -36,8 +35,6 @@ public:
|
|||
void emitKeyPressEvent(QKeyEvent* event);
|
||||
void emitKeyReleaseEvent(QKeyEvent* event);
|
||||
|
||||
void handleMetaEvent(HFMetaEvent* event);
|
||||
|
||||
void emitMouseMoveEvent(QMouseEvent* event);
|
||||
void emitMousePressEvent(QMouseEvent* event);
|
||||
void emitMouseDoublePressEvent(QMouseEvent* event);
|
||||
|
@ -66,18 +63,12 @@ public slots:
|
|||
virtual void releaseEntityClickEvents();
|
||||
|
||||
virtual glm::vec2 getViewportDimensions() const;
|
||||
virtual QVariant getRecommendedOverlayRect() const;
|
||||
virtual QVariant getRecommendedHUDRect() const;
|
||||
|
||||
signals:
|
||||
void keyPressEvent(const KeyEvent& event);
|
||||
void keyReleaseEvent(const KeyEvent& event);
|
||||
|
||||
void actionStartEvent(const HFActionEvent& event);
|
||||
void actionEndEvent(const HFActionEvent& event);
|
||||
|
||||
void backStartEvent();
|
||||
void backEndEvent();
|
||||
|
||||
void mouseMoveEvent(const MouseEvent& event);
|
||||
void mousePressEvent(const MouseEvent& event);
|
||||
void mouseDoublePressEvent(const MouseEvent& event);
|
||||
|
|
|
@ -29,7 +29,7 @@ int DesktopScriptingInterface::getHeight() {
|
|||
return size.height();
|
||||
}
|
||||
|
||||
void DesktopScriptingInterface::setOverlayAlpha(float alpha) {
|
||||
void DesktopScriptingInterface::setHUDAlpha(float alpha) {
|
||||
qApp->getApplicationCompositor().setAlpha(alpha);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ class DesktopScriptingInterface : public QObject, public Dependency {
|
|||
Q_PROPERTY(int height READ getHeight) // Physical height of screen(s) including task bars and system menus
|
||||
|
||||
public:
|
||||
Q_INVOKABLE void setOverlayAlpha(float alpha);
|
||||
Q_INVOKABLE void setHUDAlpha(float alpha);
|
||||
Q_INVOKABLE void show(const QString& path, const QString& title);
|
||||
|
||||
int getWidth();
|
||||
|
|
|
@ -22,16 +22,14 @@ class RatesScriptingInterface : public QObject {
|
|||
Q_PROPERTY(float newFrame READ getNewFrameRate)
|
||||
Q_PROPERTY(float dropped READ getDropRate)
|
||||
Q_PROPERTY(float simulation READ getSimulationRate)
|
||||
Q_PROPERTY(float avatar READ getAvatarRate)
|
||||
|
||||
public:
|
||||
RatesScriptingInterface(QObject* parent) : QObject(parent) {}
|
||||
float getRenderRate() { return qApp->getFps(); }
|
||||
float getRenderRate() { return qApp->getRenderLoopRate(); }
|
||||
float getPresentRate() { return qApp->getActiveDisplayPlugin()->presentRate(); }
|
||||
float getNewFrameRate() { return qApp->getActiveDisplayPlugin()->newFramePresentRate(); }
|
||||
float getDropRate() { return qApp->getActiveDisplayPlugin()->droppedFrameRate(); }
|
||||
float getSimulationRate() { return qApp->getAverageSimsPerSecond(); }
|
||||
float getAvatarRate() { return qApp->getAvatarSimrate(); }
|
||||
float getSimulationRate() { return qApp->getGameLoopRate(); }
|
||||
};
|
||||
|
||||
#endif // HIFI_INTERFACE_RATES_SCRIPTING_INTERFACE_H
|
||||
|
|
52
interface/src/scripting/WalletScriptingInterface.cpp
Normal file
52
interface/src/scripting/WalletScriptingInterface.cpp
Normal file
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// WalletScriptingInterface.cpp
|
||||
// interface/src/scripting
|
||||
//
|
||||
// Created by Zach Fox on 2017-09-29.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "WalletScriptingInterface.h"
|
||||
|
||||
CheckoutProxy::CheckoutProxy(QObject* qmlObject, QObject* parent) : QmlWrapper(qmlObject, parent) {
|
||||
Q_ASSERT(QThread::currentThread() == qApp->thread());
|
||||
}
|
||||
|
||||
WalletScriptingInterface::WalletScriptingInterface() {
|
||||
}
|
||||
|
||||
void WalletScriptingInterface::refreshWalletStatus() {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
wallet->getWalletStatus();
|
||||
}
|
||||
|
||||
static const QString CHECKOUT_QML_PATH = qApp->applicationDirPath() + "../../../qml/hifi/commerce/checkout/Checkout.qml";
|
||||
void WalletScriptingInterface::buy(const QString& name, const QString& id, const int& price, const QString& href) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "buy", Q_ARG(const QString&, name), Q_ARG(const QString&, id), Q_ARG(const int&, price), Q_ARG(const QString&, href));
|
||||
return;
|
||||
}
|
||||
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
auto tablet = dynamic_cast<TabletProxy*>(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
|
||||
|
||||
tablet->loadQMLSource(CHECKOUT_QML_PATH);
|
||||
DependencyManager::get<HMDScriptingInterface>()->openTablet();
|
||||
|
||||
QQuickItem* root = nullptr;
|
||||
if (tablet->getToolbarMode() || (!tablet->getTabletRoot() && !qApp->isHMDMode())) {
|
||||
root = DependencyManager::get<OffscreenUi>()->getRootItem();
|
||||
} else {
|
||||
root = tablet->getTabletRoot();
|
||||
}
|
||||
CheckoutProxy* checkout = new CheckoutProxy(root->findChild<QObject*>("checkout"));
|
||||
|
||||
// Example: Wallet.buy("Test Flaregun", "0d90d21c-ce7a-4990-ad18-e9d2cf991027", 17, "http://mpassets.highfidelity.com/0d90d21c-ce7a-4990-ad18-e9d2cf991027-v1/flaregun.json");
|
||||
checkout->writeProperty("itemName", name);
|
||||
checkout->writeProperty("itemId", id);
|
||||
checkout->writeProperty("itemPrice", price);
|
||||
checkout->writeProperty("itemHref", href);
|
||||
}
|
54
interface/src/scripting/WalletScriptingInterface.h
Normal file
54
interface/src/scripting/WalletScriptingInterface.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
|
||||
// WalletScriptingInterface.h
|
||||
// interface/src/scripting
|
||||
//
|
||||
// Created by Zach Fox on 2017-09-29.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_WalletScriptingInterface_h
|
||||
#define hifi_WalletScriptingInterface_h
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <DependencyManager.h>
|
||||
|
||||
#include "scripting/HMDScriptingInterface.h"
|
||||
#include <ui/TabletScriptingInterface.h>
|
||||
#include <ui/QmlWrapper.h>
|
||||
#include <OffscreenUi.h>
|
||||
#include "Application.h"
|
||||
#include "commerce/Wallet.h"
|
||||
|
||||
class CheckoutProxy : public QmlWrapper {
|
||||
Q_OBJECT
|
||||
public:
|
||||
CheckoutProxy(QObject* qmlObject, QObject* parent = nullptr);
|
||||
};
|
||||
|
||||
|
||||
class WalletScriptingInterface : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(uint walletStatus READ getWalletStatus WRITE setWalletStatus NOTIFY walletStatusChanged)
|
||||
|
||||
public:
|
||||
WalletScriptingInterface();
|
||||
|
||||
Q_INVOKABLE void refreshWalletStatus();
|
||||
Q_INVOKABLE uint getWalletStatus() { return _walletStatus; }
|
||||
void setWalletStatus(const uint& status) { _walletStatus = status; }
|
||||
|
||||
Q_INVOKABLE void buy(const QString& name, const QString& id, const int& price, const QString& href);
|
||||
|
||||
signals:
|
||||
void walletStatusChanged();
|
||||
void walletNotSetup();
|
||||
|
||||
private:
|
||||
uint _walletStatus;
|
||||
};
|
||||
|
||||
#endif // hifi_WalletScriptingInterface_h
|
|
@ -171,6 +171,11 @@ void WindowScriptingInterface::setPreviousBrowseAssetLocation(const QString& loc
|
|||
Setting::Handle<QVariant>(LAST_BROWSE_ASSETS_LOCATION_SETTING).set(location);
|
||||
}
|
||||
|
||||
bool WindowScriptingInterface::isPointOnDesktopWindow(QVariant point) {
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
return offscreenUi->isPointOnDesktopWindow(point);
|
||||
}
|
||||
|
||||
/// Makes sure that the reticle is visible, use this in blocking forms that require a reticle and
|
||||
/// might be in same thread as a script that sets the reticle to invisible
|
||||
void WindowScriptingInterface::ensureReticleVisible() const {
|
||||
|
|
|
@ -72,6 +72,7 @@ public slots:
|
|||
void shareSnapshot(const QString& path, const QUrl& href = QUrl(""));
|
||||
bool isPhysicsEnabled();
|
||||
bool setDisplayTexture(const QString& name);
|
||||
bool isPointOnDesktopWindow(QVariant point);
|
||||
|
||||
int openMessageBox(QString title, QString text, int buttons, int defaultButton);
|
||||
void updateMessageBox(int id, QString title, QString text, int buttons, int defaultButton);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "Stats.h"
|
||||
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
#include <QFontDatabase>
|
||||
|
||||
|
@ -116,12 +117,6 @@ void Stats::updateStats(bool force) {
|
|||
}
|
||||
}
|
||||
|
||||
bool shouldDisplayTimingDetail = Menu::getInstance()->isOptionChecked(MenuOption::DisplayDebugTimingDetails) &&
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::Stats) && isExpanded();
|
||||
if (shouldDisplayTimingDetail != PerformanceTimer::isActive()) {
|
||||
PerformanceTimer::setActive(shouldDisplayTimingDetail);
|
||||
}
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||
// we need to take one avatar out so we don't include ourselves
|
||||
|
@ -129,7 +124,7 @@ void Stats::updateStats(bool force) {
|
|||
STAT_UPDATE(updatedAvatarCount, avatarManager->getNumAvatarsUpdated());
|
||||
STAT_UPDATE(notUpdatedAvatarCount, avatarManager->getNumAvatarsNotUpdated());
|
||||
STAT_UPDATE(serverCount, (int)nodeList->size());
|
||||
STAT_UPDATE_FLOAT(framerate, qApp->getFps(), 0.1f);
|
||||
STAT_UPDATE_FLOAT(renderrate, qApp->getRenderLoopRate(), 0.1f);
|
||||
if (qApp->getActiveDisplayPlugin()) {
|
||||
auto displayPlugin = qApp->getActiveDisplayPlugin();
|
||||
auto stats = displayPlugin->getHardwareStats();
|
||||
|
@ -137,7 +132,6 @@ void Stats::updateStats(bool force) {
|
|||
STAT_UPDATE(longrenders, stats["long_render_count"].toInt());
|
||||
STAT_UPDATE(longsubmits, stats["long_submit_count"].toInt());
|
||||
STAT_UPDATE(longframes, stats["long_frame_count"].toInt());
|
||||
STAT_UPDATE_FLOAT(renderrate, displayPlugin->renderRate(), 0.1f);
|
||||
STAT_UPDATE_FLOAT(presentrate, displayPlugin->presentRate(), 0.1f);
|
||||
STAT_UPDATE_FLOAT(presentnewrate, displayPlugin->newFramePresentRate(), 0.1f);
|
||||
STAT_UPDATE_FLOAT(presentdroprate, displayPlugin->droppedFrameRate(), 0.1f);
|
||||
|
@ -150,8 +144,7 @@ void Stats::updateStats(bool force) {
|
|||
STAT_UPDATE(presentnewrate, -1);
|
||||
STAT_UPDATE(presentdroprate, -1);
|
||||
}
|
||||
STAT_UPDATE(simrate, (int)qApp->getAverageSimsPerSecond());
|
||||
STAT_UPDATE(avatarSimrate, (int)qApp->getAvatarSimrate());
|
||||
STAT_UPDATE(gameLoopRate, (int)qApp->getGameLoopRate());
|
||||
|
||||
auto bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
|
||||
STAT_UPDATE(packetInCount, (int)bandwidthRecorder->getCachedTotalAverageInputPacketsPerSecond());
|
||||
|
@ -406,14 +399,21 @@ void Stats::updateStats(bool force) {
|
|||
STAT_UPDATE(lodStatus, "You can see " + DependencyManager::get<LODManager>()->getLODFeedbackText());
|
||||
}
|
||||
|
||||
bool performanceTimerIsActive = PerformanceTimer::isActive();
|
||||
bool displayPerf = _expanded && Menu::getInstance()->isOptionChecked(MenuOption::DisplayDebugTimingDetails);
|
||||
if (displayPerf && performanceTimerIsActive) {
|
||||
if (!_timingExpanded) {
|
||||
_timingExpanded = true;
|
||||
|
||||
bool performanceTimerShouldBeActive = Menu::getInstance()->isOptionChecked(MenuOption::Stats) && _expanded;
|
||||
if (performanceTimerShouldBeActive != PerformanceTimer::isActive()) {
|
||||
PerformanceTimer::setActive(performanceTimerShouldBeActive);
|
||||
}
|
||||
if (performanceTimerShouldBeActive) {
|
||||
PerformanceTimer::tallyAllTimerRecords(); // do this even if we're not displaying them, so they don't stack up
|
||||
}
|
||||
|
||||
if (performanceTimerShouldBeActive &&
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::DisplayDebugTimingDetails)) {
|
||||
if (!_showTimingDetails) {
|
||||
_showTimingDetails = true;
|
||||
emit timingExpandedChanged();
|
||||
}
|
||||
PerformanceTimer::tallyAllTimerRecords(); // do this even if we're not displaying them, so they don't stack up
|
||||
|
||||
// we will also include room for 1 line per timing record and a header of 4 lines
|
||||
// Timing details...
|
||||
|
@ -453,10 +453,55 @@ void Stats::updateStats(bool force) {
|
|||
}
|
||||
_timingStats = perfLines;
|
||||
emit timingStatsChanged();
|
||||
} else if (_timingExpanded) {
|
||||
_timingExpanded = false;
|
||||
} else if (_showTimingDetails) {
|
||||
_showTimingDetails = false;
|
||||
emit timingExpandedChanged();
|
||||
}
|
||||
|
||||
if (_expanded && performanceTimerShouldBeActive) {
|
||||
if (!_showGameUpdateStats) {
|
||||
_showGameUpdateStats = true;
|
||||
}
|
||||
class SortableStat {
|
||||
public:
|
||||
SortableStat(QString a, float p) : message(a), priority(p) {}
|
||||
QString message;
|
||||
float priority;
|
||||
bool operator<(const SortableStat& other) const { return priority < other.priority; }
|
||||
};
|
||||
|
||||
const QMap<QString, PerformanceTimerRecord>& allRecords = PerformanceTimer::getAllTimerRecords();
|
||||
std::priority_queue<SortableStat> idleUpdateStats;
|
||||
auto itr = allRecords.find("/idle/update");
|
||||
if (itr != allRecords.end()) {
|
||||
float dt = (float)itr.value().getMovingAverage() / (float)USECS_PER_MSEC;
|
||||
_gameUpdateStats = QString("/idle/update = %1 ms").arg(dt);
|
||||
|
||||
QVector<QString> categories = { "devices", "physics", "otherAvatars", "MyAvatar", "misc" };
|
||||
for (int32_t j = 0; j < categories.size(); ++j) {
|
||||
QString recordKey = "/idle/update/" + categories[j];
|
||||
itr = allRecords.find(recordKey);
|
||||
if (itr != allRecords.end()) {
|
||||
float dt = (float)itr.value().getMovingAverage() / (float)USECS_PER_MSEC;
|
||||
QString message = QString("\n %1 = %2").arg(categories[j]).arg(dt);
|
||||
idleUpdateStats.push(SortableStat(message, dt));
|
||||
}
|
||||
}
|
||||
while (!idleUpdateStats.empty()) {
|
||||
SortableStat stat = idleUpdateStats.top();
|
||||
_gameUpdateStats += stat.message;
|
||||
idleUpdateStats.pop();
|
||||
}
|
||||
emit gameUpdateStatsChanged();
|
||||
} else if (_gameUpdateStats != "") {
|
||||
_gameUpdateStats = "";
|
||||
emit gameUpdateStatsChanged();
|
||||
}
|
||||
} else if (_showGameUpdateStats) {
|
||||
_showGameUpdateStats = false;
|
||||
_gameUpdateStats = "";
|
||||
emit gameUpdateStatsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void Stats::setRenderDetails(const render::RenderDetails& details) {
|
||||
|
|
|
@ -32,8 +32,6 @@ class Stats : public QQuickItem {
|
|||
|
||||
STATS_PROPERTY(int, serverCount, 0)
|
||||
// How often the app is creating new gpu::Frames
|
||||
STATS_PROPERTY(float, framerate, 0)
|
||||
// How often the display plugin is executing a given frame
|
||||
STATS_PROPERTY(float, renderrate, 0)
|
||||
// How often the display plugin is presenting to the device
|
||||
STATS_PROPERTY(float, presentrate, 0)
|
||||
|
@ -47,8 +45,7 @@ class Stats : public QQuickItem {
|
|||
|
||||
STATS_PROPERTY(float, presentnewrate, 0)
|
||||
STATS_PROPERTY(float, presentdroprate, 0)
|
||||
STATS_PROPERTY(int, simrate, 0)
|
||||
STATS_PROPERTY(int, avatarSimrate, 0)
|
||||
STATS_PROPERTY(int, gameLoopRate, 0)
|
||||
STATS_PROPERTY(int, avatarCount, 0)
|
||||
STATS_PROPERTY(int, updatedAvatarCount, 0)
|
||||
STATS_PROPERTY(int, notUpdatedAvatarCount, 0)
|
||||
|
@ -108,6 +105,7 @@ class Stats : public QQuickItem {
|
|||
STATS_PROPERTY(QString, packetStats, QString())
|
||||
STATS_PROPERTY(QString, lodStatus, QString())
|
||||
STATS_PROPERTY(QString, timingStats, QString())
|
||||
STATS_PROPERTY(QString, gameUpdateStats, QString())
|
||||
STATS_PROPERTY(int, serverElements, 0)
|
||||
STATS_PROPERTY(int, serverInternal, 0)
|
||||
STATS_PROPERTY(int, serverLeaves, 0)
|
||||
|
@ -148,7 +146,7 @@ public:
|
|||
void updateStats(bool force = false);
|
||||
|
||||
bool isExpanded() { return _expanded; }
|
||||
bool isTimingExpanded() { return _timingExpanded; }
|
||||
bool isTimingExpanded() { return _showTimingDetails; }
|
||||
|
||||
void setExpanded(bool expanded) {
|
||||
if (_expanded != expanded) {
|
||||
|
@ -167,7 +165,6 @@ signals:
|
|||
void longrendersChanged();
|
||||
void longframesChanged();
|
||||
void appdroppedChanged();
|
||||
void framerateChanged();
|
||||
void expandedChanged();
|
||||
void timingExpandedChanged();
|
||||
void serverCountChanged();
|
||||
|
@ -176,8 +173,7 @@ signals:
|
|||
void presentnewrateChanged();
|
||||
void presentdroprateChanged();
|
||||
void stutterrateChanged();
|
||||
void simrateChanged();
|
||||
void avatarSimrateChanged();
|
||||
void gameLoopRateChanged();
|
||||
void avatarCountChanged();
|
||||
void updatedAvatarCountChanged();
|
||||
void notUpdatedAvatarCountChanged();
|
||||
|
@ -242,6 +238,7 @@ signals:
|
|||
void localInternalChanged();
|
||||
void localLeavesChanged();
|
||||
void timingStatsChanged();
|
||||
void gameUpdateStatsChanged();
|
||||
void glContextSwapchainMemoryChanged();
|
||||
void qmlTextureMemoryChanged();
|
||||
void texturePendingTransfersChanged();
|
||||
|
@ -267,7 +264,8 @@ private:
|
|||
int _recentMaxPackets{ 0 } ; // recent max incoming voxel packets to process
|
||||
bool _resetRecentMaxPacketsSoon{ true };
|
||||
bool _expanded{ false };
|
||||
bool _timingExpanded{ false };
|
||||
bool _showTimingDetails{ false };
|
||||
bool _showGameUpdateStats{ false };
|
||||
QString _monospaceFont;
|
||||
const AudioIOStats* _audioStats;
|
||||
QStringList _downloadUrls = QStringList();
|
||||
|
|
|
@ -26,7 +26,8 @@ Base3DOverlay::Base3DOverlay() :
|
|||
_isSolid(DEFAULT_IS_SOLID),
|
||||
_isDashedLine(DEFAULT_IS_DASHED_LINE),
|
||||
_ignoreRayIntersection(false),
|
||||
_drawInFront(false)
|
||||
_drawInFront(false),
|
||||
_drawHUDLayer(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -38,6 +39,7 @@ Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) :
|
|||
_isDashedLine(base3DOverlay->_isDashedLine),
|
||||
_ignoreRayIntersection(base3DOverlay->_ignoreRayIntersection),
|
||||
_drawInFront(base3DOverlay->_drawInFront),
|
||||
_drawHUDLayer(base3DOverlay->_drawHUDLayer),
|
||||
_isGrabbable(base3DOverlay->_isGrabbable)
|
||||
{
|
||||
setTransform(base3DOverlay->getTransform());
|
||||
|
@ -125,13 +127,19 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) {
|
|||
bool needRenderItemUpdate = false;
|
||||
|
||||
auto drawInFront = properties["drawInFront"];
|
||||
|
||||
if (drawInFront.isValid()) {
|
||||
bool value = drawInFront.toBool();
|
||||
setDrawInFront(value);
|
||||
needRenderItemUpdate = true;
|
||||
}
|
||||
|
||||
auto drawHUDLayer = properties["drawHUDLayer"];
|
||||
if (drawHUDLayer.isValid()) {
|
||||
bool value = drawHUDLayer.toBool();
|
||||
setDrawHUDLayer(value);
|
||||
needRenderItemUpdate = true;
|
||||
}
|
||||
|
||||
auto isGrabbable = properties["grabbable"];
|
||||
if (isGrabbable.isValid()) {
|
||||
setIsGrabbable(isGrabbable.toBool());
|
||||
|
@ -265,15 +273,14 @@ void Base3DOverlay::parentDeleted() {
|
|||
}
|
||||
|
||||
void Base3DOverlay::update(float duration) {
|
||||
|
||||
// In Base3DOverlay, if its location or bound changed, the renderTrasnformDirty flag is true.
|
||||
// then the correct transform used for rendering is computed in the update transaction and assigned.
|
||||
if (_renderTransformDirty) {
|
||||
auto itemID = getRenderItemID();
|
||||
// Capture the render transform value in game loop before
|
||||
auto latestTransform = evalRenderTransform();
|
||||
_renderTransformDirty = false;
|
||||
if (render::Item::isValidID(itemID)) {
|
||||
// Capture the render transform value in game loop before
|
||||
auto latestTransform = evalRenderTransform();
|
||||
_renderTransformDirty = false;
|
||||
render::ScenePointer scene = qApp->getMain3DScene();
|
||||
render::Transaction transaction;
|
||||
transaction.updateItem<Overlay>(itemID, [latestTransform](Overlay& data) {
|
||||
|
@ -283,8 +290,6 @@ void Base3DOverlay::update(float duration) {
|
|||
}
|
||||
});
|
||||
scene->enqueueTransaction(transaction);
|
||||
} else {
|
||||
setRenderTransform(latestTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ public:
|
|||
bool getIsSolidLine() const { return !_isDashedLine; }
|
||||
bool getIgnoreRayIntersection() const { return _ignoreRayIntersection; }
|
||||
bool getDrawInFront() const { return _drawInFront; }
|
||||
bool getDrawHUDLayer() const { return _drawHUDLayer; }
|
||||
bool getIsGrabbable() const { return _isGrabbable; }
|
||||
|
||||
void setLineWidth(float lineWidth) { _lineWidth = lineWidth; }
|
||||
|
@ -48,6 +49,7 @@ public:
|
|||
void setIsDashedLine(bool isDashedLine) { _isDashedLine = isDashedLine; }
|
||||
void setIgnoreRayIntersection(bool value) { _ignoreRayIntersection = value; }
|
||||
virtual void setDrawInFront(bool value) { _drawInFront = value; }
|
||||
virtual void setDrawHUDLayer(bool value) { _drawHUDLayer = value; }
|
||||
void setIsGrabbable(bool value) { _isGrabbable = value; }
|
||||
|
||||
virtual AABox getBounds() const override = 0;
|
||||
|
@ -81,6 +83,7 @@ protected:
|
|||
bool _isDashedLine;
|
||||
bool _ignoreRayIntersection;
|
||||
bool _drawInFront;
|
||||
bool _drawHUDLayer;
|
||||
bool _isGrabbable { false };
|
||||
mutable bool _renderTransformDirty{ true };
|
||||
|
||||
|
|
|
@ -263,7 +263,7 @@ const render::ShapeKey Circle3DOverlay::getShapeKey() {
|
|||
if (isTransparent()) {
|
||||
builder.withTranslucent();
|
||||
}
|
||||
if (!getIsSolid() || shouldDrawHUDLayer()) {
|
||||
if (!getIsSolid()) {
|
||||
builder.withUnlit().withDepthBias();
|
||||
}
|
||||
return builder.build();
|
||||
|
|
|
@ -41,6 +41,7 @@ ContextOverlayInterface::ContextOverlayInterface() {
|
|||
_entityPropertyFlags += PROP_MARKETPLACE_ID;
|
||||
_entityPropertyFlags += PROP_DIMENSIONS;
|
||||
_entityPropertyFlags += PROP_REGISTRATION_POINT;
|
||||
_entityPropertyFlags += PROP_CERTIFICATE_ID;
|
||||
|
||||
auto entityTreeRenderer = DependencyManager::get<EntityTreeRenderer>().data();
|
||||
connect(entityTreeRenderer, SIGNAL(mousePressOnEntity(const EntityItemID&, const PointerEvent&)), this, SLOT(createOrDestroyContextOverlay(const EntityItemID&, const PointerEvent&)));
|
||||
|
@ -176,7 +177,12 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID&
|
|||
|
||||
bool ContextOverlayInterface::contextOverlayFilterPassed(const EntityItemID& entityItemID) {
|
||||
EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityItemID, _entityPropertyFlags);
|
||||
return (entityProperties.getMarketplaceID().length() != 0);
|
||||
Setting::Handle<bool> _settingSwitch{ "commerce", false };
|
||||
if (_settingSwitch.get()) {
|
||||
return (entityProperties.getCertificateID().length() != 0);
|
||||
} else {
|
||||
return (entityProperties.getMarketplaceID().length() != 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool ContextOverlayInterface::destroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event) {
|
||||
|
@ -201,7 +207,8 @@ bool ContextOverlayInterface::destroyContextOverlay(const EntityItemID& entityIt
|
|||
void ContextOverlayInterface::contextOverlays_mousePressOnOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
||||
if (overlayID == _contextOverlayID && event.getButton() == PointerEvent::PrimaryButton) {
|
||||
qCDebug(context_overlay) << "Clicked Context Overlay. Entity ID:" << _currentEntityWithContextOverlay << "Overlay ID:" << overlayID;
|
||||
if (_commerceSettingSwitch.get()) {
|
||||
Setting::Handle<bool> _settingSwitch{ "commerce", false };
|
||||
if (_settingSwitch.get()) {
|
||||
openInspectionCertificate();
|
||||
} else {
|
||||
openMarketplace();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue