Merge branch 'master' into issue/2645

# Conflicts:
#	src/documentation/documentationengine.cpp
#	src/properties/propertyowner.cpp
#	src/scripting/scriptengine.cpp
#	src/util/factorymanager.cpp
This commit is contained in:
Ylva Selling
2024-03-25 11:14:09 +01:00
626 changed files with 12773 additions and 9245 deletions

85
.clang_tidy Normal file
View File

@@ -0,0 +1,85 @@
Checks: >-
-*,
bugprone-*,
-bugprone-argument-comment,
-bugprone-easily-swappable-parameters,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-narrowing-conversions,
-bugprone-suspicious-include,
-bugprone-switch-missing-default-case,
-bugprone-unchecked-optional-access,
clang-analyzer-*,
-clang-analyzer-apiModeling*,
-clang-analyzer-osx*,
-clang-analyzer-security.FloatLoopCounter,
-clang-analyzer-webkit*,
cppcoreguidelines-*,
-cppcoreguidelines-avoid-do-while,
-cppcoreguidelines-avoid-magic-numbers,
-cppcoreguidelines-avoid-non-const-global-variables,
-cppcoreguidelines-narrowing-conversions,
-cppcoreguidelines-no-malloc,
-cppcoreguidelines-owning-memory,
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
-cppcoreguidelines-pro-bounds-constant-array-index,
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
-cppcoreguidelines-pro-type-member-init,
-cppcoreguidelines-pro-type-reinterpret-cast,
-cppcoreguidelines-pro-type-static-cast-downcast,
-cppcoreguidelines-pro-type-union-access,
-cppcoreguidelines-pro-type-vararg,
google-*,
-google-objc-*,
-google-build-using-namespace,
-google-default-arguments,
-google-readability-casting,
-google-readability-function-size,
-google-readability-namespace-comments,
-google-explicit-constructor,
-google-runtime-int,
llvm-*,
-llvm-else-after-return,
-llvm-include-order,
-llvm-qualified-auto,
misc-*,
-misc-include-cleaner,
-misc-no-recursion,
modernize-*,
-modernize-raw-string-literal,
-modernize-return-braced-init-list,
-modernize-use-trailing-return-type,
-modernize-use-auto,
performance-*,
-performance-no-int-to-ptr,
readability-*,
-readability-avoid-unconditional-preprocessor-if,
-readability-else-after-return,
-readability-function-cognitive-complexity,
-readability-identifier-length,
-readability-implicit-bool-conversion,
-readability-magic-numbers,
-readability-named-parameter,
-readability-uppercase-literal-suffix,
-readability-use-anyofallof
CheckOptions:
- key: bugprone-assert-side-effect.AssertMacros
value: ghoul_assert,ghoul_precondition
- key: cppcoreguidelines-rvalue-reference-param-not-moved.AllowPartialMove
value: True
- key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
value: True
- key: modernize-loop-convert.UseCxx20ReverseRanges
value: False
- key: performance-move-const-arg.CheckTriviallyCopyableMove
value: False
- key: performance-unnecessary-value-param.AllowedTypes
value: glm::vec2;glm::vec3;glm::vec4;glm::ivec2;glm::ivec3;glm::ivec4;glm::dvec2;glm::dvec3;glm::dvec4;glm::uvec2;glm::uvec3;glm::uvec4;glm::mat2;glm::mat3;glm::mat4;glm::mat[2-4]x[2-4];glm::dmat2;glm::dmat3;glm::dmat4;glm::dmat[2-4]x[2-4];glm::quat;glm::dquat
- key: readability-inconsistent-declaration-parameter-name.Strict
value: True
- key: readability-qualified-auto.AddConstToQualified
value: False
- key: readability-simplify-boolean-expr.ChainedConditionalReturn
value: True
- key: readability-simplify-boolean-expr.ChainedConditionalAssignment
value: True

3
.gitmodules vendored
View File

@@ -41,3 +41,6 @@
[submodule "support/doxygen/css"]
path = support/doxygen/css
url = https://github.com/jothepro/doxygen-awesome-css.git
[submodule "modules/audio/ext/soloud"]
path = modules/audio/ext/soloud
url = https://github.com/jarikomppa/soloud

5
Jenkinsfile vendored
View File

