Skip to content

Commit

Permalink
Allow setting clear color
Browse files Browse the repository at this point in the history
See: #48
  • Loading branch information
bpe2 committed May 25, 2023
1 parent 0df7209 commit 08e9459
Show file tree
Hide file tree
Showing 8 changed files with 714 additions and 454 deletions.
36 changes: 36 additions & 0 deletions src/settings/SettingsManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,27 @@ SettingsManager::WindowTheme SettingsManager::WindowThemeFromInt(int value) {
return WindowTheme::Dark;
}

SettingsManager::BackgroundColor SettingsManager::BackgroundColorFromInt(int value) {
using BackgroundColor = SettingsManager::BackgroundColor;

switch (value) {
case static_cast<int>(BackgroundColor::Black):
return BackgroundColor::Black;
case static_cast<int>(BackgroundColor::White):
return BackgroundColor::White;
case static_cast<int>(BackgroundColor::Custom):
return BackgroundColor::Custom;
default:
QMessageBox::critical(nullptr, "Invalid value provided for 'BackgroundColor'!",
"An unrecognised value for 'BackgroundColor': " + QString::number(value) + " was provided");
QApplication::exit(1);
break;
}

// Should never happen, but just in case
return BackgroundColor::Black;
}

const SettingsManager::SettingValue &SettingsManager::getQtKey(SettingsManager::Key key) const {
auto iterator = SettingsManager::qtKeyMap.find(key);
if (iterator == SettingsManager::qtKeyMap.end()) {
Expand Down Expand Up @@ -171,4 +192,19 @@ void SettingsManager::setTheme(SettingsManager::WindowTheme theme) {
}
}

QColor SettingsManager::getRenderBackgroundColor() const {
switch (get<BackgroundColor>(Key::RenderBackgroundColor).value()) {
case BackgroundColor::Black:
return QColorConstants::Black;
case BackgroundColor::White:
return QColorConstants::White;
case BackgroundColor::Custom:
return get<QColor>(Key::RenderBackgroundColorCustom).value();
}

// Just in case
std::cerr << "Error getting render background color\n";
return QColorConstants::Black;
}

} // namespace netsimulyzer
90 changes: 87 additions & 3 deletions src/settings/SettingsManager.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "parser/model.h"
#include <QColor>
#include <QSettings>
#include <QString>
#include <Qt>
Expand Down Expand Up @@ -52,6 +53,8 @@ class SettingsManager {
RenderMotionTrailLength,
RenderLabels,
RenderSkybox,
RenderBackgroundColor,
RenderBackgroundColorCustom,
ChartDropdownSortOrder,
WindowTheme
};
Expand All @@ -62,6 +65,7 @@ class SettingsManager {
enum class MotionTrailRenderMode : int { Always, EnabledOnly, Never };
enum class TimeUnit : int { Milliseconds, Microseconds, Nanoseconds };
enum class WindowTheme : int { Dark, Light, Native };
enum class BackgroundColor : int { Black, White, Custom };

/**
* Convert an int to a `BuildingRenderMode` enum value.
Expand Down Expand Up @@ -135,6 +139,18 @@ class SettingsManager {
*/
static WindowTheme WindowThemeFromInt(int value);

/**
* Convert an int to a `BackgroundColor` enum value.
* Necessary since Qt will only allow sending registered types with signals/slots.
*
* @param value
* An integer that corresponds to an enum value
*
* @return
* The enum value corresponding to `value`
*/
static BackgroundColor BackgroundColorFromInt(int value);

/**
* Defines when retrieving a value fails,
* should it's default value be provided in the return
Expand Down Expand Up @@ -184,6 +200,8 @@ class SettingsManager {
{Key::RenderGrid, {"renderer/showGrid", true}},
{Key::RenderGridStep, {"renderer/gridStepSize", 1}},
{Key::RenderSkybox, {"renderer/enableSkybox", true}},
{Key::RenderBackgroundColor, {"renderer/backgroundColor", "black"}},
{Key::RenderBackgroundColorCustom, {"renderer/backgroundColorCustom", QColorConstants::Black}},
{Key::RenderLabels, {"renderer/showLabels", "enabledOnly"}},
{Key::RenderMotionTrails, {"renderer/showMotionTrails", "enabledOnly"}},
{Key::RenderMotionTrailLength, {"renderer/motionTrailLength", 100}},
Expand Down Expand Up @@ -349,6 +367,9 @@ class SettingsManager {
* The theme to load into the application.
*/
void setTheme(WindowTheme theme);

[[nodiscard]]
QColor getRenderBackgroundColor() const;
};

