Merge pull request #4131 from Atlante45/pull_out_menu_mess

Settings - Part I
This commit is contained in:
Andrew Meadows 2015-01-27 16:23:23 -08:00
commit 026c39e010
85 changed files with 2116 additions and 1854 deletions

View file

@ -13,7 +13,6 @@
#include <QtCore/QEventLoop> #include <QtCore/QEventLoop>
#include <QtCore/QStandardPaths> #include <QtCore/QStandardPaths>
#include <QtCore/QTimer> #include <QtCore/QTimer>
#include <QtNetwork/QNetworkDiskCache>
#include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply> #include <QtNetwork/QNetworkReply>
@ -171,11 +170,6 @@ void Agent::run() {
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
QNetworkReply *reply = networkAccessManager.get(QNetworkRequest(scriptURL)); QNetworkReply *reply = networkAccessManager.get(QNetworkRequest(scriptURL));
QNetworkDiskCache* cache = new QNetworkDiskCache();
QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
cache->setCacheDirectory(!cachePath.isEmpty() ? cachePath : "agentCache");
networkAccessManager.setCache(cache);
qDebug() << "Downloading script at" << scriptURL.toString(); qDebug() << "Downloading script at" << scriptURL.toString();
QEventLoop loop; QEventLoop loop;

View file

@ -9,10 +9,11 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include <QtCore/QProcess> #include <QProcess>
#include <QtCore/qsharedmemory.h> #include <QSettings>
#include <QtCore/QThread> #include <QSharedMemory>
#include <QtCore/QTimer> #include <QThread>
#include <QTimer>
#include <AccountManager.h> #include <AccountManager.h>
#include <AddressManager.h> #include <AddressManager.h>

View file

@ -13,21 +13,22 @@
#include <openssl/rsa.h> #include <openssl/rsa.h>
#include <openssl/x509.h> #include <openssl/x509.h>
#include <QtCore/QDir> #include <QDir>
#include <QtCore/QJsonDocument> #include <QJsonDocument>
#include <QtCore/QJsonObject> #include <QJsonObject>
#include <QtCore/QJsonArray> #include <QJsonArray>
#include <QtCore/QProcess> #include <QProcess>
#include <QtCore/qsharedmemory.h> #include <QSharedMemory>
#include <QtCore/QStandardPaths> #include <QStandardPaths>
#include <QtCore/QTimer> #include <QTimer>
#include <QtCore/QUrlQuery> #include <QUrlQuery>
#include <AccountManager.h> #include <AccountManager.h>
#include <HifiConfigVariantMap.h> #include <HifiConfigVariantMap.h>
#include <HTTPConnection.h> #include <HTTPConnection.h>
#include <LogUtils.h> #include <LogUtils.h>
#include <PacketHeaders.h> #include <PacketHeaders.h>
#include <Settings.h>
#include <SharedUtil.h> #include <SharedUtil.h>
#include <ShutdownEventListener.h> #include <ShutdownEventListener.h>
#include <UUID.h> #include <UUID.h>
@ -1920,10 +1921,8 @@ Headers DomainServer::setupCookieHeadersFromProfileReply(QNetworkReply* profileR
_cookieSessionHash.insert(cookieUUID, sessionData); _cookieSessionHash.insert(cookieUUID, sessionData);
// persist the cookie to settings file so we can get it back on DS relaunch // persist the cookie to settings file so we can get it back on DS relaunch
QSettings localSettings; QStringList path = QStringList() << DS_SETTINGS_SESSIONS_GROUP << cookieUUID.toString();
localSettings.beginGroup(DS_SETTINGS_SESSIONS_GROUP); SettingHandles::SettingHandle<QVariant>(path).set(QVariant::fromValue(sessionData));
QVariant sessionVariant = QVariant::fromValue(sessionData);
localSettings.setValue(cookieUUID.toString(), QVariant::fromValue(sessionData));
// setup expiry for cookie to 1 month from today // setup expiry for cookie to 1 month from today
QDateTime cookieExpiry = QDateTime::currentDateTimeUtc().addMonths(1); QDateTime cookieExpiry = QDateTime::currentDateTimeUtc().addMonths(1);
@ -1943,11 +1942,12 @@ Headers DomainServer::setupCookieHeadersFromProfileReply(QNetworkReply* profileR
void DomainServer::loadExistingSessionsFromSettings() { void DomainServer::loadExistingSessionsFromSettings() {
// read data for existing web sessions into memory so existing sessions can be leveraged // read data for existing web sessions into memory so existing sessions can be leveraged
QSettings domainServerSettings; Settings domainServerSettings;
domainServerSettings.beginGroup(DS_SETTINGS_SESSIONS_GROUP); domainServerSettings.beginGroup(DS_SETTINGS_SESSIONS_GROUP);
foreach(const QString& uuidKey, domainServerSettings.childKeys()) { foreach(const QString& uuidKey, domainServerSettings.childKeys()) {
_cookieSessionHash.insert(QUuid(uuidKey), domainServerSettings.value(uuidKey).value<DomainServerWebSessionData>()); _cookieSessionHash.insert(QUuid(uuidKey),
domainServerSettings.value(uuidKey).value<DomainServerWebSessionData>());
qDebug() << "Pulled web session from settings - cookie UUID is" << uuidKey; qDebug() << "Pulled web session from settings - cookie UUID is" << uuidKey;
} }
} }

View file

@ -33,13 +33,12 @@
#include <QMenuBar> #include <QMenuBar>
#include <QMouseEvent> #include <QMouseEvent>
#include <QNetworkReply> #include <QNetworkReply>
#include <QNetworkDiskCache>
#include <QOpenGLFramebufferObject> #include <QOpenGLFramebufferObject>
#include <QObject> #include <QObject>
#include <QWheelEvent> #include <QWheelEvent>
#include <QScreen> #include <QScreen>
#include <QSettings>
#include <QShortcut> #include <QShortcut>
#include <QSystemTrayIcon>
#include <QTimer> #include <QTimer>
#include <QUrl> #include <QUrl>
#include <QWindow> #include <QWindow>
@ -73,13 +72,16 @@
#include <PhysicsEngine.h> #include <PhysicsEngine.h>
#include <ProgramObject.h> #include <ProgramObject.h>
#include <ResourceCache.h> #include <ResourceCache.h>
#include <Settings.h>
#include <SoundCache.h> #include <SoundCache.h>
#include <TextRenderer.h> #include <TextRenderer.h>
#include <UserActivityLogger.h> #include <UserActivityLogger.h>
#include <UUID.h> #include <UUID.h>
#include "Application.h" #include "Application.h"
#include "Audio.h"
#include "InterfaceVersion.h" #include "InterfaceVersion.h"
#include "LODManager.h"
#include "Menu.h" #include "Menu.h"
#include "ModelUploader.h" #include "ModelUploader.h"
#include "Util.h" #include "Util.h"
@ -100,7 +102,6 @@
#include "gpu/Batch.h" #include "gpu/Batch.h"
#include "gpu/GLBackend.h" #include "gpu/GLBackend.h"
#include "scripting/AccountScriptingInterface.h" #include "scripting/AccountScriptingInterface.h"
#include "scripting/AudioDeviceScriptingInterface.h" #include "scripting/AudioDeviceScriptingInterface.h"
#include "scripting/ClipboardScriptingInterface.h" #include "scripting/ClipboardScriptingInterface.h"
@ -112,9 +113,16 @@
#include "scripting/WindowScriptingInterface.h" #include "scripting/WindowScriptingInterface.h"
#include "scripting/WebWindowClass.h" #include "scripting/WebWindowClass.h"
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
#include "SpeechRecognizer.h"
#endif
#include "ui/DataWebDialog.h" #include "ui/DataWebDialog.h"
#include "ui/DialogsManager.h"
#include "ui/InfoView.h" #include "ui/InfoView.h"
#include "ui/LoginDialog.h"
#include "ui/Snapshot.h" #include "ui/Snapshot.h"
#include "ui/StandAloneJSConsole.h"
#include "ui/Stats.h" #include "ui/Stats.h"
@ -127,9 +135,6 @@ static unsigned STARFIELD_SEED = 1;
static const int BANDWIDTH_METER_CLICK_MAX_DRAG_LENGTH = 6; // farther dragged clicks are ignored static const int BANDWIDTH_METER_CLICK_MAX_DRAG_LENGTH = 6; // farther dragged clicks are ignored
const qint64 MAXIMUM_CACHE_SIZE = 10737418240; // 10GB
static QTimer* idleTimer = NULL; static QTimer* idleTimer = NULL;
const QString CHECK_VERSION_URL = "https://highfidelity.io/latestVersion.xml"; const QString CHECK_VERSION_URL = "https://highfidelity.io/latestVersion.xml";
@ -137,6 +142,12 @@ const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::D
const QString DEFAULT_SCRIPTS_JS_URL = "http://s3.amazonaws.com/hifi-public/scripts/defaultScripts.js"; const QString DEFAULT_SCRIPTS_JS_URL = "http://s3.amazonaws.com/hifi-public/scripts/defaultScripts.js";
namespace SettingHandles {
const SettingHandle<bool> firstRun("firstRun", true);
const SettingHandle<QString> lastScriptLocation("LastScriptLocation");
const SettingHandle<QString> scriptsLocation("scriptsLocation");
}
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
QString logMessage = LogHandler::getInstance().printMessage((LogMsgType) type, context, message); QString logMessage = LogHandler::getInstance().printMessage((LogMsgType) type, context, message);
@ -183,6 +194,12 @@ bool setupEssentials(int& argc, char** argv) {
auto ddeFaceTracker = DependencyManager::set<DdeFaceTracker>(); auto ddeFaceTracker = DependencyManager::set<DdeFaceTracker>();
auto modelBlender = DependencyManager::set<ModelBlender>(); auto modelBlender = DependencyManager::set<ModelBlender>();
auto audioToolBox = DependencyManager::set<AudioToolBox>(); auto audioToolBox = DependencyManager::set<AudioToolBox>();
auto lodManager = DependencyManager::set<LODManager>();
auto jsConsole = DependencyManager::set<StandAloneJSConsole>();
auto dialogsManager = DependencyManager::set<DialogsManager>();
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
auto speechRecognizer = DependencyManager::set<SpeechRecognizer>();
#endif
return true; return true;
} }
@ -276,6 +293,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
auto audioIO = DependencyManager::get<Audio>(); auto audioIO = DependencyManager::get<Audio>();
audioIO->moveToThread(audioThread); audioIO->moveToThread(audioThread);
connect(audioThread, &QThread::started, audioIO.data(), &Audio::start); connect(audioThread, &QThread::started, audioIO.data(), &Audio::start);
connect(audioIO.data(), SIGNAL(muteToggled()), this, SLOT(audioMuteToggled()));
audioThread->start(); audioThread->start();
@ -287,7 +305,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(updateWindowTitle())); connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(updateWindowTitle()));
connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(clearDomainOctreeDetails())); connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(clearDomainOctreeDetails()));
connect(&domainHandler, &DomainHandler::settingsReceived, this, &Application::domainSettingsReceived); connect(&domainHandler, &DomainHandler::settingsReceived, this, &Application::domainSettingsReceived);
connect(&domainHandler, &DomainHandler::hostnameChanged, Menu::getInstance(), &Menu::clearLoginDialogDisplayedFlag); connect(&domainHandler, &DomainHandler::hostnameChanged,
DependencyManager::get<AddressManager>().data(), &AddressManager::storeCurrentAddress);
// update our location every 5 seconds in the data-server, assuming that we are authenticated with one // update our location every 5 seconds in the data-server, assuming that we are authenticated with one
const qint64 DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS = 5 * 1000; const qint64 DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS = 5 * 1000;
@ -313,7 +332,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
connect(&accountManager, &AccountManager::balanceChanged, this, &Application::updateWindowTitle); connect(&accountManager, &AccountManager::balanceChanged, this, &Application::updateWindowTitle);
connect(&accountManager, &AccountManager::authRequired, Menu::getInstance(), &Menu::loginForCurrentDomain); auto dialogsManager = DependencyManager::get<DialogsManager>();
connect(&accountManager, &AccountManager::authRequired, dialogsManager.data(), &DialogsManager::showLoginDialog);
connect(&accountManager, &AccountManager::usernameChanged, this, &Application::updateWindowTitle); connect(&accountManager, &AccountManager::usernameChanged, this, &Application::updateWindowTitle);
// once we have a profile in account manager make sure we generate a new keypair // once we have a profile in account manager make sure we generate a new keypair
@ -334,9 +354,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
connect(addressManager.data(), &AddressManager::rootPlaceNameChanged, this, &Application::updateWindowTitle); connect(addressManager.data(), &AddressManager::rootPlaceNameChanged, this, &Application::updateWindowTitle);
_settings = new QSettings(this);
_numChangedSettings = 0;
#ifdef _WIN32 #ifdef _WIN32
WSADATA WsaData; WSADATA WsaData;
int wsaresult = WSAStartup(MAKEWORD(2,2), &WsaData); int wsaresult = WSAStartup(MAKEWORD(2,2), &WsaData);
@ -366,18 +383,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
connect(billboardPacketTimer, &QTimer::timeout, _myAvatar, &MyAvatar::sendBillboardPacket); connect(billboardPacketTimer, &QTimer::timeout, _myAvatar, &MyAvatar::sendBillboardPacket);
billboardPacketTimer->start(AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS); billboardPacketTimer->start(AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS);
QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
QNetworkDiskCache* cache = new QNetworkDiskCache();
cache->setMaximumCacheSize(MAXIMUM_CACHE_SIZE);
cache->setCacheDirectory(!cachePath.isEmpty() ? cachePath : "interfaceCache");
networkAccessManager.setCache(cache);
ResourceCache::setRequestLimit(3); ResourceCache::setRequestLimit(3);
_window->setCentralWidget(glCanvas.data()); _window->setCentralWidget(glCanvas.data());
restoreSizeAndPosition(); _window->restoreGeometry();
_window->setVisible(true); _window->setVisible(true);
glCanvas->setFocusPolicy(Qt::StrongFocus); glCanvas->setFocusPolicy(Qt::StrongFocus);
@ -411,23 +423,31 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
connect(this, SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit())); connect(this, SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit()));
// check first run... // check first run...
QVariant firstRunValue = _settings->value("firstRun",QVariant(true)); bool firstRun = SettingHandles::firstRun.get();
if (firstRunValue.isValid() && firstRunValue.toBool()) { if (firstRun) {
qDebug() << "This is a first run..."; qDebug() << "This is a first run...";
// clear the scripts, and set out script to our default scripts // clear the scripts, and set out script to our default scripts
clearScriptsBeforeRunning(); clearScriptsBeforeRunning();
loadScript(DEFAULT_SCRIPTS_JS_URL); loadScript(DEFAULT_SCRIPTS_JS_URL);
QMutexLocker locker(&_settingsMutex); SettingHandles::firstRun.set(false);
_settings->setValue("firstRun",QVariant(false));
} else { } else {
// do this as late as possible so that all required subsystems are initialized // do this as late as possible so that all required subsystems are initialized
loadScripts(); loadScripts();
QMutexLocker locker(&_settingsMutex); _previousScriptLocation = SettingHandles::lastScriptLocation.get();
_previousScriptLocation = _settings->value("LastScriptLocation", QVariant("")).toString();
} }
loadSettings();
int SAVE_SETTINGS_INTERVAL = 10 * MSECS_PER_SECOND; // Let's save every seconds for now
connect(&_settingsTimer, &QTimer::timeout, this, &Application::saveSettings);
connect(&_settingsThread, SIGNAL(started), &_settingsTimer, SLOT(start));
connect(&_settingsThread, &QThread::finished, &_settingsTimer, &QTimer::deleteLater);
_settingsTimer.moveToThread(&_settingsThread);
_settingsTimer.setSingleShot(false);
_settingsTimer.setInterval(SAVE_SETTINGS_INTERVAL);
_settingsThread.start();
_trayIcon->show(); _trayIcon->show();
// set the local loopback interface for local sounds from audio scripts // set the local loopback interface for local sounds from audio scripts
@ -448,12 +468,12 @@ void Application::aboutToQuit() {
} }
Application::~Application() { Application::~Application() {
saveSettings();
_entities.getTree()->setSimulation(NULL); _entities.getTree()->setSimulation(NULL);
qInstallMessageHandler(NULL); qInstallMessageHandler(NULL);
saveSettings(); _window->saveGeometry();
storeSizeAndPosition();
int DELAY_TIME = 1000; int DELAY_TIME = 1000;
UserActivityLogger::getInstance().close(DELAY_TIME); UserActivityLogger::getInstance().close(DELAY_TIME);
@ -490,45 +510,6 @@ Application::~Application() {
DependencyManager::destroy<GLCanvas>(); DependencyManager::destroy<GLCanvas>();
} }
void Application::saveSettings() {
Menu::getInstance()->saveSettings();
_rearMirrorTools->saveSettings(_settings);
_settings->sync();
_numChangedSettings = 0;
}
void Application::restoreSizeAndPosition() {
QRect available = desktop()->availableGeometry();
QMutexLocker locker(&_settingsMutex);
_settings->beginGroup("Window");
int x = (int)loadSetting(_settings, "x", 0);
int y = (int)loadSetting(_settings, "y", 0);
_window->move(x, y);
int width = (int)loadSetting(_settings, "width", available.width());
int height = (int)loadSetting(_settings, "height", available.height());
_window->resize(width, height);
_settings->endGroup();
}
void Application::storeSizeAndPosition() {
QMutexLocker locker(&_settingsMutex);
_settings->beginGroup("Window");
_settings->setValue("width", _window->rect().width());
_settings->setValue("height", _window->rect().height());
_settings->setValue("x", _window->pos().x());
_settings->setValue("y", _window->pos().y());
_settings->endGroup();
}
void Application::initializeGL() { void Application::initializeGL() {
qDebug( "Created Display Window."); qDebug( "Created Display Window.");
@ -650,7 +631,7 @@ void Application::paintGL() {
_myCamera.update(1.0f / _fps); _myCamera.update(1.0f / _fps);
} }
if (Menu::getInstance()->getShadowsEnabled()) { if (getShadowsEnabled()) {
updateShadowMap(); updateShadowMap();
} }
@ -706,6 +687,24 @@ void Application::paintGL() {
_frameCount++; _frameCount++;
} }
void Application::runTests() {
runTimingTests();
}
void Application::audioMuteToggled() {
QAction* muteAction = Menu::getInstance()->getActionForOption(MenuOption::MuteAudio);
Q_CHECK_PTR(muteAction);
muteAction->setChecked(DependencyManager::get<Audio>()->isMuted());
}
void Application::aboutApp() {
InfoView::forcedShow(INFO_HELP_PATH);
}
void Application::showEditEntitiesHelp() {
InfoView::forcedShow(INFO_EDIT_ENTITIES_PATH);
}
void Application::resetCamerasOnResizeGL(Camera& camera, int width, int height) { void Application::resetCamerasOnResizeGL(Camera& camera, int width, int height) {
if (OculusManager::isConnected()) { if (OculusManager::isConnected()) {
OculusManager::configureCamera(camera, width, height); OculusManager::configureCamera(camera, width, height);
@ -713,7 +712,7 @@ void Application::resetCamerasOnResizeGL(Camera& camera, int width, int height)
TV3DManager::configureCamera(camera, width, height); TV3DManager::configureCamera(camera, width, height);
} else { } else {
camera.setAspectRatio((float)width / height); camera.setAspectRatio((float)width / height);
camera.setFieldOfView(Menu::getInstance()->getFieldOfView()); camera.setFieldOfView(_viewFrustum.getFieldOfView());
} }
} }
@ -1436,10 +1435,6 @@ void Application::idle() {
// After finishing all of the above work, restart the idle timer, allowing 2ms to process events. // After finishing all of the above work, restart the idle timer, allowing 2ms to process events.
idleTimer->start(2); idleTimer->start(2);
if (_numChangedSettings > 0) {
saveSettings();
}
} }
} }
} }
@ -1457,7 +1452,7 @@ void Application::checkBandwidthMeterClick() {
// The bandwidth meter is visible, the click didn't get dragged too far and // The bandwidth meter is visible, the click didn't get dragged too far and
// we actually hit the bandwidth meter // we actually hit the bandwidth meter
Menu::getInstance()->bandwidthDetails(); DependencyManager::get<DialogsManager>()->bandwidthDetails();
} }
} }
@ -1595,6 +1590,20 @@ bool Application::exportEntities(const QString& filename, float x, float y, floa
return true; return true;
} }
void Application::loadSettings() {
DependencyManager::get<Audio>()->loadSettings();
DependencyManager::get<LODManager>()->loadSettings();
Menu::getInstance()->loadSettings();
_myAvatar->loadData();
}
void Application::saveSettings() {
DependencyManager::get<Audio>()->saveSettings();
DependencyManager::get<LODManager>()->saveSettings();
Menu::getInstance()->saveSettings();
_myAvatar->saveData();
}
bool Application::importEntities(const QString& filename) { bool Application::importEntities(const QString& filename) {
_entityClipboard.eraseAllOctreeElements(); _entityClipboard.eraseAllOctreeElements();
bool success = _entityClipboard.readFromSVOFile(filename.toLocal8Bit().constData()); bool success = _entityClipboard.readFromSVOFile(filename.toLocal8Bit().constData());
@ -1645,8 +1654,6 @@ void Application::init() {
_timerStart.start(); _timerStart.start();
_lastTimeUpdated.start(); _lastTimeUpdated.start();
Menu::getInstance()->loadSettings();
// when --url in command line, teleport to location // when --url in command line, teleport to location
const QString HIFI_URL_COMMAND_LINE_KEY = "--url"; const QString HIFI_URL_COMMAND_LINE_KEY = "--url";
@ -1664,11 +1671,11 @@ void Application::init() {
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseEnabled)) { if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseEnabled)) {
// on OS X we only setup sixense if the user wants it on - this allows running without the hid_init crash // on OS X we only setup sixense if the user wants it on - this allows running without the hid_init crash
// if hydra support is temporarily not required // if hydra support is temporarily not required
Menu::getInstance()->toggleSixense(true); SixenseManager::getInstance().toggleSixense(true);
} }
#else #else
// setup sixense // setup sixense
Menu::getInstance()->toggleSixense(true); SixenseManager::getInstance().toggleSixense(true);
#endif #endif
// initialize our face trackers after loading the menu settings // initialize our face trackers after loading the menu settings
@ -1707,16 +1714,13 @@ void Application::init() {
_metavoxels.init(); _metavoxels.init();
auto glCanvas = DependencyManager::get<GLCanvas>(); auto glCanvas = DependencyManager::get<GLCanvas>();
_rearMirrorTools = new RearMirrorTools(glCanvas.data(), _mirrorViewRect, _settings); _rearMirrorTools = new RearMirrorTools(glCanvas.data(), _mirrorViewRect);
connect(_rearMirrorTools, SIGNAL(closeView()), SLOT(closeMirrorView())); connect(_rearMirrorTools, SIGNAL(closeView()), SLOT(closeMirrorView()));
connect(_rearMirrorTools, SIGNAL(restoreView()), SLOT(restoreMirrorView())); connect(_rearMirrorTools, SIGNAL(restoreView()), SLOT(restoreMirrorView()));
connect(_rearMirrorTools, SIGNAL(shrinkView()), SLOT(shrinkMirrorView())); connect(_rearMirrorTools, SIGNAL(shrinkView()), SLOT(shrinkMirrorView()));
connect(_rearMirrorTools, SIGNAL(resetView()), SLOT(resetSensors())); connect(_rearMirrorTools, SIGNAL(resetView()), SLOT(resetSensors()));
// save settings when avatar changes
connect(_myAvatar, &MyAvatar::transformChanged, this, &Application::bumpSettings);
// make sure our texture cache knows about window size changes // make sure our texture cache knows about window size changes
DependencyManager::get<TextureCache>()->associateWithWidget(glCanvas.data()); DependencyManager::get<TextureCache>()->associateWithWidget(glCanvas.data());
@ -1758,9 +1762,9 @@ void Application::updateLOD() {
PerformanceTimer perfTimer("LOD"); PerformanceTimer perfTimer("LOD");
// adjust it unless we were asked to disable this feature, or if we're currently in throttleRendering mode // adjust it unless we were asked to disable this feature, or if we're currently in throttleRendering mode
if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableAutoAdjustLOD) && !isThrottleRendering()) { if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableAutoAdjustLOD) && !isThrottleRendering()) {
Menu::getInstance()->autoAdjustLOD(_fps); DependencyManager::get<LODManager>()->autoAdjustLOD(_fps);
} else { } else {
Menu::getInstance()->resetLODAdjust(); DependencyManager::get<LODManager>()->resetLODAdjust();
} }
} }
@ -1877,7 +1881,7 @@ void Application::updateMyAvatarLookAtPosition() {
// deflect using Faceshift gaze data // deflect using Faceshift gaze data
glm::vec3 origin = _myAvatar->getHead()->getEyePosition(); glm::vec3 origin = _myAvatar->getHead()->getEyePosition();
float pitchSign = (_myCamera.getMode() == CAMERA_MODE_MIRROR) ? -1.0f : 1.0f; float pitchSign = (_myCamera.getMode() == CAMERA_MODE_MIRROR) ? -1.0f : 1.0f;
float deflection = Menu::getInstance()->getFaceshiftEyeDeflection(); float deflection = DependencyManager::get<Faceshift>()->getEyeDeflection();
if (isLookingAtSomeone) { if (isLookingAtSomeone) {
deflection *= GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT; deflection *= GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT;
} }
@ -1949,14 +1953,15 @@ void Application::updateDialogs(float deltaTime) {
PerformanceTimer perfTimer("updateDialogs"); PerformanceTimer perfTimer("updateDialogs");
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateDialogs()"); PerformanceWarning warn(showWarnings, "Application::updateDialogs()");
auto dialogsManager = DependencyManager::get<DialogsManager>();
// Update bandwidth dialog, if any // Update bandwidth dialog, if any
BandwidthDialog* bandwidthDialog = Menu::getInstance()->getBandwidthDialog(); BandwidthDialog* bandwidthDialog = dialogsManager->getBandwidthDialog();
if (bandwidthDialog) { if (bandwidthDialog) {
bandwidthDialog->update(); bandwidthDialog->update();
} }
OctreeStatsDialog* octreeStatsDialog = Menu::getInstance()->getOctreeStatsDialog(); QPointer<OctreeStatsDialog> octreeStatsDialog = dialogsManager->getOctreeStatsDialog();
if (octreeStatsDialog) { if (octreeStatsDialog) {
octreeStatsDialog->update(); octreeStatsDialog->update();
} }
@ -2227,8 +2232,9 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
_octreeQuery.setCameraNearClip(_viewFrustum.getNearClip()); _octreeQuery.setCameraNearClip(_viewFrustum.getNearClip());
_octreeQuery.setCameraFarClip(_viewFrustum.getFarClip()); _octreeQuery.setCameraFarClip(_viewFrustum.getFarClip());
_octreeQuery.setCameraEyeOffsetPosition(_viewFrustum.getEyeOffsetPosition()); _octreeQuery.setCameraEyeOffsetPosition(_viewFrustum.getEyeOffsetPosition());
_octreeQuery.setOctreeSizeScale(Menu::getInstance()->getOctreeSizeScale()); auto lodManager = DependencyManager::get<LODManager>();
_octreeQuery.setBoundaryLevelAdjust(Menu::getInstance()->getBoundaryLevelAdjust()); _octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale());
_octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust());
unsigned char queryPacket[MAX_PACKET_SIZE]; unsigned char queryPacket[MAX_PACKET_SIZE];
@ -2280,7 +2286,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
int perServerPPS = 0; int perServerPPS = 0;
const int SMALL_BUDGET = 10; const int SMALL_BUDGET = 10;
int perUnknownServer = SMALL_BUDGET; int perUnknownServer = SMALL_BUDGET;
int totalPPS = Menu::getInstance()->getMaxOctreePacketsPerSecond(); int totalPPS = _octreeQuery.getMaxOctreePacketsPerSecond();
// determine PPS based on number of servers // determine PPS based on number of servers
if (inViewServers >= 1) { if (inViewServers >= 1) {
@ -2401,7 +2407,7 @@ QRect Application::getDesirableApplicationGeometry() {
// If our parent window is on the HMD, then don't use it's geometry, instead use // If our parent window is on the HMD, then don't use it's geometry, instead use
// the "main screen" geometry. // the "main screen" geometry.
HMDToolsDialog* hmdTools = Menu::getInstance()->getHMDToolsDialog(); HMDToolsDialog* hmdTools = DependencyManager::get<DialogsManager>()->getHMDToolsDialog();
if (hmdTools && hmdTools->hasHMDScreen()) { if (hmdTools && hmdTools->hasHMDScreen()) {
QScreen* hmdScreen = hmdTools->getHMDScreen(); QScreen* hmdScreen = hmdTools->getHMDScreen();
QWindow* appWindow = getWindow()->windowHandle(); QWindow* appWindow = getWindow()->windowHandle();
@ -2626,15 +2632,15 @@ void Application::setupWorldLight() {
} }
bool Application::shouldRenderMesh(float largestDimension, float distanceToCamera) { bool Application::shouldRenderMesh(float largestDimension, float distanceToCamera) {
return Menu::getInstance()->shouldRenderMesh(largestDimension, distanceToCamera); return DependencyManager::get<LODManager>()->shouldRenderMesh(largestDimension, distanceToCamera);
} }
float Application::getSizeScale() const { float Application::getSizeScale() const {
return Menu::getInstance()->getOctreeSizeScale(); return DependencyManager::get<LODManager>()->getOctreeSizeScale();
} }
int Application::getBoundaryLevelAdjust() const { int Application::getBoundaryLevelAdjust() const {
return Menu::getInstance()->getBoundaryLevelAdjust(); return DependencyManager::get<LODManager>()->getBoundaryLevelAdjust();
} }
PickRay Application::computePickRay(float x, float y) { PickRay Application::computePickRay(float x, float y) {
@ -2930,8 +2936,10 @@ void Application::computeOffAxisFrustum(float& left, float& right, float& bottom
} }
} }
bool Application::getShadowsEnabled() { bool Application::getShadowsEnabled() {
return Menu::getInstance()->getShadowsEnabled(); Menu* menubar = Menu::getInstance();
return menubar->isOptionChecked(MenuOption::SimpleShadows) ||
menubar->isOptionChecked(MenuOption::CascadedShadows);
} }
bool Application::getCascadeShadowsEnabled() { bool Application::getCascadeShadowsEnabled() {
@ -2976,7 +2984,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) {
_mirrorCamera.setPosition(_myAvatar->getPosition() + _mirrorCamera.setPosition(_myAvatar->getPosition() +
_myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * BILLBOARD_DISTANCE * _myAvatar->getScale()); _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * BILLBOARD_DISTANCE * _myAvatar->getScale());
} else if (_rearMirrorTools->getZoomLevel() == BODY) { } else if (SettingHandles::rearViewZoomLevel.get() == BODY) {
_mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees
_mirrorCamera.setPosition(_myAvatar->getChestPosition() + _mirrorCamera.setPosition(_myAvatar->getChestPosition() +
_myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale()); _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale());
@ -3373,45 +3381,45 @@ void Application::packetSent(quint64 length) {
_bandwidthMeter.outputStream(BandwidthMeter::OCTREE).updateValue(length); _bandwidthMeter.outputStream(BandwidthMeter::OCTREE).updateValue(length);
} }
const QString SETTINGS_KEY = "Settings";
void Application::loadScripts() { void Application::loadScripts() {
// loads all saved scripts // loads all saved scripts
int size = lockSettings()->beginReadArray("Settings"); Settings settings;
unlockSettings(); int size = settings.beginReadArray(SETTINGS_KEY);
for (int i = 0; i < size; ++i){ for (int i = 0; i < size; ++i){
lockSettings()->setArrayIndex(i); settings.setArrayIndex(i);
QString string = _settings->value("script").toString(); QString string = settings.value("script").toString();
unlockSettings();
if (!string.isEmpty()) { if (!string.isEmpty()) {
loadScript(string); loadScript(string);
} }
} }
settings.endArray();
QMutexLocker locker(&_settingsMutex);
_settings->endArray();
} }
void Application::clearScriptsBeforeRunning() { void Application::clearScriptsBeforeRunning() {
// clears all scripts from the settings // clears all scripts from the settings
QMutexLocker locker(&_settingsMutex); SettingHandles::SettingHandle<QVariant>(SETTINGS_KEY).remove();
_settings->remove("Settings");
} }
void Application::saveScripts() { void Application::saveScripts() {
// Saves all currently running user-loaded scripts
QMutexLocker locker(&_settingsMutex);
_settings->beginWriteArray("Settings");
QStringList runningScripts = getRunningScripts(); QStringList runningScripts = getRunningScripts();
if (runningScripts.isEmpty()) {
return;
}
// Saves all currently running user-loaded scripts
Settings settings;
settings.beginWriteArray(SETTINGS_KEY);
int i = 0; int i = 0;
for (QStringList::const_iterator it = runningScripts.begin(); it != runningScripts.end(); it += 1) { for (auto it = runningScripts.begin(); it != runningScripts.end(); ++it) {
if (getScriptEngine(*it)->isUserLoaded()) { if (getScriptEngine(*it)->isUserLoaded()) {
_settings->setArrayIndex(i); settings.setArrayIndex(i);
_settings->setValue("script", *it); settings.setValue("script", *it);
i += 1; ++i;
} }
} }
settings.endArray();
_settings->endArray();
} }
QScriptValue joystickToScriptValue(QScriptEngine *engine, Joystick* const &in) { QScriptValue joystickToScriptValue(QScriptEngine *engine, Joystick* const &in) {
@ -3438,7 +3446,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
scriptEngine->registerGlobalObject("Camera", &_myCamera); scriptEngine->registerGlobalObject("Camera", &_myCamera);
#if defined(Q_OS_MAC) || defined(Q_OS_WIN) #if defined(Q_OS_MAC) || defined(Q_OS_WIN)
scriptEngine->registerGlobalObject("SpeechRecognizer", Menu::getInstance()->getSpeechRecognizer()); scriptEngine->registerGlobalObject("SpeechRecognizer", DependencyManager::get<SpeechRecognizer>().data());
#endif #endif
ClipboardScriptingInterface* clipboardScriptable = new ClipboardScriptingInterface(); ClipboardScriptingInterface* clipboardScriptable = new ClipboardScriptingInterface();
@ -3538,7 +3546,6 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser
if (activateMainWindow && !loadScriptFromEditor) { if (activateMainWindow && !loadScriptFromEditor) {
_window->activateWindow(); _window->activateWindow();
} }
bumpSettings();
return scriptEngine; return scriptEngine;
} }
@ -3566,7 +3573,6 @@ void Application::scriptFinished(const QString& scriptName) {
_scriptEnginesHash.erase(it); _scriptEnginesHash.erase(it);
_runningScriptsWidget->scriptStopped(scriptName); _runningScriptsWidget->scriptStopped(scriptName);
_runningScriptsWidget->setRunningScripts(getRunningScripts()); _runningScriptsWidget->setRunningScripts(getRunningScripts());
bumpSettings();
} }
} }
@ -3662,7 +3668,6 @@ void Application::openUrl(const QUrl& url) {
} }
void Application::updateMyAvatarTransform() { void Application::updateMyAvatarTransform() {
bumpSettings();
const float SIMULATION_OFFSET_QUANTIZATION = 16.0f; // meters const float SIMULATION_OFFSET_QUANTIZATION = 16.0f; // meters
glm::vec3 avatarPosition = _myAvatar->getPosition(); glm::vec3 avatarPosition = _myAvatar->getPosition();
glm::vec3 physicsWorldOffset = _physicsEngine.getOriginOffset(); glm::vec3 physicsWorldOffset = _physicsEngine.getOriginOffset();
@ -3679,7 +3684,6 @@ void Application::updateMyAvatarTransform() {
} }
void Application::domainSettingsReceived(const QJsonObject& domainSettingsObject) { void Application::domainSettingsReceived(const QJsonObject& domainSettingsObject) {
// from the domain-handler, figure out the satoshi cost per voxel and per meter cubed // from the domain-handler, figure out the satoshi cost per voxel and per meter cubed
const QString VOXEL_SETTINGS_KEY = "voxels"; const QString VOXEL_SETTINGS_KEY = "voxels";
const QString PER_VOXEL_COST_KEY = "per-voxel-credits"; const QString PER_VOXEL_COST_KEY = "per-voxel-credits";
@ -3722,9 +3726,7 @@ QString Application::getPreviousScriptLocation() {
void Application::setPreviousScriptLocation(const QString& previousScriptLocation) { void Application::setPreviousScriptLocation(const QString& previousScriptLocation) {
_previousScriptLocation = previousScriptLocation; _previousScriptLocation = previousScriptLocation;
QMutexLocker locker(&_settingsMutex); SettingHandles::lastScriptLocation.set(_previousScriptLocation);
_settings->setValue("LastScriptLocation", _previousScriptLocation);
bumpSettings();
} }
void Application::loadDialog() { void Application::loadDialog() {
@ -3740,7 +3742,6 @@ void Application::loadDialog() {
} }
void Application::loadScriptURLDialog() { void Application::loadScriptURLDialog() {
QInputDialog scriptURLDialog(Application::getInstance()->getWindow()); QInputDialog scriptURLDialog(Application::getInstance()->getWindow());
scriptURLDialog.setWindowTitle("Open and Run Script URL"); scriptURLDialog.setWindowTitle("Open and Run Script URL");
scriptURLDialog.setLabelText("Script:"); scriptURLDialog.setLabelText("Script:");
@ -3758,11 +3759,16 @@ void Application::loadScriptURLDialog() {
} }
loadScript(newScript); loadScript(newScript);
} }
sendFakeEnterEvent();
} }
QString Application::getScriptsLocation() const {
return SettingHandles::scriptsLocation.get();
}
void Application::setScriptsLocation(const QString& scriptsLocation) {
SettingHandles::scriptsLocation.set(scriptsLocation);
emit scriptLocationChanged(scriptsLocation);
}
void Application::toggleLogDialog() { void Application::toggleLogDialog() {
if (! _logDialog) { if (! _logDialog) {
@ -3864,7 +3870,8 @@ void Application::takeSnapshot() {
_snapshotShareDialog->show(); _snapshotShareDialog->show();
} }
void Application::setVSyncEnabled(bool vsyncOn) { void Application::setVSyncEnabled() {
bool vsyncOn = Menu::getInstance()->isOptionChecked(MenuOption::RenderTargetFramerateVSyncOn);
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
if (wglewGetExtension("WGL_EXT_swap_control")) { if (wglewGetExtension("WGL_EXT_swap_control")) {
wglSwapIntervalEXT(vsyncOn); wglSwapIntervalEXT(vsyncOn);
@ -3888,6 +3895,7 @@ void Application::setVSyncEnabled(bool vsyncOn) {
#else #else
qDebug("V-Sync is FORCED ON on this system\n"); qDebug("V-Sync is FORCED ON on this system\n");
#endif #endif
vsyncOn = true; // Turns off unused variable warning
} }
bool Application::isVSyncOn() const { bool Application::isVSyncOn() const {

View file

@ -19,7 +19,6 @@
#include <QImage> #include <QImage>
#include <QPointer> #include <QPointer>
#include <QSet> #include <QSet>
#include <QSettings>
#include <QStringList> #include <QStringList>
#include <QUndoStack> #include <QUndoStack>
@ -34,10 +33,10 @@
#include <PacketHeaders.h> #include <PacketHeaders.h>
#include <PhysicsEngine.h> #include <PhysicsEngine.h>
#include <ScriptEngine.h> #include <ScriptEngine.h>
#include <StDev.h>
#include <TextureCache.h> #include <TextureCache.h>
#include <ViewFrustum.h> #include <ViewFrustum.h>
#include "Audio.h"
#include "Bookmarks.h" #include "Bookmarks.h"
#include "Camera.h" #include "Camera.h"
#include "DatagramProcessor.h" #include "DatagramProcessor.h"
@ -80,7 +79,6 @@
class QGLWidget; class QGLWidget;
class QKeyEvent; class QKeyEvent;
class QMouseEvent; class QMouseEvent;
class QSettings;
class QSystemTrayIcon; class QSystemTrayIcon;
class QTouchEvent; class QTouchEvent;
class QWheelEvent; class QWheelEvent;
@ -121,6 +119,12 @@ static const quint64 TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS = 1 * USECS
static const QString INFO_HELP_PATH = "html/interface-welcome-allsvg.html"; static const QString INFO_HELP_PATH = "html/interface-welcome-allsvg.html";
static const QString INFO_EDIT_ENTITIES_PATH = "html/edit-entities-commands.html"; static const QString INFO_EDIT_ENTITIES_PATH = "html/edit-entities-commands.html";
class Application;
#if defined(qApp)
#undef qApp
#endif
#define qApp (static_cast<Application*>(QCoreApplication::instance()))
class Application : public QApplication, public AbstractViewStateInterface, AbstractScriptingServicesInterface { class Application : public QApplication, public AbstractViewStateInterface, AbstractScriptingServicesInterface {
Q_OBJECT Q_OBJECT
@ -128,18 +132,16 @@ class Application : public QApplication, public AbstractViewStateInterface, Abst
friend class DatagramProcessor; friend class DatagramProcessor;
public: public:
static Application* getInstance() { return static_cast<Application*>(QCoreApplication::instance()); } static Application* getInstance() { return qApp; } // TODO: replace fully by qApp
static const glm::vec3& getPositionForPath() { return getInstance()->_myAvatar->getPosition(); } static const glm::vec3& getPositionForPath() { return getInstance()->_myAvatar->getPosition(); }
static glm::quat getOrientationForPath() { return getInstance()->_myAvatar->getOrientation(); } static glm::quat getOrientationForPath() { return getInstance()->_myAvatar->getOrientation(); }
Application(int& argc, char** argv, QElapsedTimer &startup_time); Application(int& argc, char** argv, QElapsedTimer &startup_time);
~Application(); ~Application();
void restoreSizeAndPosition();
void loadScripts(); void loadScripts();
QString getPreviousScriptLocation(); QString getPreviousScriptLocation();
void setPreviousScriptLocation(const QString& previousScriptLocation); void setPreviousScriptLocation(const QString& previousScriptLocation);
void storeSizeAndPosition();
void clearScriptsBeforeRunning(); void clearScriptsBeforeRunning();
void initializeGL(); void initializeGL();
void paintGL(); void paintGL();
@ -180,6 +182,7 @@ public:
PrioVR* getPrioVR() { return &_prioVR; } PrioVR* getPrioVR() { return &_prioVR; }
QUndoStack* getUndoStack() { return &_undoStack; } QUndoStack* getUndoStack() { return &_undoStack; }
MainWindow* getWindow() { return _window; } MainWindow* getWindow() { return _window; }
OctreeQuery& getOctreeQuery() { return _octreeQuery; }
EntityTree* getEntityClipboard() { return &_entityClipboard; } EntityTree* getEntityClipboard() { return &_entityClipboard; }
EntityTreeRenderer* getEntityClipboardRenderer() { return &_entityClipboardRenderer; } EntityTreeRenderer* getEntityClipboardRenderer() { return &_entityClipboardRenderer; }
@ -215,12 +218,6 @@ public:
virtual const Transform& getViewTransform() const { return _viewTransform; } virtual const Transform& getViewTransform() const { return _viewTransform; }
void setViewTransform(const Transform& view); void setViewTransform(const Transform& view);
/// if you need to access the application settings, use lockSettings()/unlockSettings()
QSettings* lockSettings() { _settingsMutex.lock(); return _settings; }
void unlockSettings() { _settingsMutex.unlock(); }
void saveSettings();
NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; } NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; }
void lockOctreeSceneStats() { _octreeSceneStatsLock.lockForRead(); } void lockOctreeSceneStats() { _octreeSceneStatsLock.lockForRead(); }
void unlockOctreeSceneStats() { _octreeSceneStatsLock.unlock(); } void unlockOctreeSceneStats() { _octreeSceneStatsLock.unlock(); }
@ -303,6 +300,9 @@ public:
RunningScriptsWidget* getRunningScriptsWidget() { return _runningScriptsWidget; } RunningScriptsWidget* getRunningScriptsWidget() { return _runningScriptsWidget; }
Bookmarks* getBookmarks() const { return _bookmarks; } Bookmarks* getBookmarks() const { return _bookmarks; }
QString getScriptsLocation() const;
void setScriptsLocation(const QString& scriptsLocation);
signals: signals:
@ -317,6 +317,8 @@ signals:
/// Fired when the import window is closed /// Fired when the import window is closed
void importDone(); void importDone();
void scriptLocationChanged(const QString& newPath);
public slots: public slots:
void domainChanged(const QString& domainHostname); void domainChanged(const QString& domainHostname);
@ -353,13 +355,17 @@ public slots:
void openUrl(const QUrl& url); void openUrl(const QUrl& url);
void updateMyAvatarTransform(); void updateMyAvatarTransform();
void bumpSettings() { ++_numChangedSettings; }
void domainSettingsReceived(const QJsonObject& domainSettingsObject); void domainSettingsReceived(const QJsonObject& domainSettingsObject);
void setVSyncEnabled(bool vsyncOn); void setVSyncEnabled();
void resetSensors(); void resetSensors();
void aboutApp();
void showEditEntitiesHelp();
void loadSettings();
void saveSettings();
private slots: private slots:
void clearDomainOctreeDetails(); void clearDomainOctreeDetails();
@ -387,6 +393,10 @@ private slots:
void parseVersionXml(); void parseVersionXml();
void manageRunningScriptsWidgetVisibility(bool shown); void manageRunningScriptsWidgetVisibility(bool shown);
void runTests();
void audioMuteToggled();
private: private:
void resetCamerasOnResizeGL(Camera& camera, int width, int height); void resetCamerasOnResizeGL(Camera& camera, int width, int height);
@ -443,10 +453,6 @@ private:
QThread* _nodeThread; QThread* _nodeThread;
DatagramProcessor _datagramProcessor; DatagramProcessor _datagramProcessor;
QMutex _settingsMutex;
QSettings* _settings;
int _numChangedSettings;
QUndoStack _undoStack; QUndoStack _undoStack;
UndoStackScriptingInterface _undoStackScriptingInterface; UndoStackScriptingInterface _undoStackScriptingInterface;
@ -566,6 +572,7 @@ private:
RunningScriptsWidget* _runningScriptsWidget; RunningScriptsWidget* _runningScriptsWidget;
QHash<QString, ScriptEngine*> _scriptEnginesHash; QHash<QString, ScriptEngine*> _scriptEnginesHash;
bool _runningScriptsWidgetWasVisible; bool _runningScriptsWidgetWasVisible;
QString _scriptsLocation;
QSystemTrayIcon* _trayIcon; QSystemTrayIcon* _trayIcon;
@ -579,6 +586,9 @@ private:
bool _aboutToQuit; bool _aboutToQuit;
Bookmarks* _bookmarks; Bookmarks* _bookmarks;
QThread _settingsThread;
QTimer _settingsTimer;
}; };
#endif // hifi_Application_h #endif // hifi_Application_h

View file

@ -10,9 +10,10 @@
// //
#include <cstring> #include <cstring>
#include <math.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <math.h> #include <glm/glm.hpp>
#ifdef __APPLE__ #ifdef __APPLE__
#include <CoreAudio/AudioHardware.h> #include <CoreAudio/AudioHardware.h>
@ -28,29 +29,35 @@
#include <VersionHelpers.h> #include <VersionHelpers.h>
#endif #endif
#include <AudioConstants.h>
#include <QtCore/QBuffer> #include <QtCore/QBuffer>
#include <QtMultimedia/QAudioInput> #include <QtMultimedia/QAudioInput>
#include <QtMultimedia/QAudioOutput> #include <QtMultimedia/QAudioOutput>
#include <glm/glm.hpp> #include <AudioConstants.h>
#include <AudioInjector.h> #include <AudioInjector.h>
#include <NodeList.h> #include <NodeList.h>
#include <PacketHeaders.h> #include <PacketHeaders.h>
#include <PositionalAudioStream.h> #include <PositionalAudioStream.h>
#include <Settings.h>
#include <SharedUtil.h> #include <SharedUtil.h>
#include <UUID.h> #include <UUID.h>
#include "Application.h" #include "Application.h"
#include "Audio.h" #include "Audio.h"
static const int RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES = 100; static const int RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES = 100;
namespace SettingHandles {
const SettingHandle<bool> audioOutputStarveDetectionEnabled("audioOutputStarveDetectionEnabled",
DEFAULT_AUDIO_OUTPUT_STARVE_DETECTION_ENABLED);
const SettingHandle<int> audioOutputStarveDetectionThreshold("audioOutputStarveDetectionThreshold",
DEFAULT_AUDIO_OUTPUT_STARVE_DETECTION_THRESHOLD);
const SettingHandle<int> audioOutputStarveDetectionPeriod("audioOutputStarveDetectionPeriod",
DEFAULT_AUDIO_OUTPUT_STARVE_DETECTION_PERIOD);
const SettingHandle<int> audioOutputBufferSize("audioOutputBufferSize",
DEFAULT_MAX_FRAMES_OVER_DESIRED);
}
Audio::Audio() : Audio::Audio() :
AbstractAudioInterface(), AbstractAudioInterface(),
_audioInput(NULL), _audioInput(NULL),
@ -1108,3 +1115,28 @@ qint64 Audio::AudioOutputIODevice::readData(char * data, qint64 maxSize) {
return bytesWritten; return bytesWritten;
} }
void Audio::loadSettings() {
_receivedAudioStream.loadSettings();
setOutputStarveDetectionEnabled(SettingHandles::audioOutputStarveDetectionEnabled.get());
setOutputStarveDetectionThreshold(SettingHandles::audioOutputStarveDetectionThreshold.get());
setOutputStarveDetectionPeriod(SettingHandles::audioOutputStarveDetectionPeriod.get());
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "setOutputBufferSize",
Q_ARG(int, SettingHandles::audioOutputBufferSize.get()));
} else {
setOutputBufferSize(SettingHandles::audioOutputBufferSize.get());
}
}
void Audio::saveSettings() {
_receivedAudioStream.saveSettings();
SettingHandles::audioOutputStarveDetectionEnabled.set(getOutputStarveDetectionEnabled());
SettingHandles::audioOutputStarveDetectionThreshold.set(getOutputStarveDetectionThreshold());
SettingHandles::audioOutputStarveDetectionPeriod.set(getOutputStarveDetectionPeriod());
SettingHandles::audioOutputBufferSize.set(getOutputBufferSize());
}

View file

@ -30,7 +30,6 @@
#include <DependencyManager.h> #include <DependencyManager.h>
#include <StDev.h> #include <StDev.h>
#include "InterfaceConfig.h"
#include "audio/AudioIOStats.h" #include "audio/AudioIOStats.h"
#include "audio/AudioNoiseGate.h" #include "audio/AudioNoiseGate.h"
#include "AudioStreamStats.h" #include "AudioStreamStats.h"
@ -96,14 +95,13 @@ public:
}; };
const MixedProcessedAudioStream& getReceivedAudioStream() const { return _receivedAudioStream; } const MixedProcessedAudioStream& getReceivedAudioStream() const { return _receivedAudioStream; }
MixedProcessedAudioStream& getReceivedAudioStream() { return _receivedAudioStream; }
float getLastInputLoudness() const { return glm::max(_lastInputLoudness - _inputGate.getMeasuredFloor(), 0.0f); } float getLastInputLoudness() const { return glm::max(_lastInputLoudness - _inputGate.getMeasuredFloor(), 0.0f); }
float getTimeSinceLastClip() const { return _timeSinceLastClip; } float getTimeSinceLastClip() const { return _timeSinceLastClip; }
float getAudioAverageInputLoudness() const { return _lastInputLoudness; } float getAudioAverageInputLoudness() const { return _lastInputLoudness; }
void setReceivedAudioStreamSettings(const InboundAudioStream::Settings& settings) { _receivedAudioStream.setSettings(settings); }
int getDesiredJitterBufferFrames() const { return _receivedAudioStream.getDesiredJitterBufferFrames(); } int getDesiredJitterBufferFrames() const { return _receivedAudioStream.getDesiredJitterBufferFrames(); }
bool isMuted() { return _muted; } bool isMuted() { return _muted; }
@ -174,6 +172,9 @@ public slots:
void outputNotify(); void outputNotify();
void loadSettings();
void saveSettings();
signals: signals:
bool muteToggled(); bool muteToggled();
void inputReceived(const QByteArray& inputSamples); void inputReceived(const QByteArray& inputSamples);

View file

@ -9,10 +9,21 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include <QAction>
#include <QDebug>
#include <QJsonObject>
#include <QFile> #include <QFile>
#include <QInputDialog>
#include <QJsonDocument> #include <QJsonDocument>
#include <QMessageBox>
#include <QStandardPaths> #include <QStandardPaths>
#include <AddressManager.h>
#include <Application.h>
#include "MainWindow.h"
#include "Menu.h"
#include "Bookmarks.h" #include "Bookmarks.h"
Bookmarks::Bookmarks() { Bookmarks::Bookmarks() {
@ -71,3 +82,125 @@ void Bookmarks::persistToFile() {
QByteArray data = json.toJson(); QByteArray data = json.toJson();
saveFile.write(data); saveFile.write(data);
} }
void Bookmarks::setupMenus(Menu* menubar, QMenu* menu) {
// Add menus/actions
menubar->addActionToQMenuAndActionHash(menu, MenuOption::BookmarkLocation, 0,
this, SLOT(bookmarkLocation()));
_bookmarksMenu = menu->addMenu(MenuOption::Bookmarks);
_deleteBookmarksAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::DeleteBookmark, 0,
this, SLOT(deleteBookmark()));
// Enable/Disable menus as needed
enableMenuItems(_bookmarks.count() > 0);
// Load bookmarks
for (auto it = _bookmarks.begin(); it != _bookmarks.end(); ++it ) {
QString bookmarkName = it.key();
QString bookmarkAddress = it.value().toString();
addLocationToMenu(menubar, bookmarkName, bookmarkAddress);
}
}
void Bookmarks::bookmarkLocation() {
QInputDialog bookmarkLocationDialog(qApp->getWindow());
bookmarkLocationDialog.setWindowTitle("Bookmark Location");
bookmarkLocationDialog.setLabelText("Name:");
bookmarkLocationDialog.setInputMode(QInputDialog::TextInput);
bookmarkLocationDialog.resize(400, 200);
if (bookmarkLocationDialog.exec() == QDialog::Rejected) {
return;
}
QString bookmarkName = bookmarkLocationDialog.textValue().trimmed();
bookmarkName = bookmarkName.replace(QRegExp("(\r\n|[\r\n\t\v ])+"), " ");
if (bookmarkName.length() == 0) {
return;
}
auto addressManager = DependencyManager::get<AddressManager>();
QString bookmarkAddress = addressManager->currentAddress().toString();
Menu* menubar = Menu::getInstance();
if (contains(bookmarkName)) {
QMessageBox duplicateBookmarkMessage;
duplicateBookmarkMessage.setIcon(QMessageBox::Warning);
duplicateBookmarkMessage.setText("The bookmark name you entered already exists in your list.");
duplicateBookmarkMessage.setInformativeText("Would you like to overwrite it?");
duplicateBookmarkMessage.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
duplicateBookmarkMessage.setDefaultButton(QMessageBox::Yes);
if (duplicateBookmarkMessage.exec() == QMessageBox::No) {
return;
}
removeLocationFromMenu(menubar, bookmarkName);
}
addLocationToMenu(menubar, bookmarkName, bookmarkAddress);
insert(bookmarkName, bookmarkAddress); // Overwrites any item with the same bookmarkName.
enableMenuItems(true);
}
void Bookmarks::teleportToBookmark() {
QAction* action = qobject_cast<QAction*>(sender());
QString address = action->data().toString();
DependencyManager::get<AddressManager>()->handleLookupString(address);
}
void Bookmarks::deleteBookmark() {
QStringList bookmarkList;
QList<QAction*> menuItems = _bookmarksMenu->actions();
for (int i = 0; i < menuItems.count(); i += 1) {
bookmarkList.append(menuItems[i]->text());
}
QInputDialog deleteBookmarkDialog(qApp->getWindow());
deleteBookmarkDialog.setWindowTitle("Delete Bookmark");
deleteBookmarkDialog.setLabelText("Select the bookmark to delete");
deleteBookmarkDialog.resize(400, 400);
deleteBookmarkDialog.setOption(QInputDialog::UseListViewForComboBoxItems);
deleteBookmarkDialog.setComboBoxItems(bookmarkList);
deleteBookmarkDialog.setOkButtonText("Delete");
if (deleteBookmarkDialog.exec() == QDialog::Rejected) {
return;
}
QString bookmarkName = deleteBookmarkDialog.textValue().trimmed();
if (bookmarkName.length() == 0) {
return;
}
removeLocationFromMenu(Menu::getInstance(), bookmarkName);
remove(bookmarkName);
if (_bookmarksMenu->actions().count() == 0) {
enableMenuItems(false);
}
}
void Bookmarks::enableMenuItems(bool enabled) {
if (_bookmarksMenu) {
_bookmarksMenu->setEnabled(enabled);
}
if (_deleteBookmarksAction) {
_deleteBookmarksAction->setEnabled(enabled);
}
}
void Bookmarks::addLocationToMenu(Menu* menubar, QString& name, QString& address) {
QAction* teleportAction = new QAction(_bookmarksMenu);
teleportAction->setData(address);
connect(teleportAction, SIGNAL(triggered()), this, SLOT(teleportToBookmark()));
menubar->addActionToQMenuAndActionHash(_bookmarksMenu, teleportAction,
name, 0, QAction::NoRole);
}
void Bookmarks::removeLocationFromMenu(Menu* menubar, QString& name) {
menubar->removeAction(_bookmarksMenu, name);
}

View file

@ -12,10 +12,13 @@
#ifndef hifi_Bookmarks_h #ifndef hifi_Bookmarks_h
#define hifi_Bookmarks_h #define hifi_Bookmarks_h
#include <QJsonObject>
#include <QDebug>
#include <QMap> #include <QMap>
#include <QObject> #include <QObject>
#include <QPointer>
class QAction;
class QMenu;
class Menu;
class Bookmarks: public QObject { class Bookmarks: public QObject {
Q_OBJECT Q_OBJECT
@ -23,19 +26,32 @@ class Bookmarks: public QObject {
public: public:
Bookmarks(); Bookmarks();
void setupMenus(Menu* menubar, QMenu* menu);
private slots:
void bookmarkLocation();
void teleportToBookmark();
void deleteBookmark();
private:
QVariantMap _bookmarks; // { name: address, ... }
QPointer<QMenu> _bookmarksMenu;
QPointer<QAction> _deleteBookmarksAction;
const QString BOOKMARKS_FILENAME = "bookmarks.json";
QString _bookmarksFilename;
void insert(const QString& name, const QString& address); // Overwrites any existing entry with same name. void insert(const QString& name, const QString& address); // Overwrites any existing entry with same name.
void remove(const QString& name); void remove(const QString& name);
bool contains(const QString& name) const; bool contains(const QString& name) const;
QVariantMap* getBookmarks() { return &_bookmarks; };
private:
QVariantMap _bookmarks; // { name: address, ... }
const QString BOOKMARKS_FILENAME = "bookmarks.json";
QString _bookmarksFilename;
void readFromFile(); void readFromFile();
void persistToFile(); void persistToFile();
void enableMenuItems(bool enabled);
void addLocationToMenu(Menu* menubar, QString& name, QString& address);
void removeLocationFromMenu(Menu* menubar, QString& name);
}; };
#endif // hifi_Bookmarks_h #endif // hifi_Bookmarks_h

View file

@ -15,6 +15,7 @@
#include <PerfStat.h> #include <PerfStat.h>
#include "Application.h" #include "Application.h"
#include "Audio.h"
#include "Menu.h" #include "Menu.h"
#include "DatagramProcessor.h" #include "DatagramProcessor.h"

View file

@ -0,0 +1,210 @@
//
// LODManager.cpp
//
//
// Created by Clement on 1/16/15.
// 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
//
#include <Util.h>
#include "Application.h"
#include "ui/DialogsManager.h"
#include "LODManager.h"
namespace SettingHandles {
const SettingHandle<bool> automaticAvatarLOD("automaticAvatarLOD", true);
const SettingHandle<float> avatarLODDecreaseFPS("avatarLODDecreaseFPS", DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS);
const SettingHandle<float> avatarLODIncreaseFPS("avatarLODIncreaseFPS", ADJUST_LOD_UP_FPS);
const SettingHandle<float> avatarLODDistanceMultiplier("avatarLODDistanceMultiplier",
DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER);
const SettingHandle<int> boundaryLevelAdjust("boundaryLevelAdjust", 0);
const SettingHandle<float> octreeSizeScale("octreeSizeScale", DEFAULT_OCTREE_SIZE_SCALE);
}
void LODManager::autoAdjustLOD(float currentFPS) {
// NOTE: our first ~100 samples at app startup are completely all over the place, and we don't
// really want to count them in our average, so we will ignore the real frame rates and stuff
// our moving average with simulated good data
const int IGNORE_THESE_SAMPLES = 100;
const float ASSUMED_FPS = 60.0f;
if (_fpsAverage.getSampleCount() < IGNORE_THESE_SAMPLES) {
currentFPS = ASSUMED_FPS;
}
_fpsAverage.updateAverage(currentFPS);
_fastFPSAverage.updateAverage(currentFPS);
quint64 now = usecTimestampNow();
const quint64 ADJUST_AVATAR_LOD_DOWN_DELAY = 1000 * 1000;
if (_automaticAvatarLOD) {
if (_fastFPSAverage.getAverage() < _avatarLODDecreaseFPS) {
if (now - _lastAvatarDetailDrop > ADJUST_AVATAR_LOD_DOWN_DELAY) {
// attempt to lower the detail in proportion to the fps difference
float targetFps = (_avatarLODDecreaseFPS + _avatarLODIncreaseFPS) * 0.5f;
float averageFps = _fastFPSAverage.getAverage();
const float MAXIMUM_MULTIPLIER_SCALE = 2.0f;
_avatarLODDistanceMultiplier = qMin(MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER, _avatarLODDistanceMultiplier *
(averageFps < EPSILON ? MAXIMUM_MULTIPLIER_SCALE :
qMin(MAXIMUM_MULTIPLIER_SCALE, targetFps / averageFps)));
_lastAvatarDetailDrop = now;
}
} else if (_fastFPSAverage.getAverage() > _avatarLODIncreaseFPS) {
// let the detail level creep slowly upwards
const float DISTANCE_DECREASE_RATE = 0.05f;
_avatarLODDistanceMultiplier = qMax(MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER,
_avatarLODDistanceMultiplier - DISTANCE_DECREASE_RATE);
}
}
bool changed = false;
quint64 elapsed = now - _lastAdjust;
if (elapsed > ADJUST_LOD_DOWN_DELAY && _fpsAverage.getAverage() < ADJUST_LOD_DOWN_FPS
&& _octreeSizeScale > ADJUST_LOD_MIN_SIZE_SCALE) {
_octreeSizeScale *= ADJUST_LOD_DOWN_BY;
if (_octreeSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) {
_octreeSizeScale = ADJUST_LOD_MIN_SIZE_SCALE;
}
changed = true;
_lastAdjust = now;
qDebug() << "adjusting LOD down... average fps for last approximately 5 seconds=" << _fpsAverage.getAverage()
<< "_octreeSizeScale=" << _octreeSizeScale;
}
if (elapsed > ADJUST_LOD_UP_DELAY && _fpsAverage.getAverage() > ADJUST_LOD_UP_FPS
&& _octreeSizeScale < ADJUST_LOD_MAX_SIZE_SCALE) {
_octreeSizeScale *= ADJUST_LOD_UP_BY;
if (_octreeSizeScale > ADJUST_LOD_MAX_SIZE_SCALE) {
_octreeSizeScale = ADJUST_LOD_MAX_SIZE_SCALE;
}
changed = true;
_lastAdjust = now;
qDebug() << "adjusting LOD up... average fps for last approximately 5 seconds=" << _fpsAverage.getAverage()
<< "_octreeSizeScale=" << _octreeSizeScale;
}
if (changed) {
_shouldRenderTableNeedsRebuilding = true;
auto lodToolsDialog = DependencyManager::get<DialogsManager>()->getLodToolsDialog();
if (lodToolsDialog) {
lodToolsDialog->reloadSliders();
}
}
}
void LODManager::resetLODAdjust() {
_fpsAverage.reset();
_fastFPSAverage.reset();
_lastAvatarDetailDrop = _lastAdjust = usecTimestampNow();
}
QString LODManager::getLODFeedbackText() {
// determine granularity feedback
int boundaryLevelAdjust = getBoundaryLevelAdjust();
QString granularityFeedback;
switch (boundaryLevelAdjust) {
case 0: {
granularityFeedback = QString("at standard granularity.");
} break;
case 1: {
granularityFeedback = QString("at half of standard granularity.");
} break;
case 2: {
granularityFeedback = QString("at a third of standard granularity.");
} break;
default: {
granularityFeedback = QString("at 1/%1th of standard granularity.").arg(boundaryLevelAdjust + 1);
} break;
}
// distance feedback
float octreeSizeScale = getOctreeSizeScale();
float relativeToDefault = octreeSizeScale / DEFAULT_OCTREE_SIZE_SCALE;
QString result;
if (relativeToDefault > 1.01) {
result = QString("%1 further %2").arg(relativeToDefault,8,'f',2).arg(granularityFeedback);
} else if (relativeToDefault > 0.99) {
result = QString("the default distance %1").arg(granularityFeedback);
} else {
result = QString("%1 of default %2").arg(relativeToDefault,8,'f',3).arg(granularityFeedback);
}
return result;
}
// TODO: This is essentially the same logic used to render octree cells, but since models are more detailed then octree cells
// I've added a voxelToModelRatio that adjusts how much closer to a model you have to be to see it.
bool LODManager::shouldRenderMesh(float largestDimension, float distanceToCamera) {
const float octreeToMeshRatio = 4.0f; // must be this many times closer to a mesh than a voxel to see it.
float octreeSizeScale = getOctreeSizeScale();
int boundaryLevelAdjust = getBoundaryLevelAdjust();
float maxScale = (float)TREE_SCALE;
float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale) / octreeToMeshRatio;
if (_shouldRenderTableNeedsRebuilding) {
_shouldRenderTable.clear();
float SMALLEST_SCALE_IN_TABLE = 0.001f; // 1mm is plenty small
float scale = maxScale;
float visibleDistanceAtScale = visibleDistanceAtMaxScale;
while (scale > SMALLEST_SCALE_IN_TABLE) {
scale /= 2.0f;
visibleDistanceAtScale /= 2.0f;
_shouldRenderTable[scale] = visibleDistanceAtScale;
}
_shouldRenderTableNeedsRebuilding = false;
}
float closestScale = maxScale;
float visibleDistanceAtClosestScale = visibleDistanceAtMaxScale;
QMap<float, float>::const_iterator lowerBound = _shouldRenderTable.lowerBound(largestDimension);
if (lowerBound != _shouldRenderTable.constEnd()) {
closestScale = lowerBound.key();
visibleDistanceAtClosestScale = lowerBound.value();
}
if (closestScale < largestDimension) {
visibleDistanceAtClosestScale *= 2.0f;
}
return (distanceToCamera <= visibleDistanceAtClosestScale);
}
void LODManager::setOctreeSizeScale(float sizeScale) {
_octreeSizeScale = sizeScale;
_shouldRenderTableNeedsRebuilding = true;
}
void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) {
_boundaryLevelAdjust = boundaryLevelAdjust;
_shouldRenderTableNeedsRebuilding = true;
}
void LODManager::loadSettings() {
setAutomaticAvatarLOD(SettingHandles::automaticAvatarLOD.get());
setAvatarLODDecreaseFPS(SettingHandles::avatarLODDecreaseFPS.get());
setAvatarLODIncreaseFPS(SettingHandles::avatarLODIncreaseFPS.get());
setAvatarLODDistanceMultiplier(SettingHandles::avatarLODDistanceMultiplier.get());
setBoundaryLevelAdjust(SettingHandles::boundaryLevelAdjust.get());
setOctreeSizeScale(SettingHandles::octreeSizeScale.get());
}
void LODManager::saveSettings() {
SettingHandles::automaticAvatarLOD.set(getAutomaticAvatarLOD());
SettingHandles::avatarLODDecreaseFPS.set(getAvatarLODDecreaseFPS());
SettingHandles::avatarLODIncreaseFPS.set(getAvatarLODIncreaseFPS());
SettingHandles::avatarLODDistanceMultiplier.set(getAvatarLODDistanceMultiplier());
SettingHandles::boundaryLevelAdjust.set(getBoundaryLevelAdjust());
SettingHandles::octreeSizeScale.set(getOctreeSizeScale());
}

View file

@ -0,0 +1,91 @@
//
// LODManager.h
//
//
// Created by Clement on 1/16/15.
// 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
//
#ifndef hifi_LODManager_h
#define hifi_LODManager_h
#include <DependencyManager.h>
#include <OctreeConstants.h>
#include <Settings.h>
#include <SharedUtil.h>
#include <SimpleMovingAverage.h>
const float ADJUST_LOD_DOWN_FPS = 40.0;
const float ADJUST_LOD_UP_FPS = 55.0;
const float DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS = 30.0f;
const quint64 ADJUST_LOD_DOWN_DELAY = 1000 * 1000 * 5;
const quint64 ADJUST_LOD_UP_DELAY = ADJUST_LOD_DOWN_DELAY * 2;
const float ADJUST_LOD_DOWN_BY = 0.9f;
const float ADJUST_LOD_UP_BY = 1.1f;
const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.25f;
const float ADJUST_LOD_MAX_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE;
const float MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER = 0.1f;
const float MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER = 15.0f;
const float DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER = 1.0f;
const int ONE_SECOND_OF_FRAMES = 60;
const int FIVE_SECONDS_OF_FRAMES = 5 * ONE_SECOND_OF_FRAMES;
class LODManager : public Dependency {
SINGLETON_DEPENDENCY
public:
void setAutomaticAvatarLOD(bool automaticAvatarLOD) { _automaticAvatarLOD = automaticAvatarLOD; }
bool getAutomaticAvatarLOD() const { return _automaticAvatarLOD; }
void setAvatarLODDecreaseFPS(float avatarLODDecreaseFPS) { _avatarLODDecreaseFPS = avatarLODDecreaseFPS; }
float getAvatarLODDecreaseFPS() const { return _avatarLODDecreaseFPS; }
void setAvatarLODIncreaseFPS(float avatarLODIncreaseFPS) { _avatarLODIncreaseFPS = avatarLODIncreaseFPS; }
float getAvatarLODIncreaseFPS() const { return _avatarLODIncreaseFPS; }
void setAvatarLODDistanceMultiplier(float multiplier) { _avatarLODDistanceMultiplier = multiplier; }
float getAvatarLODDistanceMultiplier() const { return _avatarLODDistanceMultiplier; }
// User Tweakable LOD Items
QString getLODFeedbackText();
void setOctreeSizeScale(float sizeScale);
float getOctreeSizeScale() const { return _octreeSizeScale; }
void setBoundaryLevelAdjust(int boundaryLevelAdjust);
int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
void autoAdjustLOD(float currentFPS);
void resetLODAdjust();
bool shouldRenderMesh(float largestDimension, float distanceToCamera);
void loadSettings();
void saveSettings();
private:
LODManager() {}
bool _automaticAvatarLOD = true;
float _avatarLODDecreaseFPS = DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS;
float _avatarLODIncreaseFPS = ADJUST_LOD_UP_FPS;
float _avatarLODDistanceMultiplier = DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER;
float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
int _boundaryLevelAdjust = 0;
quint64 _lastAdjust = 0;
quint64 _lastAvatarDetailDrop = 0;
SimpleMovingAverage _fpsAverage = FIVE_SECONDS_OF_FRAMES;
SimpleMovingAverage _fastFPSAverage = ONE_SECOND_OF_FRAMES;
bool _shouldRenderTableNeedsRebuilding = true;
QMap<float, float> _shouldRenderTable;
};
#endif // hifi_LODManager_h

View file

@ -9,9 +9,8 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include "MainWindow.h" #include <QApplication>
#include "Menu.h" #include <QDesktopWidget>
#include <QEvent> #include <QEvent>
#include <QMoveEvent> #include <QMoveEvent>
#include <QResizeEvent> #include <QResizeEvent>
@ -19,8 +18,33 @@
#include <QHideEvent> #include <QHideEvent>
#include <QWindowStateChangeEvent> #include <QWindowStateChangeEvent>
MainWindow::MainWindow(QWidget* parent) : #include <Settings.h>
QMainWindow(parent) {
#include "MainWindow.h"
#include "Menu.h"
#include "Util.h"
namespace SettingHandles {
const SettingHandle<QRect> windowGeometry("WindowGeometry");
}
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) {
}
void MainWindow::restoreGeometry() {
// Did not use setGeometry() on purpose,
// see http://doc.qt.io/qt-5/qsettings.html#restoring-the-state-of-a-gui-application
QRect geometry = SettingHandles::windowGeometry.get(qApp->desktop()->availableGeometry());
move(geometry.topLeft());
resize(geometry.size());
}
void MainWindow::saveGeometry() {
// Did not use geometry() on purpose,
// see http://doc.qt.io/qt-5/qsettings.html#restoring-the-state-of-a-gui-application
QRect geometry(pos(), size());
SettingHandles::windowGeometry.set(geometry);
} }
void MainWindow::moveEvent(QMoveEvent* event) { void MainWindow::moveEvent(QMoveEvent* event) {

View file

@ -14,12 +14,15 @@
#include <QMainWindow> #include <QMainWindow>
class MainWindow : public QMainWindow class MainWindow : public QMainWindow {
{
Q_OBJECT Q_OBJECT
public: public:
explicit MainWindow(QWidget* parent = NULL); explicit MainWindow(QWidget* parent = NULL);
public slots:
void restoreGeometry();
void saveGeometry();
signals: signals:
void windowGeometryChanged(QRect geometry); void windowGeometryChanged(QRect geometry);
void windowShown(bool shown); void windowShown(bool shown);

File diff suppressed because it is too large Load diff

View file

@ -19,128 +19,23 @@
#include <QPointer> #include <QPointer>
#include <QStandardPaths> #include <QStandardPaths>
#include <EventTypes.h>
#include <MenuItemProperties.h> #include <MenuItemProperties.h>
#include <OctreeConstants.h>
#if defined(Q_OS_MAC) || defined(Q_OS_WIN) class Settings;
#include "SpeechRecognizer.h"
#endif
#include "devices/Faceshift.h"
#include "devices/SixenseManager.h"
#include "ui/ChatWindow.h"
#include "ui/JSConsole.h"
#include "ui/ScriptEditorWindow.h"
// Make an LOD handler class and move everything overthere
const float ADJUST_LOD_DOWN_FPS = 40.0;
const float ADJUST_LOD_UP_FPS = 55.0;
const float DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS = 30.0f;
const quint64 ADJUST_LOD_DOWN_DELAY = 1000 * 1000 * 5;
const quint64 ADJUST_LOD_UP_DELAY = ADJUST_LOD_DOWN_DELAY * 2;
const float ADJUST_LOD_DOWN_BY = 0.9f;
const float ADJUST_LOD_UP_BY = 1.1f;
const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.25f;
const float ADJUST_LOD_MAX_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE;
const float MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER = 0.1f;
const float MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER = 15.0f;
const float DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER = 1.0f;
const int ONE_SECOND_OF_FRAMES = 60;
const int FIVE_SECONDS_OF_FRAMES = 5 * ONE_SECOND_OF_FRAMES;
//////////////////////////////////////////////////////////
const float DEFAULT_OCULUS_UI_ANGULAR_SIZE = 72.0f;
const QString SETTINGS_ADDRESS_KEY = "address";
class QSettings;
class AddressBarDialog;
class AnimationsDialog;
class AttachmentsDialog;
class CachesSizeDialog;
class BandwidthDialog;
class DataWebDialog;
class HMDToolsDialog;
class LodToolsDialog;
class LoginDialog;
class OctreeStatsDialog;
class PreferencesDialog;
class MetavoxelEditor;
class MetavoxelNetworkSimulator;
class ChatWindow;
class MenuItemProperties;
class Menu : public QMenuBar { class Menu : public QMenuBar {
Q_OBJECT Q_OBJECT
public: public:
static Menu* getInstance(); static Menu* getInstance();
void loadSettings();
void saveSettings();
QMenu* getMenu(const QString& menuName);
void triggerOption(const QString& menuOption); void triggerOption(const QString& menuOption);
QAction* getActionForOption(const QString& menuOption); QAction* getActionForOption(const QString& menuOption);
const InboundAudioStream::Settings& getReceivedAudioStreamSettings() const { return _receivedAudioStreamSettings; }
void setReceivedAudioStreamSettings(const InboundAudioStream::Settings& receivedAudioStreamSettings) { _receivedAudioStreamSettings = receivedAudioStreamSettings; }
float getFieldOfView() const { return _fieldOfView; }
void setFieldOfView(float fieldOfView) { _fieldOfView = fieldOfView; bumpSettings(); }
float getRealWorldFieldOfView() const { return _realWorldFieldOfView; }
void setRealWorldFieldOfView(float realWorldFieldOfView) { _realWorldFieldOfView = realWorldFieldOfView; bumpSettings(); }
float getOculusUIAngularSize() const { return _oculusUIAngularSize; }
void setOculusUIAngularSize(float oculusUIAngularSize) { _oculusUIAngularSize = oculusUIAngularSize; bumpSettings(); }
float getSixenseReticleMoveSpeed() const { return _sixenseReticleMoveSpeed; }
void setSixenseReticleMoveSpeed(float sixenseReticleMoveSpeed) { _sixenseReticleMoveSpeed = sixenseReticleMoveSpeed; bumpSettings(); }
bool getInvertSixenseButtons() const { return _invertSixenseButtons; }
void setInvertSixenseButtons(bool invertSixenseButtons) { _invertSixenseButtons = invertSixenseButtons; bumpSettings(); }
float getFaceshiftEyeDeflection() const { return _faceshiftEyeDeflection; }
void setFaceshiftEyeDeflection(float faceshiftEyeDeflection) { _faceshiftEyeDeflection = faceshiftEyeDeflection; bumpSettings(); }
const QString& getFaceshiftHostname() const { return _faceshiftHostname; }
void setFaceshiftHostname(const QString& hostname) { _faceshiftHostname = hostname; bumpSettings(); }
QString getSnapshotsLocation() const;
void setSnapshotsLocation(QString snapshotsLocation) { _snapshotsLocation = snapshotsLocation; bumpSettings(); }
const QString& getScriptsLocation() const { return _scriptsLocation; }
void setScriptsLocation(const QString& scriptsLocation);
BandwidthDialog* getBandwidthDialog() const { return _bandwidthDialog; }
OctreeStatsDialog* getOctreeStatsDialog() const { return _octreeStatsDialog; }
LodToolsDialog* getLodToolsDialog() const { return _lodToolsDialog; }
HMDToolsDialog* getHMDToolsDialog() const { return _hmdToolsDialog; }
bool getShadowsEnabled() const;
// User Tweakable LOD Items
QString getLODFeedbackText();
void autoAdjustLOD(float currentFPS);
void resetLODAdjust();
void setOctreeSizeScale(float sizeScale);
float getOctreeSizeScale() const { return _octreeSizeScale; }
void setAutomaticAvatarLOD(bool automaticAvatarLOD) { _automaticAvatarLOD = automaticAvatarLOD; bumpSettings(); }
bool getAutomaticAvatarLOD() const { return _automaticAvatarLOD; }
void setAvatarLODDecreaseFPS(float avatarLODDecreaseFPS) { _avatarLODDecreaseFPS = avatarLODDecreaseFPS; bumpSettings(); }
float getAvatarLODDecreaseFPS() const { return _avatarLODDecreaseFPS; }
void setAvatarLODIncreaseFPS(float avatarLODIncreaseFPS) { _avatarLODIncreaseFPS = avatarLODIncreaseFPS; bumpSettings(); }
float getAvatarLODIncreaseFPS() const { return _avatarLODIncreaseFPS; }
void setAvatarLODDistanceMultiplier(float multiplier) { _avatarLODDistanceMultiplier = multiplier; bumpSettings(); }
float getAvatarLODDistanceMultiplier() const { return _avatarLODDistanceMultiplier; }
void setBoundaryLevelAdjust(int boundaryLevelAdjust);
int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
bool shouldRenderMesh(float largestDimension, float distanceToCamera);
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
SpeechRecognizer* getSpeechRecognizer() { return &_speechRecognizer; }
#endif
// User Tweakable PPS from Voxel Server
int getMaxOctreePacketsPerSecond() const { return _maxOctreePacketsPerSecond; }
void setMaxOctreePacketsPerSecond(int value) { _maxOctreePacketsPerSecond = value; bumpSettings(); }
QAction* addActionToQMenuAndActionHash(QMenu* destinationMenu, QAction* addActionToQMenuAndActionHash(QMenu* destinationMenu,
const QString& actionName, const QString& actionName,
const QKeySequence& shortcut = 0, const QKeySequence& shortcut = 0,
@ -154,35 +49,10 @@ public:
const QKeySequence& shortcut = 0, const QKeySequence& shortcut = 0,
QAction::MenuRole role = QAction::NoRole, QAction::MenuRole role = QAction::NoRole,
int menuItemLocation = UNSPECIFIED_POSITION); int menuItemLocation = UNSPECIFIED_POSITION);
void removeAction(QMenu* menu, const QString& actionName); void removeAction(QMenu* menu, const QString& actionName);
const QByteArray& getWalletPrivateKey() const { return _walletPrivateKey; }
signals:
void scriptLocationChanged(const QString& newPath);
public slots: public slots:
void clearLoginDialogDisplayedFlag();
void loginForCurrentDomain();
void showLoginForCurrentDomain();
void bandwidthDetails();
void octreeStatsDetails();
void cachesSizeDialog();
void lodTools();
void hmdTools(bool showTools);
void loadSettings(QSettings* settings = NULL);
void saveSettings(QSettings* settings = NULL);
void importSettings();
void exportSettings();
void toggleAddressBar();
void copyAddress();
void copyPath();
void toggleLoginMenuItem();
void toggleSixense(bool shouldEnable);
QMenu* addMenu(const QString& menuName); QMenu* addMenu(const QString& menuName);
void removeMenu(const QString& menuName); void removeMenu(const QString& menuName);
bool menuExists(const QString& menuName); bool menuExists(const QString& menuName);
@ -193,47 +63,21 @@ public slots:
bool menuItemExists(const QString& menuName, const QString& menuitem); bool menuItemExists(const QString& menuName, const QString& menuitem);
bool isOptionChecked(const QString& menuOption) const; bool isOptionChecked(const QString& menuOption) const;
void setIsOptionChecked(const QString& menuOption, bool isChecked); void setIsOptionChecked(const QString& menuOption, bool isChecked);
private slots:
void aboutApp();
void showEditEntitiesHelp();
void bumpSettings();
void editPreferences();
void editAttachments();
void editAnimations();
void changePrivateKey();
void bookmarkLocation();
void teleportToBookmark();
void deleteBookmark();
void hmdToolsClosed();
void runTests();
void showMetavoxelEditor();
void showMetavoxelNetworkSimulator();
void showScriptEditor();
void showChat();
void toggleConsole();
void toggleToolWindow();
void toggleChat();
void audioMuteToggled();
void displayNameLocationResponse(const QString& errorString);
void changeVSync();
void loadRSSDKFile();
private: private:
static Menu* _instance; static Menu* _instance;
Menu(); Menu();
typedef void(*settingsAction)(QSettings*, QAction*); typedef void(*settingsAction)(Settings&, QAction&);
static void loadAction(QSettings* set, QAction* action); static void loadAction(Settings& settings, QAction& action);
static void saveAction(QSettings* set, QAction* action); static void saveAction(Settings& settings, QAction& action);
void scanMenuBar(settingsAction modifySetting, QSettings* set); void scanMenuBar(settingsAction modifySetting);
void scanMenu(QMenu* menu, settingsAction modifySetting, QSettings* set); void scanMenu(QMenu& menu, settingsAction modifySetting, Settings& settings);
/// helper method to have separators with labels that are also compatible with OS X /// helper method to have separators with labels that are also compatible with OS X
void addDisabledActionAndSeparator(QMenu* destinationMenu, const QString& actionName, void addDisabledActionAndSeparator(QMenu* destinationMenu, const QString& actionName,
int menuItemLocation = UNSPECIFIED_POSITION); int menuItemLocation = UNSPECIFIED_POSITION);
QAction* addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu, QAction* addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu,
const QString& actionName, const QString& actionName,
const QKeySequence& shortcut = 0, const QKeySequence& shortcut = 0,
@ -241,78 +85,17 @@ private:
const QObject* receiver = NULL, const QObject* receiver = NULL,
const char* member = NULL, const char* member = NULL,
int menuItemLocation = UNSPECIFIED_POSITION); int menuItemLocation = UNSPECIFIED_POSITION);
QAction* getActionFromName(const QString& menuName, QMenu* menu); QAction* getActionFromName(const QString& menuName, QMenu* menu);
QMenu* getSubMenuFromName(const QString& menuName, QMenu* menu); QMenu* getSubMenuFromName(const QString& menuName, QMenu* menu);
QMenu* getMenuParent(const QString& menuName, QString& finalMenuPart); QMenu* getMenuParent(const QString& menuName, QString& finalMenuPart);
QAction* getMenuAction(const QString& menuName); QAction* getMenuAction(const QString& menuName);
int findPositionOfMenuItem(QMenu* menu, const QString& searchMenuItem); int findPositionOfMenuItem(QMenu* menu, const QString& searchMenuItem);
int positionBeforeSeparatorIfNeeded(QMenu* menu, int requestedPosition); int positionBeforeSeparatorIfNeeded(QMenu* menu, int requestedPosition);
QMenu* getMenu(const QString& menuName);
QHash<QString, QAction*> _actionHash; QHash<QString, QAction*> _actionHash;
InboundAudioStream::Settings _receivedAudioStreamSettings;
// in Degrees, doesn't apply to HMD like Oculus
float _fieldOfView = DEFAULT_FIELD_OF_VIEW_DEGREES;
// The actual FOV set by the user's monitor size and view distance
float _realWorldFieldOfView = DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES;
float _faceshiftEyeDeflection = DEFAULT_FACESHIFT_EYE_DEFLECTION;
QString _faceshiftHostname = DEFAULT_FACESHIFT_HOSTNAME;
QDialog* _jsConsole = nullptr;
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
SpeechRecognizer _speechRecognizer;
#endif
float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
float _oculusUIAngularSize = DEFAULT_OCULUS_UI_ANGULAR_SIZE;
float _sixenseReticleMoveSpeed = DEFAULT_SIXENSE_RETICLE_MOVE_SPEED;
bool _invertSixenseButtons = DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS;
bool _hasLoginDialogDisplayed = false;
bool _automaticAvatarLOD = true;
float _avatarLODDecreaseFPS = DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS;
float _avatarLODIncreaseFPS = ADJUST_LOD_UP_FPS;
float _avatarLODDistanceMultiplier = DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER;
int _boundaryLevelAdjust = 0;
int _maxOctreePacketsPerSecond = DEFAULT_MAX_OCTREE_PPS;
quint64 _lastAdjust;
quint64 _lastAvatarDetailDrop;
SimpleMovingAverage _fpsAverage = FIVE_SECONDS_OF_FRAMES;
SimpleMovingAverage _fastFPSAverage = ONE_SECOND_OF_FRAMES;
QPointer<AddressBarDialog> _addressBarDialog;
QPointer<AnimationsDialog> _animationsDialog;
QPointer<AttachmentsDialog> _attachmentsDialog;
QPointer<BandwidthDialog> _bandwidthDialog;
QPointer<CachesSizeDialog> _cachesSizeDialog;
QPointer<HMDToolsDialog> _hmdToolsDialog;
QPointer<LodToolsDialog> _lodToolsDialog;
QPointer<LoginDialog> _loginDialog;
QPointer<OctreeStatsDialog> _octreeStatsDialog;
QPointer<PreferencesDialog> _preferencesDialog;
QPointer<MetavoxelEditor> _MetavoxelEditor;
QPointer<MetavoxelNetworkSimulator> _metavoxelNetworkSimulator;
QPointer<ScriptEditorWindow> _ScriptEditor;
QPointer<ChatWindow> _chatWindow;
QAction* _loginAction = nullptr;
QAction* _chatAction = nullptr;
QString _snapshotsLocation;
QString _scriptsLocation;
QByteArray _walletPrivateKey;
bool _shouldRenderTableNeedsRebuilding = true;
QMap<float, float> _shouldRenderTable;
void loadBookmarks();
QMenu* _bookmarksMenu;
QAction* _deleteBookmarksMenu;
}; };
namespace MenuOption { namespace MenuOption {
@ -402,7 +185,6 @@ namespace MenuOption {
const QString LodTools = "LOD Tools"; const QString LodTools = "LOD Tools";
const QString Login = "Login"; const QString Login = "Login";
const QString Log = "Log"; const QString Log = "Log";
const QString Logout = "Logout";
const QString LowVelocityFilter = "Low Velocity Filter"; const QString LowVelocityFilter = "Low Velocity Filter";
const QString MetavoxelEditor = "Metavoxel Editor..."; const QString MetavoxelEditor = "Metavoxel Editor...";
const QString Metavoxels = "Metavoxels"; const QString Metavoxels = "Metavoxels";
@ -484,10 +266,7 @@ namespace MenuOption {
const QString UploadSkeleton = "Upload Skeleton Model"; const QString UploadSkeleton = "Upload Skeleton Model";
const QString UserInterface = "User Interface"; const QString UserInterface = "User Interface";
const QString Visage = "Visage"; const QString Visage = "Visage";
const QString WalletPrivateKey = "Wallet Private Key...";
const QString Wireframe = "Wireframe"; const QString Wireframe = "Wireframe";
} }
void sendFakeEnterEvent();
#endif // hifi_Menu_h #endif // hifi_Menu_h

View file

@ -9,6 +9,7 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include <QBuffer>
#include <QCheckBox> #include <QCheckBox>
#include <QComboBox> #include <QComboBox>
#include <QDebug> #include <QDebug>
@ -21,6 +22,7 @@
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QHttpMultiPart> #include <QHttpMultiPart>
#include <QImage> #include <QImage>
#include <QJsonDocument>
#include <QLineEdit> #include <QLineEdit>
#include <QMessageBox> #include <QMessageBox>
#include <QProgressBar> #include <QProgressBar>
@ -28,12 +30,17 @@
#include <QStandardPaths> #include <QStandardPaths>
#include <QTemporaryFile> #include <QTemporaryFile>
#include <QTextStream> #include <QTextStream>
#include <QThread>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QVariant> #include <QVariant>
#include <AccountManager.h> #include <AccountManager.h>
#include <GeometryCache.h>
#include <GLMHelpers.h>
#include <ResourceCache.h>
#include <Settings.h>
#include <TextureCache.h>
#include "Application.h"
#include "ModelUploader.h" #include "ModelUploader.h"
@ -53,8 +60,6 @@ static const QString BLENDSHAPE_FIELD = "bs";
static const QString S3_URL = "http://public.highfidelity.io"; static const QString S3_URL = "http://public.highfidelity.io";
static const QString MODEL_URL = "/api/v1/models"; static const QString MODEL_URL = "/api/v1/models";
static const QString SETTING_NAME = "LastModelUploadLocation";
static const unsigned long long MAX_SIZE = 50 * 1024 * BYTES_PER_MEGABYTES; // 50 GB (Virtually remove limit) static const unsigned long long MAX_SIZE = 50 * 1024 * BYTES_PER_MEGABYTES; // 50 GB (Virtually remove limit)
static const int MAX_TEXTURE_SIZE = 1024; static const int MAX_TEXTURE_SIZE = 1024;
static const int TIMEOUT = 1000; static const int TIMEOUT = 1000;
@ -63,6 +68,11 @@ static const int MAX_CHECK = 30;
static const int QCOMPRESS_HEADER_POSITION = 0; static const int QCOMPRESS_HEADER_POSITION = 0;
static const int QCOMPRESS_HEADER_SIZE = 4; static const int QCOMPRESS_HEADER_SIZE = 4;
namespace SettingHandles {
const SettingHandle<QString> lastModelUploadLocation("LastModelUploadLocation",
QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
}
void ModelUploader::uploadModel(ModelType modelType) { void ModelUploader::uploadModel(ModelType modelType) {
ModelUploader* uploader = new ModelUploader(modelType); ModelUploader* uploader = new ModelUploader(modelType);
QThread* thread = new QThread(); QThread* thread = new QThread();
@ -107,8 +117,7 @@ ModelUploader::~ModelUploader() {
bool ModelUploader::zip() { bool ModelUploader::zip() {
// File Dialog // File Dialog
QSettings* settings = Application::getInstance()->lockSettings(); QString lastLocation = SettingHandles::lastModelUploadLocation.get();
QString lastLocation = settings->value(SETTING_NAME).toString();
if (lastLocation.isEmpty()) { if (lastLocation.isEmpty()) {
lastLocation = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); lastLocation = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
@ -123,11 +132,9 @@ bool ModelUploader::zip() {
lastLocation, "Model files (*.fst *.fbx)"); lastLocation, "Model files (*.fst *.fbx)");
if (filename == "") { if (filename == "") {
// If the user canceled we return. // If the user canceled we return.
Application::getInstance()->unlockSettings();
return false; return false;
} }
settings->setValue(SETTING_NAME, filename); SettingHandles::lastModelUploadLocation.set(filename);
Application::getInstance()->unlockSettings();
// First we check the FST file (if any) // First we check the FST file (if any)
QFile* fst; QFile* fst;

View file

@ -17,6 +17,7 @@
#include <NetworkAccessManager.h> #include <NetworkAccessManager.h>
#include "Application.h"
#include "Menu.h" #include "Menu.h"
#include "ScriptsModel.h" #include "ScriptsModel.h"
@ -33,8 +34,8 @@ static const QString KEY_NAME = "Key";
TreeNodeBase::TreeNodeBase(TreeNodeFolder* parent, const QString& name, TreeNodeType type) : TreeNodeBase::TreeNodeBase(TreeNodeFolder* parent, const QString& name, TreeNodeType type) :
_parent(parent), _parent(parent),
_name(name), _type(type),
_type(type) { _name(name) {
}; };
TreeNodeScript::TreeNodeScript(const QString& localPath, const QString& fullPath, ScriptOrigin origin) : TreeNodeScript::TreeNodeScript(const QString& localPath, const QString& fullPath, ScriptOrigin origin) :
@ -58,10 +59,10 @@ ScriptsModel::ScriptsModel(QObject* parent) :
_localDirectory.setFilter(QDir::Files | QDir::Readable); _localDirectory.setFilter(QDir::Files | QDir::Readable);
_localDirectory.setNameFilters(QStringList("*.js")); _localDirectory.setNameFilters(QStringList("*.js"));
updateScriptsLocation(Menu::getInstance()->getScriptsLocation()); updateScriptsLocation(qApp->getScriptsLocation());
connect(&_fsWatcher, &QFileSystemWatcher::directoryChanged, this, &ScriptsModel::reloadLocalFiles); connect(&_fsWatcher, &QFileSystemWatcher::directoryChanged, this, &ScriptsModel::reloadLocalFiles);
connect(Menu::getInstance(), &Menu::scriptLocationChanged, this, &ScriptsModel::updateScriptsLocation); connect(qApp, &Application::scriptLocationChanged, this, &ScriptsModel::updateScriptsLocation);
reloadLocalFiles(); reloadLocalFiles();
reloadRemoteFiles(); reloadRemoteFiles();

View file

@ -20,12 +20,13 @@
#include <QWinEventNotifier> #include <QWinEventNotifier>
#endif #endif
class SpeechRecognizer : public QObject { #include <DependencyManager.h>
Q_OBJECT
public:
SpeechRecognizer();
~SpeechRecognizer();
class SpeechRecognizer : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
public:
void handleCommandRecognized(const char* command); void handleCommandRecognized(const char* command);
bool getEnabled() const { return _enabled; } bool getEnabled() const { return _enabled; }
@ -42,6 +43,9 @@ protected:
void reloadCommands(); void reloadCommands();
private: private:
SpeechRecognizer();
virtual ~SpeechRecognizer();
bool _enabled; bool _enabled;
QSet<QString> _commands; QSet<QString> _commands;
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)

View file

@ -238,14 +238,6 @@ void runTimingTests() {
qDebug("vec3 assign and dot() usecs: %f, last result:%f", elapsedUsecs / (float) numTests, result); qDebug("vec3 assign and dot() usecs: %f, last result:%f", elapsedUsecs / (float) numTests, result);
} }
float loadSetting(QSettings* settings, const char* name, float defaultValue) {
float value = settings->value(name, defaultValue).toFloat();
if (glm::isnan(value)) {
value = defaultValue;
}
return value;
}
bool rayIntersectsSphere(const glm::vec3& rayStarting, const glm::vec3& rayNormalizedDirection, bool rayIntersectsSphere(const glm::vec3& rayStarting, const glm::vec3& rayNormalizedDirection,
const glm::vec3& sphereCenter, float sphereRadius, float& distance) { const glm::vec3& sphereCenter, float sphereRadius, float& distance) {
glm::vec3 relativeOrigin = rayStarting - sphereCenter; glm::vec3 relativeOrigin = rayStarting - sphereCenter;

View file

@ -31,8 +31,6 @@ void renderBevelCornersRect(int x, int y, int width, int height, int bevelDistan
void runTimingTests(); void runTimingTests();
float loadSetting(QSettings* settings, const char* name, float defaultValue);
bool rayIntersectsSphere(const glm::vec3& rayStarting, const glm::vec3& rayNormalizedDirection, bool rayIntersectsSphere(const glm::vec3& rayStarting, const glm::vec3& rayNormalizedDirection,
const glm::vec3& sphereCenter, float sphereRadius, float& distance); const glm::vec3& sphereCenter, float sphereRadius, float& distance);

View file

@ -25,6 +25,7 @@
#include <DeferredLightingEffect.h> #include <DeferredLightingEffect.h>
#include <GeometryUtil.h> #include <GeometryUtil.h>
#include <GlowEffect.h> #include <GlowEffect.h>
#include <LODManager.h>
#include <NodeList.h> #include <NodeList.h>
#include <PacketHeaders.h> #include <PacketHeaders.h>
#include <PathUtils.h> #include <PathUtils.h>
@ -114,8 +115,8 @@ glm::quat Avatar::getWorldAlignedOrientation () const {
} }
float Avatar::getLODDistance() const { float Avatar::getLODDistance() const {
return Menu::getInstance()->getAvatarLODDistanceMultiplier() * return DependencyManager::get<LODManager>()->getAvatarLODDistanceMultiplier() *
glm::distance(Application::getInstance()->getCamera()->getPosition(), _position) / _scale; glm::distance(qApp->getCamera()->getPosition(), _position) / _scale;
} }
void Avatar::simulate(float deltaTime) { void Avatar::simulate(float deltaTime) {

View file

@ -28,6 +28,7 @@
#include <NodeList.h> #include <NodeList.h>
#include <PacketHeaders.h> #include <PacketHeaders.h>
#include <PerfStat.h> #include <PerfStat.h>
#include <Settings.h>
#include <ShapeCollider.h> #include <ShapeCollider.h>
#include <SharedUtil.h> #include <SharedUtil.h>
#include <TextRenderer.h> #include <TextRenderer.h>
@ -338,7 +339,8 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
head->setDeltaPitch(estimatedRotation.x); head->setDeltaPitch(estimatedRotation.x);
head->setDeltaYaw(estimatedRotation.y); head->setDeltaYaw(estimatedRotation.y);
} else { } else {
float magnifyFieldOfView = Menu::getInstance()->getFieldOfView() / Menu::getInstance()->getRealWorldFieldOfView(); float magnifyFieldOfView = qApp->getViewFrustum()->getFieldOfView() /
qApp->getViewFrustum()->getRealWorldFieldOfView();
head->setDeltaPitch(estimatedRotation.x * magnifyFieldOfView); head->setDeltaPitch(estimatedRotation.x * magnifyFieldOfView);
head->setDeltaYaw(estimatedRotation.y * magnifyFieldOfView); head->setDeltaYaw(estimatedRotation.y * magnifyFieldOfView);
} }
@ -677,60 +679,70 @@ AnimationDetails MyAvatar::getAnimationDetails(const QString& url) {
return result; return result;
} }
void MyAvatar::saveData(QSettings* settings) { void MyAvatar::saveData() {
settings->beginGroup("Avatar"); Settings settings;
settings.beginGroup("Avatar");
settings->setValue("headPitch", getHead()->getBasePitch()); settings.setValue("headPitch", getHead()->getBasePitch());
settings->setValue("pupilDilation", getHead()->getPupilDilation()); settings.setValue("pupilDilation", getHead()->getPupilDilation());
settings->setValue("leanScale", _leanScale); settings.setValue("leanScale", _leanScale);
settings->setValue("scale", _targetScale); settings.setValue("scale", _targetScale);
settings->setValue("faceModelURL", _faceModelURL); settings.setValue("faceModelURL", _faceModelURL);
settings->setValue("skeletonModelURL", _skeletonModelURL); settings.setValue("skeletonModelURL", _skeletonModelURL);
settings->beginWriteArray("attachmentData"); settings.beginWriteArray("attachmentData");
for (int i = 0; i < _attachmentData.size(); i++) { for (int i = 0; i < _attachmentData.size(); i++) {
settings->setArrayIndex(i); settings.setArrayIndex(i);
const AttachmentData& attachment = _attachmentData.at(i); const AttachmentData& attachment = _attachmentData.at(i);
settings->setValue("modelURL", attachment.modelURL); settings.setValue("modelURL", attachment.modelURL);
settings->setValue("jointName", attachment.jointName); settings.setValue("jointName", attachment.jointName);
settings->setValue("translation_x", attachment.translation.x); settings.setValue("translation_x", attachment.translation.x);
settings->setValue("translation_y", attachment.translation.y); settings.setValue("translation_y", attachment.translation.y);
settings->setValue("translation_z", attachment.translation.z); settings.setValue("translation_z", attachment.translation.z);
glm::vec3 eulers = safeEulerAngles(attachment.rotation); glm::vec3 eulers = safeEulerAngles(attachment.rotation);
settings->setValue("rotation_x", eulers.x); settings.setValue("rotation_x", eulers.x);
settings->setValue("rotation_y", eulers.y); settings.setValue("rotation_y", eulers.y);
settings->setValue("rotation_z", eulers.z); settings.setValue("rotation_z", eulers.z);
settings->setValue("scale", attachment.scale); settings.setValue("scale", attachment.scale);
} }
settings->endArray(); settings.endArray();
settings->beginWriteArray("animationHandles"); settings.beginWriteArray("animationHandles");
for (int i = 0; i < _animationHandles.size(); i++) { for (int i = 0; i < _animationHandles.size(); i++) {
settings->setArrayIndex(i); settings.setArrayIndex(i);
const AnimationHandlePointer& pointer = _animationHandles.at(i); const AnimationHandlePointer& pointer = _animationHandles.at(i);
settings->setValue("role", pointer->getRole()); settings.setValue("role", pointer->getRole());
settings->setValue("url", pointer->getURL()); settings.setValue("url", pointer->getURL());
settings->setValue("fps", pointer->getFPS()); settings.setValue("fps", pointer->getFPS());
settings->setValue("priority", pointer->getPriority()); settings.setValue("priority", pointer->getPriority());
settings->setValue("loop", pointer->getLoop()); settings.setValue("loop", pointer->getLoop());
settings->setValue("hold", pointer->getHold()); settings.setValue("hold", pointer->getHold());
settings->setValue("startAutomatically", pointer->getStartAutomatically()); settings.setValue("startAutomatically", pointer->getStartAutomatically());
settings->setValue("firstFrame", pointer->getFirstFrame()); settings.setValue("firstFrame", pointer->getFirstFrame());
settings->setValue("lastFrame", pointer->getLastFrame()); settings.setValue("lastFrame", pointer->getLastFrame());
settings->setValue("maskedJoints", pointer->getMaskedJoints()); settings.setValue("maskedJoints", pointer->getMaskedJoints());
} }
settings->endArray(); settings.endArray();
settings->setValue("displayName", _displayName); settings.setValue("displayName", _displayName);
settings->endGroup(); settings.endGroup();
} }
void MyAvatar::loadData(QSettings* settings) { float loadSetting(QSettings& settings, const char* name, float defaultValue) {
settings->beginGroup("Avatar"); float value = settings.value(name, defaultValue).toFloat();
if (glm::isnan(value)) {
value = defaultValue;
}
return value;
}
void MyAvatar::loadData() {
Settings settings;
settings.beginGroup("Avatar");
getHead()->setBasePitch(loadSetting(settings, "headPitch", 0.0f)); getHead()->setBasePitch(loadSetting(settings, "headPitch", 0.0f));
@ -741,16 +753,16 @@ void MyAvatar::loadData(QSettings* settings) {
setScale(_scale); setScale(_scale);
Application::getInstance()->getCamera()->setScale(_scale); Application::getInstance()->getCamera()->setScale(_scale);
setFaceModelURL(settings->value("faceModelURL", DEFAULT_HEAD_MODEL_URL).toUrl()); setFaceModelURL(settings.value("faceModelURL", DEFAULT_HEAD_MODEL_URL).toUrl());
setSkeletonModelURL(settings->value("skeletonModelURL").toUrl()); setSkeletonModelURL(settings.value("skeletonModelURL").toUrl());
QVector<AttachmentData> attachmentData; QVector<AttachmentData> attachmentData;
int attachmentCount = settings->beginReadArray("attachmentData"); int attachmentCount = settings.beginReadArray("attachmentData");
for (int i = 0; i < attachmentCount; i++) { for (int i = 0; i < attachmentCount; i++) {
settings->setArrayIndex(i); settings.setArrayIndex(i);
AttachmentData attachment; AttachmentData attachment;
attachment.modelURL = settings->value("modelURL").toUrl(); attachment.modelURL = settings.value("modelURL").toUrl();
attachment.jointName = settings->value("jointName").toString(); attachment.jointName = settings.value("jointName").toString();
attachment.translation.x = loadSetting(settings, "translation_x", 0.0f); attachment.translation.x = loadSetting(settings, "translation_x", 0.0f);
attachment.translation.y = loadSetting(settings, "translation_y", 0.0f); attachment.translation.y = loadSetting(settings, "translation_y", 0.0f);
attachment.translation.z = loadSetting(settings, "translation_z", 0.0f); attachment.translation.z = loadSetting(settings, "translation_z", 0.0f);
@ -762,10 +774,10 @@ void MyAvatar::loadData(QSettings* settings) {
attachment.scale = loadSetting(settings, "scale", 1.0f); attachment.scale = loadSetting(settings, "scale", 1.0f);
attachmentData.append(attachment); attachmentData.append(attachment);
} }
settings->endArray(); settings.endArray();
setAttachmentData(attachmentData); setAttachmentData(attachmentData);
int animationCount = settings->beginReadArray("animationHandles"); int animationCount = settings.beginReadArray("animationHandles");
while (_animationHandles.size() > animationCount) { while (_animationHandles.size() > animationCount) {
_animationHandles.takeLast()->stop(); _animationHandles.takeLast()->stop();
} }
@ -773,65 +785,64 @@ void MyAvatar::loadData(QSettings* settings) {
addAnimationHandle(); addAnimationHandle();
} }
for (int i = 0; i < animationCount; i++) { for (int i = 0; i < animationCount; i++) {
settings->setArrayIndex(i); settings.setArrayIndex(i);
const AnimationHandlePointer& handle = _animationHandles.at(i); const AnimationHandlePointer& handle = _animationHandles.at(i);
handle->setRole(settings->value("role", "idle").toString()); handle->setRole(settings.value("role", "idle").toString());
handle->setURL(settings->value("url").toUrl()); handle->setURL(settings.value("url").toUrl());
handle->setFPS(loadSetting(settings, "fps", 30.0f)); handle->setFPS(loadSetting(settings, "fps", 30.0f));
handle->setPriority(loadSetting(settings, "priority", 1.0f)); handle->setPriority(loadSetting(settings, "priority", 1.0f));
handle->setLoop(settings->value("loop", true).toBool()); handle->setLoop(settings.value("loop", true).toBool());
handle->setHold(settings->value("hold", false).toBool()); handle->setHold(settings.value("hold", false).toBool());
handle->setStartAutomatically(settings->value("startAutomatically", true).toBool()); handle->setStartAutomatically(settings.value("startAutomatically", true).toBool());
handle->setFirstFrame(settings->value("firstFrame", 0.0f).toFloat()); handle->setFirstFrame(settings.value("firstFrame", 0.0f).toFloat());
handle->setLastFrame(settings->value("lastFrame", INT_MAX).toFloat()); handle->setLastFrame(settings.value("lastFrame", INT_MAX).toFloat());
handle->setMaskedJoints(settings->value("maskedJoints").toStringList()); handle->setMaskedJoints(settings.value("maskedJoints").toStringList());
} }
settings->endArray(); settings.endArray();
setDisplayName(settings->value("displayName").toString()); setDisplayName(settings.value("displayName").toString());
settings->endGroup(); settings.endGroup();
} }
void MyAvatar::saveAttachmentData(const AttachmentData& attachment) const { void MyAvatar::saveAttachmentData(const AttachmentData& attachment) const {
QSettings* settings = Application::getInstance()->lockSettings(); Settings settings;
settings->beginGroup("savedAttachmentData"); settings.beginGroup("savedAttachmentData");
settings->beginGroup(_skeletonModel.getURL().toString()); settings.beginGroup(_skeletonModel.getURL().toString());
settings->beginGroup(attachment.modelURL.toString()); settings.beginGroup(attachment.modelURL.toString());
settings->setValue("jointName", attachment.jointName); settings.setValue("jointName", attachment.jointName);
settings->beginGroup(attachment.jointName); settings.beginGroup(attachment.jointName);
settings->setValue("translation_x", attachment.translation.x); settings.setValue("translation_x", attachment.translation.x);
settings->setValue("translation_y", attachment.translation.y); settings.setValue("translation_y", attachment.translation.y);
settings->setValue("translation_z", attachment.translation.z); settings.setValue("translation_z", attachment.translation.z);
glm::vec3 eulers = safeEulerAngles(attachment.rotation); glm::vec3 eulers = safeEulerAngles(attachment.rotation);
settings->setValue("rotation_x", eulers.x); settings.setValue("rotation_x", eulers.x);
settings->setValue("rotation_y", eulers.y); settings.setValue("rotation_y", eulers.y);
settings->setValue("rotation_z", eulers.z); settings.setValue("rotation_z", eulers.z);
settings->setValue("scale", attachment.scale); settings.setValue("scale", attachment.scale);
settings->endGroup(); settings.endGroup();
settings->endGroup(); settings.endGroup();
settings->endGroup(); settings.endGroup();
settings->endGroup(); settings.endGroup();
Application::getInstance()->unlockSettings();
} }
AttachmentData MyAvatar::loadAttachmentData(const QUrl& modelURL, const QString& jointName) const { AttachmentData MyAvatar::loadAttachmentData(const QUrl& modelURL, const QString& jointName) const {
QSettings* settings = Application::getInstance()->lockSettings(); Settings settings;
settings->beginGroup("savedAttachmentData"); settings.beginGroup("savedAttachmentData");
settings->beginGroup(_skeletonModel.getURL().toString()); settings.beginGroup(_skeletonModel.getURL().toString());
settings->beginGroup(modelURL.toString()); settings.beginGroup(modelURL.toString());
AttachmentData attachment; AttachmentData attachment;
attachment.modelURL = modelURL; attachment.modelURL = modelURL;
if (jointName.isEmpty()) { if (jointName.isEmpty()) {
attachment.jointName = settings->value("jointName").toString(); attachment.jointName = settings.value("jointName").toString();
} else { } else {
attachment.jointName = jointName; attachment.jointName = jointName;
} }
settings->beginGroup(attachment.jointName); settings.beginGroup(attachment.jointName);
if (settings->contains("translation_x")) { if (settings.contains("translation_x")) {
attachment.translation.x = loadSetting(settings, "translation_x", 0.0f); attachment.translation.x = loadSetting(settings, "translation_x", 0.0f);
attachment.translation.y = loadSetting(settings, "translation_y", 0.0f); attachment.translation.y = loadSetting(settings, "translation_y", 0.0f);
attachment.translation.z = loadSetting(settings, "translation_z", 0.0f); attachment.translation.z = loadSetting(settings, "translation_z", 0.0f);
@ -845,11 +856,10 @@ AttachmentData MyAvatar::loadAttachmentData(const QUrl& modelURL, const QString&
attachment = AttachmentData(); attachment = AttachmentData();
} }
settings->endGroup(); settings.endGroup();
settings->endGroup(); settings.endGroup();
settings->endGroup(); settings.endGroup();
settings->endGroup(); settings.endGroup();
Application::getInstance()->unlockSettings();
return attachment; return attachment;
} }

View file

@ -78,8 +78,8 @@ public:
Q_INVOKABLE AnimationDetails getAnimationDetails(const QString& url); Q_INVOKABLE AnimationDetails getAnimationDetails(const QString& url);
// get/set avatar data // get/set avatar data
void saveData(QSettings* settings); void saveData();
void loadData(QSettings* settings); void loadData();
void saveAttachmentData(const AttachmentData& attachment) const; void saveAttachmentData(const AttachmentData& attachment) const;
AttachmentData loadAttachmentData(const QUrl& modelURL, const QString& jointName = QString()) const; AttachmentData loadAttachmentData(const QUrl& modelURL, const QString& jointName = QString()) const;

View file

@ -11,7 +11,9 @@
#include <QTimer> #include <QTimer>
#include <GLMHelpers.h>
#include <PerfStat.h> #include <PerfStat.h>
#include <Settings.h>
#include <SharedUtil.h> #include <SharedUtil.h>
#include "Faceshift.h" #include "Faceshift.h"
@ -27,6 +29,11 @@ using namespace std;
const quint16 FACESHIFT_PORT = 33433; const quint16 FACESHIFT_PORT = 33433;
float STARTING_FACESHIFT_FRAME_TIME = 0.033f; float STARTING_FACESHIFT_FRAME_TIME = 0.033f;
namespace SettingHandles {
const SettingHandle<float> faceshiftEyeDeflection("faceshiftEyeDeflection", DEFAULT_FACESHIFT_EYE_DEFLECTION);
const SettingHandle<QString> faceshiftHostname("faceshiftHostname", DEFAULT_FACESHIFT_HOSTNAME);
}
Faceshift::Faceshift() : Faceshift::Faceshift() :
_tcpEnabled(true), _tcpEnabled(true),
_tcpRetryCount(0), _tcpRetryCount(0),
@ -66,6 +73,9 @@ Faceshift::Faceshift() :
_udpSocket.bind(FACESHIFT_PORT); _udpSocket.bind(FACESHIFT_PORT);
#endif #endif
_eyeDeflection = SettingHandles::faceshiftEyeDeflection.get();
_hostname = SettingHandles::faceshiftHostname.get();
} }
void Faceshift::init() { void Faceshift::init() {
@ -159,7 +169,7 @@ void Faceshift::connectSocket() {
qDebug("Faceshift: Connecting..."); qDebug("Faceshift: Connecting...");
} }
_tcpSocket.connectToHost(Menu::getInstance()->getFaceshiftHostname(), FACESHIFT_PORT); _tcpSocket.connectToHost(_hostname, FACESHIFT_PORT);
_tracking = false; _tracking = false;
} }
} }
@ -309,3 +319,13 @@ void Faceshift::receive(const QByteArray& buffer) {
} }
#endif #endif
} }
void Faceshift::setEyeDeflection(float faceshiftEyeDeflection) {
_eyeDeflection = faceshiftEyeDeflection;
SettingHandles::faceshiftEyeDeflection.set(_eyeDeflection);
}
void Faceshift::setHostname(const QString& hostname) {
_hostname = hostname;
SettingHandles::faceshiftHostname.set(_hostname);
}

View file

@ -61,6 +61,12 @@ public:
float getMouthSize() const { return getBlendshapeCoefficient(_jawOpenIndex); } float getMouthSize() const { return getBlendshapeCoefficient(_jawOpenIndex); }
float getMouthSmileLeft() const { return getBlendshapeCoefficient(_mouthSmileLeftIndex); } float getMouthSmileLeft() const { return getBlendshapeCoefficient(_mouthSmileLeftIndex); }
float getMouthSmileRight() const { return getBlendshapeCoefficient(_mouthSmileRightIndex); } float getMouthSmileRight() const { return getBlendshapeCoefficient(_mouthSmileRightIndex); }
float getEyeDeflection() const { return _eyeDeflection; }
void setEyeDeflection(float faceshiftEyeDeflection);
const QString& getHostname() const { return _hostname; }
void setHostname(const QString& hostname);
void update(); void update();
void reset(); void reset();
@ -145,6 +151,9 @@ private:
float _longTermAverageEyeYaw; float _longTermAverageEyeYaw;
bool _longTermAverageInitialized; bool _longTermAverageInitialized;
float _eyeDeflection = DEFAULT_FACESHIFT_EYE_DEFLECTION;
QString _hostname = DEFAULT_FACESHIFT_HOSTNAME;
}; };
#endif // hifi_Faceshift_h #endif // hifi_Faceshift_h

View file

@ -8,6 +8,8 @@
// Distributed under the Apache License, Version 2.0. // Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include "Application.h"
#include "RealSense.h" #include "RealSense.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "Menu.h" #include "Menu.h"

View file

@ -40,6 +40,7 @@ public:
virtual void update(); virtual void update();
public slots:
void loadRSSDKFile(); void loadRSSDKFile();
protected: protected:

View file

@ -301,7 +301,16 @@ const float RANGE_MULT = (MAX_PIXEL_RANGE_MULT - MIN_PIXEL_RANGE_MULT) * 0.01;
//Returns a multiplier to be applied to the cursor range for the controllers //Returns a multiplier to be applied to the cursor range for the controllers
float SixenseManager::getCursorPixelRangeMult() const { float SixenseManager::getCursorPixelRangeMult() const {
//scales (0,100) to (MINIMUM_PIXEL_RANGE_MULT, MAXIMUM_PIXEL_RANGE_MULT) //scales (0,100) to (MINIMUM_PIXEL_RANGE_MULT, MAXIMUM_PIXEL_RANGE_MULT)
return Menu::getInstance()->getSixenseReticleMoveSpeed() * RANGE_MULT + MIN_PIXEL_RANGE_MULT; return _reticleMoveSpeed * RANGE_MULT + MIN_PIXEL_RANGE_MULT;
}
void SixenseManager::toggleSixense(bool shouldEnable) {
if (shouldEnable && !isInitialized()) {
initialize();
setFilter(Menu::getInstance()->isOptionChecked(MenuOption::FilterSixense));
setLowVelocityFilter(Menu::getInstance()->isOptionChecked(MenuOption::LowVelocityFilter));
}
setIsEnabled(shouldEnable);
} }
#ifdef HAVE_SIXENSE #ifdef HAVE_SIXENSE
@ -459,7 +468,7 @@ void SixenseManager::emulateMouse(PalmData* palm, int index) {
unsigned int deviceID = index == 0 ? CONTROLLER_0_EVENT : CONTROLLER_1_EVENT; unsigned int deviceID = index == 0 ? CONTROLLER_0_EVENT : CONTROLLER_1_EVENT;
if (Menu::getInstance()->getInvertSixenseButtons()) { if (_invertButtons) {
bumperButton = Qt::LeftButton; bumperButton = Qt::LeftButton;
triggerButton = Qt::RightButton; triggerButton = Qt::RightButton;
} else { } else {

View file

@ -55,8 +55,13 @@ public:
void update(float deltaTime); void update(float deltaTime);
float getCursorPixelRangeMult() const; float getCursorPixelRangeMult() const;
public slots: float getReticleMoveSpeed() const { return _reticleMoveSpeed; }
void setReticleMoveSpeed(float sixenseReticleMoveSpeed) { _reticleMoveSpeed = sixenseReticleMoveSpeed; }
bool getInvertButtons() const { return _invertButtons; }
void setInvertButtons(bool invertSixenseButtons) { _invertButtons = invertSixenseButtons; }
public slots:
void toggleSixense(bool shouldEnable);
void setFilter(bool filter); void setFilter(bool filter);
void setLowVelocityFilter(bool lowVelocityFilter) { _lowVelocityFilter = lowVelocityFilter; }; void setLowVelocityFilter(bool lowVelocityFilter) { _lowVelocityFilter = lowVelocityFilter; };
@ -102,6 +107,9 @@ private:
bool _lowVelocityFilter; bool _lowVelocityFilter;
bool _controllersAtBase; bool _controllersAtBase;
float _reticleMoveSpeed = DEFAULT_SIXENSE_RETICLE_MOVE_SPEED;
bool _invertButtons = DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS;
}; };
#endif // hifi_SixenseManager_h #endif // hifi_SixenseManager_h

View file

@ -8,13 +8,15 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include "Application.h"
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include <QSettings>
#include <QTranslator> #include <QTranslator>
#include <SharedUtil.h> #include <SharedUtil.h>
#include "Application.h"
int main(int argc, const char * argv[]) { int main(int argc, const char * argv[]) {
QElapsedTimer startupTime; QElapsedTimer startupTime;
startupTime.start(); startupTime.start();

View file

@ -9,7 +9,7 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include "Application.h" #include "Audio.h"
#include "AudioDeviceScriptingInterface.h" #include "AudioDeviceScriptingInterface.h"

View file

@ -12,11 +12,11 @@
#ifndef hifi_AudioDeviceScriptingInterface_h #ifndef hifi_AudioDeviceScriptingInterface_h
#define hifi_AudioDeviceScriptingInterface_h #define hifi_AudioDeviceScriptingInterface_h
#include <QDebug>
#include <QObject> #include <QObject>
#include <QString> #include <QString>
#include <QVector>
#include "Application.h" class AudioEffectOptions;
class AudioDeviceScriptingInterface : public QObject { class AudioDeviceScriptingInterface : public QObject {
Q_OBJECT Q_OBJECT

View file

@ -9,7 +9,8 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include "Application.h" #include <Settings.h>
#include "SettingsScriptingInterface.h" #include "SettingsScriptingInterface.h"
@ -19,9 +20,7 @@ SettingsScriptingInterface* SettingsScriptingInterface::getInstance() {
} }
QVariant SettingsScriptingInterface::getValue(const QString& setting) { QVariant SettingsScriptingInterface::getValue(const QString& setting) {
QSettings* settings = Application::getInstance()->lockSettings(); QVariant value = SettingHandles::SettingHandle<QVariant>(setting).get();
QVariant value = settings->value(setting);
Application::getInstance()->unlockSettings();
if (!value.isValid()) { if (!value.isValid()) {
value = ""; value = "";
} }
@ -29,9 +28,7 @@ QVariant SettingsScriptingInterface::getValue(const QString& setting) {
} }
QVariant SettingsScriptingInterface::getValue(const QString& setting, const QVariant& defaultValue) { QVariant SettingsScriptingInterface::getValue(const QString& setting, const QVariant& defaultValue) {
QSettings* settings = Application::getInstance()->lockSettings(); QVariant value = SettingHandles::SettingHandle<QVariant>(setting, defaultValue).get();
QVariant value = settings->value(setting, defaultValue);
Application::getInstance()->unlockSettings();
if (!value.isValid()) { if (!value.isValid()) {
value = ""; value = "";
} }
@ -39,7 +36,5 @@ QVariant SettingsScriptingInterface::getValue(const QString& setting, const QVar
} }
void SettingsScriptingInterface::setValue(const QString& setting, const QVariant& value) { void SettingsScriptingInterface::setValue(const QString& setting, const QVariant& value) {
QSettings* settings = Application::getInstance()->lockSettings(); SettingHandles::SettingHandle<QVariant>(setting).set(value);
settings->setValue(setting, value);
Application::getInstance()->unlockSettings();
} }

View file

@ -15,6 +15,7 @@
#include <QInputDialog> #include <QInputDialog>
#include <QMessageBox> #include <QMessageBox>
#include <QScriptValue> #include <QScriptValue>
#include <QScrollArea>
#include "Application.h" #include "Application.h"
#include "MainWindow.h" #include "MainWindow.h"

View file

@ -21,8 +21,8 @@
const QString ADDRESSBAR_GO_BUTTON_ICON = "images/address-bar-submit.svg"; const QString ADDRESSBAR_GO_BUTTON_ICON = "images/address-bar-submit.svg";
const QString ADDRESSBAR_GO_BUTTON_ACTIVE_ICON = "images/address-bar-submit-active.svg"; const QString ADDRESSBAR_GO_BUTTON_ACTIVE_ICON = "images/address-bar-submit-active.svg";
AddressBarDialog::AddressBarDialog() : AddressBarDialog::AddressBarDialog(QWidget* parent) :
FramelessDialog(Application::getInstance()->getWindow(), 0, FramelessDialog::POSITION_TOP) FramelessDialog(parent, 0, FramelessDialog::POSITION_TOP)
{ {
setAttribute(Qt::WA_DeleteOnClose, false); setAttribute(Qt::WA_DeleteOnClose, false);
setupUI(); setupUI();

View file

@ -23,7 +23,7 @@ class AddressBarDialog : public FramelessDialog {
Q_OBJECT Q_OBJECT
public: public:
AddressBarDialog(); AddressBarDialog(QWidget* parent);
private: private:
void setupUI(); void setupUI();

View file

@ -20,12 +20,18 @@
#include <QScrollArea> #include <QScrollArea>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <Settings.h>
#include "AnimationsDialog.h" #include "AnimationsDialog.h"
#include "Application.h" #include "Application.h"
#include "MainWindow.h" #include "MainWindow.h"
AnimationsDialog::AnimationsDialog() : namespace SettingHandles {
QDialog(Application::getInstance()->getWindow()) { const SettingHandle<QString> animationDirectory("animation_directory", QString());
}
AnimationsDialog::AnimationsDialog(QWidget* parent) :
QDialog(parent) {
setWindowTitle("Edit Animations"); setWindowTitle("Edit Animations");
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
@ -157,14 +163,12 @@ AnimationPanel::AnimationPanel(AnimationsDialog* dialog, const AnimationHandlePo
} }
void AnimationPanel::chooseURL() { void AnimationPanel::chooseURL() {
QString directory = Application::getInstance()->lockSettings()->value("animation_directory").toString(); QString directory = SettingHandles::animationDirectory.get();
Application::getInstance()->unlockSettings();
QString filename = QFileDialog::getOpenFileName(this, "Choose Animation", directory, "Animation files (*.fbx)"); QString filename = QFileDialog::getOpenFileName(this, "Choose Animation", directory, "Animation files (*.fbx)");
if (filename.isEmpty()) { if (filename.isEmpty()) {
return; return;
} }
Application::getInstance()->lockSettings()->setValue("animation_directory", QFileInfo(filename).path()); SettingHandles::animationDirectory.set(QFileInfo(filename).path());
Application::getInstance()->unlockSettings();
_url->setText(QUrl::fromLocalFile(filename).toString()); _url->setText(QUrl::fromLocalFile(filename).toString());
emit _url->returnPressed(); emit _url->returnPressed();
} }

View file

@ -13,6 +13,7 @@
#define hifi_AnimationsDialog_h #define hifi_AnimationsDialog_h
#include <QDialog> #include <QDialog>
#include <QDoubleSpinBox>
#include <QFrame> #include <QFrame>
#include "avatar/MyAvatar.h" #include "avatar/MyAvatar.h"
@ -30,7 +31,7 @@ class AnimationsDialog : public QDialog {
public: public:
AnimationsDialog(); AnimationsDialog(QWidget* parent = nullptr);
virtual void setVisible(bool visible); virtual void setVisible(bool visible);

View file

@ -16,6 +16,7 @@
#include <PathUtils.h> #include <PathUtils.h>
#include <PerfStat.h> #include <PerfStat.h>
#include "Audio.h"
#include "audio/AudioIOStatsRenderer.h" #include "audio/AudioIOStatsRenderer.h"
#include "audio/AudioScope.h" #include "audio/AudioScope.h"
#include "audio/AudioToolBox.h" #include "audio/AudioToolBox.h"
@ -164,7 +165,7 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
Overlays& overlays = application->getOverlays(); Overlays& overlays = application->getOverlays();
auto glCanvas = DependencyManager::get<GLCanvas>(); auto glCanvas = DependencyManager::get<GLCanvas>();
_textureFov = glm::radians(Menu::getInstance()->getOculusUIAngularSize()); _textureFov = glm::radians(_oculusUIAngularSize);
_textureAspectRatio = (float)glCanvas->getDeviceWidth() / (float)glCanvas->getDeviceHeight(); _textureAspectRatio = (float)glCanvas->getDeviceWidth() / (float)glCanvas->getDeviceHeight();
//Handle fading and deactivation/activation of UI //Handle fading and deactivation/activation of UI

View file

@ -20,6 +20,8 @@ const float MAGNIFY_WIDTH = 220.0f;
const float MAGNIFY_HEIGHT = 100.0f; const float MAGNIFY_HEIGHT = 100.0f;
const float MAGNIFY_MULT = 2.0f; const float MAGNIFY_MULT = 2.0f;
const float DEFAULT_OCULUS_UI_ANGULAR_SIZE = 72.0f;
// Handles the drawing of the overlays to the screen // Handles the drawing of the overlays to the screen
class ApplicationOverlay { class ApplicationOverlay {
public: public:
@ -35,6 +37,9 @@ public:
QPoint getPalmClickLocation(const PalmData *palm) const; QPoint getPalmClickLocation(const PalmData *palm) const;
bool calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction, glm::vec3& result) const; bool calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction, glm::vec3& result) const;
float getOculusUIAngularSize() const { return _oculusUIAngularSize; }
void setOculusUIAngularSize(float oculusUIAngularSize) { _oculusUIAngularSize = oculusUIAngularSize; }
// Converter from one frame of reference to another. // Converter from one frame of reference to another.
// Frame of reference: // Frame of reference:
// Screen: Position on the screen (x,y) // Screen: Position on the screen (x,y)
@ -80,6 +85,8 @@ private:
VerticesIndices _vbo; VerticesIndices _vbo;
}; };
float _oculusUIAngularSize = DEFAULT_OCULUS_UI_ANGULAR_SIZE;
void renderReticle(glm::quat orientation, float alpha); void renderReticle(glm::quat orientation, float alpha);
void renderPointers();; void renderPointers();;
void renderMagnifier(glm::vec2 magPos, float sizeMult, bool showBorder); void renderMagnifier(glm::vec2 magPos, float sizeMult, bool showBorder);

View file

@ -22,8 +22,8 @@
#include "AttachmentsDialog.h" #include "AttachmentsDialog.h"
#include "MainWindow.h" #include "MainWindow.h"
AttachmentsDialog::AttachmentsDialog() : AttachmentsDialog::AttachmentsDialog(QWidget* parent) :
QDialog(Application::getInstance()->getWindow()) { QDialog(parent) {
setWindowTitle("Edit Attachments"); setWindowTitle("Edit Attachments");
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);

View file

@ -27,8 +27,7 @@ class AttachmentsDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
AttachmentsDialog(QWidget* parent = nullptr);
AttachmentsDialog();
virtual void setVisible(bool visible); virtual void setVisible(bool visible);

View file

@ -22,6 +22,7 @@
#include <AddressManager.h> #include <AddressManager.h>
#include <AccountManager.h> #include <AccountManager.h>
#include <PathUtils.h> #include <PathUtils.h>
#include <Settings.h>
#include "Application.h" #include "Application.h"
#include "ChatMessageArea.h" #include "ChatMessageArea.h"
@ -41,6 +42,10 @@ const QRegularExpression regexHifiLinks("([#@]\\S+)");
const QString mentionSoundsPath("/mention-sounds/"); const QString mentionSoundsPath("/mention-sounds/");
const QString mentionRegex("@(\\b%1\\b)"); const QString mentionRegex("@(\\b%1\\b)");
namespace SettingHandles {
const SettingHandle<QDateTime> usernameMentionTimestamp("MentionTimestamp", QDateTime());
}
ChatWindow::ChatWindow(QWidget* parent) : ChatWindow::ChatWindow(QWidget* parent) :
QWidget(parent, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | QWidget(parent, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint |
Qt::WindowCloseButtonHint), Qt::WindowCloseButtonHint),
@ -377,12 +382,10 @@ void ChatWindow::messageReceived(const QXmppMessage& message) {
if (message.body().contains(usernameMention)) { if (message.body().contains(usernameMention)) {
// Don't show messages already seen in icon tray at start-up. // Don't show messages already seen in icon tray at start-up.
QSettings* settings = Application::getInstance()->lockSettings(); bool showMessage = SettingHandles::usernameMentionTimestamp.get() < _lastMessageStamp;
bool showMessage = settings->value("usernameMentionTimestamp").toDateTime() < _lastMessageStamp;
if (showMessage) { if (showMessage) {
settings->setValue("usernameMentionTimestamp", _lastMessageStamp); SettingHandles::usernameMentionTimestamp.set(_lastMessageStamp);
} }
Application::getInstance()->unlockSettings();
if (isHidden() && showMessage) { if (isHidden() && showMessage) {

View file

@ -0,0 +1,215 @@
//
// DialogsManager.cpp
//
//
// Created by Clement on 1/18/15.
// 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
//
#include <AccountManager.h>
#include <MainWindow.h>
#include <PathUtils.h>
#include <XmppClient.h>
#include "AddressBarDialog.h"
#include "AnimationsDialog.h"
#include "AttachmentsDialog.h"
#include "BandwidthDialog.h"
#include "CachesSizeDialog.h"
#include "ChatWindow.h"
#include "HMDToolsDialog.h"
#include "LodToolsDialog.h"
#include "LoginDialog.h"
#include "MetavoxelEditor.h"
#include "MetavoxelNetworkSimulator.h"
#include "OctreeStatsDialog.h"
#include "PreferencesDialog.h"
#include "ScriptEditorWindow.h"
#include "DialogsManager.h"
void DialogsManager::toggleAddressBar() {
maybeCreateDialog(_addressBarDialog);
if (!_addressBarDialog->isVisible()) {
_addressBarDialog->show();
}
}
void DialogsManager::toggleLoginDialog() {
maybeCreateDialog(_loginDialog);
_loginDialog->toggleQAction();
}
void DialogsManager::showLoginDialog() {
maybeCreateDialog(_loginDialog);
_loginDialog->showLoginForCurrentDomain();
}
void DialogsManager::octreeStatsDetails() {
if (!_octreeStatsDialog) {
_octreeStatsDialog = new OctreeStatsDialog(qApp->getWindow(), qApp->getOcteeSceneStats());
if (_hmdToolsDialog) {
_hmdToolsDialog->watchWindow(_octreeStatsDialog->windowHandle());
}
connect(_octreeStatsDialog, SIGNAL(closed()), _octreeStatsDialog, SLOT(deleteLater()));
_octreeStatsDialog->show();
}
_octreeStatsDialog->raise();
}
void DialogsManager::cachesSizeDialog() {
qDebug() << "Caches size:" << _cachesSizeDialog.isNull();
if (!_cachesSizeDialog) {
maybeCreateDialog(_cachesSizeDialog);
connect(_cachesSizeDialog, SIGNAL(closed()), _cachesSizeDialog, SLOT(deleteLater()));
_cachesSizeDialog->show();
}
_cachesSizeDialog->raise();
}
void DialogsManager::editPreferences() {
if (!_preferencesDialog) {
maybeCreateDialog(_preferencesDialog);
_preferencesDialog->show();
} else {
_preferencesDialog->close();
}
}
void DialogsManager::editAttachments() {
if (!_attachmentsDialog) {
maybeCreateDialog(_attachmentsDialog);
_attachmentsDialog->show();
} else {
_attachmentsDialog->close();
}
}
void DialogsManager::editAnimations() {
if (!_animationsDialog) {
maybeCreateDialog(_animationsDialog);
_animationsDialog->show();
} else {
_animationsDialog->close();
}
}
void DialogsManager::bandwidthDetails() {
if (! _bandwidthDialog) {
_bandwidthDialog = new BandwidthDialog(qApp->getWindow(), qApp->getBandwidthMeter());
connect(_bandwidthDialog, SIGNAL(closed()), _bandwidthDialog, SLOT(deleteLater()));
if (_hmdToolsDialog) {
_hmdToolsDialog->watchWindow(_bandwidthDialog->windowHandle());
}
_bandwidthDialog->show();
}
_bandwidthDialog->raise();
}
void DialogsManager::lodTools() {
if (!_lodToolsDialog) {
maybeCreateDialog(_lodToolsDialog);
connect(_lodToolsDialog, SIGNAL(closed()), _lodToolsDialog, SLOT(deleteLater()));
_lodToolsDialog->show();
}
_lodToolsDialog->raise();
}
void DialogsManager::toggleToolWindow() {
QMainWindow* toolWindow = qApp->getToolWindow();
toolWindow->setVisible(!toolWindow->isVisible());
}
void DialogsManager::hmdTools(bool showTools) {
if (showTools) {
if (!_hmdToolsDialog) {
maybeCreateDialog(_hmdToolsDialog);
connect(_hmdToolsDialog, SIGNAL(closed()), SLOT(hmdToolsClosed()));
}
_hmdToolsDialog->show();
_hmdToolsDialog->raise();
} else {
hmdToolsClosed();
}
qApp->getWindow()->activateWindow();
}
void DialogsManager::hmdToolsClosed() {
Menu::getInstance()->getActionForOption(MenuOption::HMDTools)->setChecked(false);
_hmdToolsDialog->hide();
}
void DialogsManager::showMetavoxelEditor() {
maybeCreateDialog(_metavoxelEditor);
_metavoxelEditor->raise();
}
void DialogsManager::showMetavoxelNetworkSimulator() {
maybeCreateDialog(_metavoxelNetworkSimulator);
_metavoxelNetworkSimulator->raise();
}
void DialogsManager::showScriptEditor() {
maybeCreateDialog(_scriptEditor);
_scriptEditor->raise();
}
void DialogsManager::setupChat() {
#ifdef HAVE_QXMPP
const QXmppClient& xmppClient = XmppClient::getInstance().getXMPPClient();
connect(&xmppClient, &QXmppClient::connected, this, &DialogsManager::toggleChat);
connect(&xmppClient, &QXmppClient::disconnected, this, &DialogsManager::toggleChat);
QDir::setCurrent(PathUtils::resourcesPath());
// init chat window to listen chat
maybeCreateDialog(_chatWindow);
#endif
}
void DialogsManager::showChat() {
if (AccountManager::getInstance().isLoggedIn()) {
maybeCreateDialog(_chatWindow);
if (_chatWindow->isHidden()) {
_chatWindow->show();
}
_chatWindow->raise();
_chatWindow->activateWindow();
_chatWindow->setFocus();
} else {
qApp->getTrayIcon()->showMessage("Interface",
"You need to login to be able to chat with others on this domain.");
}
}
void DialogsManager::toggleChat() {
#ifdef HAVE_QXMPP
QAction* chatAction = Menu::getInstance()->getActionForOption(MenuOption::Login);
Q_CHECK_PTR(chatAction);
chatAction->setEnabled(XmppClient::getInstance().getXMPPClient().isConnected());
if (!chatAction->isEnabled() && _chatWindow && AccountManager::getInstance().isLoggedIn()) {
if (_chatWindow->isHidden()) {
_chatWindow->show();
_chatWindow->raise();
_chatWindow->activateWindow();
_chatWindow->setFocus();
} else {
_chatWindow->hide();
}
}
#endif
}

View file

@ -0,0 +1,105 @@
//
// DialogsManager.h
//
//
// Created by Clement on 1/18/15.
// 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
//
#ifndef hifi_DialogsManager_h
#define hifi_DialogsManager_h
#include <QPointer>
#include <Application.h>
#include <DependencyManager.h>
#include "HMDToolsDialog.h"
class QAction;
class AddressBarDialog;
class AnimationsDialog;
class AttachmentsDialog;
class CachesSizeDialog;
class ChatWindow;
class BandwidthDialog;
class LodToolsDialog;
class LoginDialog;
class MetavoxelEditor;
class MetavoxelNetworkSimulator;
class OctreeStatsDialog;
class PreferencesDialog;
class ScriptEditorWindow;
class DialogsManager : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
public:
QPointer<BandwidthDialog> getBandwidthDialog() const { return _bandwidthDialog; }
QPointer<HMDToolsDialog> getHMDToolsDialog() const { return _hmdToolsDialog; }
QPointer<LodToolsDialog> getLodToolsDialog() const { return _lodToolsDialog; }
QPointer<OctreeStatsDialog> getOctreeStatsDialog() const { return _octreeStatsDialog; }
void setupChat();
public slots:
void toggleAddressBar();
void toggleLoginDialog();
void showLoginDialog();
void octreeStatsDetails();
void cachesSizeDialog();
void editPreferences();
void editAttachments();
void editAnimations();
void bandwidthDetails();
void lodTools();
void hmdTools(bool showTools);
void showMetavoxelEditor();
void showMetavoxelNetworkSimulator();
void showScriptEditor();
void showChat();
private slots:
void toggleToolWindow();
void hmdToolsClosed();
void toggleChat();
private:
DialogsManager() {}
template<typename T>
void maybeCreateDialog(QPointer<T>& member) {
if (!member) {
MainWindow* parent = qApp->getWindow();
Q_CHECK_PTR(parent);
member = new T(parent);
Q_CHECK_PTR(member);
if (_hmdToolsDialog) {
_hmdToolsDialog->watchWindow(member->windowHandle());
}
}
}
QPointer<AddressBarDialog> _addressBarDialog;
QPointer<AnimationsDialog> _animationsDialog;
QPointer<AttachmentsDialog> _attachmentsDialog;
QPointer<BandwidthDialog> _bandwidthDialog;
QPointer<CachesSizeDialog> _cachesSizeDialog;
QPointer<ChatWindow> _chatWindow;
QPointer<HMDToolsDialog> _hmdToolsDialog;
QPointer<LodToolsDialog> _lodToolsDialog;
QPointer<LoginDialog> _loginDialog;
QPointer<MetavoxelEditor> _metavoxelEditor;
QPointer<MetavoxelNetworkSimulator> _metavoxelNetworkSimulator;
QPointer<OctreeStatsDialog> _octreeStatsDialog;
QPointer<PreferencesDialog> _preferencesDialog;
QPointer<ScriptEditorWindow> _scriptEditor;
};
#endif // hifi_DialogsManager_h

View file

@ -19,11 +19,13 @@
#include <QScreen> #include <QScreen>
#include <QWindow> #include <QWindow>
#include "MainWindow.h" #include "MainWindow.h"
#include "Menu.h" #include "Menu.h"
#include "devices/OculusManager.h" #include "ui/DialogsManager.h"
#include "ui/HMDToolsDialog.h" #include "ui/HMDToolsDialog.h"
#include "devices/OculusManager.h"
HMDToolsDialog::HMDToolsDialog(QWidget* parent) : HMDToolsDialog::HMDToolsDialog(QWidget* parent) :
QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint) , QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint) ,
@ -67,20 +69,21 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) :
// watch for our dialog window moving screens. If it does we want to enforce our rules about // watch for our dialog window moving screens. If it does we want to enforce our rules about
// what screens we're allowed on // what screens we're allowed on
watchWindow(windowHandle()); watchWindow(windowHandle());
auto dialogsManager = DependencyManager::get<DialogsManager>();
if (Application::getInstance()->getRunningScriptsWidget()) { if (Application::getInstance()->getRunningScriptsWidget()) {
watchWindow(Application::getInstance()->getRunningScriptsWidget()->windowHandle()); watchWindow(Application::getInstance()->getRunningScriptsWidget()->windowHandle());
} }
if (Application::getInstance()->getToolWindow()) { if (Application::getInstance()->getToolWindow()) {
watchWindow(Application::getInstance()->getToolWindow()->windowHandle()); watchWindow(Application::getInstance()->getToolWindow()->windowHandle());
} }
if (Menu::getInstance()->getBandwidthDialog()) { if (dialogsManager->getBandwidthDialog()) {
watchWindow(Menu::getInstance()->getBandwidthDialog()->windowHandle()); watchWindow(dialogsManager->getBandwidthDialog()->windowHandle());
} }
if (Menu::getInstance()->getOctreeStatsDialog()) { if (dialogsManager->getOctreeStatsDialog()) {
watchWindow(Menu::getInstance()->getOctreeStatsDialog()->windowHandle()); watchWindow(dialogsManager->getOctreeStatsDialog()->windowHandle());
} }
if (Menu::getInstance()->getLodToolsDialog()) { if (dialogsManager->getLodToolsDialog()) {
watchWindow(Menu::getInstance()->getLodToolsDialog()->windowHandle()); watchWindow(dialogsManager->getLodToolsDialog()->windowHandle());
} }
// when the application is about to quit, leave HDM mode // when the application is about to quit, leave HDM mode

View file

@ -10,18 +10,21 @@
// //
#include <QApplication> #include <QApplication>
#include <QDesktopWidget>
#include <QFileInfo>
#include <QtWebKitWidgets/QWebFrame> #include <QtWebKitWidgets/QWebFrame>
#include <QtWebKit/QWebElement> #include <QtWebKit/QWebElement>
#include <QDesktopWidget>
#include <PathUtils.h> #include <PathUtils.h>
#include <Settings.h>
#include "Application.h"
#include "InfoView.h" #include "InfoView.h"
#define SETTINGS_VERSION_KEY "info-version" static const float MAX_DIALOG_HEIGHT_RATIO = 0.9f;
#define MAX_DIALOG_HEIGHT_RATIO 0.9
namespace SettingHandles {
const SettingHandle<QString> infoVersion("info-version", QString());
}
InfoView::InfoView(bool forced, QString path) : InfoView::InfoView(bool forced, QString path) :
_forced(forced) _forced(forced)
@ -49,20 +52,17 @@ bool InfoView::shouldShow() {
return true; return true;
} }
QSettings* settings = Application::getInstance()->lockSettings(); QString lastVersion = SettingHandles::infoVersion.get();
QString lastVersion = settings->value(SETTINGS_VERSION_KEY).toString();
QWebElement versionTag = page()->mainFrame()->findFirstElement("#version"); QWebElement versionTag = page()->mainFrame()->findFirstElement("#version");
QString version = versionTag.attribute("value"); QString version = versionTag.attribute("value");
if (version != QString::null && (lastVersion == QString::null || lastVersion != version)) { if (version != QString::null && (lastVersion == QString::null || lastVersion != version)) {
settings->setValue(SETTINGS_VERSION_KEY, version); SettingHandles::infoVersion.set(version);
shouldShow = true; shouldShow = true;
} else { } else {
shouldShow = false; shouldShow = false;
} }
Application::getInstance()->unlockSettings();
return shouldShow; return shouldShow;
} }
@ -72,7 +72,7 @@ void InfoView::loaded(bool ok) {
return; return;
} }
QDesktopWidget* desktop = Application::getInstance()->desktop(); QDesktopWidget* desktop = qApp->desktop();
QWebFrame* mainFrame = page()->mainFrame(); QWebFrame* mainFrame = page()->mainFrame();
int height = mainFrame->contentsSize().height() > desktop->height() ? int height = mainFrame->contentsSize().height() > desktop->height() ?

View file

@ -9,17 +9,19 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include <QFormLayout>
#include <QDialogButtonBox>
#include <QPalette>
#include <QCheckBox> #include <QCheckBox>
#include <QColor> #include <QColor>
#include <QDialogButtonBox>
#include <QDoubleSpinBox> #include <QDoubleSpinBox>
#include <QSlider> #include <QFormLayout>
#include <QLabel>
#include <QPalette>
#include <QPushButton> #include <QPushButton>
#include <QSlider>
#include <QString> #include <QString>
#include <LODManager.h>
#include "Menu.h" #include "Menu.h"
#include "ui/LodToolsDialog.h" #include "ui/LodToolsDialog.h"
@ -28,6 +30,7 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint) QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint)
{ {
this->setWindowTitle("LOD Tools"); this->setWindowTitle("LOD Tools");
auto lodManager = DependencyManager::get<LODManager>();
// Create layouter // Create layouter
QFormLayout* form = new QFormLayout(this); QFormLayout* form = new QFormLayout(this);
@ -45,7 +48,7 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
_lodSize->setTickPosition(QSlider::TicksBelow); _lodSize->setTickPosition(QSlider::TicksBelow);
_lodSize->setFixedWidth(SLIDER_WIDTH); _lodSize->setFixedWidth(SLIDER_WIDTH);
_lodSize->setPageStep(PAGE_STEP_LOD_SIZE); _lodSize->setPageStep(PAGE_STEP_LOD_SIZE);
int sliderValue = Menu::getInstance()->getOctreeSizeScale() / TREE_SCALE; int sliderValue = lodManager->getOctreeSizeScale() / TREE_SCALE;
_lodSize->setValue(sliderValue); _lodSize->setValue(sliderValue);
form->addRow("LOD Size Scale:", _lodSize); form->addRow("LOD Size Scale:", _lodSize);
connect(_lodSize,SIGNAL(valueChanged(int)),this,SLOT(sizeScaleValueChanged(int))); connect(_lodSize,SIGNAL(valueChanged(int)),this,SLOT(sizeScaleValueChanged(int)));
@ -60,7 +63,7 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
_boundaryLevelAdjust->setTickInterval(STEP_ADJUST); _boundaryLevelAdjust->setTickInterval(STEP_ADJUST);
_boundaryLevelAdjust->setTickPosition(QSlider::TicksBelow); _boundaryLevelAdjust->setTickPosition(QSlider::TicksBelow);
_boundaryLevelAdjust->setFixedWidth(SLIDER_WIDTH); _boundaryLevelAdjust->setFixedWidth(SLIDER_WIDTH);
sliderValue = Menu::getInstance()->getBoundaryLevelAdjust(); sliderValue = lodManager->getBoundaryLevelAdjust();
_boundaryLevelAdjust->setValue(sliderValue); _boundaryLevelAdjust->setValue(sliderValue);
form->addRow("Boundary Level Adjust:", _boundaryLevelAdjust); form->addRow("Boundary Level Adjust:", _boundaryLevelAdjust);
connect(_boundaryLevelAdjust,SIGNAL(valueChanged(int)),this,SLOT(boundaryLevelValueChanged(int))); connect(_boundaryLevelAdjust,SIGNAL(valueChanged(int)),this,SLOT(boundaryLevelValueChanged(int)));
@ -71,22 +74,22 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
const unsigned redish = 0xfff00000; const unsigned redish = 0xfff00000;
palette.setColor(QPalette::WindowText, QColor::fromRgb(redish)); palette.setColor(QPalette::WindowText, QColor::fromRgb(redish));
_feedback->setPalette(palette); _feedback->setPalette(palette);
_feedback->setText(Menu::getInstance()->getLODFeedbackText()); _feedback->setText(lodManager->getLODFeedbackText());
const int FEEDBACK_WIDTH = 350; const int FEEDBACK_WIDTH = 350;
_feedback->setFixedWidth(FEEDBACK_WIDTH); _feedback->setFixedWidth(FEEDBACK_WIDTH);
form->addRow("You can see... ", _feedback); form->addRow("You can see... ", _feedback);
form->addRow("Automatic Avatar LOD Adjustment:", _automaticAvatarLOD = new QCheckBox(this)); form->addRow("Automatic Avatar LOD Adjustment:", _automaticAvatarLOD = new QCheckBox(this));
_automaticAvatarLOD->setChecked(Menu::getInstance()->getAutomaticAvatarLOD()); _automaticAvatarLOD->setChecked(lodManager->getAutomaticAvatarLOD());
connect(_automaticAvatarLOD, SIGNAL(toggled(bool)), SLOT(updateAvatarLODControls())); connect(_automaticAvatarLOD, SIGNAL(toggled(bool)), SLOT(updateAvatarLODControls()));
form->addRow("Decrease Avatar LOD Below FPS:", _avatarLODDecreaseFPS = new QDoubleSpinBox(this)); form->addRow("Decrease Avatar LOD Below FPS:", _avatarLODDecreaseFPS = new QDoubleSpinBox(this));
_avatarLODDecreaseFPS->setValue(Menu::getInstance()->getAvatarLODDecreaseFPS()); _avatarLODDecreaseFPS->setValue(lodManager->getAvatarLODDecreaseFPS());
_avatarLODDecreaseFPS->setDecimals(0); _avatarLODDecreaseFPS->setDecimals(0);
connect(_avatarLODDecreaseFPS, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues())); connect(_avatarLODDecreaseFPS, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues()));
form->addRow("Increase Avatar LOD Above FPS:", _avatarLODIncreaseFPS = new QDoubleSpinBox(this)); form->addRow("Increase Avatar LOD Above FPS:", _avatarLODIncreaseFPS = new QDoubleSpinBox(this));
_avatarLODIncreaseFPS->setValue(Menu::getInstance()->getAvatarLODIncreaseFPS()); _avatarLODIncreaseFPS->setValue(lodManager->getAvatarLODIncreaseFPS());
_avatarLODIncreaseFPS->setDecimals(0); _avatarLODIncreaseFPS->setDecimals(0);
connect(_avatarLODIncreaseFPS, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues())); connect(_avatarLODIncreaseFPS, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues()));
@ -94,7 +97,7 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
_avatarLOD->setDecimals(3); _avatarLOD->setDecimals(3);
_avatarLOD->setRange(1.0 / MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER, 1.0 / MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER); _avatarLOD->setRange(1.0 / MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER, 1.0 / MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER);
_avatarLOD->setSingleStep(0.001); _avatarLOD->setSingleStep(0.001);
_avatarLOD->setValue(1.0 / Menu::getInstance()->getAvatarLODDistanceMultiplier()); _avatarLOD->setValue(1.0 / lodManager->getAvatarLODDistanceMultiplier());
connect(_avatarLOD, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues())); connect(_avatarLOD, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues()));
// Add a button to reset // Add a button to reset
@ -108,15 +111,17 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
} }
void LodToolsDialog::reloadSliders() { void LodToolsDialog::reloadSliders() {
_lodSize->setValue(Menu::getInstance()->getOctreeSizeScale() / TREE_SCALE); auto lodManager = DependencyManager::get<LODManager>();
_boundaryLevelAdjust->setValue(Menu::getInstance()->getBoundaryLevelAdjust()); _lodSize->setValue(lodManager->getOctreeSizeScale() / TREE_SCALE);
_feedback->setText(Menu::getInstance()->getLODFeedbackText()); _boundaryLevelAdjust->setValue(lodManager->getBoundaryLevelAdjust());
_feedback->setText(lodManager->getLODFeedbackText());
} }
void LodToolsDialog::updateAvatarLODControls() { void LodToolsDialog::updateAvatarLODControls() {
QFormLayout* form = static_cast<QFormLayout*>(layout()); QFormLayout* form = static_cast<QFormLayout*>(layout());
Menu::getInstance()->setAutomaticAvatarLOD(_automaticAvatarLOD->isChecked()); auto lodManager = DependencyManager::get<LODManager>();
lodManager->setAutomaticAvatarLOD(_automaticAvatarLOD->isChecked());
_avatarLODDecreaseFPS->setVisible(_automaticAvatarLOD->isChecked()); _avatarLODDecreaseFPS->setVisible(_automaticAvatarLOD->isChecked());
form->labelForField(_avatarLODDecreaseFPS)->setVisible(_automaticAvatarLOD->isChecked()); form->labelForField(_avatarLODDecreaseFPS)->setVisible(_automaticAvatarLOD->isChecked());
@ -128,7 +133,7 @@ void LodToolsDialog::updateAvatarLODControls() {
form->labelForField(_avatarLOD)->setVisible(!_automaticAvatarLOD->isChecked()); form->labelForField(_avatarLOD)->setVisible(!_automaticAvatarLOD->isChecked());
if (!_automaticAvatarLOD->isChecked()) { if (!_automaticAvatarLOD->isChecked()) {
_avatarLOD->setValue(1.0 / Menu::getInstance()->getAvatarLODDistanceMultiplier()); _avatarLOD->setValue(1.0 / lodManager->getAvatarLODDistanceMultiplier());
} }
if (isVisible()) { if (isVisible()) {
@ -137,25 +142,28 @@ void LodToolsDialog::updateAvatarLODControls() {
} }
void LodToolsDialog::updateAvatarLODValues() { void LodToolsDialog::updateAvatarLODValues() {
auto lodManager = DependencyManager::get<LODManager>();
if (_automaticAvatarLOD->isChecked()) { if (_automaticAvatarLOD->isChecked()) {
Menu::getInstance()->setAvatarLODDecreaseFPS(_avatarLODDecreaseFPS->value()); lodManager->setAvatarLODDecreaseFPS(_avatarLODDecreaseFPS->value());
Menu::getInstance()->setAvatarLODIncreaseFPS(_avatarLODIncreaseFPS->value()); lodManager->setAvatarLODIncreaseFPS(_avatarLODIncreaseFPS->value());
} else { } else {
Menu::getInstance()->setAvatarLODDistanceMultiplier(1.0 / _avatarLOD->value()); lodManager->setAvatarLODDistanceMultiplier(1.0 / _avatarLOD->value());
} }
} }
void LodToolsDialog::sizeScaleValueChanged(int value) { void LodToolsDialog::sizeScaleValueChanged(int value) {
auto lodManager = DependencyManager::get<LODManager>();
float realValue = value * TREE_SCALE; float realValue = value * TREE_SCALE;
Menu::getInstance()->setOctreeSizeScale(realValue); lodManager->setOctreeSizeScale(realValue);
_feedback->setText(Menu::getInstance()->getLODFeedbackText()); _feedback->setText(lodManager->getLODFeedbackText());
} }
void LodToolsDialog::boundaryLevelValueChanged(int value) { void LodToolsDialog::boundaryLevelValueChanged(int value) {
Menu::getInstance()->setBoundaryLevelAdjust(value); auto lodManager = DependencyManager::get<LODManager>();
_feedback->setText(Menu::getInstance()->getLODFeedbackText()); lodManager->setBoundaryLevelAdjust(value);
_feedback->setText(lodManager->getLODFeedbackText());
} }
void LodToolsDialog::resetClicked(bool checked) { void LodToolsDialog::resetClicked(bool checked) {

View file

@ -29,12 +29,9 @@ LoginDialog::LoginDialog(QWidget* parent) :
_ui(new Ui::LoginDialog) { _ui(new Ui::LoginDialog) {
_ui->setupUi(this); _ui->setupUi(this);
_ui->errorLabel->hide(); reset();
_ui->emailLineEdit->setFocus();
_ui->logoLabel->setPixmap(QPixmap(PathUtils::resourcesPath() + "images/hifi-logo.svg")); setAttribute(Qt::WA_DeleteOnClose, false);
_ui->loginButton->setIcon(QIcon(PathUtils::resourcesPath() + "images/login.svg"));
_ui->infoLabel->setVisible(false);
_ui->errorLabel->setVisible(false);
connect(&AccountManager::getInstance(), &AccountManager::loginComplete, connect(&AccountManager::getInstance(), &AccountManager::loginComplete,
this, &LoginDialog::handleLoginCompleted); this, &LoginDialog::handleLoginCompleted);
@ -50,9 +47,21 @@ LoginDialog::~LoginDialog() {
delete _ui; delete _ui;
}; };
void LoginDialog::handleLoginCompleted(const QUrl& authURL) { void LoginDialog::reset() {
_ui->errorLabel->hide();
_ui->emailLineEdit->setFocus();
_ui->logoLabel->setPixmap(QPixmap(PathUtils::resourcesPath() + "images/hifi-logo.svg"));
_ui->loginButton->setIcon(QIcon(PathUtils::resourcesPath() + "images/login.svg"));
_ui->infoLabel->setVisible(false); _ui->infoLabel->setVisible(false);
_ui->errorLabel->setVisible(false); _ui->errorLabel->setVisible(false);
_ui->emailLineEdit->setText("");
_ui->passwordLineEdit->setText("");
_ui->loginArea->setDisabled(false);
}
void LoginDialog::handleLoginCompleted(const QUrl& authURL) {
reset();
close(); close();
}; };
@ -87,3 +96,27 @@ void LoginDialog::moveEvent(QMoveEvent* event) {
// Modal dialogs seemed to get repositioned automatically. Combat this by moving the window if needed. // Modal dialogs seemed to get repositioned automatically. Combat this by moving the window if needed.
resizeAndPosition(); resizeAndPosition();
}; };
void LoginDialog::toggleQAction() {
AccountManager& accountManager = AccountManager::getInstance();
QAction* loginAction = Menu::getInstance()->getActionForOption(MenuOption::Login);
Q_CHECK_PTR(loginAction);
disconnect(loginAction, 0, 0, 0);
if (accountManager.isLoggedIn()) {
// change the menu item to logout
loginAction->setText("Logout " + accountManager.getAccountInfo().getUsername());
connect(loginAction, &QAction::triggered, &accountManager, &AccountManager::logout);
} else {
// change the menu item to login
loginAction->setText("Login");
connect(loginAction, &QAction::triggered, this, &LoginDialog::showLoginForCurrentDomain);
}
}
void LoginDialog::showLoginForCurrentDomain() {
show();
resizeAndPosition(false);
}

View file

@ -27,6 +27,11 @@ public:
~LoginDialog(); ~LoginDialog();
public slots: public slots:
void toggleQAction();
void showLoginForCurrentDomain();
protected slots:
void reset();
void handleLoginClicked(); void handleLoginClicked();
void handleLoginCompleted(const QUrl& authURL); void handleLoginCompleted(const QUrl& authURL);
void handleLoginFailed(); void handleLoginFailed();
@ -35,8 +40,7 @@ protected:
void moveEvent(QMoveEvent* event); void moveEvent(QMoveEvent* event);
private: private:
Ui::LoginDialog* _ui; Ui::LoginDialog* _ui = nullptr;
}; };
#endif // hifi_LoginDialog_h #endif // hifi_LoginDialog_h

View file

@ -50,8 +50,8 @@ enum GridPlane {
const glm::vec2 INVALID_VECTOR(FLT_MAX, FLT_MAX); const glm::vec2 INVALID_VECTOR(FLT_MAX, FLT_MAX);
MetavoxelEditor::MetavoxelEditor() : MetavoxelEditor::MetavoxelEditor(QWidget* parent) :
QWidget(Application::getInstance()->getWindow(), Qt::Tool) { QWidget(parent, Qt::Tool) {
setWindowTitle("Metavoxel Editor"); setWindowTitle("Metavoxel Editor");
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);

View file

@ -12,6 +12,7 @@
#ifndef hifi_MetavoxelEditor_h #ifndef hifi_MetavoxelEditor_h
#define hifi_MetavoxelEditor_h #define hifi_MetavoxelEditor_h
#include <QFormLayout>
#include <QList> #include <QList>
#include <QWidget> #include <QWidget>
@ -38,7 +39,7 @@ class MetavoxelEditor : public QWidget {
public: public:
MetavoxelEditor(); MetavoxelEditor(QWidget* parent = nullptr);
QString getSelectedAttribute() const; QString getSelectedAttribute() const;

View file

@ -20,8 +20,8 @@
const int BYTES_PER_KILOBYTE = 1024; const int BYTES_PER_KILOBYTE = 1024;
MetavoxelNetworkSimulator::MetavoxelNetworkSimulator() : MetavoxelNetworkSimulator::MetavoxelNetworkSimulator(QWidget* parent) :
QWidget(DependencyManager::get<GLCanvas>().data(), Qt::Dialog) { QWidget(parent, Qt::Dialog) {
setWindowTitle("Metavoxel Network Simulator"); setWindowTitle("Metavoxel Network Simulator");
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);

View file

@ -23,7 +23,7 @@ class MetavoxelNetworkSimulator : public QWidget {
public: public:
MetavoxelNetworkSimulator(); MetavoxelNetworkSimulator(QWidget* parent = nullptr);
private slots: private slots:

View file

@ -11,18 +11,22 @@
#include <QFileDialog> #include <QFileDialog>
#include <devices/Faceshift.h>
#include <devices/SixenseManager.h>
#include "Application.h" #include "Application.h"
#include "Audio.h" #include "Audio.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "Menu.h" #include "Menu.h"
#include "ModelsBrowser.h" #include "ModelsBrowser.h"
#include "PreferencesDialog.h" #include "PreferencesDialog.h"
#include "Snapshot.h"
#include "UserActivityLogger.h" #include "UserActivityLogger.h"
const int PREFERENCES_HEIGHT_PADDING = 20; const int PREFERENCES_HEIGHT_PADDING = 20;
PreferencesDialog::PreferencesDialog() : PreferencesDialog::PreferencesDialog(QWidget* parent) :
QDialog(Application::getInstance()->getWindow()) { QDialog(parent) {
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
@ -117,51 +121,53 @@ void PreferencesDialog::loadPreferences() {
ui.sendDataCheckBox->setChecked(!menuInstance->isOptionChecked(MenuOption::DisableActivityLogger)); ui.sendDataCheckBox->setChecked(!menuInstance->isOptionChecked(MenuOption::DisableActivityLogger));
ui.snapshotLocationEdit->setText(menuInstance->getSnapshotsLocation()); ui.snapshotLocationEdit->setText(SettingHandles::snapshotsLocation.get());
ui.scriptsLocationEdit->setText(menuInstance->getScriptsLocation()); ui.scriptsLocationEdit->setText(qApp->getScriptsLocation());
ui.pupilDilationSlider->setValue(myAvatar->getHead()->getPupilDilation() * ui.pupilDilationSlider->setValue(myAvatar->getHead()->getPupilDilation() *
ui.pupilDilationSlider->maximum()); ui.pupilDilationSlider->maximum());
ui.faceshiftEyeDeflectionSider->setValue(menuInstance->getFaceshiftEyeDeflection() * auto faceshift = DependencyManager::get<Faceshift>();
ui.faceshiftEyeDeflectionSider->setValue(faceshift->getEyeDeflection() *
ui.faceshiftEyeDeflectionSider->maximum()); ui.faceshiftEyeDeflectionSider->maximum());
ui.faceshiftHostnameEdit->setText(menuInstance->getFaceshiftHostname()); ui.faceshiftHostnameEdit->setText(faceshift->getHostname());
const InboundAudioStream::Settings& streamSettings = menuInstance->getReceivedAudioStreamSettings();
ui.dynamicJitterBuffersCheckBox->setChecked(streamSettings._dynamicJitterBuffers);
ui.staticDesiredJitterBufferFramesSpin->setValue(streamSettings._staticDesiredJitterBufferFrames);
ui.maxFramesOverDesiredSpin->setValue(streamSettings._maxFramesOverDesired);
ui.useStdevForJitterCalcCheckBox->setChecked(streamSettings._useStDevForJitterCalc);
ui.windowStarveThresholdSpin->setValue(streamSettings._windowStarveThreshold);
ui.windowSecondsForDesiredCalcOnTooManyStarvesSpin->setValue(streamSettings._windowSecondsForDesiredCalcOnTooManyStarves);
ui.windowSecondsForDesiredReductionSpin->setValue(streamSettings._windowSecondsForDesiredReduction);
ui.repetitionWithFadeCheckBox->setChecked(streamSettings._repetitionWithFade);
auto audio = DependencyManager::get<Audio>(); auto audio = DependencyManager::get<Audio>();
MixedProcessedAudioStream& stream = audio->getReceivedAudioStream();
ui.dynamicJitterBuffersCheckBox->setChecked(stream.getDynamicJitterBuffers());
ui.staticDesiredJitterBufferFramesSpin->setValue(stream.getDesiredJitterBufferFrames());
ui.maxFramesOverDesiredSpin->setValue(stream.getMaxFramesOverDesired());
ui.useStdevForJitterCalcCheckBox->setChecked(stream.getUseStDevForJitterCalc());
ui.windowStarveThresholdSpin->setValue(stream.getWindowStarveThreshold());
ui.windowSecondsForDesiredCalcOnTooManyStarvesSpin->setValue(
stream.getWindowSecondsForDesiredCalcOnTooManyStarves());
ui.windowSecondsForDesiredReductionSpin->setValue(stream.getWindowSecondsForDesiredReduction());
ui.repetitionWithFadeCheckBox->setChecked(stream.getRepetitionWithFade());
ui.outputBufferSizeSpinner->setValue(audio->getOutputBufferSize()); ui.outputBufferSizeSpinner->setValue(audio->getOutputBufferSize());
ui.outputStarveDetectionCheckBox->setChecked(audio->getOutputStarveDetectionEnabled()); ui.outputStarveDetectionCheckBox->setChecked(audio->getOutputStarveDetectionEnabled());
ui.outputStarveDetectionThresholdSpinner->setValue(audio->getOutputStarveDetectionThreshold()); ui.outputStarveDetectionThresholdSpinner->setValue(audio->getOutputStarveDetectionThreshold());
ui.outputStarveDetectionPeriodSpinner->setValue(audio->getOutputStarveDetectionPeriod()); ui.outputStarveDetectionPeriodSpinner->setValue(audio->getOutputStarveDetectionPeriod());
ui.realWorldFieldOfViewSpin->setValue(menuInstance->getRealWorldFieldOfView()); ui.realWorldFieldOfViewSpin->setValue(qApp->getViewFrustum()->getRealWorldFieldOfView());
ui.fieldOfViewSpin->setValue(menuInstance->getFieldOfView()); ui.fieldOfViewSpin->setValue(qApp->getViewFrustum()->getFieldOfView());
ui.leanScaleSpin->setValue(myAvatar->getLeanScale()); ui.leanScaleSpin->setValue(myAvatar->getLeanScale());
ui.avatarScaleSpin->setValue(myAvatar->getScale()); ui.avatarScaleSpin->setValue(myAvatar->getScale());
ui.maxOctreePPSSpin->setValue(menuInstance->getMaxOctreePacketsPerSecond()); ui.maxOctreePPSSpin->setValue(qApp->getOctreeQuery().getMaxOctreePacketsPerSecond());
ui.oculusUIAngularSizeSpin->setValue(menuInstance->getOculusUIAngularSize()); ui.oculusUIAngularSizeSpin->setValue(qApp->getApplicationOverlay().getOculusUIAngularSize());
ui.sixenseReticleMoveSpeedSpin->setValue(menuInstance->getSixenseReticleMoveSpeed()); SixenseManager& sixense = SixenseManager::getInstance();
ui.sixenseReticleMoveSpeedSpin->setValue(sixense.getReticleMoveSpeed());
ui.invertSixenseButtonsCheckBox->setChecked(menuInstance->getInvertSixenseButtons()); ui.invertSixenseButtonsCheckBox->setChecked(sixense.getInvertButtons());
} }
@ -213,11 +219,11 @@ void PreferencesDialog::savePreferences() {
} }
if (!ui.snapshotLocationEdit->text().isEmpty() && QDir(ui.snapshotLocationEdit->text()).exists()) { if (!ui.snapshotLocationEdit->text().isEmpty() && QDir(ui.snapshotLocationEdit->text()).exists()) {
Menu::getInstance()->setSnapshotsLocation(ui.snapshotLocationEdit->text()); SettingHandles::snapshotsLocation.set(ui.snapshotLocationEdit->text());
} }
if (!ui.scriptsLocationEdit->text().isEmpty() && QDir(ui.scriptsLocationEdit->text()).exists()) { if (!ui.scriptsLocationEdit->text().isEmpty() && QDir(ui.scriptsLocationEdit->text()).exists()) {
Menu::getInstance()->setScriptsLocation(ui.scriptsLocationEdit->text()); qApp->setScriptsLocation(ui.scriptsLocationEdit->text());
} }
myAvatar->getHead()->setPupilDilation(ui.pupilDilationSlider->value() / (float)ui.pupilDilationSlider->maximum()); myAvatar->getHead()->setPupilDilation(ui.pupilDilationSlider->value() / (float)ui.pupilDilationSlider->maximum());
@ -227,36 +233,35 @@ void PreferencesDialog::savePreferences() {
auto glCanvas = DependencyManager::get<GLCanvas>(); auto glCanvas = DependencyManager::get<GLCanvas>();
Application::getInstance()->resizeGL(glCanvas->width(), glCanvas->height()); Application::getInstance()->resizeGL(glCanvas->width(), glCanvas->height());
Menu::getInstance()->setRealWorldFieldOfView(ui.realWorldFieldOfViewSpin->value()); qApp->getViewFrustum()->setRealWorldFieldOfView(ui.realWorldFieldOfViewSpin->value());
Menu::getInstance()->setFieldOfView(ui.fieldOfViewSpin->value()); qApp->getViewFrustum()->setFieldOfView(ui.fieldOfViewSpin->value());
Menu::getInstance()->setFaceshiftEyeDeflection(ui.faceshiftEyeDeflectionSider->value() /
(float)ui.faceshiftEyeDeflectionSider->maximum());
Menu::getInstance()->setFaceshiftHostname(ui.faceshiftHostnameEdit->text()); auto faceshift = DependencyManager::get<Faceshift>();
faceshift->setEyeDeflection(ui.faceshiftEyeDeflectionSider->value() /
(float)ui.faceshiftEyeDeflectionSider->maximum());
Menu::getInstance()->setMaxOctreePacketsPerSecond(ui.maxOctreePPSSpin->value()); faceshift->setHostname(ui.faceshiftHostnameEdit->text());
qApp->getOctreeQuery().setMaxOctreePacketsPerSecond(ui.maxOctreePPSSpin->value());
Menu::getInstance()->setOculusUIAngularSize(ui.oculusUIAngularSizeSpin->value()); qApp->getApplicationOverlay().setOculusUIAngularSize(ui.oculusUIAngularSizeSpin->value());
Menu::getInstance()->setSixenseReticleMoveSpeed(ui.sixenseReticleMoveSpeedSpin->value()); SixenseManager& sixense = SixenseManager::getInstance();
sixense.setReticleMoveSpeed(ui.sixenseReticleMoveSpeedSpin->value());
Menu::getInstance()->setInvertSixenseButtons(ui.invertSixenseButtonsCheckBox->isChecked()); sixense.setInvertButtons(ui.invertSixenseButtonsCheckBox->isChecked());
InboundAudioStream::Settings streamSettings;
streamSettings._dynamicJitterBuffers = ui.dynamicJitterBuffersCheckBox->isChecked();
streamSettings._staticDesiredJitterBufferFrames = ui.staticDesiredJitterBufferFramesSpin->value();
streamSettings._maxFramesOverDesired = ui.maxFramesOverDesiredSpin->value();
streamSettings._useStDevForJitterCalc = ui.useStdevForJitterCalcCheckBox->isChecked();
streamSettings._windowStarveThreshold = ui.windowStarveThresholdSpin->value();
streamSettings._windowSecondsForDesiredCalcOnTooManyStarves = ui.windowSecondsForDesiredCalcOnTooManyStarvesSpin->value();
streamSettings._windowSecondsForDesiredReduction = ui.windowSecondsForDesiredReductionSpin->value();
streamSettings._repetitionWithFade = ui.repetitionWithFadeCheckBox->isChecked();
Menu::getInstance()->setReceivedAudioStreamSettings(streamSettings);
auto audio = DependencyManager::get<Audio>(); auto audio = DependencyManager::get<Audio>();
MixedProcessedAudioStream& stream = audio->getReceivedAudioStream();
stream.setDynamicJitterBuffers(ui.dynamicJitterBuffersCheckBox->isChecked());
stream.setStaticDesiredJitterBufferFrames(ui.staticDesiredJitterBufferFramesSpin->value());
stream.setMaxFramesOverDesired(ui.maxFramesOverDesiredSpin->value());
stream.setUseStDevForJitterCalc(ui.useStdevForJitterCalcCheckBox->isChecked());
stream.setWindowStarveThreshold(ui.windowStarveThresholdSpin->value());
stream.setWindowSecondsForDesiredCalcOnTooManyStarves(ui.windowSecondsForDesiredCalcOnTooManyStarvesSpin->value());
stream.setWindowSecondsForDesiredReduction(ui.windowSecondsForDesiredReductionSpin->value());
stream.setRepetitionWithFade(ui.repetitionWithFadeCheckBox->isChecked());
QMetaObject::invokeMethod(audio.data(), "setOutputBufferSize", Q_ARG(int, ui.outputBufferSizeSpinner->value())); QMetaObject::invokeMethod(audio.data(), "setOutputBufferSize", Q_ARG(int, ui.outputBufferSizeSpinner->value()));
@ -265,6 +270,4 @@ void PreferencesDialog::savePreferences() {
audio->setOutputStarveDetectionPeriod(ui.outputStarveDetectionPeriodSpinner->value()); audio->setOutputStarveDetectionPeriod(ui.outputStarveDetectionPeriodSpinner->value());
Application::getInstance()->resizeGL(glCanvas->width(), glCanvas->height()); Application::getInstance()->resizeGL(glCanvas->width(), glCanvas->height());
Application::getInstance()->bumpSettings();
} }

View file

@ -21,7 +21,7 @@ class PreferencesDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
PreferencesDialog(); PreferencesDialog(QWidget* parent = nullptr);
protected: protected:
void resizeEvent(QResizeEvent* resizeEvent); void resizeEvent(QResizeEvent* resizeEvent);

View file

@ -20,24 +20,17 @@
#include "RearMirrorTools.h" #include "RearMirrorTools.h"
#include "Util.h" #include "Util.h"
const char SETTINGS_GROUP_NAME[] = "Rear View Tools";
const char ZOOM_LEVEL_SETTINGS[] = "ZoomLevel";
const int ICON_SIZE = 24; const int ICON_SIZE = 24;
const int ICON_PADDING = 5; const int ICON_PADDING = 5;
RearMirrorTools::RearMirrorTools(QGLWidget* parent, QRect& bounds, QSettings* settings) : RearMirrorTools::RearMirrorTools(QGLWidget* parent, QRect& bounds) :
_parent(parent), _parent(parent),
_bounds(bounds), _bounds(bounds),
_windowed(false), _windowed(false),
_fullScreen(false) _fullScreen(false)
{ {
_zoomLevel = HEAD;
_closeTextureId = _parent->bindTexture(QImage(PathUtils::resourcesPath() + "images/close.svg")); _closeTextureId = _parent->bindTexture(QImage(PathUtils::resourcesPath() + "images/close.svg"));
// Disabled for now https://worklist.net/19548
// _resetTextureId = _parent->bindTexture(QImage(PathUtils::resourcesPath() + "images/reset.png"));
_zoomHeadTextureId = _parent->bindTexture(QImage(PathUtils::resourcesPath() + "images/plus.svg")); _zoomHeadTextureId = _parent->bindTexture(QImage(PathUtils::resourcesPath() + "images/plus.svg"));
_zoomBodyTextureId = _parent->bindTexture(QImage(PathUtils::resourcesPath() + "images/minus.svg")); _zoomBodyTextureId = _parent->bindTexture(QImage(PathUtils::resourcesPath() + "images/minus.svg"));
@ -46,11 +39,7 @@ RearMirrorTools::RearMirrorTools(QGLWidget* parent, QRect& bounds, QSettings* se
_resetIconRect = QRect(_bounds.width() - ICON_SIZE - ICON_PADDING, _bounds.top() + ICON_PADDING, ICON_SIZE, ICON_SIZE); _resetIconRect = QRect(_bounds.width() - ICON_SIZE - ICON_PADDING, _bounds.top() + ICON_PADDING, ICON_SIZE, ICON_SIZE);
_bodyZoomIconRect = QRect(_bounds.width() - ICON_SIZE - ICON_PADDING, _bounds.bottom() - ICON_PADDING - ICON_SIZE, ICON_SIZE, ICON_SIZE); _bodyZoomIconRect = QRect(_bounds.width() - ICON_SIZE - ICON_PADDING, _bounds.bottom() - ICON_PADDING - ICON_SIZE, ICON_SIZE, ICON_SIZE);
_headZoomIconRect = QRect(_bounds.left() + ICON_PADDING, _bounds.bottom() - ICON_PADDING - ICON_SIZE, ICON_SIZE, ICON_SIZE); _headZoomIconRect = QRect(_bounds.left() + ICON_PADDING, _bounds.bottom() - ICON_PADDING - ICON_SIZE, ICON_SIZE, ICON_SIZE);
}
settings->beginGroup(SETTINGS_GROUP_NAME);
_zoomLevel = loadSetting(settings, ZOOM_LEVEL_SETTINGS, 0) == HEAD ? HEAD : BODY;
settings->endGroup();
};
void RearMirrorTools::render(bool fullScreen) { void RearMirrorTools::render(bool fullScreen) {
if (fullScreen) { if (fullScreen) {
@ -63,11 +52,9 @@ void RearMirrorTools::render(bool fullScreen) {
if (_windowed) { if (_windowed) {
displayIcon(_bounds, _closeIconRect, _closeTextureId); displayIcon(_bounds, _closeIconRect, _closeTextureId);
// Disabled for now https://worklist.net/19548 ZoomLevel zoomLevel = (ZoomLevel)SettingHandles::rearViewZoomLevel.get();
// displayIcon(_bounds, _resetIconRect, _resetTextureId); displayIcon(_bounds, _headZoomIconRect, _zoomHeadTextureId, zoomLevel == HEAD);
displayIcon(_bounds, _bodyZoomIconRect, _zoomBodyTextureId, zoomLevel == BODY);
displayIcon(_bounds, _headZoomIconRect, _zoomHeadTextureId, _zoomLevel == HEAD);
displayIcon(_bounds, _bodyZoomIconRect, _zoomBodyTextureId, _zoomLevel == BODY);
} }
} }
} }
@ -79,23 +66,14 @@ bool RearMirrorTools::mousePressEvent(int x, int y) {
emit closeView(); emit closeView();
return true; return true;
} }
/* Disabled for now https://worklist.net/19548
if (_resetIconRect.contains(x, y)) {
emit resetView();
return true;
}
*/
if (_headZoomIconRect.contains(x, y)) { if (_headZoomIconRect.contains(x, y)) {
_zoomLevel = HEAD; SettingHandles::rearViewZoomLevel.set(HEAD);
Application::getInstance()->bumpSettings();
return true; return true;
} }
if (_bodyZoomIconRect.contains(x, y)) { if (_bodyZoomIconRect.contains(x, y)) {
_zoomLevel = BODY; SettingHandles::rearViewZoomLevel.set(BODY);
Application::getInstance()->bumpSettings();
return true; return true;
} }
@ -116,12 +94,6 @@ bool RearMirrorTools::mousePressEvent(int x, int y) {
return false; return false;
} }
void RearMirrorTools::saveSettings(QSettings* settings) {
settings->beginGroup(SETTINGS_GROUP_NAME);
settings->setValue(ZOOM_LEVEL_SETTINGS, _zoomLevel);
settings->endGroup();
}
void RearMirrorTools::displayIcon(QRect bounds, QRect iconBounds, GLuint textureId, bool selected) { void RearMirrorTools::displayIcon(QRect bounds, QRect iconBounds, GLuint textureId, bool selected) {
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);

View file

@ -15,21 +15,27 @@
#include "InterfaceConfig.h" #include "InterfaceConfig.h"
#include <QGLWidget> #include <QGLWidget>
#include <QSettings>
#include <Settings.h>
enum ZoomLevel { enum ZoomLevel {
HEAD, HEAD = 0,
BODY BODY = 1
}; };
namespace SettingHandles {
const char SETTINGS_GROUP_NAME[] = "Rear View Tools";
const char ZOOM_LEVEL_SETTINGS[] = "ZoomLevel";
const SettingHandle<int> rearViewZoomLevel(QStringList() << SETTINGS_GROUP_NAME << ZOOM_LEVEL_SETTINGS,
ZoomLevel::HEAD);
}
class RearMirrorTools : public QObject { class RearMirrorTools : public QObject {
Q_OBJECT Q_OBJECT
public: public:
RearMirrorTools(QGLWidget* parent, QRect& bounds, QSettings* settings); RearMirrorTools(QGLWidget* parent, QRect& bounds);
void render(bool fullScreen); void render(bool fullScreen);
bool mousePressEvent(int x, int y); bool mousePressEvent(int x, int y);
ZoomLevel getZoomLevel() { return _zoomLevel; }
void saveSettings(QSettings* settings);
signals: signals:
void closeView(); void closeView();
@ -44,7 +50,6 @@ private:
GLuint _resetTextureId; GLuint _resetTextureId;
GLuint _zoomBodyTextureId; GLuint _zoomBodyTextureId;
GLuint _zoomHeadTextureId; GLuint _zoomHeadTextureId;
ZoomLevel _zoomLevel;
QRect _closeIconRect; QRect _closeIconRect;
QRect _resetIconRect; QRect _resetIconRect;

View file

@ -11,6 +11,7 @@
#include "ui_scriptEditorWidget.h" #include "ui_scriptEditorWidget.h"
#include "ScriptEditorWidget.h" #include "ScriptEditorWidget.h"
#include "ScriptEditorWindow.h"
#include <QGridLayout> #include <QGridLayout>
#include <QFileDialog> #include <QFileDialog>

View file

@ -31,7 +31,8 @@
#include "FlowLayout.h" #include "FlowLayout.h"
#include "JSConsole.h" #include "JSConsole.h"
ScriptEditorWindow::ScriptEditorWindow() : ScriptEditorWindow::ScriptEditorWindow(QWidget* parent) :
QWidget(parent),
_ScriptEditorWindowUI(new Ui::ScriptEditorWindow), _ScriptEditorWindowUI(new Ui::ScriptEditorWindow),
_loadMenu(new QMenu), _loadMenu(new QMenu),
_saveMenu(new QMenu) _saveMenu(new QMenu)

View file

@ -22,7 +22,7 @@ class ScriptEditorWindow : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
ScriptEditorWindow(); ScriptEditorWindow(QWidget* parent = nullptr);
~ScriptEditorWindow(); ~ScriptEditorWindow();
void terminateCurrentTab(); void terminateCurrentTab();

View file

@ -10,13 +10,17 @@
// //
#include <QDateTime> #include <QDateTime>
#include <QDir>
#include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QImage>
#include <QTemporaryFile>
#include <AccountManager.h> #include <AccountManager.h>
#include <Application.h>
#include <FileUtils.h> #include <FileUtils.h>
#include "Snapshot.h" #include "Snapshot.h"
#include "Menu.h"
// filename format: hifi-snap-by-%username%-on-%date%_%time%_@-%location%.jpg // filename format: hifi-snap-by-%username%-on-%date%_%time%_@-%location%.jpg
// %1 <= username, %2 <= date and time, %3 <= current location // %1 <= username, %2 <= date and time, %3 <= current location
@ -86,7 +90,7 @@ QFile* Snapshot::savedFileForSnapshot(bool isTemporary) {
auto glCanvas = DependencyManager::get<GLCanvas>(); auto glCanvas = DependencyManager::get<GLCanvas>();
QImage shot = glCanvas->grabFrameBuffer(); QImage shot = glCanvas->grabFrameBuffer();
Avatar* avatar = Application::getInstance()->getAvatar(); Avatar* avatar = qApp->getAvatar();
glm::vec3 location = avatar->getPosition(); glm::vec3 location = avatar->getPosition();
glm::quat orientation = avatar->getHead()->getOrientation(); glm::quat orientation = avatar->getHead()->getOrientation();
@ -118,7 +122,7 @@ QFile* Snapshot::savedFileForSnapshot(bool isTemporary) {
const int IMAGE_QUALITY = 100; const int IMAGE_QUALITY = 100;
if (!isTemporary) { if (!isTemporary) {
QString snapshotFullPath = Menu::getInstance()->getSnapshotsLocation(); QString snapshotFullPath = SettingHandles::snapshotsLocation.get();
if (!snapshotFullPath.endsWith(QDir::separator())) { if (!snapshotFullPath.endsWith(QDir::separator())) {
snapshotFullPath.append(QDir::separator()); snapshotFullPath.append(QDir::separator());

View file

@ -12,15 +12,19 @@
#ifndef hifi_Snapshot_h #ifndef hifi_Snapshot_h
#define hifi_Snapshot_h #define hifi_Snapshot_h
#include "InterfaceConfig.h" #include <glm/glm.hpp>
#include <qimage.h> #include <QString>
#include <qfile.h>
#include <qtemporaryfile.h>
#include <QGLWidget>
#include <qstring.h>
#include "avatar/Avatar.h" #include <Settings.h>
class QFile;
class QTemporaryFile;
namespace SettingHandles {
const SettingHandle<QString> snapshotsLocation("snapshotsLocation",
QStandardPaths::writableLocation(QStandardPaths::DesktopLocation));
}
class SnapshotMetaData { class SnapshotMetaData {
public: public:
@ -41,7 +45,6 @@ private:
}; };
class Snapshot { class Snapshot {
public: public:
static QString saveSnapshot(); static QString saveSnapshot();
static QTemporaryFile* saveTempSnapshot(); static QTemporaryFile* saveTempSnapshot();

View file

@ -0,0 +1,39 @@
//
// StandAloneJSConsole.cpp
//
//
// Created by Clement on 1/17/15.
// 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
//
#include <QMainWindow>
#include <QDialog>
#include <QVBoxLayout>
#include <Application.h>
#include <MainWindow.h>
#include "StandAloneJSConsole.h"
void StandAloneJSConsole::toggleConsole() {
QMainWindow* mainWindow = qApp->getWindow();
if (!_jsConsole) {
QDialog* dialog = new QDialog(mainWindow, Qt::WindowStaysOnTopHint);
QVBoxLayout* layout = new QVBoxLayout(dialog);
dialog->setLayout(layout);
dialog->resize(QSize(CONSOLE_WIDTH, CONSOLE_HEIGHT));
layout->setMargin(0);
layout->setSpacing(0);
layout->addWidget(new JSConsole(dialog));
dialog->setWindowOpacity(CONSOLE_WINDOW_OPACITY);
dialog->setWindowTitle(CONSOLE_TITLE);
_jsConsole = dialog;
}
_jsConsole->setVisible(!_jsConsole->isVisible());
}

View file

@ -0,0 +1,35 @@
//
// StandAloneJSConsole.h
//
//
// Created by Clement on 1/17/15.
// 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
//
#ifndef hifi_StandAloneJSConsole_h
#define hifi_StandAloneJSConsole_h
#include <QPointer>
#include <DependencyManager.h>
#include "JSConsole.h"
class QDialog;
class StandAloneJSConsole : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
public slots:
void toggleConsole();
private:
StandAloneJSConsole() {}
QPointer<QDialog> _jsConsole;
};
#endif // hifi_StandAloneJSConsole_h

View file

@ -18,6 +18,10 @@
#include <glm/gtx/quaternion.hpp> #include <glm/gtx/quaternion.hpp>
#include <glm/gtx/vector_angle.hpp> #include <glm/gtx/vector_angle.hpp>
#include <Application.h>
#include <GeometryCache.h>
#include <GLCanvas.h>
#include <LODManager.h>
#include <PerfStat.h> #include <PerfStat.h>
#include "Stats.h" #include "Stats.h"
@ -623,7 +627,7 @@ void Stats::display(
// LOD Details // LOD Details
if (_expanded) { if (_expanded) {
octreeStats.str(""); octreeStats.str("");
QString displayLODDetails = Menu::getInstance()->getLODFeedbackText(); QString displayLODDetails = DependencyManager::get<LODManager>()->getLODFeedbackText();
octreeStats << "LOD: You can see " << qPrintable(displayLODDetails.trimmed()); octreeStats << "LOD: You can see " << qPrintable(displayLODDetails.trimmed());
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)octreeStats.str().c_str(), color); drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)octreeStats.str().c_str(), color);

View file

@ -8,12 +8,14 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include <QScriptValueIterator>
#include <limits> #include <limits>
#include <typeinfo> #include <typeinfo>
#include <Application.h> #include <Application.h>
#include <devices/OculusManager.h> #include <devices/OculusManager.h>
#include <Menu.h> #include <LODManager.h>
#include <QScriptValueIterator>
#include "BillboardOverlay.h" #include "BillboardOverlay.h"
#include "Circle3DOverlay.h" #include "Circle3DOverlay.h"
@ -83,10 +85,13 @@ void Overlays::update(float deltatime) {
void Overlays::renderHUD() { void Overlays::renderHUD() {
QReadLocker lock(&_lock); QReadLocker lock(&_lock);
auto lodManager = DependencyManager::get<LODManager>();
RenderArgs args = { NULL, Application::getInstance()->getViewFrustum(), RenderArgs args = { NULL, Application::getInstance()->getViewFrustum(),
Menu::getInstance()->getOctreeSizeScale(), Menu::getInstance()->getBoundaryLevelAdjust(), lodManager->getOctreeSizeScale(),
RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; lodManager->getBoundaryLevelAdjust(),
RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
foreach(Overlay* thisOverlay, _overlaysHUD) { foreach(Overlay* thisOverlay, _overlaysHUD) {
if (thisOverlay->is3D()) { if (thisOverlay->is3D()) {
@ -116,9 +121,12 @@ void Overlays::renderWorld(bool drawFront, RenderArgs::RenderMode renderMode, Re
glm::vec3 axis(0.0f, 1.0f, 0.0f); glm::vec3 axis(0.0f, 1.0f, 0.0f);
float myAvatarScale = 1.0f; float myAvatarScale = 1.0f;
auto lodManager = DependencyManager::get<LODManager>();
RenderArgs args = { NULL, Application::getInstance()->getViewFrustum(), RenderArgs args = { NULL, Application::getInstance()->getViewFrustum(),
Menu::getInstance()->getOctreeSizeScale(), Menu::getInstance()->getBoundaryLevelAdjust(), lodManager->getOctreeSizeScale(),
renderMode, renderSide, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; lodManager->getBoundaryLevelAdjust(),
renderMode, renderSide,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
foreach(Overlay* thisOverlay, _overlaysWorld) { foreach(Overlay* thisOverlay, _overlaysWorld) {

View file

@ -11,11 +11,27 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <Settings.h>
#include "InboundAudioStream.h" #include "InboundAudioStream.h"
#include "PacketHeaders.h" #include "PacketHeaders.h"
const int STARVE_HISTORY_CAPACITY = 50; const int STARVE_HISTORY_CAPACITY = 50;
namespace SettingHandles {
const SettingHandle<bool> dynamicJitterBuffers("dynamicJitterBuffers", DEFAULT_DYNAMIC_JITTER_BUFFERS);
const SettingHandle<int> maxFramesOverDesired("maxFramesOverDesired", DEFAULT_MAX_FRAMES_OVER_DESIRED);
const SettingHandle<int> staticDesiredJitterBufferFrames("staticDesiredJitterBufferFrames",
DEFAULT_STATIC_DESIRED_JITTER_BUFFER_FRAMES);
const SettingHandle<bool> useStDevForJitterCalc("useStDevForJitterCalc", DEFAULT_USE_STDEV_FOR_JITTER_CALC);
const SettingHandle<int> windowStarveThreshold("windowStarveThreshold", DEFAULT_WINDOW_STARVE_THRESHOLD);
const SettingHandle<int> windowSecondsForDesiredCalcOnTooManyStarves("windowSecondsForDesiredCalcOnTooManyStarves",
DEFAULT_WINDOW_SECONDS_FOR_DESIRED_CALC_ON_TOO_MANY_STARVES);
const SettingHandle<int> windowSecondsForDesiredReduction("windowSecondsForDesiredReduction",
DEFAULT_WINDOW_SECONDS_FOR_DESIRED_REDUCTION);
const SettingHandle<bool> repetitionWithFade("repetitionWithFade", DEFAULT_REPETITION_WITH_FADE);
}
InboundAudioStream::InboundAudioStream(int numFrameSamples, int numFramesCapacity, const Settings& settings) : InboundAudioStream::InboundAudioStream(int numFrameSamples, int numFramesCapacity, const Settings& settings) :
_ringBuffer(numFrameSamples, false, numFramesCapacity), _ringBuffer(numFrameSamples, false, numFramesCapacity),
_lastPopSucceeded(false), _lastPopSucceeded(false),
@ -500,3 +516,28 @@ float calculateRepeatedFrameFadeFactor(int indexOfRepeat) {
} }
return 0.0f; return 0.0f;
} }
void InboundAudioStream::loadSettings() {
setDynamicJitterBuffers(SettingHandles::dynamicJitterBuffers.get());
setMaxFramesOverDesired(SettingHandles::maxFramesOverDesired.get());
setStaticDesiredJitterBufferFrames(SettingHandles::staticDesiredJitterBufferFrames.get());
setUseStDevForJitterCalc(SettingHandles::useStDevForJitterCalc.get());
setWindowStarveThreshold(SettingHandles::windowStarveThreshold.get());
setWindowSecondsForDesiredCalcOnTooManyStarves(SettingHandles::windowSecondsForDesiredCalcOnTooManyStarves.get());
setWindowSecondsForDesiredReduction(SettingHandles::windowSecondsForDesiredReduction.get());
setRepetitionWithFade(SettingHandles::repetitionWithFade.get());
}
void InboundAudioStream::saveSettings() {
SettingHandles::dynamicJitterBuffers.set(getDynamicJitterBuffers());
SettingHandles::maxFramesOverDesired.set(getMaxFramesOverDesired());
SettingHandles::staticDesiredJitterBufferFrames.set(getDesiredJitterBufferFrames());
SettingHandles::useStDevForJitterCalc.set(getUseStDevForJitterCalc());
SettingHandles::windowStarveThreshold.set(getWindowStarveThreshold());
SettingHandles::windowSecondsForDesiredCalcOnTooManyStarves.set(getWindowSecondsForDesiredCalcOnTooManyStarves());
SettingHandles::windowSecondsForDesiredReduction.set(getWindowSecondsForDesiredReduction());
SettingHandles::repetitionWithFade.set(getRepetitionWithFade());
}

View file

@ -126,6 +126,8 @@ public:
void setWindowSecondsForDesiredReduction(int windowSecondsForDesiredReduction); void setWindowSecondsForDesiredReduction(int windowSecondsForDesiredReduction);
void setRepetitionWithFade(bool repetitionWithFade) { _repetitionWithFade = repetitionWithFade; } void setRepetitionWithFade(bool repetitionWithFade) { _repetitionWithFade = repetitionWithFade; }
void loadSettings();
void saveSettings();
virtual AudioStreamStats getAudioStreamStats() const; virtual AudioStreamStats getAudioStreamStats() const;
@ -138,7 +140,15 @@ public:
/// returns the desired number of jitter buffer frames using Freddy's method /// returns the desired number of jitter buffer frames using Freddy's method
int getCalculatedJitterBufferFramesUsingMaxGap() const { return _calculatedJitterBufferFramesUsingMaxGap; } int getCalculatedJitterBufferFramesUsingMaxGap() const { return _calculatedJitterBufferFramesUsingMaxGap; }
int getWindowSecondsForDesiredReduction() const {
return _timeGapStatsForDesiredReduction.getWindowIntervals(); }
int getWindowSecondsForDesiredCalcOnTooManyStarves() const {
return _timeGapStatsForDesiredCalcOnTooManyStarves.getWindowIntervals(); }
bool getDynamicJitterBuffers() const { return _dynamicJitterBuffers; }
bool getRepetitionWithFade() const { return _repetitionWithFade;}
int getWindowStarveThreshold() const { return _starveThreshold;}
bool getUseStDevForJitterCalc() const { return _useStDevForJitterCalc; }
int getDesiredJitterBufferFrames() const { return _desiredJitterBufferFrames; } int getDesiredJitterBufferFrames() const { return _desiredJitterBufferFrames; }
int getMaxFramesOverDesired() const { return _maxFramesOverDesired; } int getMaxFramesOverDesired() const { return _maxFramesOverDesired; }
int getNumFrameSamples() const { return _ringBuffer.getNumFrameSamples(); } int getNumFrameSamples() const { return _ringBuffer.getNumFrameSamples(); }
@ -204,7 +214,7 @@ protected:
bool _lastPopSucceeded; bool _lastPopSucceeded;
AudioRingBuffer::ConstIterator _lastPopOutput; AudioRingBuffer::ConstIterator _lastPopOutput;
bool _dynamicJitterBuffers; // if false, _desiredJitterBufferFrames is locked at 1 (old behavior) bool _dynamicJitterBuffers; // if false, _desiredJitterBufferFrames is locked at 1 (old behavior)
int _staticDesiredJitterBufferFrames; int _staticDesiredJitterBufferFrames;

View file

@ -19,11 +19,11 @@
#include <QMetaType> #include <QMetaType>
#include <QPushButton> #include <QPushButton>
#include <QScriptEngine> #include <QScriptEngine>
#include <QSettings>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QtDebug> #include <QtDebug>
#include <GLMHelpers.h> #include <GLMHelpers.h>
#include <Settings.h>
#include "MetavoxelUtil.h" #include "MetavoxelUtil.h"
#include "ScriptCache.h" #include "ScriptCache.h"
@ -485,6 +485,10 @@ void QColorEditor::selectColor() {
} }
} }
namespace SettingHandles {
const SettingHandle<QStringList> editorURLs("editorURLs");
}
QUrlEditor::QUrlEditor(QWidget* parent) : QUrlEditor::QUrlEditor(QWidget* parent) :
QComboBox(parent) { QComboBox(parent) {
@ -492,7 +496,7 @@ QUrlEditor::QUrlEditor(QWidget* parent) :
setInsertPolicy(InsertAtTop); setInsertPolicy(InsertAtTop);
// populate initial URL list from settings // populate initial URL list from settings
addItems(QSettings().value("editorURLs").toStringList()); addItems(SettingHandles::editorURLs.get());
connect(this, SIGNAL(activated(const QString&)), SLOT(updateURL(const QString&))); connect(this, SIGNAL(activated(const QString&)), SLOT(updateURL(const QString&)));
connect(model(), SIGNAL(rowsInserted(const QModelIndex&,int,int)), SLOT(updateSettings())); connect(model(), SIGNAL(rowsInserted(const QModelIndex&,int,int)), SLOT(updateSettings()));
@ -512,7 +516,7 @@ void QUrlEditor::updateSettings() {
for (int i = 0, size = qMin(MAX_STORED_URLS, count()); i < size; i++) { for (int i = 0, size = qMin(MAX_STORED_URLS, count()); i < size; i++) {
urls.append(itemText(i)); urls.append(itemText(i));
} }
QSettings().setValue("editorURLs", urls); SettingHandles::editorURLs.set(urls);
} }
BaseVec3Editor::BaseVec3Editor(QWidget* parent) : QWidget(parent) { BaseVec3Editor::BaseVec3Editor(QWidget* parent) : QWidget(parent) {

View file

@ -17,12 +17,12 @@
#include <QItemEditorFactory> #include <QItemEditorFactory>
#include <QMessageBox> #include <QMessageBox>
#include <QPushButton> #include <QPushButton>
#include <QSettings>
#include <QThread> #include <QThread>
#include <glm/gtx/transform.hpp> #include <glm/gtx/transform.hpp>
#include <GeometryUtil.h> #include <GeometryUtil.h>
#include <Settings.h>
#include "MetavoxelData.h" #include "MetavoxelData.h"
#include "Spanner.h" #include "Spanner.h"
@ -58,6 +58,10 @@ static QItemEditorCreatorBase* heightfieldColorEditorCreator = createHeightfield
const float DEFAULT_PLACEMENT_GRANULARITY = 0.01f; const float DEFAULT_PLACEMENT_GRANULARITY = 0.01f;
const float DEFAULT_VOXELIZATION_GRANULARITY = powf(2.0f, -3.0f); const float DEFAULT_VOXELIZATION_GRANULARITY = powf(2.0f, -3.0f);
namespace SettingHandles {
const SettingHandle<QString> heightfieldDir("heightDir", QString());
}
Spanner::Spanner() : Spanner::Spanner() :
_renderer(NULL), _renderer(NULL),
_placementGranularity(DEFAULT_PLACEMENT_GRANULARITY), _placementGranularity(DEFAULT_PLACEMENT_GRANULARITY),
@ -610,13 +614,13 @@ static int getHeightfieldSize(int size) {
} }
void HeightfieldHeightEditor::select() { void HeightfieldHeightEditor::select() {
QSettings settings; QString result = QFileDialog::getOpenFileName(this, "Select Height Image",
QString result = QFileDialog::getOpenFileName(this, "Select Height Image", settings.value("heightDir").toString(), SettingHandles::heightfieldDir.get(),
"Images (*.png *.jpg *.bmp *.raw *.mdr)"); "Images (*.png *.jpg *.bmp *.raw *.mdr)");
if (result.isNull()) { if (result.isNull()) {
return; return;
} }
settings.setValue("heightDir", QFileInfo(result).path()); SettingHandles::heightfieldDir.set(QFileInfo(result).path());
const quint16 CONVERSION_OFFSET = 1; const quint16 CONVERSION_OFFSET = 1;
QString lowerResult = result.toLower(); QString lowerResult = result.toLower();
bool isMDR = lowerResult.endsWith(".mdr"); bool isMDR = lowerResult.endsWith(".mdr");
@ -880,13 +884,13 @@ void HeightfieldColorEditor::setColor(const HeightfieldColorPointer& color) {
} }
void HeightfieldColorEditor::select() { void HeightfieldColorEditor::select() {
QSettings settings; QString result = QFileDialog::getOpenFileName(this, "Select Color Image",
QString result = QFileDialog::getOpenFileName(this, "Select Color Image", settings.value("heightDir").toString(), SettingHandles::heightfieldDir.get(),
"Images (*.png *.jpg *.bmp)"); "Images (*.png *.jpg *.bmp)");
if (result.isNull()) { if (result.isNull()) {
return; return;
} }
settings.setValue("heightDir", QFileInfo(result).path()); SettingHandles::heightfieldDir.get(QFileInfo(result).path());
QImage image; QImage image;
if (!image.load(result)) { if (!image.load(result)) {
QMessageBox::warning(this, "Invalid Image", "The selected image could not be read."); QMessageBox::warning(this, "Invalid Image", "The selected image could not be read.");

View file

@ -21,6 +21,8 @@
#include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkRequest>
#include <qthread.h> #include <qthread.h>
#include <Settings.h>
#include "NodeList.h" #include "NodeList.h"
#include "PacketHeaders.h" #include "PacketHeaders.h"
#include "RSAKeypairGenerator.h" #include "RSAKeypairGenerator.h"
@ -88,11 +90,9 @@ void AccountManager::logout() {
connect(&_accountInfo, &DataServerAccountInfo::balanceChanged, this, &AccountManager::accountInfoBalanceChanged); connect(&_accountInfo, &DataServerAccountInfo::balanceChanged, this, &AccountManager::accountInfoBalanceChanged);
if (_shouldPersistToSettingsFile) { if (_shouldPersistToSettingsFile) {
QSettings settings;
settings.beginGroup(ACCOUNTS_GROUP);
QString keyURLString(_authURL.toString().replace("//", DOUBLE_SLASH_SUBSTITUTE)); QString keyURLString(_authURL.toString().replace("//", DOUBLE_SLASH_SUBSTITUTE));
settings.remove(keyURLString); QStringList path = QStringList() << ACCOUNTS_GROUP << keyURLString;
SettingHandles::SettingHandle<DataServerAccountInfo>(path).remove();
qDebug() << "Removed account info for" << _authURL << "from in-memory accounts and .ini file"; qDebug() << "Removed account info for" << _authURL << "from in-memory accounts and .ini file";
} else { } else {
@ -127,13 +127,13 @@ void AccountManager::setAuthURL(const QUrl& authURL) {
if (_shouldPersistToSettingsFile) { if (_shouldPersistToSettingsFile) {
// check if there are existing access tokens to load from settings // check if there are existing access tokens to load from settings
QSettings settings; Settings settings;
settings.beginGroup(ACCOUNTS_GROUP); settings.beginGroup(ACCOUNTS_GROUP);
foreach(const QString& key, settings.allKeys()) { foreach(const QString& key, settings.allKeys()) {
// take a key copy to perform the double slash replacement // take a key copy to perform the double slash replacement
QString keyCopy(key); QString keyCopy(key);
QUrl keyURL(keyCopy.replace("slashslash", "//")); QUrl keyURL(keyCopy.replace(DOUBLE_SLASH_SUBSTITUTE, "//"));
if (keyURL == _authURL) { if (keyURL == _authURL) {
// pull out the stored access token and store it in memory // pull out the stored access token and store it in memory
@ -337,10 +337,9 @@ void AccountManager::passErrorToCallback(QNetworkReply* requestReply) {
void AccountManager::persistAccountToSettings() { void AccountManager::persistAccountToSettings() {
if (_shouldPersistToSettingsFile) { if (_shouldPersistToSettingsFile) {
// store this access token into the local settings // store this access token into the local settings
QSettings localSettings; QString keyURLString(_authURL.toString().replace("//", DOUBLE_SLASH_SUBSTITUTE));
localSettings.beginGroup(ACCOUNTS_GROUP); QStringList path = QStringList() << ACCOUNTS_GROUP << keyURLString;
localSettings.setValue(_authURL.toString().replace("//", DOUBLE_SLASH_SUBSTITUTE), SettingHandles::SettingHandle<QVariant>(path).set(QVariant::fromValue(_accountInfo));
QVariant::fromValue(_accountInfo));
} }
} }

View file

@ -9,25 +9,36 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include <qdebug.h> #include <QApplication>
#include <qjsondocument.h> #include <QClipboard>
#include <qregexp.h> #include <QDebug>
#include <qstringlist.h> #include <QJsonDocument>
#include <QRegExp>
#include <QStringList>
#include <GLMHelpers.h> #include <GLMHelpers.h>
#include <Settings.h>
#include <UUID.h> #include <UUID.h>
#include "NodeList.h" #include "NodeList.h"
#include "AddressManager.h" #include "AddressManager.h"
const QString ADDRESS_MANAGER_SETTINGS_GROUP = "AddressManager";
const QString SETTINGS_CURRENT_ADDRESS_KEY = "address";
namespace SettingHandles {
const SettingHandle<QUrl> currentAddress(QStringList() << ADDRESS_MANAGER_SETTINGS_GROUP
<< "address",
QUrl());
}
AddressManager::AddressManager() : AddressManager::AddressManager() :
_rootPlaceName(), _rootPlaceName(),
_rootPlaceID(), _rootPlaceID(),
_positionGetter(NULL), _positionGetter(NULL),
_orientationGetter(NULL) _orientationGetter(NULL)
{ {
connect(qApp, &QCoreApplication::aboutToQuit, this, &AddressManager::storeCurrentAddress);
} }
bool AddressManager::isConnected() { bool AddressManager::isConnected() {
@ -44,25 +55,16 @@ const QUrl AddressManager::currentAddress() const {
return hifiURL; return hifiURL;
} }
const QString ADDRESS_MANAGER_SETTINGS_GROUP = "AddressManager";
const QString SETTINGS_CURRENT_ADDRESS_KEY = "address";
void AddressManager::loadSettings(const QString& lookupString) { void AddressManager::loadSettings(const QString& lookupString) {
if (lookupString.isEmpty()) { if (lookupString.isEmpty()) {
QSettings settings; handleLookupString(SettingHandles::currentAddress.get().toString());
settings.beginGroup(ADDRESS_MANAGER_SETTINGS_GROUP);
handleLookupString(settings.value(SETTINGS_CURRENT_ADDRESS_KEY).toString());
} else { } else {
handleLookupString(lookupString); handleLookupString(lookupString);
} }
} }
void AddressManager::storeCurrentAddress() { void AddressManager::storeCurrentAddress() {
QSettings settings; SettingHandles::currentAddress.set(currentAddress());
settings.beginGroup(ADDRESS_MANAGER_SETTINGS_GROUP);
settings.setValue(SETTINGS_CURRENT_ADDRESS_KEY, currentAddress());
settings.endGroup();
} }
const QString AddressManager::currentPath(bool withOrientation) const { const QString AddressManager::currentPath(bool withOrientation) const {
@ -430,3 +432,11 @@ void AddressManager::goToUser(const QString& username) {
QNetworkAccessManager::GetOperation, QNetworkAccessManager::GetOperation,
apiCallbackParameters()); apiCallbackParameters());
} }
void AddressManager::copyAddress() {
QApplication::clipboard()->setText(currentAddress().toString());
}
void AddressManager::copyPath() {
QApplication::clipboard()->setText(currentPath());
}

View file

@ -61,6 +61,9 @@ public slots:
void storeCurrentAddress(); void storeCurrentAddress();
void copyAddress();
void copyPath();
signals: signals:
void lookupResultsFinished(); void lookupResultsFinished();
void lookupResultIsOffline(); void lookupResultIsOffline();

View file

@ -9,15 +9,27 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include <QNetworkDiskCache>
#include <QStandardPaths>
#include <QThreadStorage> #include <QThreadStorage>
#include "NetworkAccessManager.h" #include "NetworkAccessManager.h"
const qint64 MAXIMUM_CACHE_SIZE = 10737418240; // 10GB
QThreadStorage<QNetworkAccessManager*> networkAccessManagers; QThreadStorage<QNetworkAccessManager*> networkAccessManagers;
QNetworkAccessManager& NetworkAccessManager::getInstance() { QNetworkAccessManager& NetworkAccessManager::getInstance() {
if (!networkAccessManagers.hasLocalData()) { if (!networkAccessManagers.hasLocalData()) {
networkAccessManagers.setLocalData(new QNetworkAccessManager()); QNetworkAccessManager* networkAccessManager = new QNetworkAccessManager();
QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
QNetworkDiskCache* cache = new QNetworkDiskCache();
cache->setMaximumCacheSize(MAXIMUM_CACHE_SIZE);
cache->setCacheDirectory(!cachePath.isEmpty() ? cachePath : "interfaceCache");
networkAccessManager->setCache(cache);
networkAccessManagers.setLocalData(networkAccessManager);
} }
return *networkAccessManagers.localData(); return *networkAccessManagers.localData();

View file

@ -23,7 +23,6 @@
#include <QtCore/QElapsedTimer> #include <QtCore/QElapsedTimer>
#include <QtCore/QMutex> #include <QtCore/QMutex>
#include <QtCore/QSet> #include <QtCore/QSet>
#include <QtCore/QSettings>
#include <QtCore/QSharedPointer> #include <QtCore/QSharedPointer>
#include <QtNetwork/QHostAddress> #include <QtNetwork/QHostAddress>
#include <QtNetwork/QUdpSocket> #include <QtNetwork/QUdpSocket>

View file

@ -9,9 +9,9 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include <QtCore/QSettings> #include <QSettings>
#include <QtCore/QString> #include <QString>
#include <QtCore/QStringList> #include <QStringList>
#include <QDebug> #include <QDebug>
#include <PacketHeaders.h> #include <PacketHeaders.h>
@ -209,9 +209,9 @@ JurisdictionMap::Area JurisdictionMap::isMyJurisdiction(const unsigned char* nod
bool JurisdictionMap::readFromFile(const char* filename) { bool JurisdictionMap::readFromFile(const char* filename) {
QString settingsFile(filename); QString settingsFile(filename);
QSettings settings(settingsFile, QSettings::IniFormat); QSettings settings(settingsFile, QSettings::IniFormat);
QString rootCode = settings.value("root","00").toString(); QString rootCode = settings.value("root","00").toString();
qDebug() << "rootCode=" << rootCode; qDebug() << "rootCode=" << rootCode;
_rootOctalCode = hexStringToOctalCode(rootCode); _rootOctalCode = hexStringToOctalCode(rootCode);

View file

@ -9,36 +9,29 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include <PacketHeaders.h>
//#include <SharedUtil.h>
#include <GLMHelpers.h> #include <GLMHelpers.h>
#include <PacketHeaders.h>
#include <Settings.h>
#include "OctreeConstants.h" #include "OctreeConstants.h"
#include "OctreeQuery.h" #include "OctreeQuery.h"
OctreeQuery::OctreeQuery() : namespace SettingHandles {
NodeData(), const SettingHandle<int> maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS);
_cameraPosition(0,0,0),
_cameraOrientation(),
_cameraFov(0.0f),
_cameraAspectRatio(0.0f),
_cameraNearClip(0.0f),
_cameraFarClip(0.0f),
_wantColor(true),
_wantDelta(true),
_wantLowResMoving(true),
_wantOcclusionCulling(false), // disabled by default
_wantCompression(false), // disabled by default
_maxOctreePPS(DEFAULT_MAX_OCTREE_PPS),
_octreeElementSizeScale(DEFAULT_OCTREE_SIZE_SCALE)
{
} }
OctreeQuery::~OctreeQuery() { OctreeQuery::OctreeQuery() {
// nothing to do _maxOctreePPS = SettingHandles::maxOctreePacketsPerSecond.get();
} }
void OctreeQuery::setMaxOctreePacketsPerSecond(int maxOctreePPS) {
if (maxOctreePPS != _maxOctreePPS) {
_maxOctreePPS = maxOctreePPS;
SettingHandles::maxOctreePacketsPerSecond.set(_maxOctreePPS);
}
}
int OctreeQuery::getBroadcastData(unsigned char* destinationBuffer) { int OctreeQuery::getBroadcastData(unsigned char* destinationBuffer) {
unsigned char* bufferStart = destinationBuffer; unsigned char* bufferStart = destinationBuffer;

View file

@ -45,7 +45,7 @@ class OctreeQuery : public NodeData {
public: public:
OctreeQuery(); OctreeQuery();
virtual ~OctreeQuery(); virtual ~OctreeQuery() {}
int getBroadcastData(unsigned char* destinationBuffer); int getBroadcastData(unsigned char* destinationBuffer);
int parseData(const QByteArray& packet); int parseData(const QByteArray& packet);
@ -86,29 +86,29 @@ public slots:
void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; } void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; }
void setWantOcclusionCulling(bool wantOcclusionCulling) { _wantOcclusionCulling = wantOcclusionCulling; } void setWantOcclusionCulling(bool wantOcclusionCulling) { _wantOcclusionCulling = wantOcclusionCulling; }
void setWantCompression(bool wantCompression) { _wantCompression = wantCompression; } void setWantCompression(bool wantCompression) { _wantCompression = wantCompression; }
void setMaxOctreePacketsPerSecond(int maxOctreePPS) { _maxOctreePPS = maxOctreePPS; } void setMaxOctreePacketsPerSecond(int maxOctreePPS);
void setOctreeSizeScale(float octreeSizeScale) { _octreeElementSizeScale = octreeSizeScale; } void setOctreeSizeScale(float octreeSizeScale) { _octreeElementSizeScale = octreeSizeScale; }
void setBoundaryLevelAdjust(int boundaryLevelAdjust) { _boundaryLevelAdjust = boundaryLevelAdjust; } void setBoundaryLevelAdjust(int boundaryLevelAdjust) { _boundaryLevelAdjust = boundaryLevelAdjust; }
protected: protected:
// camera details for the avatar // camera details for the avatar
glm::vec3 _cameraPosition; glm::vec3 _cameraPosition = glm::vec3(0.0f);
glm::quat _cameraOrientation; glm::quat _cameraOrientation = glm::quat();
float _cameraFov; float _cameraFov = 0.0f;
float _cameraAspectRatio; float _cameraAspectRatio = 0.0f;
float _cameraNearClip; float _cameraNearClip = 0.0f;
float _cameraFarClip; float _cameraFarClip = 0.0f;
glm::vec3 _cameraEyeOffsetPosition; glm::vec3 _cameraEyeOffsetPosition = glm::vec3(0.0f);
// octree server sending items // octree server sending items
bool _wantColor; bool _wantColor = true;
bool _wantDelta; bool _wantDelta = true;
bool _wantLowResMoving; bool _wantLowResMoving = true;
bool _wantOcclusionCulling; bool _wantOcclusionCulling = false;
bool _wantCompression; bool _wantCompression = false;
int _maxOctreePPS; int _maxOctreePPS = DEFAULT_MAX_OCTREE_PPS;
float _octreeElementSizeScale; /// used for LOD calculations float _octreeElementSizeScale = DEFAULT_OCTREE_SIZE_SCALE; /// used for LOD calculations
int _boundaryLevelAdjust; /// used for LOD calculations int _boundaryLevelAdjust = 0; /// used for LOD calculations
private: private:
// privatize the copy constructor and assignment operator so they cannot be called // privatize the copy constructor and assignment operator so they cannot be called

View file

@ -17,6 +17,8 @@
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <Settings.h>
#include "GeometryUtil.h" #include "GeometryUtil.h"
#include "SharedUtil.h" #include "SharedUtil.h"
#include "ViewFrustum.h" #include "ViewFrustum.h"
@ -24,38 +26,34 @@
using namespace std; using namespace std;
ViewFrustum::ViewFrustum() : namespace SettingHandles {
_position(0,0,0), const SettingHandle<float> fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES);
_positionVoxelScale(0,0,0), const SettingHandle<float> realWorldFieldOfView("realWorldFieldOfView", DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES);
_orientation(), }
_direction(IDENTITY_FRONT),
_up(IDENTITY_UP), ViewFrustum::ViewFrustum() {
_right(IDENTITY_RIGHT), _fieldOfView = SettingHandles::fieldOfView.get();
_orthographic(false), _realWorldFieldOfView = SettingHandles::realWorldFieldOfView.get();
_width(1.0f),
_height(1.0f),
_fieldOfView(0.0),
_aspectRatio(1.0f),
_nearClip(DEFAULT_NEAR_CLIP),
_farClip(DEFAULT_FAR_CLIP),
_focalLength(0.25f),
_keyholeRadius(DEFAULT_KEYHOLE_RADIUS),
_farTopLeft(0,0,0),
_farTopRight(0,0,0),
_farBottomLeft(0,0,0),
_farBottomRight(0,0,0),
_nearTopLeft(0,0,0),
_nearTopRight(0,0,0),
_nearBottomLeft(0,0,0),
_nearBottomRight(0,0,0)
{
} }
void ViewFrustum::setOrientation(const glm::quat& orientationAsQuaternion) { void ViewFrustum::setOrientation(const glm::quat& orientationAsQuaternion) {
_orientation = orientationAsQuaternion; _orientation = orientationAsQuaternion;
_right = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_RIGHT, 0.0f)); _right = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_RIGHT, 0.0f));
_up = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_UP, 0.0f)); _up = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_UP, 0.0f));
_direction = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_FRONT, 0.0f)); _direction = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_FRONT, 0.0f));
}
void ViewFrustum::setFieldOfView(float f) {
if (f != _fieldOfView) {
_fieldOfView = f;
SettingHandles::fieldOfView.set(f);
}
}
void ViewFrustum::setRealWorldFieldOfView(float realWorldFieldOfView) {
if (realWorldFieldOfView != _realWorldFieldOfView) {
_realWorldFieldOfView = realWorldFieldOfView;
SettingHandles::realWorldFieldOfView.set(realWorldFieldOfView);
}
} }
// ViewFrustum::calculateViewFrustum() // ViewFrustum::calculateViewFrustum()

View file

@ -34,6 +34,8 @@ const float DEFAULT_FAR_CLIP = TREE_SCALE;
class ViewFrustum { class ViewFrustum {
public: public:
ViewFrustum();
// setters for camera attributes // setters for camera attributes
void setPosition(const glm::vec3& p) { _position = p; _positionVoxelScale = (p / (float)TREE_SCALE); } void setPosition(const glm::vec3& p) { _position = p; _positionVoxelScale = (p / (float)TREE_SCALE); }
void setOrientation(const glm::quat& orientationAsQuaternion); void setOrientation(const glm::quat& orientationAsQuaternion);
@ -50,7 +52,8 @@ public:
void setOrthographic(bool orthographic) { _orthographic = orthographic; } void setOrthographic(bool orthographic) { _orthographic = orthographic; }
void setWidth(float width) { _width = width; } void setWidth(float width) { _width = width; }
void setHeight(float height) { _height = height; } void setHeight(float height) { _height = height; }
void setFieldOfView(float f) { _fieldOfView = f; } void setFieldOfView(float f);
void setRealWorldFieldOfView(float realWorldFieldOfView);
void setAspectRatio(float a) { _aspectRatio = a; } void setAspectRatio(float a) { _aspectRatio = a; }
void setNearClip(float n) { _nearClip = n; } void setNearClip(float n) { _nearClip = n; }
void setFarClip(float f) { _farClip = f; } void setFarClip(float f) { _farClip = f; }
@ -63,6 +66,7 @@ public:
float getWidth() const { return _width; } float getWidth() const { return _width; }
float getHeight() const { return _height; } float getHeight() const { return _height; }
float getFieldOfView() const { return _fieldOfView; } float getFieldOfView() const { return _fieldOfView; }
float getRealWorldFieldOfView() const { return _realWorldFieldOfView; }
float getAspectRatio() const { return _aspectRatio; } float getAspectRatio() const { return _aspectRatio; }
float getNearClip() const { return _nearClip; } float getNearClip() const { return _nearClip; }
float getFarClip() const { return _farClip; } float getFarClip() const { return _farClip; }
@ -91,8 +95,6 @@ public:
void calculate(); void calculate();
ViewFrustum();
typedef enum {OUTSIDE, INTERSECT, INSIDE} location; typedef enum {OUTSIDE, INTERSECT, INSIDE} location;
ViewFrustum::location pointInFrustum(const glm::vec3& point) const; ViewFrustum::location pointInFrustum(const glm::vec3& point) const;
@ -132,47 +134,52 @@ private:
ViewFrustum::location boxInKeyhole(const AABox& box) const; ViewFrustum::location boxInKeyhole(const AABox& box) const;
void calculateOrthographic(); void calculateOrthographic();
// camera location/orientation attributes // camera location/orientation attributes
glm::vec3 _position; // the position in TREE_SCALE glm::vec3 _position = glm::vec3(0.0f); // the position in TREE_SCALE
glm::vec3 _positionVoxelScale; // the position in voxel scale glm::vec3 _positionVoxelScale = glm::vec3(0.0f); // the position in voxel scale
glm::quat _orientation; glm::quat _orientation = glm::quat();
// calculated for orientation // calculated for orientation
glm::vec3 _direction; glm::vec3 _direction = IDENTITY_FRONT;
glm::vec3 _up; glm::vec3 _up = IDENTITY_UP;
glm::vec3 _right; glm::vec3 _right = IDENTITY_RIGHT;
// Lens attributes // Lens attributes
bool _orthographic; bool _orthographic = false;
float _width; float _width = 1.0f;
float _height; float _height = 1.0f;
float _fieldOfView; // degrees float _aspectRatio = 1.0f;
float _aspectRatio; float _nearClip = DEFAULT_NEAR_CLIP;
float _nearClip; float _farClip = DEFAULT_FAR_CLIP;
float _farClip; float _focalLength = 0.25f;
float _focalLength; glm::vec3 _eyeOffsetPosition = glm::vec3(0.0f);
glm::vec3 _eyeOffsetPosition; glm::quat _eyeOffsetOrientation = glm::quat();
glm::quat _eyeOffsetOrientation;
// in Degrees, doesn't apply to HMD like Oculus
float _fieldOfView = DEFAULT_FIELD_OF_VIEW_DEGREES;
// The actual FOV set by the user's monitor size and view distance
float _realWorldFieldOfView = DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES;
// keyhole attributes // keyhole attributes
float _keyholeRadius; float _keyholeRadius = DEFAULT_KEYHOLE_RADIUS;
AACube _keyholeBoundingCube; AACube _keyholeBoundingCube;
// Calculated values // Calculated values
glm::vec3 _offsetPosition; glm::vec3 _offsetPosition = glm::vec3(0.0f);
glm::vec3 _offsetDirection; glm::vec3 _offsetDirection = glm::vec3(0.0f);
glm::vec3 _offsetUp; glm::vec3 _offsetUp = glm::vec3(0.0f);
glm::vec3 _offsetRight; glm::vec3 _offsetRight = glm::vec3(0.0f);
glm::vec3 _farTopLeft; glm::vec3 _farTopLeft = glm::vec3(0.0f);
glm::vec3 _farTopRight; glm::vec3 _farTopRight = glm::vec3(0.0f);
glm::vec3 _farBottomLeft; glm::vec3 _farBottomLeft = glm::vec3(0.0f);
glm::vec3 _farBottomRight; glm::vec3 _farBottomRight = glm::vec3(0.0f);
glm::vec3 _nearTopLeft; glm::vec3 _nearTopLeft = glm::vec3(0.0f);
glm::vec3 _nearTopRight; glm::vec3 _nearTopRight = glm::vec3(0.0f);
glm::vec3 _nearBottomLeft; glm::vec3 _nearBottomLeft = glm::vec3(0.0f);
glm::vec3 _nearBottomRight; glm::vec3 _nearBottomRight = glm::vec3(0.0f);
enum { TOP_PLANE = 0, BOTTOM_PLANE, LEFT_PLANE, RIGHT_PLANE, NEAR_PLANE, FAR_PLANE }; enum { TOP_PLANE = 0, BOTTOM_PLANE, LEFT_PLANE, RIGHT_PLANE, NEAR_PLANE, FAR_PLANE };
::Plane _planes[6]; // How will this be used? ::Plane _planes[6]; // How will this be used?

View file

@ -168,6 +168,7 @@ public:
int getWindowSamples() const { return _windowStats.getSamples(); } int getWindowSamples() const { return _windowStats.getSamples(); }
double getWindowSum() const { return _windowStats.getSum(); } double getWindowSum() const { return _windowStats.getSum(); }
int getWindowIntervals() const { return _windowIntervals; }
T getCurrentIntervalMin() const { return _currentIntervalStats.getMin(); } T getCurrentIntervalMin() const { return _currentIntervalStats.getMin(); }
T getCurrentIntervalMax() const { return _currentIntervalStats.getMax(); } T getCurrentIntervalMax() const { return _currentIntervalStats.getMax(); }
double getCurrentIntervalAverage() const { return _currentIntervalStats.getAverage(); } double getCurrentIntervalAverage() const { return _currentIntervalStats.getAverage(); }

View file

@ -0,0 +1,43 @@
//
// Settings.cpp
//
//
// Created by Clement on 1/18/15.
// 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
//
#include <QSettings>
#include <QThread>
#include <QThreadStorage>
#include "Settings.h"
namespace SettingHandles {
static QThreadStorage<QSettings*> storage;
QSettings* getSettings() {
if (!storage.hasLocalData()) {
storage.setLocalData(new QSettings());
QObject::connect(QThread::currentThread(), &QThread::destroyed,
storage.localData(), &QSettings::deleteLater);
}
return storage.localData();
}
QVariant SettingsBridge::getFromSettings(const QString& key, const QVariant& defaultValue) {
return getSettings()->value(key, defaultValue);
}
void SettingsBridge::setInSettings(const QString& key, const QVariant& value) {
getSettings()->setValue(key, value);
}
void SettingsBridge::removeFromSettings(const QString& key) {
getSettings()->remove(key);
}
}

View file

@ -0,0 +1,121 @@
//
// Settings.h
//
//
// Created by Clement on 1/18/15.
// 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
//
#ifndef hifi_Settings_h
#define hifi_Settings_h
#include <QSettings>
#include <QString>
#include <QVariant>
// TODO: remove
class Settings : public QSettings {
};
namespace SettingHandles {
template <typename T>
class SettingHandle {
public:
SettingHandle(const QString& key);
SettingHandle(const QStringList& path);
SettingHandle(const QString& key, const T& defaultValue);
SettingHandle(const QStringList& path, const T& defaultValue);
T get() const; // Returns setting value, returns its default value if not found
T get(const T& other) const; // Returns setting value, returns other if not found
T getDefault() const;
void set(const T& value) const;
void reset() const;
void remove() const;
private:
const QString _key;
const QVariant _defaultValue;
};
class SettingsBridge {
private:
static QVariant getFromSettings(const QString& key, const QVariant& defaultValue);
static void setInSettings(const QString& key, const QVariant& value);
static void removeFromSettings(const QString& key);
template<typename T>
friend class SettingHandle;
};
template <typename T>
SettingHandle<T>::SettingHandle(const QString& key) : _key(key) {
}
template <typename T>
SettingHandle<T>::SettingHandle(const QStringList& path) : _key(path.join("/")) {
}
template <typename T>
SettingHandle<T>::SettingHandle(const QString& key, const T& defaultValue) :
_key(key),
_defaultValue(defaultValue) {
}
template <typename T>
SettingHandle<T>::SettingHandle(const QStringList& path, const T& defaultValue) :
_key(path.join("/")),
_defaultValue(defaultValue) {
}
template <typename T>
T SettingHandle<T>::get() const {
QVariant variant = SettingsBridge::getFromSettings(_key, _defaultValue);
if (variant.canConvert<T>()) {
return variant.value<T>();
}
return _defaultValue.value<T>();
}
template <typename T>
T SettingHandle<T>::get(const T& other) const {
QVariant variant = SettingsBridge::getFromSettings(_key, QVariant(other));
if (variant.canConvert<T>()) {
return variant.value<T>();
}
return other;
}
template <typename T> inline
T SettingHandle<T>::getDefault() const {
return _defaultValue.value<T>();
}
template <typename T> inline
void SettingHandle<T>::set(const T& value) const {
if (value != get()) {
SettingsBridge::setInSettings(_key, QVariant(value));
}
}
template <typename T> inline
void SettingHandle<T>::reset() const {
SettingsBridge::setInSettings(_key, _defaultValue);
}
template <typename T> inline
void SettingHandle<T>::remove() const {
SettingsBridge::removeFromSettings(_key);
}
}
#endif // hifi_Settings_h