From ec73edb8d88f80195d6b9708d6b6847db00c4cf4 Mon Sep 17 00:00:00 2001 From: stojce Date: Sun, 23 Feb 2014 13:54:22 +0100 Subject: [PATCH 01/23] restyled preferences dialog - Frameless dialog super class --- interface/resources/styles/global.qss | 35 ++ interface/src/Menu.cpp | 139 +----- interface/src/Menu.h | 2 + interface/src/ui/FramelessDialog.cpp | 23 + interface/src/ui/FramelessDialog.h | 27 ++ interface/src/ui/PreferencesDialog.cpp | 96 ++++ interface/src/ui/PreferencesDialog.h | 37 ++ interface/ui/preferencesDialog.ui | 646 +++++++++++++++++++++++++ 8 files changed, 871 insertions(+), 134 deletions(-) create mode 100644 interface/resources/styles/global.qss create mode 100644 interface/src/ui/FramelessDialog.cpp create mode 100644 interface/src/ui/FramelessDialog.h create mode 100644 interface/src/ui/PreferencesDialog.cpp create mode 100644 interface/src/ui/PreferencesDialog.h create mode 100644 interface/ui/preferencesDialog.ui diff --git a/interface/resources/styles/global.qss b/interface/resources/styles/global.qss new file mode 100644 index 0000000000..3ecb96fa8c --- /dev/null +++ b/interface/resources/styles/global.qss @@ -0,0 +1,35 @@ +* { + padding: 0; + margin: 0; +} + +FramelessDialog { + background-color: rgb(255, 255, 255); + font-family: Helvetica, Arial, sans-serif; + font-size: 16px; +} + +QLineEdit { + background-color: rgba(255, 255, 255, 1); + border-style: solid; + border-width: 1px; + border-color: #ccc; + padding: 7px; + opacity: 1; +} + +QLabel p { + color: #0e7077; + font-size: 23px; +} + +QPushButton { + border-width: 0; + border-radius: 9px; + border-radius: 9px; + font-family: Arial; + font-size: 18px; + font-weight: 100; + color: #ffffff; + padding: 10px 15px; +} diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 327f905194..e3fd698ecf 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -71,7 +71,8 @@ Menu::Menu() : _voxelSizeScale(DEFAULT_OCTREE_SIZE_SCALE), _boundaryLevelAdjust(0), _maxVoxelPacketsPerSecond(DEFAULT_MAX_VOXEL_PPS), - _lastAdjust(usecTimestampNow()) + _lastAdjust(usecTimestampNow()), + _preferencesDialog() { Application *appInstance = Application::getInstance(); @@ -763,140 +764,10 @@ void Menu::login() { } void Menu::editPreferences() { - Application* applicationInstance = Application::getInstance(); - - QDialog dialog(applicationInstance->getWindow()); - dialog.setWindowTitle("Interface Preferences"); - QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom); - dialog.setLayout(layout); - - QFormLayout* form = new QFormLayout(); - layout->addLayout(form, 1); - - QString faceURLString = applicationInstance->getAvatar()->getHead()->getFaceModel().getURL().toString(); - QLineEdit* faceURLEdit = new QLineEdit(faceURLString); - faceURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); - faceURLEdit->setPlaceholderText(DEFAULT_HEAD_MODEL_URL.toString()); - form->addRow("Face URL:", faceURLEdit); - - QString skeletonURLString = applicationInstance->getAvatar()->getSkeletonModel().getURL().toString(); - QLineEdit* skeletonURLEdit = new QLineEdit(skeletonURLString); - skeletonURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); - skeletonURLEdit->setPlaceholderText(DEFAULT_BODY_MODEL_URL.toString()); - form->addRow("Skeleton URL:", skeletonURLEdit); - - QString displayNameString = applicationInstance->getAvatar()->getDisplayName(); - QLineEdit* displayNameEdit = new QLineEdit(displayNameString); - displayNameEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); - form->addRow("Display name:", displayNameEdit); - - QSlider* pupilDilation = new QSlider(Qt::Horizontal); - pupilDilation->setValue(applicationInstance->getAvatar()->getHead()->getPupilDilation() * pupilDilation->maximum()); - form->addRow("Pupil Dilation:", pupilDilation); - - QSlider* faceshiftEyeDeflection = new QSlider(Qt::Horizontal); - faceshiftEyeDeflection->setValue(_faceshiftEyeDeflection * faceshiftEyeDeflection->maximum()); - form->addRow("Faceshift Eye Deflection:", faceshiftEyeDeflection); - - QSpinBox* fieldOfView = new QSpinBox(); - fieldOfView->setMaximum(180); - fieldOfView->setMinimum(1); - fieldOfView->setValue(_fieldOfView); - form->addRow("Vertical Field of View (Degrees):", fieldOfView); - - QDoubleSpinBox* leanScale = new QDoubleSpinBox(); - leanScale->setValue(applicationInstance->getAvatar()->getLeanScale()); - form->addRow("Lean Scale:", leanScale); - - QDoubleSpinBox* avatarScale = new QDoubleSpinBox(); - avatarScale->setValue(applicationInstance->getAvatar()->getScale()); - form->addRow("Avatar Scale:", avatarScale); - - QSpinBox* audioJitterBufferSamples = new QSpinBox(); - audioJitterBufferSamples->setMaximum(10000); - audioJitterBufferSamples->setMinimum(-10000); - audioJitterBufferSamples->setValue(_audioJitterBufferSamples); - form->addRow("Audio Jitter Buffer Samples (0 for automatic):", audioJitterBufferSamples); - - QSpinBox* maxVoxels = new QSpinBox(); - const int MAX_MAX_VOXELS = 5000000; - const int MIN_MAX_VOXELS = 0; - const int STEP_MAX_VOXELS = 50000; - maxVoxels->setMaximum(MAX_MAX_VOXELS); - maxVoxels->setMinimum(MIN_MAX_VOXELS); - maxVoxels->setSingleStep(STEP_MAX_VOXELS); - maxVoxels->setValue(_maxVoxels); - form->addRow("Maximum Voxels:", maxVoxels); - - QSpinBox* maxVoxelsPPS = new QSpinBox(); - const int MAX_MAX_VOXELS_PPS = 6000; - const int MIN_MAX_VOXELS_PPS = 60; - const int STEP_MAX_VOXELS_PPS = 10; - maxVoxelsPPS->setMaximum(MAX_MAX_VOXELS_PPS); - maxVoxelsPPS->setMinimum(MIN_MAX_VOXELS_PPS); - maxVoxelsPPS->setSingleStep(STEP_MAX_VOXELS_PPS); - maxVoxelsPPS->setValue(_maxVoxelPacketsPerSecond); - form->addRow("Maximum Voxels Packets Per Second:", maxVoxelsPPS); - - QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept())); - dialog.connect(buttons, SIGNAL(rejected()), SLOT(reject())); - layout->addWidget(buttons); - - int ret = dialog.exec(); - if (ret == QDialog::Accepted) { - QUrl faceModelURL(faceURLEdit->text()); - - bool shouldDispatchIdentityPacket = false; - - if (faceModelURL.toString() != faceURLString) { - // change the faceModelURL in the profile, it will also update this user's BlendFace - applicationInstance->getAvatar()->setFaceModelURL(faceModelURL); - shouldDispatchIdentityPacket = true; - } - - QUrl skeletonModelURL(skeletonURLEdit->text()); - - if (skeletonModelURL.toString() != skeletonURLString) { - // change the skeletonModelURL in the profile, it will also update this user's Body - applicationInstance->getAvatar()->setSkeletonModelURL(skeletonModelURL); - shouldDispatchIdentityPacket = true; - } - - QString displayNameStr(displayNameEdit->text()); - - if (displayNameStr != displayNameString) { - applicationInstance->getAvatar()->setDisplayName(displayNameStr); - shouldDispatchIdentityPacket = true; - } - - if (shouldDispatchIdentityPacket) { - applicationInstance->getAvatar()->sendIdentityPacket(); - } - - applicationInstance->getAvatar()->getHead()->setPupilDilation(pupilDilation->value() / (float)pupilDilation->maximum()); - - _maxVoxels = maxVoxels->value(); - applicationInstance->getVoxels()->setMaxVoxels(_maxVoxels); - - _maxVoxelPacketsPerSecond = maxVoxelsPPS->value(); - - applicationInstance->getAvatar()->setLeanScale(leanScale->value()); - applicationInstance->getAvatar()->setClampedTargetScale(avatarScale->value()); - - _audioJitterBufferSamples = audioJitterBufferSamples->value(); - - if (_audioJitterBufferSamples != 0) { - applicationInstance->getAudio()->setJitterBufferSamples(_audioJitterBufferSamples); - } - - _fieldOfView = fieldOfView->value(); - applicationInstance->resizeGL(applicationInstance->getGLWidget()->width(), applicationInstance->getGLWidget()->height()); - - _faceshiftEyeDeflection = faceshiftEyeDeflection->value() / (float)faceshiftEyeDeflection->maximum(); + if (! _preferencesDialog) { + _preferencesDialog = new PreferencesDialog(Application::getInstance()->getGLWidget()); } - - sendFakeEnterEvent(); + _preferencesDialog->show(); } void Menu::goToDomain(const QString newDomain) { diff --git a/interface/src/Menu.h b/interface/src/Menu.h index bd9cdc523e..4e75bc6fb9 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -15,6 +15,7 @@ #include #include +#include "ui/PreferencesDialog.h" const float ADJUST_LOD_DOWN_FPS = 40.0; const float ADJUST_LOD_UP_FPS = 55.0; @@ -173,6 +174,7 @@ private: QMenu* _activeScriptsMenu; QString replaceLastOccurrence(QChar search, QChar replace, QString string); quint64 _lastAdjust; + QPointer _preferencesDialog; }; namespace MenuOption { diff --git a/interface/src/ui/FramelessDialog.cpp b/interface/src/ui/FramelessDialog.cpp new file mode 100644 index 0000000000..ddd056fd32 --- /dev/null +++ b/interface/src/ui/FramelessDialog.cpp @@ -0,0 +1,23 @@ +// +// FramelessDialog.cpp +// hifi +// +// Created by Stojce Slavkovski on 2/20/14. +// +// + +#include "FramelessDialog.h" +#include +#include + +FramelessDialog::FramelessDialog(QWidget *parent, Qt::WindowFlags flags) : QDialog(parent, flags | Qt::FramelessWindowHint) { + QFile styleSheet("resources/styles/global.qss"); + if (styleSheet.open(QIODevice::ReadOnly)) { + setStyleSheet(styleSheet.readAll()); + } + setWindowOpacity(0.95); +} + +FramelessDialog::~FramelessDialog() { + +} diff --git a/interface/src/ui/FramelessDialog.h b/interface/src/ui/FramelessDialog.h new file mode 100644 index 0000000000..ca11c3eb2f --- /dev/null +++ b/interface/src/ui/FramelessDialog.h @@ -0,0 +1,27 @@ +// +// FramelessDialog.h +// hifi +// +// Created by Stojce Slavkovski on 2/20/14. +// +// + +#ifndef __hifi__FramelessDialog__ +#define __hifi__FramelessDialog__ + +#include +#include +#include +#include +#include + +class FramelessDialog : public QDialog { + Q_OBJECT + +public: + FramelessDialog(QWidget* parent = 0, Qt::WindowFlags flags = 0); + ~FramelessDialog(); + +}; + +#endif /* defined(__hifi__FramelessDialog__) */ diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp new file mode 100644 index 0000000000..df3e94f31f --- /dev/null +++ b/interface/src/ui/PreferencesDialog.cpp @@ -0,0 +1,96 @@ +// +// PreferencesDialog.cpp +// hifi +// +// Created by Stojce Slavkovski on 2/22/14. +// +// + +#include "PreferencesDialog.h" +#include "Application.h" +#include "Menu.h" + +PreferencesDialog::PreferencesDialog(QWidget* parent, Qt::WindowFlags flags) : FramelessDialog(parent, flags) { + ui.setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + loadPreferences(); +} + +void PreferencesDialog::accept() { + savePreferences(); + close(); +} + +void PreferencesDialog::loadPreferences() { + + MyAvatar* myAvatar = Application::getInstance()->getAvatar(); + Menu* menuInstance = Menu::getInstance(); + + _displayNameString = myAvatar->getDisplayName(); + ui.displayNameEdit->setText(_displayNameString); + + _faceURLString = myAvatar->getHead()->getFaceModel().getURL().toString(); + ui.faceURLEdit->setText(_faceURLString); + + _skeletonURLString = myAvatar->getSkeletonModel().getURL().toString(); + ui.skeletonURLEdit->setText(_skeletonURLString); + + float pupilDilation = myAvatar->getHead()->getPupilDilation(); + ui.pupilDilationSlider->setValue(pupilDilation * ui.pupilDilationSlider->maximum()); + + ui.faceshiftEyeDeflectionSider->setValue(menuInstance->getFaceshiftEyeDeflection() * + ui.faceshiftEyeDeflectionSider->maximum()); + + ui.fieldOfViewSpin->setValue(menuInstance->getFieldOfView() * ui.fieldOfViewSpin->maximum()); + + ui.leanScaleSpin->setValue(myAvatar->getLeanScale()); + + ui.avatarScaleSpin->setValue(myAvatar->getScale()); + + ui.maxVoxelsSpin->setValue(menuInstance->getMaxVoxels()); + + ui.maxVoxelsPPSSpin->setValue(menuInstance->getMaxVoxelPacketsPerSecond()); +} + +void PreferencesDialog::savePreferences() { + + MyAvatar* myAvatar = Application::getInstance()->getAvatar(); + bool shouldDispatchIdentityPacket = false; + + QString displayNameStr(ui.displayNameEdit->text()); + if (displayNameStr != _displayNameString) { + myAvatar->setDisplayName(displayNameStr); + shouldDispatchIdentityPacket = true; + } + + QUrl faceModelURL(ui.faceURLEdit->text()); + if (faceModelURL.toString() != _faceURLString) { + // change the faceModelURL in the profile, it will also update this user's BlendFace + myAvatar->setFaceModelURL(faceModelURL); + shouldDispatchIdentityPacket = true; + } + + QUrl skeletonModelURL(ui.skeletonURLEdit->text()); + if (skeletonModelURL.toString() != _skeletonURLString) { + // change the skeletonModelURL in the profile, it will also update this user's Body + myAvatar->setSkeletonModelURL(skeletonModelURL); + shouldDispatchIdentityPacket = true; + } + + if (shouldDispatchIdentityPacket) { + myAvatar->sendIdentityPacket(); + } + + myAvatar->getHead()->setPupilDilation(ui.pupilDilationSlider->value() / (float)ui.pupilDilationSlider->maximum()); + Application::getInstance()->getVoxels()->setMaxVoxels(ui.maxVoxelsSpin->value()); + + + myAvatar->setLeanScale(ui.leanScaleSpin->value()); + myAvatar->setClampedTargetScale(ui.avatarScaleSpin->value()); + + Application::getInstance()->resizeGL(Application::getInstance()->getGLWidget()->width(), + Application::getInstance()->getGLWidget()->height()); + + // _maxVoxelPacketsPerSecond = maxVoxelsPPS->value(); + // _faceshiftEyeDeflection = faceshiftEyeDeflection->value() / (float)faceshiftEyeDeflection->maximum(); +} diff --git a/interface/src/ui/PreferencesDialog.h b/interface/src/ui/PreferencesDialog.h new file mode 100644 index 0000000000..d5cb41c7df --- /dev/null +++ b/interface/src/ui/PreferencesDialog.h @@ -0,0 +1,37 @@ +// +// PreferencesDialog.h +// hifi +// +// Created by Stojce Slavkovski on 2/22/14. +// +// + +#ifndef __hifi__PreferencesDialog__ +#define __hifi__PreferencesDialog__ + +#include "FramelessDialog.h" +#include "ui_preferencesDialog.h" + +#include + +class PreferencesDialog : public FramelessDialog { + Q_OBJECT + +public: + PreferencesDialog(QWidget* parent = 0, Qt::WindowFlags flags = 0); + +private: + Ui_PreferencesDialog ui; + void loadPreferences(); + void savePreferences(); + + QString _faceURLString; + QString _skeletonURLString; + QString _displayNameString; + +private slots: + void accept(); + +}; + +#endif /* defined(__hifi__PreferencesDialog__) */ diff --git a/interface/ui/preferencesDialog.ui b/interface/ui/preferencesDialog.ui new file mode 100644 index 0000000000..7c89eb15c9 --- /dev/null +++ b/interface/ui/preferencesDialog.ui @@ -0,0 +1,646 @@ + + + PreferencesDialog + + + + 0 + 0 + 611 + 745 + + + + + + 30 + 30 + 555 + 596 + + + + + + + + 23 + + + + color: #0e7077 + + + Avatar + + + faceURLEdit + + + + + + + + 0 + 0 + + + + color: #0e7077 + + + <html><head/><body><p>Avatar display name <span style=" color:#909090;">(optional)</span></p></body></html> + + + displayNameEdit + + + + + + + + 0 + 0 + + + + + 280 + 0 + + + + Qt::LeftToRight + + + + + + Not showing a name + + + + + + + color: #0e7077 + + + Head + + + faceURLEdit + + + + + + + + + + color: #0e7077 + + + Body + + + faceURLEdit + + + + + + + + + + + 23 + + + + color: #0e7077 + + + Advanced Tuning + + + + + + + It's not recomended that you play with these settings unless you've looked into exactly what they do. + + + false + + + true + + + + + + + + 20 + 50 + false + + + + color: #0e7077 + + + <p>Avatar</p> + + + + + + + + 0 + 0 + + + + background-color: #fff + + + + + 7 + 0 + 531 + 26 + + + + + + + Lean scale (applies to Faceshift users) + + + leanScaleSpin + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + Vertical field of view + + + fieldOfViewSpin + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 1 + + + 180 + + + + + + + + + + 0 + 0 + + + + background-color: #fff + + + + + 7 + 0 + 531 + 26 + + + + + + + Avatar scale (default is 1.0) + + + avatarScaleSpin + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + Pupil dillation + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + + + + + + 0 + 0 + + + + background-color: #fff + + + + + 7 + 0 + 531 + 26 + + + + + + + Faceshift eye detection + + + avatarScaleSpin + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + + + + + + + + 20 + 50 + false + + + + color: #0e7077 + + + <html><head/><body><p>Voxels</p></body></html> + + + + + + + + 0 + 0 + + + + background-color: #fff + + + + + 7 + 0 + 531 + 26 + + + + + + + Maximum voxels + + + leanScaleSpin + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 5000000 + + + 50000 + + + + + + + + + + + + 0 + 0 + + + + background-color: #fff + + + + + 7 + 0 + 531 + 26 + + + + + + + Max voxels sent each second + + + leanScaleSpin + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 60 + + + 6000 + + + 10 + + + + + + + + + + + + + 0 + 665 + 616 + 80 + + + + background-color: #0e7077 + + + + + 0 + 20 + 591 + 41 + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + Cancel + + + + + + + background-color: #fff; +color: #0e7077 + + + Save all changes + + + true + + + + + + + + + + FramelessDialog + 1 + + + + displayNameEdit + faceURLEdit + leanScaleSpin + fieldOfViewSpin + avatarScaleSpin + pupilDilationSlider + + + + + cancelButton + clicked() + PreferencesDialog + close() + + + 372 + 700 + + + 528 + -9 + + + + + defaultButton + clicked() + PreferencesDialog + accept() + + + 20 + 20 + + + 20 + 20 + + + + + From 1e2cd0c1a2c93b3d3b4ff8301e5e1af15e5a0a26 Mon Sep 17 00:00:00 2001 From: stojce Date: Tue, 25 Feb 2014 20:36:14 +0100 Subject: [PATCH 02/23] UI changes --- interface/resources/styles/avatar.svg | 27 + interface/resources/styles/close.svg | 14 + interface/resources/styles/down.svg | 9 + interface/resources/styles/slider-bg.svg | 10 + interface/resources/styles/slider-handle.svg | 10 + interface/resources/styles/up.svg | 9 + interface/resources/styles/wrench.svg | 9 + interface/src/Menu.h | 5 +- interface/src/ui/PreferencesDialog.cpp | 20 +- interface/ui/preferencesDialog.ui | 493 ++++++++----------- 10 files changed, 320 insertions(+), 286 deletions(-) create mode 100644 interface/resources/styles/avatar.svg create mode 100644 interface/resources/styles/close.svg create mode 100644 interface/resources/styles/down.svg create mode 100644 interface/resources/styles/slider-bg.svg create mode 100644 interface/resources/styles/slider-handle.svg create mode 100644 interface/resources/styles/up.svg create mode 100644 interface/resources/styles/wrench.svg diff --git a/interface/resources/styles/avatar.svg b/interface/resources/styles/avatar.svg new file mode 100644 index 0000000000..f9382edee4 --- /dev/null +++ b/interface/resources/styles/avatar.svg @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/interface/resources/styles/close.svg b/interface/resources/styles/close.svg new file mode 100644 index 0000000000..8fe4bf4bdb --- /dev/null +++ b/interface/resources/styles/close.svg @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/interface/resources/styles/down.svg b/interface/resources/styles/down.svg new file mode 100644 index 0000000000..983ccd9597 --- /dev/null +++ b/interface/resources/styles/down.svg @@ -0,0 +1,9 @@ + + + + + + diff --git a/interface/resources/styles/slider-bg.svg b/interface/resources/styles/slider-bg.svg new file mode 100644 index 0000000000..36c6478026 --- /dev/null +++ b/interface/resources/styles/slider-bg.svg @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/interface/resources/styles/slider-handle.svg b/interface/resources/styles/slider-handle.svg new file mode 100644 index 0000000000..5d87e8599c --- /dev/null +++ b/interface/resources/styles/slider-handle.svg @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/interface/resources/styles/up.svg b/interface/resources/styles/up.svg new file mode 100644 index 0000000000..d122c4801e --- /dev/null +++ b/interface/resources/styles/up.svg @@ -0,0 +1,9 @@ + + + + + + diff --git a/interface/resources/styles/wrench.svg b/interface/resources/styles/wrench.svg new file mode 100644 index 0000000000..5019f92b18 --- /dev/null +++ b/interface/resources/styles/wrench.svg @@ -0,0 +1,9 @@ + + + + + + diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 5c1e26933d..81089473d3 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -65,10 +65,12 @@ public: void triggerOption(const QString& menuOption); QAction* getActionForOption(const QString& menuOption); bool isVoxelModeActionChecked(); - + float getAudioJitterBufferSamples() const { return _audioJitterBufferSamples; } + void setAudioJitterBufferSamples(int audioJitterBufferSamples) { _audioJitterBufferSamples = audioJitterBufferSamples; } float getFieldOfView() const { return _fieldOfView; } float getFaceshiftEyeDeflection() const { return _faceshiftEyeDeflection; } + void setFaceshiftEyeDeflection(float faceshiftEyeDeflection) { _faceshiftEyeDeflection = faceshiftEyeDeflection; } BandwidthDialog* getBandwidthDialog() const { return _bandwidthDialog; } FrustumDrawMode getFrustumDrawMode() const { return _frustumDrawMode; } ViewFrustumOffset getViewFrustumOffset() const { return _viewFrustumOffset; } @@ -89,6 +91,7 @@ public: // User Tweakable PPS from Voxel Server int getMaxVoxelPacketsPerSecond() const { return _maxVoxelPacketsPerSecond; } + void setMaxVoxelPacketsPerSecond(int maxVoxelPacketsPerSecond) { _maxVoxelPacketsPerSecond = maxVoxelPacketsPerSecond; } virtual QMenu* getActiveScriptsMenu() { return _activeScriptsMenu;} virtual QAction* addActionToQMenuAndActionHash(QMenu* destinationMenu, diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index df3e94f31f..de585d0a2a 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -35,13 +35,15 @@ void PreferencesDialog::loadPreferences() { _skeletonURLString = myAvatar->getSkeletonModel().getURL().toString(); ui.skeletonURLEdit->setText(_skeletonURLString); - float pupilDilation = myAvatar->getHead()->getPupilDilation(); - ui.pupilDilationSlider->setValue(pupilDilation * ui.pupilDilationSlider->maximum()); + ui.pupilDilationSlider->setValue(myAvatar->getHead()->getPupilDilation() * + ui.pupilDilationSlider->maximum()); ui.faceshiftEyeDeflectionSider->setValue(menuInstance->getFaceshiftEyeDeflection() * ui.faceshiftEyeDeflectionSider->maximum()); - ui.fieldOfViewSpin->setValue(menuInstance->getFieldOfView() * ui.fieldOfViewSpin->maximum()); + ui.audioJitterSpin->setValue(menuInstance->getAudioJitterBufferSamples()); + + ui.fieldOfViewSpin->setValue(menuInstance->getFieldOfView()); ui.leanScaleSpin->setValue(myAvatar->getLeanScale()); @@ -82,15 +84,17 @@ void PreferencesDialog::savePreferences() { } myAvatar->getHead()->setPupilDilation(ui.pupilDilationSlider->value() / (float)ui.pupilDilationSlider->maximum()); - Application::getInstance()->getVoxels()->setMaxVoxels(ui.maxVoxelsSpin->value()); - - myAvatar->setLeanScale(ui.leanScaleSpin->value()); myAvatar->setClampedTargetScale(ui.avatarScaleSpin->value()); + Application::getInstance()->getVoxels()->setMaxVoxels(ui.maxVoxelsSpin->value()); Application::getInstance()->resizeGL(Application::getInstance()->getGLWidget()->width(), Application::getInstance()->getGLWidget()->height()); + + Menu::getInstance()->setFaceshiftEyeDeflection(ui.faceshiftEyeDeflectionSider->value() / + (float)ui.faceshiftEyeDeflectionSider->maximum()); + Menu::getInstance()->setMaxVoxelPacketsPerSecond(ui.maxVoxelsPPSSpin->value()); + + Menu::getInstance()->setAudioJitterBufferSamples(ui.audioJitterSpin->value()); - // _maxVoxelPacketsPerSecond = maxVoxelsPPS->value(); - // _faceshiftEyeDeflection = faceshiftEyeDeflection->value() / (float)faceshiftEyeDeflection->maximum(); } diff --git a/interface/ui/preferencesDialog.ui b/interface/ui/preferencesDialog.ui index 7c89eb15c9..8fed57c06b 100644 --- a/interface/ui/preferencesDialog.ui +++ b/interface/ui/preferencesDialog.ui @@ -7,16 +7,16 @@ 0 0 611 - 745 + 805 30 - 30 + 0 555 - 596 + 701 @@ -96,7 +96,14 @@ - + + + + 0 + 0 + + + @@ -160,55 +167,34 @@ - - - - 0 - 0 - - - - background-color: #fff - - - - - 7 - 0 - 531 - 26 - - - - - - - Lean scale (applies to Faceshift users) - - - leanScaleSpin - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - + + + + + Lean scale (applies to Faceshift users) + + + leanScaleSpin + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + @@ -248,55 +234,34 @@ - - - - 0 - 0 - - - - background-color: #fff - - - - - 7 - 0 - 531 - 26 - - - - - - - Avatar scale (default is 1.0) - - - avatarScaleSpin - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - + + + + + Avatar scale (default is 1.0) + + + avatarScaleSpin + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + @@ -336,65 +301,81 @@ - - - - 0 - 0 - - - - background-color: #fff - - - - - 7 - 0 - 531 - 26 - - - - - - - Faceshift eye detection - - - avatarScaleSpin - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - Qt::Horizontal - - - - - - + + + + + Audio Jitter Buffer Samples (0 for automatic) + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + -10000 + + + 10000 + + + 1 + + + + + + + + + + + Faceshift eye detection + + + avatarScaleSpin + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + @@ -414,123 +395,81 @@ - - - - 0 - 0 - - - - background-color: #fff - - - - - 7 - 0 - 531 - 26 - - - - - - - Maximum voxels - - - leanScaleSpin - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 5000000 - - - 50000 - - - - - - + + + + + Maximum voxels + + + leanScaleSpin + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 5000000 + + + 50000 + + + + - - - - 0 - 0 - - - - background-color: #fff - - - - - 7 - 0 - 531 - 26 - - - - - - - Max voxels sent each second - - - leanScaleSpin - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 60 - - - 6000 - - - 10 - - - - - - + + + + + Max voxels sent each second + + + leanScaleSpin + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 60 + + + 6000 + + + 10 + + + + @@ -538,7 +477,7 @@ 0 - 665 + 725 616 80 From 303fddd93b6ba503557236b4f35e3701561fc2ec Mon Sep 17 00:00:00 2001 From: stojce Date: Tue, 25 Feb 2014 21:19:43 +0100 Subject: [PATCH 03/23] Bad merge fix --- interface/src/Menu.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 5f8cc5c4dc..662f91548f 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -71,8 +71,6 @@ Menu::Menu() : _boundaryLevelAdjust(0), _maxVoxelPacketsPerSecond(DEFAULT_MAX_VOXEL_PPS), _lastAdjust(usecTimestampNow()), - _loginAction(NULL) - _lastAdjust(usecTimestampNow()), _preferencesDialog() { Application *appInstance = Application::getInstance(); From 6383457e4e11f777c109e1fbec832569904026e8 Mon Sep 17 00:00:00 2001 From: stojce Date: Wed, 26 Feb 2014 22:15:12 +0100 Subject: [PATCH 04/23] styling bad merge fix --- interface/resources/styles/global.qss | 32 +++++- interface/src/Menu.cpp | 135 +------------------------ interface/src/ui/FramelessDialog.cpp | 1 + interface/src/ui/PreferencesDialog.cpp | 1 - 4 files changed, 35 insertions(+), 134 deletions(-) diff --git a/interface/resources/styles/global.qss b/interface/resources/styles/global.qss index 3ecb96fa8c..e3548fb52e 100644 --- a/interface/resources/styles/global.qss +++ b/interface/resources/styles/global.qss @@ -26,10 +26,40 @@ QLabel p { QPushButton { border-width: 0; border-radius: 9px; - border-radius: 9px; font-family: Arial; font-size: 18px; font-weight: 100; color: #ffffff; padding: 10px 15px; } + + +QSpinBox { + padding: 5px; + border-width: 1; + +} + +QSpinBox::up-button { + + width: 25px; + height: 18px; + background-image: url(resources/styles/up.svg); + background-repeat: no-repeat; + border: 1px #ccc solid; + + border-top-left-radius: 2px; + border-top-right-radius: 2px; +} + +QSpinBox::down-button { + + width: 25px; + height: 18px; + background-image: url(resources/styles/down.svg); + background-repeat: no-repeat; + border: 1px #ccc solid; + + border-top-left-radius: 2px; + border-top-right-radius: 2px; +} diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 662f91548f..d3a0d7f8c1 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -792,139 +792,10 @@ void Menu::loginForCurrentDomain() { } void Menu::editPreferences() { - Application* applicationInstance = Application::getInstance(); - - QDialog dialog(applicationInstance->getWindow()); - dialog.setWindowTitle("Interface Preferences"); - - QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom); - dialog.setLayout(layout); - - QFormLayout* form = new QFormLayout(); - layout->addLayout(form, 1); - - QString faceURLString = applicationInstance->getAvatar()->getHead()->getFaceModel().getURL().toString(); - QLineEdit* faceURLEdit = new QLineEdit(faceURLString); - faceURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); - faceURLEdit->setPlaceholderText(DEFAULT_HEAD_MODEL_URL.toString()); - form->addRow("Face URL:", faceURLEdit); - - QString skeletonURLString = applicationInstance->getAvatar()->getSkeletonModel().getURL().toString(); - QLineEdit* skeletonURLEdit = new QLineEdit(skeletonURLString); - skeletonURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); - skeletonURLEdit->setPlaceholderText(DEFAULT_BODY_MODEL_URL.toString()); - form->addRow("Skeleton URL:", skeletonURLEdit); - - QString displayNameString = applicationInstance->getAvatar()->getDisplayName(); - QLineEdit* displayNameEdit = new QLineEdit(displayNameString); - displayNameEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); - form->addRow("Display name:", displayNameEdit); - - QSlider* pupilDilation = new QSlider(Qt::Horizontal); - pupilDilation->setValue(applicationInstance->getAvatar()->getHead()->getPupilDilation() * pupilDilation->maximum()); - form->addRow("Pupil Dilation:", pupilDilation); - - QSlider* faceshiftEyeDeflection = new QSlider(Qt::Horizontal); - faceshiftEyeDeflection->setValue(_faceshiftEyeDeflection * faceshiftEyeDeflection->maximum()); - form->addRow("Faceshift Eye Deflection:", faceshiftEyeDeflection); - - QSpinBox* fieldOfView = new QSpinBox(); - fieldOfView->setMaximum(180); - fieldOfView->setMinimum(1); - fieldOfView->setValue(_fieldOfView); - form->addRow("Vertical Field of View (Degrees):", fieldOfView); - - QDoubleSpinBox* leanScale = new QDoubleSpinBox(); - leanScale->setValue(applicationInstance->getAvatar()->getLeanScale()); - form->addRow("Lean Scale:", leanScale); - - QDoubleSpinBox* avatarScale = new QDoubleSpinBox(); - avatarScale->setValue(applicationInstance->getAvatar()->getScale()); - form->addRow("Avatar Scale:", avatarScale); - - QSpinBox* audioJitterBufferSamples = new QSpinBox(); - audioJitterBufferSamples->setMaximum(10000); - audioJitterBufferSamples->setMinimum(-10000); - audioJitterBufferSamples->setValue(_audioJitterBufferSamples); - form->addRow("Audio Jitter Buffer Samples (0 for automatic):", audioJitterBufferSamples); - - QSpinBox* maxVoxels = new QSpinBox(); - const int MAX_MAX_VOXELS = 5000000; - const int MIN_MAX_VOXELS = 0; - const int STEP_MAX_VOXELS = 50000; - maxVoxels->setMaximum(MAX_MAX_VOXELS); - maxVoxels->setMinimum(MIN_MAX_VOXELS); - maxVoxels->setSingleStep(STEP_MAX_VOXELS); - maxVoxels->setValue(_maxVoxels); - form->addRow("Maximum Voxels:", maxVoxels); - - QSpinBox* maxVoxelsPPS = new QSpinBox(); - const int MAX_MAX_VOXELS_PPS = 6000; - const int MIN_MAX_VOXELS_PPS = 60; - const int STEP_MAX_VOXELS_PPS = 10; - maxVoxelsPPS->setMaximum(MAX_MAX_VOXELS_PPS); - maxVoxelsPPS->setMinimum(MIN_MAX_VOXELS_PPS); - maxVoxelsPPS->setSingleStep(STEP_MAX_VOXELS_PPS); - maxVoxelsPPS->setValue(_maxVoxelPacketsPerSecond); - form->addRow("Maximum Voxels Packets Per Second:", maxVoxelsPPS); - - QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept())); - dialog.connect(buttons, SIGNAL(rejected()), SLOT(reject())); - layout->addWidget(buttons); - - int ret = dialog.exec(); - if (ret == QDialog::Accepted) { - QUrl faceModelURL(faceURLEdit->text()); - - bool shouldDispatchIdentityPacket = false; - - if (faceModelURL.toString() != faceURLString) { - // change the faceModelURL in the profile, it will also update this user's BlendFace - applicationInstance->getAvatar()->setFaceModelURL(faceModelURL); - shouldDispatchIdentityPacket = true; - } - - QUrl skeletonModelURL(skeletonURLEdit->text()); - - if (skeletonModelURL.toString() != skeletonURLString) { - // change the skeletonModelURL in the profile, it will also update this user's Body - applicationInstance->getAvatar()->setSkeletonModelURL(skeletonModelURL); - shouldDispatchIdentityPacket = true; - } - - QString displayNameStr(displayNameEdit->text()); - - if (displayNameStr != displayNameString) { - applicationInstance->getAvatar()->setDisplayName(displayNameStr); - shouldDispatchIdentityPacket = true; - } - - if (shouldDispatchIdentityPacket) { - applicationInstance->getAvatar()->sendIdentityPacket(); - } - - applicationInstance->getAvatar()->getHead()->setPupilDilation(pupilDilation->value() / (float)pupilDilation->maximum()); - - _maxVoxels = maxVoxels->value(); - applicationInstance->getVoxels()->setMaxVoxels(_maxVoxels); - - _maxVoxelPacketsPerSecond = maxVoxelsPPS->value(); - - applicationInstance->getAvatar()->setLeanScale(leanScale->value()); - applicationInstance->getAvatar()->setClampedTargetScale(avatarScale->value()); - - _audioJitterBufferSamples = audioJitterBufferSamples->value(); - - if (_audioJitterBufferSamples != 0) { - applicationInstance->getAudio()->setJitterBufferSamples(_audioJitterBufferSamples); - } - - _fieldOfView = fieldOfView->value(); - applicationInstance->resizeGL(applicationInstance->getGLWidget()->width(), applicationInstance->getGLWidget()->height()); - - _faceshiftEyeDeflection = faceshiftEyeDeflection->value() / (float)faceshiftEyeDeflection->maximum(); + if(! _preferencesDialog) { + _preferencesDialog = new PreferencesDialog(Application::getInstance()->getGLWidget()); } + _preferencesDialog->show(); } diff --git a/interface/src/ui/FramelessDialog.cpp b/interface/src/ui/FramelessDialog.cpp index ddd056fd32..4ca765b352 100644 --- a/interface/src/ui/FramelessDialog.cpp +++ b/interface/src/ui/FramelessDialog.cpp @@ -16,6 +16,7 @@ FramelessDialog::FramelessDialog(QWidget *parent, Qt::WindowFlags flags) : QDial setStyleSheet(styleSheet.readAll()); } setWindowOpacity(0.95); + setAttribute(Qt::WA_DeleteOnClose); } FramelessDialog::~FramelessDialog() { diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index de585d0a2a..b82bcd7e68 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -12,7 +12,6 @@ PreferencesDialog::PreferencesDialog(QWidget* parent, Qt::WindowFlags flags) : FramelessDialog(parent, flags) { ui.setupUi(this); - setAttribute(Qt::WA_DeleteOnClose); loadPreferences(); } From b8bb8013f3862f0e0ff687da25192cbb26163c6c Mon Sep 17 00:00:00 2001 From: stojce Date: Thu, 27 Feb 2014 23:15:57 +0100 Subject: [PATCH 05/23] Bad merge fixes --- interface/src/Menu.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 041f1fcd50..f7beca0f39 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -18,6 +18,8 @@ #include #include +#include "ui/PreferencesDialog.h" + const float ADJUST_LOD_DOWN_FPS = 40.0; const float ADJUST_LOD_UP_FPS = 55.0; @@ -66,10 +68,12 @@ public: void setIsOptionChecked(const QString& menuOption, bool isChecked); void triggerOption(const QString& menuOption); QAction* getActionForOption(const QString& menuOption); - + float getAudioJitterBufferSamples() const { return _audioJitterBufferSamples; } + void setAudioJitterBufferSamples(float audioJitterBufferSamples) { _audioJitterBufferSamples = audioJitterBufferSamples; } float getFieldOfView() const { return _fieldOfView; } float getFaceshiftEyeDeflection() const { return _faceshiftEyeDeflection; } + void setFaceshiftEyeDeflection(float faceshiftEyeDeflection) { _faceshiftEyeDeflection = faceshiftEyeDeflection; } BandwidthDialog* getBandwidthDialog() const { return _bandwidthDialog; } FrustumDrawMode getFrustumDrawMode() const { return _frustumDrawMode; } ViewFrustumOffset getViewFrustumOffset() const { return _viewFrustumOffset; } @@ -89,6 +93,7 @@ public: // User Tweakable PPS from Voxel Server int getMaxVoxelPacketsPerSecond() const { return _maxVoxelPacketsPerSecond; } + void setMaxVoxelPacketsPerSecond(int maxVoxelPacketsPerSecond) { _maxVoxelPacketsPerSecond = maxVoxelPacketsPerSecond; } QMenu* getActiveScriptsMenu() { return _activeScriptsMenu;} @@ -194,6 +199,7 @@ private: QString replaceLastOccurrence(QChar search, QChar replace, QString string); quint64 _lastAdjust; QAction* _loginAction; + QPointer _preferencesDialog; }; namespace MenuOption { From a29025a7396f7400fe2ac9f4f69d344dd90998ce Mon Sep 17 00:00:00 2001 From: stojce Date: Fri, 14 Mar 2014 01:51:22 +0100 Subject: [PATCH 06/23] New layout --- interface/interface_en.ts | 133 +++++++++++++++++++++++++++++++++++--- interface/src/Menu.cpp | 12 +++- 2 files changed, 135 insertions(+), 10 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 1d962393d7..a0d1378d44 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -4,22 +4,22 @@ Application - + Export Voxels - + Sparse Voxel Octree Files (*.svo) - + Open Script - + JavaScript Files (*.js) @@ -113,22 +113,139 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file + + PreferencesDialog + + + + Avatar + + + + + + <html><head/><body><p>Avatar display name <span style=" color:#909090;">(optional)</span></p></body></html> + + + + + + Not showing a name + + + + + + Head + + + + + + Body + + + + + + Advanced Tuning + + + + + + It's not recomended that you play with these settings unless you've looked into exactly what they do. + + + + + + <p>Avatar</p> + + + + + + Lean scale (applies to Faceshift users) + + + + + + Vertical field of view + + + + + + Avatar scale (default is 1.0) + + + + + + Pupil dillation + + + + + + Audio Jitter Buffer Samples (0 for automatic) + + + + + + Faceshift eye detection + + + + + + <html><head/><body><p>Voxels</p></body></html> + + + + + + Maximum voxels + + + + + + Max voxels sent each second + + + + + + Cancel + + + + + + Save all changes + + + QObject diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index bf94c3ad4b..b20b468acf 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -76,7 +76,7 @@ Menu::Menu() : _lastAdjust(usecTimestampNow()), _fpsAverage(FIVE_SECONDS_OF_FRAMES), _loginAction(NULL), - _preferencesDialog() + _preferencesDialog(NULL) { Application *appInstance = Application::getInstance(); @@ -678,6 +678,14 @@ void Menu::loginForCurrentDomain() { } void Menu::editPreferences() { + if (! _preferencesDialog) { + _preferencesDialog = new PreferencesDialog(Application::getInstance()->getGLWidget()); + _preferencesDialog->show(); + } + _preferencesDialog->raise(); + + /* + Application* applicationInstance = Application::getInstance(); QDialog dialog(applicationInstance->getWindow()); @@ -812,7 +820,7 @@ void Menu::editPreferences() { _faceshiftEyeDeflection = faceshiftEyeDeflection->value() / (float)faceshiftEyeDeflection->maximum(); } QMetaObject::invokeMethod(applicationInstance->getAudio(), "reset", Qt::QueuedConnection); - +*/ sendFakeEnterEvent(); } From 4e2d3c95495a2ae1beb9156ec74bf299cddf604b Mon Sep 17 00:00:00 2001 From: stojce Date: Fri, 14 Mar 2014 23:24:32 +0100 Subject: [PATCH 07/23] styling QSlider --- interface/interface_en.ts | 125 ++++++++++++++++++++++- interface/resources/styles/global.qss | 30 ++++-- interface/src/Menu.cpp | 142 +------------------------- interface/src/ui/FramelessDialog.cpp | 10 +- interface/src/ui/FramelessDialog.h | 2 +- 5 files changed, 154 insertions(+), 155 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index c52ec91671..18ae5f446c 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -113,22 +113,139 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file + + PreferencesDialog + + + + Avatar + + + + + + <html><head/><body><p>Avatar display name <span style=" color:#909090;">(optional)</span></p></body></html> + + + + + + Not showing a name + + + + + + Head + + + + + + Body + + + + + + Advanced Tuning + + + + + + It's not recomended that you play with these settings unless you've looked into exactly what they do. + + + + + + <p>Avatar</p> + + + + + + Lean scale (applies to Faceshift users) + + + + + + Vertical field of view + + + + + + Avatar scale (default is 1.0) + + + + + + Pupil dillation + + + + + + Audio Jitter Buffer Samples (0 for automatic) + + + + + + Faceshift eye detection + + + + + + <html><head/><body><p>Voxels</p></body></html> + + + + + + Maximum voxels + + + + + + Max voxels sent each second + + + + + + Cancel + + + + + + Save all changes + + + QObject diff --git a/interface/resources/styles/global.qss b/interface/resources/styles/global.qss index e3548fb52e..87e142eb00 100644 --- a/interface/resources/styles/global.qss +++ b/interface/resources/styles/global.qss @@ -33,18 +33,18 @@ QPushButton { padding: 10px 15px; } - QSpinBox { padding: 5px; border-width: 1; } +QDoubleSpinBox::up-button, QSpinBox::up-button { width: 25px; height: 18px; - background-image: url(resources/styles/up.svg); + background-image: url(styles/up.svg); background-repeat: no-repeat; border: 1px #ccc solid; @@ -52,14 +52,32 @@ QSpinBox::up-button { border-top-right-radius: 2px; } +QDoubleSpinBox::down-button, QSpinBox::down-button { width: 25px; height: 18px; - background-image: url(resources/styles/down.svg); + background-image: url(styles/down.svg); background-repeat: no-repeat; border: 1px #ccc solid; - - border-top-left-radius: 2px; - border-top-right-radius: 2px; +} + +QSlider { + width: 125px; + height: 18px; +} + +QSlider::groove:horizontal { + border: none; + background-image: url(styles/slider-bg.svg); + background-repeat: no-repeat; + background-position: center center; +} + +QSlider::handle:horizontal { + width: 18px; + height: 18px; + background-image: url(styles/slider-handle.svg); + background-repeat: no-repeat; + background-position: center center; } diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 1d3b6753ff..df9e1d40dc 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -687,148 +687,8 @@ void Menu::loginForCurrentDomain() { void Menu::editPreferences() { if (! _preferencesDialog) { _preferencesDialog = new PreferencesDialog(Application::getInstance()->getGLWidget()); - _preferencesDialog->show(); } - _preferencesDialog->raise(); - - /* - - Application* applicationInstance = Application::getInstance(); - - QDialog dialog(applicationInstance->getWindow()); - dialog.setWindowTitle("Interface Preferences"); - - QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom); - dialog.setLayout(layout); - - QFormLayout* form = new QFormLayout(); - layout->addLayout(form, 1); - - QString faceURLString = applicationInstance->getAvatar()->getHead()->getFaceModel().getURL().toString(); - QLineEdit* faceURLEdit = new QLineEdit(faceURLString); - faceURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); - faceURLEdit->setPlaceholderText(DEFAULT_HEAD_MODEL_URL.toString()); - form->addRow("Face URL:", faceURLEdit); - - QString skeletonURLString = applicationInstance->getAvatar()->getSkeletonModel().getURL().toString(); - QLineEdit* skeletonURLEdit = new QLineEdit(skeletonURLString); - skeletonURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); - skeletonURLEdit->setPlaceholderText(DEFAULT_BODY_MODEL_URL.toString()); - form->addRow("Skeleton URL:", skeletonURLEdit); - - QString displayNameString = applicationInstance->getAvatar()->getDisplayName(); - QLineEdit* displayNameEdit = new QLineEdit(displayNameString); - displayNameEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); - form->addRow("Display name:", displayNameEdit); - - QSlider* pupilDilation = new QSlider(Qt::Horizontal); - pupilDilation->setValue(applicationInstance->getAvatar()->getHead()->getPupilDilation() * pupilDilation->maximum()); - form->addRow("Pupil Dilation:", pupilDilation); - - QSlider* faceshiftEyeDeflection = new QSlider(Qt::Horizontal); - faceshiftEyeDeflection->setValue(_faceshiftEyeDeflection * faceshiftEyeDeflection->maximum()); - form->addRow("Faceshift Eye Deflection:", faceshiftEyeDeflection); - - QSpinBox* fieldOfView = new QSpinBox(); - fieldOfView->setMaximum(180.f); - fieldOfView->setMinimum(1.f); - fieldOfView->setValue(_fieldOfView); - form->addRow("Vertical Field of View (Degrees):", fieldOfView); - - QDoubleSpinBox* leanScale = new QDoubleSpinBox(); - leanScale->setValue(applicationInstance->getAvatar()->getLeanScale()); - form->addRow("Lean Scale:", leanScale); - - QDoubleSpinBox* avatarScale = new QDoubleSpinBox(); - avatarScale->setValue(applicationInstance->getAvatar()->getScale()); - form->addRow("Avatar Scale:", avatarScale); - - QSpinBox* audioJitterBufferSamples = new QSpinBox(); - audioJitterBufferSamples->setMaximum(10000); - audioJitterBufferSamples->setMinimum(-10000); - audioJitterBufferSamples->setValue(_audioJitterBufferSamples); - form->addRow("Audio Jitter Buffer Samples (0 for automatic):", audioJitterBufferSamples); - - QSpinBox* maxVoxels = new QSpinBox(); - const int MAX_MAX_VOXELS = 5000000; - const int MIN_MAX_VOXELS = 0; - const int STEP_MAX_VOXELS = 50000; - maxVoxels->setMaximum(MAX_MAX_VOXELS); - maxVoxels->setMinimum(MIN_MAX_VOXELS); - maxVoxels->setSingleStep(STEP_MAX_VOXELS); - maxVoxels->setValue(_maxVoxels); - form->addRow("Maximum Voxels:", maxVoxels); - - QSpinBox* maxVoxelsPPS = new QSpinBox(); - const int MAX_MAX_VOXELS_PPS = 6000; - const int MIN_MAX_VOXELS_PPS = 60; - const int STEP_MAX_VOXELS_PPS = 10; - maxVoxelsPPS->setMaximum(MAX_MAX_VOXELS_PPS); - maxVoxelsPPS->setMinimum(MIN_MAX_VOXELS_PPS); - maxVoxelsPPS->setSingleStep(STEP_MAX_VOXELS_PPS); - maxVoxelsPPS->setValue(_maxVoxelPacketsPerSecond); - form->addRow("Maximum Voxels Packets Per Second:", maxVoxelsPPS); - - QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept())); - dialog.connect(buttons, SIGNAL(rejected()), SLOT(reject())); - layout->addWidget(buttons); - - int ret = dialog.exec(); - if (ret == QDialog::Accepted) { - QUrl faceModelURL(faceURLEdit->text()); - - bool shouldDispatchIdentityPacket = false; - - if (faceModelURL.toString() != faceURLString) { - // change the faceModelURL in the profile, it will also update this user's BlendFace - applicationInstance->getAvatar()->setFaceModelURL(faceModelURL); - shouldDispatchIdentityPacket = true; - } - - QUrl skeletonModelURL(skeletonURLEdit->text()); - - if (skeletonModelURL.toString() != skeletonURLString) { - // change the skeletonModelURL in the profile, it will also update this user's Body - applicationInstance->getAvatar()->setSkeletonModelURL(skeletonModelURL); - shouldDispatchIdentityPacket = true; - } - - QString displayNameStr(displayNameEdit->text()); - - if (displayNameStr != displayNameString) { - applicationInstance->getAvatar()->setDisplayName(displayNameStr); - shouldDispatchIdentityPacket = true; - } - - if (shouldDispatchIdentityPacket) { - applicationInstance->getAvatar()->sendIdentityPacket(); - } - - applicationInstance->getAvatar()->getHead()->setPupilDilation(pupilDilation->value() / (float)pupilDilation->maximum()); - - _maxVoxels = maxVoxels->value(); - applicationInstance->getVoxels()->setMaxVoxels(_maxVoxels); - - _maxVoxelPacketsPerSecond = maxVoxelsPPS->value(); - - applicationInstance->getAvatar()->setLeanScale(leanScale->value()); - applicationInstance->getAvatar()->setClampedTargetScale(avatarScale->value()); - - _audioJitterBufferSamples = audioJitterBufferSamples->value(); - - if (_audioJitterBufferSamples != 0) { - applicationInstance->getAudio()->setJitterBufferSamples(_audioJitterBufferSamples); - } - - _fieldOfView = fieldOfView->value(); - applicationInstance->resizeGL(applicationInstance->getGLWidget()->width(), applicationInstance->getGLWidget()->height()); - - _faceshiftEyeDeflection = faceshiftEyeDeflection->value() / (float)faceshiftEyeDeflection->maximum(); - } - QMetaObject::invokeMethod(applicationInstance->getAudio(), "reset", Qt::QueuedConnection); -*/ - sendFakeEnterEvent(); + _preferencesDialog->show(); } void Menu::goToDomain(const QString newDomain) { diff --git a/interface/src/ui/FramelessDialog.cpp b/interface/src/ui/FramelessDialog.cpp index 4ca765b352..94bb218171 100644 --- a/interface/src/ui/FramelessDialog.cpp +++ b/interface/src/ui/FramelessDialog.cpp @@ -6,13 +6,17 @@ // // -#include "FramelessDialog.h" -#include #include +#include + +#include "Application.h" +#include "FramelessDialog.h" FramelessDialog::FramelessDialog(QWidget *parent, Qt::WindowFlags flags) : QDialog(parent, flags | Qt::FramelessWindowHint) { - QFile styleSheet("resources/styles/global.qss"); + + QFile styleSheet(Application::resourcesPath() + "styles/global.qss"); if (styleSheet.open(QIODevice::ReadOnly)) { + QDir::setCurrent(Application::resourcesPath()); setStyleSheet(styleSheet.readAll()); } setWindowOpacity(0.95); diff --git a/interface/src/ui/FramelessDialog.h b/interface/src/ui/FramelessDialog.h index ca11c3eb2f..fd2121ddad 100644 --- a/interface/src/ui/FramelessDialog.h +++ b/interface/src/ui/FramelessDialog.h @@ -20,7 +20,7 @@ class FramelessDialog : public QDialog { public: FramelessDialog(QWidget* parent = 0, Qt::WindowFlags flags = 0); - ~FramelessDialog(); + virtual ~FramelessDialog(); }; From ebd7dff4b97a2a9dd221fb114ff40785f3b08e24 Mon Sep 17 00:00:00 2001 From: stojce Date: Sat, 15 Mar 2014 22:07:29 +0100 Subject: [PATCH 08/23] QSpinBox, QDoubleSpinBox styling --- interface/resources/styles/global.qss | 49 +++++++++++++++++---------- interface/src/ui/FramelessDialog.cpp | 1 + 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/interface/resources/styles/global.qss b/interface/resources/styles/global.qss index 87e142eb00..14929d39af 100644 --- a/interface/resources/styles/global.qss +++ b/interface/resources/styles/global.qss @@ -33,33 +33,48 @@ QPushButton { padding: 10px 15px; } -QSpinBox { +QSpinBox, QDoubleSpinBox { padding: 5px; border-width: 1; - +} + +QDoubleSpinBox::up-arrow, +QSpinBox::up-arrow { + background-image: url(styles/up.svg); + background-repeat: no-repeat; + background-position: center center; +} + +QDoubleSpinBox::down-arrow, +QSpinBox::down-arrow { + background-image: url(styles/down.svg); + background-repeat: no-repeat; + background-position: center center; +} + +QDoubleSpinBox::up-button, +QSpinBox::up-button, +QDoubleSpinBox::down-button, +QSpinBox::down-button { + width: 26px; + height: 13px; + + background-color: #f2f2f2; + border-color: #ccc; + border-style: solid; + border-width: 1px; } QDoubleSpinBox::up-button, QSpinBox::up-button { - - width: 25px; - height: 18px; - background-image: url(styles/up.svg); - background-repeat: no-repeat; - border: 1px #ccc solid; - - border-top-left-radius: 2px; - border-top-right-radius: 2px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; } QDoubleSpinBox::down-button, QSpinBox::down-button { - - width: 25px; - height: 18px; - background-image: url(styles/down.svg); - background-repeat: no-repeat; - border: 1px #ccc solid; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; } QSlider { diff --git a/interface/src/ui/FramelessDialog.cpp b/interface/src/ui/FramelessDialog.cpp index 94bb218171..2216e61b91 100644 --- a/interface/src/ui/FramelessDialog.cpp +++ b/interface/src/ui/FramelessDialog.cpp @@ -19,6 +19,7 @@ FramelessDialog::FramelessDialog(QWidget *parent, Qt::WindowFlags flags) : QDial QDir::setCurrent(Application::resourcesPath()); setStyleSheet(styleSheet.readAll()); } + setWindowOpacity(0.95); setAttribute(Qt::WA_DeleteOnClose); } From 913783c0f121cd6763a2a76f3e4771a30d35eb2a Mon Sep 17 00:00:00 2001 From: stojce Date: Sun, 16 Mar 2014 22:47:03 +0100 Subject: [PATCH 09/23] resizing - fixed layout --- interface/interface_en.ts | 131 +- interface/resources/styles/global.qss | 4 +- interface/resources/styles/preferences.qss | 11 + interface/src/Menu.cpp | 3 +- interface/src/ui/FramelessDialog.cpp | 42 +- interface/src/ui/FramelessDialog.h | 13 +- interface/src/ui/PreferencesDialog.cpp | 1 + interface/ui/preferencesDialog.ui | 1615 ++++++++++++++------ 8 files changed, 1296 insertions(+), 524 deletions(-) create mode 100644 interface/resources/styles/preferences.qss diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 75ada1910c..3c61d5f17a 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -113,22 +113,145 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file + + PreferencesDialog + + + + Avatar + + + + + + <html><head/><body><p>Avatar display name <span style=" color:#909090;">(optional)</span></p></body></html> + + + + + + Not showing a name + + + + + + Head + + + + + + Body + + + + + + Advanced Tuning + + + + + + It's not recomended that you play with these settings unless you've looked into exactly what they do. + + + + + + <p>Avatar</p> + + + + + + Lean scale (applies to Faceshift users) + + + + + + Vertical field of view + + + + + + Avatar scale (default is 1.0) + + + + + + Pupil dillation + + + + + + Audio Jitter Buffer Samples (0 for automatic) + + + + + + Faceshift eye detection + + + + + + <html><head/><body><p>Voxels</p></body></html> + + + + + + Maximum voxels + + + + + + Max voxels sent each second + + + + + + PushButton + + + + + + Cancel + + + + + + Save all changes + + + QObject diff --git a/interface/resources/styles/global.qss b/interface/resources/styles/global.qss index 14929d39af..d302555463 100644 --- a/interface/resources/styles/global.qss +++ b/interface/resources/styles/global.qss @@ -4,7 +4,6 @@ } FramelessDialog { - background-color: rgb(255, 255, 255); font-family: Helvetica, Arial, sans-serif; font-size: 16px; } @@ -67,12 +66,15 @@ QSpinBox::down-button { QDoubleSpinBox::up-button, QSpinBox::up-button { + + margin-top:2px; border-top-left-radius: 4px; border-top-right-radius: 4px; } QDoubleSpinBox::down-button, QSpinBox::down-button { + margin-bottom:3px; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; } diff --git a/interface/resources/styles/preferences.qss b/interface/resources/styles/preferences.qss new file mode 100644 index 0000000000..ee587b70da --- /dev/null +++ b/interface/resources/styles/preferences.qss @@ -0,0 +1,11 @@ +QLabel#avatarLabel { + background-image: url(styles/avatar.svg); + background-repeat: no-repeat; + background-position: left center; +} + +QLabel#advancedTuningLabel { + background-image: url(styles/wrench.svg); + background-repeat: no-repeat; + background-position: left center; +} diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index dd43e511bd..99e984c8cb 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -695,8 +695,9 @@ void Menu::loginForCurrentDomain() { void Menu::editPreferences() { if (! _preferencesDialog) { _preferencesDialog = new PreferencesDialog(Application::getInstance()->getGLWidget()); + _preferencesDialog->show(); } - _preferencesDialog->show(); + _preferencesDialog->raise(); } void Menu::goToDomain(const QString newDomain) { diff --git a/interface/src/ui/FramelessDialog.cpp b/interface/src/ui/FramelessDialog.cpp index 2216e61b91..9239deed90 100644 --- a/interface/src/ui/FramelessDialog.cpp +++ b/interface/src/ui/FramelessDialog.cpp @@ -8,20 +8,46 @@ #include #include +#include #include "Application.h" #include "FramelessDialog.h" FramelessDialog::FramelessDialog(QWidget *parent, Qt::WindowFlags flags) : QDialog(parent, flags | Qt::FramelessWindowHint) { - - QFile styleSheet(Application::resourcesPath() + "styles/global.qss"); - if (styleSheet.open(QIODevice::ReadOnly)) { - QDir::setCurrent(Application::resourcesPath()); - setStyleSheet(styleSheet.readAll()); - } - - setWindowOpacity(0.95); + setWindowOpacity(0.9); setAttribute(Qt::WA_DeleteOnClose); + isResizing = false; +} + +void FramelessDialog::setStyleSheet(const QString& fileName) { + QFile globalStyleSheet(Application::resourcesPath() + "styles/global.qss"); + QFile styleSheet(Application::resourcesPath() + fileName); + if (styleSheet.open(QIODevice::ReadOnly) && globalStyleSheet.open(QIODevice::ReadOnly) ) { + QDir::setCurrent(Application::resourcesPath()); + QDialog::setStyleSheet(globalStyleSheet.readAll() + styleSheet.readAll()); + } +} +void FramelessDialog::mousePressEvent(QMouseEvent* mouseEvent) { + if (abs(mouseEvent->pos().x() - size().width()) < 2 && mouseEvent->button() == Qt::LeftButton) { + isResizing = true; + QApplication::setOverrideCursor(Qt::SizeHorCursor); + } + // propagate the event + QDialog::mousePressEvent(mouseEvent); +} + +void FramelessDialog::mouseReleaseEvent(QMouseEvent* mouseEvent) { + QApplication::restoreOverrideCursor(); + isResizing = false; + // propagate the event + QDialog::mouseReleaseEvent(mouseEvent); +} + +void FramelessDialog::mouseMoveEvent(QMouseEvent* mouseEvent) { + if (isResizing) { + resize(mouseEvent->pos().x(), size().height()); + } + QDialog::mouseMoveEvent(mouseEvent); } FramelessDialog::~FramelessDialog() { diff --git a/interface/src/ui/FramelessDialog.h b/interface/src/ui/FramelessDialog.h index fd2121ddad..4e18aff161 100644 --- a/interface/src/ui/FramelessDialog.h +++ b/interface/src/ui/FramelessDialog.h @@ -10,10 +10,10 @@ #define __hifi__FramelessDialog__ #include +#include +#include #include #include -#include -#include class FramelessDialog : public QDialog { Q_OBJECT @@ -21,6 +21,15 @@ class FramelessDialog : public QDialog { public: FramelessDialog(QWidget* parent = 0, Qt::WindowFlags flags = 0); virtual ~FramelessDialog(); + void setStyleSheet(const QString& fileName); + +protected: + void mouseMoveEvent(QMouseEvent* mouseEvent); + void mousePressEvent(QMouseEvent* mouseEvent); + void mouseReleaseEvent(QMouseEvent* mouseEvent); + +private: + bool isResizing; }; diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index b82bcd7e68..318db54f2c 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -12,6 +12,7 @@ PreferencesDialog::PreferencesDialog(QWidget* parent, Qt::WindowFlags flags) : FramelessDialog(parent, flags) { ui.setupUi(this); + setStyleSheet("styles/preferences.qss"); loadPreferences(); } diff --git a/interface/ui/preferencesDialog.ui b/interface/ui/preferencesDialog.ui index 8fed57c06b..0099838177 100644 --- a/interface/ui/preferencesDialog.ui +++ b/interface/ui/preferencesDialog.ui @@ -2,486 +2,43 @@ PreferencesDialog + + Qt::ApplicationModal + 0 0 - 611 - 805 + 640 + 752 - - - - 30 - 0 - 555 - 701 - - - - - - - - 23 - - - - color: #0e7077 - - - Avatar - - - faceURLEdit - - - - - - - - 0 - 0 - - - - color: #0e7077 - - - <html><head/><body><p>Avatar display name <span style=" color:#909090;">(optional)</span></p></body></html> - - - displayNameEdit - - - - - - - - 0 - 0 - - - - - 280 - 0 - - - - Qt::LeftToRight - - - - - - Not showing a name - - - - - - - color: #0e7077 - - - Head - - - faceURLEdit - - - - - - - - 0 - 0 - - - - - - - - color: #0e7077 - - - Body - - - faceURLEdit - - - - - - - - - - - 23 - - - - color: #0e7077 - - - Advanced Tuning - - - - - - - It's not recomended that you play with these settings unless you've looked into exactly what they do. - - - false - - - true - - - - - - - - 20 - 50 - false - - - - color: #0e7077 - - - <p>Avatar</p> - - - - - - - - - Lean scale (applies to Faceshift users) - - - leanScaleSpin - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - Vertical field of view - - - fieldOfViewSpin - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 1 - - - 180 - - - - - - - - - - - Avatar scale (default is 1.0) - - - avatarScaleSpin - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - Pupil dillation - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - Qt::Horizontal - - - - - - - - - - - Audio Jitter Buffer Samples (0 for automatic) - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - -10000 - - - 10000 - - - 1 - - - - - - - - - - - Faceshift eye detection - - - avatarScaleSpin - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - Qt::Horizontal - - - - - - - - - - 20 - 50 - false - - - - color: #0e7077 - - - <html><head/><body><p>Voxels</p></body></html> - - - - - - - - - Maximum voxels - - - leanScaleSpin - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 5000000 - - - 50000 - - - - - - - - - - - Max voxels sent each second - - - leanScaleSpin - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 60 - - - 6000 - - - 10 - - - - - - - + + + 0 + 0 + + + + + 610 + 0 + + 0 - 725 + 720 616 80 + + + Arial + + background-color: #0e7077 @@ -494,9 +51,22 @@ 41 + + + Arial + + + + 0 + + + + Arial + + Qt::Horizontal @@ -510,6 +80,11 @@ + + + Arial + + Cancel @@ -517,6 +92,11 @@ + + + Arial + + background-color: #fff; color: #0e7077 @@ -532,6 +112,1066 @@ color: #0e7077 + + + + 0 + 0 + 621 + 1000 + + + + + 0 + 0 + + + + true + + + + + 0 + 0 + 619 + 998 + + + + + + 0 + 50 + 621 + 783 + + + + + Arial + + + + + 0 + + + 30 + + + 0 + + + 30 + + + + + + 0 + 0 + + + + + Arial + 24 + + + + color: #0e7077 + + + Avatar + + + 25 + + + + + + + + + + + 0 + 0 + + + + + 0 + 30 + + + + + Arial + 16 + + + + color: #0e7077 + + + <html><head/><body><p>Avatar display name <span style=" color:#909090;">(optional)</span></p></body></html> + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + displayNameEdit + + + + + + + + 0 + 0 + + + + + 280 + 0 + + + + + Arial + + + + Qt::LeftToRight + + + + + + Not showing a name + + + + + + + + 0 + 0 + + + + + 0 + 30 + + + + + Arial + 16 + + + + color: #0e7077 + + + Head + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + 0 + + + faceURLEdit + + + + + + + + 0 + 0 + + + + + Arial + + + + + + + + + 0 + 0 + + + + + 0 + 30 + + + + + Arial + 16 + + + + color: #0e7077 + + + Body + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + skeletonURLEdit + + + + + + + + 0 + 0 + + + + + Arial + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + Arial + 24 + + + + color: #0e7077 + + + Advanced Tuning + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + 25 + + + + + + + + 0 + 0 + + + + + Arial + + + + color: rgb(51, 51, 51) + + + It's not recomended that you play with these settings unless you've looked into exactly what they do. + + + false + + + true + + + + + + + + 0 + 0 + + + + + 0 + 40 + + + + + Arial + 20 + 50 + false + + + + color: #0e7077 + + + <p>Avatar</p> + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + 0 + + + 10 + + + 10 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 25 + + + + + Arial + + + + color: rgb(51, 51, 51) + + + Lean scale (applies to Faceshift users) + + + leanScaleSpin + + + + + + + + Arial + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 10 + + + + + + + + + 0 + 0 + + + + + 95 + 36 + + + + + 70 + 16777215 + + + + + Arial + + + + + + + + + + 0 + + + 10 + + + 0 + + + 10 + + + + + + Arial + + + + color: rgb(51, 51, 51) + + + Vertical field of view + + + fieldOfViewSpin + + + + + + + + Arial + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 95 + 36 + + + + + 70 + 16777215 + + + + + Arial + + + + 1 + + + 180 + + + + + + + + + 0 + + + 10 + + + 0 + + + 10 + + + + + + Arial + + + + color: rgb(51, 51, 51) + + + Avatar scale (default is 1.0) + + + avatarScaleSpin + + + + + + + + Arial + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 95 + 36 + + + + + 70 + 16777215 + + + + + Arial + + + + + + + + + + 0 + + + 10 + + + 0 + + + 10 + + + + + + Arial + + + + color: rgb(51, 51, 51) + + + Pupil dillation + + + + + + + + Arial + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 125 + 0 + + + + + Arial + + + + Qt::Horizontal + + + + + + + + + 0 + + + 10 + + + 0 + + + 10 + + + + + + Arial + + + + color: rgb(51, 51, 51) + + + Audio Jitter Buffer Samples (0 for automatic) + + + + + + + + Arial + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 95 + 36 + + + + + 70 + 16777215 + + + + + Arial + + + + -10000 + + + 10000 + + + 1 + + + + + + + + + 0 + + + 10 + + + 0 + + + 10 + + + + + + Arial + + + + color: rgb(51, 51, 51) + + + Faceshift eye detection + + + avatarScaleSpin + + + + + + + + Arial + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 125 + 0 + + + + + Arial + + + + Qt::Horizontal + + + + + + + + + + 0 + 0 + + + + + 0 + 40 + + + + + Arial + 20 + 50 + false + + + + color: #0e7077 + + + <html><head/><body><p>Voxels</p></body></html> + + + + + + + 0 + + + 10 + + + 0 + + + 10 + + + + + + Arial + + + + color: rgb(51, 51, 51) + + + Maximum voxels + + + leanScaleSpin + + + + + + + + Arial + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 125 + 36 + + + + + Arial + + + + 5000000 + + + 50000 + + + + + + + + + 0 + + + 10 + + + 0 + + + 10 + + + + + + Arial + + + + Max voxels sent each second + + + leanScaleSpin + + + + + + + + Arial + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 95 + 36 + + + + + 70 + 16777215 + + + + + Arial + + + + 60 + + + 6000 + + + 10 + + + + + + + + + + + 540 + 40 + 114 + 32 + + + + PushButton + + + + @@ -539,47 +1179,6 @@ color: #0e7077 1 - - displayNameEdit - faceURLEdit - leanScaleSpin - fieldOfViewSpin - avatarScaleSpin - pupilDilationSlider - - - - cancelButton - clicked() - PreferencesDialog - close() - - - 372 - 700 - - - 528 - -9 - - - - - defaultButton - clicked() - PreferencesDialog - accept() - - - 20 - 20 - - - 20 - 20 - - - - + From 9077a05f9d76881ea5c5776f4404d4f48337ad6d Mon Sep 17 00:00:00 2001 From: stojce Date: Fri, 21 Mar 2014 22:34:10 +0100 Subject: [PATCH 10/23] - Layout fix - Model browsers - merge --- assignment-client/src/audio/AudioMixer.cpp | 64 +- assignment-client/src/audio/AudioMixer.h | 9 +- .../src/audio/AudioMixerClientData.cpp | 22 +- .../src/audio/AudioMixerClientData.h | 5 +- .../src/octree/OctreeQueryNode.cpp | 66 +- .../src/octree/OctreeQueryNode.h | 5 + .../src/octree/OctreeSendThread.cpp | 25 +- assignment-client/src/octree/OctreeServer.cpp | 16 +- examples/editVoxels.js | 250 +- examples/inspect.js | 240 ++ interface/interface_en.ts | 98 +- interface/resources/resources.qrc | 7 +- interface/resources/styles/global.qss | 21 +- interface/src/Application.cpp | 100 +- interface/src/Application.h | 5 + interface/src/Environment.cpp | 16 +- interface/src/GLCanvas.cpp | 4 + interface/src/GLCanvas.h | 2 + interface/src/Menu.cpp | 11 +- interface/src/Menu.h | 3 +- interface/src/ModelBrowser.cpp | 150 ++ interface/src/ModelBrowser.h | 62 + interface/src/avatar/MyAvatar.cpp | 5 +- interface/src/avatar/MyAvatar.h | 2 + interface/src/renderer/TextureCache.cpp | 2 +- interface/src/ui/FramelessDialog.cpp | 40 +- interface/src/ui/FramelessDialog.h | 11 +- interface/src/ui/PreferencesDialog.cpp | 50 +- interface/src/ui/PreferencesDialog.h | 12 +- interface/ui/preferencesDialog.ui | 2366 +++++++++-------- libraries/audio/src/AudioRingBuffer.cpp | 19 +- libraries/audio/src/AudioRingBuffer.h | 5 +- .../audio/src/PositionalAudioRingBuffer.cpp | 1 + libraries/avatars/src/AvatarData.cpp | 26 + libraries/shared/src/FileDownloader.cpp | 65 + libraries/shared/src/FileDownloader.h | 44 + libraries/shared/src/FstReader.cpp | 23 +- libraries/shared/src/FstReader.h | 1 + libraries/shared/src/PacketHeaders.cpp | 4 +- libraries/voxels/src/EnvironmentData.cpp | 15 + libraries/voxels/src/EnvironmentData.h | 8 + 41 files changed, 2347 insertions(+), 1533 deletions(-) create mode 100644 examples/inspect.js create mode 100644 interface/src/ModelBrowser.cpp create mode 100644 interface/src/ModelBrowser.h create mode 100644 libraries/shared/src/FileDownloader.cpp create mode 100644 libraries/shared/src/FileDownloader.h diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 988bcc1da7..e86ecda36e 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -62,7 +62,12 @@ void attachNewBufferToNode(Node *newNode) { } AudioMixer::AudioMixer(const QByteArray& packet) : - ThreadedAssignment(packet) + ThreadedAssignment(packet), + _trailingSleepRatio(1.0f), + _minSourceLoudnessInFrame(1.0f), + _maxSourceLoudnessInFrame(0.0f), + _loudnessCutoffRatio(0.0f), + _minRequiredLoudness(0.0f) { } @@ -301,7 +306,7 @@ void AudioMixer::prepareMixForListeningNode(Node* node) { if ((*otherNode != *node || otherNodeBuffer->shouldLoopbackForNode()) && otherNodeBuffer->willBeAddedToMix() - && otherNodeClientData->getNextOutputLoudness() > 0) { + && otherNodeBuffer->getAverageLoudness() > _minRequiredLoudness) { addBufferToMixForListeningNodeWithBuffer(otherNodeBuffer, nodeRingBuffer); } } @@ -350,14 +355,65 @@ void AudioMixer::run() { char* clientMixBuffer = new char[NETWORK_BUFFER_LENGTH_BYTES_STEREO + numBytesForPacketHeaderGivenPacketType(PacketTypeMixedAudio)]; + + int usecToSleep = BUFFER_SEND_INTERVAL_USECS; while (!_isFinished) { + _minSourceLoudnessInFrame = 1.0f; + _maxSourceLoudnessInFrame = 0.0f; + foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { if (node->getLinkedData()) { - ((AudioMixerClientData*) node->getLinkedData())->checkBuffersBeforeFrameSend(JITTER_BUFFER_SAMPLES); + ((AudioMixerClientData*) node->getLinkedData())->checkBuffersBeforeFrameSend(JITTER_BUFFER_SAMPLES, + _minSourceLoudnessInFrame, + _maxSourceLoudnessInFrame); } } + + const float STRUGGLE_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD = 0.10; + const float BACK_OFF_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD = 0.30; + const float CUTOFF_EPSILON = 0.0001; + + const int TRAILING_AVERAGE_FRAMES = 100; + const float CURRENT_FRAME_RATIO = 1.0f / TRAILING_AVERAGE_FRAMES; + const float PREVIOUS_FRAMES_RATIO = 1 - CURRENT_FRAME_RATIO; + + if (usecToSleep < 0) { + usecToSleep = 0; + } + + _trailingSleepRatio = (PREVIOUS_FRAMES_RATIO * _trailingSleepRatio) + + (usecToSleep * CURRENT_FRAME_RATIO / (float) BUFFER_SEND_INTERVAL_USECS); + + float lastCutoffRatio = _loudnessCutoffRatio; + bool hasRatioChanged = false; + + if (_trailingSleepRatio <= STRUGGLE_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD) { + // we're struggling - change our min required loudness to reduce some load + _loudnessCutoffRatio += (1 - _loudnessCutoffRatio) / 2; + + qDebug() << "Mixer is struggling, sleeping" << _trailingSleepRatio * 100 << "% of frame time. Old cutoff was" + << lastCutoffRatio << "and is now" << _loudnessCutoffRatio; + hasRatioChanged = true; + } else if (_trailingSleepRatio >= BACK_OFF_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD && _loudnessCutoffRatio != 0) { + // we've recovered and can back off the required loudness + _loudnessCutoffRatio -= _loudnessCutoffRatio / 2; + + if (_loudnessCutoffRatio < CUTOFF_EPSILON) { + _loudnessCutoffRatio = 0; + } + + qDebug() << "Mixer is recovering, sleeping" << _trailingSleepRatio * 100 << "% of frame time. Old cutoff was" + << lastCutoffRatio << "and is now" << _loudnessCutoffRatio; + hasRatioChanged = true; + } + + if (hasRatioChanged) { + // set out min required loudness from the new ratio + _minRequiredLoudness = _loudnessCutoffRatio * (_maxSourceLoudnessInFrame - _minSourceLoudnessInFrame); + qDebug() << "Minimum loudness required to be mixed is now" << _minRequiredLoudness; + } foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { if (node->getType() == NodeType::Agent && node->getActiveSocket() && node->getLinkedData() @@ -384,7 +440,7 @@ void AudioMixer::run() { break; } - int usecToSleep = usecTimestamp(&startTime) + (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - usecTimestampNow(); + usecToSleep = usecTimestamp(&startTime) + (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - usecTimestampNow(); if (usecToSleep > 0) { usleep(usecToSleep); diff --git a/assignment-client/src/audio/AudioMixer.h b/assignment-client/src/audio/AudioMixer.h index 5a68b0023f..4ba8cdebd3 100644 --- a/assignment-client/src/audio/AudioMixer.h +++ b/assignment-client/src/audio/AudioMixer.h @@ -37,7 +37,14 @@ private: void prepareMixForListeningNode(Node* node); // client samples capacity is larger than what will be sent to optimize mixing - int16_t _clientSamples[NETWORK_BUFFER_LENGTH_SAMPLES_STEREO + SAMPLE_PHASE_DELAY_AT_90]; + // we are MMX adding 4 samples at a time so we need client samples to have an extra 4 + int16_t _clientSamples[NETWORK_BUFFER_LENGTH_SAMPLES_STEREO + (SAMPLE_PHASE_DELAY_AT_90 * 2)]; + + float _trailingSleepRatio; + float _minSourceLoudnessInFrame; + float _maxSourceLoudnessInFrame; + float _loudnessCutoffRatio; + float _minRequiredLoudness; }; #endif /* defined(__hifi__AudioMixer__) */ diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index b2da0a0aaa..41fd72e54e 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -6,6 +6,8 @@ // Copyright (c) 2013 HighFidelity, Inc. All rights reserved. // +#include + #include #include @@ -14,8 +16,7 @@ #include "AudioMixerClientData.h" AudioMixerClientData::AudioMixerClientData() : - _ringBuffers(), - _nextOutputLoudness(0) + _ringBuffers() { } @@ -82,16 +83,29 @@ int AudioMixerClientData::parseData(const QByteArray& packet) { return 0; } -void AudioMixerClientData::checkBuffersBeforeFrameSend(int jitterBufferLengthSamples) { +void AudioMixerClientData::checkBuffersBeforeFrameSend(int jitterBufferLengthSamples, + float& currentMinLoudness, + float& currentMaxLoudness) { for (unsigned int i = 0; i < _ringBuffers.size(); i++) { if (_ringBuffers[i]->shouldBeAddedToMix(jitterBufferLengthSamples)) { // this is a ring buffer that is ready to go // set its flag so we know to push its buffer when all is said and done _ringBuffers[i]->setWillBeAddedToMix(true); + // calculate the average loudness for the next NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL // that would be mixed in - _nextOutputLoudness = _ringBuffers[i]->averageLoudnessForBoundarySamples(NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL); + _ringBuffers[i]->updateAverageLoudnessForBoundarySamples(NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL); + + float ringBufferLoudness = _ringBuffers[i]->getAverageLoudness(); + + if (ringBufferLoudness != 0 && ringBufferLoudness < currentMinLoudness) { + currentMinLoudness = ringBufferLoudness; + } + + if (ringBufferLoudness > currentMaxLoudness) { + currentMaxLoudness = ringBufferLoudness; + } } } } diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index bb10098e23..d41563bbca 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -24,14 +24,11 @@ public: const std::vector getRingBuffers() const { return _ringBuffers; } AvatarAudioRingBuffer* getAvatarAudioRingBuffer() const; - float getNextOutputLoudness() const { return _nextOutputLoudness; } - int parseData(const QByteArray& packet); - void checkBuffersBeforeFrameSend(int jitterBufferLengthSamples); + void checkBuffersBeforeFrameSend(int jitterBufferLengthSamples, float& currentMinLoudness, float& currentMaxLoudness); void pushBuffersAfterFrameSend(); private: std::vector _ringBuffers; - float _nextOutputLoudness; }; #endif /* defined(__hifi__AudioMixerClientData__) */ diff --git a/assignment-client/src/octree/OctreeQueryNode.cpp b/assignment-client/src/octree/OctreeQueryNode.cpp index a1922f980d..2ceb9e1040 100644 --- a/assignment-client/src/octree/OctreeQueryNode.cpp +++ b/assignment-client/src/octree/OctreeQueryNode.cpp @@ -36,18 +36,34 @@ OctreeQueryNode::OctreeQueryNode() : _lodChanged(false), _lodInitialized(false), _sequenceNumber(0), - _lastRootTimestamp(0) + _lastRootTimestamp(0), + _myPacketType(PacketTypeUnknown), + _isShuttingDown(false) { } OctreeQueryNode::~OctreeQueryNode() { + _isShuttingDown = true; + const bool extraDebugging = false; + if (extraDebugging) { + qDebug() << "OctreeQueryNode::~OctreeQueryNode()"; + } if (_octreeSendThread) { + if (extraDebugging) { + qDebug() << "OctreeQueryNode::~OctreeQueryNode()... calling _octreeSendThread->terminate()"; + } _octreeSendThread->terminate(); + if (extraDebugging) { + qDebug() << "OctreeQueryNode::~OctreeQueryNode()... calling delete _octreeSendThread"; + } delete _octreeSendThread; } delete[] _octreePacket; delete[] _lastOctreePacket; + if (extraDebugging) { + qDebug() << "OctreeQueryNode::~OctreeQueryNode()... DONE..."; + } } @@ -59,9 +75,13 @@ void OctreeQueryNode::initializeOctreeSendThread(OctreeServer* octreeServer, con } bool OctreeQueryNode::packetIsDuplicate() const { + // if shutting down, return immediately + if (_isShuttingDown) { + return false; + } // since our packets now include header information, like sequence number, and createTime, we can't just do a memcmp // of the entire packet, we need to compare only the packet content... - int numBytesPacketHeader = numBytesForPacketHeaderGivenPacketType(getMyPacketType()); + int numBytesPacketHeader = numBytesForPacketHeaderGivenPacketType(_myPacketType); if (_lastOctreePacketLength == getPacketLength()) { if (memcmp(_lastOctreePacket + (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE), @@ -74,6 +94,11 @@ bool OctreeQueryNode::packetIsDuplicate() const { } bool OctreeQueryNode::shouldSuppressDuplicatePacket() { + // if shutting down, return immediately + if (_isShuttingDown) { + return true; + } + bool shouldSuppress = false; // assume we won't suppress // only consider duplicate packets @@ -107,7 +132,17 @@ bool OctreeQueryNode::shouldSuppressDuplicatePacket() { return shouldSuppress; } +void OctreeQueryNode::init() { + _myPacketType = getMyPacketType(); + resetOctreePacket(true); // don't bump sequence +} + void OctreeQueryNode::resetOctreePacket(bool lastWasSurpressed) { + // if shutting down, return immediately + if (_isShuttingDown) { + return; + } + // Whenever we call this, we will keep a copy of the last packet, so we can determine if the last packet has // changed since we last reset it. Since we know that no two packets can ever be identical without being the same // scene information, (e.g. the root node packet of a static scene), we can use this as a strategy for reducing @@ -128,7 +163,7 @@ void OctreeQueryNode::resetOctreePacket(bool lastWasSurpressed) { } _octreePacketAvailableBytes = MAX_PACKET_SIZE; - int numBytesPacketHeader = populatePacketHeader(reinterpret_cast(_octreePacket), getMyPacketType()); + int numBytesPacketHeader = populatePacketHeader(reinterpret_cast(_octreePacket), _myPacketType); _octreePacketAt = _octreePacket + numBytesPacketHeader; _octreePacketAvailableBytes -= numBytesPacketHeader; @@ -158,6 +193,11 @@ void OctreeQueryNode::resetOctreePacket(bool lastWasSurpressed) { } void OctreeQueryNode::writeToPacket(const unsigned char* buffer, unsigned int bytes) { + // if shutting down, return immediately + if (_isShuttingDown) { + return; + } + // compressed packets include lead bytes which contain compressed size, this allows packing of // multiple compressed portions together if (_currentPacketIsCompressed) { @@ -174,6 +214,11 @@ void OctreeQueryNode::writeToPacket(const unsigned char* buffer, unsigned int by } bool OctreeQueryNode::updateCurrentViewFrustum() { + // if shutting down, return immediately + if (_isShuttingDown) { + return false; + } + bool currentViewFrustumChanged = false; ViewFrustum newestViewFrustum; // get position and orientation details from the camera @@ -233,6 +278,11 @@ void OctreeQueryNode::setViewSent(bool viewSent) { } void OctreeQueryNode::updateLastKnownViewFrustum() { + // if shutting down, return immediately + if (_isShuttingDown) { + return; + } + bool frustumChanges = !_lastKnownViewFrustum.isVerySimilar(_currentViewFrustum); if (frustumChanges) { @@ -247,6 +297,11 @@ void OctreeQueryNode::updateLastKnownViewFrustum() { bool OctreeQueryNode::moveShouldDump() const { + // if shutting down, return immediately + if (_isShuttingDown) { + return false; + } + glm::vec3 oldPosition = _lastKnownViewFrustum.getPosition(); glm::vec3 newPosition = _currentViewFrustum.getPosition(); @@ -259,6 +314,11 @@ bool OctreeQueryNode::moveShouldDump() const { } void OctreeQueryNode::dumpOutOfView() { + // if shutting down, return immediately + if (_isShuttingDown) { + return; + } + int stillInView = 0; int outOfView = 0; OctreeElementBag tempBag; diff --git a/assignment-client/src/octree/OctreeQueryNode.h b/assignment-client/src/octree/OctreeQueryNode.h index 20fa2c5858..eab8cb5d0a 100644 --- a/assignment-client/src/octree/OctreeQueryNode.h +++ b/assignment-client/src/octree/OctreeQueryNode.h @@ -28,6 +28,7 @@ public: OctreeQueryNode(); virtual ~OctreeQueryNode(); + void init(); // called after creation to set up some virtual items virtual PacketType getMyPacketType() const = 0; void resetOctreePacket(bool lastWasSurpressed = false); // resets octree packet to after "V" header @@ -91,6 +92,7 @@ public: unsigned int getlastOctreePacketLength() const { return _lastOctreePacketLength; } int getDuplicatePacketCount() const { return _duplicatePacketCount; } + bool isShuttingDown() const { return _isShuttingDown; } private: OctreeQueryNode(const OctreeQueryNode &); @@ -127,6 +129,9 @@ private: OCTREE_PACKET_SEQUENCE _sequenceNumber; quint64 _lastRootTimestamp; + + PacketType _myPacketType; + bool _isShuttingDown; }; #endif /* defined(__hifi__OctreeQueryNode__) */ diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index caa729e340..9c04c4a1ad 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -65,7 +65,7 @@ bool OctreeSendThread::process() { nodeData = (OctreeQueryNode*) node->getLinkedData(); // Sometimes the node data has not yet been linked, in which case we can't really do anything - if (nodeData) { + if (nodeData && !nodeData->isShuttingDown()) { bool viewFrustumChanged = nodeData->updateCurrentViewFrustum(); packetDistributor(node, nodeData, viewFrustumChanged); } @@ -99,7 +99,14 @@ quint64 OctreeSendThread::_totalBytes = 0; quint64 OctreeSendThread::_totalWastedBytes = 0; quint64 OctreeSendThread::_totalPackets = 0; -int OctreeSendThread::handlePacketSend(const SharedNodePointer& node, OctreeQueryNode* nodeData, int& trueBytesSent, int& truePacketsSent) { +int OctreeSendThread::handlePacketSend(const SharedNodePointer& node, + OctreeQueryNode* nodeData, int& trueBytesSent, int& truePacketsSent) { + + // if we're shutting down, then exit early + if (nodeData->isShuttingDown()) { + return 0; + } + bool debug = _myServer->wantsDebugSending(); quint64 now = usecTimestampNow(); @@ -136,7 +143,7 @@ int OctreeSendThread::handlePacketSend(const SharedNodePointer& node, OctreeQuer // If we've got a stats message ready to send, then see if we can piggyback them together - if (nodeData->stats.isReadyToSend()) { + if (nodeData->stats.isReadyToSend() && !nodeData->isShuttingDown()) { // Send the stats message to the client unsigned char* statsMessage = nodeData->stats.getStatsMessage(); int statsMessageLength = nodeData->stats.getStatsMessageLength(); @@ -203,7 +210,7 @@ int OctreeSendThread::handlePacketSend(const SharedNodePointer& node, OctreeQuer nodeData->stats.markAsSent(); } else { // If there's actually a packet waiting, then send it. - if (nodeData->isPacketWaiting()) { + if (nodeData->isPacketWaiting() && !nodeData->isShuttingDown()) { // just send the voxel packet NodeList::getInstance()->writeDatagram((char*) nodeData->getPacket(), nodeData->getPacketLength(), SharedNodePointer(node)); @@ -234,6 +241,12 @@ int OctreeSendThread::handlePacketSend(const SharedNodePointer& node, OctreeQuer /// Version of voxel distributor that sends the deepest LOD level at once int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQueryNode* nodeData, bool viewFrustumChanged) { + + // if shutting down, exit early + if (nodeData->isShuttingDown()) { + return 0; + } + int truePacketsSent = 0; int trueBytesSent = 0; int packetsSentThisInterval = 0; @@ -336,7 +349,7 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue int extraPackingAttempts = 0; bool completedScene = false; - while (somethingToSend && packetsSentThisInterval < maxPacketsPerInterval) { + while (somethingToSend && packetsSentThisInterval < maxPacketsPerInterval && !nodeData->isShuttingDown()) { float lockWaitElapsedUsec = OctreeServer::SKIP_TIME; float encodeElapsedUsec = OctreeServer::SKIP_TIME; float compressAndWriteElapsedUsec = OctreeServer::SKIP_TIME; @@ -503,7 +516,7 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue // Here's where we can/should allow the server to send other data... // send the environment packet // TODO: should we turn this into a while loop to better handle sending multiple special packets - if (_myServer->hasSpecialPacketToSend(node)) { + if (_myServer->hasSpecialPacketToSend(node) && !nodeData->isShuttingDown()) { trueBytesSent += _myServer->sendSpecialPacket(node); truePacketsSent++; packetsSentThisInterval++; diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 7e6ffe52da..496f9af1a0 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -168,7 +168,7 @@ void OctreeServer::trackPacketSendingTime(float time) { void OctreeServer::attachQueryNodeToNode(Node* newNode) { if (!newNode->getLinkedData()) { OctreeQueryNode* newQueryNodeData = _instance->createOctreeQueryNode(); - newQueryNodeData->resetOctreePacket(true); // don't bump sequence + newQueryNodeData->init(); newNode->setLinkedData(newQueryNodeData); } } @@ -784,16 +784,26 @@ void OctreeServer::readPendingDatagrams() { if (packetType == getMyQueryMessageType()) { bool debug = false; if (debug) { - qDebug() << "Got PacketTypeVoxelQuery at" << usecTimestampNow(); + if (matchingNode) { + qDebug() << "Got PacketTypeVoxelQuery at" << usecTimestampNow() << "node:" << *matchingNode; + } else { + qDebug() << "Got PacketTypeVoxelQuery at" << usecTimestampNow() << "node: ??????"; + } } // If we got a PacketType_VOXEL_QUERY, then we're talking to an NodeType_t_AVATAR, and we // need to make sure we have it in our nodeList. if (matchingNode) { + if (debug) { + qDebug() << "calling updateNodeWithDataFromPacket()... node:" << *matchingNode; + } nodeList->updateNodeWithDataFromPacket(matchingNode, receivedPacket); OctreeQueryNode* nodeData = (OctreeQueryNode*) matchingNode->getLinkedData(); if (nodeData && !nodeData->isOctreeSendThreadInitalized()) { + if (debug) { + qDebug() << "calling initializeOctreeSendThread()... node:" << *matchingNode; + } nodeData->initializeOctreeSendThread(this, matchingNode->getUUID()); } } @@ -999,6 +1009,8 @@ void OctreeServer::nodeKilled(SharedNodePointer node) { node->setLinkedData(NULL); // set this first in case another thread comes through and tryes to acces this qDebug() << qPrintable(_safeServerName) << "server deleting Linked Data for node:" << *node; nodeData->deleteLater(); + } else { + qDebug() << qPrintable(_safeServerName) << "server node missing linked data node:" << *node; } } diff --git a/examples/editVoxels.js b/examples/editVoxels.js index 31d483d798..43bc485274 100644 --- a/examples/editVoxels.js +++ b/examples/editVoxels.js @@ -20,8 +20,6 @@ var windowDimensions = Controller.getViewportDimensions(); var NEW_VOXEL_SIZE = 1.0; var NEW_VOXEL_DISTANCE_FROM_CAMERA = 3.0; -var ORBIT_RATE_ALTITUDE = 200.0; -var ORBIT_RATE_AZIMUTH = 90.0; var PIXELS_PER_EXTRUDE_VOXEL = 16; var WHEEL_PIXELS_PER_SCALE_CHANGE = 100; var MAX_VOXEL_SCALE = 1.0; @@ -37,19 +35,7 @@ var previewLineWidth = 1.5; var oldMode = Camera.getMode(); var isAdding = false; -var isExtruding = false; -var isOrbiting = false; -var isOrbitingFromTouch = false; -var isPanning = false; -var isPanningFromTouch = false; -var touchPointsToOrbit = 2; // you can change these, but be mindful that on some track pads 2 touch points = right click+drag -var touchPointsToPan = 3; -var orbitAzimuth = 0.0; -var orbitAltitude = 0.0; -var orbitCenter = { x: 0, y: 0, z: 0 }; -var orbitPosition = { x: 0, y: 0, z: 0 }; -var torsoToEyeVector = { x: 0, y: 0, z: 0 }; -var orbitRadius = 0.0; +var isExtruding = false; var extrudeDirection = { x: 0, y: 0, z: 0 }; var extrudeScale = 0.0; var lastVoxelPosition = { x: 0, y: 0, z: 0 }; @@ -444,24 +430,11 @@ function getNewVoxelPosition() { return newPosition; } -function fixEulerAngles(eulers) { - var rVal = { x: 0, y: 0, z: eulers.z }; - if (eulers.x >= 90.0) { - rVal.x = 180.0 - eulers.x; - rVal.y = eulers.y - 180.0; - } else if (eulers.x <= -90.0) { - rVal.x = 180.0 - eulers.x; - rVal.y = eulers.y - 180.0; - } - return rVal; -} - var trackLastMouseX = 0; var trackLastMouseY = 0; var trackAsDelete = false; var trackAsRecolor = false; var trackAsEyedropper = false; -var trackAsOrbitOrPan = false; var voxelToolSelected = true; var recolorToolSelected = false; @@ -761,10 +734,6 @@ function trackKeyPressEvent(event) { trackAsEyedropper = true; moveTools(); } - if (event.text == "ALT") { - trackAsOrbitOrPan = true; - moveTools(); - } showPreviewGuides(); } @@ -802,10 +771,6 @@ function trackKeyReleaseEvent(event) { trackAsEyedropper = false; moveTools(); } - if (event.text == "ALT") { - trackAsOrbitOrPan = false; - moveTools(); - } // on F1 toggle the preview mode between cubes and lines if (event.text == "F1") { @@ -816,74 +781,6 @@ function trackKeyReleaseEvent(event) { } } -function startOrbitMode(event) { - mouseX = event.x; - mouseY = event.y; - var pickRay = Camera.computePickRay(event.x, event.y); - var intersection = Voxels.findRayIntersection(pickRay); - - // start orbit camera! - var cameraPosition = Camera.getPosition(); - torsoToEyeVector = Vec3.subtract(cameraPosition, MyAvatar.position); - torsoToEyeVector.x = 0.0; - torsoToEyeVector.z = 0.0; - oldMode = Camera.getMode(); - Camera.setMode("independent"); - Camera.keepLookingAt(intersection.intersection); - // get position for initial azimuth, elevation - orbitCenter = intersection.intersection; - var orbitVector = Vec3.subtract(cameraPosition, orbitCenter); - orbitRadius = Vec3.length(orbitVector); - orbitAzimuth = Math.atan2(orbitVector.z, orbitVector.x); - orbitAltitude = Math.asin(orbitVector.y / Vec3.length(orbitVector)); - - //print("startOrbitMode..."); -} - -function handleOrbitingMove(event) { - var cameraOrientation = Camera.getOrientation(); - var origEulers = Quat.safeEulerAngles(cameraOrientation); - var newEulers = fixEulerAngles(Quat.safeEulerAngles(cameraOrientation)); - var dx = event.x - mouseX; - var dy = event.y - mouseY; - orbitAzimuth += dx / ORBIT_RATE_AZIMUTH; - orbitAltitude += dy / ORBIT_RATE_ALTITUDE; - var orbitVector = { x:(Math.cos(orbitAltitude) * Math.cos(orbitAzimuth)) * orbitRadius, - y:Math.sin(orbitAltitude) * orbitRadius, - z:(Math.cos(orbitAltitude) * Math.sin(orbitAzimuth)) * orbitRadius }; - orbitPosition = Vec3.sum(orbitCenter, orbitVector); - Camera.setPosition(orbitPosition); - - mouseX = event.x; - mouseY = event.y; - //print("handleOrbitingMove..."); -} - -function endOrbitMode(event) { - var cameraOrientation = Camera.getOrientation(); - MyAvatar.position = Vec3.subtract(Camera.getPosition(), torsoToEyeVector); - MyAvatar.headOrientation = cameraOrientation; - Camera.stopLooking(); - Camera.setMode(oldMode); - Camera.setOrientation(cameraOrientation); - //print("endOrbitMode..."); -} - -function startPanMode(event, intersection) { - // start pan camera! - print("handle PAN mode!!!"); -} - -function handlePanMove(event) { - print("PANNING mode!!! "); - //print("isPanning="+isPanning + " inPanningFromTouch="+isPanningFromTouch + " trackAsOrbitOrPan="+trackAsOrbitOrPan); -} - -function endPanMode(event) { - print("ending PAN mode!!!"); -} - - function mousePressEvent(event) { // if our tools are off, then don't do anything @@ -891,31 +788,6 @@ function mousePressEvent(event) { return; } - // Normally, if we're panning or orbiting from touch, ignore these... because our touch takes precedence. - // but In the case of a button="RIGHT" click, we may get some touch messages first, and we actually want to - // cancel any touch mode, and then let the right-click through - if (isOrbitingFromTouch || isPanningFromTouch) { - - // if the user is holding the ALT key AND they are clicking the RIGHT button (or on multi-touch doing a two - // finger touch, then we want to let the new panning behavior take over. - // if it's any other case we still want to bail - if (event.button == "RIGHT" && trackAsOrbitOrPan) { - // cancel our current multitouch operation... - if (isOrbitingFromTouch) { - endOrbitMode(event); - isOrbitingFromTouch = false; - } - if (isPanningFromTouch) { - //print("mousePressEvent... calling endPanMode()"); - endPanMode(event); - isPanningFromTouch = false; - } - // let things fall through - } else { - return; - } - } - // no clicking on overlays while in panning mode if (!trackAsOrbitOrPan) { var clickedOnSomething = false; @@ -1008,17 +880,7 @@ function mousePressEvent(event) { calcThumbFromScale(intersection.voxel.s); } - // Note: touch and mouse events can cross paths, so we want to ignore any mouse events that would - // start a pan or orbit if we're already doing a pan or orbit via touch... - if ((event.isAlt || trackAsOrbitOrPan) && !(isOrbitingFromTouch || isPanningFromTouch)) { - if (event.isLeftButton && !event.isRightButton) { - startOrbitMode(event); - isOrbiting = true; - } else if (event.isRightButton && !event.isLeftButton) { - startPanMode(event); - isPanning = true; - } - } else if (trackAsDelete || event.isRightButton && !trackAsEyedropper) { + if (trackAsDelete || event.isRightButton && !trackAsEyedropper) { // Delete voxel voxelDetails = calculateVoxelFromIntersection(intersection,"delete"); Voxels.eraseVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s); @@ -1209,23 +1071,7 @@ function mouseMoveEvent(event) { return; } - // if we're panning or orbiting from touch, ignore these... because our touch takes precedence. - if (isOrbitingFromTouch || isPanningFromTouch) { - return; - } - // double check that we didn't accidentally miss a pan or orbit click request - if (trackAsOrbitOrPan && !isPanning && !isOrbiting) { - if (event.isLeftButton && !event.isRightButton) { - startOrbitMode(event); - isOrbiting = true; - } - if (!event.isLeftButton && event.isRightButton) { - startPanMode(event); - isPanning = true; - } - } - if (!trackAsOrbitOrPan && isMovingSlider) { thumbX = (event.x - thumbClickOffsetX) - sliderX; if (thumbX < minThumbX) { @@ -1236,10 +1082,6 @@ function mouseMoveEvent(event) { } calcScaleFromThumb(thumbX); - } else if (isOrbiting) { - handleOrbitingMove(event); - } else if (isPanning) { - handlePanMove(event); } else if (!trackAsOrbitOrPan && isAdding) { // Watch the drag direction to tell which way to 'extrude' this voxel if (!isExtruding) { @@ -1293,16 +1135,6 @@ function mouseReleaseEvent(event) { if (isMovingSlider) { isMovingSlider = false; } - - if (isOrbiting) { - endOrbitMode(event); - isOrbiting = false; - } - if (isPanning) { - print("mouseReleaseEvent... calling endPanMode()"); - endPanMode(event); - isPanning = false; - } isAdding = false; isExtruding = false; } @@ -1396,96 +1228,18 @@ function touchBeginEvent(event) { if (!editToolsOn) { return; } - - // if we're already in the middle of orbiting or panning, then ignore these multi-touch events... - if (isOrbiting || isPanning) { - return; - } - - if (event.isAlt || trackAsOrbitOrPan) { - if (event.touchPoints == touchPointsToOrbit) { - // we need to double check that we didn't start an orbit, because the touch events will sometimes - // come in as 2 then 3 touches... - if (isPanningFromTouch) { - print("touchBeginEvent... calling endPanMode()"); - endPanMode(event); - isPanningFromTouch = false; - } - startOrbitMode(event); - isOrbitingFromTouch = true; - } else if (event.touchPoints == touchPointsToPan) { - // we need to double check that we didn't start an orbit, because the touch events will sometimes - // come in as 2 then 3 touches... - if (isOrbitingFromTouch) { - endOrbitMode(event); - isOrbitingFromTouch = false; - } - startPanMode(event); - isPanningFromTouch = true; - } - } } function touchUpdateEvent(event) { if (!editToolsOn) { return; } - - // if we're already in the middle of orbiting or panning, then ignore these multi-touch events... - if (isOrbiting || isPanning) { - return; - } - - if (isOrbitingFromTouch) { - // we need to double check that we didn't start an orbit, because the touch events will sometimes - // come in as 2 then 3 touches... - if (event.touchPoints == touchPointsToPan) { - //print("we now have touchPointsToPan touches... switch to pan..."); - endOrbitMode(event); - isOrbitingFromTouch = false; - startPanMode(event); - isPanningFromTouch = true; - } else { - handleOrbitingMove(event); - } - } - if (isPanningFromTouch) { - //print("touchUpdateEvent... isPanningFromTouch... event.touchPoints=" + event.touchPoints); - // we need to double check that we didn't start an orbit, because the touch events will sometimes - // come in as 2 then 3 touches... - if (event.touchPoints == touchPointsToOrbit) { - //print("we now have touchPointsToOrbit touches... switch to orbit..."); - //print("touchUpdateEvent... calling endPanMode()"); - endPanMode(event); - isPanningFromTouch = false; - startOrbitMode(event); - isOrbitingFromTouch = true; - handleOrbitingMove(event); - } else { - handlePanMove(event); - } - } } function touchEndEvent(event) { if (!editToolsOn) { return; } - - // if we're already in the middle of orbiting or panning, then ignore these multi-touch events... - if (isOrbiting || isPanning) { - return; - } - - if (isOrbitingFromTouch) { - endOrbitMode(event); - isOrbitingFromTouch = false; - } - if (isPanningFromTouch) { - print("touchEndEvent... calling endPanMode()"); - endPanMode(event); - isPanningFromTouch = false; - } } var lastFingerAddVoxel = { x: -1, y: -1, z: -1}; // off of the build-able area diff --git a/examples/inspect.js b/examples/inspect.js new file mode 100644 index 0000000000..9292450784 --- /dev/null +++ b/examples/inspect.js @@ -0,0 +1,240 @@ +// +// inspect.js +// hifi +// +// Created by Clément Brisset on March 20, 2014 +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// +// Allows you to inspect non moving objects (Voxels or Avatars) using Atl, Control (Command on Mac) and Shift +// +// radial mode = hold ALT +// orbit mode = hold ALT + CONTROL +// pan mode = hold ALT + CONTROL + SHIFT +// Once you are in a mode left click on the object to inspect and hold the click +// Dragging the mouse will move your camera according to the mode you are in. +// + +var AZIMUTH_RATE = 90.0; +var ALTITUDE_RATE = 200.0; +var RADIUS_RATE = 20.0; +var PAN_RATE = 50.0; + +var alt = false; +var shift = false; +var control = false; + +var isActive = false; + +var noMode = 0; +var orbitMode = 1; +var radialMode = 2; +var panningMode = 3; + +var mode = noMode; + +var mouseLastX = 0; +var mouseLastY = 0; + + +var center = { x: 0, y: 0, z: 0 }; +var position = { x: 0, y: 0, z: 0 }; +var vector = { x: 0, y: 0, z: 0 }; +var radius = 0.0; +var azimuth = 0.0; +var altitude = 0.0; + + +function handleRadialMode(dx, dy) { + azimuth += dx / AZIMUTH_RATE; + radius += radius * dy / RADIUS_RATE; + if (radius < 1) { + radius = 1; + } + + vector = { x: (Math.cos(altitude) * Math.cos(azimuth)) * radius, + y: Math.sin(altitude) * radius, + z: (Math.cos(altitude) * Math.sin(azimuth)) * radius }; + position = Vec3.sum(center, vector); + Camera.setPosition(position); +} + +function handleOrbitMode(dx, dy) { + azimuth += dx / AZIMUTH_RATE; + altitude += dy / ALTITUDE_RATE; + + vector = { x:(Math.cos(altitude) * Math.cos(azimuth)) * radius, + y:Math.sin(altitude) * radius, + z:(Math.cos(altitude) * Math.sin(azimuth)) * radius }; + position = Vec3.sum(center, vector); + Camera.setPosition(position); +} + + +function handlePanMode(dx, dy) { + var up = Quat.getUp(Camera.getOrientation()); + var right = Quat.getRight(Camera.getOrientation()); + var distance = Vec3.length(vector); + + var dv = Vec3.sum(Vec3.multiply(up, - distance * dy / PAN_RATE), Vec3.multiply(right, distance * dx / PAN_RATE)); + + center = Vec3.sum(center, dv); + position = Vec3.sum(position, dv); + + Camera.setPosition(position); + Camera.keepLookingAt(center); +} + +function saveCameraState() { + oldMode = Camera.getMode(); + var oldPosition = Camera.getPosition(); + Camera.setMode("independent"); + Camera.setPosition(oldPosition); +} + +function restoreCameraState() { + Camera.stopLooking(); + Camera.setMode(oldMode); +} + +function handleModes() { + var newMode = noMode; + if (alt) { + if (control) { + if (shift) { + newMode = panningMode; + } else { + newMode = orbitMode; + } + } else { + newMode = radialMode; + } + } + + // if leaving noMode + if (mode == noMode && newMode != noMode) { + saveCameraState(); + } + // if entering noMode + if (newMode == noMode && mode != noMode) { + restoreCameraState(); + } + + mode = newMode; +} + +function keyPressEvent(event) { + var changed = false; + + if (event.text == "ALT") { + alt = true; + changed = true; + } + if (event.text == "CONTROL") { + control = true; + changed = true; + } + if (event.text == "SHIFT") { + shift = true; + changed = true; + } + + if (changed) { + handleModes(); + } +} + +function keyReleaseEvent(event) { + var changed = false; + + if (event.text == "ALT") { + alt = false; + changed = true; + } + if (event.text == "CONTROL") { + control = false; + changed = true; + } + if (event.text == "SHIFT") { + shift = false; + changed = true; + } + + if (changed) { + handleModes(); + } +} + +function mousePressEvent(event) { + if (alt) { + isActive = true; + mouseLastX = event.x; + mouseLastY = event.y; + + // Compute trajectories related values + var pickRay = Camera.computePickRay(mouseLastX, mouseLastY); + var intersection = Voxels.findRayIntersection(pickRay); + + position = Camera.getPosition(); + + avatarTarget = MyAvatar.getTargetAvatarPosition(); + voxelTarget = intersection.intersection; + if (Vec3.length(Vec3.subtract(avatarTarget, position)) < Vec3.length(Vec3.subtract(voxelTarget, position))) { + if (avatarTarget.x != 0 || avatarTarget.y != 0 || avatarTarget.z != 0) { + center = avatarTarget; + } else { + center = voxelTarget; + } + } else { + if (voxelTarget.x != 0 || voxelTarget.y != 0 || voxelTarget.z != 0) { + center = voxelTarget; + } else { + center = avatarTarget; + } + } + + vector = Vec3.subtract(position, center); + radius = Vec3.length(vector); + azimuth = Math.atan2(vector.z, vector.x); + altitude = Math.asin(vector.y / Vec3.length(vector)); + + Camera.keepLookingAt(center); + } +} + +function mouseReleaseEvent(event) { + if (isActive) { + isActive = false; + } +} + +function mouseMoveEvent(event) { + if (isActive && mode != noMode) { + if (mode == radialMode) { + handleRadialMode(event.x - mouseLastX, event.y - mouseLastY); + } + if (mode == orbitMode) { + handleOrbitMode(event.x - mouseLastX, event.y - mouseLastY); + } + if (mode == panningMode) { + handlePanMode(event.x - mouseLastX, event.y - mouseLastY); + } + + mouseLastX = event.x; + mouseLastY = event.y; + } +} + +function scriptEnding() { + if (mode != noMode) { + restoreCameraState(); + } +} + +Controller.keyPressEvent.connect(keyPressEvent); +Controller.keyReleaseEvent.connect(keyReleaseEvent); + +Controller.mousePressEvent.connect(mousePressEvent); +Controller.mouseReleaseEvent.connect(mouseReleaseEvent); +Controller.mouseMoveEvent.connect(mouseMoveEvent); + +Script.scriptEnding.connect(scriptEnding); \ No newline at end of file diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 3c61d5f17a..05998e6436 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -4,22 +4,22 @@ Application - + Export Voxels - + Sparse Voxel Octree Files (*.svo) - + Open Script - + JavaScript Files (*.js) @@ -113,18 +113,18 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file @@ -132,122 +132,116 @@ PreferencesDialog - - + + Avatar - - + + <html><head/><body><p>Avatar display name <span style=" color:#909090;">(optional)</span></p></body></html> - - + + Not showing a name - - + + Head - - + + Body - - + + Advanced Tuning - - + + It's not recomended that you play with these settings unless you've looked into exactly what they do. - - + + <p>Avatar</p> - - + + Lean scale (applies to Faceshift users) - - + + Vertical field of view - - + + Avatar scale (default is 1.0) - - + + Pupil dillation - - + + Audio Jitter Buffer Samples (0 for automatic) - - + + Faceshift eye detection - - + + <html><head/><body><p>Voxels</p></body></html> - - + + Maximum voxels - - + + Max voxels sent each second - - - PushButton - - - - - + + Cancel - - + + Save all changes diff --git a/interface/resources/resources.qrc b/interface/resources/resources.qrc index 372fa8b1d4..300728392c 100644 --- a/interface/resources/resources.qrc +++ b/interface/resources/resources.qrc @@ -1,5 +1,6 @@ - - images/close.svg - + + images/close.svg + styles/search.svg + diff --git a/interface/resources/styles/global.qss b/interface/resources/styles/global.qss index d302555463..2554f3b2c9 100644 --- a/interface/resources/styles/global.qss +++ b/interface/resources/styles/global.qss @@ -13,8 +13,9 @@ QLineEdit { border-style: solid; border-width: 1px; border-color: #ccc; - padding: 7px; - opacity: 1; + padding: 8px; + font-size: 16px; + color: rgb(51, 51, 51); } QLabel p { @@ -27,14 +28,15 @@ QPushButton { border-radius: 9px; font-family: Arial; font-size: 18px; - font-weight: 100; color: #ffffff; - padding: 10px 15px; + padding: 10px 0px; } QSpinBox, QDoubleSpinBox { padding: 5px; border-width: 1; + font-size: 16px; + color: rgb(51, 51, 51); } QDoubleSpinBox::up-arrow, @@ -98,3 +100,14 @@ QSlider::handle:horizontal { background-repeat: no-repeat; background-position: center center; } + +QPushButton#closeButton { + border-color: #ccc; + border-style: solid; + border-width: 1px; + border-radius: 0; + background-color: #fff; + background-image: url(styles/close.svg); + background-repeat: no-repeat; + background-position: center center; +} diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 50dbf1b51a..030e3bc6fd 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -692,6 +692,8 @@ bool Application::event(QEvent* event) { void Application::keyPressEvent(QKeyEvent* event) { + _keysPressed.insert(event->key()); + _controllerScriptingInterface.emitKeyPressEvent(event); // send events to any registered scripts // if one of our scripts have asked to capture this event, then stop processing it @@ -914,6 +916,8 @@ void Application::keyPressEvent(QKeyEvent* event) { void Application::keyReleaseEvent(QKeyEvent* event) { + _keysPressed.remove(event->key()); + _controllerScriptingInterface.emitKeyReleaseEvent(event); // send events to any registered scripts // if one of our scripts have asked to capture this event, then stop processing it @@ -921,60 +925,66 @@ void Application::keyReleaseEvent(QKeyEvent* event) { return; } + switch (event->key()) { + case Qt::Key_E: + _myAvatar->setDriveKeys(UP, 0.f); + break; - if (activeWindow() == _window) { - switch (event->key()) { - case Qt::Key_E: - _myAvatar->setDriveKeys(UP, 0.f); - break; + case Qt::Key_C: + _myAvatar->setDriveKeys(DOWN, 0.f); + break; - case Qt::Key_C: - _myAvatar->setDriveKeys(DOWN, 0.f); - break; + case Qt::Key_W: + _myAvatar->setDriveKeys(FWD, 0.f); + break; - case Qt::Key_W: - _myAvatar->setDriveKeys(FWD, 0.f); - break; + case Qt::Key_S: + _myAvatar->setDriveKeys(BACK, 0.f); + break; - case Qt::Key_S: - _myAvatar->setDriveKeys(BACK, 0.f); - break; + case Qt::Key_A: + _myAvatar->setDriveKeys(ROT_LEFT, 0.f); + break; - case Qt::Key_A: - _myAvatar->setDriveKeys(ROT_LEFT, 0.f); - break; + case Qt::Key_D: + _myAvatar->setDriveKeys(ROT_RIGHT, 0.f); + break; - case Qt::Key_D: - _myAvatar->setDriveKeys(ROT_RIGHT, 0.f); - break; + case Qt::Key_Up: + _myAvatar->setDriveKeys(FWD, 0.f); + _myAvatar->setDriveKeys(UP, 0.f); + break; - case Qt::Key_Up: - _myAvatar->setDriveKeys(FWD, 0.f); - _myAvatar->setDriveKeys(UP, 0.f); - break; + case Qt::Key_Down: + _myAvatar->setDriveKeys(BACK, 0.f); + _myAvatar->setDriveKeys(DOWN, 0.f); + break; - case Qt::Key_Down: - _myAvatar->setDriveKeys(BACK, 0.f); - _myAvatar->setDriveKeys(DOWN, 0.f); - break; + case Qt::Key_Left: + _myAvatar->setDriveKeys(LEFT, 0.f); + _myAvatar->setDriveKeys(ROT_LEFT, 0.f); + break; - case Qt::Key_Left: - _myAvatar->setDriveKeys(LEFT, 0.f); - _myAvatar->setDriveKeys(ROT_LEFT, 0.f); - break; + case Qt::Key_Right: + _myAvatar->setDriveKeys(RIGHT, 0.f); + _myAvatar->setDriveKeys(ROT_RIGHT, 0.f); + break; - case Qt::Key_Right: - _myAvatar->setDriveKeys(RIGHT, 0.f); - _myAvatar->setDriveKeys(ROT_RIGHT, 0.f); - break; - - default: - event->ignore(); - break; - } + default: + event->ignore(); + break; } } +void Application::focusOutEvent(QFocusEvent* event) { + // synthesize events for keys currently pressed, since we may not get their release events + foreach (int key, _keysPressed) { + QKeyEvent event(QEvent::KeyRelease, key, Qt::NoModifier); + keyReleaseEvent(&event); + } + _keysPressed.clear(); +} + void Application::mouseMoveEvent(QMouseEvent* event) { _controllerScriptingInterface.emitMouseMoveEvent(event); // send events to any registered scripts @@ -1680,7 +1690,7 @@ void Application::updateMyAvatarLookAtPosition() { } else { // look in direction of the mouse ray, but use distance from intersection, if any float distance = TREE_SCALE; - if (_myAvatar->getLookAtTargetAvatar()) { + if (_myAvatar->getLookAtTargetAvatar() && _myAvatar != _myAvatar->getLookAtTargetAvatar()) { distance = glm::distance(_mouseRayOrigin, static_cast(_myAvatar->getLookAtTargetAvatar())->getHead()->calculateAverageEyePosition()); } @@ -2140,7 +2150,8 @@ void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) { } glm::vec3 Application::getSunDirection() { - return glm::normalize(_environment.getClosestData(_myCamera.getPosition()).getSunLocation() - _myCamera.getPosition()); + return glm::normalize(_environment.getClosestData(_myCamera.getPosition()).getSunLocation(_myCamera.getPosition()) - + _myCamera.getPosition()); } void Application::updateShadowMap() { @@ -2302,7 +2313,8 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { float alpha = 1.0f; if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) { const EnvironmentData& closestData = _environment.getClosestData(whichCamera.getPosition()); - float height = glm::distance(whichCamera.getPosition(), closestData.getAtmosphereCenter()); + float height = glm::distance(whichCamera.getPosition(), + closestData.getAtmosphereCenter(whichCamera.getPosition())); if (height < closestData.getAtmosphereInnerRadius()) { alpha = 0.0f; diff --git a/interface/src/Application.h b/interface/src/Application.h index cbfbf4166d..28060113a9 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -122,6 +123,8 @@ public: void keyPressEvent(QKeyEvent* event); void keyReleaseEvent(QKeyEvent* event); + void focusOutEvent(QFocusEvent* event); + void mouseMoveEvent(QMouseEvent* event); void mousePressEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event); @@ -432,6 +435,8 @@ private: bool _mousePressed; // true if mouse has been pressed (clear when finished) + QSet _keysPressed; + GeometryCache _geometryCache; TextureCache _textureCache; diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index 1f9e23bee1..096b8770fb 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -92,7 +92,7 @@ glm::vec3 Environment::getGravity (const glm::vec3& position) { foreach (const ServerData& serverData, _data) { foreach (const EnvironmentData& environmentData, serverData) { - glm::vec3 vector = environmentData.getAtmosphereCenter() - position; + glm::vec3 vector = environmentData.getAtmosphereCenter(position) - position; float surfaceRadius = environmentData.getAtmosphereInnerRadius(); if (glm::length(vector) <= surfaceRadius) { // At or inside a planet, gravity is as set for the planet @@ -116,7 +116,7 @@ const EnvironmentData Environment::getClosestData(const glm::vec3& position) { float closestDistance = FLT_MAX; foreach (const ServerData& serverData, _data) { foreach (const EnvironmentData& environmentData, serverData) { - float distance = glm::distance(position, environmentData.getAtmosphereCenter()) - + float distance = glm::distance(position, environmentData.getAtmosphereCenter(position)) - environmentData.getAtmosphereOuterRadius(); if (distance < closestDistance) { closest = environmentData; @@ -132,6 +132,8 @@ bool Environment::findCapsulePenetration(const glm::vec3& start, const glm::vec3 // collide with the "floor" bool found = findCapsulePlanePenetration(start, end, radius, glm::vec4(0.0f, 1.0f, 0.0f, 0.0f), penetration); + glm::vec3 middle = (start + end) * 0.5f; + // get the lock for the duration of the call QMutexLocker locker(&_mutex); @@ -141,7 +143,7 @@ bool Environment::findCapsulePenetration(const glm::vec3& start, const glm::vec3 continue; // don't bother colliding with gravity-less environments } glm::vec3 environmentPenetration; - if (findCapsuleSpherePenetration(start, end, radius, environmentData.getAtmosphereCenter(), + if (findCapsuleSpherePenetration(start, end, radius, environmentData.getAtmosphereCenter(middle), environmentData.getAtmosphereInnerRadius(), environmentPenetration)) { penetration = addPenetrations(penetration, environmentPenetration); found = true; @@ -203,10 +205,12 @@ ProgramObject* Environment::createSkyProgram(const char* from, int* locations) { } void Environment::renderAtmosphere(Camera& camera, const EnvironmentData& data) { + glm::vec3 center = data.getAtmosphereCenter(camera.getPosition()); + glPushMatrix(); - glTranslatef(data.getAtmosphereCenter().x, data.getAtmosphereCenter().y, data.getAtmosphereCenter().z); - - glm::vec3 relativeCameraPos = camera.getPosition() - data.getAtmosphereCenter(); + glTranslatef(center.x, center.y, center.z); + + glm::vec3 relativeCameraPos = camera.getPosition() - center; float height = glm::length(relativeCameraPos); // use the appropriate shader depending on whether we're inside or outside diff --git a/interface/src/GLCanvas.cpp b/interface/src/GLCanvas.cpp index a91452c06d..513dcfe40c 100644 --- a/interface/src/GLCanvas.cpp +++ b/interface/src/GLCanvas.cpp @@ -55,6 +55,10 @@ void GLCanvas::keyReleaseEvent(QKeyEvent* event) { Application::getInstance()->keyReleaseEvent(event); } +void GLCanvas::focusOutEvent(QFocusEvent* event) { + Application::getInstance()->focusOutEvent(event); +} + void GLCanvas::mouseMoveEvent(QMouseEvent* event) { Application::getInstance()->mouseMoveEvent(event); } diff --git a/interface/src/GLCanvas.h b/interface/src/GLCanvas.h index ad396a48ce..f7f7fb7c20 100644 --- a/interface/src/GLCanvas.h +++ b/interface/src/GLCanvas.h @@ -31,6 +31,8 @@ protected: virtual void keyPressEvent(QKeyEvent* event); virtual void keyReleaseEvent(QKeyEvent* event); + virtual void focusOutEvent(QFocusEvent* event); + virtual void mouseMoveEvent(QMouseEvent* event); virtual void mousePressEvent(QMouseEvent* event); virtual void mouseReleaseEvent(QMouseEvent* event); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 54b6a5dac2..2b1003f2e4 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -24,11 +24,12 @@ #include #include #include -#include +#include #include #include #include +#include #include "Application.h" #include "Menu.h" @@ -36,6 +37,7 @@ #include "Util.h" #include "InfoView.h" #include "ui/MetavoxelEditor.h" +#include "ModelBrowser.h" Menu* Menu::_instance = NULL; @@ -138,9 +140,8 @@ Menu::Menu() : this, SLOT(goTo())); - addDisabledActionAndSeparator(fileMenu, "Upload/Browse"); - addActionToQMenuAndActionHash(fileMenu, MenuOption::UploaderAvatarHead, 0, Application::getInstance(), SLOT(uploadFST())); - addActionToQMenuAndActionHash(fileMenu, MenuOption::UploaderAvatarSkeleton, 0, Application::getInstance(), SLOT(uploadFST())); + addDisabledActionAndSeparator(fileMenu, "Upload Avatar Model"); + addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadFST, 0, Application::getInstance(), SLOT(uploadFST())); addDisabledActionAndSeparator(fileMenu, "Settings"); addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsImport, 0, this, SLOT(importSettings())); @@ -693,7 +694,7 @@ void Menu::loginForCurrentDomain() { } void Menu::editPreferences() { - if (! _preferencesDialog) { + if (!_preferencesDialog) { _preferencesDialog = new PreferencesDialog(Application::getInstance()->getGLWidget()); _preferencesDialog->show(); } diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 15a4ee1811..96d5267b9c 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -300,8 +300,7 @@ namespace MenuOption { const QString StopAllScripts = "Stop All Scripts"; const QString TestPing = "Test Ping"; const QString TransmitterDrive = "Transmitter Drive"; - const QString UploaderAvatarHead = "Upload Avatar Head"; - const QString UploaderAvatarSkeleton = "Upload Avatar Skeleton"; + const QString UploadFST = "Upload FST file"; const QString Visage = "Visage"; const QString Quit = "Quit"; const QString Voxels = "Voxels"; diff --git a/interface/src/ModelBrowser.cpp b/interface/src/ModelBrowser.cpp new file mode 100644 index 0000000000..e03081273f --- /dev/null +++ b/interface/src/ModelBrowser.cpp @@ -0,0 +1,150 @@ +// +// ModelBrowser.cpp +// hifi +// +// Created by Clement on 3/17/14. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ModelBrowser.h" + +static const QString PREFIX_PARAMETER_NAME = "prefix"; +static const QString MARKER_PARAMETER_NAME = "marker"; +static const QString IS_TRUNCATED_NAME = "IsTruncated"; +static const QString CONTAINER_NAME = "Contents"; +static const QString KEY_NAME = "Key"; + +ModelBrowser::ModelBrowser(ModelType modelType, QWidget* parent) : QWidget(parent), _type(modelType) { + QUrl url(S3_URL); + QUrlQuery query; + + if (_type == Head) { + query.addQueryItem(PREFIX_PARAMETER_NAME, HEAD_MODELS_LOCATION); + } else if (_type == Skeleton) { + query.addQueryItem(PREFIX_PARAMETER_NAME, SKELETON_MODELS_LOCATION); + } + url.setQuery(query); + + _downloader = new FileDownloader(url); + connect(_downloader, SIGNAL(done(QNetworkReply::NetworkError)), SLOT(downloadFinished())); +} + +ModelBrowser::~ModelBrowser() { + delete _downloader; +} + +void ModelBrowser::downloadFinished() { + parseXML(_downloader->getData()); +} + +void ModelBrowser::browse() { + QDialog dialog(this); + dialog.setWindowTitle("Browse models"); + + QGridLayout* layout = new QGridLayout(&dialog); + dialog.setLayout(layout); + + QLineEdit* searchBar = new QLineEdit(&dialog); + layout->addWidget(searchBar, 0, 0); + + ListView* listView = new ListView(&dialog); + listView->setEditTriggers(QAbstractItemView::NoEditTriggers); + layout->addWidget(listView, 1, 0); + listView->connect(searchBar, SIGNAL(textChanged(const QString&)), SLOT(keyboardSearch(const QString&))); + dialog.connect(listView, SIGNAL(doubleClicked(const QModelIndex&)), SLOT(accept())); + + QStringListModel* model = new QStringListModel(_models.keys(), listView); + model->sort(0); + listView->setModel(model); + + QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + layout->addWidget(buttons, 2, 0); + dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept())); + dialog.connect(buttons, SIGNAL(rejected()), SLOT(reject())); + + if (dialog.exec() == QDialog::Rejected) { + return; + } + + QString selectedKey = model->data(listView->currentIndex(), Qt::DisplayRole).toString(); + + emit selected(_models[selectedKey]); +} + +bool ModelBrowser::parseXML(QByteArray xmlFile) { + QXmlStreamReader xml(xmlFile); + QRegExp rx(".*fst"); + bool truncated = false; + QString lastKey; + + // Read xml until the end or an error is detected + while(!xml.atEnd() && !xml.hasError()) { + if(xml.tokenType() == QXmlStreamReader::StartElement && xml.name() == IS_TRUNCATED_NAME) { + while(!(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == IS_TRUNCATED_NAME)) { + // Let's check if there is more + xml.readNext(); + if (xml.text().toString() == "True") { + truncated = true; + } + } + } + + if(xml.tokenType() == QXmlStreamReader::StartElement && xml.name() == CONTAINER_NAME) { + while(!(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == CONTAINER_NAME)) { + // If a file is find, process it + if(xml.tokenType() == QXmlStreamReader::StartElement && xml.name() == KEY_NAME) { + xml.readNext(); + lastKey = xml.text().toString(); + if (rx.exactMatch(xml.text().toString())) { + // Add the found file to the list + _models.insert(QFileInfo(xml.text().toString()).baseName(), + S3_URL + "/" + xml.text().toString()); + } + } + xml.readNext(); + } + } + xml.readNext(); + } + + // Error handling + if(xml.hasError()) { + _models.clear(); + QMessageBox::critical(this, + "ModelBrowser::ModelBrowser()", + xml.errorString(), + QMessageBox::Ok); + return false; + } + + // If we didn't all the files, download the next ones + if (truncated) { + QUrl url(S3_URL); + QUrlQuery query; + + if (_type == Head) { + query.addQueryItem(PREFIX_PARAMETER_NAME, HEAD_MODELS_LOCATION); + } else if (_type == Skeleton) { + query.addQueryItem(PREFIX_PARAMETER_NAME, SKELETON_MODELS_LOCATION); + } + query.addQueryItem(MARKER_PARAMETER_NAME, lastKey); + url.setQuery(query); + + delete _downloader; + _downloader = new FileDownloader(url); + connect(_downloader, SIGNAL(done(QNetworkReply::NetworkError)), SLOT(downloadFinished())); + } + + return true; +} \ No newline at end of file diff --git a/interface/src/ModelBrowser.h b/interface/src/ModelBrowser.h new file mode 100644 index 0000000000..4628642e89 --- /dev/null +++ b/interface/src/ModelBrowser.h @@ -0,0 +1,62 @@ +// +// ModelBrowser.h +// hifi +// +// Created by Clement on 3/17/14. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// + +#ifndef __hifi__ModelBrowser__ +#define __hifi__ModelBrowser__ + +#include + +#include +#include + +static const QString S3_URL = "http://highfidelity-public.s3-us-west-1.amazonaws.com"; +static const QString HEAD_MODELS_LOCATION = "models/heads/"; +static const QString SKELETON_MODELS_LOCATION = "models/skeletons/"; + +enum ModelType { + Head, + Skeleton +}; + +class ModelBrowser : public QWidget { + Q_OBJECT + +public: + ModelBrowser(ModelType modelType, QWidget* parent = NULL); + ~ModelBrowser(); + +signals: + void selected(QString filename); + +public slots: + void browse(); + +private slots: + void downloadFinished(); + +private: + ModelType _type; + FileDownloader* _downloader; + QHash _models; + + bool parseXML(QByteArray xmlFile); +}; + + + +class ListView : public QListView { + Q_OBJECT +public: + ListView(QWidget* parent) : QListView(parent) {} + public slots: + void keyboardSearch(const QString& text) { + QAbstractItemView::keyboardSearch(text); + } +}; + +#endif /* defined(__hifi__ModelBrowser__) */ diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index fb0d704c6a..13e2d3321a 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -582,16 +582,15 @@ void MyAvatar::updateLookAtTargetAvatar() { foreach (const AvatarSharedPointer& avatarPointer, Application::getInstance()->getAvatarManager().getAvatarHash()) { Avatar* avatar = static_cast(avatarPointer.data()); - if (avatar == static_cast(this)) { - continue; - } float distance; if (avatar->findRayIntersection(mouseOrigin, mouseDirection, distance)) { _lookAtTargetAvatar = avatarPointer; + _targetAvatarPosition = avatarPointer->getPosition(); return; } } _lookAtTargetAvatar.clear(); + _targetAvatarPosition = glm::vec3(0, 0, 0); } } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 3544fb1a61..d958103fa6 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -76,6 +76,7 @@ public: void orbit(const glm::vec3& position, int deltaX, int deltaY); + Q_INVOKABLE glm::vec3 getTargetAvatarPosition() const { return _targetAvatarPosition; } AvatarData* getLookAtTargetAvatar() const { return _lookAtTargetAvatar.data(); } void updateLookAtTargetAvatar(); void clearLookAtTargetAvatar(); @@ -116,6 +117,7 @@ private: glm::vec3 _moveTarget; int _moveTargetStepCounter; QWeakPointer _lookAtTargetAvatar; + glm::vec3 _targetAvatarPosition; bool _shouldRender; bool _billboardValid; diff --git a/interface/src/renderer/TextureCache.cpp b/interface/src/renderer/TextureCache.cpp index 2b43c89998..b3820abf25 100644 --- a/interface/src/renderer/TextureCache.cpp +++ b/interface/src/renderer/TextureCache.cpp @@ -313,7 +313,7 @@ void ImageReader::run() { int imageArea = image.width() * image.height(); if (opaquePixels == imageArea) { qDebug() << "Image with alpha channel is completely opaque:" << url; - image.convertToFormat(QImage::Format_RGB888); + image = image.convertToFormat(QImage::Format_RGB888); } QMetaObject::invokeMethod(texture.data(), "setImage", Q_ARG(const QImage&, image), Q_ARG(bool, translucentPixels >= imageArea / 2)); diff --git a/interface/src/ui/FramelessDialog.cpp b/interface/src/ui/FramelessDialog.cpp index 9239deed90..1f67e9f4d1 100644 --- a/interface/src/ui/FramelessDialog.cpp +++ b/interface/src/ui/FramelessDialog.cpp @@ -6,6 +6,7 @@ // // +#include #include #include #include @@ -13,13 +14,29 @@ #include "Application.h" #include "FramelessDialog.h" -FramelessDialog::FramelessDialog(QWidget *parent, Qt::WindowFlags flags) : QDialog(parent, flags | Qt::FramelessWindowHint) { - setWindowOpacity(0.9); +const int RESIZE_HANDLE_WIDTH = 7; + +FramelessDialog::FramelessDialog(QWidget *parent, Qt::WindowFlags flags) : + QDialog(parent, flags | Qt::FramelessWindowHint), + _isResizing(false) { + + setWindowOpacity(0.95); setAttribute(Qt::WA_DeleteOnClose); - isResizing = false; + + installEventFilter(this); } -void FramelessDialog::setStyleSheet(const QString& fileName) { +void FramelessDialog::showEvent(QShowEvent* event) { + QDesktopWidget desktop; + + // move to upper left + move(desktop.availableGeometry().x(), desktop.availableGeometry().y()); + + // keep full height + resize(size().width(), desktop.availableGeometry().height()); +} + +void FramelessDialog::setStyleSheetFile(const QString& fileName) { QFile globalStyleSheet(Application::resourcesPath() + "styles/global.qss"); QFile styleSheet(Application::resourcesPath() + fileName); if (styleSheet.open(QIODevice::ReadOnly) && globalStyleSheet.open(QIODevice::ReadOnly) ) { @@ -27,27 +44,24 @@ void FramelessDialog::setStyleSheet(const QString& fileName) { QDialog::setStyleSheet(globalStyleSheet.readAll() + styleSheet.readAll()); } } + void FramelessDialog::mousePressEvent(QMouseEvent* mouseEvent) { - if (abs(mouseEvent->pos().x() - size().width()) < 2 && mouseEvent->button() == Qt::LeftButton) { - isResizing = true; + + if (abs(mouseEvent->pos().x() - size().width()) < RESIZE_HANDLE_WIDTH && mouseEvent->button() == Qt::LeftButton) { + _isResizing = true; QApplication::setOverrideCursor(Qt::SizeHorCursor); } - // propagate the event - QDialog::mousePressEvent(mouseEvent); } void FramelessDialog::mouseReleaseEvent(QMouseEvent* mouseEvent) { QApplication::restoreOverrideCursor(); - isResizing = false; - // propagate the event - QDialog::mouseReleaseEvent(mouseEvent); + _isResizing = false; } void FramelessDialog::mouseMoveEvent(QMouseEvent* mouseEvent) { - if (isResizing) { + if (_isResizing) { resize(mouseEvent->pos().x(), size().height()); } - QDialog::mouseMoveEvent(mouseEvent); } FramelessDialog::~FramelessDialog() { diff --git a/interface/src/ui/FramelessDialog.h b/interface/src/ui/FramelessDialog.h index 4e18aff161..2bb8d6b85c 100644 --- a/interface/src/ui/FramelessDialog.h +++ b/interface/src/ui/FramelessDialog.h @@ -21,15 +21,16 @@ class FramelessDialog : public QDialog { public: FramelessDialog(QWidget* parent = 0, Qt::WindowFlags flags = 0); virtual ~FramelessDialog(); - void setStyleSheet(const QString& fileName); + void setStyleSheetFile(const QString& fileName); protected: - void mouseMoveEvent(QMouseEvent* mouseEvent); - void mousePressEvent(QMouseEvent* mouseEvent); - void mouseReleaseEvent(QMouseEvent* mouseEvent); + virtual void mouseMoveEvent(QMouseEvent* mouseEvent); + virtual void mousePressEvent(QMouseEvent* mouseEvent); + virtual void mouseReleaseEvent(QMouseEvent* mouseEvent); + virtual void showEvent(QShowEvent* event); private: - bool isResizing; + bool _isResizing; }; diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 318db54f2c..56dbf8470c 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -6,14 +6,27 @@ // // -#include "PreferencesDialog.h" #include "Application.h" #include "Menu.h" +#include "ModelBrowser.h" +#include "PreferencesDialog.h" + +const int SCROLL_PANEL_BOTTOM_MARGIN = 30; +const int OK_BUTTON_RIGHT_MARGIN = 30; +const int BUTTONS_TOP_MARGIN = 24; PreferencesDialog::PreferencesDialog(QWidget* parent, Qt::WindowFlags flags) : FramelessDialog(parent, flags) { + ui.setupUi(this); - setStyleSheet("styles/preferences.qss"); + setStyleSheetFile("styles/preferences.qss"); loadPreferences(); + connect(ui.closeButton, &QPushButton::clicked, this, &QDialog::close); + connect(ui.buttonBrowseHead, &QPushButton::clicked, this, &PreferencesDialog::openHeadModelBrowser); + connect(ui.buttonBrowseBody, &QPushButton::clicked, this, &PreferencesDialog::openBodyModelBrowser); +} + +PreferencesDialog::~PreferencesDialog() { + deleteLater(); } void PreferencesDialog::accept() { @@ -21,6 +34,39 @@ void PreferencesDialog::accept() { close(); } +void PreferencesDialog::openHeadModelBrowser() { + ModelBrowser modelBrowser(Head); + modelBrowser.browse(); + connect(&modelBrowser, &ModelBrowser::selected, ui.faceURLEdit, &QLineEdit::setText); +} + +void PreferencesDialog::openBodyModelBrowser() { + ModelBrowser modelBrowser(Skeleton); + modelBrowser.browse(); + connect(&modelBrowser, &ModelBrowser::selected, ui.skeletonURLEdit, &QLineEdit::setText); +} + +void PreferencesDialog::resizeEvent(QResizeEvent *resizeEvent) { + + // keep buttons panel at the bottom + ui.buttonsPanel->setGeometry(0, size().height() - ui.buttonsPanel->height(), size().width(), ui.buttonsPanel->height()); + + // set width and height of srcollarea to match bottom panel and width + ui.scrollArea->setGeometry(ui.scrollArea->geometry().x(), ui.scrollArea->geometry().y(), + size().width(), + size().height() - ui.buttonsPanel->height() - + SCROLL_PANEL_BOTTOM_MARGIN - ui.scrollArea->geometry().y()); + + // move Save button to left position + ui.defaultButton->move(size().width() - OK_BUTTON_RIGHT_MARGIN - ui.defaultButton->size().width(), BUTTONS_TOP_MARGIN); + + // move Save button to left position + ui.cancelButton->move(ui.defaultButton->pos().x() - ui.cancelButton->size().width(), BUTTONS_TOP_MARGIN); + + // move close button + ui.closeButton->move(size().width() - OK_BUTTON_RIGHT_MARGIN - ui.closeButton->size().width(), ui.closeButton->pos().y()); +} + void PreferencesDialog::loadPreferences() { MyAvatar* myAvatar = Application::getInstance()->getAvatar(); diff --git a/interface/src/ui/PreferencesDialog.h b/interface/src/ui/PreferencesDialog.h index d5cb41c7df..f1f37c66cd 100644 --- a/interface/src/ui/PreferencesDialog.h +++ b/interface/src/ui/PreferencesDialog.h @@ -19,16 +19,22 @@ class PreferencesDialog : public FramelessDialog { public: PreferencesDialog(QWidget* parent = 0, Qt::WindowFlags flags = 0); + ~PreferencesDialog(); + +protected: + void resizeEvent(QResizeEvent* resizeEvent); private: - Ui_PreferencesDialog ui; void loadPreferences(); void savePreferences(); - + void openHeadModelBrowser(); + void openBodyModelBrowser(); + + Ui_PreferencesDialog ui; QString _faceURLString; QString _skeletonURLString; QString _displayNameString; - + private slots: void accept(); diff --git a/interface/ui/preferencesDialog.ui b/interface/ui/preferencesDialog.ui index 0099838177..0f33e2a0b0 100644 --- a/interface/ui/preferencesDialog.ui +++ b/interface/ui/preferencesDialog.ui @@ -3,14 +3,14 @@ PreferencesDialog - Qt::ApplicationModal + Qt::NonModal 0 0 - 640 - 752 + 610 + 499 @@ -25,15 +25,27 @@ 0 - + 0 - 720 - 616 - 80 + 400 + 611 + 97 + + + 0 + 0 + + + + + 0 + 97 + + Arial @@ -42,1136 +54,1245 @@ background-color: #0e7077 - + - 0 - 20 - 591 - 41 + 310 + 24 + 91 + 50 + + + 0 + 0 + + + + + 0 + 50 + + Arial + 18 + 50 + false - - - 0 - - - - - - Arial - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - Arial - - - - Cancel - - - - - - - - Arial - - - - background-color: #fff; + + + + + Cancel + + + + + + 400 + 24 + 188 + 50 + + + + + 0 + 0 + + + + + 188 + 49 + + + + + Arial + 18 + + + + background-color: #fff; color: #0e7077 - - - Save all changes - - - true - - - - + + + Save all changes + + + true + 0 - 0 - 621 - 1000 + 30 + 615 + 351 - - - 0 - 0 - + + QFrame::NoFrame + + + QFrame::Plain + + + 0 true - + 0 0 - 619 - 998 + 615 + 833 - - - - 0 - 50 - 621 - 783 - + + + 0 - - - Arial - + + 30 - - - 0 - - - 30 - - - 0 - - - 30 - - - - - - 0 - 0 - - - - - Arial - 24 - - - - color: #0e7077 - - - Avatar - - - 25 - - - - - - - - - - - 0 - 0 - - - - - 0 - 30 - - - - - Arial - 16 - - - - color: #0e7077 - - - <html><head/><body><p>Avatar display name <span style=" color:#909090;">(optional)</span></p></body></html> - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - displayNameEdit - - - - - - - - 0 - 0 - - - - - 280 - 0 - - - - - Arial - - - - Qt::LeftToRight - - - - - - Not showing a name - - - - - - - - 0 - 0 - - - - - 0 - 30 - - - - - Arial - 16 - - - - color: #0e7077 - - - Head - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - 0 - - - faceURLEdit - - - - - - - - 0 - 0 - - - - - Arial - - - - - - - - - 0 - 0 - - - - - 0 - 30 - - - - - Arial - 16 - - - - color: #0e7077 - - - Body - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - skeletonURLEdit - - - - - - - - 0 - 0 - - - - - Arial - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - Arial - 24 - - - - color: #0e7077 - - - Advanced Tuning - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - 25 - - - - - - - - 0 - 0 - - - - - Arial - - - - color: rgb(51, 51, 51) - - - It's not recomended that you play with these settings unless you've looked into exactly what they do. - - - false - - - true - - - - - - - - 0 - 0 - - - - - 0 - 40 - - - - - Arial - 20 - 50 - false - - - - color: #0e7077 - - - <p>Avatar</p> - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - - - - - 0 - - - 10 - - - 10 - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 25 - - - - - Arial - - - - color: rgb(51, 51, 51) - - - Lean scale (applies to Faceshift users) - - - leanScaleSpin - - - - - - - - Arial - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 10 - - - - - - - - - 0 - 0 - - - - - 95 - 36 - - - - - 70 - 16777215 - - - - - Arial - - - - - - - - - - 0 - - - 10 - - - 0 - - - 10 - - - - - - Arial - - - - color: rgb(51, 51, 51) - - - Vertical field of view - - - fieldOfViewSpin - - - - - - - - Arial - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 95 - 36 - - - - - 70 - 16777215 - - - - - Arial - - - - 1 - - - 180 - - - - - - - - - 0 - - - 10 - - - 0 - - - 10 - - - - - - Arial - - - - color: rgb(51, 51, 51) - - - Avatar scale (default is 1.0) - - - avatarScaleSpin - - - - - - - - Arial - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 95 - 36 - - - - - 70 - 16777215 - - - - - Arial - - - - - - - - - - 0 - - - 10 - - - 0 - - - 10 - - - - - - Arial - - - - color: rgb(51, 51, 51) - - - Pupil dillation - - - - - - - - Arial - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 125 - 0 - - - - - Arial - - - - Qt::Horizontal - - - - - - - - - 0 - - - 10 - - - 0 - - - 10 - - - - - - Arial - - - - color: rgb(51, 51, 51) - - - Audio Jitter Buffer Samples (0 for automatic) - - - - - - - - Arial - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 95 - 36 - - - - - 70 - 16777215 - - - - - Arial - - - - -10000 - - - 10000 - - - 1 - - - - - - - - - 0 - - - 10 - - - 0 - - - 10 - - - - - - Arial - - - - color: rgb(51, 51, 51) - - - Faceshift eye detection - - - avatarScaleSpin - - - - - - - - Arial - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 125 - 0 - - - - - Arial - - - - Qt::Horizontal - - - - - - - - - - 0 - 0 - - - - - 0 - 40 - - - - - Arial - 20 - 50 - false - - - - color: #0e7077 - - - <html><head/><body><p>Voxels</p></body></html> - - - - - - - 0 - - - 10 - - - 0 - - - 10 - - - - - - Arial - - - - color: rgb(51, 51, 51) - - - Maximum voxels - - - leanScaleSpin - - - - - - - - Arial - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 125 - 36 - - - - - Arial - - - - 5000000 - - - 50000 - - - - - - - - - 0 - - - 10 - - - 0 - - - 10 - - - - - - Arial - - - - Max voxels sent each second - - - leanScaleSpin - - - - - - - - Arial - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 95 - 36 - - - - - 70 - 16777215 - - - - - Arial - - - - 60 - - - 6000 - - - 10 - - - - - - - - - - - 540 - 40 - 114 - 32 - + + 0 - - PushButton + + 30 - + + 30 + + + + + + 0 + 0 + + + + + Arial + 24 + + + + color: #0e7077 + + + Avatar + + + 25 + + + + + + + + + + + 0 + 0 + + + + + 0 + 30 + + + + + Arial + 16 + + + + color: #0e7077 + + + <html><head/><body><p>Avatar display name <span style=" color:#909090;">(optional)</span></p></body></html> + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + displayNameEdit + + + + + + + + 0 + 0 + + + + + 280 + 20 + + + + + Arial + + + + Qt::LeftToRight + + + + + + Not showing a name + + + + + + + + 0 + 0 + + + + + 0 + 30 + + + + + Arial + 16 + + + + color: #0e7077 + + + Head + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + 0 + + + faceURLEdit + + + + + + + + + + 0 + 0 + + + + + Arial + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + background-color: #fff; +border-radius: 0; +padding: 0; + + + + + + + :/styles/search.svg + + + + + + + + + + + 0 + 0 + + + + + 0 + 30 + + + + + Arial + 16 + + + + color: #0e7077 + + + Body + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + skeletonURLEdit + + + + + + + + + + 0 + 0 + + + + + Arial + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + background-color: #fff; +border-radius: 0; +padding: 0; + + + + + + + :/styles/search.svg + + + + + + + + + + Qt::Vertical + + + + 0 + 35 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + Arial + 24 + + + + color: #0e7077 + + + Advanced Tuning + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + 25 + + + + + + + + 0 + 0 + + + + + Arial + 16 + + + + color: rgb(51, 51, 51) + + + It's not recomended that you play with these settings unless you've looked into exactly what they do. + + + false + + + true + + + + + + + + 0 + 0 + + + + + 0 + 40 + + + + + Arial + 20 + 50 + false + + + + color: #0e7077 + + + <p>Avatar</p> + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + 0 + + + 10 + + + 0 + + + 10 + + + + + + Arial + + + + color: rgb(51, 51, 51) + + + Vertical field of view + + + fieldOfViewSpin + + + + + + + + Arial + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 95 + 36 + + + + + 70 + 16777215 + + + + + Arial + + + + 1 + + + 180 + + + + + + + + + 0 + + + 10 + + + 10 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 25 + + + + + Arial + + + + color: rgb(51, 51, 51) + + + Lean scale (applies to Faceshift users) + + + leanScaleSpin + + + + + + + + Arial + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 10 + + + + + + + + + 0 + 0 + + + + + 95 + 36 + + + + + 70 + 16777215 + + + + + Arial + + + + + + + + + + 0 + + + 10 + + + 0 + + + 10 + + + + + + Arial + + + + color: rgb(51, 51, 51) + + + Avatar scale (default is 1.0) + + + avatarScaleSpin + + + + + + + + Arial + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 95 + 36 + + + + + 70 + 16777215 + + + + + Arial + + + + + + + + + + 0 + + + 10 + + + 0 + + + 10 + + + + + + Arial + + + + color: rgb(51, 51, 51) + + + Pupil dillation + + + pupilDilationSlider + + + + + + + + Arial + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 125 + 0 + + + + + Arial + + + + Qt::Horizontal + + + + + + + + + 0 + + + 10 + + + 0 + + + 10 + + + + + + Arial + + + + color: rgb(51, 51, 51) + + + Audio Jitter Buffer Samples (0 for automatic) + + + audioJitterSpin + + + + + + + + Arial + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 95 + 36 + + + + + 70 + 16777215 + + + + + Arial + + + + -10000 + + + 10000 + + + 1 + + + + + + + + + 0 + + + 10 + + + 0 + + + 10 + + + + + + Arial + + + + color: rgb(51, 51, 51) + + + Faceshift eye detection + + + faceshiftEyeDeflectionSider + + + + + + + + Arial + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 125 + 0 + + + + + Arial + + + + Qt::Horizontal + + + + + + + + + + 0 + 0 + + + + + 0 + 40 + + + + + Arial + 20 + 50 + false + + + + color: #0e7077 + + + <html><head/><body><p>Voxels</p></body></html> + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + 0 + + + 10 + + + 0 + + + 10 + + + + + + Arial + + + + color: rgb(51, 51, 51) + + + Maximum voxels + + + maxVoxelsSpin + + + + + + + + Arial + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 125 + 36 + + + + + Arial + + + + 5000000 + + + 50000 + + + + + + + + + 0 + + + 10 + + + 0 + + + 10 + + + + + + Arial + + + + Max voxels sent each second + + + maxVoxelsPPSSpin + + + + + + + + Arial + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 95 + 36 + + + + + 70 + 16777215 + + + + + Arial + + + + 60 + + + 6000 + + + 10 + + + + + + + + + + 540 + 24 + 31 + 31 + + + + + PreferAntialias + + + + + + @@ -1179,6 +1300,41 @@ color: #0e7077 1 - - + + + + + + cancelButton + clicked() + PreferencesDialog + close() + + + 495 + 749 + + + 528 + 0 + + + + + defaultButton + clicked() + PreferencesDialog + accept() + + + 504 + 749 + + + 20 + 20 + + + + diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 0e92ab4eb5..cf35b6a20f 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -19,7 +19,8 @@ AudioRingBuffer::AudioRingBuffer(int numFrameSamples) : NodeData(), _sampleCapacity(numFrameSamples * RING_BUFFER_LENGTH_FRAMES), _isStarved(true), - _hasStarted(false) + _hasStarted(false), + _averageLoudness(0) { if (numFrameSamples) { _buffer = new int16_t[_sampleCapacity]; @@ -55,18 +56,22 @@ int AudioRingBuffer::parseData(const QByteArray& packet) { return writeData(packet.data() + numBytesPacketHeader, packet.size() - numBytesPacketHeader); } -float AudioRingBuffer::averageLoudnessForBoundarySamples(int numSamples) { +void AudioRingBuffer::updateAverageLoudnessForBoundarySamples(int numSamples) { // ForBoundarySamples means that we expect the number of samples not to roll of the end of the ring buffer - float averageLoudness = 0; + float nextLoudness = 0; for (int i = 0; i < numSamples; ++i) { - averageLoudness += fabsf(_nextOutput[i]); + nextLoudness += fabsf(_nextOutput[i]); } - averageLoudness /= numSamples; - averageLoudness /= MAX_SAMPLE_VALUE; + nextLoudness /= numSamples; + nextLoudness /= MAX_SAMPLE_VALUE; + + const int TRAILING_AVERAGE_FRAMES = 100; + const float CURRENT_FRAME_RATIO = 1.0f / TRAILING_AVERAGE_FRAMES; + const float PREVIOUS_FRAMES_RATIO = 1 - CURRENT_FRAME_RATIO; - return averageLoudness; + _averageLoudness = (_averageLoudness * PREVIOUS_FRAMES_RATIO) + (CURRENT_FRAME_RATIO * nextLoudness); } qint64 AudioRingBuffer::readSamples(int16_t* destination, qint64 maxSamples) { diff --git a/libraries/audio/src/AudioRingBuffer.h b/libraries/audio/src/AudioRingBuffer.h index 0beb45ca18..efc85ac94b 100644 --- a/libraries/audio/src/AudioRingBuffer.h +++ b/libraries/audio/src/AudioRingBuffer.h @@ -50,7 +50,8 @@ public: const int16_t* getNextOutput() { return _nextOutput; } const int16_t* getBuffer() { return _buffer; } - float averageLoudnessForBoundarySamples(int numSamples); + void updateAverageLoudnessForBoundarySamples(int numSamples); + float getAverageLoudness() const { return _averageLoudness; } qint64 readSamples(int16_t* destination, qint64 maxSamples); qint64 writeSamples(const int16_t* source, qint64 maxSamples); @@ -85,6 +86,8 @@ protected: int16_t* _buffer; bool _isStarved; bool _hasStarted; + + float _averageLoudness; }; #endif /* defined(__interface__AudioRingBuffer__) */ diff --git a/libraries/audio/src/PositionalAudioRingBuffer.cpp b/libraries/audio/src/PositionalAudioRingBuffer.cpp index 66a27647d6..ccbe5d3f23 100644 --- a/libraries/audio/src/PositionalAudioRingBuffer.cpp +++ b/libraries/audio/src/PositionalAudioRingBuffer.cpp @@ -50,6 +50,7 @@ int PositionalAudioRingBuffer::parseData(const QByteArray& packet) { int16_t numSilentSamples; memcpy(&numSilentSamples, packet.data() + readBytes, sizeof(int16_t)); + readBytes += sizeof(int16_t); addSilentFrame(numSilentSamples); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index e5e0e4b3d7..4e57e311eb 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -88,6 +88,17 @@ QByteArray AvatarData::toByteArray() { // Body scale destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _targetScale); + // Head rotation (NOTE: This needs to become a quaternion to save two bytes) + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getTweakedYaw()); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getTweakedPitch()); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getTweakedRoll()); + + // Head lean X,Z (head lateral and fwd/back motion relative to torso) + memcpy(destinationBuffer, &_headData->_leanSideways, sizeof(_headData->_leanSideways)); + destinationBuffer += sizeof(_headData->_leanSideways); + memcpy(destinationBuffer, &_headData->_leanForward, sizeof(_headData->_leanForward)); + destinationBuffer += sizeof(_headData->_leanForward); + // Lookat Position memcpy(destinationBuffer, &_headData->_lookAtPosition, sizeof(_headData->_lookAtPosition)); destinationBuffer += sizeof(_headData->_lookAtPosition); @@ -191,6 +202,21 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) { // Body scale sourceBuffer += unpackFloatRatioFromTwoByte(sourceBuffer, _targetScale); + // Head rotation (NOTE: This needs to become a quaternion to save two bytes) + float headYaw, headPitch, headRoll; + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headYaw); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headPitch); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headRoll); + _headData->setYaw(headYaw); + _headData->setPitch(headPitch); + _headData->setRoll(headRoll); + + // Head position relative to pelvis + memcpy(&_headData->_leanSideways, sourceBuffer, sizeof(_headData->_leanSideways)); + sourceBuffer += sizeof(float); + memcpy(&_headData->_leanForward, sourceBuffer, sizeof(_headData->_leanForward)); + sourceBuffer += sizeof(_headData->_leanForward); + // Lookat Position memcpy(&_headData->_lookAtPosition, sourceBuffer, sizeof(_headData->_lookAtPosition)); sourceBuffer += sizeof(_headData->_lookAtPosition); diff --git a/libraries/shared/src/FileDownloader.cpp b/libraries/shared/src/FileDownloader.cpp new file mode 100644 index 0000000000..2b65bbd8df --- /dev/null +++ b/libraries/shared/src/FileDownloader.cpp @@ -0,0 +1,65 @@ +// +// FileDownloader.cpp +// hifi +// +// Created by Clement Brisset on 3/14/14. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// +// + +#include +#include +#include +#include + +#include "FileDownloader.h" + +FileDownloader::FileDownloader(const QUrl dataURL, QObject* parent) : + QObject(parent), + _done(false) +{ + connect(&_networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(processReply(QNetworkReply*))); + + QNetworkRequest request(dataURL); + _networkAccessManager.get(request); +} + +void FileDownloader::processReply(QNetworkReply *reply) { + if (reply->error() == QNetworkReply::NoError) { + _downloadedData = reply->readAll(); + } + + reply->deleteLater(); + _done = true; + emit done(reply->error()); +} + +void FileDownloader::waitForFile(int timeout) { + QTimer timer; + QEventLoop loop; + connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + connect(this, SIGNAL(done(QNetworkReply::NetworkError)), &loop, SLOT(quit())); + + if (!_done) { + if (timeout > 0) { + timer.start(timeout); + } + loop.exec(); + } +} + +QByteArray FileDownloader::download(const QUrl dataURL, int timeout) { + QTimer timer; + QEventLoop loop; + connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit)); + + FileDownloader downloader(dataURL); + connect(&downloader, SIGNAL(done(QNetworkReply::NetworkError)), &loop, SLOT(quit())); + + if (timeout > 0) { + timer.start(timeout); + } + loop.exec(); + + return downloader.getData(); +} \ No newline at end of file diff --git a/libraries/shared/src/FileDownloader.h b/libraries/shared/src/FileDownloader.h new file mode 100644 index 0000000000..593b39b013 --- /dev/null +++ b/libraries/shared/src/FileDownloader.h @@ -0,0 +1,44 @@ +// +// FileDownloader.h +// hifi +// +// Created by Clement Brisset on 3/14/14. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// +// + +#ifndef __hifi__FileDownloader__ +#define __hifi__FileDownloader__ + +#include +#include +#include + +class FileDownloader : public QObject { + Q_OBJECT + +public: + FileDownloader(const QUrl dataURL, QObject* parent = NULL); + + void waitForFile(int timeout = 0); + + QByteArray getData() const { return _downloadedData; } + bool done() { return _done; } + + static QByteArray download(const QUrl dataURL, int timeout = 0); + +signals: + void done(QNetworkReply::NetworkError error); + +private slots: + void processReply(QNetworkReply* reply); + +private: + QNetworkAccessManager _networkAccessManager; + QByteArray _downloadedData; + + bool _done; +}; + + +#endif /* defined(__hifi__FileDownloader__) */ diff --git a/libraries/shared/src/FstReader.cpp b/libraries/shared/src/FstReader.cpp index d82ddf68a3..a803583598 100644 --- a/libraries/shared/src/FstReader.cpp +++ b/libraries/shared/src/FstReader.cpp @@ -24,6 +24,7 @@ static const QString NAME_FIELD = "name"; static const QString FILENAME_FIELD = "filename"; static const QString TEXDIR_FIELD = "texdir"; static const QString LOD_FIELD = "lod"; +static const QString HEAD_SPECIFIC_FIELD = "bs"; static const QString MODEL_URL = "/api/v1/models"; @@ -32,6 +33,7 @@ static const int MAX_SIZE = 10 * 1024 * 1024; // 10 MB FstReader::FstReader() : _lodCount(-1), _texturesCount(-1), + _isHead(false), _readyToSend(false), _dataMultiPart(new QHttpMultiPart(QHttpMultiPart::FormDataType)) { @@ -81,13 +83,15 @@ bool FstReader::zip() { } // according to what is read, we modify the command - if (line.first() == NAME_FIELD) { + if (line[1] == HEAD_SPECIFIC_FIELD) { + _isHead = true; + } else if (line[1] == NAME_FIELD) { QHttpPart textPart; textPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data;" " name=\"model_name\""); textPart.setBody(line[1].toUtf8()); _dataMultiPart->append(textPart); - } else if (line.first() == FILENAME_FIELD) { + } else if (line[1] == FILENAME_FIELD) { QFileInfo fbx(QFileInfo(fst).path() + "/" + line[1]); if (!fbx.exists() || !fbx.isFile()) { // Check existence qDebug() << "[ERROR] FBX file " << fbx.absoluteFilePath() << " doesn't exist."; @@ -101,7 +105,7 @@ bool FstReader::zip() { if (!addPart(_zipDir.path() + "/" + line[1], "fbx")) { return false; } - } else if (line.first() == TEXDIR_FIELD) { // Check existence + } else if (line[1] == TEXDIR_FIELD) { // Check existence QFileInfo texdir(QFileInfo(fst).path() + "/" + line[1]); if (!texdir.exists() || !texdir.isDir()) { qDebug() << "[ERROR] Texture directory " << texdir.absolutePath() << " doesn't exist."; @@ -110,7 +114,7 @@ bool FstReader::zip() { if (!addTextures(texdir)) { // Recursive compress and copy return false; } - } else if (line.first() == LOD_FIELD) { + } else if (line[1] == LOD_FIELD) { QFileInfo lod(QFileInfo(fst).path() + "/" + line[1]); if (!lod.exists() || !lod.isFile()) { // Check existence qDebug() << "[ERROR] FBX file " << lod.absoluteFilePath() << " doesn't exist."; @@ -127,6 +131,17 @@ bool FstReader::zip() { } } + + QHttpPart textPart; + textPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data;" + " name=\"model_category\""); + if (_isHead) { + textPart.setBody("head"); + } else { + textPart.setBody("skeleton"); + } + _dataMultiPart->append(textPart); + _readyToSend = true; return true; } diff --git a/libraries/shared/src/FstReader.h b/libraries/shared/src/FstReader.h index aab42bd967..1d9da71641 100644 --- a/libraries/shared/src/FstReader.h +++ b/libraries/shared/src/FstReader.h @@ -27,6 +27,7 @@ private: int _lodCount; int _texturesCount; int _totalSize; + bool _isHead; bool _readyToSend; QHttpMultiPart* _dataMultiPart; diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index 307453d8bf..c7518708ce 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -45,7 +45,9 @@ int packArithmeticallyCodedValue(int value, char* destination) { PacketVersion versionForPacketType(PacketType type) { switch (type) { case PacketTypeAvatarData: - return 2; + return 3; + case PacketTypeEnvironmentData: + return 1; case PacketTypeParticleData: return 1; case PacketTypeDomainList: diff --git a/libraries/voxels/src/EnvironmentData.cpp b/libraries/voxels/src/EnvironmentData.cpp index 5cee88e127..1c9af55abd 100644 --- a/libraries/voxels/src/EnvironmentData.cpp +++ b/libraries/voxels/src/EnvironmentData.cpp @@ -14,6 +14,7 @@ // GameEngine.cpp EnvironmentData::EnvironmentData(int id) : _id(id), + _flat(true), _gravity(0.0f), _atmosphereCenter(0, -1000, 0), _atmosphereInnerRadius(1000), @@ -25,12 +26,23 @@ EnvironmentData::EnvironmentData(int id) : _sunBrightness(20.0f) { } +glm::vec3 EnvironmentData::getAtmosphereCenter(const glm::vec3& cameraPosition) const { + return _atmosphereCenter + (_flat ? glm::vec3(cameraPosition.x, 0.0f, cameraPosition.z) : glm::vec3()); +} + +glm::vec3 EnvironmentData::getSunLocation(const glm::vec3& cameraPosition) const { + return _sunLocation + (_flat ? glm::vec3(cameraPosition.x, 0.0f, cameraPosition.z) : glm::vec3()); +} + int EnvironmentData::getBroadcastData(unsigned char* destinationBuffer) const { unsigned char* bufferStart = destinationBuffer; memcpy(destinationBuffer, &_id, sizeof(_id)); destinationBuffer += sizeof(_id); + memcpy(destinationBuffer, &_flat, sizeof(_flat)); + destinationBuffer += sizeof(_flat); + memcpy(destinationBuffer, &_gravity, sizeof(_gravity)); destinationBuffer += sizeof(_gravity); @@ -67,6 +79,9 @@ int EnvironmentData::parseData(const unsigned char* sourceBuffer, int numBytes) memcpy(&_id, sourceBuffer, sizeof(_id)); sourceBuffer += sizeof(_id); + memcpy(&_flat, sourceBuffer, sizeof(_flat)); + sourceBuffer += sizeof(_flat); + memcpy(&_gravity, sourceBuffer, sizeof(_gravity)); sourceBuffer += sizeof(_gravity); diff --git a/libraries/voxels/src/EnvironmentData.h b/libraries/voxels/src/EnvironmentData.h index 90cc0763fe..627a661e1c 100644 --- a/libraries/voxels/src/EnvironmentData.h +++ b/libraries/voxels/src/EnvironmentData.h @@ -19,6 +19,9 @@ public: void setID(int id) { _id = id; } int getID() const { return _id; } + void setFlat(bool flat) { _flat = flat; } + bool isFlat() const { return _flat; } + void setGravity(float gravity) { _gravity = gravity; } float getGravity() const { return _gravity; } @@ -42,6 +45,9 @@ public: const glm::vec3& getSunLocation() const { return _sunLocation; } float getSunBrightness() const { return _sunBrightness; } + glm::vec3 getAtmosphereCenter(const glm::vec3& cameraPosition) const; + glm::vec3 getSunLocation(const glm::vec3& cameraPosition) const; + int getBroadcastData(unsigned char* destinationBuffer) const; int parseData(const unsigned char* sourceBuffer, int numBytes); @@ -49,6 +55,8 @@ private: int _id; + bool _flat; + float _gravity; glm::vec3 _atmosphereCenter; From 3eb64f5b2933fd11e341ce986a4b7932cbd53d8b Mon Sep 17 00:00:00 2001 From: stojce Date: Fri, 21 Mar 2014 22:45:15 +0100 Subject: [PATCH 11/23] updated interface_en.ts file --- interface/interface_en.ts | 125 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 121 insertions(+), 4 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 34e3614716..12d9e48589 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -113,22 +113,139 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file + + PreferencesDialog + + + + Cancel + + + + + + Save all changes + + + + + + Avatar + + + + + + <html><head/><body><p>Avatar display name <span style=" color:#909090;">(optional)</span></p></body></html> + + + + + + Not showing a name + + + + + + Head + + + + + + Body + + + + + + Advanced Tuning + + + + + + It's not recomended that you play with these settings unless you've looked into exactly what they do. + + + + + + <p>Avatar</p> + + + + + + Vertical field of view + + + + + + Lean scale (applies to Faceshift users) + + + + + + Avatar scale (default is 1.0) + + + + + + Pupil dillation + + + + + + Audio Jitter Buffer Samples (0 for automatic) + + + + + + Faceshift eye detection + + + + + + <html><head/><body><p>Voxels</p></body></html> + + + + + + Maximum voxels + + + + + + Max voxels sent each second + + + QObject From 7c36c4a2b73f1c8b33d440d146eef51d840b3555 Mon Sep 17 00:00:00 2001 From: stojce Date: Sun, 23 Mar 2014 13:20:24 +0100 Subject: [PATCH 12/23] Layout fixes --- interface/interface_en.ts | 82 ++++++++++++++-------------- interface/src/ui/FramelessDialog.cpp | 3 - interface/ui/preferencesDialog.ui | 44 ++++++++++++--- 3 files changed, 78 insertions(+), 51 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 12d9e48589..7dc5a4c41d 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -14,12 +14,12 @@ - + Open Script - + JavaScript Files (*.js) @@ -132,116 +132,116 @@ PreferencesDialog - - + + Cancel - - + + Save all changes - - + + Avatar - - + + <html><head/><body><p>Avatar display name <span style=" color:#909090;">(optional)</span></p></body></html> - - + + Not showing a name - - + + Head - - + + Body - - + + Advanced Tuning - - + + It's not recomended that you play with these settings unless you've looked into exactly what they do. - - + + <p>Avatar</p> - - + + Vertical field of view - - + + Lean scale (applies to Faceshift users) - - - Avatar scale (default is 1.0) + + + Avatar scale <span style=" color:#909090;">(default is 1.0)</span> - - + + Pupil dillation - - + + Audio Jitter Buffer Samples (0 for automatic) - - + + Faceshift eye detection - - + + <html><head/><body><p>Voxels</p></body></html> - - + + Maximum voxels - - + + Max voxels sent each second diff --git a/interface/src/ui/FramelessDialog.cpp b/interface/src/ui/FramelessDialog.cpp index 1f67e9f4d1..2b9dd42ed7 100644 --- a/interface/src/ui/FramelessDialog.cpp +++ b/interface/src/ui/FramelessDialog.cpp @@ -19,10 +19,7 @@ const int RESIZE_HANDLE_WIDTH = 7; FramelessDialog::FramelessDialog(QWidget *parent, Qt::WindowFlags flags) : QDialog(parent, flags | Qt::FramelessWindowHint), _isResizing(false) { - - setWindowOpacity(0.95); setAttribute(Qt::WA_DeleteOnClose); - installEventFilter(this); } diff --git a/interface/ui/preferencesDialog.ui b/interface/ui/preferencesDialog.ui index 0f33e2a0b0..7692da2943 100644 --- a/interface/ui/preferencesDialog.ui +++ b/interface/ui/preferencesDialog.ui @@ -9,8 +9,8 @@ 0 0 - 610 - 499 + 638 + 652 @@ -25,11 +25,14 @@ 0 + + 0.950000000000000 + 0 - 400 + 560 611 97 @@ -135,7 +138,7 @@ color: #0e7077 0 30 615 - 351 + 491 @@ -527,8 +530,11 @@ padding: 0; 16 + + true + - color: rgb(51, 51, 51) + color: rgb(51, 51, 51); It's not recomended that you play with these settings unless you've looked into exactly what they do. @@ -596,11 +602,14 @@ padding: 0; - color: rgb(51, 51, 51) + Vertical field of view + + 15 + fieldOfViewSpin @@ -701,6 +710,9 @@ padding: 0; Lean scale (applies to Faceshift users) + + 15 + leanScaleSpin @@ -781,7 +793,10 @@ padding: 0; color: rgb(51, 51, 51) - Avatar scale (default is 1.0) + Avatar scale <span style=" color:#909090;">(default is 1.0)</span> + + + 15 avatarScaleSpin @@ -862,6 +877,9 @@ padding: 0; Pupil dillation + + 15 + pupilDilationSlider @@ -938,6 +956,9 @@ padding: 0; Audio Jitter Buffer Samples (0 for automatic) + + 15 + audioJitterSpin @@ -1026,6 +1047,9 @@ padding: 0; Faceshift eye detection + + 15 + faceshiftEyeDeflectionSider @@ -1135,6 +1159,9 @@ padding: 0; Maximum voxels + + 15 + maxVoxelsSpin @@ -1211,6 +1238,9 @@ padding: 0; Max voxels sent each second + + 15 + maxVoxelsPPSSpin From 32502d7b0dbb0ca35981aae7ba574f40ec8ba39e Mon Sep 17 00:00:00 2001 From: stojce Date: Sun, 23 Mar 2014 16:20:29 +0100 Subject: [PATCH 13/23] layout improvements --- interface/interface_en.ts | 62 ++++++++++++-------------- interface/src/Menu.h | 1 + interface/src/ui/PreferencesDialog.cpp | 14 +++--- interface/ui/preferencesDialog.ui | 14 +++--- 4 files changed, 46 insertions(+), 45 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 7dc5a4c41d..b8534c1779 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -133,115 +133,111 @@ PreferencesDialog - + Cancel - + Save all changes - + + + Avatar - + <html><head/><body><p>Avatar display name <span style=" color:#909090;">(optional)</span></p></body></html> - + Not showing a name - + Head - + Body - + Advanced Tuning - + It's not recomended that you play with these settings unless you've looked into exactly what they do. - - - <p>Avatar</p> - - - - - + + Vertical field of view - - + + Lean scale (applies to Faceshift users) - - + + Avatar scale <span style=" color:#909090;">(default is 1.0)</span> - - + + Pupil dillation - - + + Audio Jitter Buffer Samples (0 for automatic) - - + + Faceshift eye detection - - + + <html><head/><body><p>Voxels</p></body></html> - - + + Maximum voxels - - + + Max voxels sent each second diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 96d5267b9c..2c459a488a 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -75,6 +75,7 @@ public: float getAudioJitterBufferSamples() const { return _audioJitterBufferSamples; } void setAudioJitterBufferSamples(float audioJitterBufferSamples) { _audioJitterBufferSamples = audioJitterBufferSamples; } float getFieldOfView() const { return _fieldOfView; } + void setFieldOfView(float fieldOfView) { _fieldOfView = fieldOfView; } float getFaceshiftEyeDeflection() const { return _faceshiftEyeDeflection; } void setFaceshiftEyeDeflection(float faceshiftEyeDeflection) { _faceshiftEyeDeflection = faceshiftEyeDeflection; } BandwidthDialog* getBandwidthDialog() const { return _bandwidthDialog; } diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 56dbf8470c..c7f5f19099 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -71,16 +71,16 @@ void PreferencesDialog::loadPreferences() { MyAvatar* myAvatar = Application::getInstance()->getAvatar(); Menu* menuInstance = Menu::getInstance(); - + _displayNameString = myAvatar->getDisplayName(); ui.displayNameEdit->setText(_displayNameString); - + _faceURLString = myAvatar->getHead()->getFaceModel().getURL().toString(); ui.faceURLEdit->setText(_faceURLString); - + _skeletonURLString = myAvatar->getSkeletonModel().getURL().toString(); ui.skeletonURLEdit->setText(_skeletonURLString); - + ui.pupilDilationSlider->setValue(myAvatar->getHead()->getPupilDilation() * ui.pupilDilationSlider->maximum()); @@ -137,10 +137,14 @@ void PreferencesDialog::savePreferences() { Application::getInstance()->resizeGL(Application::getInstance()->getGLWidget()->width(), Application::getInstance()->getGLWidget()->height()); + Menu::getInstance()->setFieldOfView(ui.fieldOfViewSpin->value()); + Menu::getInstance()->setFaceshiftEyeDeflection(ui.faceshiftEyeDeflectionSider->value() / (float)ui.faceshiftEyeDeflectionSider->maximum()); Menu::getInstance()->setMaxVoxelPacketsPerSecond(ui.maxVoxelsPPSSpin->value()); Menu::getInstance()->setAudioJitterBufferSamples(ui.audioJitterSpin->value()); - + + Application::getInstance()->resizeGL(Application::getInstance()->getGLWidget()->width(), + Application::getInstance()->getGLWidget()->height()); } diff --git a/interface/ui/preferencesDialog.ui b/interface/ui/preferencesDialog.ui index 7692da2943..14db1b6d5e 100644 --- a/interface/ui/preferencesDialog.ui +++ b/interface/ui/preferencesDialog.ui @@ -573,7 +573,7 @@ padding: 0; color: #0e7077 - <p>Avatar</p> + Avatar Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft @@ -627,8 +627,8 @@ padding: 0; - 40 - 20 + 0 + 0 @@ -649,8 +649,8 @@ padding: 0; - 70 - 16777215 + 95 + 36 @@ -1100,7 +1100,7 @@ padding: 0; - + 0 @@ -1125,7 +1125,7 @@ padding: 0; color: #0e7077 - <html><head/><body><p>Voxels</p></body></html> + Voxels Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft From 22a8693b896dfdfba3a2079682539f94f5488bf3 Mon Sep 17 00:00:00 2001 From: stojce Date: Wed, 26 Mar 2014 00:05:11 +0100 Subject: [PATCH 14/23] Overlay behaviour --- interface/interface_en.ts | 129 +++++++++++++++++++++++++-- interface/src/Menu.cpp | 2 +- interface/src/ui/FramelessDialog.cpp | 22 ++++- interface/src/ui/FramelessDialog.h | 3 + 4 files changed, 144 insertions(+), 12 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 689b45afcf..913ae2c50b 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -4,22 +4,22 @@ Application - + Export Voxels - + Sparse Voxel Octree Files (*.svo) - + Open Script - + JavaScript Files (*.js) @@ -113,22 +113,135 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file + + PreferencesDialog + + + + Cancel + + + + + + Save all changes + + + + + + + + Avatar + + + + + + <html><head/><body><p>Avatar display name <span style=" color:#909090;">(optional)</span></p></body></html> + + + + + + Not showing a name + + + + + + Head + + + + + + Body + + + + + + Advanced Tuning + + + + + + It's not recomended that you play with these settings unless you've looked into exactly what they do. + + + + + + Vertical field of view + + + + + + Lean scale (applies to Faceshift users) + + + + + + Avatar scale <span style=" color:#909090;">(default is 1.0)</span> + + + + + + Pupil dillation + + + + + + Audio Jitter Buffer Samples (0 for automatic) + + + + + + Faceshift eye detection + + + + + + Voxels + + + + + + Maximum voxels + + + + + + Max voxels sent each second + + + QObject diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 38a1bc8aaa..7373bb8833 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -714,7 +714,7 @@ void Menu::loginForCurrentDomain() { void Menu::editPreferences() { if (!_preferencesDialog) { - _preferencesDialog = new PreferencesDialog(Application::getInstance()->getGLWidget()); + _preferencesDialog = new PreferencesDialog(Application::getInstance()->getWindow()); _preferencesDialog->show(); } _preferencesDialog->raise(); diff --git a/interface/src/ui/FramelessDialog.cpp b/interface/src/ui/FramelessDialog.cpp index 2b9dd42ed7..d11fd5ae6b 100644 --- a/interface/src/ui/FramelessDialog.cpp +++ b/interface/src/ui/FramelessDialog.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "Application.h" #include "FramelessDialog.h" @@ -17,20 +18,35 @@ const int RESIZE_HANDLE_WIDTH = 7; FramelessDialog::FramelessDialog(QWidget *parent, Qt::WindowFlags flags) : - QDialog(parent, flags | Qt::FramelessWindowHint), + QDialog(parent, flags | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint), _isResizing(false) { setAttribute(Qt::WA_DeleteOnClose); installEventFilter(this); + + startTimer(20); +} + +void FramelessDialog::timerEvent(QTimerEvent *event) { + move(parentWidget()->pos().x(), parentWidget()->pos().y() + 22); + setFixedHeight(parentWidget()->size().height()); +} + +void FramelessDialog::paintEvent(QPaintEvent* event) { + //move(parentWidget()->pos()); + //resize(size().width(), parentWidget()->size().height()); } void FramelessDialog::showEvent(QShowEvent* event) { QDesktopWidget desktop; // move to upper left - move(desktop.availableGeometry().x(), desktop.availableGeometry().y()); +// move(desktop.availableGeometry().x(), desktop.availableGeometry().y()); + + move(parentWidget()->pos().x(), parentWidget()->pos().y() + 22); // keep full height - resize(size().width(), desktop.availableGeometry().height()); + setFixedHeight(parentWidget()->size().height()); +// resize(size().width(), desktop.availableGeometry().height()); } void FramelessDialog::setStyleSheetFile(const QString& fileName) { diff --git a/interface/src/ui/FramelessDialog.h b/interface/src/ui/FramelessDialog.h index 2bb8d6b85c..3cca9ec4fb 100644 --- a/interface/src/ui/FramelessDialog.h +++ b/interface/src/ui/FramelessDialog.h @@ -14,6 +14,7 @@ #include #include #include +#include class FramelessDialog : public QDialog { Q_OBJECT @@ -28,6 +29,8 @@ protected: virtual void mousePressEvent(QMouseEvent* mouseEvent); virtual void mouseReleaseEvent(QMouseEvent* mouseEvent); virtual void showEvent(QShowEvent* event); + void paintEvent(QPaintEvent* event); + void timerEvent(QTimerEvent *event); private: bool _isResizing; From 8b6db350da404b21a3e4effb6fee6c2126f9eaa6 Mon Sep 17 00:00:00 2001 From: stojce Date: Thu, 27 Mar 2014 21:50:41 +0100 Subject: [PATCH 15/23] Switched to QDockWidget --- interface/interface_en.ts | 76 ++++++++++++++-------------- interface/src/Menu.cpp | 7 +-- interface/src/ui/FramelessDialog.cpp | 58 +++------------------ interface/src/ui/FramelessDialog.h | 12 ++--- interface/ui/preferencesDialog.ui | 5 +- 5 files changed, 55 insertions(+), 103 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 913ae2c50b..6403e5fdd5 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -132,112 +132,112 @@ PreferencesDialog - - + + Cancel - - + + Save all changes - - - - + + + + Avatar - - + + <html><head/><body><p>Avatar display name <span style=" color:#909090;">(optional)</span></p></body></html> - - + + Not showing a name - - + + Head - - + + Body - - + + Advanced Tuning - - + + It's not recomended that you play with these settings unless you've looked into exactly what they do. - - + + Vertical field of view - - + + Lean scale (applies to Faceshift users) - - + + Avatar scale <span style=" color:#909090;">(default is 1.0)</span> - - + + Pupil dillation - - + + Audio Jitter Buffer Samples (0 for automatic) - - + + Faceshift eye detection - - + + Voxels - - + + Maximum voxels - - + + Max voxels sent each second diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 7373bb8833..5c0fd72eee 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -714,10 +714,11 @@ void Menu::loginForCurrentDomain() { void Menu::editPreferences() { if (!_preferencesDialog) { - _preferencesDialog = new PreferencesDialog(Application::getInstance()->getWindow()); - _preferencesDialog->show(); + Application::getInstance()->getWindow()->addDockWidget(Qt::LeftDockWidgetArea, _preferencesDialog = new PreferencesDialog()); + } else { + Application::getInstance()->getWindow()->removeDockWidget(_preferencesDialog); + _preferencesDialog->close(); } - _preferencesDialog->raise(); } void Menu::goToDomain(const QString newDomain) { diff --git a/interface/src/ui/FramelessDialog.cpp b/interface/src/ui/FramelessDialog.cpp index d11fd5ae6b..40388b2f5f 100644 --- a/interface/src/ui/FramelessDialog.cpp +++ b/interface/src/ui/FramelessDialog.cpp @@ -15,38 +15,17 @@ #include "Application.h" #include "FramelessDialog.h" -const int RESIZE_HANDLE_WIDTH = 7; - FramelessDialog::FramelessDialog(QWidget *parent, Qt::WindowFlags flags) : - QDialog(parent, flags | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint), - _isResizing(false) { + QDockWidget(parent, flags) { setAttribute(Qt::WA_DeleteOnClose); - installEventFilter(this); - startTimer(20); -} + // set as floating + setFeatures(QDockWidget::DockWidgetFloatable); -void FramelessDialog::timerEvent(QTimerEvent *event) { - move(parentWidget()->pos().x(), parentWidget()->pos().y() + 22); - setFixedHeight(parentWidget()->size().height()); -} + // remove titlebar + setTitleBarWidget(new QWidget()); -void FramelessDialog::paintEvent(QPaintEvent* event) { - //move(parentWidget()->pos()); - //resize(size().width(), parentWidget()->size().height()); -} - -void FramelessDialog::showEvent(QShowEvent* event) { - QDesktopWidget desktop; - - // move to upper left -// move(desktop.availableGeometry().x(), desktop.availableGeometry().y()); - - move(parentWidget()->pos().x(), parentWidget()->pos().y() + 22); - - // keep full height - setFixedHeight(parentWidget()->size().height()); -// resize(size().width(), desktop.availableGeometry().height()); + setAllowedAreas(Qt::LeftDockWidgetArea); } void FramelessDialog::setStyleSheetFile(const QString& fileName) { @@ -54,29 +33,6 @@ void FramelessDialog::setStyleSheetFile(const QString& fileName) { QFile styleSheet(Application::resourcesPath() + fileName); if (styleSheet.open(QIODevice::ReadOnly) && globalStyleSheet.open(QIODevice::ReadOnly) ) { QDir::setCurrent(Application::resourcesPath()); - QDialog::setStyleSheet(globalStyleSheet.readAll() + styleSheet.readAll()); + setStyleSheet(globalStyleSheet.readAll() + styleSheet.readAll()); } } - -void FramelessDialog::mousePressEvent(QMouseEvent* mouseEvent) { - - if (abs(mouseEvent->pos().x() - size().width()) < RESIZE_HANDLE_WIDTH && mouseEvent->button() == Qt::LeftButton) { - _isResizing = true; - QApplication::setOverrideCursor(Qt::SizeHorCursor); - } -} - -void FramelessDialog::mouseReleaseEvent(QMouseEvent* mouseEvent) { - QApplication::restoreOverrideCursor(); - _isResizing = false; -} - -void FramelessDialog::mouseMoveEvent(QMouseEvent* mouseEvent) { - if (_isResizing) { - resize(mouseEvent->pos().x(), size().height()); - } -} - -FramelessDialog::~FramelessDialog() { - -} diff --git a/interface/src/ui/FramelessDialog.h b/interface/src/ui/FramelessDialog.h index 3cca9ec4fb..5c55f3de25 100644 --- a/interface/src/ui/FramelessDialog.h +++ b/interface/src/ui/FramelessDialog.h @@ -9,29 +9,27 @@ #ifndef __hifi__FramelessDialog__ #define __hifi__FramelessDialog__ -#include +#include #include #include #include #include #include -class FramelessDialog : public QDialog { +class FramelessDialog : public QDockWidget { Q_OBJECT public: FramelessDialog(QWidget* parent = 0, Qt::WindowFlags flags = 0); - virtual ~FramelessDialog(); void setStyleSheetFile(const QString& fileName); protected: + /* virtual void mouseMoveEvent(QMouseEvent* mouseEvent); virtual void mousePressEvent(QMouseEvent* mouseEvent); virtual void mouseReleaseEvent(QMouseEvent* mouseEvent); - virtual void showEvent(QShowEvent* event); - void paintEvent(QPaintEvent* event); - void timerEvent(QTimerEvent *event); - + */ + private: bool _isResizing; diff --git a/interface/ui/preferencesDialog.ui b/interface/ui/preferencesDialog.ui index 14db1b6d5e..f28bcde60c 100644 --- a/interface/ui/preferencesDialog.ui +++ b/interface/ui/preferencesDialog.ui @@ -2,9 +2,6 @@ PreferencesDialog - - Qt::NonModal - 0 @@ -251,7 +248,7 @@ color: #0e7077 280 - 20 + 0 From 252326726980ec2bb3ce601ad86321a4944ced26 Mon Sep 17 00:00:00 2001 From: stojce Date: Thu, 27 Mar 2014 22:02:45 +0100 Subject: [PATCH 16/23] i18n file updates --- interface/interface_en.ts | 121 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 117 insertions(+), 4 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index da8827d89d..48b395339e 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -113,22 +113,135 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file + + PreferencesDialog + + + + Cancel + + + + + + Save all changes + + + + + + + + Avatar + + + + + + <html><head/><body><p>Avatar display name <span style=" color:#909090;">(optional)</span></p></body></html> + + + + + + Not showing a name + + + + + + Head + + + + + + Body + + + + + + Advanced Tuning + + + + + + It's not recomended that you play with these settings unless you've looked into exactly what they do. + + + + + + Vertical field of view + + + + + + Lean scale (applies to Faceshift users) + + + + + + Avatar scale <span style=" color:#909090;">(default is 1.0)</span> + + + + + + Pupil dillation + + + + + + Audio Jitter Buffer Samples (0 for automatic) + + + + + + Faceshift eye detection + + + + + + Voxels + + + + + + Maximum voxels + + + + + + Max voxels sent each second + + + QObject From ba5a092ad7287baf2033caeab9042b01fd6ced24 Mon Sep 17 00:00:00 2001 From: stojce Date: Sun, 6 Apr 2014 15:30:30 +0200 Subject: [PATCH 17/23] Frameless dialog position/size fixes Fixed frameless dialog size and position on main window resize and move --- interface/src/Menu.cpp | 4 +- interface/src/ui/FramelessDialog.cpp | 93 ++++++++++++++++++++++++---- interface/src/ui/FramelessDialog.h | 12 ++-- 3 files changed, 90 insertions(+), 19 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 859b3250be..9615238b36 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -717,9 +717,9 @@ void Menu::loginForCurrentDomain() { void Menu::editPreferences() { if (!_preferencesDialog) { - Application::getInstance()->getWindow()->addDockWidget(Qt::LeftDockWidgetArea, _preferencesDialog = new PreferencesDialog()); + _preferencesDialog = new PreferencesDialog(Application::getInstance()->getWindow()); + _preferencesDialog->show(); } else { - Application::getInstance()->getWindow()->removeDockWidget(_preferencesDialog); _preferencesDialog->close(); } } diff --git a/interface/src/ui/FramelessDialog.cpp b/interface/src/ui/FramelessDialog.cpp index 40388b2f5f..14f7e57f3b 100644 --- a/interface/src/ui/FramelessDialog.cpp +++ b/interface/src/ui/FramelessDialog.cpp @@ -6,26 +6,65 @@ // // -#include -#include -#include -#include -#include - #include "Application.h" #include "FramelessDialog.h" +const int RESIZE_HANDLE_WIDTH = 7; + FramelessDialog::FramelessDialog(QWidget *parent, Qt::WindowFlags flags) : - QDockWidget(parent, flags) { +QDialog(parent, flags | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint) { setAttribute(Qt::WA_DeleteOnClose); - // set as floating - setFeatures(QDockWidget::DockWidgetFloatable); + // handle rezize and move events + parentWidget()->installEventFilter(this); - // remove titlebar - setTitleBarWidget(new QWidget()); + // handle minimize, restore and focus events + Application::getInstance()->installEventFilter(this); +} - setAllowedAreas(Qt::LeftDockWidgetArea); +bool FramelessDialog::eventFilter(QObject* sender, QEvent* event) { + switch (event->type()) { + case QEvent::Move: + + if (sender == parentWidget()) { + // move to upper left corner on app move + move(parentWidget()->geometry().topLeft()); + } + break; + + case QEvent::Resize: + if (sender == parentWidget()) { + // keep full app height on resizing the app + setFixedHeight(parentWidget()->size().height()); + } + break; + + case QEvent::WindowStateChange: + if (parentWidget()->isMinimized()) { + setHidden(true); + } else { + setHidden(false); + } + break; + + case QEvent::ApplicationDeactivate: + // hide on minimize and focus lost + setHidden(true); + break; + + case QEvent::ApplicationActivate: + setHidden(false); + break; + + default: + break; + } + + return false; +} + +FramelessDialog::~FramelessDialog() { + deleteLater(); } void FramelessDialog::setStyleSheetFile(const QString& fileName) { @@ -36,3 +75,33 @@ void FramelessDialog::setStyleSheetFile(const QString& fileName) { setStyleSheet(globalStyleSheet.readAll() + styleSheet.readAll()); } } + +void FramelessDialog::showEvent(QShowEvent* event) { + // move to upper left corner + move(parentWidget()->geometry().topLeft()); + + // keep full app height + setFixedHeight(parentWidget()->size().height()); + + // resize parrent if width is smaller than this dialog + if (parentWidget()->size().width() < size().width()) { + parentWidget()->resize(size().width(), parentWidget()->size().height()); + } +} +void FramelessDialog::mousePressEvent(QMouseEvent* mouseEvent) { + if (abs(mouseEvent->pos().x() - size().width()) < RESIZE_HANDLE_WIDTH && mouseEvent->button() == Qt::LeftButton) { + _isResizing = true; + QApplication::setOverrideCursor(Qt::SizeHorCursor); + } +} + +void FramelessDialog::mouseReleaseEvent(QMouseEvent* mouseEvent) { + QApplication::restoreOverrideCursor(); + _isResizing = false; +} + +void FramelessDialog::mouseMoveEvent(QMouseEvent* mouseEvent) { + if (_isResizing) { + resize(mouseEvent->pos().x(), size().height()); + } +} diff --git a/interface/src/ui/FramelessDialog.h b/interface/src/ui/FramelessDialog.h index 5c55f3de25..f13219a688 100644 --- a/interface/src/ui/FramelessDialog.h +++ b/interface/src/ui/FramelessDialog.h @@ -9,27 +9,29 @@ #ifndef __hifi__FramelessDialog__ #define __hifi__FramelessDialog__ -#include +#include #include #include #include #include #include -class FramelessDialog : public QDockWidget { +class FramelessDialog : public QDialog { Q_OBJECT public: FramelessDialog(QWidget* parent = 0, Qt::WindowFlags flags = 0); + ~FramelessDialog(); void setStyleSheetFile(const QString& fileName); protected: - /* virtual void mouseMoveEvent(QMouseEvent* mouseEvent); virtual void mousePressEvent(QMouseEvent* mouseEvent); virtual void mouseReleaseEvent(QMouseEvent* mouseEvent); - */ - + virtual void showEvent(QShowEvent* event); + + bool eventFilter(QObject* sender, QEvent* event); + private: bool _isResizing; From dd5a19874012c5c420aefa22217fcbb40ef36bfc Mon Sep 17 00:00:00 2001 From: stojce Date: Sun, 6 Apr 2014 16:13:15 +0200 Subject: [PATCH 18/23] Models browser fixes --- interface/src/ui/FramelessDialog.h | 5 ----- interface/src/ui/ModelsBrowser.cpp | 2 +- interface/src/ui/PreferencesDialog.cpp | 17 +++++++++++++++-- interface/src/ui/PreferencesDialog.h | 2 ++ 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/interface/src/ui/FramelessDialog.h b/interface/src/ui/FramelessDialog.h index f13219a688..aa83960b8b 100644 --- a/interface/src/ui/FramelessDialog.h +++ b/interface/src/ui/FramelessDialog.h @@ -10,11 +10,6 @@ #define __hifi__FramelessDialog__ #include -#include -#include -#include -#include -#include class FramelessDialog : public QDialog { Q_OBJECT diff --git a/interface/src/ui/ModelsBrowser.cpp b/interface/src/ui/ModelsBrowser.cpp index 616aba3881..52c10a51d7 100644 --- a/interface/src/ui/ModelsBrowser.cpp +++ b/interface/src/ui/ModelsBrowser.cpp @@ -62,7 +62,7 @@ static const QString propertiesIds[MODEL_METADATA_COUNT] = { }; ModelsBrowser::ModelsBrowser(ModelType modelsType, QWidget* parent) : - QWidget(parent), + QWidget(parent, Qt::WindowStaysOnTopHint), _handler(new ModelHandler(modelsType)) { connect(_handler, SIGNAL(doneDownloading()), SLOT(resizeView())); diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 3aa439558a..96ffe662c7 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -21,6 +21,7 @@ PreferencesDialog::PreferencesDialog(QWidget* parent, Qt::WindowFlags flags) : F setStyleSheetFile("styles/preferences.qss"); loadPreferences(); connect(ui.closeButton, &QPushButton::clicked, this, &QDialog::close); + connect(ui.buttonBrowseHead, &QPushButton::clicked, this, &PreferencesDialog::openHeadModelBrowser); connect(ui.buttonBrowseBody, &QPushButton::clicked, this, &PreferencesDialog::openBodyModelBrowser); } @@ -34,16 +35,28 @@ void PreferencesDialog::accept() { close(); } +void PreferencesDialog::setHeadUrl(QString modelUrl) { + ui.faceURLEdit->setText(modelUrl); + setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); +} + +void PreferencesDialog::setSkeletonUrl(QString modelUrl) { + ui.skeletonURLEdit->setText(modelUrl); + setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); +} + void PreferencesDialog::openHeadModelBrowser() { + setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint); ModelsBrowser modelBrowser(Head); + connect(&modelBrowser, &ModelsBrowser::selected, this, &PreferencesDialog::setHeadUrl); modelBrowser.browse(); - connect(&modelBrowser, &ModelsBrowser::selected, ui.faceURLEdit, &QLineEdit::setText); } void PreferencesDialog::openBodyModelBrowser() { + setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint); ModelsBrowser modelBrowser(Skeleton); + connect(&modelBrowser, &ModelsBrowser::selected, this, &PreferencesDialog::setSkeletonUrl); modelBrowser.browse(); - connect(&modelBrowser, &ModelsBrowser::selected, ui.skeletonURLEdit, &QLineEdit::setText); } void PreferencesDialog::resizeEvent(QResizeEvent *resizeEvent) { diff --git a/interface/src/ui/PreferencesDialog.h b/interface/src/ui/PreferencesDialog.h index f1f37c66cd..c7f8f43616 100644 --- a/interface/src/ui/PreferencesDialog.h +++ b/interface/src/ui/PreferencesDialog.h @@ -37,6 +37,8 @@ private: private slots: void accept(); + void setHeadUrl(QString modelUrl); + void setSkeletonUrl(QString modelUrl); }; From a1c6843bd409555ce44b9f1a36fe02508295bffd Mon Sep 17 00:00:00 2001 From: stojce Date: Wed, 9 Apr 2014 22:14:35 +0200 Subject: [PATCH 19/23] CR Fixes --- interface/src/ui/FramelessDialog.cpp | 15 ++++----------- interface/src/ui/FramelessDialog.h | 13 ++++++++----- interface/src/ui/PreferencesDialog.cpp | 8 ++++++-- interface/src/ui/PreferencesDialog.h | 13 ++++++++----- 4 files changed, 26 insertions(+), 23 deletions(-) diff --git a/interface/src/ui/FramelessDialog.cpp b/interface/src/ui/FramelessDialog.cpp index 14f7e57f3b..18e3bca89a 100644 --- a/interface/src/ui/FramelessDialog.cpp +++ b/interface/src/ui/FramelessDialog.cpp @@ -1,9 +1,12 @@ // // FramelessDialog.cpp -// hifi +// interface/src/ui // // Created by Stojce Slavkovski on 2/20/14. +// Copyright 2014 High Fidelity, Inc. // +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "Application.h" @@ -25,20 +28,17 @@ QDialog(parent, flags | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint) { bool FramelessDialog::eventFilter(QObject* sender, QEvent* event) { switch (event->type()) { case QEvent::Move: - if (sender == parentWidget()) { // move to upper left corner on app move move(parentWidget()->geometry().topLeft()); } break; - case QEvent::Resize: if (sender == parentWidget()) { // keep full app height on resizing the app setFixedHeight(parentWidget()->size().height()); } break; - case QEvent::WindowStateChange: if (parentWidget()->isMinimized()) { setHidden(true); @@ -46,16 +46,13 @@ bool FramelessDialog::eventFilter(QObject* sender, QEvent* event) { setHidden(false); } break; - case QEvent::ApplicationDeactivate: // hide on minimize and focus lost setHidden(true); break; - case QEvent::ApplicationActivate: setHidden(false); break; - default: break; } @@ -63,10 +60,6 @@ bool FramelessDialog::eventFilter(QObject* sender, QEvent* event) { return false; } -FramelessDialog::~FramelessDialog() { - deleteLater(); -} - void FramelessDialog::setStyleSheetFile(const QString& fileName) { QFile globalStyleSheet(Application::resourcesPath() + "styles/global.qss"); QFile styleSheet(Application::resourcesPath() + fileName); diff --git a/interface/src/ui/FramelessDialog.h b/interface/src/ui/FramelessDialog.h index aa83960b8b..db9f6dfd6c 100644 --- a/interface/src/ui/FramelessDialog.h +++ b/interface/src/ui/FramelessDialog.h @@ -1,13 +1,17 @@ // // FramelessDialog.h -// hifi +// interface/src/ui // // Created by Stojce Slavkovski on 2/20/14. +// Copyright 2014 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__FramelessDialog__ -#define __hifi__FramelessDialog__ + +#ifndef hifi_FramelessDialog_h +#define hifi_FramelessDialog_h #include @@ -16,7 +20,6 @@ class FramelessDialog : public QDialog { public: FramelessDialog(QWidget* parent = 0, Qt::WindowFlags flags = 0); - ~FramelessDialog(); void setStyleSheetFile(const QString& fileName); protected: @@ -32,4 +35,4 @@ private: }; -#endif /* defined(__hifi__FramelessDialog__) */ +#endif // hifi_FramelessDialog_h diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 96ffe662c7..c6a994b4d5 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -1,11 +1,15 @@ // // PreferencesDialog.cpp -// hifi +// interface/src/ui // -// Created by Stojce Slavkovski on 2/22/14. +// Created by Stojce Slavkovski on 2/20/14. +// Copyright 2014 High Fidelity, Inc. // +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // + #include "Application.h" #include "Menu.h" #include "PreferencesDialog.h" diff --git a/interface/src/ui/PreferencesDialog.h b/interface/src/ui/PreferencesDialog.h index c7f8f43616..25a1e1b6cf 100644 --- a/interface/src/ui/PreferencesDialog.h +++ b/interface/src/ui/PreferencesDialog.h @@ -1,13 +1,16 @@ // // PreferencesDialog.h -// hifi +// interface/src/ui // -// Created by Stojce Slavkovski on 2/22/14. +// Created by Stojce Slavkovski on 2/20/14. +// Copyright 2014 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__PreferencesDialog__ -#define __hifi__PreferencesDialog__ +#ifndef hifi_PreferencesDialog_h +#define hifi_PreferencesDialog_h #include "FramelessDialog.h" #include "ui_preferencesDialog.h" @@ -42,4 +45,4 @@ private slots: }; -#endif /* defined(__hifi__PreferencesDialog__) */ +#endif // hifi_PreferencesDialog_h From 9ab61faacbabbe448ad45735042fc4423b0f3781 Mon Sep 17 00:00:00 2001 From: stojce Date: Wed, 9 Apr 2014 22:32:15 +0200 Subject: [PATCH 20/23] additional CR fixes --- interface/src/ui/PreferencesDialog.cpp | 4 ---- interface/src/ui/PreferencesDialog.h | 1 - 2 files changed, 5 deletions(-) diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index c6a994b4d5..d1c9b4f6ca 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -30,10 +30,6 @@ PreferencesDialog::PreferencesDialog(QWidget* parent, Qt::WindowFlags flags) : F connect(ui.buttonBrowseBody, &QPushButton::clicked, this, &PreferencesDialog::openBodyModelBrowser); } -PreferencesDialog::~PreferencesDialog() { - deleteLater(); -} - void PreferencesDialog::accept() { savePreferences(); close(); diff --git a/interface/src/ui/PreferencesDialog.h b/interface/src/ui/PreferencesDialog.h index 25a1e1b6cf..c9514e584a 100644 --- a/interface/src/ui/PreferencesDialog.h +++ b/interface/src/ui/PreferencesDialog.h @@ -22,7 +22,6 @@ class PreferencesDialog : public FramelessDialog { public: PreferencesDialog(QWidget* parent = 0, Qt::WindowFlags flags = 0); - ~PreferencesDialog(); protected: void resizeEvent(QResizeEvent* resizeEvent); From 5d812c8cb221253e160f1664609e05dfb9db129f Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 9 Apr 2014 23:44:40 +0200 Subject: [PATCH 21/23] Fixed loading local stored scripts on Windows machines --- libraries/script-engine/src/ScriptEngine.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 7d3dd650ae..c5c1fdb2bf 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -92,8 +92,9 @@ ScriptEngine::ScriptEngine(const QUrl& scriptURL, QUrl url(scriptURL); - // if the scheme is empty, maybe they typed in a file, let's try - if (url.scheme().isEmpty()) { + // if the scheme length is one or lower, maybe they typed in a file, let's try + const DWORD WINDOWS_DRIVE_LETTER_SIZE = 1; + if (url.scheme().size() <= WINDOWS_DRIVE_LETTER_SIZE) { url = QUrl::fromLocalFile(scriptURLString); } From 825acbbd9cfe529745af12a45cf5a6e8efa1532d Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 10 Apr 2014 10:47:21 +0200 Subject: [PATCH 22/23] Update ScriptEngine.cpp DWORD is not defined in UNIX based systems. int should be fine --- libraries/script-engine/src/ScriptEngine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index c5c1fdb2bf..c857e1193a 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -93,7 +93,7 @@ ScriptEngine::ScriptEngine(const QUrl& scriptURL, QUrl url(scriptURL); // if the scheme length is one or lower, maybe they typed in a file, let's try - const DWORD WINDOWS_DRIVE_LETTER_SIZE = 1; + const int WINDOWS_DRIVE_LETTER_SIZE = 1; if (url.scheme().size() <= WINDOWS_DRIVE_LETTER_SIZE) { url = QUrl::fromLocalFile(scriptURLString); } From 3af3b29588d0f9060425e5af4e1d00e5f7b2842b Mon Sep 17 00:00:00 2001 From: Stojce Slavkovski Date: Fri, 11 Apr 2014 00:54:54 +0200 Subject: [PATCH 23/23] removed dependency on QT resource --- interface/resources/styles/preferences.qss | 10 ++++++ interface/ui/preferencesDialog.ui | 42 +++++++++++++--------- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/interface/resources/styles/preferences.qss b/interface/resources/styles/preferences.qss index ee587b70da..643fd13a77 100644 --- a/interface/resources/styles/preferences.qss +++ b/interface/resources/styles/preferences.qss @@ -9,3 +9,13 @@ QLabel#advancedTuningLabel { background-repeat: no-repeat; background-position: left center; } + +QPushButton#buttonBrowseHead, +QPushButton#buttonBrowseBody { + background-image: url(styles/search.svg); + background-repeat: no-repeat; + background-position: center center; + background-color: #fff; + border-radius: 0; + padding: 0; +} diff --git a/interface/ui/preferencesDialog.ui b/interface/ui/preferencesDialog.ui index f28bcde60c..a151a499c6 100644 --- a/interface/ui/preferencesDialog.ui +++ b/interface/ui/preferencesDialog.ui @@ -351,18 +351,23 @@ color: #0e7077 30 + + + 30 + 30 + + - background-color: #fff; -border-radius: 0; -padding: 0; + - - - :/styles/search.svg - + + + 30 + 30 + @@ -449,18 +454,23 @@ padding: 0; 30 + + + 30 + 30 + + - background-color: #fff; -border-radius: 0; -padding: 0; + - - - :/styles/search.svg - + + + 30 + 30 + @@ -1327,9 +1337,7 @@ padding: 0; 1 - - - + cancelButton