// Specialize so we don't have to convert to/from QString all the time
Expand Down Expand Up @@ -449,6 +470,18 @@ template <>
return SettingsManager::WindowTheme::Dark;
}

template <>
[[nodiscard]] inline SettingsManager::BackgroundColor SettingsManager::getDefault(SettingsManager::Key key) const {
const auto &settingKey = getQtKey(key);
if (!settingKey.defaultValue.isValid()) {
std::cerr << "Requested default for key: " << settingKey.key.toStdString() << " which has no default\n";
std::abort();
}

// TODO: Use the map value
return SettingsManager::BackgroundColor::Black;
}

template <>
[[nodiscard]] inline std::optional<SettingsManager::BuildingRenderMode> SettingsManager::get(Key key,
RetrieveMode mode) const {
Expand Down Expand Up @@ -479,7 +512,8 @@ template <>
}

template <>
[[nodiscard]] inline std::optional<SettingsManager::LabelRenderMode> SettingsManager::get(Key key, RetrieveMode mode) const {
[[nodiscard]]
inline std::optional<SettingsManager::LabelRenderMode> SettingsManager::get(Key key, RetrieveMode mode) const {
const auto &settingKey = getQtKey(key);
const auto qtSetting = qtSettings.value(settingKey.key);

Expand Down Expand Up @@ -602,8 +636,8 @@ SettingsManager::get(Key key, RetrieveMode mode) const {
}

template <>
[[nodiscard]] inline std::optional<SettingsManager::WindowTheme>
SettingsManager::get(Key key, RetrieveMode mode) const {
[[nodiscard]]
inline std::optional<SettingsManager::WindowTheme> SettingsManager::get(Key key, RetrieveMode mode) const {
const auto &settingKey = getQtKey(key);
const auto qtSetting = qtSettings.value(settingKey.key);

Expand Down Expand Up @@ -632,6 +666,37 @@ SettingsManager::get(Key key, RetrieveMode mode) const {
return {};
}

template <>
[[nodiscard]] inline std::optional<SettingsManager::BackgroundColor> SettingsManager::get(Key key,
RetrieveMode mode) const {
const auto &settingKey = getQtKey(key);
const auto qtSetting = qtSettings.value(settingKey.key);

QString stringMode;

if (qtSetting.isValid() && !qtSetting.isNull() && qtSetting.template canConvert<QString>())
stringMode = qtSetting.toString();
else if (mode == RetrieveMode::AllowDefault)
stringMode = settingKey.defaultValue.toString();
else
return {};

if (stringMode == "black")
return {BackgroundColor::Black};
else if (stringMode == "white")
return {BackgroundColor::White};
else if (stringMode == "custom")
return {BackgroundColor::Custom};
else
std::cerr << "Unrecognised 'BackgroundColor' provided '" << stringMode.toStdString() << "' value ignored!\n";

// Final catch if the provided string value is invalid
if (mode == RetrieveMode::AllowDefault)
return getDefault<BackgroundColor>(Key::RenderBackgroundColor);

return {};
}

template <>
inline void SettingsManager::set(SettingsManager::Key key, const SettingsManager::BuildingRenderMode &value) {
const auto &settingKey = getQtKey(key);
Expand Down Expand Up @@ -746,4 +811,23 @@ inline void SettingsManager::set(SettingsManager::Key key, const SettingsManager
}
}

template <>
inline void SettingsManager::set(SettingsManager::Key key, const SettingsManager::BackgroundColor &value) {
const auto &settingKey = getQtKey(key);

switch (value) {
case BackgroundColor::Black:
qtSettings.setValue(settingKey.key, "black");
break;
case BackgroundColor::White:
qtSettings.setValue(settingKey.key, "white");
break;
case BackgroundColor::Custom:
qtSettings.setValue(settingKey.key, "custom");
break;
default:
std::cerr << "Unrecognised 'BackgroundColor': " << static_cast<int>(value) << " value not saved!\n";
}
}

} // namespace netsimulyzer
2 changes: 2 additions & 0 deletions src/window/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ MainWindow::MainWindow() : QMainWindow() {
scene.setSkyboxRenderState(enable);
});

QObject::connect(&settingsDialog, &SettingsDialog::backgroundColorChanged, &scene, &SceneWidget::setClearColor);

QObject::connect(&settingsDialog, &SettingsDialog::buildingRenderModeChanged, [this](int mode) {
scene.setBuildingRenderMode(SettingsManager::BuildingRenderModeFromInt(mode));
});
Expand Down
10 changes: 9 additions & 1 deletion src/window/scene/SceneWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ void SceneWidget::paintGL() {
camera.move(static_cast<float>(frameTimer.elapsed()));
renderer.use(camera);

glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClearColor(clearColorGl[0], clearColorGl[1], clearColorGl[2], 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (renderSkybox)
renderer.render(*skyBox);
Expand Down Expand Up @@ -723,6 +723,14 @@ void SceneWidget::setSkyboxRenderState(bool enable) {
renderSkybox = enable;
}

void SceneWidget::setClearColor(const QColor &value) {
clearColor = value;

clearColorGl[0] = static_cast<float>(clearColor.redF());
clearColorGl[1] = static_cast<float>(clearColor.greenF());
clearColorGl[2] = static_cast<float>(clearColor.blueF());
}

void SceneWidget::setBuildingRenderMode(SettingsManager::BuildingRenderMode mode) {
buildingRenderMode = mode;
}
Expand Down
14 changes: 14 additions & 0 deletions src/window/scene/SceneWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
#include <QOpenGLFunctions_3_3_Core>
#include <QOpenGLWidget>
#include <QTimer>
#include <array>
#include <deque>
#include <glm/glm.hpp>
#include <iostream>
Expand Down Expand Up @@ -99,6 +100,11 @@ class SceneWidget : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core {
bool renderBuildingOutlines = settings.get<bool>(SettingsManager::Key::RenderBuildingOutlines).value();
SettingsManager::MotionTrailRenderMode renderMotionTrails =
settings.get<SettingsManager::MotionTrailRenderMode>(SettingsManager::Key::RenderMotionTrails).value();
QColor clearColor = settings.getRenderBackgroundColor();
// Store the converted form of the clear color,
// that OpenGL can accept
std::array<float, 3> clearColorGl{static_cast<float>(clearColor.redF()), static_cast<float>(clearColor.greenF()),
static_cast<float>(clearColor.blueF())};

std::unique_ptr<PickingFramebuffer> pickingFbo;

Expand Down Expand Up @@ -233,6 +239,14 @@ class SceneWidget : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core {
*/
void setSkyboxRenderState(bool enable);

/**
*
* @param value
* The value to use when clearing the scene.
* Only visible when the skybox is off
*/
void setClearColor(const QColor &value);

/**
* Sets the building render behavior
* @param mode
Expand Down
59 changes: 59 additions & 0 deletions src/window/settings/SettingsDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "src/window/util/file-operations.h"
#include "ui_SettingsDialog.h"
#include <QApplication>
#include <QColorDialog>
#include <QComboBox>
#include <QFileDialog>
#include <QFileInfo>
#include <QMessageBox>
Expand Down Expand Up @@ -37,6 +39,12 @@ void SettingsDialog::loadSettings() {

ui.checkBoxSkybox->setChecked(settings.get<bool>(Key::RenderSkybox).value());

const auto backgroundColor = *settings.get<SettingsManager::BackgroundColor>(Key::RenderBackgroundColor);
ui.comboBackgroundColor->setCurrentIndex(static_cast<int>(backgroundColor));

customBackgroundColor = settings.get<QColor>(SettingsManager::Key::RenderBackgroundColorCustom).value();
ui.comboBackgroundColor->setItemData(2, customBackgroundColor, Qt::DecorationRole);

const auto buildingMode = settings.get<SettingsManager::BuildingRenderMode>(Key::RenderBuildingMode).value();
ui.comboBuildingRender->setCurrentIndex(ui.comboBuildingRender->findData(static_cast<int>(buildingMode)));

Expand Down Expand Up @@ -92,9 +100,27 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent) {
ui.comboSamples->addItem("8", 8);
ui.comboSamples->addItem("16", 16);

ui.comboBackgroundColor->addItem("Black", static_cast<int>(SettingsManager::BackgroundColor::Black));
ui.comboBackgroundColor->setItemData(0, QColorConstants::Black, Qt::DecorationRole);

ui.comboBackgroundColor->addItem("White", static_cast<int>(SettingsManager::BackgroundColor::White));
ui.comboBackgroundColor->setItemData(1, QColorConstants::White, Qt::DecorationRole);

ui.comboBackgroundColor->addItem("Custom", static_cast<int>(SettingsManager::BackgroundColor::Custom));
ui.comboBackgroundColor->setItemData(2, customBackgroundColor, Qt::DecorationRole);

ui.comboBuildingRender->addItem("Transparent", static_cast<int>(SettingsManager::BuildingRenderMode::Transparent));
ui.comboBuildingRender->addItem("Opaque", static_cast<int>(SettingsManager::BuildingRenderMode::Opaque));

QObject::connect(ui.buttonSetCustomBackgroundColor, &QPushButton::clicked, [this]() {
const auto userColor = QColorDialog::getColor(customBackgroundColor, this, "Select a Background Color");
if (!userColor.isValid())
return;

customBackgroundColor = userColor;
ui.comboBackgroundColor->setItemData(2, customBackgroundColor, Qt::DecorationRole);
});

using SortOrder = SettingsManager::ChartDropdownSortOrder;
ui.comboSortOrder->addItem("Alphabetical", static_cast<int>(SortOrder::Alphabetical));
ui.comboSortOrder->addItem("Type", static_cast<int>(SortOrder::Type));
Expand Down Expand Up @@ -156,6 +182,7 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent) {
QObject::connect(ui.buttonResetSortOrder, &QPushButton::clicked, this, &SettingsDialog::defaultChartSortOrder);

QObject::connect(ui.buttonResetSkybox, &QPushButton::clicked, this, &SettingsDialog::defaultEnableSkybox);
QObject::connect(ui.buttonResetBackgroundColor, &QPushButton::clicked, this, &SettingsDialog::defaultBackgroundColor);
QObject::connect(ui.buttonResetSamples, &QPushButton::clicked, this, &SettingsDialog::defaultSamples);
QObject::connect(ui.buttonResetBuildingRender, &QPushButton::clicked, this, &SettingsDialog::defaultBuildingEffect);
QObject::connect(ui.buttonResetBuildingOutlines, &QPushButton::clicked, this,
Expand Down Expand Up @@ -217,6 +244,7 @@ void SettingsDialog::dialogueButtonClicked(QAbstractButton *button) {
ui.buttonResetSortOrder->click();

ui.buttonResetSkybox->click();
ui.buttonResetBackgroundColor->click();
ui.buttonResetSamples->click();
ui.buttonResetBuildingRender->click();
ui.buttonResetBuildingOutlines->click();
Expand Down Expand Up @@ -325,6 +353,31 @@ void SettingsDialog::dialogueButtonClicked(QAbstractButton *button) {
emit renderSkyboxChanged(enableSkybox);
}

using BackgroundColor = SettingsManager::BackgroundColor;
const auto backgroundColorMode =
SettingsManager::BackgroundColorFromInt(ui.comboBackgroundColor->currentData().toInt());
// Handle basic modes
if (backgroundColorMode != settings.get<BackgroundColor>(Key::RenderBackgroundColor)) {
settings.set(Key::RenderBackgroundColor, backgroundColorMode);
switch (backgroundColorMode) {
case BackgroundColor::Black:
emit backgroundColorChanged(QColorConstants::Black);
case BackgroundColor::White:
emit backgroundColorChanged(QColorConstants::White);
break;
case BackgroundColor::Custom:
// Ignored here
break;
}
}

// Handle custom color
if (backgroundColorMode == BackgroundColor::Custom &&
customBackgroundColor != settings.get<QColor>(Key::RenderBackgroundColorCustom).value()) {
settings.set(Key::RenderBackgroundColorCustom, customBackgroundColor);
emit backgroundColorChanged(customBackgroundColor);
}

auto buildingRenderMode = SettingsManager::BuildingRenderModeFromInt(ui.comboBuildingRender->currentData().toInt());
if (buildingRenderMode != settings.get<SettingsManager::BuildingRenderMode>(Key::RenderBuildingMode).value()) {
settings.set(Key::RenderBuildingMode, buildingRenderMode);
Expand Down Expand Up @@ -456,6 +509,12 @@ void SettingsDialog::defaultChartSortOrder() {
ui.comboSortOrder->setCurrentIndex(ui.comboSortOrder->findData(defaultValue));
}

void SettingsDialog::defaultBackgroundColor() {
const auto defaultValue = static_cast<int>(
settings.getDefault<SettingsManager::BackgroundColor>(SettingsManager::Key::RenderBackgroundColor));
ui.comboBackgroundColor->setCurrentIndex(ui.comboBackgroundColor->findData(defaultValue));
}

void SettingsDialog::defaultSamples() {
ui.comboSamples->setCurrentIndex(
ui.comboSamples->findData(settings.getDefault<int>(SettingsManager::Key::NumberSamples)));
Expand Down
Loading

0 comments on commit 08e9459

Please sign in to comment.