Merge branch 'feature/sgct-ui'

This commit is contained in:
Alexander Bock
2022-04-25 17:49:17 +02:00
9 changed files with 115 additions and 82 deletions
+1 -1
View File
@@ -98,7 +98,7 @@ elseif (${QT_VERSION_MAJOR} EQUAL 6)
qt6_wrap_cpp(
MOC_FILES
${HEADER_SOURCE}
${HEADER_FILES}
)
qt6_add_resources(RESOURCE_FILES resources/resources.qrc)
elseif (NOT DEFINED QT_VERSION_MAJOR)
@@ -30,6 +30,7 @@
#include <sgct/math.h>
class QCheckBox;
class QLabel;
class SettingsWidget final : public QWidget {
Q_OBJECT
@@ -54,9 +55,17 @@ public:
*/
bool vsync() const;
/**
* Gets whether the UI should be restricted to the first window
*
* \return true if the UI should only be on the first window
*/
bool showUiOnFirstWindow() const;
private:
sgct::quat _orientationValue = { 0.f, 0.f, 0.f, 0.f };
QCheckBox* _checkBoxVsync = nullptr;
QCheckBox* _showUiOnFirstWindow = nullptr;
};
#endif // __OPENSPACE_UI_LAUNCHER___SETTINGSWIDGET___H__
@@ -67,7 +67,7 @@ public:
private:
void createWidgets(const std::vector<QRect>& monitorSizes);
void saveConfigToSgctFormat();
sgct::config::Cluster generateConfiguration() const;
void save();
void apply();
@@ -61,29 +61,15 @@ public:
*/
void showWindowLabel(bool show);
/**
* Function called in order to disable/uncheck the WebGUI checkbox option
*/
void uncheckWebGuiOption();
/**
* Resets all controls for this window to default settings
*/
void resetToDefaults();
/**
* Returns bool for if the window control checkbox for WebGUI is enabled
*
* \return bool for if window has WebGUI enabled
*/
bool isGuiWindow() const;
sgct::config::Window generateWindowInformation() const;
signals:
void windowChanged(int monitorIndex, int windowIndex, const QRectF& newDimensions);
void webGuiChanged(int windowIndex);
private:
enum class ProjectionIndices {
@@ -131,7 +117,6 @@ private:
QSpinBox* _offsetX = nullptr;
QSpinBox* _offsetY = nullptr;
QCheckBox* _windowDecoration = nullptr;
QCheckBox* _webGui = nullptr;
QComboBox* _projectionType = nullptr;
struct {
@@ -64,17 +64,6 @@ void DisplayWindowUnion::createWidgets(int nMaxWindows,
ctrl, &WindowControl::windowChanged,
this, &DisplayWindowUnion::windowChanged
);
connect(
ctrl, &WindowControl::webGuiChanged,
[this](unsigned int winIndex) {
for (size_t w = 0; w < _windowControl.size(); ++w) {
if (w != winIndex) {
_windowControl[w]->uncheckWebGuiOption();
}
}
}
);
}
QBoxLayout* layout = new QVBoxLayout(this);
@@ -36,6 +36,17 @@ SettingsWidget::SettingsWidget(sgct::quat orientation, QWidget* parent)
QBoxLayout* layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
_showUiOnFirstWindow = new QCheckBox("Show only user interface on the first window");
_showUiOnFirstWindow->setChecked(false);
_showUiOnFirstWindow->setToolTip(
"If enabled the first window is marked as a GUI window resulting in the user "
"interface only being shown on that window and the rendering is suppressed on "
"this first window. The remaining windows will render normally but they will not "
"show the user interface"
);
layout->addWidget(_showUiOnFirstWindow);
_checkBoxVsync = new QCheckBox("Enable VSync");
_checkBoxVsync->setToolTip(
"If enabled the framerate will be locked to the refresh rate of the monitor"
@@ -65,3 +76,7 @@ sgct::quat SettingsWidget::orientation() const {
bool SettingsWidget::vsync() const {
return _checkBoxVsync->isChecked();
}
bool SettingsWidget::showUiOnFirstWindow() const {
return _showUiOnFirstWindow->isChecked();
}
@@ -32,6 +32,7 @@
#include <QApplication>
#include <QFileDialog>
#include <QFrame>
#include <QMessageBox>
#include <QPushButton>
#include <QScreen>
#include <QVBoxLayout>
@@ -40,6 +41,30 @@
namespace {
constexpr QRect MonitorWidgetSize = { 0, 0, 500, 500 };
constexpr int MaxNumberWindows = 4;
// Returns true if the windows are not ordered correctly. 'Correct' in this means that
// there is a smaller window defined before a bigger one
// This check is only necessary until
// https://github.com/OpenSpace/OpenSpace/issues/507
// is fixed
bool hasWindowIssues(const sgct::config::Cluster& cluster) {
sgct::ivec2 size = {
std::numeric_limits<int>::max(),
std::numeric_limits<int>::max()
};
for (const sgct::config::Window& window : cluster.nodes.front().windows) {
if (window.size.x <= size.x && window.size.y <= size.y) {
size = window.size;
}
else {
// The window size is bigger than a previous one, so we gotta bail
return true;
}
}
// We got to the end without running into any problems, so we are golden
return false;
}
} // namespace
SgctEdit::SgctEdit(QWidget* parent, std::string userConfigPath)
@@ -148,6 +173,23 @@ std::filesystem::path SgctEdit::saveFilename() const {
}
void SgctEdit::save() {
sgct::config::Cluster cluster = generateConfiguration();
if (hasWindowIssues(cluster)) {
int ret = QMessageBox::warning(
this,
"Window Sizes Incompatible",
"Window sizes for multiple windows have to be strictly ordered, meaning that "
"the size of window 1 has to be bigger in each dimension than window 2, "
"window 2 has to be bigger than window 3 (if it exists), and window 3 has to "
"be bigger than window 4.\nOtherwise, rendering errors might occur.\n\nAre "
"you sure you want to continue?",
QMessageBox::StandardButtons(QMessageBox::Yes || QMessageBox::No)
);
if (ret == QMessageBox::No) {
return;
}
}
QString fileName = QFileDialog::getSaveFileName(
this,
"Save Window Configuration File",
@@ -161,12 +203,29 @@ void SgctEdit::save() {
);
if (!fileName.isEmpty()) {
_saveTarget = fileName.toStdString();
saveConfigToSgctFormat();
_cluster = std::move(cluster);
accept();
}
}
void SgctEdit::apply() {
sgct::config::Cluster cluster = generateConfiguration();
if (hasWindowIssues(cluster)) {
int ret = QMessageBox::warning(
this,
"Window Sizes Incompatible",
"Window sizes for multiple windows have to be strictly ordered, meaning that "
"the size of window 1 has to be bigger in each dimension than window 2, "
"window 2 has to be bigger than window 3 (if it exists), and window 3 has to "
"be bigger than window 4.\nOtherwise, rendering errors might occur.\n\nAre "
"you sure you want to continue?",
QMessageBox::Yes | QMessageBox::No
);
if (ret == QMessageBox::No) {
return;
}
}
std::string userCfgTempDir = _userConfigPath;
if (userCfgTempDir.back() != '/') {
userCfgTempDir += '/';
@@ -176,11 +235,11 @@ void SgctEdit::apply() {
std::filesystem::create_directories(absPath(userCfgTempDir));
}
_saveTarget = userCfgTempDir + "/apply-without-saving.json";
saveConfigToSgctFormat();
_cluster = std::move(cluster);
accept();
}
void SgctEdit::saveConfigToSgctFormat() {
sgct::config::Cluster SgctEdit::generateConfiguration() const {
sgct::config::Cluster cluster;
sgct::config::Scene scene;
@@ -208,15 +267,16 @@ void SgctEdit::saveConfigToSgctFormat() {
for (WindowControl* wCtrl : _displayWidget->windowControls()) {
sgct::config::Window window = wCtrl->generateWindowInformation();
if (wCtrl->isGuiWindow()) {
window.viewports.back().isTracked = false;
window.tags.push_back("GUI");
window.draw2D = true;
window.draw3D = false;
}
window.id = windowIndex++;
node.windows.push_back(window);
node.windows.push_back(std::move(window));
}
if (_settingsWidget->showUiOnFirstWindow()) {
sgct::config::Window& window = node.windows.front();
window.viewports.back().isTracked = false;
window.tags.push_back("GUI");
window.draw2D = true;
window.draw3D = false;
}
cluster.nodes.push_back(node);
@@ -226,7 +286,7 @@ void SgctEdit::saveConfigToSgctFormat() {
user.position = { 0.f, 0.f, 4.f };
cluster.users = { user };
_cluster = std::move(cluster);
return cluster;
}
sgct::config::Cluster SgctEdit::cluster() const {
@@ -127,28 +127,28 @@ void WindowControl::createWidgets(const QColor& windowColor) {
_windowName->setToolTip(tip);
layout->addWidget(_windowName, 1, 1, 1, 7);
}
if (_monitorResolutions.size() > 1) {
QString tip = "The monitor where this window is located.";
QString tip = "The monitor where this window is located.";
_monitor = new QComboBox;
_monitor->addItems(monitorNames(_monitorResolutions));
_monitor->setCurrentIndex(_monitorIndexDefault);
_monitor->setToolTip(tip);
connect(
_monitor, qOverload<int>(&QComboBox::currentIndexChanged),
[this]() {
emit windowChanged(
_monitor->currentIndex(),
_windowIndex,
_windowDimensions
);
}
);
if (_monitorResolutions.size() > 1) {
QLabel* labelLocation = new QLabel("Monitor");
labelLocation->setToolTip(tip);
layout->addWidget(labelLocation, 2, 0);
_monitor = new QComboBox;
_monitor->addItems(monitorNames(_monitorResolutions));
_monitor->setCurrentIndex(_monitorIndexDefault);
_monitor->setToolTip(tip);
layout->addWidget(_monitor, 2, 1, 1, 7);
connect(
_monitor, qOverload<int>(&QComboBox::currentIndexChanged),
[this]() {
emit windowChanged(
_monitor->currentIndex(),
_windowIndex,
_windowDimensions
);
}
);
}
{
QLabel* size = new QLabel("Size");
@@ -277,22 +277,6 @@ void WindowControl::createWidgets(const QColor& windowColor) {
"controls for minimizing/maximizing, resizing, or closing the window"
);
layout->addWidget(_windowDecoration, 5, 0, 1, 8);
_webGui = new QCheckBox("Show user interface only in this window");
_webGui->setToolTip(
"If enabled, the window will be dedicated solely to displaying the GUI "
"controls, and will not\nrender any other content. All other window(s) will "
"render normally but will not have GUI controls"
);
layout->addWidget(_webGui, 6, 0, 1, 8);
connect(
_webGui, &QCheckBox::stateChanged,
[this]() {
if (_webGui->isChecked()) {
emit webGuiChanged(_windowIndex);
}
}
);
}
{
QFrame* projectionGroup = new QFrame;
@@ -626,7 +610,6 @@ void WindowControl::resetToDefaults() {
_monitor->setCurrentIndex(_monitorIndexDefault);
}
_windowDecoration->setChecked(true);
_webGui->setChecked(false);
_fisheye.spoutOutput->setChecked(false);
_equirectangular.spoutOutput->setChecked(false);
_projectionType->setCurrentIndex(static_cast<int>(ProjectionIndices::Planar));
@@ -837,11 +820,3 @@ void WindowControl::updatePlanarLockedFov() {
_planar.fovV->setValue(std::min(DefaultFovV / ratio, 180.f));
}
}
void WindowControl::uncheckWebGuiOption() {
_webGui->setChecked(false);
}
bool WindowControl::isGuiWindow() const {
return _webGui->isChecked();
}