@@ -51,16 +51,15 @@ parallel tools: {
stage('tools/scm') {
deleteDir();
gitHelper.checkoutGit(url, branch, false);
helper.createDirectory('build');
}
stage('tools/cppcheck') {
sh(
script: 'cppcheck --enable=all --xml --xml-version=2 -i ext --suppressions-list=support/cppcheck/suppressions.txt include modules src tests 2> build/cppcheck.xml',
script: 'cppcheck --enable=all --xml --xml-version=2 -i ext --suppressions-list=support/cppcheck/suppressions.txt include modules src tests 2> cppcheck.xml',
label: 'CPPCheck'
)
recordIssues(
id: 'tools-cppcheck',
tool: cppCheck(pattern: 'build/cppcheck.xml')
tool: cppCheck(pattern: 'cppcheck.xml')
)
}
cleanWs()

View File

@@ -104,7 +104,7 @@ void Handler::onVREvent(const VRDataIndex& eventData) {
else {
LERRORC(
"onVREvent()",
fmt::format("Received an event named {} of unknown type", eventData.getName())
std::format("Received an event named {} of unknown type", eventData.getName())
);
}
@@ -244,7 +244,7 @@ void Handler::onVREvent(const VRDataIndex& eventData) {
global::openSpaceEngine.decode(std::move(synchronizationBuffer));
}
else {
LERRORC("onVREvent()", fmt::format("Received an event of unknown type {}", type));
LERRORC("onVREvent()", std::format("Received an event of unknown type {}", type));
}
}
@@ -372,7 +372,7 @@ int main(int argc, char** argv) {
LFATALC("main", "Could not find configuration: " + configurationFilePath);
exit(EXIT_FAILURE);
}
LINFO(fmt::format("Configuration Path: '{}'", configurationFilePath));
LINFO(std::format("Configuration Path: '{}'", configurationFilePath));
// Loading configuration from disk
LDEBUG("Loading configuration from disk");

View File

@@ -33,7 +33,7 @@ public:
* Constructor for filesystemAccess class.
*
* \param fileExtension The file extensiopn filter used to find files. Only files with
* this extension will be recognized (e.g. '.xml')
* this extension will be recognized (e.g. '.json')
* \param hideFileExtensions If `true` then file extensions will be removed from the
* listed files in the output
* \param useCheckboxes If `true` then the text output format will contain a '0' as
@@ -48,14 +48,14 @@ public:
*
* \param dir The directory from which to start the search from
*/
std::string useQtFileSystemModelToTraverseDir(std::string dir,
bool usersAssets = false);
std::string useQtFileSystemModelToTraverseDir(const std::string& dir,
bool userAssets = false);
private:
void parseChildDirElements(QFileInfo item, std::string space, int level,
std::vector<std::string>& dirNames, std::vector<std::string>& output,
void parseChildDirElements(const QFileInfo& fileInfo, const std::string& space,
int level, std::vector<std::string>& dirNames, std::vector<std::string>& output,
bool userAssets);
void parseChildFile(std::string res, bool& hasDirHeaderBeenAdded,
void parseChildFile(std::string filename, bool& hasDirHeaderBeenAdded,
std::vector<std::string>& dirNames, std::vector<std::string>& output);
QFileSystemModel _filesystemModel;

View File

@@ -96,12 +96,11 @@ private:
void editRefusalDialog(const std::string& title, const std::string& msg,
const std::string& detailedText);
void populateProfilesList(std::string preset);
void populateWindowConfigsList(std::string preset);
void populateProfilesList(const std::string& preset);
void populateWindowConfigsList(const std::string& preset);
void handleReturnFromWindowEditor(const sgct::config::Cluster& cluster,
std::filesystem::path savePath, const std::string& saveWindowCfgPath);
void onNewWindowConfigSelection(int newIndex);
bool versionCheck(sgct::config::GeneratorVersion& v) const;
const std::string _assetPath;
const std::string _userAssetPath;

View File

@@ -56,18 +56,18 @@ private:
void actionRemove();
void actionSelected();
void actionSaved();
void clearActionFields();
void clearActionFields() const;
void actionRejected();
void chooseScripts();
void appendScriptsToTextfield(std::vector<std::string> scripts);
void appendScriptsToTextfield(const std::vector<std::string>& scripts) const;
openspace::Profile::Keybinding* selectedKeybinding();
void keybindingAdd();
void keybindingRemove();
void keybindingSelected();
void keybindingActionSelected(int);
void keybindingActionSelected(int) const;
void keybindingSaved();
void clearKeybindingFields();
void clearKeybindingFields() const;
void keybindingRejected();
std::vector<openspace::Profile::Action>* _actions = nullptr;

View File

@@ -52,7 +52,7 @@ private:
*
* \param scripts The scripts to be appended
*/
void appendScriptsToTextfield(std::vector<std::string> scripts);
void appendScriptsToTextfield(const std::vector<std::string>& scripts);
std::vector<std::string>* _scripts = nullptr;
std::vector<std::string> _scriptsData;

View File

@@ -205,7 +205,7 @@ public:
* \param index Location of the item to set
* \param name The asset name to set
*/
void setName(QModelIndex& index, QString name);
void setName(QModelIndex& index, const QString& name);
/**
* Set state of checked/selected of an item.

View File

@@ -56,7 +56,7 @@ private:
QWidget* createNavStateWidget();
QWidget* createGeoWidget();
void addErrorMsg(QString errorDescription);
void addErrorMsg(const QString& errorDescription);
bool areRequiredFormsFilledAndValid();
std::optional<openspace::Profile::CameraType>* _camera = nullptr;

View File

@@ -80,7 +80,7 @@ private:
*/
void transitionEditMode(int index, bool state);
void setLabelForKey(int index, bool editMode, std::string color);
void setLabelForKey(int index, bool editMode, std::string_view color);
bool isLineEmpty(int index);
std::vector<double>* _deltaTimes = nullptr;

View File

@@ -71,7 +71,7 @@ private:
void openSaveAs();
void typeOnChange(int index);
void downloadProgress(int value, int max);
void downloadProgress(int value, int total);
void importTimeRange();
void approved();

View File

@@ -65,7 +65,6 @@ private:
void transitionToEditMode();
void parseSelections();
QString createOneLineSummary(openspace::Profile::Module m);
void transitionFromEditMode();
void editBoxDisabled(bool disabled);
bool isLineEmpty(int index) const;

View File

@@ -69,7 +69,6 @@ private:
void selectLineFromScriptLog();
QString createOneLineSummary(openspace::Profile::Property p);
void transitionFromEditMode();
void editBoxDisabled(bool disabled);
bool areRequiredFormsFilled();

View File

@@ -109,7 +109,7 @@ signals:
void nWindowsChanged(int newCount);
private:
void createWidgets(int nMaxWindows, std::vector<QRect> monitorResolutions,
void createWidgets(int nMaxWindows, const std::vector<QRect>& monitorResolutions,
std::array<QColor, 4> windowColors, bool resetToDefault);
void showWindows();

View File

@@ -66,9 +66,9 @@ public:
/**
* Called when the number of windows that should be displayed changes.
*
* \param newCount The new number of windows included
* \param nWindows The new number of windows included
*/
void nWindowsDisplayedChanged(int newCount);
void nWindowsDisplayedChanged(int nWindows);
protected:
void paintEvent(QPaintEvent* event) override;

View File

@@ -66,7 +66,7 @@ public:
* \param configBasePath The path to the folder where default config files reside
* \param parent Pointer to parent Qt widget
*/
SgctEdit(sgct::config::Cluster& cluster, const std::string& configName,
SgctEdit(sgct::config::Cluster& cluster, std::string configName,
std::string& configBasePath, QWidget* parent);
/**

View File

@@ -199,7 +199,7 @@ private:
void onSizeYChanged(int newValue);
void onOffsetXChanged(int newValue);
void onOffsetYChanged(int newValue);
void onProjectionChanged(int newSelection);
void onProjectionChanged(int newSelection) const;
void onFullscreenClicked();
void onAspectRatioLockClicked();
void onFovLockClicked();

View File

@@ -31,11 +31,12 @@ FileSystemAccess::FileSystemAccess(std::string fileExtension,
, _useCheckboxes(useCheckboxes)
{}
std::string FileSystemAccess::useQtFileSystemModelToTraverseDir(std::string dir,
bool userAssets) {
std::string FileSystemAccess::useQtFileSystemModelToTraverseDir(const std::string& dir,
bool userAssets)
{
_filesystemModel.setRootPath(QString::fromStdString(dir));
QModelIndex index = _filesystemModel.index(_filesystemModel.rootPath());
QFileInfo fileInfo = _filesystemModel.fileInfo(index);
const QModelIndex index = _filesystemModel.index(_filesystemModel.rootPath());
const QFileInfo fileInfo = _filesystemModel.fileInfo(index);
std::vector<std::string> dirsNested;
std::vector<std::string> out;
parseChildDirElements(fileInfo, "", 0, dirsNested, out, userAssets);
@@ -46,32 +47,38 @@ std::string FileSystemAccess::useQtFileSystemModelToTraverseDir(std::string dir,
return combined;
}
void FileSystemAccess::parseChildDirElements(QFileInfo fileInfo, std::string space,
int level,
void FileSystemAccess::parseChildDirElements(const QFileInfo& fileInfo,
const std::string& space, int level,
std::vector<std::string>& dirNames,
std::vector<std::string>& output,
bool userAssets)
{
QDir dir(fileInfo.filePath());
const QDir dir = QDir(fileInfo.filePath());
bool hasDirHeaderBeenAdded = false;
QFileInfoList fileList = dir.entryInfoList(_fileFilterOptions);
for (int i = 0; i < fileList.size(); i++) {
QFileInfo fi = fileList[i];
const QFileInfoList fileList = dir.entryInfoList(_fileFilterOptions);
for (const QFileInfo& fi : fileList) {
std::string res = space + fi.fileName().toStdString();
if (level == 0 && userAssets) {
res = "${USER_ASSETS}/" + res;
res = std::format("${{USER_ASSETS}}/{}", res);
}
if (fi.isDir()) {
dirNames.push_back(res);
parseChildDirElements(fi, (space + " "), level + 1, dirNames, output, userAssets);
parseChildDirElements(
fi,
(space + " "),
level + 1,
dirNames,
output,
userAssets
);
}
else {
parseChildFile(res, hasDirHeaderBeenAdded, dirNames, output);
}
}
bool isThisDirAnEmptyDeadEnd = !hasDirHeaderBeenAdded;
if (isThisDirAnEmptyDeadEnd && (dirNames.size() != 0)) {
const bool isThisDirAnEmptyDeadEnd = !hasDirHeaderBeenAdded;
if (isThisDirAnEmptyDeadEnd && !dirNames.empty()) {
dirNames.pop_back();
}
}
@@ -80,12 +87,12 @@ void FileSystemAccess::parseChildFile(std::string filename, bool& hasDirHeaderBe
std::vector<std::string>& dirNames,
std::vector<std::string>& output)
{
std::string cbox = (_useCheckboxes) ? "0" : "";
const std::string cbox = _useCheckboxes ? "0" : "";
if (filename.length() <= _fileExtension.length()) {
return;
}
else {
std::string extension = filename.substr(filename.length()
const std::string extension = filename.substr(filename.length()
- _fileExtension.length());
if (extension != _fileExtension) {
return;

View File

@@ -94,7 +94,7 @@ namespace {
SettingsIconSize,
SettingsIconSize
);
} // geometry
} // namespace geometry
std::optional<Profile> loadProfileFromFile(QWidget* parent, std::string filename) {
// Verify that the file actually exists
@@ -102,7 +102,7 @@ namespace {
QMessageBox::critical(
parent,
"Exception",
QString::fromStdString(fmt::format(
QString::fromStdString(std::format(
"Could not open profile file '{}'", filename
))
);
@@ -117,8 +117,8 @@ namespace {
QMessageBox::critical(
parent,
"Exception",
QString::fromStdString(fmt::format(
"ParsingError exception in {}: {}, {}",
QString::fromStdString(std::format(
"ParsingError exception in '{}': {}, {}",
filename, e.component, e.message
))
);
@@ -128,8 +128,8 @@ namespace {
QMessageBox::critical(
parent,
"Exception",
QString::fromStdString(fmt::format(
"RuntimeError exception in {}, component {}: {}",
QString::fromStdString(std::format(
"RuntimeError exception in '{}', component {}: {}",
filename, e.component, e.message
))
);
@@ -153,8 +153,8 @@ namespace {
QMessageBox::critical(
parent,
"Exception",
QString::fromStdString(fmt::format(
"Error writing data to file: '{}' as file is marked hidden",
QString::fromStdString(std::format(
"Error writing data to file '{}' as file is marked hidden",
path
))
);
@@ -165,8 +165,8 @@ namespace {
QMessageBox::critical(
parent,
"Exception",
QString::fromStdString(fmt::format(
"Error writing data to file: {} ({})", path, e.what()
QString::fromStdString(std::format(
"Error writing data to file '{}': {}", path, e.what()
))
);
}
@@ -188,12 +188,19 @@ namespace {
QMessageBox::critical(
parent,
"Exception",
QString::fromStdString(fmt::format(
"Error writing data to file: {} ({})", path, e.what()
QString::fromStdString(std::format(
"Error writing data to file '{}': {}", path, e.what()
))
);
}
}
bool versionCheck(sgct::config::GeneratorVersion& v) {
return
v.versionCheck(versionMin) ||
v == versionLegacy18 ||
v == versionLegacy19;
}
} // namespace
using namespace openspace;
@@ -211,14 +218,14 @@ LauncherWindow::LauncherWindow(bool profileEnabled,
, _userProfilePath(
absPath(globalConfig.pathTokens.at("USER_PROFILES")).string() + '/'
)
, _sgctConfigName(sgctConfigName)
, _sgctConfigName(std::move(sgctConfigName))
{
Q_INIT_RESOURCE(resources);
qInstallMessageHandler(
[](QtMsgType type, const QMessageLogContext&, const QString& msg) {
if (type == QtCriticalMsg || type == QtFatalMsg || type == QtSystemMsg) {
std::cerr << msg.toStdString() << std::endl;
std::cerr << msg.toStdString() << '\n';
}
}
);
@@ -230,7 +237,7 @@ LauncherWindow::LauncherWindow(bool profileEnabled,
{
QFile file(":/qss/launcher.qss");
file.open(QFile::ReadOnly);
QString styleSheet = QLatin1String(file.readAll());
const QString styleSheet = QLatin1String(file.readAll());
setStyleSheet(styleSheet);
}
@@ -244,7 +251,7 @@ LauncherWindow::LauncherWindow(bool profileEnabled,
// Trigger currentIndexChanged so the preview file read is performed
_windowConfigBox->currentIndexChanged(_windowConfigBox->currentIndex());
std::filesystem::path p = absPath(
const std::filesystem::path p = absPath(
globalConfig.pathTokens.at("SYNC") + "/http/launcher_images"
);
if (std::filesystem::exists(p)) {
@@ -324,8 +331,8 @@ QWidget* LauncherWindow::createCentralWidget() {
editProfileButton, &QPushButton::released,
[this]() {
const std::string selection = _profileBox->currentText().toStdString();
int selectedIndex = _profileBox->currentIndex();
bool isUserProfile = selectedIndex < _userAssetCount;
const int selectedIndex = _profileBox->currentIndex();
const bool isUserProfile = selectedIndex < _userAssetCount;
openProfileEditor(selection, isUserProfile);
}
);
@@ -349,9 +356,9 @@ QWidget* LauncherWindow::createCentralWidget() {
_editWindowButton,
&QPushButton::released,
[this]() {
std::filesystem::path pathSelected = absPath(selectedWindowConfig());
bool isUserConfig = isUserConfigSelected();
std::string fileSelected = pathSelected.generic_string();
const std::filesystem::path pathSelected = absPath(selectedWindowConfig());
const bool isUserConfig = isUserConfigSelected();
const std::string fileSelected = pathSelected.generic_string();
if (std::filesystem::is_regular_file(pathSelected)) {
openWindowEditor(fileSelected, isUserConfig);
}
@@ -446,7 +453,7 @@ void LauncherWindow::setBackgroundImage(const std::string& syncPath) {
std::shuffle(files.begin(), files.end(), g);
// We know there has to be at least one folder, so it's fine to just pick the first
while (!files.empty()) {
std::string p = files.front();
const std::string& p = files.front();
if (std::filesystem::path(p).extension() == ".png") {
// If the top path starts with the png extension, we have found our candidate
break;
@@ -460,12 +467,12 @@ void LauncherWindow::setBackgroundImage(const std::string& syncPath) {
// There better be at least one file left, but just in in case
if (!files.empty()) {
std::string image = files.front();
const std::string& image = files.front();
_backgroundImage->setPixmap(QPixmap(QString::fromStdString(image)));
}
}
void LauncherWindow::populateProfilesList(std::string preset) {
void LauncherWindow::populateProfilesList(const std::string& preset) {
namespace fs = std::filesystem;
_profileBox->clear();
@@ -474,7 +481,7 @@ void LauncherWindow::populateProfilesList(std::string preset) {
if (!std::filesystem::exists(_profilePath)) {
LINFOC(
"LauncherWindow",
fmt::format("Could not find profile folder '{}'", _profilePath)
std::format("Could not find profile folder '{}'", _profilePath)
);
return;
}
@@ -497,7 +504,7 @@ void LauncherWindow::populateProfilesList(std::string preset) {
}
std::sort(profiles.begin(), profiles.end());
for (const fs::directory_entry& profile : profiles) {
std::filesystem::path path = profile.path();
const std::filesystem::path& path = profile.path();
_profileBox->addItem(
QString::fromStdString(path.stem().string()),
QString::fromStdString(path.string())
@@ -505,12 +512,14 @@ void LauncherWindow::populateProfilesList(std::string preset) {
// Add toooltip
std::optional<Profile> p = loadProfileFromFile(this, path.string());
int idx = _profileBox->count() - 1;
const int idx = _profileBox->count() - 1;
if (p.has_value() && (*p).meta.has_value()) {
const std::optional<std::string>& d = (*p).meta.value().description;
const std::optional<std::string>& d = p->meta.value().description;
if (d.has_value()) {
// Tooltip has to be 'rich text' to linebreak properly
QString tooltip = QString::fromStdString(fmt::format("<p>{}</p>", *d));
const QString tooltip = QString::fromStdString(std::format(
"<p>{}</p>", *d
));
_profileBox->setItemData(idx, tooltip, Qt::ToolTipRole);
}
}
@@ -533,7 +542,7 @@ void LauncherWindow::populateProfilesList(std::string preset) {
// Add sorted items to list
for (const fs::directory_entry& profile : profiles) {
std::filesystem::path path = profile.path();
const std::filesystem::path& path = profile.path();
_profileBox->addItem(
QString::fromStdString(path.stem().string()),
QString::fromStdString(path.string())
@@ -541,12 +550,14 @@ void LauncherWindow::populateProfilesList(std::string preset) {
// Add toooltip
std::optional<Profile> p = loadProfileFromFile(this, path.string());
int idx = _profileBox->count() - 1;
const int idx = _profileBox->count() - 1;
if (p.has_value() && (*p).meta.has_value()) {
const std::optional<std::string>& d = (*p).meta.value().description;
const std::optional<std::string>& d = p->meta.value().description;
if (d.has_value()) {
// Tooltip has to be 'rich text' to linebreak properly
QString tooltip = QString::fromStdString(fmt::format("<p>{}</p>", *d));
const QString tooltip = QString::fromStdString(std::format(
"<p>{}</p>", *d
));
_profileBox->setItemData(idx, tooltip, Qt::ToolTipRole);
}
}
@@ -573,9 +584,8 @@ void LauncherWindow::populateProfilesList(std::string preset) {
// Returns 'true' if the file was a configuration file, 'false' otherwise
bool handleConfigurationFile(QComboBox& box, const std::filesystem::directory_entry& p) {
const bool isXml = p.path().extension() == ".xml";
const bool isJson = p.path().extension() == ".json";
if (!isXml && !isJson) {
if (!isJson) {
return false;
}
box.addItem(QString::fromStdString(p.path().filename().string()));
@@ -584,29 +594,24 @@ bool handleConfigurationFile(QComboBox& box, const std::filesystem::directory_en
if (isJson) {
std::string tooltipDescription;
try {
sgct::config::Meta meta = sgct::readMeta(p.path().string());
const sgct::config::Meta meta = sgct::readMeta(p.path().string());
tooltipDescription = meta.description;
}
catch (const sgct::Error&) {
tooltipDescription = "(no description available)";
}
if (!tooltipDescription.empty()) {
QString toolTip = QString::fromStdString(
fmt::format("<p>{}</p>", tooltipDescription)
const QString toolTip = QString::fromStdString(
std::format("<p>{}</p>", tooltipDescription)
);
box.setItemData(box.count() - 1, toolTip, Qt::ToolTipRole);
}
}
// For now, mark the XML configuration files to show that they are deprecated
if (isXml) {
box.setItemData(box.count() - 1, QBrush(Qt::darkYellow), Qt::ForegroundRole);
}
return true;
}
void LauncherWindow::populateWindowConfigsList(std::string preset) {
void LauncherWindow::populateWindowConfigsList(const std::string& preset) {
namespace fs = std::filesystem;
// Disconnect the signal for new window config selection during population process
@@ -630,8 +635,6 @@ void LauncherWindow::populateWindowConfigsList(std::string preset) {
_userConfigStartingIdx++;
_preDefinedConfigStartingIdx++;
bool hasXmlConfig = false;
// Sort files
std::vector<fs::directory_entry> files;
for (const fs::directory_entry& p : fs::directory_iterator(_userConfigPath)) {
@@ -639,15 +642,14 @@ void LauncherWindow::populateWindowConfigsList(std::string preset) {
}
std::sort(files.begin(), files.end());
// Add all the files with the .xml or .json extension to the dropdown
// Add all the files with the .json extension to the dropdown
for (const fs::directory_entry& p : files) {
bool isConfigFile = handleConfigurationFile(*_windowConfigBox, p);
const bool isConfigFile = handleConfigurationFile(*_windowConfigBox, p);
if (isConfigFile) {
_userConfigCount++;
_userConfigStartingIdx++;
_preDefinedConfigStartingIdx++;
}
hasXmlConfig |= p.path().extension() == ".xml";
}
_windowConfigBox->addItem(QString::fromStdString("--- OpenSpace Configurations ---"));
model = qobject_cast<const QStandardItemModel*>(_windowConfigBox->model());
@@ -661,36 +663,24 @@ void LauncherWindow::populateWindowConfigsList(std::string preset) {
files.push_back(p);
}
std::sort(files.begin(), files.end());
// Add all the files with the .xml or .json extension to the dropdown
// Add all the files with the .json extension to the dropdown
for (const fs::directory_entry& p : files) {
handleConfigurationFile(*_windowConfigBox, p);
hasXmlConfig |= p.path().extension() == ".xml";
}
}
else {
LINFOC(
"LauncherWindow",
fmt::format("Could not find config folder '{}'", _configPath)
std::format("Could not find config folder '{}'", _configPath)
);
}
if (hasXmlConfig) {
// At least one XML configuration file is present, so we should show the tooltip
// informing the user that files will be deprecated
_windowConfigBox->setToolTip(
"Support for XML-based configuration files will be removed in the next "
"version of OpenSpace. Please convert the files to the new JSON format or "
"run the Node tool at "
"https://github.com/sgct/sgct/tree/master/support/config-converter"
);
}
// Always add the .cfg sgct default as first item
// Always add the .cfg SGCT default as first item
_windowConfigBox->insertItem(
_windowConfigBoxIndexSgctCfgDefault,
QString::fromStdString(_sgctConfigName)
);
QString defaultTip =
const QString defaultTip =
"<p>The basic default configuration specified in the .cfg file</p>";
_windowConfigBox->setItemData(
_windowConfigBoxIndexSgctCfgDefault,
@@ -700,7 +690,7 @@ void LauncherWindow::populateWindowConfigsList(std::string preset) {
// Try to find the requested configuration file and set it as the current one. As we
// have support for function-generated configuration files that will not be in the
// list we need to add a preset that doesn't exist a file for
const int idx = _windowConfigBox->findText(QString::fromStdString(std::move(preset)));
const int idx = _windowConfigBox->findText(QString::fromStdString(preset));
if (idx != -1) {
_windowConfigBox->setCurrentIndex(idx);
}
@@ -728,8 +718,8 @@ void LauncherWindow::populateWindowConfigsList(std::string preset) {
}
void LauncherWindow::onNewWindowConfigSelection(int newIndex) {
std::filesystem::path pathSelected = absPath(selectedWindowConfig());
std::string fileSelected = pathSelected.string();
const std::filesystem::path pathSelected = absPath(selectedWindowConfig());
const std::string fileSelected = pathSelected.string();
if (newIndex == _windowConfigBoxIndexSgctCfgDefault) {
_editWindowButton->setEnabled(false);
_editWindowButton->setToolTip(
@@ -739,9 +729,10 @@ void LauncherWindow::onNewWindowConfigSelection(int newIndex) {
else if (newIndex >= _preDefinedConfigStartingIdx) {
_editWindowButton->setEnabled(false);
_editWindowButton->setToolTip(
QString::fromStdString(fmt::format(
QString::fromStdString(std::format(
"Cannot edit '{}'\nsince it is one of the configuration "
"files provided in the OpenSpace installation", fileSelected))
"files provided in the OpenSpace installation", fileSelected
))
);
}
else {
@@ -750,9 +741,10 @@ void LauncherWindow::onNewWindowConfigSelection(int newIndex) {
sgct::readConfigGenerator(fileSelected);
if (!versionCheck(previewGenVersion)) {
_editWindowButton->setEnabled(false);
_editWindowButton->setToolTip(QString::fromStdString(fmt::format(
_editWindowButton->setToolTip(QString::fromStdString(std::format(
"This file does not meet the minimum required version of {}.",
versionMin.versionString())));
versionMin.versionString()
)));
return;
}
}
@@ -765,10 +757,6 @@ void LauncherWindow::onNewWindowConfigSelection(int newIndex) {
}
}
bool LauncherWindow::versionCheck(sgct::config::GeneratorVersion& v) const {
return (v.versionCheck(versionMin) || v == versionLegacy18 || v == versionLegacy19);
}
void LauncherWindow::openProfileEditor(const std::string& profile, bool isUserProfile) {
std::optional<Profile> p;
std::string saveProfilePath = isUserProfile ? _userProfilePath : _profilePath;
@@ -779,13 +767,13 @@ void LauncherWindow::openProfileEditor(const std::string& profile, bool isUserPr
else {
// Otherwise, we want to load that profile
std::string fullProfilePath = saveProfilePath + profile + ".profile";
p = loadProfileFromFile(this, fullProfilePath);
p = loadProfileFromFile(this, std::move(fullProfilePath));
if (!p.has_value()) {
return;
}
}
ProfileEdit editor(
ProfileEdit editor = ProfileEdit(
*p,
profile,
_assetPath,
@@ -799,7 +787,8 @@ void LauncherWindow::openProfileEditor(const std::string& profile, bool isUserPr
if (editor.specifiedFilename() != profile) {
saveProfilePath = _userProfilePath;
}
std::string path = saveProfilePath + editor.specifiedFilename() + ".profile";
const std::string path =
saveProfilePath + editor.specifiedFilename() + ".profile";
saveProfile(this, path, *p);
populateProfilesList(editor.specifiedFilename());
}
@@ -862,12 +851,10 @@ void LauncherWindow::openWindowEditor(const std::string& winCfg, bool isUserWinC
}
catch (const std::runtime_error& e) {
//Re-throw an SGCT error exception with the runtime exception message
throw std::runtime_error(
fmt::format(
"Importing of this configuration file failed because of a "
"problem detected in the readConfig function:\n\n{}", e.what()
)
);
throw std::runtime_error(std::format(
"Importing of this configuration file failed because of a "
"problem detected in the readConfig function:\n\n{}", e.what()
));
}
SgctEdit editor(
preview,
@@ -887,8 +874,8 @@ void LauncherWindow::openWindowEditor(const std::string& winCfg, bool isUserWinC
else {
editRefusalDialog(
"File Format Version Error",
fmt::format(
"File '{}' does not meet the minimum required version of {}.",
std::format(
"File '{}' does not meet the minimum required version of {}",
winCfg, versionMin.versionString()
),
""
@@ -898,7 +885,7 @@ void LauncherWindow::openWindowEditor(const std::string& winCfg, bool isUserWinC
catch (const std::runtime_error& e) {
editRefusalDialog(
"Format Validation Error",
fmt::format("Parsing error found in file '{}'", winCfg),
std::format("Parsing error found in file '{}'", winCfg),
e.what()
);
}
@@ -912,8 +899,11 @@ void LauncherWindow::handleReturnFromWindowEditor(const sgct::config::Cluster& c
savePath.replace_extension(".json");
saveWindowConfig(this, savePath, cluster);
// Truncate path to convert this back to path relative to _userConfigPath
std::string p = std::filesystem::proximate(savePath, saveWindowCfgPath).string();
populateWindowConfigsList(p);
const std::filesystem::path p = std::filesystem::proximate(
savePath,
saveWindowCfgPath
);
populateWindowConfigsList(p.string());
}
bool LauncherWindow::wasLaunchSelected() const {
@@ -926,7 +916,7 @@ std::string LauncherWindow::selectedProfile() const {
}
std::string LauncherWindow::selectedWindowConfig() const {
int idx = _windowConfigBox->currentIndex();
const int idx = _windowConfigBox->currentIndex();
if (idx == 0) {
return _sgctConfigName;
}
@@ -939,6 +929,6 @@ std::string LauncherWindow::selectedWindowConfig() const {
}
bool LauncherWindow::isUserConfigSelected() const {
int selectedIndex = _windowConfigBox->currentIndex();
const int selectedIndex = _windowConfigBox->currentIndex();
return (selectedIndex <= _userConfigCount);
}

View File

@@ -56,8 +56,8 @@ namespace {
void updateListItem(QListWidgetItem* item, const Profile::Keybinding& kb) {
ghoul_assert(item, "Item must exist at this point");
std::string name = fmt::format("{}\t{}", ghoul::to_string(kb.key), kb.action);
item->setText(QString::fromStdString(name));
const std::string n = std::format("{}\t{}", ghoul::to_string(kb.key), kb.action);
item->setText(QString::fromStdString(n));
}
} // namespace
@@ -140,9 +140,8 @@ void ActionDialog::createActionWidgets(QGridLayout* layout) {
this, &ActionDialog::actionSelected
);
for (size_t i = 0; i < _actionData.size(); ++i) {
const Profile::Action& action = _actionData[i];
std::string name = action.name.empty() ? action.identifier : action.name;
for (const Profile::Action& action : _actionData) {
const std::string name = action.name.empty() ? action.identifier : action.name;
_actionWidgets.list->addItem(new QListWidgetItem(QString::fromStdString(name)));
}
@@ -161,8 +160,8 @@ void ActionDialog::createActionWidgets(QGridLayout* layout) {
_actionWidgets.identifier, &QLineEdit::textEdited,
[this]() {
// Check if the identifier is legal
std::string identifier = _actionWidgets.identifier->text().toStdString();
bool isLegal = identifier.find_first_of("\t\n. ") == std::string::npos;
const std::string id = _actionWidgets.identifier->text().toStdString();
const bool isLegal = id.find_first_of("\t\n. ") == std::string::npos;
if (isLegal) {
_actionWidgets.infoText->clear();
_actionWidgets.infoText->setHidden(true);
@@ -308,10 +307,9 @@ void ActionDialog::createKeyboardWidgets(QGridLayout* layout) {
this, &ActionDialog::keybindingSelected
);
for (size_t i = 0; i < _keybindingsData.size(); ++i) {
const Profile::Keybinding& kv = _keybindingsData[i];
for (const Profile::Keybinding& keybinding : _keybindingsData) {
QListWidgetItem* item = new QListWidgetItem;
updateListItem(item, kv);
updateListItem(item, keybinding);
_keybindingWidgets.list->addItem(item);
}
@@ -454,7 +452,7 @@ Profile::Action* ActionDialog::selectedAction() {
void ActionDialog::actionAdd() {
_actionWidgets.list->addItem("");
_actionData.push_back(Profile::Action());
_actionData.emplace_back();
_actionWidgets.list->setCurrentRow(_actionWidgets.list->count() - 1);
}
@@ -468,15 +466,15 @@ void ActionDialog::actionRemove() {
);
// We can't remove an action if it has a keyboard shortcut attached to it
for (size_t i = 0; i < _keybindingsData.size(); ++i) {
for (size_t i = 0; i < _keybindingsData.size(); i++) {
const Profile::Keybinding& kb = _keybindingsData[i];
if (kb.action != action->identifier) {
continue;
}
QMessageBox::StandardButton button = QMessageBox::information(
const QMessageBox::StandardButton button = QMessageBox::information(
this,
"Remove action",
QString::fromStdString(fmt::format(
QString::fromStdString(std::format(
"Action '{}' is used in the keybind '{}' and cannot be removed unless "
"the keybind is removed as well. Do you want to remove the keybind as "
"well?",
@@ -500,7 +498,7 @@ void ActionDialog::actionRemove() {
}
}
for (size_t i = 0; i < _actionData.size(); ++i) {
for (size_t i = 0; i < _actionData.size(); i++) {
if (_actionData[i].identifier == action->identifier) {
clearActionFields();
_actionData.erase(_actionData.begin() + i);
@@ -563,14 +561,14 @@ void ActionDialog::actionSelected() {
}
void ActionDialog::actionSaved() {
std::string newIdentifier = _actionWidgets.identifier->text().toStdString();
const std::string newIdentifier = _actionWidgets.identifier->text().toStdString();
if (newIdentifier.empty()) {
QMessageBox::critical(this, "Empty identifier", "Identifier must not be empty");
return;
}
Profile::Action* action = selectedAction();
std::string oldIdentifier = action->identifier;
const std::string oldIdentifier = action->identifier;
if (oldIdentifier != newIdentifier) {
// The identifier is a bit special as we need to make sure that we didn't
// accidentally create a duplicate while renaming the currently selected action.
@@ -598,13 +596,13 @@ void ActionDialog::actionSaved() {
_keybindingWidgets.list->count() == static_cast<int>(_keybindingsData.size()),
"The list and data got out of sync"
);
for (int i = 0; i < _keybindingWidgets.list->count(); ++i) {
for (int i = 0; i < _keybindingWidgets.list->count(); i++) {
if (_keybindingsData[i].action == oldIdentifier) {
_keybindingsData[i].action = newIdentifier;
updateListItem(_keybindingWidgets.list->item(i), _keybindingsData[i]);
}
}
for (int i = 0; i < _keybindingWidgets.action->count(); ++i) {
for (int i = 0; i < _keybindingWidgets.action->count(); i++) {
if (_keybindingWidgets.action->itemText(i).toStdString() == oldIdentifier) {
_keybindingWidgets.action->setItemText(
i,
@@ -641,7 +639,7 @@ void ActionDialog::actionSaved() {
clearActionFields();
}
void ActionDialog::clearActionFields() {
void ActionDialog::clearActionFields() const {
_actionWidgets.list->setCurrentRow(-1);
_actionWidgets.identifier->clear();
_actionWidgets.identifier->setEnabled(false);
@@ -681,9 +679,10 @@ void ActionDialog::chooseScripts() {
d.exec();
}
void ActionDialog::appendScriptsToTextfield(std::vector<std::string> scripts) {
for (std::string script : scripts) {
_actionWidgets.script->append(QString::fromStdString(std::move(script)));
void ActionDialog::appendScriptsToTextfield(const std::vector<std::string>& scripts) const
{
for (const std::string& script : scripts) {
_actionWidgets.script->append(QString::fromStdString(script));
}
}
@@ -695,7 +694,7 @@ Profile::Keybinding* ActionDialog::selectedKeybinding() {
void ActionDialog::keybindingAdd() {
_keybindingWidgets.list->addItem("");
_keybindingsData.push_back(Profile::Keybinding());
_keybindingsData.emplace_back();
_keybindingWidgets.list->setCurrentRow(_keybindingWidgets.list->count() - 1);
}
@@ -703,7 +702,7 @@ void ActionDialog::keybindingRemove() {
const Profile::Keybinding* keybinding = selectedKeybinding();
ghoul_assert(keybinding, "A keybinding must be selected at this point");
for (size_t i = 0; i < _keybindingsData.size(); ++i) {
for (size_t i = 0; i < _keybindingsData.size(); i++) {
if (_keybindingsData[i].key == keybinding->key &&
_keybindingsData[i].action == keybinding->action)
{
@@ -735,7 +734,7 @@ void ActionDialog::keybindingSelected() {
hasKeyModifier(keybinding->key.modifier, KeyModifier::Alt)
);
std::string key = ghoul::to_string(keybinding->key.key);
const std::string key = ghoul::to_string(keybinding->key.key);
_keybindingWidgets.key->setCurrentText(QString::fromStdString(key));
_keybindingWidgets.key->setEnabled(true);
_keybindingWidgets.action->setCurrentText(
@@ -773,7 +772,7 @@ void ActionDialog::keybindingSelected() {
}
}
void ActionDialog::keybindingActionSelected(int) {
void ActionDialog::keybindingActionSelected(int) const {
_keybindingWidgets.actionText->setText(_keybindingWidgets.action->currentText());
}
@@ -814,7 +813,7 @@ void ActionDialog::keybindingSaved() {
clearKeybindingFields();
}
void ActionDialog::clearKeybindingFields() {
void ActionDialog::clearKeybindingFields() const {
_keybindingWidgets.list->setCurrentRow(-1);
_keybindingWidgets.shiftModifier->setChecked(false);
_keybindingWidgets.shiftModifier->setEnabled(false);
@@ -832,8 +831,8 @@ void ActionDialog::clearKeybindingFields() {
}
void ActionDialog::keybindingRejected() {
bool isKeyEmpty = (_keybindingsData.back().key.key == Key::Unknown);
bool isActionEmpty = _keybindingsData.back().action.empty();
const bool isKeyEmpty = (_keybindingsData.back().key.key == Key::Unknown);
const bool isActionEmpty = _keybindingsData.back().action.empty();
if (isKeyEmpty || isActionEmpty) {
delete _keybindingWidgets.list->takeItem(_keybindingWidgets.list->count() - 1);
_keybindingsData.erase(_keybindingsData.begin() + _keybindingsData.size() - 1);

View File

@@ -44,11 +44,12 @@ AdditionalScriptsDialog::AdditionalScriptsDialog(QWidget* parent,
setWindowTitle("Additional Scripts");
createWidgets();
std::string scriptText = std::accumulate(
const std::string scriptText = std::accumulate(
_scriptsData.begin(), _scriptsData.end(),
std::string(), [](std::string lhs, std::string rhs) { return lhs + rhs + '\n'; }
std::string(),
[](std::string lhs, const std::string& rhs) { return lhs + rhs + '\n'; }
);
_textScripts->setText(QString::fromStdString(std::move(scriptText)));
_textScripts->setText(QString::fromStdString(scriptText));
_textScripts->moveCursor(QTextCursor::MoveOperation::End);
}
@@ -109,8 +110,10 @@ void AdditionalScriptsDialog::chooseScripts() {
d.exec();
}
void AdditionalScriptsDialog::appendScriptsToTextfield(std::vector<std::string> scripts) {
for (std::string script : scripts) {
_textScripts->append(QString::fromStdString(std::move(script)));
void AdditionalScriptsDialog::appendScriptsToTextfield(
const std::vector<std::string>& scripts)
{
for (const std::string& script : scripts) {
_textScripts->append(QString::fromStdString(script));
}
}

View File

@@ -46,7 +46,7 @@ namespace {
QModelIndex idx = model.index(r, 0, parent);
if (!model.isAsset(idx)) {
int nChildRows = model.childCount(idx);
const int nChildRows = model.childCount(idx);
if (traverseToExpandSelectedItems(tree, model, nChildRows, idx)) {
tree.setExpanded(idx, true);
isExpanded = true;
@@ -63,25 +63,25 @@ namespace {
int nRows, const std::string& path)
{
int startIndex = 0;
std::string token = "${USER_ASSETS}/";
const std::string token = "${USER_ASSETS}/";
if (path.starts_with(token)) {
startIndex = static_cast<int>(token.length());
}
const size_t slash = path.find_first_of('/', startIndex);
const bool endOfPath = (slash == std::string::npos);
std::string firstDir = endOfPath ? "" : path.substr(0, slash);
const std::string firstDir = endOfPath ? "" : path.substr(0, slash);
if (!endOfPath) {
std::string nextPath = (slash == std::string::npos) ?
const std::string nextPath = (slash == std::string::npos) ?
path :
path.substr(slash + 1);
bool foundDirMatch = false;
for (int r = 0; r < nRows; r++) {
QModelIndex idx = model.index(r, 0, parent);
std::string assetName = model.name(idx).toStdString();
const std::string assetName = model.name(idx).toStdString();
if (!model.isAsset(idx)) {
if (firstDir == assetName) {
int nChildRows = model.childCount(idx);
const int nChildRows = model.childCount(idx);
foundDirMatch = true;
traverseToFindFilesystemMatch(model, idx, nChildRows, nextPath);
break;
@@ -104,7 +104,7 @@ namespace {
bool foundFileMatch = false;
for (int r = 0; r < nRows; r++) {
QModelIndex idx = model.index(r, 0, parent);
std::string assetName = model.name(idx).toStdString();
const std::string assetName = model.name(idx).toStdString();
// Need to check if it actually is an asset to prevent issue #2154
if (model.isAsset(idx) && path == assetName) {
foundFileMatch = true;
@@ -173,12 +173,12 @@ AssetsDialog::AssetsDialog(QWidget* parent, openspace::Profile* profile,
for (const std::string& a : _profile->assets) {
QModelIndex p = _assetTreeModel.index(-1, 0);
int nRows = _assetTreeModel.rowCount(p);
const QModelIndex p = _assetTreeModel.index(-1, 0);
const int nRows = _assetTreeModel.rowCount(p);
traverseToFindFilesystemMatch(_assetTreeModel, p, nRows, a);
}
int nRows = _assetTreeModel.rowCount(_assetTreeModel.index(-1, 0));
const int nRows = _assetTreeModel.rowCount(_assetTreeModel.index(-1, 0));
traverseToExpandSelectedItems(
*_assetTree,
_assetTreeModel,
@@ -249,12 +249,12 @@ QString AssetsDialog::createTextSummary() {
return "";
}
QString summary;
for (size_t i = 0; i < summaryItems.size(); ++i) {
bool existsInFilesystem = summaryItems.at(i)->doesExistInFilesystem();
for (size_t i = 0; i < summaryItems.size(); i++) {
const bool existsInFilesystem = summaryItems.at(i)->doesExistInFilesystem();
std::string s = existsInFilesystem ?
fmt::format("{}<br>", summaryPaths.at(i)) :
fmt::format("<font color='red'>{}</font><br>", summaryPaths.at(i));
const std::string s = existsInFilesystem ?
std::format("{}<br>", summaryPaths.at(i)) :
std::format("<font color='red'>{}</font><br>", summaryPaths.at(i));
summary += QString::fromStdString(s);
}
return summary;
@@ -316,7 +316,7 @@ void SearchProxyModel::setFilterRegularExpression(const QString& pattern) {
bool SearchProxyModel::filterAcceptsRow(int sourceRow,
const QModelIndex& sourceParent) const
{
QModelIndex idx = sourceModel()->index(sourceRow, 0, sourceParent);
const QModelIndex idx = sourceModel()->index(sourceRow, 0, sourceParent);
return acceptIndex(idx);
}
@@ -324,13 +324,14 @@ bool SearchProxyModel::acceptIndex(const QModelIndex& idx) const {
if (!idx.isValid() || !_regExPattern) {
return false;
}
QString text = idx.data(Qt::DisplayRole).toString();
QRegularExpressionMatchIterator matchIterator = _regExPattern->globalMatch(text);
if (matchIterator.hasNext()) {
const QString text = idx.data(Qt::DisplayRole).toString();
const QRegularExpressionMatchIterator matchIt = _regExPattern->globalMatch(text);
if (matchIt.hasNext()) {
return true;
}
for (int row = 0; row < idx.model()->rowCount(idx); ++row) {
if (acceptIndex(idx.model()->index(row, 0, idx))) {
const bool accept = acceptIndex(idx.model()->index(row, 0, idx));
if (accept) {
return true;
}
}

View File

@@ -121,8 +121,8 @@ bool AssetTreeItem::insertChildren(int position, int count, int columns) {
}
for (int row = 0; row < count; ++row) {
std::vector<QVariant> data(columns);
AssetTreeItem*item = new AssetTreeItem(data, this);
std::vector<QVariant> data = std::vector<QVariant>(columns);
AssetTreeItem* item = new AssetTreeItem(std::move(data), this);
_childItems.insert(_childItems.begin() + position, item);
}

View File

@@ -39,9 +39,9 @@ namespace {
bool existsInFilesystem = true;
};
int getLevelFromLine(std::string line) {
int getLevelFromLine(const std::string& line) {
int level = 0;
for (unsigned int i = 0; i < line.length(); ++i) {
for (unsigned int i = 0; i < line.length(); i++) {
if (line.substr(i, 1) == " ") {
level++;
}
@@ -80,14 +80,19 @@ namespace {
int nChildInsert = -1;
bool continueToNextLine = true;
while (continueToNextLine && elem.line.length() != 0) {
int levelChange = elem.level - level;
while (continueToNextLine && !elem.line.empty()) {
const int levelChange = elem.level - level;
if (levelChange == 0) {
parent->insertChildren(++nChildInsert, 1, 3);
parent->child(nChildInsert)->setData(0, QString::fromStdString(elem.line));
bool shouldMakeElemChecked = (elem.checked || !elem.existsInFilesystem);
Qt::CheckState check = (shouldMakeElemChecked) ? Qt::Checked : Qt::Unchecked;
parent->child(nChildInsert)->setData(
0,
QString::fromStdString(elem.line)
);
const bool shouldMakeElemChecked =
(elem.checked || !elem.existsInFilesystem);
const Qt::CheckState check =
shouldMakeElemChecked ? Qt::Checked : Qt::Unchecked;
parent->child(nChildInsert)->setData(1, check);
parent->child(nChildInsert)->setExistsInFilesystem(elem.existsInFilesystem);
continueToNextLine = importGetNextLine(elem, iss);
@@ -96,7 +101,6 @@ namespace {
importInsertItem(iss, parent->child(nChildInsert), elem, level + 1);
}
else if (levelChange < 0) {
continueToNextLine = false;
break;
}
}
@@ -108,14 +112,14 @@ namespace {
std::vector<AssetTreeItem*>& outputItems,
std::string pathPrefix)
{
std::string itemName = item->data(0).toString().toStdString();
bool isPathPrefix = ((pathPrefix.length()) == 0 && (itemName == Header1));
const std::string itemName = item->data(0).toString().toStdString();
const bool isPathPrefix = ((pathPrefix.length()) == 0 && (itemName == Header1));
if (item->isAsset()) {
if (item->isChecked()) {
std::string path = pathPrefix + itemName;
outputItems.push_back(item);
outputPaths.push_back(path);
outputPaths.push_back(std::move(path));
}
}
else {
@@ -123,7 +127,7 @@ namespace {
pathPrefix += itemName;
pathPrefix += "/";
}
for (int i = 0; i < item->childCount(); ++i) {
for (int i = 0; i < item->childCount(); i++) {
parseChildrenForSelected(
item->child(i),
outputPaths,
@@ -200,7 +204,7 @@ QString AssetTreeModel::name(QModelIndex& index) const {
return item(index)->name();
}
void AssetTreeModel::setName(QModelIndex& index, QString name) {
void AssetTreeModel::setName(QModelIndex& index, const QString& name) {
item(index)->setData(0, name);
}
@@ -245,7 +249,7 @@ QModelIndex AssetTreeModel::index(int row, int column, const QModelIndex& parent
}
QModelIndex AssetTreeModel::parent(int row, int column, const QModelIndex& parent) const {
QModelIndex idx = index(row, column, parent);
const QModelIndex idx = index(row, column, parent);
return AssetTreeModel::parent(idx);
}

View File

@@ -37,6 +37,7 @@
#include <QPlainTextEdit>
#include <QPushButton>
#include <QTabWidget>
#include <fstream>
namespace {
constexpr int CameraTypeNode = 0;
@@ -47,29 +48,23 @@ namespace {
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
bool inNumericalRange(QLineEdit* le, float min, float max) {
QString s = le->text();
const QString s = le->text();
bool validConversion = false;
float value = s.toFloat(&validConversion);
const float value = s.toFloat(&validConversion);
if (!validConversion) {
return false;
}
if (value < min || value > max) {
return false;
}
return true;
return (value >= min) && (value <= max);
}
bool isNumericalLargerThan(QLineEdit* le, float limit) {
QString s = le->text();
const QString s = le->text();
bool validConversion = false;
float value = s.toFloat(&validConversion);
const float value = s.toFloat(&validConversion);
if (!validConversion) {
return false;
}
if (value > limit) {
return true;
}
return false;
return value > limit;
}
} // namespace
@@ -353,17 +348,17 @@ QWidget* CameraDialog::createNavStateWidget() {
connect(
loadFile, &QPushButton::clicked,
[this]() {
QString file = QFileDialog::getOpenFileName(
const QString file = QFileDialog::getOpenFileName(
this,
"Select navigate state file"
);
std::ifstream f(file.toStdString());
std::string contents = std::string(
(std::istreambuf_iterator<char>(f)),
std::ifstream f = std::ifstream(file.toStdString());
const std::string contents = std::string(
std::istreambuf_iterator<char>(f),
std::istreambuf_iterator<char>()
);
nlohmann::json json = nlohmann::json::parse(contents);
const nlohmann::json json = nlohmann::json::parse(contents);
using namespace openspace::interaction;
NavigationState state = NavigationState(json);
@@ -529,7 +524,7 @@ bool CameraDialog::areRequiredFormsFilledAndValid() {
return allFormsOk;
}
void CameraDialog::addErrorMsg(QString errorDescription) {
void CameraDialog::addErrorMsg(const QString& errorDescription) {
QString contents = _errorMsg->text();
if (!contents.isEmpty()) {
contents += ", ";
@@ -563,7 +558,7 @@ void CameraDialog::approved() {
!_navState.upY->text().isEmpty() &&
!_navState.upZ->text().isEmpty())
{
glm::dvec3 u = glm::dvec3(
const glm::dvec3 u = glm::dvec3(
_navState.upX->text().toDouble(),
_navState.upY->text().toDouble(),
_navState.upZ->text().toDouble()

View File

@@ -60,7 +60,7 @@ namespace {
std::string checkForTimeDescription(int intervalIndex, double value) {
double amount = value / TimeIntervals[intervalIndex].secondsPerInterval;
std::string description = fmt::format("{}", amount);
std::string description = std::format("{}", amount);
description += " " + TimeIntervals[intervalIndex].intervalName + "/sec";
return description;
}
@@ -70,9 +70,9 @@ namespace {
return "";
}
size_t i;
for (i = 0; i < (TimeIntervals.size() - 1); ++i) {
if (abs(value) >= TimeIntervals[i].secondsPerInterval) {
size_t i = 0;
for (i = 0; i < (TimeIntervals.size() - 1); i++) {
if (std::abs(value) >= TimeIntervals[i].secondsPerInterval) {
break;
}
}
@@ -89,7 +89,7 @@ DeltaTimesDialog::DeltaTimesDialog(QWidget* parent, std::vector<double>* deltaTi
createWidgets();
for (size_t d = 0; d < _deltaTimesData.size(); ++d) {
std::string summary = createSummaryForDeltaTime(d, true);
const std::string summary = createSummaryForDeltaTime(d, true);
_listWidget->addItem(new QListWidgetItem(QString::fromStdString(summary)));
}
@@ -185,7 +185,7 @@ void DeltaTimesDialog::createWidgets() {
std::string DeltaTimesDialog::createSummaryForDeltaTime(size_t idx, bool forListView) {
int k = (idx % 10 == 9) ? 0 : idx % 10 + 1;
k = (idx == 0) ? 1 : k;
std::string key = std::to_string(k);
const std::string key = std::to_string(k);
std::string s;
if (idx >= 20) {
@@ -202,7 +202,7 @@ std::string DeltaTimesDialog::createSummaryForDeltaTime(size_t idx, bool forList
}
if (forListView) {
s += fmt::format(
s += std::format(
"\t{}\t{}", _deltaTimesData.at(idx), timeDescription(_deltaTimesData.at(idx))
);
}
@@ -211,7 +211,7 @@ std::string DeltaTimesDialog::createSummaryForDeltaTime(size_t idx, bool forList
void DeltaTimesDialog::listItemSelected() {
QListWidgetItem *item = _listWidget->currentItem();
int index = _listWidget->row(item);
const int index = _listWidget->row(item);
if (index < (static_cast<int>(_deltaTimesData.size()) - 1)) {
_listWidget->setCurrentRow(index);
@@ -229,7 +229,7 @@ void DeltaTimesDialog::listItemSelected() {
transitionEditMode(index, true);
}
void DeltaTimesDialog::setLabelForKey(int index, bool editMode, std::string color) {
void DeltaTimesDialog::setLabelForKey(int index, bool editMode, std::string_view color) {
std::string labelS = "Set Simulation Time Increment for key";
if (index >= static_cast<int>(_deltaTimesData.size())) {
index = static_cast<int>(_deltaTimesData.size()) - 1;
@@ -237,9 +237,9 @@ void DeltaTimesDialog::setLabelForKey(int index, bool editMode, std::string colo
if (editMode) {
labelS += " '" + createSummaryForDeltaTime(index, false) + "':";
}
_adjustLabel->setText(QString::fromStdString(
"<font color='" + color + "'>" + labelS + "</font>"
));
_adjustLabel->setText(QString::fromStdString(std::format(
"<font color='{}'>{}</font>", color, labelS
)));
}
void DeltaTimesDialog::valueChanged(const QString& text) {
@@ -247,9 +247,9 @@ void DeltaTimesDialog::valueChanged(const QString& text) {
_errorMsg->setText("");
}
else {
int value = text.toDouble();
if (value != 0) {
_value->setText(QString::fromStdString(timeDescription(text.toDouble())));
const double value = text.toDouble();
if (value != 0.0) {
_value->setText(QString::fromStdString(timeDescription(value)));
_errorMsg->setText("");
}
}
@@ -267,7 +267,7 @@ bool DeltaTimesDialog::isLineEmpty(int index) {
}
void DeltaTimesDialog::addDeltaTimeValue() {
int currentListSize = _listWidget->count();
const int currentListSize = _listWidget->count();
const QString messageAddValue = " (Enter integer value below & click 'Save')";
if ((currentListSize == 1) && (isLineEmpty(0))) {
@@ -292,9 +292,9 @@ void DeltaTimesDialog::addDeltaTimeValue() {
void DeltaTimesDialog::saveDeltaTimeValue() {
QListWidgetItem* item = _listWidget->currentItem();
if (item && !_deltaTimesData.empty()) {
int index = _listWidget->row(item);
const int index = _listWidget->row(item);
_deltaTimesData.at(index) = _seconds->text().toDouble();
std::string summary = createSummaryForDeltaTime(index, true);
const std::string summary = createSummaryForDeltaTime(index, true);
_listWidget->item(index)->setText(QString::fromStdString(summary));
transitionEditMode(index, false);
_editModeNewItem = false;
@@ -362,7 +362,8 @@ void DeltaTimesDialog::parseSelections() {
}
}
std::vector<double> tempDt;
for (int i = 0; i < (finalNonzeroIndex + 1); ++i) {
tempDt.reserve(finalNonzeroIndex);
for (int i = 0; i < (finalNonzeroIndex + 1); i++) {
tempDt.push_back(_deltaTimesData[i]);
}
*_deltaTimes = std::move(_deltaTimesData);
@@ -379,11 +380,13 @@ void DeltaTimesDialog::keyPressEvent(QKeyEvent* evt) {
}
return;
}
else if (evt->key() == Qt::Key_Escape) {
if (evt->key() == Qt::Key_Escape) {
if (_editModeNewItem) {
discardDeltaTimeValue();
return;
}
}
QDialog::keyPressEvent(evt);
}

View File

@@ -47,18 +47,8 @@
#include <QStyle>
#include <sstream>
using json = nlohmann::json;
using namespace openspace;
namespace {
BooleanType(IsDirty);
void styleLabel(QLabel* label, IsDirty isDirty) {
std::string newStyle = isDirty ? "error" : "normal";
label->setObjectName(QString::fromStdString(newStyle));
label->style()->unpolish(label);
label->style()->polish(label);
}
} // namespace
//using json = nlohmann::json;
//using namespace openspace;
namespace {
constexpr std::string_view _loggerCat = "HorizonsDialog";
@@ -72,11 +62,18 @@ namespace {
constexpr std::string_view Years = "calendar years";
constexpr std::string_view Unitless = "equal intervals (unitless)";
BooleanType(IsDirty);
void styleLabel(QLabel* label, IsDirty isDirty) {
const std::string newStyle = isDirty ? "error" : "normal";
label->setObjectName(QString::fromStdString(newStyle));
label->style()->unpolish(label);
label->style()->polish(label);
}
int findId(const std::string& match) {
// Format: id, other information...
std::stringstream str(match);
int id;
int id = 0;
str >> id;
return id;
}
@@ -84,10 +81,12 @@ namespace {
HorizonsDialog::HorizonsDialog(QWidget* parent)
: QDialog(parent)
{
#ifdef OPENSPACE_MODULE_SPACE_ENABLED
_manager = new QNetworkAccessManager(this);
, _manager(new QNetworkAccessManager(this))
#endif // OPENSPACE_MODULE_SPACE_ENABLED
{
#ifdef OPENSPACE_MODULE_SPACE_ENABLED
setWindowTitle("Horizons");
createWidgets();
#endif // OPENSPACE_MODULE_SPACE_ENABLED
@@ -102,7 +101,7 @@ std::filesystem::path HorizonsDialog::file() const {
}
void HorizonsDialog::openSaveAs() {
QString filename = QFileDialog::getSaveFileName(
const QString filename = QFileDialog::getSaveFileName(
this,
"Choose a file path where the generated Horizons file will be saved",
QString::fromStdString(absPath("${USER}").string()),
@@ -142,8 +141,8 @@ void HorizonsDialog::downloadProgress(int value, int total) {
}
void HorizonsDialog::importTimeRange() {
QString startStr = QString::fromStdString(_validTimeRange.first);
QString endStr = QString::fromStdString(_validTimeRange.second);
const QString startStr = QString::fromStdString(_validTimeRange.first);
const QString endStr = QString::fromStdString(_validTimeRange.second);
QDateTime start = QDateTime::fromString(startStr, "yyyy-MMM-dd T hh:mm");
QDateTime end = QDateTime::fromString(endStr, "yyyy-MMM-dd T hh:mm");
@@ -153,8 +152,8 @@ void HorizonsDialog::importTimeRange() {
end = QDateTime::fromString(endStr, "yyyy-MMM-dd T hh:mm:ss");
if (!start.isValid() || !end.isValid()) {
QDate startDate = QDate::fromString(startStr, "yyyy-MMM-dd");
QDate endDate = QDate::fromString(endStr, "yyyy-MMM-dd");
const QDate startDate = QDate::fromString(startStr, "yyyy-MMM-dd");
const QDate endDate = QDate::fromString(endStr, "yyyy-MMM-dd");
if (startDate.isValid() && endDate.isValid()) {
_startEdit->setDate(startDate);
@@ -165,7 +164,7 @@ void HorizonsDialog::importTimeRange() {
}
_errorMsg->setText("Could not import time range");
std::string msg = fmt::format(
const std::string msg = std::format(
"Could not import time range '{}' to '{}'",
_validTimeRange.first, _validTimeRange.second
);
@@ -183,7 +182,7 @@ void HorizonsDialog::importTimeRange() {
void HorizonsDialog::approved() {
#ifdef OPENSPACE_MODULE_SPACE_ENABLED
_downloadLabel->show();
bool result = handleRequest();
const bool result = handleRequest();
_downloadLabel->hide();
if (result && std::filesystem::is_regular_file(_horizonsFile.file())) {
accept();
@@ -216,7 +215,7 @@ void HorizonsDialog::createWidgets() {
_typeCombo = new QComboBox;
_typeCombo->setToolTip("Choose Horizons data type");
QStringList types = {
const QStringList types = {
"Vector table",
"Observer table"
};
@@ -335,7 +334,7 @@ void HorizonsDialog::createWidgets() {
_timeTypeCombo = new QComboBox;
_timeTypeCombo->setToolTip("Choose unit of the step size");
QStringList timeTypes = {
const QStringList timeTypes = {
Minutes.data(),
Hours.data(),
Days.data(),
@@ -437,9 +436,9 @@ bool HorizonsDialog::isValidInput() {
}
// Numerical
bool couldConvert = false;
int32_t step = _stepEdit->text().toInt(&couldConvert);
const int32_t step = _stepEdit->text().toInt(&couldConvert);
if (!couldConvert) {
_errorMsg->setText(QString::fromStdString(fmt::format(
_errorMsg->setText(QString::fromStdString(std::format(
"Step size needs to be a number in range 1 to {}",
std::numeric_limits<int32_t>::max()
)));
@@ -459,7 +458,7 @@ bool HorizonsDialog::isValidInput() {
// website as a uint32_t. If step size over 32 bit int is sent, this error message is
// received: Cannot read numeric value -- re-enter
if (step < 1) {
_errorMsg->setText(QString::fromStdString(fmt::format(
_errorMsg->setText(QString::fromStdString(std::format(
"Step size is outside valid range 1 to '{}'",
std::numeric_limits<int32_t>::max()
)));
@@ -470,7 +469,7 @@ bool HorizonsDialog::isValidInput() {
}
// Send request synchronously, EventLoop waits until request has finished
json HorizonsDialog::sendRequest(const std::string& url) {
nlohmann::json HorizonsDialog::sendRequest(const std::string& url) {
QNetworkRequest request;
request.setHeader(QNetworkRequest::UserAgentHeader, "OpenSpace");
request.setUrl(QUrl(QString::fromStdString(url)));
@@ -484,13 +483,13 @@ json HorizonsDialog::sendRequest(const std::string& url) {
_downloadProgress->show();
QEventLoop loop;
QMetaObject::Connection status = connect(
const QMetaObject::Connection status = connect(
reply, &QNetworkReply::finished,
&loop, &QEventLoop::quit
);
if (!status) {
appendLog("Could not connect to Horizons API", HorizonsDialog::LogLevel::Error);
return json();
return nlohmann::json();
}
loop.exec(QEventLoop::ExcludeUserInputEvents);
@@ -498,19 +497,20 @@ json HorizonsDialog::sendRequest(const std::string& url) {
return handleReply(reply);
}
json HorizonsDialog::handleReply(QNetworkReply* reply) {
nlohmann::json HorizonsDialog::handleReply(QNetworkReply* reply) {
_downloadProgress->hide();
if (reply->error() != QNetworkReply::NoError) {
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
const QVariant statusCode =
reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if (!checkHttpStatus(statusCode)) {
std::string msg = fmt::format(
"Connection Error '{}' ", reply->errorString().toStdString()
const std::string msg = std::format(
"Connection Error '{}'", reply->errorString().toStdString()
);
appendLog(msg, HorizonsDialog::LogLevel::Error);
}
reply->deleteLater();
return json();
return nlohmann::json();
}
QUrl redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
@@ -519,26 +519,26 @@ json HorizonsDialog::handleReply(QNetworkReply* reply) {
redirect = reply->url().resolved(redirect);
}
std::string msg = fmt::format(
const std::string msg = std::format(
"Redirecting request to '{}'", redirect.toString().toStdString()
);
appendLog(msg, HorizonsDialog::LogLevel::Info);
return sendRequest(redirect.toString().toStdString());
}
QString answer = reply->readAll();
const QString answer = reply->readAll();
reply->deleteLater();
if (answer.isEmpty()) {
std::string msg = fmt::format(
const std::string msg = std::format(
"Connection Error '{}'", reply->errorString().toStdString()
);
appendLog(msg, HorizonsDialog::LogLevel::Error);
return json();
return nlohmann::json();
}
// Convert the answer to a json object and return it
return json::parse(answer.toStdString());
return nlohmann::json::parse(answer.toStdString());
}
bool HorizonsDialog::checkHttpStatus(const QVariant& statusCode) {
@@ -547,7 +547,7 @@ bool HorizonsDialog::checkHttpStatus(const QVariant& statusCode) {
statusCode.toInt() != static_cast<int>(HorizonsDialog::HTTPCodes::Ok))
{
std::string message;
HorizonsDialog::HTTPCodes code =
const HorizonsDialog::HTTPCodes code =
static_cast<HorizonsDialog::HTTPCodes>(statusCode.toInt());
switch (code) {
@@ -568,7 +568,7 @@ bool HorizonsDialog::checkHttpStatus(const QVariant& statusCode) {
"later time";
break;
default:
message = fmt::format(
message = std::format(
"HTTP status code '{}' was returned",
statusCode.toString().toStdString()
);
@@ -618,7 +618,8 @@ std::pair<std::string, std::string> HorizonsDialog::readTimeRange() {
"Trajectory name"
);
QDateTime start, end;
QDateTime start;
QDateTime end;
start = QDateTime::fromString(
QString::fromStdString(timeRange.first),
"yyyy-MMM-dd T hh:mm"
@@ -665,16 +666,16 @@ std::pair<std::string, std::string> HorizonsDialog::readTimeRange() {
}
else {
_errorMsg->setText("Could not parse time range");
std::string msg = fmt::format(
"Could not read time range '{}' to '{}'", timeRange.first,
timeRange.second
const std::string msg = std::format(
"Could not read time range '{}' to '{}'",
timeRange.first, timeRange.second
);
appendLog(msg, LogLevel::Error);
}
return std::pair<std::string, std::string>();
}
else {
std::string msg = fmt::format(
const std::string msg = std::format(
"Could not find all time range information. Latest Horizons "
"mesage: {}", _latestHorizonsError
);
@@ -686,6 +687,8 @@ std::pair<std::string, std::string> HorizonsDialog::readTimeRange() {
}
bool HorizonsDialog::handleRequest() {
using namespace openspace;
if (!isValidInput()) {
return false;
}
@@ -707,14 +710,14 @@ bool HorizonsDialog::handleRequest() {
_validTimeRange = std::pair<std::string, std::string>();
_latestHorizonsError.clear();
std::string url = constructUrl();
const std::string url = constructUrl();
_chooseObserverCombo->clear();
_chooseObserverCombo->hide();
_chooseTargetCombo->clear();
_chooseTargetCombo->hide();
json answer = sendRequest(url);
nlohmann::json answer = sendRequest(url);
if (answer.empty()) {
_errorMsg->setText("Connection error");
return false;
@@ -728,19 +731,18 @@ bool HorizonsDialog::handleRequest() {
_horizonsFile = std::move(file);
HorizonsResultCode result = isValidHorizonsFile(_horizonsFile.file());
bool isValid = handleResult(result);
const bool isValid = handleResult(result);
if (!isValid && std::filesystem::is_regular_file(_horizonsFile.file())) {
std::string newName = _horizonsFile.file().filename().stem().string();
const std::string newName = _horizonsFile.file().filename().stem().string();
std::filesystem::path oldFile = _horizonsFile.file();
const std::filesystem::path& oldFile = _horizonsFile.file();
std::filesystem::path newFile = oldFile;
newFile.replace_filename(newName + "_error.txt");
std::filesystem::rename(oldFile, newFile);
std::string msg = fmt::format(
"For more information, see the saved error file {}", newFile
const std::string msg = std::format(
"For more information, see the saved error file '{}'", newFile
);
appendLog(msg, LogLevel::Info);
}
@@ -749,8 +751,10 @@ bool HorizonsDialog::handleRequest() {
}
std::string HorizonsDialog::constructUrl() {
using namespace openspace;
// Construct url for request
HorizonsType type;
HorizonsType type = HorizonsType::Invalid;
if (_typeCombo->currentIndex() == 0) {
type = HorizonsType::Vector;
}
@@ -765,7 +769,8 @@ std::string HorizonsDialog::constructUrl() {
std::string command;
if (_chooseTargetCombo->count() > 0 && _chooseTargetCombo->currentIndex() != 0) {
QVariant t = _chooseTargetCombo->itemData(_chooseTargetCombo->currentIndex());
const QVariant t =
_chooseTargetCombo->itemData(_chooseTargetCombo->currentIndex());
command = t.toString().toStdString();
_targetName = _chooseTargetCombo->currentText().toStdString();
_targetEdit->setText(QString::fromStdString(command));
@@ -777,9 +782,9 @@ std::string HorizonsDialog::constructUrl() {
std::string center;
if (_chooseObserverCombo->count() > 0 && _chooseObserverCombo->currentIndex() != 0) {
QVariant observer =
const QVariant observer =
_chooseObserverCombo->itemData(_chooseObserverCombo->currentIndex());
std::string id = observer.toString().toStdString();
const std::string id = observer.toString().toStdString();
center = "@" + id;
_observerName = _chooseObserverCombo->currentText().toStdString();
_centerEdit->setText(QString::fromStdString(id));
@@ -789,13 +794,13 @@ std::string HorizonsDialog::constructUrl() {
_observerName = center;
}
_startTime = fmt::format(
_startTime = std::format(
"{} {}",
_startEdit->date().toString("yyyy-MM-dd").toStdString(),
_startEdit->time().toString("hh:mm:ss").toStdString()
);
_endTime = fmt::format(
_endTime = std::format(
"{} {}",
_endEdit->date().toString("yyyy-MM-dd").toStdString(),
_endEdit->time().toString("hh:mm:ss").toStdString()
@@ -840,7 +845,9 @@ std::string HorizonsDialog::constructUrl() {
);
}
openspace::HorizonsFile HorizonsDialog::handleAnswer(json& answer) {
openspace::HorizonsFile HorizonsDialog::handleAnswer(nlohmann::json& answer) {
using namespace openspace;
auto it = answer.find("error");
if (it != answer.end()) {
_latestHorizonsError = *it;
@@ -860,12 +867,14 @@ openspace::HorizonsFile HorizonsDialog::handleAnswer(json& answer) {
}
// Create a text file and write reply to it
std::filesystem::path filePath =
const std::filesystem::path filePath =
std::filesystem::absolute(_fileEdit->text().toStdString());
auto result = answer.find("result");
if (result == answer.end()) {
std::string msg = fmt::format("Malformed answer recieved '{}'", answer.dump());
const std::string msg = std::format(
"Malformed answer received '{}'", answer.dump()
);
appendLog(msg, HorizonsDialog::LogLevel::Error);
return openspace::HorizonsFile();
}
@@ -878,7 +887,7 @@ openspace::HorizonsFile HorizonsDialog::handleAnswer(json& answer) {
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel
);
msgBox.setDefaultButton(QMessageBox::Yes);
int ret = msgBox.exec();
const int ret = msgBox.exec();
switch (ret) {
case QMessageBox::Yes:
// If yes then continue as normal
@@ -900,13 +909,15 @@ openspace::HorizonsFile HorizonsDialog::handleAnswer(json& answer) {
}
bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
using namespace openspace;
switch (result) {
case HorizonsResultCode::Valid: {
// If the request worked then delete the corresponding error file if it exist
std::filesystem::path validFile(_horizonsFile.file());
std::filesystem::path validFile =_horizonsFile.file();
std::string errorName = validFile.filename().stem().string();
std::filesystem::path errorFile = validFile.replace_filename(
const std::string errorName = validFile.filename().stem().string();
const std::filesystem::path errorFile = validFile.replace_filename(
errorName + "_error.txt"
);
@@ -918,7 +929,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
case HorizonsResultCode::Empty: {
_errorMsg->setText("The horizons file is empty");
if (!_latestHorizonsError.empty()) {
std::string msg = fmt::format(
const std::string msg = std::format(
"Latest Horizons error: {}", _latestHorizonsError
);
appendLog(msg, LogLevel::Error);
@@ -928,7 +939,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
break;
}
case HorizonsResultCode::ErrorSize: {
std::string msg = fmt::format(
const std::string msg = std::format(
"Time range '{}' to '{}' with step size '{} {}' is too big, try to "
"increase the step size and/or decrease the time range",
_startTime, _endTime, _stepEdit->text().toStdString(),
@@ -952,7 +963,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
std::filesystem::remove(_horizonsFile.file());
break;
case HorizonsResultCode::ErrorTimeRange: {
std::string msg = fmt::format(
std::string msg = std::format(
"Time range is outside the valid range for target '{}'", _targetName
);
appendLog(msg, HorizonsDialog::LogLevel::Error);
@@ -962,15 +973,15 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
_validTimeRange = readTimeRange();
if (_validTimeRange.first.empty() || _validTimeRange.second.empty()) {
if (!_latestHorizonsError.empty()) {
msg = fmt::format("Latest Horizons error: {}", _latestHorizonsError);
msg = std::format("Latest Horizons error: {}", _latestHorizonsError);
appendLog(msg, LogLevel::Error);
}
break;
}
msg = fmt::format(
"Valid time range is '{}' to '{}'", _validTimeRange.first,
_validTimeRange.second
msg = std::format(
"Valid time range is '{}' to '{}'",
_validTimeRange.first, _validTimeRange.second
);
appendLog(msg, HorizonsDialog::LogLevel::Info);
_importTimeButton->show();
@@ -979,12 +990,12 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
break;
}
case HorizonsResultCode::ErrorNoObserver: {
std::string msg = fmt::format(
std::string msg = std::format(
"No match was found for observer '{}'", _observerName
);
appendLog(msg, HorizonsDialog::LogLevel::Error);
msg = fmt::format(
msg = std::format(
"Try to use '@{}' as observer to search for possible matches",
_observerName
);
@@ -995,7 +1006,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
break;
}
case HorizonsResultCode::ErrorObserverTargetSame: {
std::string msg = fmt::format(
const std::string msg = std::format(
"The observer '{}' and target '{}' are the same. Please use another "
"observer for the current target", _observerName, _targetName
);
@@ -1007,7 +1018,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
break;
}
case HorizonsResultCode::ErrorNoData: {
std::string msg = fmt::format(
const std::string msg = std::format(
"There is not enough data to compute the state of target '{}' in "
"relation to the observer '{}' for the time range '{}' to '{}'. Try to "
"use another observer for the current target or another time range",
@@ -1019,20 +1030,20 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
break;
}
case HorizonsResultCode::MultipleObserverStations: {
std::string msg = fmt::format(
"Multiple matching observer stations were found for observer '{}'. ",
std::string msg = std::format(
"Multiple matching observer stations were found for observer '{}'",
_observerName
);
appendLog(msg, HorizonsDialog::LogLevel::Warning);
msg = fmt::format(
msg = std::format(
"Did not find what you were looking for? Use '@{}' as observer to search "
"for alternatives", _observerName
);
appendLog(msg, HorizonsDialog::LogLevel::Info);
styleLabel(_centerLabel, IsDirty::Yes);
std::vector<std::string> matchingstations =
const std::vector<std::string> matchingstations =
_horizonsFile.parseMatches(
"Observatory Name",
"Multiple matching stations found"
@@ -1043,7 +1054,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
HorizonsDialog::LogLevel::Error
);
if (!_latestHorizonsError.empty()) {
msg = fmt::format("Latest Horizons error: {}", _latestHorizonsError);
msg = std::format("Latest Horizons error: {}", _latestHorizonsError);
appendLog(msg, LogLevel::Error);
}
break;
@@ -1062,13 +1073,13 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
break;
}
case HorizonsResultCode::MultipleObserver: {
std::string msg = fmt::format(
std::string msg = std::format(
"Multiple matches were found for observer '{}'", _observerName
);
appendLog(msg, HorizonsDialog::LogLevel::Warning);
styleLabel(_centerLabel, IsDirty::Yes);
std::vector<std::string> matchingObservers =
const std::vector<std::string> matchingObservers =
_horizonsFile.parseMatches("Name", "matches", ">MATCH NAME<");
if (matchingObservers.empty()) {
appendLog(
@@ -1076,9 +1087,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
HorizonsDialog::LogLevel::Error
);
if (!_latestHorizonsError.empty()) {
msg = fmt::format(
"Latest Horizons error: {}", _latestHorizonsError
);
msg = std::format("Latest Horizons error: {}", _latestHorizonsError);
appendLog(msg, LogLevel::Error);
}
break;
@@ -1097,12 +1106,12 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
break;
}
case HorizonsResultCode::ErrorNoTarget: {
std::string msg = fmt::format(
std::string msg = std::format(
"No match was found for target '{}'", _targetName
);
appendLog(msg, HorizonsDialog::LogLevel::Error);
msg = fmt::format(
msg = std::format(
"Try to use '{}*' as target to search for possible matches", _targetName
);
appendLog(msg, HorizonsDialog::LogLevel::Info);
@@ -1123,13 +1132,13 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
// Format: ID#, Name, Designation, IAU/aliases/other
// Line after data: Number of matches = X. Use ID# to make unique selection.
std::string msg = fmt::format(
std::string msg = std::format(
"Multiple matches were found for target '{}'", _targetName
);
appendLog(msg, HorizonsDialog::LogLevel::Warning);
styleLabel(_targetLabel, IsDirty::Yes);
std::vector<std::string> matchingTargets =
const std::vector<std::string> matchingTargets =
_horizonsFile.parseMatches("Name", "matches", ">MATCH NAME<");
if (matchingTargets.empty()) {
appendLog(
@@ -1137,7 +1146,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
HorizonsDialog::LogLevel::Error
);
if (!_latestHorizonsError.empty()) {
msg = fmt::format("Latest Horizons error: {}", _latestHorizonsError);
msg = std::format("Latest Horizons error: {}", _latestHorizonsError);
appendLog(msg, LogLevel::Error);
}
break;
@@ -1158,7 +1167,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
case HorizonsResultCode::UnknownError: {
appendLog("Unknown error", LogLevel::Error);
if (!_latestHorizonsError.empty()) {
std::string msg = fmt::format(
const std::string msg = std::format(
"Latest Horizons error: {}", _latestHorizonsError
);
appendLog(msg, LogLevel::Error);
@@ -1168,7 +1177,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
}
default: {
if (!_latestHorizonsError.empty()) {
std::string msg = fmt::format(
const std::string msg = std::format(
"Latest Horizons error: {}", _latestHorizonsError
);
appendLog(msg, LogLevel::Error);

View File

@@ -57,9 +57,8 @@ void MarkNodesDialog::createWidgets() {
_list->setDragDropMode(QListView::InternalMove);
_list->setResizeMode(QListView::Adjust);
for (size_t i = 0; i < _markedNodes->size(); ++i) {
QListWidgetItem* item =
new QListWidgetItem(QString::fromStdString(_markedNodes->at(i)));
for (const std::string& nodes : *_markedNodes) {
QListWidgetItem* item = new QListWidgetItem(QString::fromStdString(nodes));
_list->addItem(item);
}
layout->addWidget(_list);
@@ -100,7 +99,6 @@ void MarkNodesDialog::listItemAdded() {
return;
}
std::string itemToAdd = _newNode->text().toStdString();
QListWidgetItem* item = new QListWidgetItem(_newNode->text());
_list->addItem(item);
@@ -113,14 +111,14 @@ void MarkNodesDialog::listItemAdded() {
void MarkNodesDialog::listItemRemove() {
QListWidgetItem* item = _list->currentItem();
int index = _list->row(item);
const int index = _list->row(item);
_list->takeItem(index);
}
void MarkNodesDialog::parseSelections() {
std::vector<std::string> nodes;
for (int i = 0; i < _list->count(); i++) {
QString node = _list->item(i)->text();
const QString node = _list->item(i)->text();
nodes.push_back(node.toStdString());
}
*_markedNodes = std::move(nodes);

View File

@@ -42,6 +42,26 @@ namespace {
.loadedInstruction = std::nullopt,
.notLoadedInstruction = std::nullopt
};
QString createOneLineSummary(Profile::Module m) {
QString summary = QString::fromStdString(m.name);
const bool hasCommandForLoaded = !m.loadedInstruction->empty();
const bool hasCommandForNotLoaded = !m.notLoadedInstruction->empty();
if (hasCommandForLoaded && hasCommandForNotLoaded) {
summary += " (commands set for both loaded & not-loaded conditions)";
}
else if (hasCommandForLoaded) {
summary += " (command set only for loaded condition)";
}
else if (hasCommandForNotLoaded) {
summary += " (command set only for NOT loaded condition)";
}
else {
summary += " (no commands set)";
}
return summary;
}
} // namespace
ModulesDialog::ModulesDialog(QWidget* parent,
@@ -160,29 +180,9 @@ void ModulesDialog::createWidgets() {
}
}
QString ModulesDialog::createOneLineSummary(Profile::Module m) {
QString summary = QString::fromStdString(m.name);
bool hasCommandForLoaded = !m.loadedInstruction->empty();
bool hasCommandForNotLoaded = !m.notLoadedInstruction->empty();
if (hasCommandForLoaded && hasCommandForNotLoaded) {
summary += " (commands set for both loaded & not-loaded conditions)";
}
else if (hasCommandForLoaded) {
summary += " (command set only for loaded condition)";
}
else if (hasCommandForNotLoaded) {
summary += " (command set only for NOT loaded condition)";
}
else {
summary += " (no commands set)";
}
return summary;
}
void ModulesDialog::listItemSelected() {
QListWidgetItem* item = _list->currentItem();
int index = _list->row(item);
const int index = _list->row(item);
if (!_moduleData.empty()) {
const Profile::Module& m = _moduleData[index];
@@ -211,7 +211,7 @@ bool ModulesDialog::isLineEmpty(int index) const {
}
void ModulesDialog::listItemAdded() {
int currentListSize = _list->count();
const int currentListSize = _list->count();
if ((currentListSize == 1) && (isLineEmpty(0))) {
// Special case where list is "empty" but really has one line that is blank.
@@ -259,7 +259,7 @@ void ModulesDialog::listItemSave() {
}
QListWidgetItem* item = _list->currentItem();
int index = _list->row(item);
const int index = _list->row(item);
if (!_moduleData.empty()) {
_moduleData[index].name = _moduleEdit->text().toStdString();
@@ -290,7 +290,7 @@ void ModulesDialog::listItemRemove() {
_list->item(0)->setText("");
}
else {
int index = _list->currentRow();
const int index = _list->currentRow();
if (index >= 0 && index < _list->count()) {
delete _list->takeItem(index);
if (!_moduleData.empty()) {

View File

@@ -51,7 +51,7 @@
using namespace openspace;
namespace {
QString labelText(size_t size, QString title) {
QString labelText(size_t size, const QString& title) {
QString label;
if (size > 0) {
label = title + " (" + QString::number(size) + ")";
@@ -74,14 +74,14 @@ namespace {
const std::vector<Profile::Action>& actions)
{
std::string results;
for (Profile::Keybinding k : keybindings) {
for (const Profile::Keybinding& k : keybindings) {
const auto it = std::find_if(
actions.cbegin(), actions.cend(),
[id = k.action](const Profile::Action& a) { return a.identifier == id; }
);
std::string name = it != actions.end() ? it->name : "Unknown action";
results += fmt::format("{} ({})\n", name, ghoul::to_string(k.key));
results += std::format("{} ({})\n", name, ghoul::to_string(k.key));
}
return results;
}
@@ -89,7 +89,7 @@ namespace {
std::string summarizeProperties(const std::vector<Profile::Property>& properties) {
std::string results;
for (openspace::Profile::Property p : properties) {
results += fmt::format("{} = {}\n", p.name, p.value);
results += std::format("{} = {}\n", p.name, p.value);
}
return results;
}
@@ -368,10 +368,10 @@ void ProfileEdit::duplicateProfile() {
constexpr char Separator = '_';
int version = 0;
if (size_t it = profile.rfind(Separator); it != std::string::npos) {
if (const size_t it = profile.rfind(Separator); it != std::string::npos) {
// If the value exists, we have a profile that potentially already has a version
// number attached to it
std::string versionStr = profile.substr(it + 1);
const std::string versionStr = profile.substr(it + 1);
try {
version = std::stoi(versionStr);
@@ -392,11 +392,11 @@ void ProfileEdit::duplicateProfile() {
while (true) {
version++;
std::string candidate = profile + Separator + std::to_string(version);
std::string candidatePath = _profileBasePath + candidate + ".profile";
const std::string candidate = profile + Separator + std::to_string(version);
const std::string candidatePath = _profileBasePath + candidate + ".profile";
if (!std::filesystem::exists(candidatePath)) {
_profileEdit->setText(QString::fromStdString(std::move(candidate)));
_profileEdit->setText(QString::fromStdString(candidate));
return;
}
}
@@ -489,7 +489,7 @@ void ProfileEdit::approved() {
return;
}
std::filesystem::path p = fmt::format(
const std::filesystem::path p = std::format(
"{}/{}.profile", _builtInProfilesPath, profileName
);
if (std::filesystem::exists(p)) {

View File

@@ -48,6 +48,18 @@ namespace {
"",
""
};
QString createOneLineSummary(const Profile::Property& p) {
QString summary = QString::fromStdString(p.name);
summary += " = ";
summary += QString::fromStdString(p.value);
summary += " (SetPropertyValue";
if (p.setType == Profile::Property::SetType::SetPropertyValueSingle) {
summary += "Single";
}
summary += ")";
return summary;
}
} // namespace
PropertiesDialog::PropertiesDialog(QWidget* parent,
@@ -70,8 +82,8 @@ void PropertiesDialog::createWidgets() {
_list, &QListWidget::itemSelectionChanged,
this, &PropertiesDialog::listItemSelected
);
for (size_t i = 0; i < _propertyData.size(); ++i) {
_list->addItem(new QListWidgetItem(createOneLineSummary(_propertyData[i])));
for (const Profile::Property& property : _propertyData) {
_list->addItem(new QListWidgetItem(createOneLineSummary(property)));
}
layout->addWidget(_list);
}
@@ -168,24 +180,12 @@ void PropertiesDialog::createWidgets() {
}
}
QString PropertiesDialog::createOneLineSummary(Profile::Property p) {
QString summary = QString::fromStdString(p.name);
summary += " = ";
summary += QString::fromStdString(p.value);
summary += " (SetPropertyValue";
if (p.setType == Profile::Property::SetType::SetPropertyValueSingle) {
summary += "Single";
}
summary += ")";
return summary;
}
void PropertiesDialog::listItemSelected() {
QListWidgetItem* item = _list->currentItem();
int index = _list->row(item);
const int index = _list->row(item);
if (!_propertyData.empty()) {
Profile::Property& p = _propertyData[index];
const Profile::Property& p = _propertyData[index];
if (p.setType == Profile::Property::SetType::SetPropertyValueSingle) {
_commandCombo->setCurrentIndex(0);
}
@@ -210,7 +210,7 @@ bool PropertiesDialog::isLineEmpty(int index) {
}
void PropertiesDialog::listItemAdded() {
int currentListSize = _list->count();
const int currentListSize = _list->count();
if ((currentListSize == 1) && (isLineEmpty(0))) {
// Special case where list is "empty" but really has one line that is blank.
@@ -242,7 +242,7 @@ void PropertiesDialog::listItemSave() {
}
QListWidgetItem* item = _list->currentItem();
int index = _list->row(item);
const int index = _list->row(item);
if (!_propertyData.empty()) {
if (_commandCombo->currentIndex() == 0) {
@@ -300,10 +300,10 @@ void PropertiesDialog::listItemRemove() {
_list->item(0)->setText("");
}
else {
int index = _list->currentRow();
const int index = _list->currentRow();
if (index >= 0 && index < _list->count()) {
delete _list->takeItem(index);
if (_propertyData.size() > 0) {
if (!_propertyData.empty()) {
_propertyData.erase(_propertyData.begin() + index);
}
}
@@ -379,7 +379,7 @@ void PropertiesDialog::selectLineFromScriptLog() {
ScriptlogDialog d(this, "openspace.setPropertyValue");
connect(
&d, &ScriptlogDialog::scriptsSelected,
[this](std::vector<std::string> scripts) {
[this](const std::vector<std::string>& scripts) {
for (const std::string& script : scripts) {
listItemAdded();
@@ -392,13 +392,13 @@ void PropertiesDialog::selectLineFromScriptLog() {
// openspace.setPropertyValue('prop', value);
if (text.startsWith("openspace.setPropertyValueSingle")) {
_commandCombo->setCurrentIndex(0);
std::string_view prefix = "openspace.setPropertyValueSingle";
const std::string_view prefix = "openspace.setPropertyValueSingle";
text = text.mid(static_cast<int>(prefix.size()) + 1); // +1 for (
}
else {
// command == "openspace.setPropertyValue"
_commandCombo->setCurrentIndex(1);
std::string_view prefix = "openspace.setPropertyValue";
const std::string_view prefix = "openspace.setPropertyValue";
text = text.mid(static_cast<int>(prefix.size()) + 1); // +1 for (
}
@@ -411,11 +411,10 @@ void PropertiesDialog::selectLineFromScriptLog() {
}
// Remove the string markers around the property
QString property = textList[0].mid(1, textList[0].size() - 2);
const QString property = textList[0].mid(1, textList[0].size() - 2);
textList.removeFirst();
QString value = textList.join(",");
const QString value = textList.join(",");
_propertyEdit->setText(property.trimmed());
_valueEdit->setText(value.trimmed());

View File

@@ -65,7 +65,7 @@ void ScriptlogDialog::createWidgets() {
QGridLayout* layout = new QGridLayout(this);
{
QLabel* heading = new QLabel(QString::fromStdString(fmt::format(
QLabel* heading = new QLabel(QString::fromStdString(std::format(
"Choose commands from \"{}\"", _scriptLogFile
)));
heading->setObjectName("heading");
@@ -76,7 +76,7 @@ void ScriptlogDialog::createWidgets() {
connect(
open, &QPushButton::clicked,
[this, heading]() {
QString file = QFileDialog::getOpenFileName(
const QString file = QFileDialog::getOpenFileName(
this,
"Select log file",
"",
@@ -84,7 +84,7 @@ void ScriptlogDialog::createWidgets() {
);
_scriptLogFile = file.toStdString();
heading->setText(QString::fromStdString(fmt::format(
heading->setText(QString::fromStdString(std::format(
"Choose commands from \"{}\"", _scriptLogFile
)));
loadScriptFile();
@@ -126,7 +126,7 @@ void ScriptlogDialog::createWidgets() {
void ScriptlogDialog::loadScriptFile() {
_scripts.clear();
std::string log = absPath(_scriptLogFile).string();
const std::string log = absPath(_scriptLogFile).string();
QFile file(QString::fromStdString(log));
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&file);
@@ -143,7 +143,7 @@ void ScriptlogDialog::loadScriptFile() {
}
void ScriptlogDialog::updateScriptList() {
std::string filter = _filter->text().toStdString();
const std::string filter = _filter->text().toStdString();
QListWidgetItem* curr = _scriptlogList->currentItem();
std::string selection;
if (curr) {
@@ -152,8 +152,8 @@ void ScriptlogDialog::updateScriptList() {
int index = -1;
_scriptlogList->clear();
for (const std::string& script : _scripts) {
bool foundDynamic = script.find(filter) != std::string::npos;
bool foundStatic =
const bool foundDynamic = script.find(filter) != std::string::npos;
const bool foundStatic =
_fixedFilter.empty() ? true : script.find(_fixedFilter) != std::string::npos;
if (foundDynamic && foundStatic) {
if (script == selection && index == -1) {

View File

@@ -33,7 +33,7 @@
#include <QLabel>
#include <QLineEdit>
#include <QVBoxLayout>
#include <fmt/format.h>
#include <format>
#include <algorithm>
using namespace openspace;
@@ -45,7 +45,7 @@ TimeDialog::TimeDialog(QWidget* parent, std::optional<openspace::Profile::Time>*
setWindowTitle("Time");
createWidgets();
QStringList types = { "Absolute", "Relative" };
const QStringList types = { "Absolute", "Relative" };
_typeCombo->addItems(types);
if (_time->has_value()) {
_timeData = **_time;
@@ -53,7 +53,7 @@ TimeDialog::TimeDialog(QWidget* parent, std::optional<openspace::Profile::Time>*
if (_timeData.value.empty()) {
_timeData.value = "0d";
}
int len = static_cast<int>(_relativeEdit->text().length());
const int len = static_cast<int>(_relativeEdit->text().length());
_relativeEdit->setSelection(0, len);
}
else {
@@ -121,8 +121,8 @@ void TimeDialog::createWidgets() {
}
void TimeDialog::enableAccordingToType(int idx) {
Profile::Time::Type comboIdx = static_cast<Profile::Time::Type>(idx);
bool setFormatForAbsolute = (comboIdx == Profile::Time::Type::Absolute);
const Profile::Time::Type comboIdx = static_cast<Profile::Time::Type>(idx);
const bool setFormatForAbsolute = (comboIdx == Profile::Time::Type::Absolute);
enableFormatForAbsolute(setFormatForAbsolute);
_typeCombo->setCurrentIndex(idx);
if (comboIdx == Profile::Time::Type::Relative) {
@@ -137,9 +137,13 @@ void TimeDialog::enableAccordingToType(int idx) {
}
else {
_relativeEdit->setText("<font color='gray'>Relative Time:</font>");
size_t tIdx = _timeData.value.find_first_of('T', 0);
QString importDate = QString::fromStdString(_timeData.value.substr(0, tIdx));
QString importTime = QString::fromStdString(_timeData.value.substr(tIdx + 1));
const size_t tIdx = _timeData.value.find_first_of('T', 0);
const QString importDate = QString::fromStdString(
_timeData.value.substr(0, tIdx)
);
const QString importTime = QString::fromStdString(
_timeData.value.substr(tIdx + 1)
);
_absoluteEdit->setDate(QDate::fromString(importDate, Qt::DateFormat::ISODate));
_absoluteEdit->setTime(QTime::fromString(importTime));
_relativeEdit->clear();
@@ -171,7 +175,7 @@ void TimeDialog::approved() {
else {
Profile::Time t;
t.type = Profile::Time::Type::Absolute;
t.value = fmt::format(
t.value = std::format(
"{}T{}",
_absoluteEdit->date().toString("yyyy-MM-dd").toStdString(),
_absoluteEdit->time().toString().toStdString()

View File

@@ -35,14 +35,13 @@
#include <QMessageBox>
#include <QPushButton>
SettingsDialog::SettingsDialog(openspace::Settings settings,
QWidget* parent)
SettingsDialog::SettingsDialog(openspace::Settings settings, QWidget* parent)
: QDialog(parent)
, _currentEdit(settings)
, _currentEdit(std::move(settings))
{
setWindowTitle("Settings");
createWidgets();
loadFromSettings(settings);
loadFromSettings(_currentEdit);
// Setting the startup values for the control will have caused the Save button to be
// enabled, so we need to manually disable it again here
@@ -91,7 +90,7 @@ void SettingsDialog::createWidgets() {
_profile,
&QLineEdit::textChanged,
[this]() {
std::string v = _profile->text().toStdString();
const std::string v = _profile->text().toStdString();
if (v.empty()) {
_currentEdit.profile = std::nullopt;
}
@@ -147,7 +146,7 @@ void SettingsDialog::createWidgets() {
_configuration,
&QLineEdit::textChanged,
[this]() {
std::string v = _configuration->text().toStdString();
const std::string v = _configuration->text().toStdString();
if (v.empty()) {
_currentEdit.configuration = std::nullopt;
}
@@ -392,7 +391,7 @@ void SettingsDialog::loadFromSettings(const openspace::Settings& settings) {
if (settings.visibility.has_value()) {
using Visibility = openspace::properties::Property::Visibility;
Visibility vis = *settings.visibility;
const Visibility vis = *settings.visibility;
switch (vis) {
case Visibility::NoviceUser:
_propertyVisibility->setCurrentText("Novice User");
@@ -417,9 +416,9 @@ void SettingsDialog::loadFromSettings(const openspace::Settings& settings) {
}
if (settings.layerServer.has_value()) {
openspace::Configuration::LayerServer server = *settings.layerServer;
Configuration::LayerServer server = *settings.layerServer;
_layerServer->setCurrentText(
QString::fromStdString(openspace::layerServerToString(server))
QString::fromStdString(openspace::layerServerToString(std::move(server)))
);
}

View File

@@ -49,12 +49,12 @@ DisplayWindowUnion::DisplayWindowUnion(const std::vector<QRect>& monitorSizeList
}
void DisplayWindowUnion::createWidgets(int nMaxWindows,
std::vector<QRect> monitorResolutions,
const std::vector<QRect>& monitorResolutions,
std::array<QColor, 4> windowColors,
bool resetToDefault)
{
// Add all window controls (some will be hidden from GUI initially)
for (int i = 0; i < nMaxWindows; ++i) {
for (int i = 0; i < nMaxWindows; i++) {
const int monitorNumForThisWindow =
(monitorResolutions.size() > 1 && i >= 2) ? 1 : 0;
@@ -94,7 +94,7 @@ void DisplayWindowUnion::createWidgets(int nMaxWindows,
layoutMonButton->addStretch(1);
_addWindowButton = new QPushButton("Add Window");
_addWindowButton->setToolTip(QString::fromStdString(fmt::format(
_addWindowButton->setToolTip(QString::fromStdString(std::format(
"Add a window to the configuration (up to {} windows allowed)", nMaxWindows
)));
_addWindowButton->setFocusPolicy(Qt::NoFocus);
@@ -114,7 +114,7 @@ void DisplayWindowUnion::createWidgets(int nMaxWindows,
QBoxLayout* layoutWindows = new QHBoxLayout;
layoutWindows->setContentsMargins(0, 0, 0, 0);
layoutWindows->setSpacing(0);
for (int i = 0; i < nMaxWindows; ++i) {
for (int i = 0; i < nMaxWindows; i++) {
layoutWindows->addWidget(_windowControl[i]);
if (i < (nMaxWindows - 1)) {
QFrame* frameForNextWindow = new QFrame;
@@ -130,7 +130,7 @@ void DisplayWindowUnion::createWidgets(int nMaxWindows,
std::vector<WindowControl*> DisplayWindowUnion::activeWindowControls() const {
std::vector<WindowControl*> res;
res.reserve(_nWindowsDisplayed);
for (unsigned int i = 0; i < _nWindowsDisplayed; ++i) {
for (unsigned int i = 0; i < _nWindowsDisplayed; i++) {
res.push_back(_windowControl[i]);
}
return res;
@@ -160,10 +160,10 @@ unsigned int DisplayWindowUnion::numWindowsDisplayed() const {
}
void DisplayWindowUnion::showWindows() {
for (size_t i = 0; i < _windowControl.size(); ++i) {
for (size_t i = 0; i < _windowControl.size(); i++) {
_windowControl[i]->setVisible(i < _nWindowsDisplayed);
}
for (size_t i = 0; i < _frameBorderLines.size(); ++i) {
for (size_t i = 0; i < _frameBorderLines.size(); i++) {
_frameBorderLines[i]->setVisible(i < (_nWindowsDisplayed - 1));
}
_removeWindowButton->setEnabled(_nWindowsDisplayed > 1);

View File

@@ -27,7 +27,7 @@
#include <QPainter>
namespace {
constexpr float MarginFractionOfWidgetSize = 0.05f;
constexpr float MarginFractionWidgetSize = 0.05f;
constexpr int WindowOpacity = 170;
QRectF computeUnion(const std::vector<QRect>& monitorResolutions) {
@@ -48,15 +48,15 @@ MonitorBox::MonitorBox(QRect widgetDims, const std::vector<QRect>& monitorResolu
{
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
QRectF monitorArrangement = computeUnion(monitorResolutions);
const QRectF monitorArrangement = computeUnion(monitorResolutions);
const float aspectRatio = monitorArrangement.width() / monitorArrangement.height();
if (aspectRatio > 1.0) {
float borderMargin = 2.f * MarginFractionOfWidgetSize * widgetDims.width();
const float borderMargin = 2.f * MarginFractionWidgetSize * widgetDims.width();
widgetDims.setHeight(widgetDims.width() / aspectRatio + borderMargin);
}
else {
float borderMargin = 2.f * MarginFractionOfWidgetSize * widgetDims.height();
const float borderMargin = 2.f * MarginFractionWidgetSize * widgetDims.height();
widgetDims.setWidth(widgetDims.height() * aspectRatio + borderMargin);
}
setFixedSize(widgetDims.width(), widgetDims.height());
@@ -68,7 +68,7 @@ MonitorBox::MonitorBox(QRect widgetDims, const std::vector<QRect>& monitorResolu
computeScaledResolutionLandscape(monitorArrangement, monitorResolutions) :
computeScaledResolutionPortrait(monitorArrangement, monitorResolutions);
for (size_t i = 0; i < monitorResolutions.size(); ++i) {
for (size_t i = 0; i < monitorResolutions.size(); i++) {
_monitorDimensionsScaled.emplace_back(
offsets[i].width(),
offsets[i].height(),
@@ -89,7 +89,7 @@ void MonitorBox::paintEvent(QPaintEvent*) {
//
// Draw window out-of-bounds region(s) first
for (int i = 0; i < _nWindows; ++i) {
for (int i = 0; i < _nWindows; i++) {
painter.setBrush(Qt::BDiagPattern);
painter.setPen(QPen(_colorsForWindows[i], 0));
painter.drawRect(_windowRendering[i]);
@@ -99,7 +99,7 @@ void MonitorBox::paintEvent(QPaintEvent*) {
painter.setPen(QPen(Qt::black, 2));
painter.setBrush(Qt::NoBrush);
for (size_t i = 0; i < _monitorDimensionsScaled.size(); ++i) {
for (size_t i = 0; i < _monitorDimensionsScaled.size(); i++) {
const QColor Grey = QColor(0xDD, 0xDD, 0xDD);
painter.drawRect(_monitorDimensionsScaled[i]);
@@ -107,7 +107,7 @@ void MonitorBox::paintEvent(QPaintEvent*) {
if (_monitorDimensionsScaled.size() > 1 && i == 0) {
// We only want to render the "Primary" if there are multiple windows
QPointF textPos = QPointF(
const QPointF textPos = QPointF(
_monitorDimensionsScaled[i].left() + 4.0,
_monitorDimensionsScaled[i].top() + 24.0
);
@@ -120,7 +120,7 @@ void MonitorBox::paintEvent(QPaintEvent*) {
// Draw window number(s) first for darker contrast, then window(s) over both
// out-of-bounds and monitors
for (int i = 0; i < _nWindows; ++i) {
for (int i = 0; i < _nWindows; i++) {
QPointF p = QPointF(
_windowRendering[i].left() + 5.0,
_windowRendering[i].bottom() - 5.0
@@ -132,7 +132,7 @@ void MonitorBox::paintEvent(QPaintEvent*) {
//
// Paint window
for (int i = 0; i < _nWindows; ++i) {
for (int i = 0; i < _nWindows; i++) {
painter.setPen(QPen(_colorsForWindows[i], 1));
painter.drawRect(_windowRendering[i]);
@@ -159,16 +159,16 @@ std::vector<QSizeF> MonitorBox::computeScaledResolutionLandscape(QRectF arrangem
{
std::vector<QSizeF> offsets;
float marginWidget = size().width() * MarginFractionOfWidgetSize;
float virtualWidth = size().width() * (1.f - MarginFractionOfWidgetSize * 2.f);
const float margin = size().width() * MarginFractionWidgetSize;
const float virtualWidth = size().width() * (1.f - MarginFractionWidgetSize * 2.f);
_monitorScaleFactor = virtualWidth / arrangement.width();
const float aspectRatio = arrangement.width() / arrangement.height();
const float newHeight = virtualWidth / aspectRatio;
for (const QRect& res : resolutions) {
float x = marginWidget + (res.x() - arrangement.x()) * _monitorScaleFactor;
float y = marginWidget + (size().height() - newHeight - marginWidget) / 4.f +
const float x = margin + (res.x() - arrangement.x()) * _monitorScaleFactor;
const float y = margin + (size().height() - newHeight - margin) / 4.f +
(res.y() - arrangement.y()) * _monitorScaleFactor;
offsets.emplace_back(x, y);
}
@@ -181,17 +181,17 @@ std::vector<QSizeF> MonitorBox::computeScaledResolutionPortrait(QRectF arrangeme
{
std::vector<QSizeF> offsets;
float marginWidget = size().height() * MarginFractionOfWidgetSize;
float virtualHeight = size().height() * (1.f - MarginFractionOfWidgetSize * 2.f);
const float marginWidget = size().height() * MarginFractionWidgetSize;
const float virtualHeight = size().height() * (1.f - MarginFractionWidgetSize * 2.f);
_monitorScaleFactor = virtualHeight / arrangement.height();
const float aspectRatio = arrangement.width() / arrangement.height();
const float newWidth = virtualHeight * aspectRatio;
for (const QRect& res : resolutions) {
float x = marginWidget + (size().width() - newWidth - marginWidget) / 4.f +
const float x = marginWidget + (size().width() - newWidth - marginWidget) / 4.f +
(res.x() - arrangement.x()) * _monitorScaleFactor;
float y = marginWidget + (res.y() - arrangement.y()) * _monitorScaleFactor;
const float y = marginWidget + (res.y() - arrangement.y()) * _monitorScaleFactor;
offsets.emplace_back(x, y);
}

View File

@@ -39,7 +39,7 @@ OrientationDialog::OrientationDialog(sgct::quat& orientation, QWidget* parent)
QGridLayout* layoutWindow = new QGridLayout(this);
{
QString pitchTip = "Pitch or elevation: negative numbers tilt the camera "
const QString pitchTip = "Pitch or elevation: negative numbers tilt the camera "
"downwards; positive numbers tilt upwards.\nThe allowed range is [-90, 90]. "
"Internally, this corresponds to the x value in the quaternion";
@@ -56,9 +56,9 @@ OrientationDialog::OrientationDialog(sgct::quat& orientation, QWidget* parent)
layoutWindow->addWidget(_linePitch, 0, 1);
}
{
QString rollTip = "Roll or bank: negative numbers rotate the camera counter-"
"clockwise; positive numbers clockwise.\nThe allowed range is [-180, 180]. "
"Internally, this corresponds to the z value in the quaternion";
const QString rollTip = "Roll or bank: negative numbers rotate the camera "
"counter-clockwise; positive numbers clockwise.\nThe allowed range is "
"[-180, 180]. Internally, this corresponds to the z value in the quaternion";
QLabel* labelRoll = new QLabel("Roll");
labelRoll->setToolTip(rollTip);
@@ -73,9 +73,10 @@ OrientationDialog::OrientationDialog(sgct::quat& orientation, QWidget* parent)
layoutWindow->addWidget(_lineRoll, 1, 1);
}
{
QString yawTip = "Yaw, heading, or azimuth: negative numbers pan the camera "
"to the left; positive numbers pan to the\nright. The allowed range is "
"[-360, 360]. Internally, this corresponds to the y value in the quaternion";
const QString yawTip = "Yaw, heading, or azimuth: negative numbers pan the "
"camera to the left; positive numbers pan to the\nright. The allowed range "
"is [-360, 360]. Internally, this corresponds to the y value in the "
"quaternion";
QLabel* labelYaw = new QLabel;
labelYaw ->setText("Yaw");

View File

@@ -32,13 +32,15 @@
SettingsWidget::SettingsWidget(sgct::quat orientation, QWidget* parent)
: QWidget(parent)
, _orientationValue(std::move(orientation))
, _firstWindowGraphicsSelection(new QComboBox)
, _firstWindowSelectionLayout(new QHBoxLayout)
,_showUiOnFirstWindow(new QCheckBox(
"Show user interface only on first window using graphics:"
))
{
QBoxLayout* layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
_showUiOnFirstWindow = new QCheckBox(
"Show user interface only on first window using graphics:"
);
_showUiOnFirstWindow->setChecked(false);
_showUiOnFirstWindow->setEnabled(false);
_showUiOnFirstWindow->setToolTip(
@@ -48,9 +50,6 @@ SettingsWidget::SettingsWidget(sgct::quat orientation, QWidget* parent)
"not show the user interface"
);
_firstWindowSelectionLayout = new QHBoxLayout;
_firstWindowGraphicsSelection = new QComboBox();
_firstWindowGraphicsSelection->setToolTip(
"Select the contents of the first window to match one of the other windows"
);
@@ -127,7 +126,7 @@ void SettingsWidget::nWindowsDisplayedChanged(int newCount) {
graphicsSelect = std::max(0, graphicsSelect);
QList<QString> graphicsOptions = {"None (GUI only)"};
for (int i = CountOneWindow; i <= newCount; ++i) {
for (int i = CountOneWindow; i <= newCount; i++) {
graphicsOptions.append("Window " + QString::number(i));
}
_firstWindowGraphicsSelection->clear();

View File

@@ -78,20 +78,20 @@ SgctEdit::SgctEdit(QWidget* parent, std::string userConfigPath)
createWidgets(createMonitorInfoSet(), 1, true);
}
SgctEdit::SgctEdit(sgct::config::Cluster& cluster, const std::string& configName,
SgctEdit::SgctEdit(sgct::config::Cluster& cluster, std::string configName,
std::string& configBasePath, QWidget* parent)
: QDialog(parent)
, _cluster(cluster)
, _userConfigPath(configBasePath)
, _configurationFilename(configName)
, _configurationFilename(std::move(configName))
, _didImportValues(true)
{
setWindowTitle("Window Configuration Editor");
size_t nWindows = _cluster.nodes.front().windows.size();
const size_t nWindows = _cluster.nodes.front().windows.size();
std::vector<QRect> monitorSizes = createMonitorInfoSet();
createWidgets(monitorSizes, static_cast<unsigned int>(nWindows), false);
size_t existingWindowsControlSize = _displayWidget->windowControls().size();
for (size_t i = 0; i < nWindows; ++i) {
const size_t existingWindowsControlSize = _displayWidget->windowControls().size();
for (size_t i = 0; i < nWindows; i++) {
sgct::config::Window& w = _cluster.nodes.front().windows[i];
WindowControl* wCtrl = _displayWidget->windowControls()[i];
if (i < existingWindowsControlSize && wCtrl) {
@@ -116,12 +116,7 @@ SgctEdit::SgctEdit(sgct::config::Cluster& cluster, const std::string& configName
posY -= monitorSizes[monitorNum].y();
}
}
QRectF newDims(
posX,
posY,
w.size.x,
w.size.y
);
const QRectF newDims = QRectF(posX, posY, w.size.x, w.size.y);
wCtrl->setDimensions(newDims);
if (w.name.has_value()) {
wCtrl->setWindowName(w.name.value());
@@ -144,7 +139,7 @@ void SgctEdit::setupStateOfUiOnFirstWindow(size_t nWindows) {
int nGuiRenderTagsFound = 0;
_settingsWidget->nWindowsDisplayedChanged(static_cast<int>(nWindows));
for (size_t i = 0; i < nWindows; ++i) {
for (size_t i = 0; i < nWindows; i++) {
sgct::config::Window& w = _cluster.nodes.front().windows[i];
//First window needs to have "GUI" tag if this mode is set
if (i == 0) {
@@ -156,9 +151,8 @@ void SgctEdit::setupStateOfUiOnFirstWindow(size_t nWindows) {
nGuiRenderTagsFound++;
}
for (int winNum = 0; winNum <= 4; ++winNum) {
std::string tagToLookFor = "GUI_Render_Win" + std::to_string(winNum);
if (std::find(w.tags.begin(), w.tags.end(), tagToLookFor) != w.tags.end())
{
const std::string searchTag = "GUI_Render_Win" + std::to_string(winNum);
if (std::find(w.tags.begin(), w.tags.end(), searchTag) != w.tags.end()) {
graphicsSelectionForFirstWindow = winNum;
nGuiRenderTagsFound++;
}
@@ -195,8 +189,8 @@ void SgctEdit::setupStateOfUiOnFirstWindow(size_t nWindows) {
void SgctEdit::setupProjectionTypeInGui(sgct::config::Viewport& vPort,
WindowControl* wCtrl)
{
std::visit(overloaded{
[&](sgct::config::CylindricalProjection p) {
std::visit(overloaded {
[&](const sgct::config::CylindricalProjection& p) {
if (p.quality && p.heightOffset) {
wCtrl->setProjectionCylindrical(
*p.quality,
@@ -204,7 +198,7 @@ void SgctEdit::setupProjectionTypeInGui(sgct::config::Viewport& vPort,
);
}
},
[&](sgct::config::EquirectangularProjection p) {
[&](const sgct::config::EquirectangularProjection& p) {
if (p.quality) {
wCtrl->setProjectionEquirectangular(
*p.quality,
@@ -212,7 +206,7 @@ void SgctEdit::setupProjectionTypeInGui(sgct::config::Viewport& vPort,
);
}
},
[&](sgct::config::FisheyeProjection p) {
[&](const sgct::config::FisheyeProjection& p) {
if (p.quality) {
wCtrl->setProjectionFisheye(
*p.quality,
@@ -220,20 +214,20 @@ void SgctEdit::setupProjectionTypeInGui(sgct::config::Viewport& vPort,
);
}
},
[&](sgct::config::PlanarProjection p) {
[&](const sgct::config::PlanarProjection& p) {
wCtrl->setProjectionPlanar(
(std::abs(p.fov.left) + std::abs(p.fov.right)),
(std::abs(p.fov.up) + std::abs(p.fov.down))
);
},
[&](sgct::config::SphericalMirrorProjection p) {
[&](const sgct::config::SphericalMirrorProjection& p) {
if (p.quality) {
wCtrl->setProjectionSphericalMirror(
*p.quality
);
}
},
[&](sgct::config::SpoutOutputProjection p) {
[&](const sgct::config::SpoutOutputProjection& p) {
if (p.quality) {
if (p.mapping ==
sgct::config::SpoutOutputProjection::Mapping::Equirectangular)
@@ -253,21 +247,21 @@ void SgctEdit::setupProjectionTypeInGui(sgct::config::Viewport& vPort,
}
}
},
[&](sgct::config::NoProjection) {},
[&](sgct::config::ProjectionPlane) {},
[&](sgct::config::SpoutFlatProjection) {}
[&](const sgct::config::NoProjection&) {},
[&](const sgct::config::ProjectionPlane&) {},
[&](const sgct::config::SpoutFlatProjection&) {}
}, vPort.projection);
}
std::vector<QRect> SgctEdit::createMonitorInfoSet() {
QList<QScreen*> screens = qApp->screens();
int nScreensManaged = std::min(static_cast<int>(screens.length()), 4);
const QList<QScreen*> screens = qApp->screens();
const int nScreensManaged = std::min(static_cast<int>(screens.length()), 4);
std::vector<QRect> monitorSizes;
for (int s = 0; s < nScreensManaged; ++s) {
QSize size = screens[s]->size();
QRect geometry = screens[s]->availableGeometry();
int actualWidth = std::max(size.width(), geometry.width());
int actualHeight = std::max(size.height(), geometry.height());
const QSize size = screens[s]->size();
const QRect geometry = screens[s]->availableGeometry();
const int actualWidth = std::max(size.width(), geometry.width());
const int actualHeight = std::max(size.height(), geometry.height());
monitorSizes.emplace_back(
geometry.x(),
geometry.y(),
@@ -318,7 +312,7 @@ void SgctEdit::createWidgets(const std::vector<QRect>& monitorSizes,
monitorBox, &MonitorBox::nWindowsDisplayedChanged
);
for (unsigned int i = 0; i < nWindows; ++i) {
for (unsigned int i = 0; i < nWindows; i++) {
_displayWidget->addWindow();
}
@@ -394,7 +388,7 @@ std::filesystem::path SgctEdit::saveFilename() const {
void SgctEdit::save() {
generateConfiguration();
if (hasWindowIssues(_cluster)) {
int ret = QMessageBox::warning(
const int ret = QMessageBox::warning(
this,
"Window Sizes Incompatible",
"Window sizes for multiple windows have to be strictly ordered, meaning that "
@@ -414,7 +408,7 @@ void SgctEdit::save() {
accept();
}
else {
QString fileName = QFileDialog::getSaveFileName(
const QString fileName = QFileDialog::getSaveFileName(
this,
"Save Window Configuration File",
QString::fromStdString(_userConfigPath),
@@ -435,7 +429,7 @@ void SgctEdit::save() {
void SgctEdit::apply() {
generateConfiguration();
if (hasWindowIssues(_cluster)) {
int ret = QMessageBox::warning(
const int ret = QMessageBox::warning(
this,
"Window Sizes Incompatible",
"Window sizes for multiple windows have to be strictly ordered, meaning that "
@@ -466,7 +460,7 @@ void SgctEdit::generateConfiguration() {
_cluster.scene = sgct::config::Scene();
_cluster.scene->orientation = _settingsWidget->orientation();
if (_cluster.nodes.empty()) {
_cluster.nodes.push_back(sgct::config::Node());
_cluster.nodes.emplace_back();
}
sgct::config::Node& node = _cluster.nodes.back();
@@ -515,12 +509,10 @@ void SgctEdit::generateConfigResizeWindowsAccordingToSelected(sgct::config::Node
std::vector<WindowControl*> windowControls = _displayWidget->activeWindowControls();
for (size_t wIdx = 0; wIdx < windowControls.size(); ++wIdx) {
if (node.windows.size() <= wIdx) {
node.windows.push_back(sgct::config::Window());
node.windows.emplace_back();
}
if (windowControls[wIdx]) {
windowControls[wIdx]->generateWindowInformation(
node.windows[wIdx]
);
windowControls[wIdx]->generateWindowInformation(node.windows[wIdx]);
}
}
while (node.windows.size() > windowControls.size()) {
@@ -529,7 +521,7 @@ void SgctEdit::generateConfigResizeWindowsAccordingToSelected(sgct::config::Node
}
void SgctEdit::generateConfigIndividualWindowSettings(sgct::config::Node& node) {
for (size_t i = 0; i < node.windows.size(); ++i) {
for (size_t i = 0; i < node.windows.size(); i++) {
// First apply default settings to each window...
node.windows[i].id = static_cast<int>(i);
node.windows[i].draw2D = true;
@@ -540,20 +532,21 @@ void SgctEdit::generateConfigIndividualWindowSettings(sgct::config::Node& node)
// depending on if this is the first window or not
if (_settingsWidget->showUiOnFirstWindow()) {
if (i == 0) {
node.windows[i].tags.push_back("GUI");
int selectedGraphics =
node.windows[i].tags.emplace_back("GUI");
const int selectedGraphics =
_settingsWidget->graphicsSelectionForShowUiOnFirstWindow();
if (selectedGraphics == 0) {
node.windows[i].viewports.back().isTracked = false;
node.windows[i].tags.push_back("GUI_No_Render");
node.windows[i].tags.emplace_back("GUI_No_Render");
}
else if (selectedGraphics > 0 &&
selectedGraphics <= static_cast<int>(node.windows.size()))
{
node.windows[i].tags.push_back("GUI_Render_Win" +
std::to_string(selectedGraphics));
//Set first window viewport to mirror the selected window's viewport
node.windows[i].tags.emplace_back(
"GUI_Render_Win" + std::to_string(selectedGraphics)
);
// Set first window viewport to mirror the selected window's viewport
node.windows[i].viewports =
node.windows[(selectedGraphics - 1)].viewports;
}
@@ -577,7 +570,7 @@ void SgctEdit::deleteFromTags(sgct::config::Window& window) {
"GUI_Render_Win3",
"GUI_Render_Win4"
};
for (std::string_view tag : Tags) {
for (const std::string_view tag : Tags) {
window.tags.erase(
std::remove(window.tags.begin(), window.tags.end(), tag),
window.tags.end()
@@ -590,12 +583,12 @@ sgct::config::Cluster SgctEdit::cluster() const {
}
void SgctEdit::firstWindowGraphicsSelectionChanged(const QString&) {
if (!_settingsWidget)
if (!_settingsWidget) {
return;
int newSetting = _settingsWidget->graphicsSelectionForShowUiOnFirstWindow();
}
if (_settingsWidget->showUiOnFirstWindow()) {
const int newSetting = _settingsWidget->graphicsSelectionForShowUiOnFirstWindow();
_displayWidget->activeWindowControls()[0]->setVisibilityOfProjectionGui(
newSetting == 1
);

View File

@@ -50,7 +50,7 @@ namespace {
"8K (8192)", "16K (16384)", "32K (32768)", "64K (65536)"
};
constexpr int QualityValues[nQualityTypes] = {
constexpr std::array<int, nQualityTypes> QualityValues = {
256, 512, 1024, 1536, 2048, 4096, 8192, 16384, 32768, 65536
};
@@ -76,7 +76,7 @@ namespace {
QList<QString> monitorNames(const std::vector<QRect>& resolutions) {
QList<QString> monitorNames;
for (size_t i = 0; i < resolutions.size(); i++) {
std::string fullName = fmt::format(
const std::string fullName = std::format(
"{} ({}x{})",
MonitorNames[i], resolutions[i].width(), resolutions[i].height()
);
@@ -116,19 +116,19 @@ void WindowControl::createWidgets(const QColor& windowColor) {
// *----------*----------*-------*----------*-------*--------*-------*-------*
QGridLayout* layout = new QGridLayout(this);
QMargins margins = layout->contentsMargins();
const QMargins margins = layout->contentsMargins();
layout->setContentsMargins(margins.left(), 0, margins.right(), 0);
layout->setColumnStretch(6, 1);
layout->setRowStretch(8, 1);
_windowNumber = new QLabel("Window " + QString::number(_windowIndex + 1));
_windowNumber->setStyleSheet(QString::fromStdString(fmt::format(
_windowNumber->setStyleSheet(QString::fromStdString(std::format(
"QLabel {{ color : #{:02x}{:02x}{:02x}; }}",
windowColor.red(), windowColor.green(), windowColor.blue()
)));
layout->addWidget(_windowNumber, 0, 0, 1, 8, Qt::AlignCenter);
{
QString tip = "The name for the window (displayed in title bar)";
const QString tip = "The name for the window (displayed in title bar)";
QLabel* labelName = new QLabel("Name");
labelName->setToolTip(tip);
@@ -138,7 +138,7 @@ void WindowControl::createWidgets(const QColor& windowColor) {
_windowName->setToolTip(tip);
layout->addWidget(_windowName, 1, 1, 1, 7);
}
QString tip = "The monitor where this window is located";
const QString tip = "The monitor where this window is located";
_monitor = new QComboBox;
_monitor->addItems(monitorNames(_monitorResolutions));
@@ -370,7 +370,8 @@ QWidget* WindowControl::createPlanarWidget() {
layout->addWidget(_planar.labelInfo, 0, 0, 1, 3);
_planar.labelFovH = new QLabel("Horizontal FOV");
QString hfovTip = "The total horizontal field of view of the viewport (degrees)";
const QString hfovTip =
"The total horizontal field of view of the viewport (degrees)";
_planar.labelFovH->setToolTip(hfovTip);
layout->addWidget(_planar.labelFovH, 1, 0);
@@ -387,7 +388,7 @@ QWidget* WindowControl::createPlanarWidget() {
layout->addWidget(_planar.fovH, 1, 1);
_planar.labelFovV = new QLabel("Vertical FOV");
QString vfovTip = "The total vertical field of view of the viewport (degrees). "
const QString vfovTip = "The total vertical field of view of the viewport (degrees). "
"Internally,\nthe values for 'up' & 'down' will each be half this value";
_planar.labelFovV->setToolTip(vfovTip);
layout->addWidget(_planar.labelFovV, 2, 0);
@@ -445,9 +446,9 @@ QWidget* WindowControl::createFisheyeWidget() {
layout->addWidget(_fisheye.labelInfo, 0, 0, 1, 2);
_fisheye.labelQuality = new QLabel("Quality");
QString qualityTip = "Determines the pixel resolution of the projection rendering. "
"The higher resolution,\nthe better the rendering quality, but at the expense of "
"increased rendering times";
const QString qualityTip = "Determines the pixel resolution of the projection "
"rendering. The higher resolution,\nthe better the rendering quality, but at the "
"expense of increased rendering times";
_fisheye.labelQuality->setToolTip(qualityTip);
layout->addWidget(_fisheye.labelQuality, 1, 0);
@@ -490,9 +491,9 @@ QWidget* WindowControl::createSphericalMirrorWidget() {
layout->addWidget(_sphericalMirror.labelInfo, 0, 0, 1, 2);
_sphericalMirror.labelQuality = new QLabel("Quality");
QString qualityTip = "Determines the pixel resolution of the projection rendering. "
"The higher resolution,\nthe better the rendering quality, but at the expense of "
"increased rendering times";
const QString qualityTip = "Determines the pixel resolution of the projection "
"rendering. The higher resolution,\nthe better the rendering quality, but at the "
"expense of increased rendering times";
_sphericalMirror.labelQuality->setToolTip(qualityTip);
layout->addWidget(_sphericalMirror.labelQuality, 1, 0);
@@ -527,9 +528,9 @@ QWidget* WindowControl::createCylindricalWidget() {
layout->addWidget(_cylindrical.labelInfo, 0, 0, 1, 2);
_cylindrical.labelQuality = new QLabel("Quality");
QString qualityTip = "Determines the pixel resolution of the projection rendering. "
"The higher resolution,\nthe better the rendering quality, but at the expense of "
"increased rendering times";
const QString qualityTip = "Determines the pixel resolution of the projection "
"rendering. The higher resolution,\nthe better the rendering quality, but at the "
"expense of increased rendering times";
_cylindrical.labelQuality->setToolTip(qualityTip);
layout->addWidget(_cylindrical.labelQuality, 1, 0);
@@ -540,10 +541,10 @@ QWidget* WindowControl::createCylindricalWidget() {
layout->addWidget(_cylindrical.quality, 1, 1);
_cylindrical.labelHeightOffset = new QLabel("Height Offset");
QString heightTip = "Offsets the height from which the cylindrical projection is "
"generated.\nThis is, in general, only necessary if the user position is offset "
"and\ncountering that offset is desired in order to continue producing\na "
"'standard' cylindrical projection";
const QString heightTip = "Offsets the height from which the cylindrical projection "
"is generated.\nThis is, in general, only necessary if the user position is "
"offset and\ncountering that offset is desired in order to continue producing\n"
"a 'standard' cylindrical projection";
_cylindrical.labelHeightOffset->setToolTip(heightTip);
layout->addWidget(_cylindrical.labelHeightOffset, 2, 0);
@@ -580,9 +581,9 @@ QWidget* WindowControl::createEquirectangularWidget() {
layout->addWidget(_equirectangular.labelInfo, 0, 0, 1, 2);
_equirectangular.labelQuality = new QLabel("Quality");
QString qualityTip = "Determines the pixel resolution of the projection rendering. "
"The higher resolution,\nthe better the rendering quality, but at the expense of "
"increased rendering times";
const QString qualityTip = "Determines the pixel resolution of the projection "
"rendering. The higher resolution,\nthe better the rendering quality, but at the "
"expense of increased rendering times";
_equirectangular.labelQuality->setToolTip(qualityTip);
layout->addWidget(_equirectangular.labelQuality, 1, 0);
@@ -613,9 +614,9 @@ void WindowControl::resetToDefaults() {
_windowDimensions = DefaultWindowSizes[_windowIndex];
_offsetX->setValue(_windowDimensions.x());
_offsetY->setValue(_windowDimensions.y());
float newHeight =
const float newHeight =
_monitorResolutions[PrimaryMonitorIdx].height() * IdealScaleVerticalLines;
float newWidth = newHeight * IdealAspectRatio;
const float newWidth = newHeight * IdealAspectRatio;
_windowDimensions.setHeight(newHeight);
_windowDimensions.setWidth(newWidth);
_sizeX->setValue(static_cast<int>(newWidth));
@@ -666,7 +667,7 @@ void WindowControl::setDecorationState(bool hasWindowDecoration) {
}
sgct::config::Projections WindowControl::generateProjectionInformation() const {
ProjectionIndices type =
const ProjectionIndices type =
static_cast<WindowControl::ProjectionIndices>(_projectionType->currentIndex());
const bool isSpoutFisheye =
@@ -745,7 +746,7 @@ sgct::config::Projections WindowControl::generateProjectionInformation() const {
void WindowControl::generateWindowInformation(sgct::config::Window& window) const {
window.size = { _sizeX->text().toInt(), _sizeY->text().toInt() };
window.monitor = _monitor->currentIndex();
QRect resolution = _monitorResolutions[_monitor->currentIndex()];
const QRect resolution = _monitorResolutions[_monitor->currentIndex()];
window.pos = sgct::ivec2(
resolution.x() + _offsetX->text().toInt(),
resolution.y() + _offsetY->text().toInt()
@@ -839,7 +840,7 @@ void WindowControl::setQualityComboBoxFromLinesResolution(int lines, QComboBox*
void WindowControl::onSizeXChanged(int newValue) {
_windowDimensions.setWidth(newValue);
if (_aspectRatioLocked) {
int updatedHeight = _windowDimensions.width() / _aspectRatioSize;
const int updatedHeight = _windowDimensions.width() / _aspectRatioSize;
_sizeY->blockSignals(true);
_sizeY->setValue(updatedHeight);
_sizeY->blockSignals(false);
@@ -854,7 +855,7 @@ void WindowControl::onSizeXChanged(int newValue) {
void WindowControl::onSizeYChanged(int newValue) {
_windowDimensions.setHeight(newValue);
if (_aspectRatioLocked) {
int updatedWidth = _windowDimensions.height() * _aspectRatioSize;
const int updatedWidth = _windowDimensions.height() * _aspectRatioSize;
_sizeX->blockSignals(true);
_sizeX->setValue(updatedWidth);
_sizeX->blockSignals(false);
@@ -867,21 +868,21 @@ void WindowControl::onSizeYChanged(int newValue) {
}
void WindowControl::onOffsetXChanged(int newValue) {
float prevWidth = _windowDimensions.width();
const float prevWidth = _windowDimensions.width();
_windowDimensions.setX(newValue);
_windowDimensions.setWidth(prevWidth);
emit windowChanged(_monitor->currentIndex(), _windowIndex, _windowDimensions);
}
void WindowControl::onOffsetYChanged(int newValue) {
float prevHeight = _windowDimensions.height();
const float prevHeight = _windowDimensions.height();
_windowDimensions.setY(newValue);
_windowDimensions.setHeight(prevHeight);
emit windowChanged(_monitor->currentIndex(), _windowIndex, _windowDimensions);
}
void WindowControl::onFullscreenClicked() {
QRect resolution = _monitorResolutions[_monitor->currentIndex()];
const QRect resolution = _monitorResolutions[_monitor->currentIndex()];
_offsetX->setValue(0);
_offsetY->setValue(0);
@@ -890,8 +891,8 @@ void WindowControl::onFullscreenClicked() {
_windowDecoration->setChecked(false);
}
void WindowControl::onProjectionChanged(int newSelection) {
ProjectionIndices selected = static_cast<ProjectionIndices>(newSelection);
void WindowControl::onProjectionChanged(int newSelection) const {
const ProjectionIndices selected = static_cast<ProjectionIndices>(newSelection);
_planar.widget->setVisible(selected == ProjectionIndices::Planar);
_fisheye.widget->setVisible(selected == ProjectionIndices::Fisheye);
_sphericalMirror.widget->setVisible(selected == ProjectionIndices::SphericalMirror);
@@ -921,8 +922,9 @@ void WindowControl::onFovLockClicked() {
}
void WindowControl::updatePlanarLockedFov() {
bool landscapeOrientation = (_windowDimensions.width() >= _windowDimensions.height());
float aspectRatio;
const bool landscapeOrientation =
(_windowDimensions.width() >= _windowDimensions.height());
float aspectRatio = 0.f;
if (landscapeOrientation) {
aspectRatio = _windowDimensions.width() / _windowDimensions.height();
}
@@ -930,7 +932,7 @@ void WindowControl::updatePlanarLockedFov() {
aspectRatio = _windowDimensions.height() / _windowDimensions.width();
}
float adjustedFov = 2.f * atan(aspectRatio * tan(DefaultFovShortEdge
float adjustedFov = 2.f * std::atan(aspectRatio * std::tan(DefaultFovShortEdge
* std::numbers::pi_v<float> / 180.f / 2.f));
// Convert to degrees and limit to 180°
adjustedFov *= 180.f / std::numbers::pi_v<float>;

View File

@@ -140,7 +140,7 @@ LONG WINAPI generateMiniDump(EXCEPTION_POINTERS* exceptionPointers) {
LINFO(s);
}
std::string dumpFile = fmt::format(
std::string dumpFile = std::format(
"OpenSpace_{}_{}_{}-{}-{}-{}-{}-{}-{}--{}--{}.dmp",
OPENSPACE_VERSION_MAJOR,
OPENSPACE_VERSION_MINOR,
@@ -155,7 +155,7 @@ LONG WINAPI generateMiniDump(EXCEPTION_POINTERS* exceptionPointers) {
GetCurrentThreadId()
);
LINFO(fmt::format("Creating dump file: {}", dumpFile));
LINFO(std::format("Creating dump file: {}", dumpFile));
HANDLE hDumpFile = CreateFileA(
dumpFile.c_str(),
@@ -198,12 +198,12 @@ LONG WINAPI generateMiniDump(EXCEPTION_POINTERS* exceptionPointers) {
void checkJoystickStatus() {
using namespace interaction;
for (int i = GLFW_JOYSTICK_1; i <= GLFW_JOYSTICK_LAST; ++i) {
for (int i = GLFW_JOYSTICK_1; i <= GLFW_JOYSTICK_LAST; i++) {
ZoneScopedN("Joystick state");
JoystickInputState& state = global::joystickInputStates->at(i);
int present = glfwJoystickPresent(i);
const int present = glfwJoystickPresent(i);
if (present == GLFW_FALSE) {
state.isConnected = false;
continue;
@@ -228,7 +228,7 @@ void checkJoystickStatus() {
std::memcpy(state.axes.data(), axes, state.nAxes * sizeof(float));
const unsigned char* buttons = glfwGetJoystickButtons(i, &state.nButtons);
for (int j = 0; j < state.nButtons; ++j) {
for (int j = 0; j < state.nButtons; j++) {
const bool currentlyPressed = buttons[j] == GLFW_PRESS;
if (currentlyPressed) {
@@ -282,8 +282,8 @@ void mainInitFunc(GLFWwindow*) {
// We save the startup value of the screenshots just in case we want to add a date
// to them later in the RenderEngine
std::filesystem::path screenshotPath = absPath("${SCREENSHOTS}");
FileSys.registerPathToken("${STARTUP_SCREENSHOT}", screenshotPath);
sgct::Settings::instance().setCapturePath(screenshotPath.string());
FileSys.registerPathToken("${STARTUP_SCREENSHOT}", std::move(screenshotPath));
LDEBUG("Initializing OpenSpace Engine started");
global::openSpaceEngine->initialize();
@@ -292,22 +292,22 @@ void mainInitFunc(GLFWwindow*) {
#ifndef __APPLE__
// Apparently: "Cocoa: Regular windows do not have icons on macOS"
{
std::filesystem::path path = absPath("${DATA}/openspace-icon.png");
int x;
int y;
int n;
const std::filesystem::path path = absPath("${DATA}/openspace-icon.png");
int x = 0;
int y = 0;
int n = 0;
unsigned char* data = stbi_load(path.string().c_str(), &x, &y, &n, 0);
GLFWimage icons[1];
icons[0].pixels = data;
icons[0].width = x;
icons[0].height = y;
GLFWimage icon;
icon.pixels = data;
icon.width = x;
icon.height = y;
for (const std::unique_ptr<Window>& window : Engine::instance().windows()) {
glfwSetWindowIcon(window->windowHandle(), 1, icons);
glfwSetWindowIcon(window->windowHandle(), 1, &icon);
}
stbi_image_free(icons[0].pixels);
stbi_image_free(icon.pixels);
}
#endif // __APPLE__
@@ -340,8 +340,8 @@ void mainInitFunc(GLFWwindow*) {
}
}
for (size_t i = 0; i < Engine::instance().windows().size(); ++i) {
Window& window = *Engine::instance().windows()[i];
for (size_t i = 0; i < Engine::instance().windows().size(); i++) {
const Window& window = *Engine::instance().windows()[i];
if (!window.hasTag(SpoutTag)) {
continue;
}
@@ -438,11 +438,7 @@ void mainRenderFunc(const sgct::RenderData& data) {
currentDrawResolution = glm::ivec2(data.bufferSize.x, data.bufferSize.y);
glm::vec3 pos;
std::memcpy(
glm::value_ptr(pos),
&Engine::instance().defaultUser().posMono().x,
sizeof(vec3)
);
std::memcpy(glm::value_ptr(pos), &Engine::defaultUser().posMono().x, sizeof(vec3));
glm::mat4 viewMatrix;
std::memcpy(
@@ -620,14 +616,11 @@ void mainCharCallback(unsigned int codepoint, int modifiers, sgct::Window* windo
void mainDropCallback(int amount, const char** paths) {
void mainDropCallback(const std::vector<std::string_view>& paths) {
ZoneScoped;
ghoul_assert(amount > 0, "Expected at least one file path");
ghoul_assert(paths, "expected non-nullptr");
for (int i = 0; i < amount; ++i) {
global::openSpaceEngine->handleDragDrop(paths[i]);
for (const std::string_view path : paths) {
global::openSpaceEngine->handleDragDrop(path);
}
}
@@ -753,11 +746,11 @@ void setSgctDelegateFunctions() {
const Viewport* viewport = dynamic_cast<const Viewport*>(currentViewport);
if (viewport) {
if (viewport->hasSubViewports() && viewport->nonLinearProjection()) {
ivec2 dim = viewport->nonLinearProjection()->cubemapResolution();
const ivec2 dim = viewport->nonLinearProjection()->cubemapResolution();
return glm::ivec2(dim.x, dim.y);
}
else {
ivec2 dim = currentWindow->finalFBODimensions();
const ivec2 dim = currentWindow->finalFBODimensions();
return glm::ivec2(dim.x, dim.y);
}
}
@@ -768,8 +761,8 @@ void setSgctDelegateFunctions() {
sgctDelegate.currentViewportSize = []() {
ZoneScoped;
if (currentViewport != nullptr) {
vec2 size = currentViewport->size();
if (currentViewport) {
const vec2 size = currentViewport->size();
return glm::ivec2(size.x, size.y);
}
return glm::ivec2(-1, -1);
@@ -777,9 +770,9 @@ void setSgctDelegateFunctions() {
sgctDelegate.currentViewportResolution = []() {
ZoneScoped;
if (currentViewport != nullptr) {
ivec2 res = currentWindow->resolution();
vec2 size = currentViewport->size();
if (currentViewport) {
const ivec2 res = currentWindow->resolution();
const vec2 size = currentViewport->size();
return glm::ivec2(size.x * res.x, size.y * res.y);
}
return glm::ivec2(-1, -1);
@@ -787,7 +780,7 @@ void setSgctDelegateFunctions() {
sgctDelegate.dpiScaling = []() {
ZoneScoped;
vec2 scale = currentWindow->scale();
const vec2 scale = currentWindow->scale();
return glm::vec2(scale.x, scale.y);
};
sgctDelegate.firstWindowResolution = []() {
@@ -833,7 +826,7 @@ void setSgctDelegateFunctions() {
glfwGetWindowContentScale(dpiWindow->windowHandle(), &scale.x, &scale.y);
if (scale.x != scale.y) {
LWARNING(fmt::format(
LWARNING(std::format(
"Non-square window scaling detected ({0}x{1}), using {0}x{0} instead",
scale.x, scale.y
));
@@ -954,10 +947,9 @@ void setSgctDelegateFunctions() {
};
sgctDelegate.swapGroupFrameNumber = []() -> uint64_t {
ZoneScoped;
return currentWindow->swapGroupFrameNumber();
return sgct::Window::swapGroupFrameNumber();
};
sgctDelegate.setScreenshotFolder = [](std::string path) {
sgctDelegate.setScreenshotFolder = [](std::filesystem::path path) {
sgct::Settings::instance().setCapturePath(std::move(path));
};
sgctDelegate.showStatistics = [](bool enabled) {
@@ -969,29 +961,30 @@ void setSgctDelegateFunctions() {
sgctDelegate.currentNode = []() {
return ClusterManager::instance().thisNodeId();
};
sgctDelegate.mousePositionViewportRelative = [](glm::vec2 mousePosition) {
sgctDelegate.mousePositionViewportRelative = [](const glm::vec2& mousePosition) {
for (const std::unique_ptr<Window>& window : Engine::instance().windows()) {
if (isGuiWindow(window.get())) {
sgct::ivec2 res = window->resolution();
for (const std::unique_ptr<Viewport>& viewport : window->viewports()) {
sgct::vec2 pos = viewport->position();
sgct::vec2 size = viewport->size();
glm::vec4 bounds = glm::vec4(
pos.x * res.x,
(1.0 - pos.y - size.y) * res.y,
(pos.x + size.x) * res.x,
(1.0 - pos.y) * res.y
);
if (!isGuiWindow(window.get())) {
continue;
}
if (
(mousePosition.x >= bounds.x && mousePosition.x <= bounds.z) &&
(mousePosition.y >= bounds.y && mousePosition.y <= bounds.w)
) {
return glm::vec2(
res.x * (mousePosition.x - bounds.x) / (bounds.z - bounds.x),
res.y * (mousePosition.y - bounds.y) / (bounds.w - bounds.y)
);
}
const sgct::ivec2 res = window->resolution();
for (const std::unique_ptr<Viewport>& viewport : window->viewports()) {
const sgct::vec2 pos = viewport->position();
const sgct::vec2 size = viewport->size();
const glm::vec4 bounds = glm::vec4(
pos.x * res.x,
(1.0 - pos.y - size.y) * res.y,
(pos.x + size.x) * res.x,
(1.0 - pos.y) * res.y
);
if ((mousePosition.x >= bounds.x && mousePosition.x <= bounds.z) &&
(mousePosition.y >= bounds.y && mousePosition.y <= bounds.w))
{
return glm::vec2(
res.x * (mousePosition.x - bounds.x) / (bounds.z - bounds.x),
res.y * (mousePosition.y - bounds.y) / (bounds.w - bounds.y)
);
}
}
}
@@ -1003,7 +996,7 @@ void setSgctDelegateFunctions() {
void checkCommandLineForSettings(int& argc, char** argv, bool& hasSGCT, bool& hasProfile,
std::string& sgctFunctionName)
{
for (int i = 1; i < argc; ++i) {
for (int i = 1; i < argc; i++) {
const std::string arg = argv[i];
if (arg == "-c" || arg == "--config") {
std::string p = ((i + 1) < argc) ? argv[i + 1] : "";
@@ -1011,7 +1004,7 @@ void checkCommandLineForSettings(int& argc, char** argv, bool& hasSGCT, bool& ha
const std::string sgctAssignment = "SGCTConfig=";
const size_t findSgct = p.find(sgctAssignment);
const size_t findBracket = p.find("}");
const size_t findBracket = p.find('}');
if (findSgct != std::string::npos) {
if (findBracket != std::string::npos) {
sgctFunctionName = arg.substr(
@@ -1028,17 +1021,17 @@ void checkCommandLineForSettings(int& argc, char** argv, bool& hasSGCT, bool& ha
}
}
std::string setWindowConfigPresetForGui(const std::string labelFromCfgFile,
std::string setWindowConfigPresetForGui(const std::string& labelFromCfgFile,
bool haveCliSGCTConfig)
{
openspace::Configuration& config = *global::configuration;
std::string preset;
bool sgctConfigFileSpecifiedByLuaFunction = !config.sgctConfigNameInitialized.empty();
const bool sgctCfgFileSpecifiedByLua = !config.sgctConfigNameInitialized.empty();
if (haveCliSGCTConfig) {
preset = fmt::format("{} (from CLI)", config.windowConfiguration);
preset = std::format("{} (from CLI)", config.windowConfiguration);
}
else if (sgctConfigFileSpecifiedByLuaFunction) {
else if (sgctCfgFileSpecifiedByLua) {
preset = config.sgctConfigNameInitialized + labelFromCfgFile;
}
else {
@@ -1048,7 +1041,7 @@ std::string setWindowConfigPresetForGui(const std::string labelFromCfgFile,
}
std::string selectedSgctProfileFromLauncher(LauncherWindow& lw, bool hasCliSGCTConfig,
std::string windowConfiguration,
const std::string& windowConfiguration,
const std::string& labelFromCfgFile)
{
std::string config = windowConfiguration;
@@ -1063,30 +1056,24 @@ std::string selectedSgctProfileFromLauncher(LauncherWindow& lw, bool hasCliSGCTC
}
}
else {
std::filesystem::path c = absPath(config);
const std::filesystem::path c = absPath(config);
std::filesystem::path cj = c;
cj.replace_extension(".json");
std::filesystem::path cx = c;
cx.replace_extension(".xml");
if (c.extension().empty()) {
if (std::filesystem::exists(cj)) {
config += ".json";
}
else if (std::filesystem::exists(cx)) {
config += ".xml";
}
else {
throw ghoul::RuntimeError(fmt::format(
"Error loading configuration file {}. File could not be found",
throw ghoul::RuntimeError(std::format(
"Error loading configuration file '{}'. File could not be found",
config
));
}
}
else {
// user customzied sgct config
// user customized SGCT config
}
}
global::configuration->windowConfiguration = config;
@@ -1098,6 +1085,8 @@ std::string selectedSgctProfileFromLauncher(LauncherWindow& lw, bool hasCliSGCTC
int main(int argc, char* argv[]) {
ZoneScoped;
#ifdef OPENSPACE_BREAK_ON_FLOATING_POINT_EXCEPTION
_clearfp();
_controlfp(_controlfp(0, 0) & ~(_EM_ZERODIVIDE | _EM_OVERFLOW), _MCW_EM);
@@ -1132,7 +1121,7 @@ int main(int argc, char* argv[]) {
std::filesystem::current_path() / std::filesystem::path(argv[0]).parent_path(),
ghoul::filesystem::FileSystem::Override::Yes
);
LDEBUG(fmt::format("Registering ${{BIN}} to {}", absPath("${BIN}")));
LDEBUG(std::format("Registering ${{BIN}} to '{}'", absPath("${BIN}")));
//
// Parse commandline arguments
@@ -1182,7 +1171,7 @@ int main(int argc, char* argv[]) {
);
try {
bool showHelp = parser.execute();
const bool showHelp = parser.execute();
if (showHelp) {
std::cout << parser.helpText();
exit(EXIT_SUCCESS);
@@ -1216,23 +1205,23 @@ int main(int argc, char* argv[]) {
if (!std::filesystem::is_regular_file(configurationFilePath)) {
LFATALC(
"main",
fmt::format("Could not find configuration {}", configurationFilePath)
std::format("Could not find configuration '{}'", configurationFilePath)
);
exit(EXIT_FAILURE);
}
LINFO(fmt::format("Configuration Path: {}", configurationFilePath));
LINFO(std::format("Configuration Path '{}'", configurationFilePath));
// Register the base path as the directory where the configuration file lives
std::filesystem::path base = configurationFilePath.parent_path();
FileSys.registerPathToken("${BASE}", base);
FileSys.registerPathToken("${BASE}", std::move(base));
// The previous incarnation of this was initializing GLFW to get the primary
// monitor's resolution, but that had some massive performance implications as
// there was some issue with the swap buffer handling inside of GLFW. My
// assumption is that GLFW doesn't like being initialized, destroyed, and then
// initialized again. Therefore we are using the platform specific functions now
glm::ivec2 size = glm::ivec2(1920, 1080);
#ifdef WIN32
glm::ivec2 size = glm::ivec2(1920, 1080);
DEVMODEW dm = { 0 };
dm.dmSize = sizeof(DEVMODEW);
BOOL success = EnumDisplaySettingsW(nullptr, ENUM_CURRENT_SETTINGS, &dm);
@@ -1240,6 +1229,8 @@ int main(int argc, char* argv[]) {
size.x = dm.dmPelsWidth;
size.y = dm.dmPelsHeight;
}
#else // ^^^^ WIN32 // !WIN32 vvvv
const glm::ivec2 size = glm::ivec2(1920, 1080);
#endif // WIN32
// Loading configuration from disk
@@ -1276,7 +1267,7 @@ int main(int argc, char* argv[]) {
properties::Property::Visibility::Developer;
}
else {
throw ghoul::RuntimeError(fmt::format(
throw ghoul::RuntimeError(std::format(
"Unknown property visibility value '{}'",
*commandlineArguments.propertyVisibility
));
@@ -1336,27 +1327,27 @@ int main(int argc, char* argv[]) {
#endif // __APPLE__
std::string pwd = std::filesystem::current_path().string();
if (size_t it = pwd.find_first_of("'\"[]"); it != std::string::npos) {
if (const size_t it = pwd.find_first_of("'\"[]"); it != std::string::npos) {
QMessageBox::warning(
nullptr,
"OpenSpace",
QString::fromStdString(fmt::format(
QString::fromStdString(std::format(
"The OpenSpace folder is started must not contain any of \"'\", "
"\"\"\", [, or ]. Path is: '{}'. Unexpected errors will occur when "
"\"\"\", [, or ]. Path is: {}. Unexpected errors will occur when "
"proceeding to run the software", pwd
))
);
}
LauncherWindow win(
LauncherWindow win = LauncherWindow(
!commandlineArguments.profile.has_value(),
*global::configuration,
!commandlineArguments.windowConfig.has_value(),
windowCfgPreset,
std::move(windowCfgPreset),
nullptr
);
win.show();
app.exec();
QApplication::exec();
if (!win.wasLaunchSelected()) {
exit(EXIT_SUCCESS);
@@ -1384,8 +1375,8 @@ int main(int argc, char* argv[]) {
// there was some issue with the swap buffer handling inside of GLFW. My
// assumption is that GLFW doesn't like being initialized, destroyed, and then
// initialized again. Therefore we are using the platform specific functions now
glm::ivec2 size = glm::ivec2(1920, 1080);
#ifdef WIN32
glm::ivec2 size = glm::ivec2(1920, 1080);
DEVMODEW dm = { 0 };
dm.dmSize = sizeof(DEVMODEW);
BOOL success = EnumDisplaySettingsW(nullptr, ENUM_CURRENT_SETTINGS, &dm);
@@ -1393,6 +1384,8 @@ int main(int argc, char* argv[]) {
size.x = dm.dmPelsWidth;
size.y = dm.dmPelsHeight;
}
#else // ^^^^ WIN32 // !WIN32 vvvv
const glm::ivec2 size = glm::ivec2(1920, 1080);
#endif // WIN32
*global::configuration = loadConfigurationFromFile(
@@ -1438,7 +1431,7 @@ int main(int argc, char* argv[]) {
LDEBUG("Creating SGCT Engine");
std::vector<std::string> arg(argv + 1, argv + argc);
LDEBUG("Parsing commandline arguments");
sgct::Configuration config = parseArguments(arg);
const sgct::Configuration config = parseArguments(arg);
LDEBUG("Loading cluster information");
config::Cluster cluster = loadCluster(absPath(windowConfiguration).string());
@@ -1462,7 +1455,7 @@ int main(int argc, char* argv[]) {
Log::instance().setNotifyLevel(Log::Level::Debug);
try {
Engine::create(cluster, callbacks, config);
Engine::create(std::move(cluster), std::move(callbacks), config);
}
catch (const std::runtime_error& e) {
LFATALC("main", e.what());
@@ -1512,8 +1505,8 @@ int main(int argc, char* argv[]) {
settings.hasStartedBefore = true;
if (settings.rememberLastProfile) {
std::filesystem::path p = global::configuration->profile;
std::filesystem::path reducedName = p.filename().replace_extension();
const std::filesystem::path p = global::configuration->profile;
const std::filesystem::path reducedName = p.filename().replace_extension();
settings.profile = reducedName.string();
}

View File

@@ -64,7 +64,7 @@ int main(int, char**) {
Task& task = *tasks[i].get();
LINFOC(
"Sync",
fmt::format(
std::format(
"Synchronizing scene {} out of {}: {}",
i + 1, tasks.size(), task.description()
)

View File

@@ -74,12 +74,12 @@ void performTasks(const std::string& path) {
LINFO("Task queue has 1 item");
}
else {
LINFO(fmt::format("Task queue has {} items", tasks.size()));
LINFO(std::format("Task queue has {} items", tasks.size()));
}
for (size_t i = 0; i < tasks.size(); i++) {
Task& task = *tasks[i].get();
LINFO(fmt::format(
LINFO(std::format(
"Performing task {} out of {}: {}", i + 1, tasks.size(), task.description()
));
ProgressBar progressBar(100);
@@ -164,7 +164,7 @@ int main(int argc, char** argv) {
// If no task file was specified in as argument, run in CLI mode.
LINFO(fmt::format("Task root: {}", absPath("${TASKS}")));
LINFO(std::format("Task root: {}", absPath("${TASKS}")));
std::filesystem::current_path(absPath("${TASKS}"));
std::cout << "TASK > ";

View File

@@ -0,0 +1,21 @@
-- Lets first download a file that we can use for our examples. If you have files
-- locally, you can skip this part.
-- The song in the example comes from https://incompetech.com/ which is a fantastic
-- webpage for very high quality royalty-free music
openspace.downloadFile(
"https://incompetech.com/music/royalty-free/mp3-royaltyfree/Arcadia.mp3",
openspace.absPath("${TEMPORARY}/Arcadia.mp3"),
true
)
local soundName = "Example_Sound_1"
asset.onInitialize(function()
-- Start playing the song immediately
openspace.audio.playAudio(openspace.absPath("${TEMPORARY}/Arcadia.mp3"), soundName)
end)
asset.onDeinitialize(function()
-- When we remove this asset, we want to audio to stop playing no matter what
openspace.audio.stopAudio(soundName)
end)

View File

@@ -0,0 +1,71 @@
-- Lets first download a file that we can use for our examples. If you have files
-- locally, you can skip this part.
-- The song in the example comes from https://incompetech.com/ which is a fantastic
-- webpage for very high quality royalty-free music
openspace.downloadFile(
"https://incompetech.com/music/royalty-free/mp3-royaltyfree/Sneaky%20Adventure.mp3",
openspace.absPath("${TEMPORARY}/SneakyAdventure.mp3"),
true
)
local soundName = "Advanced_Example_Sound_1"
local panleft = {
Identifier = "os.examples.PanLeft",
Name = "Example Audio Pan Left",
Command = [[openspace.audio.set3dSourcePosition("Advanced_Example_Sound_1", { -1, 0, 0 })]],
GuiPath = "/Example/Audio"
}
local pancenter = {
Identifier = "os.examples.PanCenter",
Name = "Example Audio Pan Center",
Command = [[openspace.audio.set3dSourcePosition("Advanced_Example_Sound_1", { 0, 0, 0 })]],
GuiPath = "/Example/Audio"
}
local panright = {
Identifier = "os.examples.PanRight",
Name = "Example Audio Pan Right",
Command = [[openspace.audio.set3dSourcePosition("Advanced_Example_Sound_1", { 1, 0, 0 })]],
GuiPath = "/Example/Audio"
}
local lowvolume = {
Identifier = "os.examples.LowVolume",
Name = "Example Audio Volume Low",
Command = [[openspace.audio.setVolume("Advanced_Example_Sound_1", 0.15)]],
GuiPath = "/Example/Audio"
}
local fullvolume = {
Identifier = "os.examples.FullVolume",
Name = "Example Audio Volume Full",
Command = [[openspace.audio.setVolume("Advanced_Example_Sound_1", 1.0)]],
GuiPath = "/Example/Audio"
}
asset.onInitialize(function()
-- Start playing the song immediately in 3D. Place the audio straight in front of us
openspace.audio.playAudio3d(
openspace.absPath("${TEMPORARY}/SneakyAdventure.mp3"),
soundName,
{ 0.0, 0.0, 0.0 }
)
openspace.action.registerAction(panleft)
openspace.action.registerAction(pancenter)
openspace.action.registerAction(panright)
openspace.action.registerAction(lowvolume)
openspace.action.registerAction(fullvolume)
end)
asset.onDeinitialize(function()
openspace.action.removeAction(fullvolume)
openspace.action.removeAction(lowvolume)
openspace.action.removeAction(panright)
openspace.action.removeAction(pancenter)
openspace.action.removeAction(panleft)
-- When we remove this asset, we want to audio to stop playing no matter what
openspace.audio.stopAudio(soundName)
end)

View File

@@ -1,3 +1,6 @@
# A dummy dataset with an xyz position and some random data columns.
# The last two columns has data values with either missing values or
# Nan values (which can be handled seprately when color mapping)
x,y,z,a,b,normaldist_withMissing,number_withNan
13428000,26239000,45870000,-3.226548224,33.95773276,-0.357778948,29
14727000,45282000,10832000,45.05941924,-106.0395917,,29
1 x # A dummy dataset with an xyz position and some random data columns. y z a b normaldist_withMissing number_withNan
1 # A dummy dataset with an xyz position and some random data columns.
2 # The last two columns has data values with either missing values or
3 # Nan values (which can be handled seprately when color mapping)
4 x x,y,z,a,b,normaldist_withMissing,number_withNan y z a b normaldist_withMissing number_withNan
5 13428000 13428000,26239000,45870000,-3.226548224,33.95773276,-0.357778948,29 26239000 45870000 -3.226548224 33.95773276 -0.357778948 29
6 14727000 14727000,45282000,10832000,45.05941924,-106.0395917,,29 45282000 10832000 45.05941924 -106.0395917 29

View File

@@ -1,3 +1,12 @@
# A test dataset for interpolation, where the xyz positions expand outward in each
# time step. There are 10 points per timestep, as illustrated by the time column.
# There are also two columns that may be used for color mapping:
#
# static_value has values that are the same for the correpsonding point in each
# time step
# dynamic_value has values that change for every timestep. The change will be
# reflected in the interpolation
#
time,x,y,z,dynamic_value,static_value
0.0,675.0297905065192,1672.6820684730765,-124.14442820502654,1,1
0.0,9.0852354697237,1080.363474597831,266.4506394528842,3,3
1 time # A test dataset for interpolation, where the xyz positions expand outward in each x y z dynamic_value static_value
1 # A test dataset for interpolation, where the xyz positions expand outward in each
2 # time step. There are 10 points per timestep, as illustrated by the time column.
3 # There are also two columns that may be used for color mapping:
4 #
5 # static_value has values that are the same for the correpsonding point in each
6 # time step
7 # dynamic_value has values that change for every timestep. The change will be
8 # reflected in the interpolation
9 #
10 time time,x,y,z,dynamic_value,static_value x y z dynamic_value static_value
11 0.0 0.0,675.0297905065192,1672.6820684730765,-124.14442820502654,1,1 675.0297905065192 1672.6820684730765 -124.14442820502654 1 1
12 0.0 0.0,9.0852354697237,1080.363474597831,266.4506394528842,3,3 9.0852354697237 1080.363474597831 266.4506394528842 3 3

View File

@@ -1,3 +1,5 @@
# A test dataset for interpolation, where the xyz vary in a random walk patterin
# time step. There are 10 points per timestep, as illustrated by the time column
time,x,y,z
0.0,675.0297905065192,1672.6820684730765,-124.14442820502654
0.0,9.0852354697237,1080.363474597831,266.4506394528842
1 time # A test dataset for interpolation, where the xyz vary in a random walk patterin x y z
1 # A test dataset for interpolation, where the xyz vary in a random walk patterin
2 # time step. There are 10 points per timestep, as illustrated by the time column
3 time time,x,y,z x y z
4 0.0 0.0,675.0297905065192,1672.6820684730765,-124.14442820502654 675.0297905065192 1672.6820684730765 -124.14442820502654
5 0.0 0.0,9.0852354697237,1080.363474597831,266.4506394528842 9.0852354697237 1080.363474597831 266.4506394528842

View File

@@ -0,0 +1,9 @@
# A dummy dataset with an xyz position, some random values and an integer value to
# use for texturing the points
#
# The texture mapping from index to file is handled in another file
x,y,z,a,b,texture
13428000,26239000,45870000,-3.226548224,33.95773276,1
14727000,45282000,10832000,45.05941924,-106.0395917,0
24999000,28370000,19911000,-70.58906931,154.1851656,2
26539000,36165000,39582000,-13.3663358,71.79484733,3
1 # A dummy dataset with an xyz position, some random values and an integer value to
2 # use for texturing the points
3 #
4 # The texture mapping from index to file is handled in another file
5 x,y,z,a,b,texture
6 13428000,26239000,45870000,-3.226548224,33.95773276,1
7 14727000,45282000,10832000,45.05941924,-106.0395917,0
8 24999000,28370000,19911000,-70.58906931,154.1851656,2
9 26539000,36165000,39582000,-13.3663358,71.79484733,3

View File

@@ -0,0 +1,8 @@
# The texture map is a mapping between an index and the name of an image file.
# All the images should be located in the same folder, or the name need to be specified as a path relative
# to a specific folder
0 test3.jpg
1 test2.jpg
2 test.jpg
3 openspace-horiz-logo.png

View File

@@ -0,0 +1,16 @@
# A dummy dataset with an xyz position, some random values and an integer value to
# use for texturing the points
datavar 0 a
datavar 1 b
datavar 2 texture
texturevar 2 # The index of the data column that has the texture data
texture 0 test3.jpg
texture 1 test.jpg
texture 2 test.jpg
texture 3 openspace-horiz-logo.png
13428000 26239000 45870000 -3.226548224 33.95773276 0
14727000 45282000 10832000 45.05941924 -106.0395917 2
24999000 28370000 19911000 -70.58906931 154.1851656 3
26539000 36165000 39582000 -13.3663358 71.79484733 1

View File

@@ -0,0 +1,107 @@
-- CSV
local Test = {
Identifier = "TexturedPointCloudExample_CSV",
Renderable = {
Type = "RenderablePointCloud",
File = asset.resource("data/textured_csv/textured_points.csv"),
DataMapping = {
-- The name of the column in the CSV file that corresponds to the texture (should
-- be an integer)
TextureColumn = "texture",
-- A Texture mapping file that provides information about which value/index
-- corresponds to which texture file
TextureMapFile = asset.resource("data/textured_csv/texturemap.tmap")
},
Texture = {
-- Where to find the texture files (in this case, in the OpenSpace data folder)
Folder = openspace.absPath("${DATA}")
},
UseAdditiveBlending = false
},
GUI = {
Name = "Multi-Textured Points",
Path = "/Example/Point Clouds/Multi-Textured"
}
}
-- Interpolated
-- Multi-texturing works also for interpolated point clouds. Here we let the same
-- dataset as used above be interpreted as representing only two points, with a different
-- texture. Note that the textures will be set based on the first two data items and will
-- not be changed during interpolation
local Test_Interpolated = {
Identifier = "TexturedPointCloudExample_Interpolated",
Renderable = {
Type = "RenderableInterpolatedPoints",
File = asset.resource("data/textured_csv/textured_points.csv"),
NumberOfObjects = 2,
DataMapping = {
TextureColumn = "texture",
TextureMapFile = asset.resource("data/textured_csv/texturemap.tmap")
},
Texture = {
Folder = openspace.absPath("${DATA}")
},
UseAdditiveBlending = false
},
GUI = {
Name = "Multi-Textured Points (Interpolation)",
Path = "/Example/Point Clouds/Multi-Textured"
}
}
-- Speck file (allows storing all data in one single file, including the texture mapping)
-- Note that we disable this scene graph node per default here, as it shows the same
-- information as the CSV version
local Test_Speck = {
Identifier = "TexturedPointCloudExample_Speck",
Renderable = {
Type = "RenderablePointCloud",
Enabled = false,
-- When loading multi-texture information from a speck file, we do not need a
-- DataMapping entry - all information is in the file
File = asset.resource("data/textured_speck/textures_points.speck"),
Texture = {
-- However, we do still need to specify where the textures are located
Folder = openspace.absPath("${DATA}")
},
UseAdditiveBlending = false
},
GUI = {
Name = "Multi-Textured Points (Speck file)",
Path = "/Example/Point Clouds/Multi-Textured"
}
}
asset.onInitialize(function()
openspace.addSceneGraphNode(Test)
openspace.addSceneGraphNode(Test_Interpolated)
openspace.addSceneGraphNode(Test_Speck)
end)
asset.onDeinitialize(function()
openspace.removeSceneGraphNode(Test_Speck)
openspace.removeSceneGraphNode(Test_Interpolated)
openspace.removeSceneGraphNode(Test)
end)
asset.export(Test)
asset.export(Test_Interpolated)
asset.export(Test_Speck)
asset.meta = {
Name = "Multi-textured Points",
Version = "1.0",
Description = [[Example of point clouds where multiple textures are used for the points,
based on information in the dataset. The dataset may be either CSV or Speck format.
If CSV is used, additional information must be provided through the DataMapping: 1)
Which column in the dataset that corresponds to the texture, and a separate file that
maps that value to a texture file
]],
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -100,13 +100,19 @@ local FixedColor_ScaleBasedOnData = {
FixedColor = { 0.5, 0.5, 0.0 }
},
SizeSettings = {
-- The options for the columns that the points can be scaled by. The first
-- alternative is chosen per default
SizeMapping = { "number_withNan", "a" },
SizeMapping = {
-- The options for the columns that the points can be scaled by. The first
-- alternative in the list is chosen per default
ParameterOptions = { "a", "b" },
-- Specify which option we want to use for size mapping at start up. Here we
-- use the last of the provided options rather than the first one, which is
-- otherwise used by default
Parameter = "b"
},
-- Use a slightly smaller scale than above for the base size of the points
-- (will decide the size of the smallest point). That way, the points don't
-- become too big when scaled by the data parameter
ScaleExponent = 5
ScaleExponent = 5.0
}
},
GUI = {
@@ -131,11 +137,13 @@ local Textured = {
Renderable = {
Type = "RenderablePointCloud",
File = asset.resource("data/dummydata.csv"),
-- The path to the texture file. Here we use openspace.absPath so that we can use
-- the ${DATA} token to get the path to a texture in the "OpenSpace/data" folder,
-- but for a file at a relative location it would also work to use asset.resource,
-- like for the data file above
Texture = openspace.absPath("${DATA}/test3.jpg"),
Texture = {
-- The path to the texture file. Here we use openspace.absPath so that we can use
-- the ${DATA} token to get the path to a texture in the "OpenSpace/data" folder,
-- but for a file at a relative location it would also work to use asset.resource,
-- like for the data file above
File = openspace.absPath("${DATA}/test3.jpg"),
},
-- Disable additive blending, so that points will be rendered with their actual color
-- and overlapping points will be sorted by depth. This works best when the points
-- have an opacity of 1

View File

@@ -21,7 +21,9 @@ local Object = {
Opacity = 1.0,
File = speck .. "2dF.speck",
Unit = "Mpc",
Texture = textures .. "point3A.png",
Texture = {
File = textures .. "point3A.png",
},
Coloring = {
ColorMapping = {
File = speck .. "2dF.cmap",

View File

@@ -21,7 +21,9 @@ local Object = {
Opacity = 1.0,
File = speck .. "2MASS.speck",
Unit = "Mpc",
Texture = textures .. "point3A.png",
Texture = {
File = textures .. "point3A.png",
},
Coloring = {
FixedColor = { 1.0, 0.4, 0.2 },
ColorMapping = {

View File

@@ -21,7 +21,9 @@ local Object = {
Opacity = 1.0,
File = speck .. "6dF.speck",
Unit = "Mpc",
Texture = textures .. "point3A.png",
Texture = {
File = textures .. "point3A.png",
},
Coloring = {
FixedColor = { 1.0, 1.0, 0.0 },
ColorMapping = {

View File

@@ -25,6 +25,7 @@ local Object = {
Renderable = {
Type = "RenderablePointCloud",
Enabled = false,
File = speck .. "abell.speck",
Labels = {
File = speck .. "abell.label",
Opacity = 1.0,
@@ -39,8 +40,9 @@ local Object = {
FixedColor = { 1.0, 0.4, 0.2 },
--ColorMap = speck .. "abell.cmap", -- TODO: Decide whether to add
},
File = speck .. "abell.speck",
Texture = textures .. "point3A.png",
Texture = {
File = textures .. "point3A.png",
},
Unit = "Mpc",
TransformationMatrix = TransformMatrix,
SizeSettings = {

View File

@@ -18,6 +18,7 @@ local DeepSkyObjects = {
Renderable = {
Type = "RenderablePointCloud",
Enabled = false,
File = speck .. "dso.speck",
Labels = {
File = speck .. "dso.label",
Color = { 0.1, 0.4, 0.6 },
@@ -29,8 +30,9 @@ local DeepSkyObjects = {
Coloring = {
FixedColor = { 1.0, 1.0, 0.0 }
},
File = speck .. "dso.speck",
Texture = textures .. "point3.png",
Texture = {
File = textures .. "point3.png",
},
Unit = "pc",
--FadeInDistances = { 0.05, 1.0 }, -- Fade in value in the same unit as "Unit"
SizeSettings = {

View File

@@ -18,6 +18,7 @@ local Object = {
Renderable = {
Type = "RenderablePointCloud",
Enabled = false,
File = speck .. "dwarfs.speck",
Labels = {
File = speck .. "dwarfs.label",
Color = { 0.5, 0.1, 0.2 },
@@ -26,8 +27,9 @@ local Object = {
Unit = "pc"
},
Opacity = 1.0,
File = speck .. "dwarfs.speck",
Texture = textures .. "point3.png",
Texture = {
File = textures .. "point3.png",
},
Unit = "pc",
Coloring = {
FixedColor = { 0.4, 0.0, 0.1 },

View File

@@ -18,6 +18,7 @@ local Object = {
Renderable = {
Type = "RenderablePointCloud",
Enabled = false,
File = speck .. "expl.speck",
Labels = {
File = speck .. "expl.label",
Color = { 0.3, 0.3, 0.8 },
@@ -26,8 +27,9 @@ local Object = {
Unit = "pc"
},
Opacity = 1.0,
Texture = textures .. "target-blue.png",
File = speck .. "expl.speck",
Texture = {
File = textures .. "target-blue.png",
},
Unit = "pc",
SizeSettings = {
ScaleExponent = 16.9,

View File

@@ -21,7 +21,9 @@ local Object = {
Opacity = 0.99,
File = speck .. "exoplanet_candidates.speck",
Unit = "pc",
Texture = textures .. "halo.png",
Texture = {
File = textures .. "halo.png",
},
Coloring = {
FixedColor = { 1.0, 1.0, 0.0 }
},

View File

@@ -27,7 +27,9 @@ local Object = {
Enabled = false,
Opacity = 1.0,
File = HUDFSpeck .. "hudf.speck",
Texture = circle .. "circle.png",
Texture = {
File = circle .. "circle.png",
},
Coloring = {
ColorMapping = {
File = ColorMap .. "hudf.cmap",

View File

@@ -18,6 +18,8 @@ local Object = {
Renderable = {
Type = "RenderablePolygonCloud",
Enabled = false,
Opacity = 0.3,
File = speck .. "localgroup.speck",
Labels = {
File = speck .. "localgroup.label",
Color = { 0.3, 0.3, 1.0 },
@@ -27,11 +29,6 @@ local Object = {
},
Coloring = {
FixedColor = { 0.0, 1.0, 0.0 },
-- @TODO: This one wasn't actually properly used before the point cloud update.
-- All points were mapped to green. Decide if we want it around.
-- @TODO: Also, the cmap is currently not applied correctly, due to speck file
-- not being read properly (it inlcudes more information than just datavar-s).
-- This should be adressed. (2023-12-13, emmbr)
ColorMapping = {
File = speck .. "localgroup.cmap",
ParameterOptions = {
@@ -39,8 +36,6 @@ local Object = {
}
}
},
Opacity = 0.3,
File = speck .. "localgroup.speck",
PolygonSides = 12,
Unit = "Mpc",
SizeSettings = {

View File

@@ -36,10 +36,11 @@ local Object = {
Opacity = 0.7,
File = speck .. "ob.speck",
Unit = "pc",
Texture = textures .. "point4.png",
PolygonSides = 7,
SizeSettings = {
SizeMapping = { "diameter" },
SizeMapping = {
ParameterOptions = { "diameter" }
},
ScaleExponent = 16.9,
MaxSize = 17,
EnableMaxSizeControl = true

View File

@@ -27,7 +27,9 @@ local Object = {
Enabled = true,
Opacity = 0.95,
File = speck .. "quasars.speck",
Texture = textures .. "point3A.png",
Texture = {
File = textures .. "point3A.png",
},
Unit = "Mpc",
Fading = {
FadeInDistances = { 1000.0, 10000.0 } -- Fade in value in the same unit as "Unit"

View File

@@ -30,7 +30,9 @@ local Object = {
}
}
},
Texture = textures .. "point3A.png",
Texture = {
File = textures .. "point3A.png",
},
Unit = "Mpc",
Fading = {
FadeInDistances = { 220.0, 650.0 } -- Fade in value in the same unit as "Unit"

View File

@@ -18,6 +18,7 @@ local Object = {
Renderable = {
Type = "RenderablePointCloud",
Enabled = false,
File = speck .. "superclust.speck",
Labels = {
Enabled = true,
File = speck .. "superclust.label",
@@ -28,8 +29,9 @@ local Object = {
},
DrawElements = false,
Opacity = 0.65,
File = speck .. "superclust.speck",
Texture = textures .. "point3A.png",
Texture = {
File = textures .. "point3A.png",
},
Unit = "Mpc",
SizeSettings = {
ScaleExponent = 23.1,

View File

@@ -35,7 +35,9 @@ local TullyGalaxies = {
},
Opacity = 0.99,
File = speck .. "tully.speck",
Texture = textures .. "point3A.png",
Texture = {
File = textures .. "point3A.png"
},
Coloring = {
FixedColor = { 1.0, 0.4, 0.2 },
ColorMapping = {

View File

@@ -0,0 +1,49 @@
local globe = asset.require("../earth")
local texturesPath = asset.resource({
Name = "5000 Years of Total Solar Eclipses",
Type = "HttpSynchronization",
Identifier = "earth_eclipse_5000_years",
Version = 1
})
local Layer = {
Identifier = "5000_Years_Eclipses",
Name = "5000 Years of Total Solar Eclipses",
Enabled = asset.enabled,
FilePath = texturesPath .. "eclipse_freq_heatmap.tif",
Description = [[
This is a heatmap showing the density of solar eclipse paths over the Earth during the 5000-year period between 2000 BCE and 3000 CE. It uses the list of eclipses calculated by Fred Espenak and Jean Meeus and published in 2006 as the Five Millennium Canon of Solar Eclipses. The paths of the 3742 eclipses classified in the Canon as either "T" (total) or "H" (hybrid or total-annular) were drawn into a global map with a pixel resolution of 4 minutes (1/15 of a degree) of latitude and longitude. The pixels counted the eclipse paths as they were drawn, and each pixel location ended up experiencing anywhere from one to 35 eclipses.
For more information visit the NASA's Scientific Visualization Studio that generated this image: https://svs.gsfc.nasa.gov/5222
Thanks to Visualizer Ernie Wright and Technical support Ian Jones and Laurence Schuler for this.
See also the paper by Jean Meeus, The Frequency of Total and Annular Solar Eclipses for a Given Place, JBAA 92, 3 (April 1982), pp 124-126.
]],
CacheSettings = { Enabled = false }
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer(globe.Earth.Identifier, "ColorLayers", Layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer(globe.Earth.Identifier, "ColorLayers", Layer)
end)
asset.export("layer", Layer)
asset.meta = {
Name = "5000 Years of Total Solar Eclipses",
Version = "1.0",
Description = Layer.Description,
Author = "OpenSpace Team",
URL = "https://svs.gsfc.nasa.gov/5222",
License = "NASA"
}

View File

@@ -11,6 +11,13 @@ local models = asset.resource({
Version = 3
})
local kernels = asset.resource({
Name = "ISS Kernels",
Type = "HttpSynchronization",
Identifier = "iss_kernels",
Version = 1
})
local omm = asset.resource({
Name = "Satellite OMM Data (ISS)",
Type = "UrlSynchronization",
@@ -20,23 +27,22 @@ local omm = asset.resource({
SecondsUntilResync = 24 * 60 * 60
})
local tle = asset.resource({
Name = "Satellite TLE Data (ISS)",
Type = "UrlSynchronization",
Identifier = "satellite_tle_data_iss",
Url = "https://www.celestrak.com/NORAD/elements/gp.php?CATNR=25544&FORMAT=tle",
Filename = "ISS.txt",
SecondsUntilResync = 24 * 60 * 60
})
local IssPosition = {
Identifier = "ISSPosition",
Parent = transforms.EarthInertial.Identifier,
BoundingSphere = 54.5, -- half the width
Transform = {
Translation = {
Type = "GPTranslation",
Observer = transforms.EarthInertial.Identifier,
File = omm .. "ISS.txt",
Format = "OMM"
},
Rotation = {
Type = "SpiceRotation",
SourceFrame = coreKernels.Frame.Galactic,
DestinationFrame = coreKernels.Frame.J2000
}
Translation = {}, -- This translation is provided in the onInitialize
},
Tag = { "earth_satellite", "ISS" },
GUI = {
@@ -51,11 +57,9 @@ local IssModel = {
Parent = IssPosition.Identifier,
Transform = {
Rotation = {
Type = "FixedRotation",
Attached = "ISS",
XAxis = { 0.01, -1.0, 0.56 },
XAxisOrthogonal = true,
YAxis = transforms.EarthInertial.Identifier
Type = "SpiceRotation",
SourceFrame = "ISS",
DestinationFrame = coreKernels.Frame.J2000
}
},
Renderable = {
@@ -79,12 +83,7 @@ local IssTrail = {
Parent = transforms.EarthInertial.Identifier,
Renderable = {
Type = "RenderableTrailOrbit",
Translation = {
Type = "GPTranslation",
Observer = transforms.EarthInertial.Identifier,
File = omm .. "ISS.txt",
Format = "OMM"
},
Translation = {}, -- This translation is provided in the onInitialize
RenderBinMode = "PostDeferredTransparent",
Color = { 0.9, 0.6715, 0.0 },
Fade = 1.5,
@@ -135,19 +134,36 @@ local FocusIss = {
}
local kernelFile
asset.onInitialize(function()
-- In order to get the orientation of the ISS correctly, we need to have its position
-- available as a SPICE object. We don't want to just convert the TLE file once as we
-- want it to update with every startup.
-- For this reason we convert the TLE file into a type 10 SPICE kernel and since we are
-- already doing that, we can also get a more accurate position for free, too
local translation, kernel = openspace.space.tleToSpiceTranslation(tle .. "ISS.txt")
kernelFile = kernel -- Store the path for the deinitialize function
openspace.spice.loadKernel(kernelFile)
IssPosition.Transform.Translation = translation;
IssTrail.Renderable.Translation = translation;
openspace.spice.loadKernel(kernels .. "iss.tf")
local i = openspace.space.readKeplerFile(omm .. "ISS.txt", "OMM")
IssTrail.Renderable.Period = i[1].Period / (60 * 60 * 24)
openspace.addSceneGraphNode(IssPosition)
openspace.addSceneGraphNode(IssModel)
openspace.addSceneGraphNode(IssTrail)
openspace.setPropertyValueSingle("Scene.ISS.Rotation.yAxisInvertObject", true)
openspace.action.registerAction(FocusIss)
end)
asset.onDeinitialize(function()
openspace.spice.unloadKernel(kernels .. "iss.tf")
openspace.spice.unloadKernel(kernelFile)
openspace.action.removeAction(FocusIss)
openspace.removeSceneGraphNode(IssTrail)
@@ -163,7 +179,7 @@ asset.export(IssPosition)
asset.meta = {
Name = "ISS",
Version = "2.0",
Version = "3.0",
Description = [[Model and Trail for ISS. Model from NASA 3D models, trail from
Celestrak.]],
Author = "OpenSpace Team",

View File

@@ -22,15 +22,13 @@ local band = asset.resource({
local LaunchTime = "2021 DEC 25 12:20:00"
local EndTime = "2024 JAN 22 00:00:00"
local JWSTBand = {
Identifier = "JWSTBand",
Parent = transforms.JWSTPosition.Identifier,
TimeFrame = {
Type = "TimeFrameInterval",
Start = LaunchTime,
End = EndTime
Start = LaunchTime
},
Transform = {
Rotation = {
@@ -65,8 +63,7 @@ local JWSTModel = {
Parent = transforms.JWSTRotation.Identifier,
TimeFrame = {
Type = "TimeFrameInterval",
Start = LaunchTime,
End = EndTime
Start = LaunchTime
},
Renderable = {
Type = "RenderableModel",
@@ -96,8 +93,7 @@ local JWSTFov = {
Parent = JWSTModel.Identifier,
TimeFrame = {
Type = "TimeFrameInterval",
Start = LaunchTime,
End = EndTime
Start = LaunchTime
},
Renderable = {
Type = "RenderablePrism",
@@ -129,8 +125,7 @@ local JWSTLabel = {
Parent = transforms.JWSTPosition.Identifier,
TimeFrame = {
Type = "TimeFrameInterval",
Start = LaunchTime,
End = EndTime
Start = LaunchTime
},
Renderable = {
Type = "RenderableLabel",

View File

@@ -13,6 +13,8 @@ local function addJoystickAsset(joystick)
openspace.asset.add("./util/joysticks/xbox")
elseif joystick == "Wireless Xbox Controller" then
openspace.asset.add("./util/joysticks/xbox-wireless")
elseif joystick == "Microsoft X-Box 360 pad" then
openspace.asset.add("./util/joysticks/microsoft-xbox-360-pad")
elseif joystick == "SpaceNavigator" then
openspace.asset.add("./util/joysticks/space-mouse-compact")
elseif joystick == "SpaceMouse Enterprise" then
@@ -74,3 +76,14 @@ asset.onDeinitialize(function()
openspace.asset.remove("./util/joysticks/space-mouse-enterprise")
end
end)
asset.meta = {
Name = "Joystick controller: Any",
Version = "1.0",
Description = [[
Checks the name on the connected controllers and adds the cooresponding joystick asset
]],
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -0,0 +1,220 @@
local propertyHelper = asset.require("../property_helper")
local joystickHelper = asset.require("./joystick_helper")
-- Allowed values for the third parameter of bindJoystickAxis:
-- "None"
-- "Orbit X"
-- "Orbit Y"
-- "Zoom" -- both in and out
-- "Zoom In"
-- "Zoom Out"
-- "LocalRoll"
-- "GlobalRoll"
-- "Pan X"
-- "Pan Y"
-- Fourth parameter determines whether the axis should be inverted
-- Fifth parameter determines whether the axis behaves like a joystick or a Trigger.
-- Allowed values are "JoystickLike" and "TriggerLike", the first one is the default
-- Sixth parameters determins if the axis should be "Sticky" or not.
-- The axis values can either go back to 0 when the joystick is released or it can
-- stay at the value it was before the joystick was released.
-- The latter is called a sticky axis, when the values don't go back to 0.
-- Seventh parameter can be used to reverse the camera movement for the axis
-- Eighth parameter is the sensitivity for the axis
local XBoxController = {
-- Axes
LeftThumbStick = {
LeftRight = 0,
UpDown = 1
},
RightThumbStick = {
LeftRight = 3,
UpDown = 4
},
LeftTrigger = 2,
RightTrigger = 5,
-- Buttons
A = 0,
B = 1,
X = 2,
Y = 3,
LB = 4,
RB = 5,
Back = 6,
Start = 7,
LeftStickButton = 9,
RightStickButton = 10,
DPad = {
Up = 11,
Right = 12,
Down = 13,
Left = 14
}
}
asset.onInitialize(function()
local controller = XBoxController
local name = "Microsoft X-Box 360 pad"
local deadzoneJoysticks = 0.2
local deadzoneTriggers = 0.05
openspace.navigation.setAxisDeadZone(name, controller.LeftThumbStick.LeftRight, deadzoneJoysticks)
openspace.navigation.setAxisDeadZone(name, controller.LeftThumbStick.UpDown, deadzoneJoysticks)
openspace.navigation.setAxisDeadZone(name, controller.RightThumbStick.LeftRight, deadzoneJoysticks)
openspace.navigation.setAxisDeadZone(name, controller.RightThumbStick.UpDown, deadzoneJoysticks)
openspace.navigation.setAxisDeadZone(name, controller.LeftTrigger, deadzoneTriggers)
openspace.navigation.setAxisDeadZone(name, controller.RightTrigger, deadzoneTriggers)
openspace.navigation.bindJoystickAxis(name, controller.LeftThumbStick.LeftRight, "Orbit X")
openspace.navigation.bindJoystickAxis(name, controller.LeftThumbStick.UpDown, "Orbit Y")
openspace.navigation.bindJoystickAxis(name, controller.RightThumbStick.LeftRight, "Pan X", true)
openspace.navigation.bindJoystickAxis(name, controller.RightThumbStick.UpDown, "Pan Y", true)
openspace.navigation.bindJoystickAxis(name, controller.LeftTrigger, "Zoom Out", false, "TriggerLike")
openspace.navigation.bindJoystickAxis(name, controller.RightTrigger, "Zoom In", false, "TriggerLike")
-- Roll
openspace.navigation.bindJoystickButton(
name,
controller.DPad.Up,
joystickHelper.bindLocalRoll(name, controller.RightThumbStick.LeftRight) ..
"openspace.navigation.bindJoystickAxis('" .. name .. "', " .. controller.RightThumbStick.UpDown .. ", 'None')",
"Switch to roll mode"
)
openspace.navigation.bindJoystickButton(
name,
controller.DPad.Up,
joystickHelper.unbindRoll(name, controller.RightThumbStick.LeftRight) ..
"openspace.navigation.bindJoystickAxis('" .. name .. "', " .. controller.RightThumbStick.UpDown .. ", 'Pan Y', true)",
"Switch back to normal mode",
"Release"
)
-- Switch focus in the interesting nodes menu
openspace.navigation.bindJoystickButton(
name,
controller.LB,
[[
openspace.navigation.targetPreviousInterestingAnchor()
openspace.navigation.retargetAnchor()
]],
"Switch target to the previous interesting node"
)
openspace.navigation.bindJoystickButton(
name,
controller.RB,
[[
openspace.navigation.targetNextInterestingAnchor()
openspace.navigation.retargetAnchor()
]],
"Switch target to the next interesting node"
)
-- Toggle Frictions
openspace.navigation.bindJoystickButton(
name,
controller.A,
propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RotationalFriction"),
"Toggle rotational friction"
)
openspace.navigation.bindJoystickButton(
name,
controller.B,
propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.ZoomFriction"),
"Toggle zoom friction"
)
openspace.navigation.bindJoystickButton(
name,
controller.Y,
propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RollFriction"),
"Toggle roll friction"
)
-- Refocus
openspace.navigation.bindJoystickButton(
name,
controller.RightStickButton,
"openspace.navigation.retargetAnchor()",
"Retarget on current focus"
)
-- Time
openspace.navigation.bindJoystickButton(
name,
controller.DPad.Left,
"openspace.time.interpolatePreviousDeltaTimeStep()",
"Go backwards in time, faster the more times this button is pressed"
)
openspace.navigation.bindJoystickButton(
name,
controller.DPad.Down,
"openspace.time.interpolateDeltaTime(1)",
"Reset realtime"
)
openspace.navigation.bindJoystickButton(
name,
controller.DPad.Right,
"openspace.time.interpolateNextDeltaTimeStep()",
"Go forwards in time, faster the more times this button is pressed"
)
-- Reset Time to yesterday
openspace.navigation.bindJoystickButton(
name,
controller.Back,
[[
openspace.time.setDeltaTime(1)
local yesterday = openspace.time.advancedTime(openspace.time.currentWallTime(), "-1d")
openspace.time.setTime(yesterday)
]],
"Reset to yesterday realtime"
)
-- Pause
openspace.navigation.bindJoystickButton(
name,
controller.Start,
"openspace.time.togglePause()",
"Pause time simulation"
)
-- Open buttons that can be customized
-- X
openspace.navigation.bindJoystickButton(
name,
controller.X,
[[
-- <-- Copy paste your custom script here
]],
"" -- <-- Description of your custom script here (optional)
)
-- Left Joystick Button
openspace.navigation.bindJoystickButton(
name,
controller.LeftStickButton,
[[
-- <-- Copy paste your custom script here
]],
"" -- <-- Description of your custom script here (optional)
)
end)
asset.meta = {
Name = "Joystick controller: Microsoft X-Box 360 pad",
Version = "1.0",
Description = "Joystick controller configuration for Microsoft X-Box 360 pad",
Author = [[
OpenSpace Team & Winston
https://openspacesupport.slack.com/archives/CLMQXJJDQ/p1710388096683769
]],
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -228,3 +228,12 @@ asset.onInitialize(function()
"" -- <-- Description of your custom script here (optional)
)
end)
asset.meta = {
Name = "Joystick controller: PS4",
Version = "1.0",
Description = "Joystick controller configuration for PS4",
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -0,0 +1,252 @@
local propertyHelper = asset.require("../property_helper")
local joystickHelper = asset.require("./joystick_helper")
-- Allowed values for the third parameter of bindJoystickAxis:
-- "None"
-- "Orbit X"
-- "Orbit Y"
-- "Zoom" -- both in and out
-- "Zoom In"
-- "Zoom Out"
-- "LocalRoll"
-- "GlobalRoll"
-- "Pan X"
-- "Pan Y"
-- Fourth parameter determines whether the axis should be inverted
-- Fifth parameter determines whether the axis behaves like a joystick or a Trigger.
-- Allowed values are "JoystickLike" and "TriggerLike", the first one is the default
-- Sixth parameters determins if the axis should be "Sticky" or not.
-- The axis values can either go back to 0 when the joystick is released or it can
-- stay at the value it was before the joystick was released.
-- The latter is called a sticky axis, when the values don't go back to 0.
-- Seventh parameter can be used to reverse the camera movement for the axis
-- Eighth parameter is the sensitivity for the axis
local PS5Controller = {
-- Axes
LeftThumbStick = {
LeftRight = 0,
UpDown = 1
},
RightThumbStick = {
LeftRight = 2,
UpDown = 5
},
L2 = 3,
R2 = 4,
-- Buttons
Cross = 1,
Circle = 2,
Square = 0,
Triangle = 3,
L1 = 4,
R1 = 5,
L2Press = 6,
R2Press = 7,
Share = 8,
Options = 9,
PS = 12,
LeftStickButton = 10,
RightStickButton = 11,
TouchPad = 13,
Mute = 14,
DPad = {
Up = 15,
Right = 16,
Down = 17,
Left = 18
}
}
asset.onInitialize(function()
local controller = PS5Controller
local name = "DualSense Wireless Controller"
local deadzoneJoysticks = 0.2
local deadzoneTriggers = 0.05
openspace.navigation.setAxisDeadZone(name, controller.LeftThumbStick.LeftRight, deadzoneJoysticks)
openspace.navigation.setAxisDeadZone(name, controller.LeftThumbStick.UpDown, deadzoneJoysticks)
openspace.navigation.setAxisDeadZone(name, controller.RightThumbStick.LeftRight, deadzoneJoysticks)
openspace.navigation.setAxisDeadZone(name, controller.RightThumbStick.UpDown, deadzoneJoysticks)
openspace.navigation.setAxisDeadZone(name, controller.L2, deadzoneTriggers)
openspace.navigation.setAxisDeadZone(name, controller.R2, deadzoneTriggers)
openspace.navigation.bindJoystickAxis(name, controller.LeftThumbStick.LeftRight, "Orbit X")
openspace.navigation.bindJoystickAxis(name, controller.LeftThumbStick.UpDown, "Orbit Y")
openspace.navigation.bindJoystickAxis(name, controller.RightThumbStick.LeftRight, "Pan X", true)
openspace.navigation.bindJoystickAxis(name, controller.RightThumbStick.UpDown, "Pan Y", true)
openspace.navigation.bindJoystickAxis(name, controller.L2, "Zoom Out", false, "TriggerLike")
openspace.navigation.bindJoystickAxis(name, controller.R2, "Zoom In", false, "TriggerLike")
-- Roll
openspace.navigation.bindJoystickButton(
name,
controller.DPad.Up,
joystickHelper.bindLocalRoll(name, controller.RightThumbStick.LeftRight) ..
"openspace.navigation.bindJoystickAxis('" .. name .. "', " .. controller.RightThumbStick.UpDown .. ", 'None')",
"Switch to roll mode"
)
openspace.navigation.bindJoystickButton(
name,
controller.DPad.Up,
joystickHelper.unbindRoll(name, controller.RightThumbStick.LeftRight) ..
"openspace.navigation.bindJoystickAxis('" .. name .. "', " .. controller.RightThumbStick.UpDown .. ", 'Pan Y', true)",
"Switch back to normal mode",
"Release"
)
-- Switch focus in the interesting nodes menu
openspace.navigation.bindJoystickButton(
name,
controller.L1,
[[
openspace.navigation.targetPreviousInterestingAnchor()
openspace.navigation.retargetAnchor()
]],
"Switch target to the previous interesting node"
)
openspace.navigation.bindJoystickButton(
name,
controller.R1,
[[
openspace.navigation.targetNextInterestingAnchor()
openspace.navigation.retargetAnchor()
]],
"Switch target to the next interesting node"
)
-- Toggle Frictions
openspace.navigation.bindJoystickButton(
name,
controller.Cross,
propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RotationalFriction"),
"Toggle rotational friction"
)
openspace.navigation.bindJoystickButton(
name,
controller.Circle,
propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.ZoomFriction"),
"Toggle zoom friction"
)
openspace.navigation.bindJoystickButton(
name,
controller.Triangle,
propertyHelper.invert("NavigationHandler.OrbitalNavigator.Friction.RollFriction"),
"Toggle roll friction"
)
-- Refocus
openspace.navigation.bindJoystickButton(
name,
controller.RightStickButton,
"openspace.navigation.retargetAnchor()",
"Retarget on current focus"
)
-- Time
openspace.navigation.bindJoystickButton(
name,
controller.DPad.Left,
"openspace.time.interpolatePreviousDeltaTimeStep()",
"Go backwards in time, faster the more times this button is pressed"
)
openspace.navigation.bindJoystickButton(
name,
controller.DPad.Down,
"openspace.time.interpolateDeltaTime(1)",
"Reset realtime"
)
openspace.navigation.bindJoystickButton(
name,
controller.DPad.Right,
"openspace.time.interpolateNextDeltaTimeStep()",
"Go forwards in time, faster the more times this button is pressed"
)
-- Reset Time to yesterday
openspace.navigation.bindJoystickButton(
name,
controller.Options,
[[
openspace.time.setDeltaTime(1)
local yesterday = openspace.time.advancedTime(openspace.time.currentWallTime(), "-1d")
openspace.time.setTime(yesterday)
]],
"Reset to yesterday realtime"
)
-- Pause
openspace.navigation.bindJoystickButton(
name,
controller.TouchPad,
"openspace.time.togglePause()",
"Pause time simulation"
)
-- Open buttons that can be customized
-- Square
openspace.navigation.bindJoystickButton(
name,
controller.Square,
[[
-- <-- Copy paste your custom script here
]],
"" -- <-- Description of your custom script here (optional)
)
-- Share button
openspace.navigation.bindJoystickButton(
name,
controller.Share,
[[
-- <-- Copy paste your custom script here
]],
"" -- <-- Description of your custom script here (optional)
)
-- Left Joystick Button
openspace.navigation.bindJoystickButton(
name,
controller.LeftStickButton,
[[
-- <-- Copy paste your custom script here
]],
"" -- <-- Description of your custom script here (optional)
)
-- Playstation button
openspace.navigation.bindJoystickButton(
name,
controller.PS,
[[
-- <-- Copy paste your custom script here
]],
"" -- <-- Description of your custom script here (optional)
)
-- Microphone mute button
openspace.navigation.bindJoystickButton(
name,
controller.Mute,
[[
-- <-- Copy paste your custom script here
]],
"" -- <-- Description of your custom script here (optional)
)
end)
asset.meta = {
Name = "Joystick controller: PS5",
Version = "1.0",
Description = "Joystick controller configuration for PS5",
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -69,3 +69,12 @@ asset.onInitialize(function()
"Switch to global roll mode"
)
end)
asset.meta = {
Name = "Joystick controller: SpaceMouse compact wireless",
Version = "1.0",
Description = "Joystick controller configuration for SpaceMouse compact wireless",
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -69,3 +69,12 @@ asset.onInitialize(function()
"Switch to global roll mode"
)
end)
asset.meta = {
Name = "Joystick controller: SpaceMouse compact (wired)",
Version = "1.0",
Description = "Joystick controller configuration for SpaceMouse compact (wired)",
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -63,3 +63,12 @@ asset.onInitialize(function()
openspace.navigation.bindJoystickAxis(name, controller.Push.UpDown, "Zoom")
openspace.navigation.bindJoystickAxis(name, controller.Tilt.LeftRight, "LocalRoll")
end)
asset.meta = {
Name = "Joystick controller: SpaceMouse enterprise wireless",
Version = "1.0",
Description = "Joystick controller configuration for SpaceMouse enterprise wireless",
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -63,3 +63,12 @@ asset.onInitialize(function()
openspace.navigation.bindJoystickAxis(name, controller.Push.UpDown, "Zoom")
openspace.navigation.bindJoystickAxis(name, controller.Tilt.LeftRight, "LocalRoll")
end)
asset.meta = {
Name = "Joystick controller: SpaceMouse enterprise (wired)",
Version = "1.0",
Description = "Joystick controller configuration for SpaceMouse enterprise (wired)",
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -206,3 +206,12 @@ asset.onInitialize(function()
"" -- <-- Description of your custom script here (optional)
)
end)
asset.meta = {
Name = "Joystick controller: Xbox wireless",
Version = "1.0",
Description = "Joystick controller configuration for Xbox wireless",
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -206,3 +206,12 @@ asset.onInitialize(function()
"" -- <-- Description of your custom script here (optional)
)
end)
asset.meta = {
Name = "Joystick controller: Xbox (wired)",
Version = "1.0",
Description = "Joystick controller configuration for Xbox (wired)",
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -4,7 +4,7 @@ local guiCustomization = asset.require("customization/gui")
-- Select which commit hashes to use for the frontend and backend
local frontendHash = "95683e59c7fa1891e7db7b83e4eeea15f9da11f1"
local frontendHash = "65c0238b8ba931b958cf3cada2ab226c8f1c9880"
local frontend = asset.resource({
Identifier = "WebGuiFrontend",

View File

@@ -78,7 +78,7 @@ public:
void setAtmosphereDimmingFactor(float atmosphereDimmingFactor);
// Relative mutators
void rotate(glm::dquat rotation);
void rotate(const glm::dquat& rotation);
// Accessors
// Remove Vec3 from the name when psc is gone

View File

@@ -34,6 +34,9 @@ namespace openspace::dataloader::csv {
Dataset loadCsvFile(std::filesystem::path path,
std::optional<DataMapping> specs = std::nullopt);
std::vector<Dataset::Texture> loadTextureMapFile(std::filesystem::path path,
const std::set<int>& texturesInData);
} // namespace openspace::dataloader
#endif // __OPENSPACE_CORE___CSVLOADER___H__

View File

@@ -103,8 +103,8 @@ namespace data {
Dataset loadFile(std::filesystem::path path,
std::optional<DataMapping> specs = std::nullopt);
std::optional<Dataset> loadCachedFile(std::filesystem::path path);
void saveCachedFile(const Dataset& dataset, std::filesystem::path path);
std::optional<Dataset> loadCachedFile(const std::filesystem::path& path);
void saveCachedFile(const Dataset& dataset, const std::filesystem::path& path);
Dataset loadFileWithCache(std::filesystem::path path,
std::optional<DataMapping> specs = std::nullopt);
@@ -116,8 +116,8 @@ namespace label {
Labelset loadFile(std::filesystem::path path,
std::optional<DataMapping> specs = std::nullopt);
std::optional<Labelset> loadCachedFile(std::filesystem::path path);
void saveCachedFile(const Labelset& labelset, std::filesystem::path path);
std::optional<Labelset> loadCachedFile(const std::filesystem::path& path);
void saveCachedFile(const Labelset& labelset, const std::filesystem::path& path);
Labelset loadFileWithCache(std::filesystem::path path);
@@ -129,8 +129,8 @@ namespace color {
ColorMap loadFile(std::filesystem::path path,
std::optional<DataMapping> specs = std::nullopt);
std::optional<ColorMap> loadCachedFile(std::filesystem::path path);
void saveCachedFile(const ColorMap& colorMap, std::filesystem::path path);
std::optional<ColorMap> loadCachedFile(const std::filesystem::path& path);
void saveCachedFile(const ColorMap& colorMap, const std::filesystem::path& path);
ColorMap loadFileWithCache(std::filesystem::path path);

View File

@@ -41,10 +41,15 @@ struct DataMapping {
bool hasExcludeColumns() const;
bool isExcludeColumn(std::string_view column) const;
bool checkIfAllProvidedColumnsExist(const std::vector<std::string>& columns) const;
std::optional<std::string> xColumnName;
std::optional<std::string> yColumnName;
std::optional<std::string> zColumnName;
std::optional<std::string> nameColumn;
std::optional<std::string> textureColumn;
std::optional<std::filesystem::path> textureMap;
std::optional<float> missingDataValue;
@@ -72,6 +77,8 @@ bool isColumnZ(const std::string& c, const std::optional<DataMapping>& mapping);
bool isNameColumn(const std::string& c, const std::optional<DataMapping>& mapping);
bool isTextureColumn(const std::string& c, const std::optional<DataMapping>& mapping);
} // namespace openspace::dataloader
#endif // __OPENSPACE_CORE___DATAMAPPING___H__

View File

@@ -954,7 +954,7 @@ public:
* necessary to make the codegen work in all cases without complications there
*/
OrVerifier(const std::vector<std::variant<Verifier*,
std::shared_ptr<Verifier>>> values);
std::shared_ptr<Verifier>>>& values);
/**
* Checks whether the \p dictionary contains the \p key and whether this key passes

View File

@@ -378,13 +378,13 @@ TestResult InListVerifier<T>::operator()(const ghoul::Dictionary& dict,
std::string list = std::accumulate(
values.begin() + 1,
values.end(),
fmt::format("{}", values.front()),
std::format("{}", values.front()),
[](std::string lhs, typename T::Type rhs) {
return fmt::format("{}, {}", lhs, rhs);
return std::format("{}, {}", lhs, rhs);
}
);
o.explanation = fmt::format(
"{} not in list of accepted values '{}'",
o.explanation = std::format(
"'{}' not in list of accepted values '{}'",
key, list
);
r.offenses.push_back(o);

View File

@@ -47,7 +47,7 @@ struct Configuration {
ghoul::Dictionary createDictionary();
std::string windowConfiguration = "${CONFIG}/single.xml";
std::string windowConfiguration = "${CONFIG}/single.json";
std::string asset;
std::string profile;

View File

@@ -104,15 +104,14 @@ public:
OverrideFile overrideFile = OverrideFile::Yes,
FailOnError failOnError = FailOnError::No, unsigned int timeout_secs = 0,
DownloadFinishedCallback finishedCallback = DownloadFinishedCallback(),
DownloadProgressCallback progressCallback = DownloadProgressCallback()
);
DownloadProgressCallback progressCallback = DownloadProgressCallback()) const;
std::future<MemoryFile> fetchFile(const std::string& url,
SuccessCallback successCallback = SuccessCallback(),
ErrorCallback errorCallback = ErrorCallback());
void getFileExtension(const std::string& url,
RequestFinishedCallback finishedCallback = RequestFinishedCallback());
void fileExtension(const std::string& url,
RequestFinishedCallback finishedCallback = RequestFinishedCallback()) const;
private:
bool _useMultithreadedDownload;

View File

@@ -96,12 +96,10 @@ public:
void deinitializeGL();
void preSynchronization();
void postSynchronizationPreDraw();
void viewportChanged();
void render(const glm::mat4& sceneMatrix, const glm::mat4& viewMatrix,
const glm::mat4& projectionMatrix);
void drawOverlays();
void postDraw();
void resetPropertyChangeFlags();
void keyboardCallback(Key key, KeyModifier mod, KeyAction action,
IsGuiWindow isGuiWindow);
void charCallback(unsigned int codepoint, KeyModifier modifier,
@@ -118,7 +116,6 @@ public:
void decode(std::vector<std::byte> data);
properties::Property::Visibility visibility() const;
bool showHiddenSceneGraphNodes() const;
void toggleShutdownMode();
Mode currentMode() const;
@@ -148,11 +145,9 @@ private:
void loadFonts();
void runGlobalCustomizationScripts();
void resetPropertyChangeFlagsOfSubowners(openspace::properties::PropertyOwner* po);
properties::BoolProperty _printEvents;
properties::OptionProperty _visibility;
properties::BoolProperty _showHiddenSceneGraphNodes;
properties::FloatProperty _fadeOnEnableDuration;
properties::BoolProperty _disableAllMouseInputs;

View File

@@ -114,7 +114,7 @@ struct WindowDelegate {
uint64_t (*swapGroupFrameNumber)() = []() { return uint64_t(0); };
void (*setScreenshotFolder)(std::string) = [](std::string) {};
void (*setScreenshotFolder)(std::filesystem::path) = [](std::filesystem::path) {};
void (*showStatistics)(bool) = [](bool) {};
@@ -122,8 +122,8 @@ struct WindowDelegate {
int (*currentNode)() = []() { return 0; };
glm::vec2 (*mousePositionViewportRelative)(glm::vec2 mousePosition) =
[](glm::vec2) { return glm::vec2(0); };
glm::vec2 (*mousePositionViewportRelative)(const glm::vec2& mousePosition) =
[](const glm::vec2&) { return glm::vec2(0); };
};
} // namespace openspace

View File

@@ -113,7 +113,7 @@ public:
*/
void unregisterEventAction(events::Event::Type type,
const std::string& identifier,
std::optional<ghoul::Dictionary> filter = std::nullopt);
const std::optional<ghoul::Dictionary>& filter = std::nullopt);
/**
* Removing registration for a specific event identified by the \p identifier.

View File

@@ -58,7 +58,7 @@ public:
* Returns true if any of the velocities are larger than zero, i.e. wether an
* interaction happened.
*/
bool hasNonZeroVelocities(bool checkOnlyMovement = false);
bool hasNonZeroVelocities(bool checkOnlyMovement = false) const;
protected:
struct InteractionState {

View File

@@ -59,7 +59,7 @@ void Interpolator<T>::setInterpolationTime(float interpolationTime) {
template <typename T>
void Interpolator<T>::step() {
_t += _scaledDeltaTime;
_t = glm::clamp(_t, 0.0f, 1.0f);
_t = glm::clamp(_t, 0.f, 1.f);
}
template <typename T>

View File

@@ -88,14 +88,14 @@ public:
void updateStateFromInput(
const JoystickInputStates& joystickInputStates, double deltaTime);
void setAxisMapping(std::string joystickName, int axis, AxisType mapping,
void setAxisMapping(const std::string& joystickName, int axis, AxisType mapping,
AxisInvert shouldInvert = AxisInvert::No,
JoystickType joystickType = JoystickType::JoystickLike,
bool isSticky = false, AxisFlip shouldFlip = AxisFlip::No,
double sensitivity = 0.0
);
void setAxisMappingProperty(std::string joystickName, int axis,
void setAxisMappingProperty(const std::string& joystickName, int axis,
std::string propertyUri, float min = 0.f, float max = 1.f,
AxisInvert shouldInvert = AxisInvert::No, bool isRemote = true
);
@@ -196,7 +196,7 @@ from_string(std::string_view string)
if (string == "Pan Y") { return T::PanY; }
if (string == "Property") { return T::Property; }
throw RuntimeError(fmt::format("Unknown axis type '{}'", string), "Joystick");
throw RuntimeError(std::format("Unknown axis type '{}'", string), "Joystick");
}
template <>
@@ -220,7 +220,7 @@ from_string(std::string_view string)
if (string == "JoystickLike") { return T::JoystickLike; }
if (string == "TriggerLike") { return T::TriggerLike; }
throw RuntimeError(fmt::format("Unknown joystick type '{}'", string), "Joystick");
throw RuntimeError(std::format("Unknown joystick type '{}'", string), "Joystick");
}
} // namespace ghoul

View File

@@ -150,7 +150,7 @@ constexpr openspace::interaction::JoystickAction from_string(std::string_view st
if (string == "Repeat") { return openspace::interaction::JoystickAction::Repeat; }
if (string == "Release") { return openspace::interaction::JoystickAction::Release; }
throw RuntimeError(fmt::format("Unknown action '{}'", string));
throw RuntimeError(std::format("Unknown action '{}'", string));
}
} // namespace ghoul

Some files were not shown because too many files have changed in this diff Show More