From 97536d934db7e0e81203d217f10df2d5839faf0f Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Sat, 16 Dec 2023 19:03:09 +0100 Subject: [PATCH 01/40] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cc52d8806..4586b4ab4 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ Further information and artwork: An Nvidia graphics card with compute capability 6.0 or higher is needed. Please check [https://en.wikipedia.org/wiki/CUDA#GPUs_supported](https://en.wikipedia.org/wiki/CUDA#GPUs_supported). # 💽 Installer -Installer for Windows: [alien-installer.msi](https://alien-project.org/media/files/alien-installer.msi) (Updated: 2023-12-10) +Installer for Windows: [alien-installer.msi](https://alien-project.org/media/files/alien-installer.msi) (Updated: 2023-12-16) In the case that the program crashes for an unknown reason, please refer to the troubleshooting section in [alien-project.org/downloads.html](https://alien-project.org/downloads.html). From b9c254b8c9a8dfe2a80329c9565e97cc3db09496 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Tue, 19 Dec 2023 09:21:54 +0100 Subject: [PATCH 02/40] browser data structures refactored --- source/Base/Resources.h | 2 +- source/Gui/BrowserDataService.cpp | 29 ++++++ source/Gui/BrowserDataService.h | 12 +++ source/Gui/BrowserSimulationData.h | 31 ++++++ source/Gui/BrowserWindow.cpp | 94 ++++++++++--------- source/Gui/BrowserWindow.h | 22 +++-- source/Gui/CMakeLists.txt | 7 +- source/Gui/Definitions.h | 6 ++ source/Gui/NetworkController.cpp | 6 +- source/Gui/NetworkDataParser.cpp | 54 ----------- source/Gui/NetworkDataParserService.cpp | 56 +++++++++++ ...ataParser.h => NetworkDataParserService.h} | 4 +- source/Gui/RemoteSimulationData.cpp | 30 +++--- source/Gui/RemoteSimulationData.h | 6 +- vcpkg.json | 2 +- 15 files changed, 226 insertions(+), 135 deletions(-) create mode 100644 source/Gui/BrowserDataService.cpp create mode 100644 source/Gui/BrowserDataService.h create mode 100644 source/Gui/BrowserSimulationData.h delete mode 100644 source/Gui/NetworkDataParser.cpp create mode 100644 source/Gui/NetworkDataParserService.cpp rename source/Gui/{NetworkDataParser.h => NetworkDataParserService.h} (84%) diff --git a/source/Base/Resources.h b/source/Base/Resources.h index bbf9a8177..dc55a29f4 100644 --- a/source/Base/Resources.h +++ b/source/Base/Resources.h @@ -2,7 +2,7 @@ namespace Const { - std::string const ProgramVersion = "4.5.1"; + std::string const ProgramVersion = "4.6.0"; std::string const DiscordLink = "https://discord.gg/7bjyZdXXQ2"; std::string const BasePath = "resources/"; diff --git a/source/Gui/BrowserDataService.cpp b/source/Gui/BrowserDataService.cpp new file mode 100644 index 000000000..2916d9dc3 --- /dev/null +++ b/source/Gui/BrowserDataService.cpp @@ -0,0 +1,29 @@ +#include "BrowserDataService.h" + +#include "BrowserSimulationData.h" + +std::vector BrowserDataService::createBrowserData(std::vector const& remoteData) +{ + std::vector result; + result.reserve(remoteData.size()); + for (auto const& entry : remoteData) { + auto browserData = std::make_shared<_BrowserSimulationData>(); + browserData->id = entry->id; + browserData->timestamp = entry->timestamp; + browserData->userName = entry->userName; + browserData->simName = entry->simName; + browserData->numLikesByEmojiType = entry->numLikesByEmojiType; + browserData->numDownloads = entry->numDownloads; + browserData->width = entry->width; + browserData->height = entry->height; + browserData->particles = entry->particles; + browserData->contentSize = entry->contentSize; + browserData->description = entry->description; + browserData->version = entry->version; + browserData->fromRelease = entry->fromRelease; + browserData->type = entry->type; + + result.emplace_back(browserData); + } + return result; +} diff --git a/source/Gui/BrowserDataService.h b/source/Gui/BrowserDataService.h new file mode 100644 index 000000000..01a086bfb --- /dev/null +++ b/source/Gui/BrowserDataService.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +#include "Definitions.h" +#include "RemoteSimulationData.h" + +class BrowserDataService +{ +public: + static std::vector createBrowserData(std::vector const& remoteData); +}; diff --git a/source/Gui/BrowserSimulationData.h b/source/Gui/BrowserSimulationData.h new file mode 100644 index 000000000..f0f6a9616 --- /dev/null +++ b/source/Gui/BrowserSimulationData.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +using BrowserDataType = int; +enum BrowserDataType_ +{ + BrowserDataType_Simulation, + BrowserDataType_Genome +}; + +class _BrowserSimulationData +{ +public: + std::string id; + std::string timestamp; + std::string userName; + std::string simName; + std::map numLikesByEmojiType; + int numDownloads; + int width; + int height; + int particles; + uint64_t contentSize; + std::string description; + std::string version; + bool fromRelease; + BrowserDataType type; +}; + diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 0e1b2f52f..cef5bfb94 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -23,8 +23,9 @@ #include "EngineInterface/SimulationController.h" #include "AlienImGui.h" +#include "BrowserDataService.h" #include "StyleRepository.h" -#include "NetworkDataParser.h" +#include "NetworkDataParserService.h" #include "NetworkController.h" #include "StatisticsWindow.h" #include "Viewport.h" @@ -113,7 +114,7 @@ void _BrowserWindow::refreshIntern(bool withRetry) _numSimulations = 0; _numGenomes = 0; for (auto const& entry : _rawRemoteDataList) { - if (entry.type == DataType_Simulation) { + if (entry->type == DataType_Simulation) { ++_numSimulations; } else { ++_numGenomes; @@ -121,6 +122,7 @@ void _BrowserWindow::refreshIntern(bool withRetry) } } calcFilteredSimulationAndGenomeLists(); + _scheduleCreateBrowserData = true; if (_networkController->getLoggedInUserName()) { if (!_networkController->getEmojiTypeBySimId(_ownEmojiTypeBySimId)) { @@ -130,7 +132,6 @@ void _BrowserWindow::refreshIntern(bool withRetry) _ownEmojiTypeBySimId.clear(); } - sortSimulationList(); sortUserList(); } catch (std::exception const& e) { if (withRetry) { @@ -307,23 +308,21 @@ void _BrowserWindow::processSimulationList() ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableHeadersRow(); - //sort our data if sort specs have been changed! + //create table data if necessary if (ImGuiTableSortSpecs* sortSpecs = ImGui::TableGetSortSpecs()) { - if (sortSpecs->SpecsDirty || _scheduleSort) { - if (_filteredRemoteSimulationList.size() > 1) { - std::sort(_filteredRemoteSimulationList.begin(), _filteredRemoteSimulationList.end(), [&](auto const& left, auto const& right) { - return RemoteSimulationData::compare(&left, &right, sortSpecs) < 0; - }); - } + if (sortSpecs->SpecsDirty || _scheduleCreateBrowserData) { + sortRemoteSimulationData(_filteredRemoteSimulationList, sortSpecs); sortSpecs->SpecsDirty = false; + _scheduleCreateBrowserData = false; + + _browserSimulationList = BrowserDataService::createBrowserData(_filteredRemoteSimulationList); } } ImGuiListClipper clipper; - clipper.Begin(_filteredRemoteSimulationList.size()); + clipper.Begin(_browserSimulationList.size()); while (clipper.Step()) for (int row = clipper.DisplayStart; row < clipper.DisplayEnd; row++) { - - RemoteSimulationData* item = &_filteredRemoteSimulationList[row]; + auto item = _browserSimulationList[row]; ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); @@ -331,7 +330,7 @@ void _BrowserWindow::processSimulationList() ImGui::TableNextColumn(); processActionButtons(item); ImGui::TableNextColumn(); - pushTextColor(*item); + pushTextColor(item); AlienImGui::Text(item->timestamp); ImGui::TableNextColumn(); processShortenedText(item->userName); @@ -408,23 +407,22 @@ void _BrowserWindow::processGenomeList() ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableHeadersRow(); - //sort our data if sort specs have been changed! + //create table data if necessary if (ImGuiTableSortSpecs* sortSpecs = ImGui::TableGetSortSpecs()) { - if (sortSpecs->SpecsDirty || _scheduleSort) { - if (_filteredRemoteGenomeList.size() > 1) { - std::sort(_filteredRemoteGenomeList.begin(), _filteredRemoteGenomeList.end(), [&](auto const& left, auto const& right) { - return RemoteSimulationData::compare(&left, &right, sortSpecs) < 0; - }); - } + if (sortSpecs->SpecsDirty || _scheduleCreateBrowserData) { + sortRemoteSimulationData(_filteredRemoteGenomeList, sortSpecs); sortSpecs->SpecsDirty = false; + _scheduleCreateBrowserData = false; + + _browserGenomeList = BrowserDataService::createBrowserData(_filteredRemoteGenomeList); } } ImGuiListClipper clipper; - clipper.Begin(_filteredRemoteGenomeList.size()); + clipper.Begin(_browserGenomeList.size()); while (clipper.Step()) for (int row = clipper.DisplayStart; row < clipper.DisplayEnd; row++) { - RemoteSimulationData* item = &_filteredRemoteGenomeList[row]; + auto& item = _browserGenomeList[row]; ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); @@ -432,7 +430,7 @@ void _BrowserWindow::processGenomeList() ImGui::TableNextColumn(); processActionButtons(item); ImGui::TableNextColumn(); - pushTextColor(*item); + pushTextColor(item); AlienImGui::Text(item->timestamp); ImGui::TableNextColumn(); processShortenedText(item->userName); @@ -577,10 +575,12 @@ void _BrowserWindow::processFilter() ImGui::Spacing(); if (AlienImGui::ToggleButton(AlienImGui::ToggleButtonParameters().name("Community creations"), _showCommunityCreations)) { calcFilteredSimulationAndGenomeLists(); + _scheduleCreateBrowserData = true; } ImGui::SameLine(); if (AlienImGui::InputText(AlienImGui::InputTextParameters().name("Filter"), _filter)) { calcFilteredSimulationAndGenomeLists(); + _scheduleCreateBrowserData = true; } } @@ -640,7 +640,7 @@ void _BrowserWindow::processEmojiButton(int emojiType) auto cursorPos = ImGui::GetCursorScreenPos(); auto emojiWidth = scale(toFloat(emoji.width)); auto emojiHeight = scale(toFloat(emoji.height)); - auto const& sim = _simOfEmojiPopup; + auto sim = _simOfEmojiPopup; if (ImGui::ImageButton((void*)(intptr_t)emoji.textureId, {emojiWidth, emojiHeight}, {0, 0}, {1.0f, 1.0f})) { onToggleLike(sim, toInt(emojiType)); ImGui::CloseCurrentPopup(); @@ -659,7 +659,7 @@ void _BrowserWindow::processEmojiButton(int emojiType) } } -void _BrowserWindow::processEmojiList(RemoteSimulationData* sim) +void _BrowserWindow::processEmojiList(BrowserSimulationData const& sim) { //calc remap which allows to show most frequent like type first std::map remap; @@ -724,10 +724,10 @@ void _BrowserWindow::processEmojiList(RemoteSimulationData* sim) } } -void _BrowserWindow::processActionButtons(RemoteSimulationData* simData) +void _BrowserWindow::processActionButtons(BrowserSimulationData const& sim) { //like button - auto liked = isLiked(simData->id); + auto liked = isLiked(sim->id); if (liked) { ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::LikeButtonTextColor); } else { @@ -737,7 +737,7 @@ void _BrowserWindow::processActionButtons(RemoteSimulationData* simData) ImGui::PopStyleColor(); if (likeButtonResult) { _activateEmojiPopup = true; - _simOfEmojiPopup = simData; + _simOfEmojiPopup = sim; } AlienImGui::Tooltip("Choose a reaction"); ImGui::SameLine(); @@ -747,18 +747,18 @@ void _BrowserWindow::processActionButtons(RemoteSimulationData* simData) auto downloadButtonResult = processActionButton(ICON_FA_DOWNLOAD); ImGui::PopStyleColor(); if (downloadButtonResult) { - onDownloadItem(simData); + onDownloadItem(sim); } AlienImGui::Tooltip("Download"); ImGui::SameLine(); //delete button - if (simData->userName == _networkController->getLoggedInUserName().value_or("")) { + if (sim->userName == _networkController->getLoggedInUserName().value_or("")) { ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DeleteButtonTextColor); auto deleteButtonResult = processActionButton(ICON_FA_TRASH); ImGui::PopStyleColor(); if (deleteButtonResult) { - onDeleteItem(simData); + onDeleteItem(sim); } AlienImGui::Tooltip("Delete"); } @@ -826,9 +826,13 @@ void _BrowserWindow::processActivated() onRefresh(); } -void _BrowserWindow::sortSimulationList() +void _BrowserWindow::sortRemoteSimulationData(std::vector& remoteData, ImGuiTableSortSpecs* sortSpecs) { - _scheduleSort = true; + if (remoteData.size() > 1) { + std::sort(remoteData.begin(), remoteData.end(), [&](auto const& left, auto const& right) { + return _RemoteSimulationData::compare(left, right, sortSpecs) < 0; + }); + } } void _BrowserWindow::sortUserList() @@ -836,7 +840,7 @@ void _BrowserWindow::sortUserList() std::sort(_userList.begin(), _userList.end(), [&](auto const& left, auto const& right) { return UserData::compareOnlineAndTimestamp(left, right) > 0; }); } -void _BrowserWindow::onDownloadItem(RemoteSimulationData* sim) +void _BrowserWindow::onDownloadItem(BrowserSimulationData const& sim) { printOverlayMessage("Downloading ..."); @@ -899,13 +903,13 @@ void _BrowserWindow::onDownloadItem(RemoteSimulationData* sim) }); } -void _BrowserWindow::onDeleteItem(RemoteSimulationData* sim) +void _BrowserWindow::onDeleteItem(BrowserSimulationData const& sim) { MessageDialog::getInstance().yesNo("Delete item", "Do you really want to delete the selected item?", [sim, this]() { printOverlayMessage("Deleting ..."); - delayedExecution([remoteData = sim, this] { - if (!_networkController->deleteSimulation(remoteData->id)) { + delayedExecution([browserData = sim, this] { + if (!_networkController->deleteSimulation(browserData->id)) { MessageDialog::getInstance().information("Error", "Failed to delete item. Please try again later."); return; } @@ -914,7 +918,7 @@ void _BrowserWindow::onDeleteItem(RemoteSimulationData* sim) }); } -void _BrowserWindow::onToggleLike(RemoteSimulationData* sim, int emojiType) +void _BrowserWindow::onToggleLike(BrowserSimulationData const& sim, int emojiType) { if (_networkController->getLoggedInUserName()) { @@ -943,7 +947,7 @@ void _BrowserWindow::onToggleLike(RemoteSimulationData* sim, int emojiType) _userNamesByEmojiTypeBySimIdCache.erase(std::make_pair(sim->id, emojiType)); //invalidate cache entry _networkController->toggleLikeSimulation(sim->id, emojiType); - sortSimulationList(); + //_scheduleCreateBrowserData = true; } else { _loginDialog.lock()->open(); } @@ -976,11 +980,11 @@ std::string _BrowserWindow::getUserNamesToEmojiType(std::string const& simId, in return boost::algorithm::join(userNames, ", "); } -void _BrowserWindow::pushTextColor(RemoteSimulationData const& entry) +void _BrowserWindow::pushTextColor(BrowserSimulationData const& entry) { - if (VersionChecker::isVersionOutdated(entry.version)) { + if (VersionChecker::isVersionOutdated(entry->version)) { ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::VersionOutdatedColor); - } else if (VersionChecker::isVersionNewer(entry.version)) { + } else if (VersionChecker::isVersionNewer(entry->version)) { ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::VersionNewerColor); } else { ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::VersionOkColor); @@ -994,8 +998,8 @@ void _BrowserWindow::calcFilteredSimulationAndGenomeLists() _filteredRemoteGenomeList.clear(); _filteredRemoteGenomeList.reserve(_filteredRemoteGenomeList.size()); for (auto const& simData : _rawRemoteDataList) { - if (simData.matchWithFilter(_filter) &&_showCommunityCreations != simData.fromRelease) { - if (simData.type == RemoteDataType_Simulation) { + if (simData->matchWithFilter(_filter) &&_showCommunityCreations != simData->fromRelease) { + if (simData->type == RemoteDataType_Simulation) { _filteredRemoteSimulationList.emplace_back(simData); } else { _filteredRemoteGenomeList.emplace_back(simData); diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index 322c32d46..ed476a666 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -6,6 +6,7 @@ #include "EngineInterface/Definitions.h" #include "AlienWindow.h" +#include "BrowserSimulationData.h" #include "RemoteSimulationData.h" #include "UserData.h" #include "Definitions.h" @@ -42,9 +43,9 @@ class _BrowserWindow : public _AlienWindow void processEmojiWindow(); void processEmojiButton(int emojiType); - void processEmojiList(RemoteSimulationData* sim); + void processEmojiList(BrowserSimulationData const& sim); - void processActionButtons(RemoteSimulationData* simData); + void processActionButtons(BrowserSimulationData const& sim); void processShortenedText(std::string const& text, bool bold = false); bool processActionButton(std::string const& text); @@ -52,23 +53,23 @@ class _BrowserWindow : public _AlienWindow void processActivated() override; - void sortSimulationList(); + void sortRemoteSimulationData(std::vector& remoteData, ImGuiTableSortSpecs* sortSpecs); void sortUserList(); - void onDownloadItem(RemoteSimulationData* sim); - void onDeleteItem(RemoteSimulationData* sim); - void onToggleLike(RemoteSimulationData* sim, int emojiType); + void onDownloadItem(BrowserSimulationData const& sim); + void onDeleteItem(BrowserSimulationData const& sim); + void onToggleLike(BrowserSimulationData const& sim, int emojiType); void openWeblink(std::string const& link); bool isLiked(std::string const& simId); std::string getUserNamesToEmojiType(std::string const& simId, int emojiType); - void pushTextColor(RemoteSimulationData const& entry); + void pushTextColor(BrowserSimulationData const& entry); void calcFilteredSimulationAndGenomeLists(); DataType _selectedDataType = DataType_Simulation; bool _scheduleRefresh = false; - bool _scheduleSort = false; + bool _scheduleCreateBrowserData = false; std::string _filter; bool _showCommunityCreations = false; float _userTableWidth = 0; @@ -82,13 +83,16 @@ class _BrowserWindow : public _AlienWindow std::vector _filteredRemoteSimulationList; std::vector _filteredRemoteGenomeList; + std::vector _browserSimulationList; + std::vector _browserGenomeList; + std::vector _userList; std::vector _emojis; bool _activateEmojiPopup = false; bool _showAllEmojis = false; - RemoteSimulationData* _simOfEmojiPopup = nullptr; + BrowserSimulationData _simOfEmojiPopup; std::optional _lastRefreshTime; diff --git a/source/Gui/CMakeLists.txt b/source/Gui/CMakeLists.txt index e0ebc0f31..f97aa1ac0 100644 --- a/source/Gui/CMakeLists.txt +++ b/source/Gui/CMakeLists.txt @@ -13,6 +13,9 @@ PUBLIC AlienWindow.h AutosaveController.cpp AutosaveController.h + BrowserDataService.cpp + BrowserDataService.h + BrowserSimulationData.h BrowserWindow.cpp BrowserWindow.h CellFunctionStrings.h @@ -69,8 +72,8 @@ PUBLIC MultiplierWindow.h NetworkController.cpp NetworkController.h - NetworkDataParser.cpp - NetworkDataParser.h + NetworkDataParserService.cpp + NetworkDataParserService.h NetworkSettingsDialog.cpp NetworkSettingsDialog.h NewSimulationDialog.cpp diff --git a/source/Gui/Definitions.h b/source/Gui/Definitions.h index 7796ab88a..2c8f8aeb0 100644 --- a/source/Gui/Definitions.h +++ b/source/Gui/Definitions.h @@ -177,3 +177,9 @@ enum DataType_ DataType_Simulation, DataType_Genome }; + +class _BrowserSimulationData; +using BrowserSimulationData = std::shared_ptr<_BrowserSimulationData>; + +class _RemoteSimulationData; +using RemoteSimulationData = std::shared_ptr<_RemoteSimulationData>; diff --git a/source/Gui/NetworkController.cpp b/source/Gui/NetworkController.cpp index 0262606bb..05c079e22 100644 --- a/source/Gui/NetworkController.cpp +++ b/source/Gui/NetworkController.cpp @@ -10,7 +10,7 @@ #include "Base/Resources.h" #include "MessageDialog.h" -#include "NetworkDataParser.h" +#include "NetworkDataParserService.h" namespace { @@ -291,7 +291,7 @@ bool _NetworkController::getRemoteSimulationList(std::vectorbody); boost::property_tree::ptree tree; boost::property_tree::read_json(stream, tree); - result = NetworkDataParser::decodeRemoteSimulationData(tree); + result = NetworkDataParserService::decodeRemoteSimulationData(tree); return true; } catch (...) { logNetworkError(); @@ -314,7 +314,7 @@ bool _NetworkController::getUserList(std::vector& result, bool withRet boost::property_tree::ptree tree; boost::property_tree::read_json(stream, tree); result.clear(); - result = NetworkDataParser::decodeUserData(tree); + result = NetworkDataParserService::decodeUserData(tree); for (UserData& userData : result) { userData.timeSpent = userData.timeSpent * RefreshInterval / 60; } diff --git a/source/Gui/NetworkDataParser.cpp b/source/Gui/NetworkDataParser.cpp deleted file mode 100644 index ae426976a..000000000 --- a/source/Gui/NetworkDataParser.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "NetworkDataParser.h" - -std::vector NetworkDataParser::decodeRemoteSimulationData(boost::property_tree::ptree const& tree) -{ - std::vector result; - for (auto const& [key, subTree] : tree) { - RemoteSimulationData entry; - entry.id = subTree.get("id"); - entry.userName = subTree.get("userName"); - entry.simName = subTree.get("simulationName"); - entry.description= subTree.get("description"); - entry.width = subTree.get("width"); - entry.height = subTree.get("height"); - entry.particles = subTree.get("particles"); - entry.version = subTree.get("version"); - entry.timestamp = subTree.get("timestamp"); - entry.contentSize = std::stoll(subTree.get("contentSize")); - - bool isArray = false; - int counter = 0; - for (auto const& [likeTypeString, numLikesString] : subTree.get_child("likesByType")) { - auto likes = std::stoi(numLikesString.data()); - if (likeTypeString.empty()) { - isArray = true; - } - auto likeType = isArray ? counter : std::stoi(likeTypeString); - entry.numLikesByEmojiType[likeType] = likes; - ++counter; - } - entry.numDownloads = subTree.get("numDownloads"); - entry.fromRelease = subTree.get("fromRelease") == 1; - entry.type = subTree.get("type"); - result.emplace_back(entry); - } - return result; -} - -std::vector NetworkDataParser::decodeUserData(boost::property_tree::ptree const& tree) -{ - std::vector result; - for (auto const& [key, subTree] : tree) { - UserData entry; - entry.userName = subTree.get("userName"); - entry.starsReceived = subTree.get("starsReceived"); - entry.starsGiven = subTree.get("starsGiven"); - entry.timestamp = subTree.get("timestamp"); - entry.online = subTree.get("online"); - entry.lastDayOnline = subTree.get("lastDayOnline"); - entry.timeSpent = subTree.get("timeSpent"); - entry.gpu = subTree.get("gpu"); - result.emplace_back(entry); - } - return result; -} diff --git a/source/Gui/NetworkDataParserService.cpp b/source/Gui/NetworkDataParserService.cpp new file mode 100644 index 000000000..de42dc2c2 --- /dev/null +++ b/source/Gui/NetworkDataParserService.cpp @@ -0,0 +1,56 @@ +#include "NetworkDataParserService.h" + +#include "RemoteSimulationData.h" + +std::vector NetworkDataParserService::decodeRemoteSimulationData(boost::property_tree::ptree const& tree) +{ + std::vector result; + for (auto const& [key, subTree] : tree) { + auto entry = std::make_shared<_RemoteSimulationData>(); + entry->id = subTree.get("id"); + entry->userName = subTree.get("userName"); + entry->simName = subTree.get("simulationName"); + entry->description= subTree.get("description"); + entry->width = subTree.get("width"); + entry->height = subTree.get("height"); + entry->particles = subTree.get("particles"); + entry->version = subTree.get("version"); + entry->timestamp = subTree.get("timestamp"); + entry->contentSize = std::stoll(subTree.get("contentSize")); + + bool isArray = false; + int counter = 0; + for (auto const& [likeTypeString, numLikesString] : subTree.get_child("likesByType")) { + auto likes = std::stoi(numLikesString.data()); + if (likeTypeString.empty()) { + isArray = true; + } + auto likeType = isArray ? counter : std::stoi(likeTypeString); + entry->numLikesByEmojiType[likeType] = likes; + ++counter; + } + entry->numDownloads = subTree.get("numDownloads"); + entry->fromRelease = subTree.get("fromRelease") == 1; + entry->type = subTree.get("type"); + result.emplace_back(entry); + } + return result; +} + +std::vector NetworkDataParserService::decodeUserData(boost::property_tree::ptree const& tree) +{ + std::vector result; + for (auto const& [key, subTree] : tree) { + UserData entry; + entry.userName = subTree.get("userName"); + entry.starsReceived = subTree.get("starsReceived"); + entry.starsGiven = subTree.get("starsGiven"); + entry.timestamp = subTree.get("timestamp"); + entry.online = subTree.get("online"); + entry.lastDayOnline = subTree.get("lastDayOnline"); + entry.timeSpent = subTree.get("timeSpent"); + entry.gpu = subTree.get("gpu"); + result.emplace_back(entry); + } + return result; +} diff --git a/source/Gui/NetworkDataParser.h b/source/Gui/NetworkDataParserService.h similarity index 84% rename from source/Gui/NetworkDataParser.h rename to source/Gui/NetworkDataParserService.h index 08b333b7e..2a4fba75e 100644 --- a/source/Gui/NetworkDataParser.h +++ b/source/Gui/NetworkDataParserService.h @@ -3,10 +3,10 @@ #include #include -#include "RemoteSimulationData.h" #include "UserData.h" +#include "Definitions.h" -class NetworkDataParser +class NetworkDataParserService { public: static std::vector decodeRemoteSimulationData(boost::property_tree::ptree const& tree); diff --git a/source/Gui/RemoteSimulationData.cpp b/source/Gui/RemoteSimulationData.cpp index 310b75f37..111ebc46a 100644 --- a/source/Gui/RemoteSimulationData.cpp +++ b/source/Gui/RemoteSimulationData.cpp @@ -3,46 +3,44 @@ #include #include -int RemoteSimulationData::compare(void const* left, void const* right, ImGuiTableSortSpecs const* specs) +int _RemoteSimulationData::compare(RemoteSimulationData const& left, RemoteSimulationData const& right, ImGuiTableSortSpecs const* specs) { - auto leftImpl = reinterpret_cast(left); - auto rightImpl = reinterpret_cast(right); for (int n = 0; n < specs->SpecsCount; n++) { const ImGuiTableColumnSortSpecs* sortSpec = &specs->Specs[n]; int delta = 0; switch (sortSpec->ColumnUserID) { case RemoteSimulationDataColumnId_Timestamp: - delta = leftImpl->timestamp.compare(rightImpl->timestamp); + delta = left->timestamp.compare(right->timestamp); break; case RemoteSimulationDataColumnId_UserName: - delta = leftImpl->userName.compare(rightImpl->userName); + delta = left->userName.compare(right->userName); break; case RemoteSimulationDataColumnId_SimulationName: - delta = leftImpl->simName.compare(rightImpl->simName); + delta = left->simName.compare(right->simName); break; case RemoteSimulationDataColumnId_Description: - delta = leftImpl->description.compare(rightImpl->description); + delta = left->description.compare(right->description); break; case RemoteSimulationDataColumnId_Likes: - delta = leftImpl->getTotalLikes() - rightImpl->getTotalLikes(); + delta = left->getTotalLikes() - right->getTotalLikes(); break; case RemoteSimulationDataColumnId_NumDownloads: - delta = leftImpl->numDownloads - rightImpl->numDownloads; + delta = left->numDownloads - right->numDownloads; break; case RemoteSimulationDataColumnId_Width: - delta = leftImpl->width - rightImpl->width; + delta = left->width - right->width; break; case RemoteSimulationDataColumnId_Height: - delta = leftImpl->height - rightImpl->height; + delta = left->height - right->height; break; case RemoteSimulationDataColumnId_Particles: - delta = leftImpl->particles - rightImpl->particles; + delta = left->particles - right->particles; break; case RemoteSimulationDataColumnId_FileSize: - delta = static_cast(leftImpl->contentSize / 1024) - static_cast(rightImpl->contentSize / 1024); + delta = static_cast(left->contentSize / 1024) - static_cast(right->contentSize / 1024); break; case RemoteSimulationDataColumnId_Version: - delta = leftImpl->version.compare(rightImpl->version); + delta = left->version.compare(right->version); break; } if (delta > 0) { @@ -56,7 +54,7 @@ int RemoteSimulationData::compare(void const* left, void const* right, ImGuiTabl return 0; } -bool RemoteSimulationData::matchWithFilter(std::string const& filter) const +bool _RemoteSimulationData::matchWithFilter(std::string const& filter) const { auto match = false; if (timestamp.find(filter) != std::string::npos) { @@ -92,7 +90,7 @@ bool RemoteSimulationData::matchWithFilter(std::string const& filter) const return match; } -int RemoteSimulationData::getTotalLikes() const +int _RemoteSimulationData::getTotalLikes() const { int result = 0; for (auto const& numReactions : numLikesByEmojiType | std::views::values) { diff --git a/source/Gui/RemoteSimulationData.h b/source/Gui/RemoteSimulationData.h index 1f8ddbda0..1872e9615 100644 --- a/source/Gui/RemoteSimulationData.h +++ b/source/Gui/RemoteSimulationData.h @@ -3,6 +3,8 @@ #include #include +#include "Definitions.h" + class ImGuiTableSortSpecs; enum RemoteSimulationDataColumnId @@ -28,7 +30,7 @@ enum RemoteDataType_ RemoteDataType_Genome }; -class RemoteSimulationData +class _RemoteSimulationData { public: std::string id; @@ -46,7 +48,7 @@ class RemoteSimulationData bool fromRelease; RemoteDataType type; - static int compare(void const* left, void const* right, ImGuiTableSortSpecs const* specs); + static int compare(RemoteSimulationData const& left, RemoteSimulationData const& right, ImGuiTableSortSpecs const* specs); bool matchWithFilter(std::string const& filter) const; int getTotalLikes() const; diff --git a/vcpkg.json b/vcpkg.json index 21ee190ec..6a23ddab1 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "name": "alien", - "version": "4.5.1", + "version": "4.6.0", "dependencies": [ { "name": "glew", From 737744afd4036b4f830f1968f902552f292bd586 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Tue, 19 Dec 2023 19:32:28 +0100 Subject: [PATCH 03/40] browser data structures refactored, part 2 --- source/Gui/BrowserDataService.cpp | 2 +- source/Gui/BrowserDataService.h | 4 +- source/Gui/BrowserWindow.cpp | 76 +++++++++---------- source/Gui/BrowserWindow.h | 10 +-- source/Gui/CMakeLists.txt | 4 +- source/Gui/Definitions.h | 4 +- source/Gui/NetworkController.cpp | 4 +- source/Gui/NetworkController.h | 6 +- source/Gui/NetworkDataParserService.cpp | 10 +-- source/Gui/NetworkDataParserService.h | 2 +- ...teSimulationData.cpp => NetworkDataTO.cpp} | 30 ++++---- source/Gui/NetworkDataTO.h | 55 ++++++++++++++ source/Gui/RemoteSimulationData.h | 55 -------------- 13 files changed, 131 insertions(+), 131 deletions(-) rename source/Gui/{RemoteSimulationData.cpp => NetworkDataTO.cpp} (74%) create mode 100644 source/Gui/NetworkDataTO.h delete mode 100644 source/Gui/RemoteSimulationData.h diff --git a/source/Gui/BrowserDataService.cpp b/source/Gui/BrowserDataService.cpp index 2916d9dc3..f44f12cbe 100644 --- a/source/Gui/BrowserDataService.cpp +++ b/source/Gui/BrowserDataService.cpp @@ -2,7 +2,7 @@ #include "BrowserSimulationData.h" -std::vector BrowserDataService::createBrowserData(std::vector const& remoteData) +std::vector BrowserDataService::createBrowserData(std::vector const& remoteData) { std::vector result; result.reserve(remoteData.size()); diff --git a/source/Gui/BrowserDataService.h b/source/Gui/BrowserDataService.h index 01a086bfb..1b0b7919e 100644 --- a/source/Gui/BrowserDataService.h +++ b/source/Gui/BrowserDataService.h @@ -3,10 +3,10 @@ #include #include "Definitions.h" -#include "RemoteSimulationData.h" +#include "NetworkDataTO.h" class BrowserDataService { public: - static std::vector createBrowserData(std::vector const& remoteData); + static std::vector createBrowserData(std::vector const& remoteData); }; diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index cef5bfb94..bb49c40fc 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -103,7 +103,7 @@ void _BrowserWindow::onRefresh() void _BrowserWindow::refreshIntern(bool withRetry) { try { - bool success = _networkController->getRemoteSimulationList(_rawRemoteDataList, withRetry); + bool success = _networkController->getRemoteSimulationList(_rawNetworkDataTOs, withRetry); success &= _networkController->getUserList(_userList, withRetry); if (!success) { @@ -113,7 +113,7 @@ void _BrowserWindow::refreshIntern(bool withRetry) } else { _numSimulations = 0; _numGenomes = 0; - for (auto const& entry : _rawRemoteDataList) { + for (auto const& entry : _rawNetworkDataTOs) { if (entry->type == DataType_Simulation) { ++_numSimulations; } else { @@ -273,49 +273,49 @@ void _BrowserWindow::processSimulationList() "Actions", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, scale(90.0f), - RemoteSimulationDataColumnId_Actions); + NetworkDataColumnId_Actions); ImGui::TableSetupColumn( "Timestamp", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_PreferSortDescending, scale(135.0f), - RemoteSimulationDataColumnId_Timestamp); + NetworkDataColumnId_Timestamp); ImGui::TableSetupColumn( "User name", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), - RemoteSimulationDataColumnId_UserName); + NetworkDataColumnId_UserName); ImGui::TableSetupColumn( "Simulation name", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(160.0f), - RemoteSimulationDataColumnId_SimulationName); + NetworkDataColumnId_SimulationName); ImGui::TableSetupColumn( "Description", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), - RemoteSimulationDataColumnId_Description); + NetworkDataColumnId_Description); ImGui::TableSetupColumn( "Reactions", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), - RemoteSimulationDataColumnId_Likes); - ImGui::TableSetupColumn("Downloads", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, RemoteSimulationDataColumnId_NumDownloads); - ImGui::TableSetupColumn("Width", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, RemoteSimulationDataColumnId_Width); - ImGui::TableSetupColumn("Height", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, RemoteSimulationDataColumnId_Height); - ImGui::TableSetupColumn("Objects", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, RemoteSimulationDataColumnId_Particles); - ImGui::TableSetupColumn("File size", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, RemoteSimulationDataColumnId_FileSize); - ImGui::TableSetupColumn("Version", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, RemoteSimulationDataColumnId_Version); + NetworkDataColumnId_Likes); + ImGui::TableSetupColumn("Downloads", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_NumDownloads); + ImGui::TableSetupColumn("Width", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_Width); + ImGui::TableSetupColumn("Height", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_Height); + ImGui::TableSetupColumn("Objects", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_Particles); + ImGui::TableSetupColumn("File size", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_FileSize); + ImGui::TableSetupColumn("Version", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_Version); ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableHeadersRow(); //create table data if necessary if (ImGuiTableSortSpecs* sortSpecs = ImGui::TableGetSortSpecs()) { if (sortSpecs->SpecsDirty || _scheduleCreateBrowserData) { - sortRemoteSimulationData(_filteredRemoteSimulationList, sortSpecs); + sortRemoteSimulationData(_filteredNetworkSimulationTOs, sortSpecs); sortSpecs->SpecsDirty = false; _scheduleCreateBrowserData = false; - _browserSimulationList = BrowserDataService::createBrowserData(_filteredRemoteSimulationList); + _browserSimulationList = BrowserDataService::createBrowserData(_filteredNetworkSimulationTOs); } } ImGuiListClipper clipper; @@ -373,48 +373,48 @@ void _BrowserWindow::processGenomeList() if (ImGui::BeginTable("Browser", 10, flags, ImVec2(0, 0), 0.0f)) { ImGui::TableSetupColumn( - "Actions", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, scale(90.0f), RemoteSimulationDataColumnId_Actions); + "Actions", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, scale(90.0f), NetworkDataColumnId_Actions); ImGui::TableSetupColumn( "Timestamp", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_PreferSortDescending, scale(135.0f), - RemoteSimulationDataColumnId_Timestamp); + NetworkDataColumnId_Timestamp); ImGui::TableSetupColumn( "User name", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), - RemoteSimulationDataColumnId_UserName); + NetworkDataColumnId_UserName); ImGui::TableSetupColumn( "Genome name", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(160.0f), - RemoteSimulationDataColumnId_SimulationName); + NetworkDataColumnId_SimulationName); ImGui::TableSetupColumn( "Description", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), - RemoteSimulationDataColumnId_Description); + NetworkDataColumnId_Description); ImGui::TableSetupColumn( "Reactions", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), - RemoteSimulationDataColumnId_Likes); + NetworkDataColumnId_Likes); ImGui::TableSetupColumn( - "Downloads", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, RemoteSimulationDataColumnId_NumDownloads); - ImGui::TableSetupColumn("Cells", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, RemoteSimulationDataColumnId_Particles); - ImGui::TableSetupColumn("File size", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, RemoteSimulationDataColumnId_FileSize); - ImGui::TableSetupColumn("Version", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, RemoteSimulationDataColumnId_Version); + "Downloads", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_NumDownloads); + ImGui::TableSetupColumn("Cells", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_Particles); + ImGui::TableSetupColumn("File size", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_FileSize); + ImGui::TableSetupColumn("Version", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_Version); ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableHeadersRow(); //create table data if necessary if (ImGuiTableSortSpecs* sortSpecs = ImGui::TableGetSortSpecs()) { if (sortSpecs->SpecsDirty || _scheduleCreateBrowserData) { - sortRemoteSimulationData(_filteredRemoteGenomeList, sortSpecs); + sortRemoteSimulationData(_filteredNetworkGenomeTOs, sortSpecs); sortSpecs->SpecsDirty = false; _scheduleCreateBrowserData = false; - _browserGenomeList = BrowserDataService::createBrowserData(_filteredRemoteGenomeList); + _browserGenomeList = BrowserDataService::createBrowserData(_filteredNetworkGenomeTOs); } } ImGuiListClipper clipper; @@ -826,11 +826,11 @@ void _BrowserWindow::processActivated() onRefresh(); } -void _BrowserWindow::sortRemoteSimulationData(std::vector& remoteData, ImGuiTableSortSpecs* sortSpecs) +void _BrowserWindow::sortRemoteSimulationData(std::vector& remoteData, ImGuiTableSortSpecs* sortSpecs) { if (remoteData.size() > 1) { std::sort(remoteData.begin(), remoteData.end(), [&](auto const& left, auto const& right) { - return _RemoteSimulationData::compare(left, right, sortSpecs) < 0; + return _NetworkDataTO::compare(left, right, sortSpecs) < 0; }); } } @@ -993,16 +993,16 @@ void _BrowserWindow::pushTextColor(BrowserSimulationData const& entry) void _BrowserWindow::calcFilteredSimulationAndGenomeLists() { - _filteredRemoteSimulationList.clear(); - _filteredRemoteSimulationList.reserve(_rawRemoteDataList.size()); - _filteredRemoteGenomeList.clear(); - _filteredRemoteGenomeList.reserve(_filteredRemoteGenomeList.size()); - for (auto const& simData : _rawRemoteDataList) { + _filteredNetworkSimulationTOs.clear(); + _filteredNetworkSimulationTOs.reserve(_rawNetworkDataTOs.size()); + _filteredNetworkGenomeTOs.clear(); + _filteredNetworkGenomeTOs.reserve(_filteredNetworkGenomeTOs.size()); + for (auto const& simData : _rawNetworkDataTOs) { if (simData->matchWithFilter(_filter) &&_showCommunityCreations != simData->fromRelease) { - if (simData->type == RemoteDataType_Simulation) { - _filteredRemoteSimulationList.emplace_back(simData); + if (simData->type == NetworkDataType_Simulation) { + _filteredNetworkSimulationTOs.emplace_back(simData); } else { - _filteredRemoteGenomeList.emplace_back(simData); + _filteredNetworkGenomeTOs.emplace_back(simData); } } } diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index ed476a666..bfa065f38 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -7,7 +7,7 @@ #include "AlienWindow.h" #include "BrowserSimulationData.h" -#include "RemoteSimulationData.h" +#include "NetworkDataTO.h" #include "UserData.h" #include "Definitions.h" @@ -53,7 +53,7 @@ class _BrowserWindow : public _AlienWindow void processActivated() override; - void sortRemoteSimulationData(std::vector& remoteData, ImGuiTableSortSpecs* sortSpecs); + void sortRemoteSimulationData(std::vector& remoteData, ImGuiTableSortSpecs* sortSpecs); void sortUserList(); void onDownloadItem(BrowserSimulationData const& sim); @@ -79,9 +79,9 @@ class _BrowserWindow : public _AlienWindow int _numSimulations = 0; int _numGenomes = 0; - std::vector _rawRemoteDataList; - std::vector _filteredRemoteSimulationList; - std::vector _filteredRemoteGenomeList; + std::vector _rawNetworkDataTOs; + std::vector _filteredNetworkSimulationTOs; + std::vector _filteredNetworkGenomeTOs; std::vector _browserSimulationList; std::vector _browserGenomeList; diff --git a/source/Gui/CMakeLists.txt b/source/Gui/CMakeLists.txt index f97aa1ac0..608af3618 100644 --- a/source/Gui/CMakeLists.txt +++ b/source/Gui/CMakeLists.txt @@ -74,6 +74,8 @@ PUBLIC NetworkController.h NetworkDataParserService.cpp NetworkDataParserService.h + NetworkDataTO.cpp + NetworkDataTO.h NetworkSettingsDialog.cpp NetworkSettingsDialog.h NewSimulationDialog.cpp @@ -90,8 +92,6 @@ PUBLIC PatternEditorWindow.h RadiationSourcesWindow.cpp RadiationSourcesWindow.h - RemoteSimulationData.cpp - RemoteSimulationData.h ResetPasswordDialog.cpp ResetPasswordDialog.h ResizeWorldDialog.cpp diff --git a/source/Gui/Definitions.h b/source/Gui/Definitions.h index 2c8f8aeb0..f31f0c700 100644 --- a/source/Gui/Definitions.h +++ b/source/Gui/Definitions.h @@ -181,5 +181,5 @@ enum DataType_ class _BrowserSimulationData; using BrowserSimulationData = std::shared_ptr<_BrowserSimulationData>; -class _RemoteSimulationData; -using RemoteSimulationData = std::shared_ptr<_RemoteSimulationData>; +class _NetworkDataTO; +using NetworkDataTO = std::shared_ptr<_NetworkDataTO>; diff --git a/source/Gui/NetworkController.cpp b/source/Gui/NetworkController.cpp index 05c079e22..1d93bf01b 100644 --- a/source/Gui/NetworkController.cpp +++ b/source/Gui/NetworkController.cpp @@ -275,7 +275,7 @@ bool _NetworkController::setNewPassword(std::string const& userName, std::string } } -bool _NetworkController::getRemoteSimulationList(std::vector& result, bool withRetry) const +bool _NetworkController::getRemoteSimulationList(std::vector& result, bool withRetry) const { log(Priority::Important, "network: get simulation list"); @@ -414,7 +414,7 @@ bool _NetworkController::uploadSimulation( std::string const& mainData, std::string const& settings, std::string const& statistics, - RemoteDataType type) + NetworkDataType type) { log(Priority::Important, "network: upload simulation with name='" + simulationName + "'"); diff --git a/source/Gui/NetworkController.h b/source/Gui/NetworkController.h index 2d9e9d5d2..12d3d6dd8 100644 --- a/source/Gui/NetworkController.h +++ b/source/Gui/NetworkController.h @@ -2,7 +2,7 @@ #include -#include "RemoteSimulationData.h" +#include "NetworkDataTO.h" #include "UserData.h" #include "Definitions.h" @@ -40,7 +40,7 @@ class _NetworkController bool resetPassword(std::string const& userName, std::string const& email); bool setNewPassword(std::string const& userName, std::string const& newPassword, std::string const& confirmationCode); - bool getRemoteSimulationList(std::vector& result, bool withRetry) const; + bool getRemoteSimulationList(std::vector& result, bool withRetry) const; bool getUserList(std::vector& result, bool withRetry) const; bool getEmojiTypeBySimId(std::unordered_map& result) const; bool getUserNamesForSimulationAndEmojiType(std::set& result, std::string const& simId, int likeType); @@ -54,7 +54,7 @@ class _NetworkController std::string const& data, std::string const& settings, std::string const& statistics, - RemoteDataType type); + NetworkDataType type); bool downloadSimulation(std::string& mainData, std::string& auxiliaryData, std::string& statistics, std::string const& simId); bool deleteSimulation(std::string const& simId); diff --git a/source/Gui/NetworkDataParserService.cpp b/source/Gui/NetworkDataParserService.cpp index de42dc2c2..be188814f 100644 --- a/source/Gui/NetworkDataParserService.cpp +++ b/source/Gui/NetworkDataParserService.cpp @@ -1,12 +1,12 @@ #include "NetworkDataParserService.h" -#include "RemoteSimulationData.h" +#include "NetworkDataTO.h" -std::vector NetworkDataParserService::decodeRemoteSimulationData(boost::property_tree::ptree const& tree) +std::vector NetworkDataParserService::decodeRemoteSimulationData(boost::property_tree::ptree const& tree) { - std::vector result; + std::vector result; for (auto const& [key, subTree] : tree) { - auto entry = std::make_shared<_RemoteSimulationData>(); + auto entry = std::make_shared<_NetworkDataTO>(); entry->id = subTree.get("id"); entry->userName = subTree.get("userName"); entry->simName = subTree.get("simulationName"); @@ -31,7 +31,7 @@ std::vector NetworkDataParserService::decodeRemoteSimulati } entry->numDownloads = subTree.get("numDownloads"); entry->fromRelease = subTree.get("fromRelease") == 1; - entry->type = subTree.get("type"); + entry->type = subTree.get("type"); result.emplace_back(entry); } return result; diff --git a/source/Gui/NetworkDataParserService.h b/source/Gui/NetworkDataParserService.h index 2a4fba75e..951e48421 100644 --- a/source/Gui/NetworkDataParserService.h +++ b/source/Gui/NetworkDataParserService.h @@ -9,6 +9,6 @@ class NetworkDataParserService { public: - static std::vector decodeRemoteSimulationData(boost::property_tree::ptree const& tree); + static std::vector decodeRemoteSimulationData(boost::property_tree::ptree const& tree); static std::vector decodeUserData(boost::property_tree::ptree const& tree); }; \ No newline at end of file diff --git a/source/Gui/RemoteSimulationData.cpp b/source/Gui/NetworkDataTO.cpp similarity index 74% rename from source/Gui/RemoteSimulationData.cpp rename to source/Gui/NetworkDataTO.cpp index 111ebc46a..62dda063c 100644 --- a/source/Gui/RemoteSimulationData.cpp +++ b/source/Gui/NetworkDataTO.cpp @@ -1,45 +1,45 @@ -#include "RemoteSimulationData.h" +#include "NetworkDataTO.h" #include #include -int _RemoteSimulationData::compare(RemoteSimulationData const& left, RemoteSimulationData const& right, ImGuiTableSortSpecs const* specs) +int _NetworkDataTO::compare(NetworkDataTO const& left, NetworkDataTO const& right, ImGuiTableSortSpecs const* specs) { for (int n = 0; n < specs->SpecsCount; n++) { const ImGuiTableColumnSortSpecs* sortSpec = &specs->Specs[n]; int delta = 0; switch (sortSpec->ColumnUserID) { - case RemoteSimulationDataColumnId_Timestamp: + case NetworkDataColumnId_Timestamp: delta = left->timestamp.compare(right->timestamp); break; - case RemoteSimulationDataColumnId_UserName: + case NetworkDataColumnId_UserName: delta = left->userName.compare(right->userName); break; - case RemoteSimulationDataColumnId_SimulationName: + case NetworkDataColumnId_SimulationName: delta = left->simName.compare(right->simName); break; - case RemoteSimulationDataColumnId_Description: + case NetworkDataColumnId_Description: delta = left->description.compare(right->description); break; - case RemoteSimulationDataColumnId_Likes: + case NetworkDataColumnId_Likes: delta = left->getTotalLikes() - right->getTotalLikes(); break; - case RemoteSimulationDataColumnId_NumDownloads: + case NetworkDataColumnId_NumDownloads: delta = left->numDownloads - right->numDownloads; break; - case RemoteSimulationDataColumnId_Width: + case NetworkDataColumnId_Width: delta = left->width - right->width; break; - case RemoteSimulationDataColumnId_Height: + case NetworkDataColumnId_Height: delta = left->height - right->height; break; - case RemoteSimulationDataColumnId_Particles: + case NetworkDataColumnId_Particles: delta = left->particles - right->particles; break; - case RemoteSimulationDataColumnId_FileSize: + case NetworkDataColumnId_FileSize: delta = static_cast(left->contentSize / 1024) - static_cast(right->contentSize / 1024); break; - case RemoteSimulationDataColumnId_Version: + case NetworkDataColumnId_Version: delta = left->version.compare(right->version); break; } @@ -54,7 +54,7 @@ int _RemoteSimulationData::compare(RemoteSimulationData const& left, RemoteSimul return 0; } -bool _RemoteSimulationData::matchWithFilter(std::string const& filter) const +bool _NetworkDataTO::matchWithFilter(std::string const& filter) const { auto match = false; if (timestamp.find(filter) != std::string::npos) { @@ -90,7 +90,7 @@ bool _RemoteSimulationData::matchWithFilter(std::string const& filter) const return match; } -int _RemoteSimulationData::getTotalLikes() const +int _NetworkDataTO::getTotalLikes() const { int result = 0; for (auto const& numReactions : numLikesByEmojiType | std::views::values) { diff --git a/source/Gui/NetworkDataTO.h b/source/Gui/NetworkDataTO.h new file mode 100644 index 000000000..6c00ed8b9 --- /dev/null +++ b/source/Gui/NetworkDataTO.h @@ -0,0 +1,55 @@ +#pragma once + +#include +#include + +#include "Definitions.h" + +class ImGuiTableSortSpecs; + +enum NetworkDataColumnId +{ + NetworkDataColumnId_Timestamp, + NetworkDataColumnId_UserName, + NetworkDataColumnId_SimulationName, + NetworkDataColumnId_Description, + NetworkDataColumnId_Likes, + NetworkDataColumnId_NumDownloads, + NetworkDataColumnId_Width, + NetworkDataColumnId_Height, + NetworkDataColumnId_Particles, + NetworkDataColumnId_FileSize, + NetworkDataColumnId_Version, + NetworkDataColumnId_Actions +}; + +using NetworkDataType = int; +enum NetworkDataType_ +{ + NetworkDataType_Simulation, + NetworkDataType_Genome +}; + +class _NetworkDataTO +{ +public: + std::string id; + std::string timestamp; + std::string userName; + std::string simName; + std::map numLikesByEmojiType; + int numDownloads; + int width; + int height; + int particles; + uint64_t contentSize; + std::string description; + std::string version; + bool fromRelease; + NetworkDataType type; + + static int compare(NetworkDataTO const& left, NetworkDataTO const& right, ImGuiTableSortSpecs const* specs); + bool matchWithFilter(std::string const& filter) const; + + int getTotalLikes() const; +}; diff --git a/source/Gui/RemoteSimulationData.h b/source/Gui/RemoteSimulationData.h deleted file mode 100644 index 1872e9615..000000000 --- a/source/Gui/RemoteSimulationData.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include -#include - -#include "Definitions.h" - -class ImGuiTableSortSpecs; - -enum RemoteSimulationDataColumnId -{ - RemoteSimulationDataColumnId_Timestamp, - RemoteSimulationDataColumnId_UserName, - RemoteSimulationDataColumnId_SimulationName, - RemoteSimulationDataColumnId_Description, - RemoteSimulationDataColumnId_Likes, - RemoteSimulationDataColumnId_NumDownloads, - RemoteSimulationDataColumnId_Width, - RemoteSimulationDataColumnId_Height, - RemoteSimulationDataColumnId_Particles, - RemoteSimulationDataColumnId_FileSize, - RemoteSimulationDataColumnId_Version, - RemoteSimulationDataColumnId_Actions -}; - -using RemoteDataType = int; -enum RemoteDataType_ -{ - RemoteDataType_Simulation, - RemoteDataType_Genome -}; - -class _RemoteSimulationData -{ -public: - std::string id; - std::string timestamp; - std::string userName; - std::string simName; - std::map numLikesByEmojiType; - int numDownloads; - int width; - int height; - int particles; - uint64_t contentSize; - std::string description; - std::string version; - bool fromRelease; - RemoteDataType type; - - static int compare(RemoteSimulationData const& left, RemoteSimulationData const& right, ImGuiTableSortSpecs const* specs); - bool matchWithFilter(std::string const& filter) const; - - int getTotalLikes() const; -}; From c0a404cbbc5f5e5da00c15b976b3e242bc0d44ef Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Tue, 19 Dec 2023 19:38:11 +0100 Subject: [PATCH 04/40] browser data structures refactored, part 3 --- source/Gui/BrowserDataService.cpp | 8 +- source/Gui/BrowserDataService.h | 2 +- ...rowserSimulationData.h => BrowserDataTO.h} | 4 +- source/Gui/BrowserWindow.cpp | 92 +++++++++---------- source/Gui/BrowserWindow.h | 24 ++--- source/Gui/CMakeLists.txt | 4 +- source/Gui/Definitions.h | 4 +- source/Gui/NetworkController.cpp | 4 +- source/Gui/NetworkController.h | 4 +- source/Gui/NetworkDataParserService.cpp | 6 +- source/Gui/NetworkDataParserService.h | 4 +- source/Gui/{UserData.h => UserTO.h} | 5 +- 12 files changed, 82 insertions(+), 79 deletions(-) rename source/Gui/{BrowserSimulationData.h => BrowserDataTO.h} (91%) rename source/Gui/{UserData.h => UserTO.h} (82%) diff --git a/source/Gui/BrowserDataService.cpp b/source/Gui/BrowserDataService.cpp index f44f12cbe..d5aee508a 100644 --- a/source/Gui/BrowserDataService.cpp +++ b/source/Gui/BrowserDataService.cpp @@ -1,13 +1,13 @@ #include "BrowserDataService.h" -#include "BrowserSimulationData.h" +#include "BrowserDataTO.h" -std::vector BrowserDataService::createBrowserData(std::vector const& remoteData) +std::vector BrowserDataService::createBrowserData(std::vector const& remoteData) { - std::vector result; + std::vector result; result.reserve(remoteData.size()); for (auto const& entry : remoteData) { - auto browserData = std::make_shared<_BrowserSimulationData>(); + auto browserData = std::make_shared<_BrowserDataTO>(); browserData->id = entry->id; browserData->timestamp = entry->timestamp; browserData->userName = entry->userName; diff --git a/source/Gui/BrowserDataService.h b/source/Gui/BrowserDataService.h index 1b0b7919e..fb673df80 100644 --- a/source/Gui/BrowserDataService.h +++ b/source/Gui/BrowserDataService.h @@ -8,5 +8,5 @@ class BrowserDataService { public: - static std::vector createBrowserData(std::vector const& remoteData); + static std::vector createBrowserData(std::vector const& remoteData); }; diff --git a/source/Gui/BrowserSimulationData.h b/source/Gui/BrowserDataTO.h similarity index 91% rename from source/Gui/BrowserSimulationData.h rename to source/Gui/BrowserDataTO.h index f0f6a9616..7df66e420 100644 --- a/source/Gui/BrowserSimulationData.h +++ b/source/Gui/BrowserDataTO.h @@ -3,6 +3,8 @@ #include #include +#include "Definitions.h" + using BrowserDataType = int; enum BrowserDataType_ { @@ -10,7 +12,7 @@ enum BrowserDataType_ BrowserDataType_Genome }; -class _BrowserSimulationData +class _BrowserDataTO { public: std::string id; diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index bb49c40fc..6d7417b61 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -104,7 +104,7 @@ void _BrowserWindow::refreshIntern(bool withRetry) { try { bool success = _networkController->getRemoteSimulationList(_rawNetworkDataTOs, withRetry); - success &= _networkController->getUserList(_userList, withRetry); + success &= _networkController->getUserList(_userTOs, withRetry); if (!success) { if (withRetry) { @@ -315,14 +315,14 @@ void _BrowserWindow::processSimulationList() sortSpecs->SpecsDirty = false; _scheduleCreateBrowserData = false; - _browserSimulationList = BrowserDataService::createBrowserData(_filteredNetworkSimulationTOs); + _browserSimulationTOs = BrowserDataService::createBrowserData(_filteredNetworkSimulationTOs); } } ImGuiListClipper clipper; - clipper.Begin(_browserSimulationList.size()); + clipper.Begin(_browserSimulationTOs.size()); while (clipper.Step()) for (int row = clipper.DisplayStart; row < clipper.DisplayEnd; row++) { - auto item = _browserSimulationList[row]; + auto item = _browserSimulationTOs[row]; ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); @@ -414,15 +414,15 @@ void _BrowserWindow::processGenomeList() sortSpecs->SpecsDirty = false; _scheduleCreateBrowserData = false; - _browserGenomeList = BrowserDataService::createBrowserData(_filteredNetworkGenomeTOs); + _browserGenomeTOs = BrowserDataService::createBrowserData(_filteredNetworkGenomeTOs); } } ImGuiListClipper clipper; - clipper.Begin(_browserGenomeList.size()); + clipper.Begin(_browserGenomeTOs.size()); while (clipper.Step()) for (int row = clipper.DisplayStart; row < clipper.DisplayEnd; row++) { - auto& item = _browserGenomeList[row]; + auto& item = _browserGenomeTOs[row]; ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); @@ -493,10 +493,10 @@ void _BrowserWindow::processUserList() ImGui::TableHeadersRow(); ImGuiListClipper clipper; - clipper.Begin(_userList.size()); + clipper.Begin(_userTOs.size()); while (clipper.Step()) { for (int row = clipper.DisplayStart; row < clipper.DisplayEnd; row++) { - auto item = &_userList[row]; + auto item = &_userTOs[row]; ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); @@ -551,7 +551,7 @@ void _BrowserWindow::processStatus() statusText += std::to_string(_numGenomes) + " genomes found"; statusText += std::string(" " ICON_FA_INFO_CIRCLE " "); - statusText += std::to_string(_userList.size()) + " simulators found"; + statusText += std::to_string(_userTOs.size()) + " simulators found"; statusText += std::string(" " ICON_FA_INFO_CIRCLE " "); if (auto userName = _networkController->getLoggedInUserName()) { @@ -640,7 +640,7 @@ void _BrowserWindow::processEmojiButton(int emojiType) auto cursorPos = ImGui::GetCursorScreenPos(); auto emojiWidth = scale(toFloat(emoji.width)); auto emojiHeight = scale(toFloat(emoji.height)); - auto sim = _simOfEmojiPopup; + auto sim = _emojiPopupTO; if (ImGui::ImageButton((void*)(intptr_t)emoji.textureId, {emojiWidth, emojiHeight}, {0, 0}, {1.0f, 1.0f})) { onToggleLike(sim, toInt(emojiType)); ImGui::CloseCurrentPopup(); @@ -659,17 +659,17 @@ void _BrowserWindow::processEmojiButton(int emojiType) } } -void _BrowserWindow::processEmojiList(BrowserSimulationData const& sim) +void _BrowserWindow::processEmojiList(BrowserDataTO const& to) { //calc remap which allows to show most frequent like type first std::map remap; std::set processedEmojiTypes; int index = 0; - while (processedEmojiTypes.size() < sim->numLikesByEmojiType.size()) { + while (processedEmojiTypes.size() < to->numLikesByEmojiType.size()) { int maxLikes = 0; std::optional maxEmojiType; - for (auto const& [emojiType, numLikes] : sim->numLikesByEmojiType) { + for (auto const& [emojiType, numLikes] : to->numLikesByEmojiType) { if (!processedEmojiTypes.contains(emojiType) && numLikes > maxLikes) { maxLikes = numLikes; maxEmojiType = emojiType; @@ -684,7 +684,7 @@ void _BrowserWindow::processEmojiList(BrowserSimulationData const& sim) int counter = 0; std::optional toggleEmojiType; for (auto const& emojiType : remap | std::views::values) { - auto numLikes = sim->numLikesByEmojiType.at(emojiType); + auto numLikes = to->numLikesByEmojiType.at(emojiType); AlienImGui::Text(std::to_string(numLikes)); ImGui::SameLine(); @@ -703,31 +703,31 @@ void _BrowserWindow::processEmojiList(BrowserSimulationData const& sim) 0)) { toggleEmojiType = emojiType; } - bool isLiked = _ownEmojiTypeBySimId.contains(sim->id) && _ownEmojiTypeBySimId.at(sim->id) == emojiType; + bool isLiked = _ownEmojiTypeBySimId.contains(to->id) && _ownEmojiTypeBySimId.at(to->id) == emojiType; if (isLiked) { ImDrawList* drawList = ImGui::GetWindowDrawList(); drawList->AddRect( ImVec2(cursorPos.x, cursorPos.y), ImVec2(cursorPos.x + emojiWidth, cursorPos.y + emojiHeight), (ImU32)ImColor::HSV(0, 0, 1, 0.5f), 1.0f); } ImGui::PopStyleColor(2); - AlienImGui::Tooltip([=, this] { return getUserNamesToEmojiType(sim->id, emojiType); }, false); + AlienImGui::Tooltip([=, this] { return getUserNamesToEmojiType(to->id, emojiType); }, false); } //separator except for last element - if (++counter < sim->numLikesByEmojiType.size()) { + if (++counter < to->numLikesByEmojiType.size()) { ImGui::SameLine(); ImGui::SetCursorPosX(ImGui::GetCursorPosX() - scale(4.0f)); } } if (toggleEmojiType) { - onToggleLike(sim, *toggleEmojiType); + onToggleLike(to, *toggleEmojiType); } } -void _BrowserWindow::processActionButtons(BrowserSimulationData const& sim) +void _BrowserWindow::processActionButtons(BrowserDataTO const& to) { //like button - auto liked = isLiked(sim->id); + auto liked = isLiked(to->id); if (liked) { ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::LikeButtonTextColor); } else { @@ -737,7 +737,7 @@ void _BrowserWindow::processActionButtons(BrowserSimulationData const& sim) ImGui::PopStyleColor(); if (likeButtonResult) { _activateEmojiPopup = true; - _simOfEmojiPopup = sim; + _emojiPopupTO = to; } AlienImGui::Tooltip("Choose a reaction"); ImGui::SameLine(); @@ -747,18 +747,18 @@ void _BrowserWindow::processActionButtons(BrowserSimulationData const& sim) auto downloadButtonResult = processActionButton(ICON_FA_DOWNLOAD); ImGui::PopStyleColor(); if (downloadButtonResult) { - onDownloadItem(sim); + onDownloadItem(to); } AlienImGui::Tooltip("Download"); ImGui::SameLine(); //delete button - if (sim->userName == _networkController->getLoggedInUserName().value_or("")) { + if (to->userName == _networkController->getLoggedInUserName().value_or("")) { ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DeleteButtonTextColor); auto deleteButtonResult = processActionButton(ICON_FA_TRASH); ImGui::PopStyleColor(); if (deleteButtonResult) { - onDeleteItem(sim); + onDeleteItem(to); } AlienImGui::Tooltip("Delete"); } @@ -837,17 +837,17 @@ void _BrowserWindow::sortRemoteSimulationData(std::vector& remote void _BrowserWindow::sortUserList() { - std::sort(_userList.begin(), _userList.end(), [&](auto const& left, auto const& right) { return UserData::compareOnlineAndTimestamp(left, right) > 0; }); + std::sort(_userTOs.begin(), _userTOs.end(), [&](auto const& left, auto const& right) { return UserTO::compareOnlineAndTimestamp(left, right) > 0; }); } -void _BrowserWindow::onDownloadItem(BrowserSimulationData const& sim) +void _BrowserWindow::onDownloadItem(BrowserDataTO const& to) { printOverlayMessage("Downloading ..."); delayedExecution([=, this] { std::string dataTypeString = _selectedDataType == DataType_Simulation ? "simulation" : "genome"; SerializedSimulation serializedSim; - if (!_networkController->downloadSimulation(serializedSim.mainData, serializedSim.auxiliaryData, serializedSim.statistics, sim->id)) { + if (!_networkController->downloadSimulation(serializedSim.mainData, serializedSim.auxiliaryData, serializedSim.statistics, to->id)) { MessageDialog::getInstance().information("Error", "Failed to download " + dataTypeString + "."); return; } @@ -893,7 +893,7 @@ void _BrowserWindow::onDownloadItem(BrowserSimulationData const& sim) _editorController->setOn(true); _editorController->getGenomeEditorWindow()->openTab(GenomeDescriptionService::convertBytesToDescription(genome)); } - if (VersionChecker::isVersionNewer(sim->version)) { + if (VersionChecker::isVersionNewer(to->version)) { MessageDialog::getInstance().information( "Warning", "The download was successful but the " + dataTypeString +" was generated using a more recent\n" @@ -903,12 +903,12 @@ void _BrowserWindow::onDownloadItem(BrowserSimulationData const& sim) }); } -void _BrowserWindow::onDeleteItem(BrowserSimulationData const& sim) +void _BrowserWindow::onDeleteItem(BrowserDataTO const& to) { - MessageDialog::getInstance().yesNo("Delete item", "Do you really want to delete the selected item?", [sim, this]() { + MessageDialog::getInstance().yesNo("Delete item", "Do you really want to delete the selected item?", [to, this]() { printOverlayMessage("Deleting ..."); - delayedExecution([browserData = sim, this] { + delayedExecution([browserData = to, this] { if (!_networkController->deleteSimulation(browserData->id)) { MessageDialog::getInstance().information("Error", "Failed to delete item. Please try again later."); return; @@ -918,35 +918,35 @@ void _BrowserWindow::onDeleteItem(BrowserSimulationData const& sim) }); } -void _BrowserWindow::onToggleLike(BrowserSimulationData const& sim, int emojiType) +void _BrowserWindow::onToggleLike(BrowserDataTO const& to, int emojiType) { if (_networkController->getLoggedInUserName()) { //remove existing like - auto findResult = _ownEmojiTypeBySimId.find(sim->id); + auto findResult = _ownEmojiTypeBySimId.find(to->id); auto onlyRemoveLike = false; if (findResult != _ownEmojiTypeBySimId.end()) { auto origEmojiType = findResult->second; - if (--sim->numLikesByEmojiType[origEmojiType] == 0) { - sim->numLikesByEmojiType.erase(origEmojiType); + if (--to->numLikesByEmojiType[origEmojiType] == 0) { + to->numLikesByEmojiType.erase(origEmojiType); } _ownEmojiTypeBySimId.erase(findResult); - _userNamesByEmojiTypeBySimIdCache.erase(std::make_pair(sim->id, origEmojiType)); //invalidate cache entry + _userNamesByEmojiTypeBySimIdCache.erase(std::make_pair(to->id, origEmojiType)); //invalidate cache entry onlyRemoveLike = origEmojiType == emojiType; //remove like if same like icon has been clicked } //create new like if (!onlyRemoveLike) { - _ownEmojiTypeBySimId[sim->id] = emojiType; - if (sim->numLikesByEmojiType.contains(emojiType)) { - ++sim->numLikesByEmojiType[emojiType]; + _ownEmojiTypeBySimId[to->id] = emojiType; + if (to->numLikesByEmojiType.contains(emojiType)) { + ++to->numLikesByEmojiType[emojiType]; } else { - sim->numLikesByEmojiType[emojiType] = 1; + to->numLikesByEmojiType[emojiType] = 1; } } - _userNamesByEmojiTypeBySimIdCache.erase(std::make_pair(sim->id, emojiType)); //invalidate cache entry - _networkController->toggleLikeSimulation(sim->id, emojiType); + _userNamesByEmojiTypeBySimIdCache.erase(std::make_pair(to->id, emojiType)); //invalidate cache entry + _networkController->toggleLikeSimulation(to->id, emojiType); //_scheduleCreateBrowserData = true; } else { _loginDialog.lock()->open(); @@ -980,11 +980,11 @@ std::string _BrowserWindow::getUserNamesToEmojiType(std::string const& simId, in return boost::algorithm::join(userNames, ", "); } -void _BrowserWindow::pushTextColor(BrowserSimulationData const& entry) +void _BrowserWindow::pushTextColor(BrowserDataTO const& to) { - if (VersionChecker::isVersionOutdated(entry->version)) { + if (VersionChecker::isVersionOutdated(to->version)) { ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::VersionOutdatedColor); - } else if (VersionChecker::isVersionNewer(entry->version)) { + } else if (VersionChecker::isVersionNewer(to->version)) { ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::VersionNewerColor); } else { ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::VersionOkColor); diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index bfa065f38..d370663ae 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -6,9 +6,9 @@ #include "EngineInterface/Definitions.h" #include "AlienWindow.h" -#include "BrowserSimulationData.h" +#include "BrowserDataTO.h" #include "NetworkDataTO.h" -#include "UserData.h" +#include "UserTO.h" #include "Definitions.h" class _BrowserWindow : public _AlienWindow @@ -43,9 +43,9 @@ class _BrowserWindow : public _AlienWindow void processEmojiWindow(); void processEmojiButton(int emojiType); - void processEmojiList(BrowserSimulationData const& sim); + void processEmojiList(BrowserDataTO const& to); - void processActionButtons(BrowserSimulationData const& sim); + void processActionButtons(BrowserDataTO const& to); void processShortenedText(std::string const& text, bool bold = false); bool processActionButton(std::string const& text); @@ -56,15 +56,15 @@ class _BrowserWindow : public _AlienWindow void sortRemoteSimulationData(std::vector& remoteData, ImGuiTableSortSpecs* sortSpecs); void sortUserList(); - void onDownloadItem(BrowserSimulationData const& sim); - void onDeleteItem(BrowserSimulationData const& sim); - void onToggleLike(BrowserSimulationData const& sim, int emojiType); + void onDownloadItem(BrowserDataTO const& to); + void onDeleteItem(BrowserDataTO const& to); + void onToggleLike(BrowserDataTO const& to, int emojiType); void openWeblink(std::string const& link); bool isLiked(std::string const& simId); std::string getUserNamesToEmojiType(std::string const& simId, int emojiType); - void pushTextColor(BrowserSimulationData const& entry); + void pushTextColor(BrowserDataTO const& to); void calcFilteredSimulationAndGenomeLists(); DataType _selectedDataType = DataType_Simulation; @@ -83,16 +83,16 @@ class _BrowserWindow : public _AlienWindow std::vector _filteredNetworkSimulationTOs; std::vector _filteredNetworkGenomeTOs; - std::vector _browserSimulationList; - std::vector _browserGenomeList; + std::vector _browserSimulationTOs; + std::vector _browserGenomeTOs; - std::vector _userList; + std::vector _userTOs; std::vector _emojis; bool _activateEmojiPopup = false; bool _showAllEmojis = false; - BrowserSimulationData _simOfEmojiPopup; + BrowserDataTO _emojiPopupTO; std::optional _lastRefreshTime; diff --git a/source/Gui/CMakeLists.txt b/source/Gui/CMakeLists.txt index 608af3618..7f9f57ec3 100644 --- a/source/Gui/CMakeLists.txt +++ b/source/Gui/CMakeLists.txt @@ -15,7 +15,7 @@ PUBLIC AutosaveController.h BrowserDataService.cpp BrowserDataService.h - BrowserSimulationData.h + BrowserDataTO.h BrowserWindow.cpp BrowserWindow.h CellFunctionStrings.h @@ -124,7 +124,7 @@ PUBLIC UiController.h UploadSimulationDialog.cpp UploadSimulationDialog.h - UserData.h + UserTO.h Viewport.cpp Viewport.h WindowController.cpp diff --git a/source/Gui/Definitions.h b/source/Gui/Definitions.h index f31f0c700..5973aef1f 100644 --- a/source/Gui/Definitions.h +++ b/source/Gui/Definitions.h @@ -178,8 +178,8 @@ enum DataType_ DataType_Genome }; -class _BrowserSimulationData; -using BrowserSimulationData = std::shared_ptr<_BrowserSimulationData>; +class _BrowserDataTO; +using BrowserDataTO = std::shared_ptr<_BrowserDataTO>; class _NetworkDataTO; using NetworkDataTO = std::shared_ptr<_NetworkDataTO>; diff --git a/source/Gui/NetworkController.cpp b/source/Gui/NetworkController.cpp index 1d93bf01b..8e527b1c7 100644 --- a/source/Gui/NetworkController.cpp +++ b/source/Gui/NetworkController.cpp @@ -299,7 +299,7 @@ bool _NetworkController::getRemoteSimulationList(std::vector& res } } -bool _NetworkController::getUserList(std::vector& result, bool withRetry) const +bool _NetworkController::getUserList(std::vector& result, bool withRetry) const { log(Priority::Important, "network: get user list"); @@ -315,7 +315,7 @@ bool _NetworkController::getUserList(std::vector& result, bool withRet boost::property_tree::read_json(stream, tree); result.clear(); result = NetworkDataParserService::decodeUserData(tree); - for (UserData& userData : result) { + for (UserTO& userData : result) { userData.timeSpent = userData.timeSpent * RefreshInterval / 60; } return true; diff --git a/source/Gui/NetworkController.h b/source/Gui/NetworkController.h index 12d3d6dd8..d59de4547 100644 --- a/source/Gui/NetworkController.h +++ b/source/Gui/NetworkController.h @@ -3,7 +3,7 @@ #include #include "NetworkDataTO.h" -#include "UserData.h" +#include "UserTO.h" #include "Definitions.h" using LoginErrorCode = int; @@ -41,7 +41,7 @@ class _NetworkController bool setNewPassword(std::string const& userName, std::string const& newPassword, std::string const& confirmationCode); bool getRemoteSimulationList(std::vector& result, bool withRetry) const; - bool getUserList(std::vector& result, bool withRetry) const; + bool getUserList(std::vector& result, bool withRetry) const; bool getEmojiTypeBySimId(std::unordered_map& result) const; bool getUserNamesForSimulationAndEmojiType(std::set& result, std::string const& simId, int likeType); bool toggleLikeSimulation(std::string const& simId, int likeType); diff --git a/source/Gui/NetworkDataParserService.cpp b/source/Gui/NetworkDataParserService.cpp index be188814f..0f88e96d5 100644 --- a/source/Gui/NetworkDataParserService.cpp +++ b/source/Gui/NetworkDataParserService.cpp @@ -37,11 +37,11 @@ std::vector NetworkDataParserService::decodeRemoteSimulationData( return result; } -std::vector NetworkDataParserService::decodeUserData(boost::property_tree::ptree const& tree) +std::vector NetworkDataParserService::decodeUserData(boost::property_tree::ptree const& tree) { - std::vector result; + std::vector result; for (auto const& [key, subTree] : tree) { - UserData entry; + UserTO entry; entry.userName = subTree.get("userName"); entry.starsReceived = subTree.get("starsReceived"); entry.starsGiven = subTree.get("starsGiven"); diff --git a/source/Gui/NetworkDataParserService.h b/source/Gui/NetworkDataParserService.h index 951e48421..e8b077b22 100644 --- a/source/Gui/NetworkDataParserService.h +++ b/source/Gui/NetworkDataParserService.h @@ -3,12 +3,12 @@ #include #include -#include "UserData.h" +#include "UserTO.h" #include "Definitions.h" class NetworkDataParserService { public: static std::vector decodeRemoteSimulationData(boost::property_tree::ptree const& tree); - static std::vector decodeUserData(boost::property_tree::ptree const& tree); + static std::vector decodeUserData(boost::property_tree::ptree const& tree); }; \ No newline at end of file diff --git a/source/Gui/UserData.h b/source/Gui/UserTO.h similarity index 82% rename from source/Gui/UserData.h rename to source/Gui/UserTO.h index 143c3c64a..4bb7fbd0e 100644 --- a/source/Gui/UserData.h +++ b/source/Gui/UserTO.h @@ -1,7 +1,8 @@ #pragma once + #include -class UserData +class UserTO { public: std::string userName; @@ -13,7 +14,7 @@ class UserData int timeSpent; std::string gpu; - static int compareOnlineAndTimestamp(UserData const& left, UserData const& right) + static int compareOnlineAndTimestamp(UserTO const& left, UserTO const& right) { if (int result = static_cast(left.online) - static_cast(right.online)) { return result; From e0e0c7088a91a3a11ebc6e312d31cb4c46f69711 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Tue, 19 Dec 2023 21:38:09 +0100 Subject: [PATCH 05/40] BrowserDataTO comprises BrowserLeaf and BrowserFolder --- source/Gui/BrowserDataService.cpp | 31 ++-- source/Gui/BrowserDataTO.cpp | 16 ++ source/Gui/BrowserDataTO.h | 20 ++- source/Gui/BrowserWindow.cpp | 256 ++++++++++++++++-------------- source/Gui/BrowserWindow.h | 4 +- source/Gui/CMakeLists.txt | 1 + source/Gui/Definitions.h | 4 +- source/Gui/NetworkDataTO.h | 3 +- source/Gui/StyleRepository.h | 2 + 9 files changed, 195 insertions(+), 142 deletions(-) create mode 100644 source/Gui/BrowserDataTO.cpp diff --git a/source/Gui/BrowserDataService.cpp b/source/Gui/BrowserDataService.cpp index d5aee508a..0a7d2b041 100644 --- a/source/Gui/BrowserDataService.cpp +++ b/source/Gui/BrowserDataService.cpp @@ -8,20 +8,25 @@ std::vector BrowserDataService::createBrowserData(std::vector(); - browserData->id = entry->id; - browserData->timestamp = entry->timestamp; - browserData->userName = entry->userName; - browserData->simName = entry->simName; - browserData->numLikesByEmojiType = entry->numLikesByEmojiType; - browserData->numDownloads = entry->numDownloads; - browserData->width = entry->width; - browserData->height = entry->height; - browserData->particles = entry->particles; - browserData->contentSize = entry->contentSize; - browserData->description = entry->description; - browserData->version = entry->version; - browserData->fromRelease = entry->fromRelease; + + BrowserLeaf leaf{ + .id = entry->id, + .timestamp = entry->timestamp, + .userName = entry->userName, + .simName = entry->simName, + .numLikesByEmojiType = entry->numLikesByEmojiType, + .numDownloads = entry->numDownloads, + .width = entry->width, + .height = entry->height, + .particles = entry->particles, + .contentSize = entry->contentSize, + .description = entry->description, + .version = entry->version + }; + browserData->type = entry->type; + browserData->level = 0; + browserData->node = leaf; result.emplace_back(browserData); } diff --git a/source/Gui/BrowserDataTO.cpp b/source/Gui/BrowserDataTO.cpp new file mode 100644 index 000000000..dbcc5cc2f --- /dev/null +++ b/source/Gui/BrowserDataTO.cpp @@ -0,0 +1,16 @@ +#include "BrowserDataTO.h" + +bool _BrowserDataTO::isLeaf() +{ + return std::holds_alternative(node); +} + +BrowserLeaf& _BrowserDataTO::getLeaf() +{ + return std::get(node); +} + +BrowserFolder& _BrowserDataTO::getFolder() +{ + return std::get(node); +} diff --git a/source/Gui/BrowserDataTO.h b/source/Gui/BrowserDataTO.h index 7df66e420..74ff41077 100644 --- a/source/Gui/BrowserDataTO.h +++ b/source/Gui/BrowserDataTO.h @@ -2,6 +2,7 @@ #include #include +#include #include "Definitions.h" @@ -12,9 +13,12 @@ enum BrowserDataType_ BrowserDataType_Genome }; -class _BrowserDataTO +struct BrowserFolder +{ +}; + +struct BrowserLeaf { -public: std::string id; std::string timestamp; std::string userName; @@ -27,7 +31,15 @@ class _BrowserDataTO uint64_t contentSize; std::string description; std::string version; - bool fromRelease; +}; + +struct _BrowserDataTO +{ BrowserDataType type; + int level; + std::variant node; + + bool isLeaf(); + BrowserLeaf& getLeaf(); + BrowserFolder& getFolder(); }; - diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 6d7417b61..ec9367c36 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -327,34 +327,37 @@ void _BrowserWindow::processSimulationList() ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); - ImGui::TableNextColumn(); - processActionButtons(item); - ImGui::TableNextColumn(); - pushTextColor(item); - AlienImGui::Text(item->timestamp); - ImGui::TableNextColumn(); - processShortenedText(item->userName); - ImGui::TableNextColumn(); - processShortenedText(item->simName); - ImGui::TableNextColumn(); - processShortenedText(item->description); - ImGui::TableNextColumn(); - processEmojiList(item); - - ImGui::TableNextColumn(); - AlienImGui::Text(std::to_string(item->numDownloads)); - ImGui::TableNextColumn(); - AlienImGui::Text(std::to_string(item->width)); - ImGui::TableNextColumn(); - AlienImGui::Text(std::to_string(item->height)); - ImGui::TableNextColumn(); - AlienImGui::Text(StringHelper::format(item->particles / 1000) + " K"); - ImGui::TableNextColumn(); - AlienImGui::Text(StringHelper::format(item->contentSize / 1024) + " KB"); - ImGui::TableNextColumn(); - AlienImGui::Text(item->version); - - ImGui::PopStyleColor(); + if (item->isLeaf()) { + auto& leaf = item->getLeaf(); + ImGui::TableNextColumn(); + processActionButtons(item); + ImGui::TableNextColumn(); + pushTextColor(item); + AlienImGui::Text(leaf.timestamp); + ImGui::TableNextColumn(); + processShortenedText(leaf.userName); + ImGui::TableNextColumn(); + processShortenedText(leaf.simName); + ImGui::TableNextColumn(); + processShortenedText(leaf.description); + ImGui::TableNextColumn(); + processEmojiList(item); + + ImGui::TableNextColumn(); + AlienImGui::Text(std::to_string(leaf.numDownloads)); + ImGui::TableNextColumn(); + AlienImGui::Text(std::to_string(leaf.width)); + ImGui::TableNextColumn(); + AlienImGui::Text(std::to_string(leaf.height)); + ImGui::TableNextColumn(); + AlienImGui::Text(StringHelper::format(leaf.particles / 1000) + " K"); + ImGui::TableNextColumn(); + AlienImGui::Text(StringHelper::format(leaf.contentSize / 1024) + " KB"); + ImGui::TableNextColumn(); + AlienImGui::Text(leaf.version); + + ImGui::PopStyleColor(); + } ImGui::PopID(); } ImGui::EndTable(); @@ -427,30 +430,34 @@ void _BrowserWindow::processGenomeList() ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); - ImGui::TableNextColumn(); - processActionButtons(item); - ImGui::TableNextColumn(); - pushTextColor(item); - AlienImGui::Text(item->timestamp); - ImGui::TableNextColumn(); - processShortenedText(item->userName); - ImGui::TableNextColumn(); - processShortenedText(item->simName); - ImGui::TableNextColumn(); - processShortenedText(item->description); - ImGui::TableNextColumn(); - processEmojiList(item); - - ImGui::TableNextColumn(); - AlienImGui::Text(std::to_string(item->numDownloads)); - ImGui::TableNextColumn(); - AlienImGui::Text(StringHelper::format(item->particles)); - ImGui::TableNextColumn(); - AlienImGui::Text(StringHelper::format(item->contentSize) + " Bytes"); - ImGui::TableNextColumn(); - AlienImGui::Text(item->version); - - ImGui::PopStyleColor(); + if (item->isLeaf()) { + auto& leaf = item->getLeaf(); + + ImGui::TableNextColumn(); + processActionButtons(item); + ImGui::TableNextColumn(); + pushTextColor(item); + AlienImGui::Text(leaf.timestamp); + ImGui::TableNextColumn(); + processShortenedText(leaf.userName); + ImGui::TableNextColumn(); + processShortenedText(leaf.simName); + ImGui::TableNextColumn(); + processShortenedText(leaf.description); + ImGui::TableNextColumn(); + processEmojiList(item); + + ImGui::TableNextColumn(); + AlienImGui::Text(std::to_string(leaf.numDownloads)); + ImGui::TableNextColumn(); + AlienImGui::Text(StringHelper::format(leaf.particles)); + ImGui::TableNextColumn(); + AlienImGui::Text(StringHelper::format(leaf.contentSize) + " Bytes"); + ImGui::TableNextColumn(); + AlienImGui::Text(leaf.version); + + ImGui::PopStyleColor(); + } ImGui::PopID(); } ImGui::EndTable(); @@ -640,14 +647,14 @@ void _BrowserWindow::processEmojiButton(int emojiType) auto cursorPos = ImGui::GetCursorScreenPos(); auto emojiWidth = scale(toFloat(emoji.width)); auto emojiHeight = scale(toFloat(emoji.height)); - auto sim = _emojiPopupTO; + auto leaf = _emojiPopupTO->getLeaf(); if (ImGui::ImageButton((void*)(intptr_t)emoji.textureId, {emojiWidth, emojiHeight}, {0, 0}, {1.0f, 1.0f})) { - onToggleLike(sim, toInt(emojiType)); + onToggleLike(_emojiPopupTO, toInt(emojiType)); ImGui::CloseCurrentPopup(); } ImGui::PopStyleColor(2); - bool isLiked = _ownEmojiTypeBySimId.contains(sim->id) && _ownEmojiTypeBySimId.at(sim->id) == emojiType; + bool isLiked = _ownEmojiTypeBySimId.contains(leaf.id) && _ownEmojiTypeBySimId.at(leaf.id) == emojiType; if (isLiked) { ImDrawList* drawList = ImGui::GetWindowDrawList(); auto& style = ImGui::GetStyle(); @@ -666,10 +673,11 @@ void _BrowserWindow::processEmojiList(BrowserDataTO const& to) std::set processedEmojiTypes; int index = 0; - while (processedEmojiTypes.size() < to->numLikesByEmojiType.size()) { + auto& leaf = to->getLeaf(); + while (processedEmojiTypes.size() < leaf.numLikesByEmojiType.size()) { int maxLikes = 0; std::optional maxEmojiType; - for (auto const& [emojiType, numLikes] : to->numLikesByEmojiType) { + for (auto const& [emojiType, numLikes] : leaf.numLikesByEmojiType) { if (!processedEmojiTypes.contains(emojiType) && numLikes > maxLikes) { maxLikes = numLikes; maxEmojiType = emojiType; @@ -684,7 +692,7 @@ void _BrowserWindow::processEmojiList(BrowserDataTO const& to) int counter = 0; std::optional toggleEmojiType; for (auto const& emojiType : remap | std::views::values) { - auto numLikes = to->numLikesByEmojiType.at(emojiType); + auto numLikes = leaf.numLikesByEmojiType.at(emojiType); AlienImGui::Text(std::to_string(numLikes)); ImGui::SameLine(); @@ -703,18 +711,18 @@ void _BrowserWindow::processEmojiList(BrowserDataTO const& to) 0)) { toggleEmojiType = emojiType; } - bool isLiked = _ownEmojiTypeBySimId.contains(to->id) && _ownEmojiTypeBySimId.at(to->id) == emojiType; + bool isLiked = _ownEmojiTypeBySimId.contains(leaf.id) && _ownEmojiTypeBySimId.at(leaf.id) == emojiType; if (isLiked) { ImDrawList* drawList = ImGui::GetWindowDrawList(); drawList->AddRect( ImVec2(cursorPos.x, cursorPos.y), ImVec2(cursorPos.x + emojiWidth, cursorPos.y + emojiHeight), (ImU32)ImColor::HSV(0, 0, 1, 0.5f), 1.0f); } ImGui::PopStyleColor(2); - AlienImGui::Tooltip([=, this] { return getUserNamesToEmojiType(to->id, emojiType); }, false); + AlienImGui::Tooltip([=, this] { return getUserNamesToEmojiType(leaf.id, emojiType); }, false); } //separator except for last element - if (++counter < to->numLikesByEmojiType.size()) { + if (++counter < leaf.numLikesByEmojiType.size()) { ImGui::SameLine(); ImGui::SetCursorPosX(ImGui::GetCursorPosX() - scale(4.0f)); } @@ -727,40 +735,43 @@ void _BrowserWindow::processEmojiList(BrowserDataTO const& to) void _BrowserWindow::processActionButtons(BrowserDataTO const& to) { //like button - auto liked = isLiked(to->id); - if (liked) { - ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::LikeButtonTextColor); - } else { - ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::NoLikeButtonTextColor); - } - auto likeButtonResult = processActionButton(ICON_FA_SMILE); - ImGui::PopStyleColor(); - if (likeButtonResult) { - _activateEmojiPopup = true; - _emojiPopupTO = to; - } - AlienImGui::Tooltip("Choose a reaction"); - ImGui::SameLine(); - - //download button - ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DownloadButtonTextColor); - auto downloadButtonResult = processActionButton(ICON_FA_DOWNLOAD); - ImGui::PopStyleColor(); - if (downloadButtonResult) { - onDownloadItem(to); - } - AlienImGui::Tooltip("Download"); - ImGui::SameLine(); + if (to->isLeaf()) { + auto const& leaf = to->getLeaf(); + auto liked = isLiked(leaf.id); + if (liked) { + ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::LikeButtonTextColor); + } else { + ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::NoLikeButtonTextColor); + } + auto likeButtonResult = processActionButton(ICON_FA_SMILE); + ImGui::PopStyleColor(); + if (likeButtonResult) { + _activateEmojiPopup = true; + _emojiPopupTO = to; + } + AlienImGui::Tooltip("Choose a reaction"); + ImGui::SameLine(); - //delete button - if (to->userName == _networkController->getLoggedInUserName().value_or("")) { - ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DeleteButtonTextColor); - auto deleteButtonResult = processActionButton(ICON_FA_TRASH); + //download button + ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DownloadButtonTextColor); + auto downloadButtonResult = processActionButton(ICON_FA_DOWNLOAD); ImGui::PopStyleColor(); - if (deleteButtonResult) { - onDeleteItem(to); + if (downloadButtonResult) { + onDownloadItem(leaf); + } + AlienImGui::Tooltip("Download"); + ImGui::SameLine(); + + //delete button + if (leaf.userName == _networkController->getLoggedInUserName().value_or("")) { + ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DeleteButtonTextColor); + auto deleteButtonResult = processActionButton(ICON_FA_TRASH); + ImGui::PopStyleColor(); + if (deleteButtonResult) { + onDeleteItem(leaf); + } + AlienImGui::Tooltip("Delete"); } - AlienImGui::Tooltip("Delete"); } } @@ -840,14 +851,14 @@ void _BrowserWindow::sortUserList() std::sort(_userTOs.begin(), _userTOs.end(), [&](auto const& left, auto const& right) { return UserTO::compareOnlineAndTimestamp(left, right) > 0; }); } -void _BrowserWindow::onDownloadItem(BrowserDataTO const& to) +void _BrowserWindow::onDownloadItem(BrowserLeaf const& leaf) { printOverlayMessage("Downloading ..."); delayedExecution([=, this] { std::string dataTypeString = _selectedDataType == DataType_Simulation ? "simulation" : "genome"; SerializedSimulation serializedSim; - if (!_networkController->downloadSimulation(serializedSim.mainData, serializedSim.auxiliaryData, serializedSim.statistics, to->id)) { + if (!_networkController->downloadSimulation(serializedSim.mainData, serializedSim.auxiliaryData, serializedSim.statistics, leaf.id)) { MessageDialog::getInstance().information("Error", "Failed to download " + dataTypeString + "."); return; } @@ -893,7 +904,7 @@ void _BrowserWindow::onDownloadItem(BrowserDataTO const& to) _editorController->setOn(true); _editorController->getGenomeEditorWindow()->openTab(GenomeDescriptionService::convertBytesToDescription(genome)); } - if (VersionChecker::isVersionNewer(to->version)) { + if (VersionChecker::isVersionNewer(leaf.version)) { MessageDialog::getInstance().information( "Warning", "The download was successful but the " + dataTypeString +" was generated using a more recent\n" @@ -903,13 +914,13 @@ void _BrowserWindow::onDownloadItem(BrowserDataTO const& to) }); } -void _BrowserWindow::onDeleteItem(BrowserDataTO const& to) +void _BrowserWindow::onDeleteItem(BrowserLeaf const& leaf) { - MessageDialog::getInstance().yesNo("Delete item", "Do you really want to delete the selected item?", [to, this]() { + MessageDialog::getInstance().yesNo("Delete item", "Do you really want to delete the selected item?", [leaf, this]() { printOverlayMessage("Deleting ..."); - delayedExecution([browserData = to, this] { - if (!_networkController->deleteSimulation(browserData->id)) { + delayedExecution([leafCopy = leaf, this] { + if (!_networkController->deleteSimulation(leafCopy.id)) { MessageDialog::getInstance().information("Error", "Failed to delete item. Please try again later."); return; } @@ -920,33 +931,35 @@ void _BrowserWindow::onDeleteItem(BrowserDataTO const& to) void _BrowserWindow::onToggleLike(BrowserDataTO const& to, int emojiType) { + CHECK(to->isLeaf()); + auto& leaf = to->getLeaf(); if (_networkController->getLoggedInUserName()) { //remove existing like - auto findResult = _ownEmojiTypeBySimId.find(to->id); + auto findResult = _ownEmojiTypeBySimId.find(leaf.id); auto onlyRemoveLike = false; if (findResult != _ownEmojiTypeBySimId.end()) { auto origEmojiType = findResult->second; - if (--to->numLikesByEmojiType[origEmojiType] == 0) { - to->numLikesByEmojiType.erase(origEmojiType); + if (--leaf.numLikesByEmojiType[origEmojiType] == 0) { + leaf.numLikesByEmojiType.erase(origEmojiType); } _ownEmojiTypeBySimId.erase(findResult); - _userNamesByEmojiTypeBySimIdCache.erase(std::make_pair(to->id, origEmojiType)); //invalidate cache entry + _userNamesByEmojiTypeBySimIdCache.erase(std::make_pair(leaf.id, origEmojiType)); //invalidate cache entry onlyRemoveLike = origEmojiType == emojiType; //remove like if same like icon has been clicked } //create new like if (!onlyRemoveLike) { - _ownEmojiTypeBySimId[to->id] = emojiType; - if (to->numLikesByEmojiType.contains(emojiType)) { - ++to->numLikesByEmojiType[emojiType]; + _ownEmojiTypeBySimId[leaf.id] = emojiType; + if (leaf.numLikesByEmojiType.contains(emojiType)) { + ++leaf.numLikesByEmojiType[emojiType]; } else { - to->numLikesByEmojiType[emojiType] = 1; + leaf.numLikesByEmojiType[emojiType] = 1; } } - _userNamesByEmojiTypeBySimIdCache.erase(std::make_pair(to->id, emojiType)); //invalidate cache entry - _networkController->toggleLikeSimulation(to->id, emojiType); + _userNamesByEmojiTypeBySimIdCache.erase(std::make_pair(leaf.id, emojiType)); //invalidate cache entry + _networkController->toggleLikeSimulation(leaf.id, emojiType); //_scheduleCreateBrowserData = true; } else { _loginDialog.lock()->open(); @@ -982,12 +995,17 @@ std::string _BrowserWindow::getUserNamesToEmojiType(std::string const& simId, in void _BrowserWindow::pushTextColor(BrowserDataTO const& to) { - if (VersionChecker::isVersionOutdated(to->version)) { - ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::VersionOutdatedColor); - } else if (VersionChecker::isVersionNewer(to->version)) { - ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::VersionNewerColor); + if (to->isLeaf()) { + auto const& leaf = to->getLeaf(); + if (VersionChecker::isVersionOutdated(leaf.version)) { + ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::VersionOutdatedColor); + } else if (VersionChecker::isVersionNewer(leaf.version)) { + ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::VersionNewerColor); + } else { + ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::VersionOkColor); + } } else { - ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::VersionOkColor); + ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::DirectoryColor); } } @@ -997,12 +1015,12 @@ void _BrowserWindow::calcFilteredSimulationAndGenomeLists() _filteredNetworkSimulationTOs.reserve(_rawNetworkDataTOs.size()); _filteredNetworkGenomeTOs.clear(); _filteredNetworkGenomeTOs.reserve(_filteredNetworkGenomeTOs.size()); - for (auto const& simData : _rawNetworkDataTOs) { - if (simData->matchWithFilter(_filter) &&_showCommunityCreations != simData->fromRelease) { - if (simData->type == NetworkDataType_Simulation) { - _filteredNetworkSimulationTOs.emplace_back(simData); + for (auto const& to : _rawNetworkDataTOs) { + if (to->matchWithFilter(_filter) &&_showCommunityCreations != to->fromRelease) { + if (to->type == NetworkDataType_Simulation) { + _filteredNetworkSimulationTOs.emplace_back(to); } else { - _filteredNetworkGenomeTOs.emplace_back(simData); + _filteredNetworkGenomeTOs.emplace_back(to); } } } diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index d370663ae..7c2199c53 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -56,8 +56,8 @@ class _BrowserWindow : public _AlienWindow void sortRemoteSimulationData(std::vector& remoteData, ImGuiTableSortSpecs* sortSpecs); void sortUserList(); - void onDownloadItem(BrowserDataTO const& to); - void onDeleteItem(BrowserDataTO const& to); + void onDownloadItem(BrowserLeaf const& leaf); + void onDeleteItem(BrowserLeaf const& leaf); void onToggleLike(BrowserDataTO const& to, int emojiType); void openWeblink(std::string const& link); diff --git a/source/Gui/CMakeLists.txt b/source/Gui/CMakeLists.txt index 7f9f57ec3..939c66256 100644 --- a/source/Gui/CMakeLists.txt +++ b/source/Gui/CMakeLists.txt @@ -15,6 +15,7 @@ PUBLIC AutosaveController.h BrowserDataService.cpp BrowserDataService.h + BrowserDataTO.cpp BrowserDataTO.h BrowserWindow.cpp BrowserWindow.h diff --git a/source/Gui/Definitions.h b/source/Gui/Definitions.h index 5973aef1f..6ba1249f5 100644 --- a/source/Gui/Definitions.h +++ b/source/Gui/Definitions.h @@ -178,8 +178,8 @@ enum DataType_ DataType_Genome }; -class _BrowserDataTO; +struct _BrowserDataTO; using BrowserDataTO = std::shared_ptr<_BrowserDataTO>; -class _NetworkDataTO; +struct _NetworkDataTO; using NetworkDataTO = std::shared_ptr<_NetworkDataTO>; diff --git a/source/Gui/NetworkDataTO.h b/source/Gui/NetworkDataTO.h index 6c00ed8b9..3afee8913 100644 --- a/source/Gui/NetworkDataTO.h +++ b/source/Gui/NetworkDataTO.h @@ -30,9 +30,8 @@ enum NetworkDataType_ NetworkDataType_Genome }; -class _NetworkDataTO +struct _NetworkDataTO { -public: std::string id; std::string timestamp; std::string userName; diff --git a/source/Gui/StyleRepository.h b/source/Gui/StyleRepository.h index fecf78496..a5c92a5ef 100644 --- a/source/Gui/StyleRepository.h +++ b/source/Gui/StyleRepository.h @@ -67,6 +67,8 @@ namespace Const ImColor const VersionOutdatedColor = ImColor::HSV(0.0f, 0.0f, 0.6f); ImColor const VersionNewerColor = ImColor::HSV(0.0f, 0.2f, 1.0f); + ImColor const DirectoryColor = ImColor::HSV(0.58f, 0.3f, 1.0f); + ImColor const GenomePreviewConnectionColor = ImColor::HSV(0, 0, 0.5f); ImColor const GenomePreviewDotSymbolColor = ImColor::HSV(0, 0, 0.7f); ImColor const GenomePreviewInfinitySymbolColor = ImColor::HSV(0, 0, 0.7f); From ba124067af12ac262de34efd3d2c52e5190c0df0 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Wed, 20 Dec 2023 20:23:12 +0100 Subject: [PATCH 06/40] + first version of automatic folder creation + test project for gui --- CMakeLists.txt | 6 ++- source/EngineTests/CMakeLists.txt | 28 +++++++------- source/Gui/BrowserDataService.cpp | 62 +++++++++++++++++++++++++++---- source/Gui/BrowserDataService.h | 2 +- source/Gui/BrowserDataTO.h | 2 +- source/Gui/BrowserWindow.cpp | 34 ++++++++++------- source/GuiTests/CMakeLists.txt | 21 +++++++++++ source/GuiTests/Testsuite.cpp | 7 ++++ 8 files changed, 123 insertions(+), 39 deletions(-) create mode 100644 source/GuiTests/CMakeLists.txt create mode 100644 source/GuiTests/Testsuite.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f219210f..103ceb439 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,7 +43,8 @@ add_compile_definitions($<$:NOMINMAX>) add_compile_options($<$:--Werror=all-warnings>) add_executable(alien) -add_executable(tests) +add_executable(engine_tests) +add_executable(gui_tests) add_executable(cli) find_package(CUDAToolkit) @@ -62,12 +63,13 @@ find_package(CLI11 CONFIG REQUIRED) add_subdirectory(external/ImFileDialog) add_subdirectory(source/Base) +add_subdirectory(source/Cli) add_subdirectory(source/EngineGpuKernels) add_subdirectory(source/EngineImpl) add_subdirectory(source/EngineInterface) add_subdirectory(source/EngineTests) add_subdirectory(source/Gui) -add_subdirectory(source/Cli) +add_subdirectory(source/GuiTests) # Copy resources to the build location add_custom_command( diff --git a/source/EngineTests/CMakeLists.txt b/source/EngineTests/CMakeLists.txt index e24da2632..1fd04312e 100644 --- a/source/EngineTests/CMakeLists.txt +++ b/source/EngineTests/CMakeLists.txt @@ -1,4 +1,4 @@ -target_sources(tests +target_sources(engine_tests PUBLIC AttackerTests.cpp CellConnectionTests.cpp @@ -20,20 +20,20 @@ PUBLIC Testsuite.cpp TransmitterTests.cpp) -target_link_libraries(tests alien_base_lib) -target_link_libraries(tests alien_engine_gpu_kernels_lib) -target_link_libraries(tests alien_engine_impl_lib) -target_link_libraries(tests alien_engine_interface_lib) +target_link_libraries(engine_tests alien_base_lib) +target_link_libraries(engine_tests alien_engine_gpu_kernels_lib) +target_link_libraries(engine_tests alien_engine_impl_lib) +target_link_libraries(engine_tests alien_engine_interface_lib) -target_link_libraries(tests CUDA::cudart_static) -target_link_libraries(tests CUDA::cuda_driver) -target_link_libraries(tests Boost::boost) -target_link_libraries(tests OpenGL::GL OpenGL::GLU) -target_link_libraries(tests GLEW::GLEW) -target_link_libraries(tests glfw) -target_link_libraries(tests glad::glad) -target_link_libraries(tests GTest::GTest GTest::Main) +target_link_libraries(engine_tests CUDA::cudart_static) +target_link_libraries(engine_tests CUDA::cuda_driver) +target_link_libraries(engine_tests Boost::boost) +target_link_libraries(engine_tests OpenGL::GL OpenGL::GLU) +target_link_libraries(engine_tests GLEW::GLEW) +target_link_libraries(engine_tests glfw) +target_link_libraries(engine_tests glad::glad) +target_link_libraries(engine_tests GTest::GTest GTest::Main) if (MSVC) - target_compile_options(tests PRIVATE "/MP") + target_compile_options(engine_tests PRIVATE "/MP") endif() diff --git a/source/Gui/BrowserDataService.cpp b/source/Gui/BrowserDataService.cpp index 0a7d2b041..ae3c49481 100644 --- a/source/Gui/BrowserDataService.cpp +++ b/source/Gui/BrowserDataService.cpp @@ -1,14 +1,62 @@ #include "BrowserDataService.h" +#include +#include + #include "BrowserDataTO.h" -std::vector BrowserDataService::createBrowserData(std::vector const& remoteData) +std::vector BrowserDataService::createBrowserData(std::vector const& networkTOs) { - std::vector result; - result.reserve(remoteData.size()); - for (auto const& entry : remoteData) { - auto browserData = std::make_shared<_BrowserDataTO>(); + std::list result; + for (auto const& entry : networkTOs) { + + //parse folder + std::vector location; + boost::split(location, entry->simName, boost::is_any_of("/")); + if (!location.empty()) { + location.pop_back(); + } + + if (!result.empty()) { + + //find matching node + auto searchIter = result.end(); + auto bestMatchIter = searchIter; + int bestMatchEqualFolders = -1; + for (int i = 0; i < result.size(); ++i) { + --searchIter; + auto otherEntry = *searchIter; + int equalFolders = 0; + int numFolders = std::min(location.size(), otherEntry->location.size()); + for (int i = 0; i < numFolders; ++i) { + if (location[i] == otherEntry->location[i]) { + ++equalFolders; + } else { + break; + } + } + + if (equalFolders < bestMatchEqualFolders) { + break; + } + if (equalFolders > bestMatchEqualFolders) { + bestMatchIter = searchIter; + bestMatchEqualFolders = equalFolders; + } + } + + //insert folders + for (int i = bestMatchEqualFolders; i < location.size(); ++i) { + auto browserData = std::make_shared<_BrowserDataTO>(); + browserData->location = std::vector(location.begin(), location.begin() + i + 1); + browserData->type = entry->type; + browserData->node = BrowserFolder(); + result.insert(bestMatchIter, browserData); + } + } + + auto browserData = std::make_shared<_BrowserDataTO>(); BrowserLeaf leaf{ .id = entry->id, .timestamp = entry->timestamp, @@ -25,10 +73,10 @@ std::vector BrowserDataService::createBrowserData(std::vectortype = entry->type; - browserData->level = 0; + browserData->location = location; browserData->node = leaf; result.emplace_back(browserData); } - return result; + return std::vector(result.begin(), result.end()); } diff --git a/source/Gui/BrowserDataService.h b/source/Gui/BrowserDataService.h index fb673df80..a7b9dcd45 100644 --- a/source/Gui/BrowserDataService.h +++ b/source/Gui/BrowserDataService.h @@ -8,5 +8,5 @@ class BrowserDataService { public: - static std::vector createBrowserData(std::vector const& remoteData); + static std::vector createBrowserData(std::vector const& browserData); }; diff --git a/source/Gui/BrowserDataTO.h b/source/Gui/BrowserDataTO.h index 74ff41077..e82333622 100644 --- a/source/Gui/BrowserDataTO.h +++ b/source/Gui/BrowserDataTO.h @@ -36,7 +36,7 @@ struct BrowserLeaf struct _BrowserDataTO { BrowserDataType type; - int level; + std::vector location; std::variant node; bool isLeaf(); diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index ec9367c36..a26d7f70f 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -274,6 +274,11 @@ void _BrowserWindow::processSimulationList() ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, scale(90.0f), NetworkDataColumnId_Actions); + ImGui::TableSetupColumn( + "Simulation name", + ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, + styleRepository.scale(160.0f), + NetworkDataColumnId_SimulationName); ImGui::TableSetupColumn( "Timestamp", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_PreferSortDescending, @@ -284,11 +289,6 @@ void _BrowserWindow::processSimulationList() ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), NetworkDataColumnId_UserName); - ImGui::TableSetupColumn( - "Simulation name", - ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, - styleRepository.scale(160.0f), - NetworkDataColumnId_SimulationName); ImGui::TableSetupColumn( "Description", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, @@ -332,13 +332,13 @@ void _BrowserWindow::processSimulationList() ImGui::TableNextColumn(); processActionButtons(item); ImGui::TableNextColumn(); + processShortenedText(leaf.simName); + ImGui::TableNextColumn(); pushTextColor(item); AlienImGui::Text(leaf.timestamp); ImGui::TableNextColumn(); processShortenedText(leaf.userName); ImGui::TableNextColumn(); - processShortenedText(leaf.simName); - ImGui::TableNextColumn(); processShortenedText(leaf.description); ImGui::TableNextColumn(); processEmojiList(item); @@ -357,6 +357,12 @@ void _BrowserWindow::processSimulationList() AlienImGui::Text(leaf.version); ImGui::PopStyleColor(); + } else { + ImGui::TableNextColumn(); + ImGui::TableNextColumn(); + AlienImGui::CollapseButton(false); + ImGui::SameLine(); + processShortenedText(item->location.back()); } ImGui::PopID(); } @@ -377,6 +383,11 @@ void _BrowserWindow::processGenomeList() if (ImGui::BeginTable("Browser", 10, flags, ImVec2(0, 0), 0.0f)) { ImGui::TableSetupColumn( "Actions", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, scale(90.0f), NetworkDataColumnId_Actions); + ImGui::TableSetupColumn( + "Genome name", + ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, + styleRepository.scale(160.0f), + NetworkDataColumnId_SimulationName); ImGui::TableSetupColumn( "Timestamp", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_PreferSortDescending, @@ -387,11 +398,6 @@ void _BrowserWindow::processGenomeList() ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), NetworkDataColumnId_UserName); - ImGui::TableSetupColumn( - "Genome name", - ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, - styleRepository.scale(160.0f), - NetworkDataColumnId_SimulationName); ImGui::TableSetupColumn( "Description", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, @@ -436,13 +442,13 @@ void _BrowserWindow::processGenomeList() ImGui::TableNextColumn(); processActionButtons(item); ImGui::TableNextColumn(); + processShortenedText(leaf.simName); + ImGui::TableNextColumn(); pushTextColor(item); AlienImGui::Text(leaf.timestamp); ImGui::TableNextColumn(); processShortenedText(leaf.userName); ImGui::TableNextColumn(); - processShortenedText(leaf.simName); - ImGui::TableNextColumn(); processShortenedText(leaf.description); ImGui::TableNextColumn(); processEmojiList(item); diff --git a/source/GuiTests/CMakeLists.txt b/source/GuiTests/CMakeLists.txt new file mode 100644 index 000000000..c1b46cd7e --- /dev/null +++ b/source/GuiTests/CMakeLists.txt @@ -0,0 +1,21 @@ +target_sources(gui_tests +PUBLIC + Testsuite.cpp) + +target_link_libraries(gui_tests alien_base_lib) +target_link_libraries(gui_tests alien_engine_gpu_kernels_lib) +target_link_libraries(gui_tests alien_engine_impl_lib) +target_link_libraries(gui_tests alien_engine_interface_lib) + +target_link_libraries(gui_tests CUDA::cudart_static) +target_link_libraries(gui_tests CUDA::cuda_driver) +target_link_libraries(gui_tests Boost::boost) +target_link_libraries(gui_tests OpenGL::GL OpenGL::GLU) +target_link_libraries(gui_tests GLEW::GLEW) +target_link_libraries(gui_tests glfw) +target_link_libraries(gui_tests glad::glad) +target_link_libraries(gui_tests GTest::GTest GTest::Main) + +if (MSVC) + target_compile_options(gui_tests PRIVATE "/MP") +endif() diff --git a/source/GuiTests/Testsuite.cpp b/source/GuiTests/Testsuite.cpp new file mode 100644 index 000000000..9bb465e02 --- /dev/null +++ b/source/GuiTests/Testsuite.cpp @@ -0,0 +1,7 @@ +#include + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} From 89ba2728ff82bd7a7801280ae14ac20ad8608e33 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Wed, 20 Dec 2023 20:41:24 +0100 Subject: [PATCH 07/40] name convention enforced --- CMakeLists.txt | 4 ++-- source/Base/CMakeLists.txt | 6 +++--- source/Cli/CMakeLists.txt | 8 ++++---- source/EngineGpuKernels/CMakeLists.txt | 8 ++++---- source/EngineImpl/CMakeLists.txt | 12 +++++------ source/EngineInterface/CMakeLists.txt | 10 ++++----- source/EngineTests/CMakeLists.txt | 28 +++++++++++++------------- source/Gui/CMakeLists.txt | 10 ++++----- source/GuiTests/CMakeLists.txt | 28 +++++++++++++------------- 9 files changed, 57 insertions(+), 57 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 103ceb439..de59a9e83 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,9 +43,9 @@ add_compile_definitions($<$:NOMINMAX>) add_compile_options($<$:--Werror=all-warnings>) add_executable(alien) -add_executable(engine_tests) -add_executable(gui_tests) add_executable(cli) +add_executable(EngineTests) +add_executable(GuiTests) find_package(CUDAToolkit) find_package(Boost REQUIRED) diff --git a/source/Base/CMakeLists.txt b/source/Base/CMakeLists.txt index 86eece9fa..981d3388e 100644 --- a/source/Base/CMakeLists.txt +++ b/source/Base/CMakeLists.txt @@ -1,5 +1,5 @@ -add_library(alien_base_lib +add_library(BaseLib Definitions.cpp Definitions.h Exceptions.h @@ -25,8 +25,8 @@ add_library(alien_base_lib VersionChecker.cpp VersionChecker.h) -target_link_libraries(alien_base_lib Boost::boost) +target_link_libraries(BaseLib Boost::boost) if (MSVC) - target_compile_options(alien_base_lib PRIVATE "/MP") + target_compile_options(BaseLib PRIVATE "/MP") endif() diff --git a/source/Cli/CMakeLists.txt b/source/Cli/CMakeLists.txt index a45b59fa1..f7501812b 100644 --- a/source/Cli/CMakeLists.txt +++ b/source/Cli/CMakeLists.txt @@ -2,10 +2,10 @@ target_sources(cli PUBLIC Main.cpp) -target_link_libraries(cli alien_base_lib) -target_link_libraries(cli alien_engine_gpu_kernels_lib) -target_link_libraries(cli alien_engine_impl_lib) -target_link_libraries(cli alien_engine_interface_lib) +target_link_libraries(cli BaseLib) +target_link_libraries(cli EngineGpuKernelsLib) +target_link_libraries(cli EngineImplLib) +target_link_libraries(cli EngineInterfaceLib) target_link_libraries(cli CUDA::cudart_static) target_link_libraries(cli CUDA::cuda_driver) diff --git a/source/EngineGpuKernels/CMakeLists.txt b/source/EngineGpuKernels/CMakeLists.txt index 3b0e24e34..a00d8d762 100644 --- a/source/EngineGpuKernels/CMakeLists.txt +++ b/source/EngineGpuKernels/CMakeLists.txt @@ -1,5 +1,5 @@ -add_library(alien_engine_gpu_kernels_lib +add_library(EngineGpuKernelsLib Array.cuh AttackerProcessor.cuh Base.cuh @@ -92,8 +92,8 @@ add_library(alien_engine_gpu_kernels_lib Util.cuh ) -target_link_libraries(alien_engine_gpu_kernels_lib alien_base_lib) -target_link_libraries(alien_engine_gpu_kernels_lib alien_engine_interface_lib) +target_link_libraries(EngineGpuKernelsLib BaseLib) +target_link_libraries(EngineGpuKernelsLib EngineInterfaceLib) # See https://gitlab.kitware.com/cmake/cmake/-/issues/17520 -set_property(TARGET alien_engine_gpu_kernels_lib PROPERTY CUDA_RESOLVE_DEVICE_SYMBOLS ON) \ No newline at end of file +set_property(TARGET EngineGpuKernelsLib PROPERTY CUDA_RESOLVE_DEVICE_SYMBOLS ON) \ No newline at end of file diff --git a/source/EngineImpl/CMakeLists.txt b/source/EngineImpl/CMakeLists.txt index 4ff382504..43d870409 100644 --- a/source/EngineImpl/CMakeLists.txt +++ b/source/EngineImpl/CMakeLists.txt @@ -1,5 +1,5 @@ -add_library(alien_engine_impl_lib +add_library(EngineImplLib AccessDataTOCache.cpp AccessDataTOCache.h DescriptionConverter.cpp @@ -10,12 +10,12 @@ add_library(alien_engine_impl_lib SimulationControllerImpl.cpp SimulationControllerImpl.h) -target_link_libraries(alien_engine_impl_lib alien_base_lib) -target_link_libraries(alien_engine_impl_lib alien_engine_gpu_kernels_lib) +target_link_libraries(EngineImplLib BaseLib) +target_link_libraries(EngineImplLib EngineGpuKernelsLib) -target_link_libraries(alien_engine_impl_lib CUDA::cudart_static) -target_link_libraries(alien_engine_impl_lib Boost::boost) +target_link_libraries(EngineImplLib CUDA::cudart_static) +target_link_libraries(EngineImplLib Boost::boost) if (MSVC) - target_compile_options(alien_engine_impl_lib PRIVATE "/MP") + target_compile_options(EngineImplLib PRIVATE "/MP") endif() diff --git a/source/EngineInterface/CMakeLists.txt b/source/EngineInterface/CMakeLists.txt index 110973033..46c657895 100644 --- a/source/EngineInterface/CMakeLists.txt +++ b/source/EngineInterface/CMakeLists.txt @@ -1,5 +1,5 @@ -add_library(alien_engine_interface_lib +add_library(EngineInterfaceLib ArraySizes.h AuxiliaryData.h AuxiliaryDataParserService.cpp @@ -49,13 +49,13 @@ add_library(alien_engine_interface_lib StatisticsHistory.h ZoomLevels.h) -target_link_libraries(alien_engine_interface_lib Boost::boost) -target_link_libraries(alien_engine_interface_lib cereal) +target_link_libraries(EngineInterfaceLib Boost::boost) +target_link_libraries(EngineInterfaceLib cereal) target_link_libraries(alien ZLIB::ZLIB) find_path(ZSTR_INCLUDE_DIRS "zstr.hpp") -target_include_directories(alien_engine_interface_lib PRIVATE ${ZSTR_INCLUDE_DIRS}) +target_include_directories(EngineInterfaceLib PRIVATE ${ZSTR_INCLUDE_DIRS}) if (MSVC) - target_compile_options(alien_engine_interface_lib PRIVATE "/MP") + target_compile_options(EngineInterfaceLib PRIVATE "/MP") endif() diff --git a/source/EngineTests/CMakeLists.txt b/source/EngineTests/CMakeLists.txt index 1fd04312e..51fe41478 100644 --- a/source/EngineTests/CMakeLists.txt +++ b/source/EngineTests/CMakeLists.txt @@ -1,4 +1,4 @@ -target_sources(engine_tests +target_sources(EngineTests PUBLIC AttackerTests.cpp CellConnectionTests.cpp @@ -20,20 +20,20 @@ PUBLIC Testsuite.cpp TransmitterTests.cpp) -target_link_libraries(engine_tests alien_base_lib) -target_link_libraries(engine_tests alien_engine_gpu_kernels_lib) -target_link_libraries(engine_tests alien_engine_impl_lib) -target_link_libraries(engine_tests alien_engine_interface_lib) +target_link_libraries(EngineTests BaseLib) +target_link_libraries(EngineTests EngineGpuKernelsLib) +target_link_libraries(EngineTests EngineImplLib) +target_link_libraries(EngineTests EngineInterfaceLib) -target_link_libraries(engine_tests CUDA::cudart_static) -target_link_libraries(engine_tests CUDA::cuda_driver) -target_link_libraries(engine_tests Boost::boost) -target_link_libraries(engine_tests OpenGL::GL OpenGL::GLU) -target_link_libraries(engine_tests GLEW::GLEW) -target_link_libraries(engine_tests glfw) -target_link_libraries(engine_tests glad::glad) -target_link_libraries(engine_tests GTest::GTest GTest::Main) +target_link_libraries(EngineTests CUDA::cudart_static) +target_link_libraries(EngineTests CUDA::cuda_driver) +target_link_libraries(EngineTests Boost::boost) +target_link_libraries(EngineTests OpenGL::GL OpenGL::GLU) +target_link_libraries(EngineTests GLEW::GLEW) +target_link_libraries(EngineTests glfw) +target_link_libraries(EngineTests glad::glad) +target_link_libraries(EngineTests GTest::GTest GTest::Main) if (MSVC) - target_compile_options(engine_tests PRIVATE "/MP") + target_compile_options(EngineTests PRIVATE "/MP") endif() diff --git a/source/Gui/CMakeLists.txt b/source/Gui/CMakeLists.txt index 939c66256..a1d621644 100644 --- a/source/Gui/CMakeLists.txt +++ b/source/Gui/CMakeLists.txt @@ -131,12 +131,12 @@ PUBLIC WindowController.cpp WindowController.h) -target_link_libraries(alien alien_base_lib) -target_link_libraries(alien alien_engine_gpu_kernels_lib) -target_link_libraries(alien alien_engine_impl_lib) -target_link_libraries(alien alien_engine_interface_lib) -target_link_libraries(alien im_file_dialog) +target_link_libraries(alien BaseLib) +target_link_libraries(alien EngineGpuKernelsLib) +target_link_libraries(alien EngineImplLib) +target_link_libraries(alien EngineInterfaceLib) +target_link_libraries(alien im_file_dialog) target_link_libraries(alien CUDA::cudart_static) target_link_libraries(alien CUDA::cuda_driver) target_link_libraries(alien Boost::boost) diff --git a/source/GuiTests/CMakeLists.txt b/source/GuiTests/CMakeLists.txt index c1b46cd7e..aacf926f5 100644 --- a/source/GuiTests/CMakeLists.txt +++ b/source/GuiTests/CMakeLists.txt @@ -1,21 +1,21 @@ -target_sources(gui_tests +target_sources(GuiTests PUBLIC Testsuite.cpp) -target_link_libraries(gui_tests alien_base_lib) -target_link_libraries(gui_tests alien_engine_gpu_kernels_lib) -target_link_libraries(gui_tests alien_engine_impl_lib) -target_link_libraries(gui_tests alien_engine_interface_lib) +target_link_libraries(GuiTests BaseLib) +target_link_libraries(GuiTests EngineGpuKernelsLib) +target_link_libraries(GuiTests EngineImplLib) +target_link_libraries(GuiTests EngineInterfaceLib) -target_link_libraries(gui_tests CUDA::cudart_static) -target_link_libraries(gui_tests CUDA::cuda_driver) -target_link_libraries(gui_tests Boost::boost) -target_link_libraries(gui_tests OpenGL::GL OpenGL::GLU) -target_link_libraries(gui_tests GLEW::GLEW) -target_link_libraries(gui_tests glfw) -target_link_libraries(gui_tests glad::glad) -target_link_libraries(gui_tests GTest::GTest GTest::Main) +target_link_libraries(GuiTests CUDA::cudart_static) +target_link_libraries(GuiTests CUDA::cuda_driver) +target_link_libraries(GuiTests Boost::boost) +target_link_libraries(GuiTests OpenGL::GL OpenGL::GLU) +target_link_libraries(GuiTests GLEW::GLEW) +target_link_libraries(GuiTests glfw) +target_link_libraries(GuiTests glad::glad) +target_link_libraries(GuiTests GTest::GTest GTest::Main) if (MSVC) - target_compile_options(gui_tests PRIVATE "/MP") + target_compile_options(GuiTests PRIVATE "/MP") endif() From cde636effe155d5d70568aafc2c0785b394967f2 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Wed, 20 Dec 2023 21:38:01 +0100 Subject: [PATCH 08/40] network project added --- CMakeLists.txt | 5 ++-- source/Gui/ActivateUserDialog.cpp | 2 +- source/Gui/ActivateUserDialog.h | 3 ++- source/Gui/BrowserWindow.cpp | 6 ++--- source/Gui/BrowserWindow.h | 6 ++--- source/Gui/CMakeLists.txt | 12 +-------- source/Gui/CreateUserDialog.cpp | 3 ++- source/Gui/CreateUserDialog.h | 3 ++- source/Gui/Definitions.h | 18 +------------ source/Gui/DeleteUserDialog.cpp | 3 ++- source/Gui/DeleteUserDialog.h | 2 ++ source/Gui/LoginDialog.cpp | 2 +- source/Gui/LoginDialog.h | 2 ++ source/Gui/MainWindow.cpp | 2 +- source/Gui/MainWindow.h | 2 ++ source/Gui/NetworkSettingsDialog.cpp | 3 ++- source/Gui/NetworkSettingsDialog.h | 2 ++ source/Gui/NewPasswordDialog.cpp | 2 +- source/Gui/NewPasswordDialog.h | 3 ++- source/Gui/ResetPasswordDialog.h | 3 ++- source/Gui/UploadSimulationDialog.cpp | 2 +- source/Gui/UploadSimulationDialog.h | 4 ++- source/GuiTests/CMakeLists.txt | 21 ---------------- .../{Gui => Network}/BrowserDataService.cpp | 0 source/{Gui => Network}/BrowserDataService.h | 0 source/{Gui => Network}/BrowserDataTO.cpp | 0 source/{Gui => Network}/BrowserDataTO.h | 0 source/Network/CMakeLists.txt | 21 ++++++++++++++++ source/Network/Definitions.h | 19 ++++++++++++++ source/{Gui => Network}/NetworkController.cpp | 1 - source/{Gui => Network}/NetworkController.h | 0 .../NetworkDataParserService.cpp | 0 .../NetworkDataParserService.h | 0 source/{Gui => Network}/NetworkDataTO.cpp | 0 source/{Gui => Network}/NetworkDataTO.h | 0 source/{Gui => Network}/UserTO.h | 0 .../NetworkTests/BrowserDataServiceTests.cpp | 25 +++++++++++++++++++ source/NetworkTests/CMakeLists.txt | 19 ++++++++++++++ .../{GuiTests => NetworkTests}/Testsuite.cpp | 0 39 files changed, 125 insertions(+), 71 deletions(-) delete mode 100644 source/GuiTests/CMakeLists.txt rename source/{Gui => Network}/BrowserDataService.cpp (100%) rename source/{Gui => Network}/BrowserDataService.h (100%) rename source/{Gui => Network}/BrowserDataTO.cpp (100%) rename source/{Gui => Network}/BrowserDataTO.h (100%) create mode 100644 source/Network/CMakeLists.txt create mode 100644 source/Network/Definitions.h rename source/{Gui => Network}/NetworkController.cpp (99%) rename source/{Gui => Network}/NetworkController.h (100%) rename source/{Gui => Network}/NetworkDataParserService.cpp (100%) rename source/{Gui => Network}/NetworkDataParserService.h (100%) rename source/{Gui => Network}/NetworkDataTO.cpp (100%) rename source/{Gui => Network}/NetworkDataTO.h (100%) rename source/{Gui => Network}/UserTO.h (100%) create mode 100644 source/NetworkTests/BrowserDataServiceTests.cpp create mode 100644 source/NetworkTests/CMakeLists.txt rename source/{GuiTests => NetworkTests}/Testsuite.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index de59a9e83..e5fb92c74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,7 +45,7 @@ add_compile_options($<$:--Werror=all-warnings>) add_executable(alien) add_executable(cli) add_executable(EngineTests) -add_executable(GuiTests) +add_executable(NetworkTests) find_package(CUDAToolkit) find_package(Boost REQUIRED) @@ -69,7 +69,8 @@ add_subdirectory(source/EngineImpl) add_subdirectory(source/EngineInterface) add_subdirectory(source/EngineTests) add_subdirectory(source/Gui) -add_subdirectory(source/GuiTests) +add_subdirectory(source/Network) +add_subdirectory(source/NetworkTests) # Copy resources to the build location add_custom_command( diff --git a/source/Gui/ActivateUserDialog.cpp b/source/Gui/ActivateUserDialog.cpp index ac82009c8..9256e9521 100644 --- a/source/Gui/ActivateUserDialog.cpp +++ b/source/Gui/ActivateUserDialog.cpp @@ -3,10 +3,10 @@ #include #include "EngineInterface/SimulationController.h" +#include "Network/NetworkController.h" #include "AlienImGui.h" #include "MessageDialog.h" -#include "NetworkController.h" #include "BrowserWindow.h" #include "CreateUserDialog.h" #include "StyleRepository.h" diff --git a/source/Gui/ActivateUserDialog.h b/source/Gui/ActivateUserDialog.h index 15d4b5ae9..224bf28c3 100644 --- a/source/Gui/ActivateUserDialog.h +++ b/source/Gui/ActivateUserDialog.h @@ -1,8 +1,9 @@ #pragma once +#include "Network/NetworkController.h" + #include "AlienDialog.h" #include "Definitions.h" -#include "NetworkController.h" class _ActivateUserDialog : public _AlienDialog { diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index a26d7f70f..987e16a34 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -21,12 +21,12 @@ #include "EngineInterface/GenomeDescriptionService.h" #include "EngineInterface/SerializerService.h" #include "EngineInterface/SimulationController.h" +#include "Network/BrowserDataService.h" +#include "Network/NetworkController.h" +#include "Network/NetworkDataParserService.h" #include "AlienImGui.h" -#include "BrowserDataService.h" #include "StyleRepository.h" -#include "NetworkDataParserService.h" -#include "NetworkController.h" #include "StatisticsWindow.h" #include "Viewport.h" #include "TemporalControlWindow.h" diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index 7c2199c53..9d22c6940 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -4,11 +4,11 @@ #include "Base/Hashes.h" #include "EngineInterface/Definitions.h" +#include "Network/BrowserDataTO.h" +#include "Network/NetworkDataTO.h" +#include "Network/UserTO.h" #include "AlienWindow.h" -#include "BrowserDataTO.h" -#include "NetworkDataTO.h" -#include "UserTO.h" #include "Definitions.h" class _BrowserWindow : public _AlienWindow diff --git a/source/Gui/CMakeLists.txt b/source/Gui/CMakeLists.txt index a1d621644..545775e2d 100644 --- a/source/Gui/CMakeLists.txt +++ b/source/Gui/CMakeLists.txt @@ -13,10 +13,6 @@ PUBLIC AlienWindow.h AutosaveController.cpp AutosaveController.h - BrowserDataService.cpp - BrowserDataService.h - BrowserDataTO.cpp - BrowserDataTO.h BrowserWindow.cpp BrowserWindow.h CellFunctionStrings.h @@ -71,12 +67,6 @@ PUBLIC ModeController.h MultiplierWindow.cpp MultiplierWindow.h - NetworkController.cpp - NetworkController.h - NetworkDataParserService.cpp - NetworkDataParserService.h - NetworkDataTO.cpp - NetworkDataTO.h NetworkSettingsDialog.cpp NetworkSettingsDialog.h NewSimulationDialog.cpp @@ -125,7 +115,6 @@ PUBLIC UiController.h UploadSimulationDialog.cpp UploadSimulationDialog.h - UserTO.h Viewport.cpp Viewport.h WindowController.cpp @@ -135,6 +124,7 @@ target_link_libraries(alien BaseLib) target_link_libraries(alien EngineGpuKernelsLib) target_link_libraries(alien EngineImplLib) target_link_libraries(alien EngineInterfaceLib) +target_link_libraries(alien NetworkLib) target_link_libraries(alien im_file_dialog) target_link_libraries(alien CUDA::cudart_static) diff --git a/source/Gui/CreateUserDialog.cpp b/source/Gui/CreateUserDialog.cpp index 01e3431e2..ac740632e 100644 --- a/source/Gui/CreateUserDialog.cpp +++ b/source/Gui/CreateUserDialog.cpp @@ -3,9 +3,10 @@ #include #include +#include "Network/NetworkController.h" + #include "AlienImGui.h" #include "MessageDialog.h" -#include "NetworkController.h" #include "ActivateUserDialog.h" _CreateUserDialog::_CreateUserDialog(ActivateUserDialog const& activateUserDialog, NetworkController const& networkController) diff --git a/source/Gui/CreateUserDialog.h b/source/Gui/CreateUserDialog.h index 4cec86eb6..3c99f0d9f 100644 --- a/source/Gui/CreateUserDialog.h +++ b/source/Gui/CreateUserDialog.h @@ -1,8 +1,9 @@ #pragma once +#include "Network/NetworkController.h" + #include "AlienDialog.h" #include "Definitions.h" -#include "NetworkController.h" class _CreateUserDialog : public _AlienDialog { diff --git a/source/Gui/Definitions.h b/source/Gui/Definitions.h index 6ba1249f5..031473364 100644 --- a/source/Gui/Definitions.h +++ b/source/Gui/Definitions.h @@ -115,9 +115,6 @@ using BrowserWindow = std::shared_ptr<_BrowserWindow>; class _ShaderWindow; using ShaderWindow = std::shared_ptr<_ShaderWindow>; -class _NetworkController; -using NetworkController = std::shared_ptr<_NetworkController>; - class _LoginDialog; using LoginDialog = std::shared_ptr<_LoginDialog>; using LoginDialogWeakPtr = std::weak_ptr<_LoginDialog>; @@ -169,17 +166,4 @@ struct TextureData unsigned int textureId; int width; int height; -}; - -using DataType = int; -enum DataType_ -{ - DataType_Simulation, - DataType_Genome -}; - -struct _BrowserDataTO; -using BrowserDataTO = std::shared_ptr<_BrowserDataTO>; - -struct _NetworkDataTO; -using NetworkDataTO = std::shared_ptr<_NetworkDataTO>; +}; \ No newline at end of file diff --git a/source/Gui/DeleteUserDialog.cpp b/source/Gui/DeleteUserDialog.cpp index 62f431b51..98d46a83b 100644 --- a/source/Gui/DeleteUserDialog.cpp +++ b/source/Gui/DeleteUserDialog.cpp @@ -2,11 +2,12 @@ #include +#include "Network/NetworkController.h" + #include "AlienImGui.h" #include "BrowserWindow.h" #include "CreateUserDialog.h" #include "MessageDialog.h" -#include "NetworkController.h" _DeleteUserDialog::_DeleteUserDialog(BrowserWindow const& browserWindow, NetworkController const& networkController) : _AlienDialog("Delete user") diff --git a/source/Gui/DeleteUserDialog.h b/source/Gui/DeleteUserDialog.h index 27ec0093e..a7f2fb80a 100644 --- a/source/Gui/DeleteUserDialog.h +++ b/source/Gui/DeleteUserDialog.h @@ -1,5 +1,7 @@ #pragma once +#include "Network/Definitions.h" + #include "AlienDialog.h" #include "Definitions.h" diff --git a/source/Gui/LoginDialog.cpp b/source/Gui/LoginDialog.cpp index ef226ab95..b3c5ccb25 100644 --- a/source/Gui/LoginDialog.cpp +++ b/source/Gui/LoginDialog.cpp @@ -4,9 +4,9 @@ #include "Base/GlobalSettings.h" #include "EngineInterface/SimulationController.h" +#include "Network/NetworkController.h" #include "AlienImGui.h" -#include "NetworkController.h" #include "MessageDialog.h" #include "CreateUserDialog.h" #include "BrowserWindow.h" diff --git a/source/Gui/LoginDialog.h b/source/Gui/LoginDialog.h index 3ffa6fa73..b0c8848bc 100644 --- a/source/Gui/LoginDialog.h +++ b/source/Gui/LoginDialog.h @@ -1,5 +1,7 @@ #pragma once +#include "Network/Definitions.h" + #include "AlienDialog.h" #include "Definitions.h" diff --git a/source/Gui/MainWindow.cpp b/source/Gui/MainWindow.cpp index bf152018f..958faa975 100644 --- a/source/Gui/MainWindow.cpp +++ b/source/Gui/MainWindow.cpp @@ -23,6 +23,7 @@ #include "EngineInterface/SerializerService.h" #include "EngineInterface/SimulationController.h" +#include "Network/NetworkController.h" #include "ModeController.h" #include "SimulationView.h" @@ -53,7 +54,6 @@ #include "PatternAnalysisDialog.h" #include "MessageDialog.h" #include "FpsController.h" -#include "NetworkController.h" #include "BrowserWindow.h" #include "LoginDialog.h" #include "UploadSimulationDialog.h" diff --git a/source/Gui/MainWindow.h b/source/Gui/MainWindow.h index a67ce56d1..1b0efea18 100644 --- a/source/Gui/MainWindow.h +++ b/source/Gui/MainWindow.h @@ -1,6 +1,8 @@ #pragma once #include "EngineInterface/Definitions.h" +#include "Network/Definitions.h" + #include "Definitions.h" class _MainWindow diff --git a/source/Gui/NetworkSettingsDialog.cpp b/source/Gui/NetworkSettingsDialog.cpp index c3892cf3a..2d0eb3918 100644 --- a/source/Gui/NetworkSettingsDialog.cpp +++ b/source/Gui/NetworkSettingsDialog.cpp @@ -2,8 +2,9 @@ #include +#include "Network/NetworkController.h" + #include "AlienImGui.h" -#include "NetworkController.h" #include "BrowserWindow.h" #include "StyleRepository.h" diff --git a/source/Gui/NetworkSettingsDialog.h b/source/Gui/NetworkSettingsDialog.h index 48365553b..27dc663fd 100644 --- a/source/Gui/NetworkSettingsDialog.h +++ b/source/Gui/NetworkSettingsDialog.h @@ -1,5 +1,7 @@ #pragma once +#include "Network/Definitions.h" + #include "AlienDialog.h" #include "Definitions.h" diff --git a/source/Gui/NewPasswordDialog.cpp b/source/Gui/NewPasswordDialog.cpp index 5d0068827..545793661 100644 --- a/source/Gui/NewPasswordDialog.cpp +++ b/source/Gui/NewPasswordDialog.cpp @@ -3,11 +3,11 @@ #include #include "EngineInterface/SimulationController.h" +#include "Network/NetworkController.h" #include "AlienImGui.h" #include "BrowserWindow.h" #include "MessageDialog.h" -#include "NetworkController.h" _NewPasswordDialog::_NewPasswordDialog( SimulationController const& simController, diff --git a/source/Gui/NewPasswordDialog.h b/source/Gui/NewPasswordDialog.h index 786557aea..5182dd2fa 100644 --- a/source/Gui/NewPasswordDialog.h +++ b/source/Gui/NewPasswordDialog.h @@ -1,8 +1,9 @@ #pragma once +#include "Network/NetworkController.h" + #include "AlienDialog.h" #include "Definitions.h" -#include "NetworkController.h" class _NewPasswordDialog : public _AlienDialog { diff --git a/source/Gui/ResetPasswordDialog.h b/source/Gui/ResetPasswordDialog.h index 86c248889..6224943cf 100644 --- a/source/Gui/ResetPasswordDialog.h +++ b/source/Gui/ResetPasswordDialog.h @@ -1,8 +1,9 @@ #pragma once +#include "Network/NetworkController.h" + #include "AlienDialog.h" #include "Definitions.h" -#include "NetworkController.h" class _ResetPasswordDialog : public _AlienDialog { diff --git a/source/Gui/UploadSimulationDialog.cpp b/source/Gui/UploadSimulationDialog.cpp index a169a0d4f..96bd5d350 100644 --- a/source/Gui/UploadSimulationDialog.cpp +++ b/source/Gui/UploadSimulationDialog.cpp @@ -6,10 +6,10 @@ #include "EngineInterface/SerializerService.h" #include "EngineInterface/SimulationController.h" #include "EngineInterface/GenomeDescriptionService.h" +#include "Network/NetworkController.h" #include "AlienImGui.h" #include "MessageDialog.h" -#include "NetworkController.h" #include "StyleRepository.h" #include "BrowserWindow.h" #include "DelayedExecutionController.h" diff --git a/source/Gui/UploadSimulationDialog.h b/source/Gui/UploadSimulationDialog.h index 4f18b98a2..b35fa450b 100644 --- a/source/Gui/UploadSimulationDialog.h +++ b/source/Gui/UploadSimulationDialog.h @@ -1,7 +1,9 @@ #pragma once -#include "AlienDialog.h" #include "EngineInterface/Definitions.h" +#include "Network/Definitions.h" + +#include "AlienDialog.h" #include "Definitions.h" class _UploadSimulationDialog : public _AlienDialog diff --git a/source/GuiTests/CMakeLists.txt b/source/GuiTests/CMakeLists.txt deleted file mode 100644 index aacf926f5..000000000 --- a/source/GuiTests/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -target_sources(GuiTests -PUBLIC - Testsuite.cpp) - -target_link_libraries(GuiTests BaseLib) -target_link_libraries(GuiTests EngineGpuKernelsLib) -target_link_libraries(GuiTests EngineImplLib) -target_link_libraries(GuiTests EngineInterfaceLib) - -target_link_libraries(GuiTests CUDA::cudart_static) -target_link_libraries(GuiTests CUDA::cuda_driver) -target_link_libraries(GuiTests Boost::boost) -target_link_libraries(GuiTests OpenGL::GL OpenGL::GLU) -target_link_libraries(GuiTests GLEW::GLEW) -target_link_libraries(GuiTests glfw) -target_link_libraries(GuiTests glad::glad) -target_link_libraries(GuiTests GTest::GTest GTest::Main) - -if (MSVC) - target_compile_options(GuiTests PRIVATE "/MP") -endif() diff --git a/source/Gui/BrowserDataService.cpp b/source/Network/BrowserDataService.cpp similarity index 100% rename from source/Gui/BrowserDataService.cpp rename to source/Network/BrowserDataService.cpp diff --git a/source/Gui/BrowserDataService.h b/source/Network/BrowserDataService.h similarity index 100% rename from source/Gui/BrowserDataService.h rename to source/Network/BrowserDataService.h diff --git a/source/Gui/BrowserDataTO.cpp b/source/Network/BrowserDataTO.cpp similarity index 100% rename from source/Gui/BrowserDataTO.cpp rename to source/Network/BrowserDataTO.cpp diff --git a/source/Gui/BrowserDataTO.h b/source/Network/BrowserDataTO.h similarity index 100% rename from source/Gui/BrowserDataTO.h rename to source/Network/BrowserDataTO.h diff --git a/source/Network/CMakeLists.txt b/source/Network/CMakeLists.txt new file mode 100644 index 000000000..b53ccc6e9 --- /dev/null +++ b/source/Network/CMakeLists.txt @@ -0,0 +1,21 @@ + +add_library(NetworkLib + BrowserDataService.cpp + BrowserDataService.h + BrowserDataTO.cpp + BrowserDataTO.h + Definitions.h + NetworkController.cpp + NetworkController.h + NetworkDataParserService.cpp + NetworkDataParserService.h + NetworkDataTO.cpp + NetworkDataTO.h + UserTO.h) + +target_link_libraries(NetworkLib BaseLib) +target_link_libraries(NetworkLib Boost::boost) + +if (MSVC) + target_compile_options(NetworkLib PRIVATE "/MP") +endif() diff --git a/source/Network/Definitions.h b/source/Network/Definitions.h new file mode 100644 index 000000000..018075bd7 --- /dev/null +++ b/source/Network/Definitions.h @@ -0,0 +1,19 @@ +#pragma once + +#include "Base/Definitions.h" + +class _NetworkController; +using NetworkController = std::shared_ptr<_NetworkController>; + +using DataType = int; +enum DataType_ +{ + DataType_Simulation, + DataType_Genome +}; + +struct _BrowserDataTO; +using BrowserDataTO = std::shared_ptr<_BrowserDataTO>; + +struct _NetworkDataTO; +using NetworkDataTO = std::shared_ptr<_NetworkDataTO>; diff --git a/source/Gui/NetworkController.cpp b/source/Network/NetworkController.cpp similarity index 99% rename from source/Gui/NetworkController.cpp rename to source/Network/NetworkController.cpp index 8e527b1c7..8b29a1477 100644 --- a/source/Gui/NetworkController.cpp +++ b/source/Network/NetworkController.cpp @@ -9,7 +9,6 @@ #include "Base/LoggingService.h" #include "Base/Resources.h" -#include "MessageDialog.h" #include "NetworkDataParserService.h" namespace diff --git a/source/Gui/NetworkController.h b/source/Network/NetworkController.h similarity index 100% rename from source/Gui/NetworkController.h rename to source/Network/NetworkController.h diff --git a/source/Gui/NetworkDataParserService.cpp b/source/Network/NetworkDataParserService.cpp similarity index 100% rename from source/Gui/NetworkDataParserService.cpp rename to source/Network/NetworkDataParserService.cpp diff --git a/source/Gui/NetworkDataParserService.h b/source/Network/NetworkDataParserService.h similarity index 100% rename from source/Gui/NetworkDataParserService.h rename to source/Network/NetworkDataParserService.h diff --git a/source/Gui/NetworkDataTO.cpp b/source/Network/NetworkDataTO.cpp similarity index 100% rename from source/Gui/NetworkDataTO.cpp rename to source/Network/NetworkDataTO.cpp diff --git a/source/Gui/NetworkDataTO.h b/source/Network/NetworkDataTO.h similarity index 100% rename from source/Gui/NetworkDataTO.h rename to source/Network/NetworkDataTO.h diff --git a/source/Gui/UserTO.h b/source/Network/UserTO.h similarity index 100% rename from source/Gui/UserTO.h rename to source/Network/UserTO.h diff --git a/source/NetworkTests/BrowserDataServiceTests.cpp b/source/NetworkTests/BrowserDataServiceTests.cpp new file mode 100644 index 000000000..d13baa885 --- /dev/null +++ b/source/NetworkTests/BrowserDataServiceTests.cpp @@ -0,0 +1,25 @@ +#include + +#include "Base/NumberGenerator.h" +#include "Network/NetworkDataTO.h" +#include "Network/BrowserDataService.h" + +class BrowserDataServiceTests : public ::testing::Test +{ +public: + BrowserDataServiceTests() + {} + ~BrowserDataServiceTests() = default; +}; + +TEST_F(BrowserDataServiceTests, singleLeaf) +{ + std::vector inputTOs; + auto inputTO = std::make_shared<_NetworkDataTO>(); + inputTO->simName = "test"; + inputTOs.emplace_back(inputTO); + + auto outputTOs = BrowserDataService::createBrowserData(inputTOs); + + ASSERT_EQ(1, outputTOs.size()); +} diff --git a/source/NetworkTests/CMakeLists.txt b/source/NetworkTests/CMakeLists.txt new file mode 100644 index 000000000..26f45d155 --- /dev/null +++ b/source/NetworkTests/CMakeLists.txt @@ -0,0 +1,19 @@ +target_sources(NetworkTests +PUBLIC + BrowserDataServiceTests.cpp + Testsuite.cpp) + +target_link_libraries(NetworkTests BaseLib) +target_link_libraries(NetworkTests EngineInterfaceLib) +target_link_libraries(NetworkTests NetworkLib) + +target_link_libraries(NetworkTests Boost::boost) +target_link_libraries(NetworkTests OpenGL::GL OpenGL::GLU) +target_link_libraries(NetworkTests GLEW::GLEW) +target_link_libraries(NetworkTests glfw) +target_link_libraries(NetworkTests glad::glad) +target_link_libraries(NetworkTests GTest::GTest GTest::Main) + +if (MSVC) + target_compile_options(NetworkTests PRIVATE "/MP") +endif() diff --git a/source/GuiTests/Testsuite.cpp b/source/NetworkTests/Testsuite.cpp similarity index 100% rename from source/GuiTests/Testsuite.cpp rename to source/NetworkTests/Testsuite.cpp From db02093d651bf4c8e7fa6ee94c3b2082394554c4 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Wed, 20 Dec 2023 21:53:41 +0100 Subject: [PATCH 09/40] renamings --- source/Gui/ActivateUserDialog.cpp | 10 +- source/Gui/ActivateUserDialog.h | 6 +- source/Gui/BrowserWindow.cpp | 46 ++++----- source/Gui/BrowserWindow.h | 4 +- source/Gui/CreateUserDialog.cpp | 8 +- source/Gui/CreateUserDialog.h | 6 +- source/Gui/DeleteUserDialog.cpp | 14 +-- source/Gui/DeleteUserDialog.h | 4 +- source/Gui/LoginDialog.cpp | 10 +- source/Gui/LoginDialog.h | 4 +- source/Gui/MainWindow.cpp | 45 +++++---- source/Gui/MainWindow.h | 2 +- source/Gui/NetworkSettingsDialog.cpp | 10 +- source/Gui/NetworkSettingsDialog.h | 4 +- source/Gui/NewPasswordDialog.cpp | 10 +- source/Gui/NewPasswordDialog.h | 6 +- source/Gui/ResetPasswordDialog.cpp | 6 +- source/Gui/ResetPasswordDialog.h | 6 +- source/Gui/UploadSimulationDialog.cpp | 10 +- source/Gui/UploadSimulationDialog.h | 4 +- source/Network/Definitions.h | 4 +- ...tworkController.cpp => NetworkService.cpp} | 94 ++++++++----------- .../{NetworkController.h => NetworkService.h} | 11 +-- 23 files changed, 155 insertions(+), 169 deletions(-) rename source/Network/{NetworkController.cpp => NetworkService.cpp} (85%) rename source/Network/{NetworkController.h => NetworkService.h} (95%) diff --git a/source/Gui/ActivateUserDialog.cpp b/source/Gui/ActivateUserDialog.cpp index 9256e9521..8a43d2dd9 100644 --- a/source/Gui/ActivateUserDialog.cpp +++ b/source/Gui/ActivateUserDialog.cpp @@ -3,7 +3,7 @@ #include #include "EngineInterface/SimulationController.h" -#include "Network/NetworkController.h" +#include "Network/NetworkService.h" #include "AlienImGui.h" #include "MessageDialog.h" @@ -14,11 +14,11 @@ _ActivateUserDialog::_ActivateUserDialog( SimulationController const& simController, BrowserWindow const& browserWindow, - NetworkController const& networkController) + NetworkService const& networkController) : _AlienDialog("Activate user") , _simController(simController) , _browserWindow(browserWindow) - , _networkController(networkController) + , _networkService(networkController) {} _ActivateUserDialog::~_ActivateUserDialog() {} @@ -81,10 +81,10 @@ void _ActivateUserDialog::processIntern() void _ActivateUserDialog::onActivateUser() { - auto result = _networkController->activateUser(_userName, _password, _userInfo, _confirmationCode); + auto result = _networkService->activateUser(_userName, _password, _userInfo, _confirmationCode); if (result) { LoginErrorCode errorCode; - result |= _networkController->login(errorCode, _userName, _password, _userInfo); + result |= _networkService->login(errorCode, _userName, _password, _userInfo); } if (!result) { MessageDialog::getInstance().information("Error", "An error occurred on the server. Your entered code may be incorrect.\nPlease try to register again."); diff --git a/source/Gui/ActivateUserDialog.h b/source/Gui/ActivateUserDialog.h index 224bf28c3..88b97ca76 100644 --- a/source/Gui/ActivateUserDialog.h +++ b/source/Gui/ActivateUserDialog.h @@ -1,6 +1,6 @@ #pragma once -#include "Network/NetworkController.h" +#include "Network/NetworkService.h" #include "AlienDialog.h" #include "Definitions.h" @@ -8,7 +8,7 @@ class _ActivateUserDialog : public _AlienDialog { public: - _ActivateUserDialog(SimulationController const& simController, BrowserWindow const& browserWindow, NetworkController const& networkController); + _ActivateUserDialog(SimulationController const& simController, BrowserWindow const& browserWindow, NetworkService const& networkController); ~_ActivateUserDialog(); void registerCyclicReferences(CreateUserDialogWeakPtr const& createUserDialog); @@ -21,7 +21,7 @@ class _ActivateUserDialog : public _AlienDialog SimulationController _simController; BrowserWindow _browserWindow; - NetworkController _networkController; + NetworkService _networkService; CreateUserDialogWeakPtr _createUserDialog; std::string _userName; diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 987e16a34..8837db2dc 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -22,7 +22,7 @@ #include "EngineInterface/SerializerService.h" #include "EngineInterface/SimulationController.h" #include "Network/BrowserDataService.h" -#include "Network/NetworkController.h" +#include "Network/NetworkService.h" #include "Network/NetworkDataParserService.h" #include "AlienImGui.h" @@ -54,14 +54,14 @@ namespace _BrowserWindow::_BrowserWindow( SimulationController const& simController, - NetworkController const& networkController, + NetworkService const& networkController, StatisticsWindow const& statisticsWindow, Viewport const& viewport, TemporalControlWindow const& temporalControlWindow, EditorController const& editorController) : _AlienWindow("Browser", "windows.browser", true) , _simController(simController) - , _networkController(networkController) + , _networkService(networkController) , _statisticsWindow(statisticsWindow) , _viewport(viewport) , _temporalControlWindow(temporalControlWindow) @@ -103,8 +103,10 @@ void _BrowserWindow::onRefresh() void _BrowserWindow::refreshIntern(bool withRetry) { try { - bool success = _networkController->getRemoteSimulationList(_rawNetworkDataTOs, withRetry); - success &= _networkController->getUserList(_userTOs, withRetry); + _networkService->refreshLogin(); + + bool success = _networkService->getRemoteSimulationList(_rawNetworkDataTOs, withRetry); + success &= _networkService->getUserList(_userTOs, withRetry); if (!success) { if (withRetry) { @@ -124,8 +126,8 @@ void _BrowserWindow::refreshIntern(bool withRetry) calcFilteredSimulationAndGenomeLists(); _scheduleCreateBrowserData = true; - if (_networkController->getLoggedInUserName()) { - if (!_networkController->getEmojiTypeBySimId(_ownEmojiTypeBySimId)) { + if (_networkService->getLoggedInUserName()) { + if (!_networkService->getEmojiTypeBySimId(_ownEmojiTypeBySimId)) { MessageDialog::getInstance().information("Error", "Failed to retrieve browser data. Please try again."); } } else { @@ -215,7 +217,7 @@ void _BrowserWindow::processToolbar() AlienImGui::Tooltip("Refresh"); ImGui::SameLine(); - ImGui::BeginDisabled(_networkController->getLoggedInUserName().has_value()); + ImGui::BeginDisabled(_networkService->getLoggedInUserName().has_value()); if (AlienImGui::ToolbarButton(ICON_FA_SIGN_IN_ALT)) { if (auto loginDialog = _loginDialog.lock()) { loginDialog->open(); @@ -225,10 +227,10 @@ void _BrowserWindow::processToolbar() AlienImGui::Tooltip("Login or register"); ImGui::SameLine(); - ImGui::BeginDisabled(!_networkController->getLoggedInUserName()); + ImGui::BeginDisabled(!_networkService->getLoggedInUserName()); if (AlienImGui::ToolbarButton(ICON_FA_SIGN_OUT_ALT)) { if (auto loginDialog = _loginDialog.lock()) { - _networkController->logout(); + _networkService->logout(); onRefresh(); } } @@ -493,7 +495,7 @@ void _BrowserWindow::processUserList() AlienImGui::Group("Simulators"); if (ImGui::BeginTable("Browser", 5, flags, ImVec2(0, 0), 0.0f)) { ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, scale(90.0f)); - auto isLoggedIn = _networkController->getLoggedInUserName().has_value(); + auto isLoggedIn = _networkService->getLoggedInUserName().has_value(); ImGui::TableSetupColumn( isLoggedIn ? "GPU model" : "GPU (visible if logged in)", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, @@ -515,7 +517,7 @@ void _BrowserWindow::processUserList() ImGui::TableNextRow(0, scale(RowHeight)); ImGui::TableNextColumn(); - auto isBoldFont = isLoggedIn && *_networkController->getLoggedInUserName() == item->userName; + auto isBoldFont = isLoggedIn && *_networkService->getLoggedInUserName() == item->userName; if (item->online) { AlienImGui::OnlineSymbol(); @@ -567,13 +569,13 @@ void _BrowserWindow::processStatus() statusText += std::to_string(_userTOs.size()) + " simulators found"; statusText += std::string(" " ICON_FA_INFO_CIRCLE " "); - if (auto userName = _networkController->getLoggedInUserName()) { - statusText += "Logged in as " + *userName + " @ " + _networkController->getServerAddress();// + ": "; + if (auto userName = _networkService->getLoggedInUserName()) { + statusText += "Logged in as " + *userName + " @ " + _networkService->getServerAddress();// + ": "; } else { - statusText += "Not logged in to " + _networkController->getServerAddress();// + ": "; + statusText += "Not logged in to " + _networkService->getServerAddress();// + ": "; } - if (!_networkController->getLoggedInUserName()) { + if (!_networkService->getLoggedInUserName()) { statusText += std::string(" " ICON_FA_INFO_CIRCLE " "); statusText += "In order to share and upvote simulations you need to log in."; } @@ -769,7 +771,7 @@ void _BrowserWindow::processActionButtons(BrowserDataTO const& to) ImGui::SameLine(); //delete button - if (leaf.userName == _networkController->getLoggedInUserName().value_or("")) { + if (leaf.userName == _networkService->getLoggedInUserName().value_or("")) { ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DeleteButtonTextColor); auto deleteButtonResult = processActionButton(ICON_FA_TRASH); ImGui::PopStyleColor(); @@ -864,7 +866,7 @@ void _BrowserWindow::onDownloadItem(BrowserLeaf const& leaf) delayedExecution([=, this] { std::string dataTypeString = _selectedDataType == DataType_Simulation ? "simulation" : "genome"; SerializedSimulation serializedSim; - if (!_networkController->downloadSimulation(serializedSim.mainData, serializedSim.auxiliaryData, serializedSim.statistics, leaf.id)) { + if (!_networkService->downloadSimulation(serializedSim.mainData, serializedSim.auxiliaryData, serializedSim.statistics, leaf.id)) { MessageDialog::getInstance().information("Error", "Failed to download " + dataTypeString + "."); return; } @@ -926,7 +928,7 @@ void _BrowserWindow::onDeleteItem(BrowserLeaf const& leaf) printOverlayMessage("Deleting ..."); delayedExecution([leafCopy = leaf, this] { - if (!_networkController->deleteSimulation(leafCopy.id)) { + if (!_networkService->deleteSimulation(leafCopy.id)) { MessageDialog::getInstance().information("Error", "Failed to delete item. Please try again later."); return; } @@ -939,7 +941,7 @@ void _BrowserWindow::onToggleLike(BrowserDataTO const& to, int emojiType) { CHECK(to->isLeaf()); auto& leaf = to->getLeaf(); - if (_networkController->getLoggedInUserName()) { + if (_networkService->getLoggedInUserName()) { //remove existing like auto findResult = _ownEmojiTypeBySimId.find(leaf.id); @@ -965,7 +967,7 @@ void _BrowserWindow::onToggleLike(BrowserDataTO const& to, int emojiType) } _userNamesByEmojiTypeBySimIdCache.erase(std::make_pair(leaf.id, emojiType)); //invalidate cache entry - _networkController->toggleLikeSimulation(leaf.id, emojiType); + _networkService->toggleLikeSimulation(leaf.id, emojiType); //_scheduleCreateBrowserData = true; } else { _loginDialog.lock()->open(); @@ -992,7 +994,7 @@ std::string _BrowserWindow::getUserNamesToEmojiType(std::string const& simId, in if (findResult != _userNamesByEmojiTypeBySimIdCache.end()) { userNames = findResult->second; } else { - _networkController->getUserNamesForSimulationAndEmojiType(userNames, simId, emojiType); + _networkService->getUserNamesForSimulationAndEmojiType(userNames, simId, emojiType); _userNamesByEmojiTypeBySimIdCache.emplace(std::make_pair(simId, emojiType), userNames); } diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index 9d22c6940..a3bcb30f2 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -16,7 +16,7 @@ class _BrowserWindow : public _AlienWindow public: _BrowserWindow( SimulationController const& simController, - NetworkController const& networkController, + NetworkService const& networkController, StatisticsWindow const& statisticsWindow, Viewport const& viewport, TemporalControlWindow const& temporalControlWindow, @@ -97,7 +97,7 @@ class _BrowserWindow : public _AlienWindow std::optional _lastRefreshTime; SimulationController _simController; - NetworkController _networkController; + NetworkService _networkService; StatisticsWindow _statisticsWindow; Viewport _viewport; TemporalControlWindow _temporalControlWindow; diff --git a/source/Gui/CreateUserDialog.cpp b/source/Gui/CreateUserDialog.cpp index ac740632e..abb77a8e1 100644 --- a/source/Gui/CreateUserDialog.cpp +++ b/source/Gui/CreateUserDialog.cpp @@ -3,15 +3,15 @@ #include #include -#include "Network/NetworkController.h" +#include "Network/NetworkService.h" #include "AlienImGui.h" #include "MessageDialog.h" #include "ActivateUserDialog.h" -_CreateUserDialog::_CreateUserDialog(ActivateUserDialog const& activateUserDialog, NetworkController const& networkController) +_CreateUserDialog::_CreateUserDialog(ActivateUserDialog const& activateUserDialog, NetworkService const& networkController) : _AlienDialog("Create user") - , _networkController(networkController) + , _networkService(networkController) , _activateUserDialog(activateUserDialog) { } @@ -62,7 +62,7 @@ void _CreateUserDialog::processIntern() void _CreateUserDialog::onCreateUser() { - if (_networkController->createUser(_userName, _password, _email)) { + if (_networkService->createUser(_userName, _password, _email)) { _activateUserDialog->open(_userName, _password, _userInfo); } else { MessageDialog::getInstance().information( diff --git a/source/Gui/CreateUserDialog.h b/source/Gui/CreateUserDialog.h index 3c99f0d9f..c2417706f 100644 --- a/source/Gui/CreateUserDialog.h +++ b/source/Gui/CreateUserDialog.h @@ -1,6 +1,6 @@ #pragma once -#include "Network/NetworkController.h" +#include "Network/NetworkService.h" #include "AlienDialog.h" #include "Definitions.h" @@ -8,7 +8,7 @@ class _CreateUserDialog : public _AlienDialog { public: - _CreateUserDialog(ActivateUserDialog const& activateUserDialog, NetworkController const& networkController); + _CreateUserDialog(ActivateUserDialog const& activateUserDialog, NetworkService const& networkController); ~_CreateUserDialog(); void open(std::string const& userName, std::string const& password, UserInfo const& userInfo); @@ -17,7 +17,7 @@ class _CreateUserDialog : public _AlienDialog private: void processIntern(); - NetworkController _networkController; + NetworkService _networkService; ActivateUserDialog _activateUserDialog; std::string _userName; diff --git a/source/Gui/DeleteUserDialog.cpp b/source/Gui/DeleteUserDialog.cpp index 98d46a83b..b8354838e 100644 --- a/source/Gui/DeleteUserDialog.cpp +++ b/source/Gui/DeleteUserDialog.cpp @@ -2,24 +2,24 @@ #include -#include "Network/NetworkController.h" +#include "Network/NetworkService.h" #include "AlienImGui.h" #include "BrowserWindow.h" #include "CreateUserDialog.h" #include "MessageDialog.h" -_DeleteUserDialog::_DeleteUserDialog(BrowserWindow const& browserWindow, NetworkController const& networkController) +_DeleteUserDialog::_DeleteUserDialog(BrowserWindow const& browserWindow, NetworkService const& networkController) : _AlienDialog("Delete user") , _browserWindow(browserWindow) - , _networkController(networkController) + , _networkService(networkController) { } void _DeleteUserDialog::processIntern() { AlienImGui::Text( - "Warning: All the data of the user '" + *_networkController->getLoggedInUserName() + "Warning: All the data of the user '" + *_networkService->getLoggedInUserName() + "' will be deleted on the server side.\nThese include the likes, the simulations and the account data."); AlienImGui::Separator(); @@ -29,7 +29,7 @@ void _DeleteUserDialog::processIntern() ImGui::BeginDisabled(_reenteredPassword.empty()); if (AlienImGui::Button("Delete")) { close(); - if (_reenteredPassword == *_networkController->getPassword()) { + if (_reenteredPassword == *_networkService->getPassword()) { onDelete(); } else { MessageDialog::getInstance().information("Error", "The password does not match."); @@ -48,8 +48,8 @@ void _DeleteUserDialog::processIntern() void _DeleteUserDialog::onDelete() { - auto userName = *_networkController->getLoggedInUserName(); - if (_networkController->deleteUser()) { + auto userName = *_networkService->getLoggedInUserName(); + if (_networkService->deleteUser()) { _browserWindow->onRefresh(); MessageDialog::getInstance().information("Information", "The user '" + userName + "' has been deleted.\nYou are logged out."); } else { diff --git a/source/Gui/DeleteUserDialog.h b/source/Gui/DeleteUserDialog.h index a7f2fb80a..eb90b3020 100644 --- a/source/Gui/DeleteUserDialog.h +++ b/source/Gui/DeleteUserDialog.h @@ -8,14 +8,14 @@ class _DeleteUserDialog : public _AlienDialog { public: - _DeleteUserDialog(BrowserWindow const& browserWindow, NetworkController const& networkController); + _DeleteUserDialog(BrowserWindow const& browserWindow, NetworkService const& networkController); private: void processIntern(); void onDelete(); BrowserWindow _browserWindow; - NetworkController _networkController; + NetworkService _networkService; std::string _reenteredPassword; }; diff --git a/source/Gui/LoginDialog.cpp b/source/Gui/LoginDialog.cpp index b3c5ccb25..0b1302d46 100644 --- a/source/Gui/LoginDialog.cpp +++ b/source/Gui/LoginDialog.cpp @@ -4,7 +4,7 @@ #include "Base/GlobalSettings.h" #include "EngineInterface/SimulationController.h" -#include "Network/NetworkController.h" +#include "Network/NetworkService.h" #include "AlienImGui.h" #include "MessageDialog.h" @@ -21,13 +21,13 @@ _LoginDialog::_LoginDialog( CreateUserDialog const& createUserDialog, ActivateUserDialog const& activateUserDialog, ResetPasswordDialog const& resetPasswordDialog, - NetworkController const& networkController) + NetworkService const& networkController) : _AlienDialog("Login") , _simController(simController) , _browserWindow(browserWindow) , _createUserDialog(createUserDialog) , _activateUserDialog(activateUserDialog) - , _networkController(networkController) + , _networkService(networkController) , _resetPasswordDialog(resetPasswordDialog) { @@ -40,7 +40,7 @@ _LoginDialog::_LoginDialog( _password = settings.getStringState("dialogs.login.password", ""); if (!_userName.empty()) { LoginErrorCode errorCode; - if (!_networkController->login(errorCode, _userName, _password, getUserInfo())) { + if (!_networkService->login(errorCode, _userName, _password, getUserInfo())) { if (errorCode != LoginErrorCode_UnconfirmedUser) { MessageDialog::getInstance().information("Error", "Login failed."); } @@ -132,7 +132,7 @@ void _LoginDialog::onLogin() auto userInfo = getUserInfo(); - if (!_networkController->login(errorCode, _userName, _password, userInfo)) { + if (!_networkService->login(errorCode, _userName, _password, userInfo)) { switch (errorCode) { case LoginErrorCode_UnconfirmedUser: { _activateUserDialog->open(_userName, _password, userInfo); diff --git a/source/Gui/LoginDialog.h b/source/Gui/LoginDialog.h index b0c8848bc..1dd8719cf 100644 --- a/source/Gui/LoginDialog.h +++ b/source/Gui/LoginDialog.h @@ -14,7 +14,7 @@ class _LoginDialog : public _AlienDialog CreateUserDialog const& createUserDialog, ActivateUserDialog const& activateUserDialog, ResetPasswordDialog const& resetPasswordDialog, - NetworkController const& networkController); + NetworkService const& networkController); ~_LoginDialog(); bool isShareGpuInfo() const; @@ -31,7 +31,7 @@ class _LoginDialog : public _AlienDialog BrowserWindow _browserWindow; CreateUserDialog _createUserDialog; ActivateUserDialog _activateUserDialog; - NetworkController _networkController; + NetworkService _networkService; ResetPasswordDialog _resetPasswordDialog; bool _shareGpuInfo = true; diff --git a/source/Gui/MainWindow.cpp b/source/Gui/MainWindow.cpp index 958faa975..2b4de53a6 100644 --- a/source/Gui/MainWindow.cpp +++ b/source/Gui/MainWindow.cpp @@ -23,7 +23,7 @@ #include "EngineInterface/SerializerService.h" #include "EngineInterface/SimulationController.h" -#include "Network/NetworkController.h" +#include "Network/NetworkService.h" #include "ModeController.h" #include "SimulationView.h" @@ -121,7 +121,7 @@ _MainWindow::_MainWindow(SimulationController const& simController, GuiLogger co _editorController = std::make_shared<_EditorController>(_simController, _viewport); _modeController = std::make_shared<_ModeController>(_editorController); - _networkController = std::make_shared<_NetworkController>(); + _networkService = std::make_shared<_NetworkService>(); _simulationView = std::make_shared<_SimulationView>(_simController, _modeController, _viewport, _editorController->getEditorModel()); simulationViewPtr = _simulationView.get(); _statisticsWindow = std::make_shared<_StatisticsWindow>(_simController); @@ -141,16 +141,16 @@ _MainWindow::_MainWindow(SimulationController const& simController, GuiLogger co _patternAnalysisDialog = std::make_shared<_PatternAnalysisDialog>(_simController); _fpsController = std::make_shared<_FpsController>(); _browserWindow = - std::make_shared<_BrowserWindow>(_simController, _networkController, _statisticsWindow, _viewport, _temporalControlWindow, _editorController); - _activateUserDialog = std::make_shared<_ActivateUserDialog>(_simController, _browserWindow, _networkController); - _createUserDialog = std::make_shared<_CreateUserDialog>(_activateUserDialog, _networkController); - _newPasswordDialog = std::make_shared<_NewPasswordDialog>(_simController, _browserWindow, _networkController); - _resetPasswordDialog = std::make_shared<_ResetPasswordDialog>(_newPasswordDialog, _networkController); - _loginDialog = std::make_shared<_LoginDialog>(_simController, _browserWindow, _createUserDialog, _activateUserDialog, _resetPasswordDialog, _networkController); + std::make_shared<_BrowserWindow>(_simController, _networkService, _statisticsWindow, _viewport, _temporalControlWindow, _editorController); + _activateUserDialog = std::make_shared<_ActivateUserDialog>(_simController, _browserWindow, _networkService); + _createUserDialog = std::make_shared<_CreateUserDialog>(_activateUserDialog, _networkService); + _newPasswordDialog = std::make_shared<_NewPasswordDialog>(_simController, _browserWindow, _networkService); + _resetPasswordDialog = std::make_shared<_ResetPasswordDialog>(_newPasswordDialog, _networkService); + _loginDialog = std::make_shared<_LoginDialog>(_simController, _browserWindow, _createUserDialog, _activateUserDialog, _resetPasswordDialog, _networkService); _uploadSimulationDialog = std::make_shared<_UploadSimulationDialog>( - _browserWindow, _loginDialog, _simController, _networkController, _viewport, _editorController->getGenomeEditorWindow()); - _deleteUserDialog = std::make_shared<_DeleteUserDialog>(_browserWindow, _networkController); - _networkSettingsDialog = std::make_shared<_NetworkSettingsDialog>(_browserWindow, _networkController); + _browserWindow, _loginDialog, _simController, _networkService, _viewport, _editorController->getGenomeEditorWindow()); + _deleteUserDialog = std::make_shared<_DeleteUserDialog>(_browserWindow, _networkService); + _networkSettingsDialog = std::make_shared<_NetworkSettingsDialog>(_browserWindow, _networkService); _imageToPatternDialog = std::make_shared<_ImageToPatternDialog>(_viewport, _simController); _shaderWindow = std::make_shared<_ShaderWindow>(_simulationView); @@ -395,30 +395,30 @@ void _MainWindow::processMenubar() _browserWindow->setOn(!_browserWindow->isOn()); } ImGui::Separator(); - ImGui::BeginDisabled((bool)_networkController->getLoggedInUserName()); + ImGui::BeginDisabled((bool)_networkService->getLoggedInUserName()); if (ImGui::MenuItem("Login", "ALT+L")) { _loginDialog->open(); } ImGui::EndDisabled(); - ImGui::BeginDisabled(!_networkController->getLoggedInUserName()); + ImGui::BeginDisabled(!_networkService->getLoggedInUserName()); if (ImGui::MenuItem("Logout", "ALT+T")) { - _networkController->logout(); + _networkService->logout(); _browserWindow->onRefresh(); } ImGui::EndDisabled(); - ImGui::BeginDisabled(!_networkController->getLoggedInUserName()); + ImGui::BeginDisabled(!_networkService->getLoggedInUserName()); if (ImGui::MenuItem("Upload simulation", "ALT+D")) { _uploadSimulationDialog->open(DataType_Simulation); } ImGui::EndDisabled(); - ImGui::BeginDisabled(!_networkController->getLoggedInUserName()); + ImGui::BeginDisabled(!_networkService->getLoggedInUserName()); if (ImGui::MenuItem("Upload genome", "ALT+Q")) { _uploadSimulationDialog->open(DataType_Genome); } ImGui::EndDisabled(); ImGui::Separator(); - ImGui::BeginDisabled(!_networkController->getLoggedInUserName()); + ImGui::BeginDisabled(!_networkService->getLoggedInUserName()); if (ImGui::MenuItem("Delete user", "ALT+J")) { _deleteUserDialog->open(); } @@ -589,20 +589,20 @@ void _MainWindow::processMenubar() if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_W)) { _browserWindow->setOn(!_browserWindow->isOn()); } - if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_L) && !_networkController->getLoggedInUserName()) { + if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_L) && !_networkService->getLoggedInUserName()) { _loginDialog->open(); } if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_T)) { - _networkController->logout(); + _networkService->logout(); _browserWindow->onRefresh(); } - if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_D) && _networkController->getLoggedInUserName()) { + if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_D) && _networkService->getLoggedInUserName()) { _uploadSimulationDialog->open(DataType_Simulation); } - if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_Q) && _networkController->getLoggedInUserName()) { + if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_Q) && _networkService->getLoggedInUserName()) { _uploadSimulationDialog->open(DataType_Genome); } - if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_J) && _networkController->getLoggedInUserName()) { + if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_J) && _networkService->getLoggedInUserName()) { _deleteUserDialog->open(); } @@ -746,7 +746,6 @@ void _MainWindow::processControllers() { _autosaveController->process(); _editorController->process(); - _networkController->process(); OverlayMessageController::getInstance().process(); DelayedExecutionController::getInstance().process(); } diff --git a/source/Gui/MainWindow.h b/source/Gui/MainWindow.h index 1b0efea18..31b0b83c9 100644 --- a/source/Gui/MainWindow.h +++ b/source/Gui/MainWindow.h @@ -73,7 +73,7 @@ class _MainWindow UiController _uiController; EditorController _editorController; FpsController _fpsController; - NetworkController _networkController; + NetworkService _networkService; bool _onExit = false; bool _simulationMenuToggled = false; diff --git a/source/Gui/NetworkSettingsDialog.cpp b/source/Gui/NetworkSettingsDialog.cpp index 2d0eb3918..d411be08f 100644 --- a/source/Gui/NetworkSettingsDialog.cpp +++ b/source/Gui/NetworkSettingsDialog.cpp @@ -2,7 +2,7 @@ #include -#include "Network/NetworkController.h" +#include "Network/NetworkService.h" #include "AlienImGui.h" #include "BrowserWindow.h" @@ -13,10 +13,10 @@ namespace auto const RightColumnWidth = 150.0f; } -_NetworkSettingsDialog::_NetworkSettingsDialog(BrowserWindow const& browserWindow, NetworkController const& networkController) +_NetworkSettingsDialog::_NetworkSettingsDialog(BrowserWindow const& browserWindow, NetworkService const& networkController) : _AlienDialog("Network settings") , _browserWindow(browserWindow) - , _networkController(networkController) + , _networkService(networkController) { } @@ -42,12 +42,12 @@ void _NetworkSettingsDialog::processIntern() void _NetworkSettingsDialog::openIntern() { - _origServerAddress = _networkController->getServerAddress(); + _origServerAddress = _networkService->getServerAddress(); _serverAddress = _origServerAddress; } void _NetworkSettingsDialog::onChangeSettings() { - _networkController->setServerAddress(_serverAddress); + _networkService->setServerAddress(_serverAddress); _browserWindow->onRefresh(); } diff --git a/source/Gui/NetworkSettingsDialog.h b/source/Gui/NetworkSettingsDialog.h index 27dc663fd..553d6a89c 100644 --- a/source/Gui/NetworkSettingsDialog.h +++ b/source/Gui/NetworkSettingsDialog.h @@ -8,7 +8,7 @@ class _NetworkSettingsDialog : public _AlienDialog { public: - _NetworkSettingsDialog(BrowserWindow const& browserWindow, NetworkController const& networkController); + _NetworkSettingsDialog(BrowserWindow const& browserWindow, NetworkService const& networkController); private: void processIntern(); @@ -17,7 +17,7 @@ class _NetworkSettingsDialog : public _AlienDialog void onChangeSettings(); BrowserWindow _browserWindow; - NetworkController _networkController; + NetworkService _networkService; std::string _serverAddress; std::string _origServerAddress; diff --git a/source/Gui/NewPasswordDialog.cpp b/source/Gui/NewPasswordDialog.cpp index 545793661..d5173f139 100644 --- a/source/Gui/NewPasswordDialog.cpp +++ b/source/Gui/NewPasswordDialog.cpp @@ -3,7 +3,7 @@ #include #include "EngineInterface/SimulationController.h" -#include "Network/NetworkController.h" +#include "Network/NetworkService.h" #include "AlienImGui.h" #include "BrowserWindow.h" @@ -12,11 +12,11 @@ _NewPasswordDialog::_NewPasswordDialog( SimulationController const& simController, BrowserWindow const& browserWindow, - NetworkController const& networkController) + NetworkService const& networkController) : _AlienDialog("New password") , _simController(simController) , _browserWindow(browserWindow) - , _networkController(networkController) + , _networkService(networkController) {} void _NewPasswordDialog::open(std::string const& userName, UserInfo const& userInfo) @@ -60,10 +60,10 @@ void _NewPasswordDialog::processIntern() void _NewPasswordDialog::onNewPassword() { - auto result = _networkController->setNewPassword(_userName, _newPassword, _confirmationCode); + auto result = _networkService->setNewPassword(_userName, _newPassword, _confirmationCode); if (result) { LoginErrorCode errorCode; - result |= _networkController->login(errorCode, _userName, _newPassword, _userInfo); + result |= _networkService->login(errorCode, _userName, _newPassword, _userInfo); } if (!result) { MessageDialog::getInstance().information("Error", "An error occurred on the server. Your entered code may be incorrect.\nPlease try to reset the password again."); diff --git a/source/Gui/NewPasswordDialog.h b/source/Gui/NewPasswordDialog.h index 5182dd2fa..a5a96f60b 100644 --- a/source/Gui/NewPasswordDialog.h +++ b/source/Gui/NewPasswordDialog.h @@ -1,6 +1,6 @@ #pragma once -#include "Network/NetworkController.h" +#include "Network/NetworkService.h" #include "AlienDialog.h" #include "Definitions.h" @@ -8,7 +8,7 @@ class _NewPasswordDialog : public _AlienDialog { public: - _NewPasswordDialog(SimulationController const& simController, BrowserWindow const& browserWindow, NetworkController const& networkController); + _NewPasswordDialog(SimulationController const& simController, BrowserWindow const& browserWindow, NetworkService const& networkController); void open(std::string const& userName, UserInfo const& userInfo); @@ -19,7 +19,7 @@ class _NewPasswordDialog : public _AlienDialog SimulationController _simController; BrowserWindow _browserWindow; - NetworkController _networkController; + NetworkService _networkService; std::string _userName; std::string _newPassword; diff --git a/source/Gui/ResetPasswordDialog.cpp b/source/Gui/ResetPasswordDialog.cpp index 7ee94c5f1..fd22127d3 100644 --- a/source/Gui/ResetPasswordDialog.cpp +++ b/source/Gui/ResetPasswordDialog.cpp @@ -6,9 +6,9 @@ #include "MessageDialog.h" #include "NewPasswordDialog.h" -_ResetPasswordDialog::_ResetPasswordDialog(NewPasswordDialog const& newPasswordDialog, NetworkController const& networkController) +_ResetPasswordDialog::_ResetPasswordDialog(NewPasswordDialog const& newPasswordDialog, NetworkService const& networkController) : _AlienDialog("Reset password") - , _networkController(networkController) + , _networkService(networkController) , _newPasswordDialog(newPasswordDialog) {} @@ -53,7 +53,7 @@ void _ResetPasswordDialog::processIntern() void _ResetPasswordDialog::onResetPassword() { - if (_networkController->resetPassword(_userName, _email)) { + if (_networkService->resetPassword(_userName, _email)) { _newPasswordDialog->open(_userName, _userInfo); } else { MessageDialog::getInstance().information( diff --git a/source/Gui/ResetPasswordDialog.h b/source/Gui/ResetPasswordDialog.h index 6224943cf..bb454ae3b 100644 --- a/source/Gui/ResetPasswordDialog.h +++ b/source/Gui/ResetPasswordDialog.h @@ -1,6 +1,6 @@ #pragma once -#include "Network/NetworkController.h" +#include "Network/NetworkService.h" #include "AlienDialog.h" #include "Definitions.h" @@ -8,7 +8,7 @@ class _ResetPasswordDialog : public _AlienDialog { public: - _ResetPasswordDialog(NewPasswordDialog const& newPasswordDialog, NetworkController const& networkController); + _ResetPasswordDialog(NewPasswordDialog const& newPasswordDialog, NetworkService const& networkController); void open(std::string const& userName, UserInfo const& userInfo); @@ -18,7 +18,7 @@ class _ResetPasswordDialog : public _AlienDialog void onResetPassword(); NewPasswordDialog _newPasswordDialog; - NetworkController _networkController; + NetworkService _networkService; std::string _userName; std::string _email; diff --git a/source/Gui/UploadSimulationDialog.cpp b/source/Gui/UploadSimulationDialog.cpp index 96bd5d350..e26b6540a 100644 --- a/source/Gui/UploadSimulationDialog.cpp +++ b/source/Gui/UploadSimulationDialog.cpp @@ -6,7 +6,7 @@ #include "EngineInterface/SerializerService.h" #include "EngineInterface/SimulationController.h" #include "EngineInterface/GenomeDescriptionService.h" -#include "Network/NetworkController.h" +#include "Network/NetworkService.h" #include "AlienImGui.h" #include "MessageDialog.h" @@ -32,12 +32,12 @@ _UploadSimulationDialog::_UploadSimulationDialog( BrowserWindow const& browserWindow, LoginDialog const& loginDialog, SimulationController const& simController, - NetworkController const& networkController, + NetworkService const& networkController, Viewport const& viewport, GenomeEditorWindow const& genomeEditorWindow) : _AlienDialog("") , _simController(simController) - , _networkController(networkController) + , _networkService(networkController) , _browserWindow(browserWindow) , _loginDialog(loginDialog) , _viewport(viewport) @@ -57,7 +57,7 @@ _UploadSimulationDialog::~_UploadSimulationDialog() void _UploadSimulationDialog::open(DataType dataType) { - if (_networkController->getLoggedInUserName()) { + if (_networkService->getLoggedInUserName()) { changeTitle("Upload " + BrowserDataTypeToLowerString.at(dataType)); _dataType = dataType; _AlienDialog::open(); @@ -154,7 +154,7 @@ void _UploadSimulationDialog::onUpload() } } - if (!_networkController->uploadSimulation(_simName, _simDescription, size, numObjects, mainData, settings, statistics, _dataType)) { + if (!_networkService->uploadSimulation(_simName, _simDescription, size, numObjects, mainData, settings, statistics, _dataType)) { showMessage("Error", "Failed to upload " + BrowserDataTypeToLowerString.at(_dataType) + "."); return; } diff --git a/source/Gui/UploadSimulationDialog.h b/source/Gui/UploadSimulationDialog.h index b35fa450b..de91447b2 100644 --- a/source/Gui/UploadSimulationDialog.h +++ b/source/Gui/UploadSimulationDialog.h @@ -13,7 +13,7 @@ class _UploadSimulationDialog : public _AlienDialog BrowserWindow const& browserWindow, LoginDialog const& loginDialog, SimulationController const& simController, - NetworkController const& networkController, + NetworkService const& networkController, Viewport const& viewport, GenomeEditorWindow const& genomeEditorWindow); ~_UploadSimulationDialog(); @@ -38,6 +38,6 @@ class _UploadSimulationDialog : public _AlienDialog LoginDialog _loginDialog; SimulationController _simController; Viewport _viewport; - NetworkController _networkController; + NetworkService _networkService; GenomeEditorWindow _genomeEditorWindow; }; \ No newline at end of file diff --git a/source/Network/Definitions.h b/source/Network/Definitions.h index 018075bd7..f6be24b8f 100644 --- a/source/Network/Definitions.h +++ b/source/Network/Definitions.h @@ -2,8 +2,8 @@ #include "Base/Definitions.h" -class _NetworkController; -using NetworkController = std::shared_ptr<_NetworkController>; +class _NetworkService; +using NetworkService = std::shared_ptr<_NetworkService>; using DataType = int; enum DataType_ diff --git a/source/Network/NetworkController.cpp b/source/Network/NetworkService.cpp similarity index 85% rename from source/Network/NetworkController.cpp rename to source/Network/NetworkService.cpp index 8b29a1477..0f7c1e701 100644 --- a/source/Network/NetworkController.cpp +++ b/source/Network/NetworkService.cpp @@ -1,4 +1,4 @@ -#include "NetworkController.h" +#include "NetworkService.h" #include @@ -57,51 +57,39 @@ namespace } } -_NetworkController::_NetworkController() +_NetworkService::_NetworkService() { _serverAddress = GlobalSettings::getInstance().getStringState("settings.server", "alien-project.org"); } -_NetworkController::~_NetworkController() +_NetworkService::~_NetworkService() { GlobalSettings::getInstance().setStringState("settings.server", _serverAddress); logout(); } -void _NetworkController::process() -{ - auto now = std::chrono::steady_clock::now(); - if (!_lastRefreshTime) { - _lastRefreshTime = now; - } - if (std::chrono::duration_cast(now - *_lastRefreshTime).count() >= RefreshInterval) { - _lastRefreshTime = now; - refreshLogin(); - } -} - -std::string _NetworkController::getServerAddress() const +std::string _NetworkService::getServerAddress() const { return _serverAddress; } -void _NetworkController::setServerAddress(std::string const& value) +void _NetworkService::setServerAddress(std::string const& value) { _serverAddress = value; logout(); } -std::optional _NetworkController::getLoggedInUserName() const +std::optional _NetworkService::getLoggedInUserName() const { return _loggedInUserName; } -std::optional _NetworkController::getPassword() const +std::optional _NetworkService::getPassword() const { return _password; } -bool _NetworkController::createUser(std::string const& userName, std::string const& password, std::string const& email) +bool _NetworkService::createUser(std::string const& userName, std::string const& password, std::string const& email) { log(Priority::Important, "network: create user '" + userName + "'"); @@ -122,7 +110,7 @@ bool _NetworkController::createUser(std::string const& userName, std::string con } } -bool _NetworkController::activateUser(std::string const& userName, std::string const& password, UserInfo const& userInfo, std::string const& confirmationCode) +bool _NetworkService::activateUser(std::string const& userName, std::string const& password, UserInfo const& userInfo, std::string const& confirmationCode) { log(Priority::Important, "network: activate user '" + userName + "'"); @@ -146,7 +134,7 @@ bool _NetworkController::activateUser(std::string const& userName, std::string c } } -bool _NetworkController::login(LoginErrorCode& errorCode, std::string const& userName, std::string const& password, UserInfo const& userInfo) +bool _NetworkService::login(LoginErrorCode& errorCode, std::string const& userName, std::string const& password, UserInfo const& userInfo) { log(Priority::Important, "network: login user '" + userName + "'"); @@ -182,7 +170,7 @@ bool _NetworkController::login(LoginErrorCode& errorCode, std::string const& use } } -bool _NetworkController::logout() +bool _NetworkService::logout() { log(Priority::Important, "network: logout"); bool result = true; @@ -208,7 +196,26 @@ bool _NetworkController::logout() return result; } -bool _NetworkController::deleteUser() +void _NetworkService::refreshLogin() +{ + if (_loggedInUserName && _password) { + log(Priority::Important, "network: refresh login"); + + httplib::SSLClient client(_serverAddress); + configureClient(client); + + httplib::Params params; + params.emplace("userName", *_loggedInUserName); + params.emplace("password", *_password); + + try { + executeRequest([&] { return client.Post("/alien-server/refreshlogin.php", params); }); + } catch (...) { + } + } +} + +bool _NetworkService::deleteUser() { log(Priority::Important, "network: delete user '" + *_loggedInUserName + "'"); @@ -233,7 +240,7 @@ bool _NetworkController::deleteUser() } } -bool _NetworkController::resetPassword(std::string const& userName, std::string const& email) +bool _NetworkService::resetPassword(std::string const& userName, std::string const& email) { log(Priority::Important, "network: reset password of user '" + userName + "'"); @@ -253,7 +260,7 @@ bool _NetworkController::resetPassword(std::string const& userName, std::string } } -bool _NetworkController::setNewPassword(std::string const& userName, std::string const& newPassword, std::string const& confirmationCode) +bool _NetworkService::setNewPassword(std::string const& userName, std::string const& newPassword, std::string const& confirmationCode) { log(Priority::Important, "network: set new password for user '" + userName + "'"); @@ -274,7 +281,7 @@ bool _NetworkController::setNewPassword(std::string const& userName, std::string } } -bool _NetworkController::getRemoteSimulationList(std::vector& result, bool withRetry) const +bool _NetworkService::getRemoteSimulationList(std::vector& result, bool withRetry) const { log(Priority::Important, "network: get simulation list"); @@ -298,7 +305,7 @@ bool _NetworkController::getRemoteSimulationList(std::vector& res } } -bool _NetworkController::getUserList(std::vector& result, bool withRetry) const +bool _NetworkService::getUserList(std::vector& result, bool withRetry) const { log(Priority::Important, "network: get user list"); @@ -324,7 +331,7 @@ bool _NetworkController::getUserList(std::vector& result, bool withRetry } } -bool _NetworkController::getEmojiTypeBySimId(std::unordered_map& result) const +bool _NetworkService::getEmojiTypeBySimId(std::unordered_map& result) const { log(Priority::Important, "network: get liked simulations"); @@ -353,7 +360,7 @@ bool _NetworkController::getEmojiTypeBySimId(std::unordered_map& result, std::string const& simId, int likeType) +bool _NetworkService::getUserNamesForSimulationAndEmojiType(std::set& result, std::string const& simId, int likeType) { log(Priority::Important, "network: get user likes for simulation with id=" + simId + " and likeType=" + std::to_string(likeType)); @@ -382,7 +389,7 @@ bool _NetworkController::getUserNamesForSimulationAndEmojiType(std::set gpu; }; -class _NetworkController +class _NetworkService { public: - _NetworkController(); - ~_NetworkController(); - - void process(); + _NetworkService(); + ~_NetworkService(); std::string getServerAddress() const; void setServerAddress(std::string const& value); @@ -36,6 +34,7 @@ class _NetworkController bool login(LoginErrorCode& errorCode, std::string const& userName, std::string const& password, UserInfo const& userInfo); bool logout(); + void refreshLogin(); bool deleteUser(); bool resetPassword(std::string const& userName, std::string const& email); bool setNewPassword(std::string const& userName, std::string const& newPassword, std::string const& confirmationCode); @@ -59,8 +58,6 @@ class _NetworkController bool deleteSimulation(std::string const& simId); private: - void refreshLogin(); - std::string _serverAddress; std::optional _loggedInUserName; std::optional _password; From aa2bfb0ed6e2d5e0b970ca78da24a06b3421ff7e Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Thu, 21 Dec 2023 20:51:26 +0100 Subject: [PATCH 10/40] make NetworkService a singleton class --- source/Base/LoggingService.h | 2 + source/Gui/ActivateUserDialog.cpp | 9 ++-- source/Gui/ActivateUserDialog.h | 3 +- source/Gui/BrowserWindow.cpp | 66 +++++++++++++++---------- source/Gui/BrowserWindow.h | 2 - source/Gui/CreateUserDialog.cpp | 7 +-- source/Gui/CreateUserDialog.h | 3 +- source/Gui/DeleteUserDialog.cpp | 14 +++--- source/Gui/DeleteUserDialog.h | 3 +- source/Gui/LogWindow.cpp | 2 +- source/Gui/LoginDialog.cpp | 10 ++-- source/Gui/LoginDialog.h | 4 +- source/Gui/MainWindow.cpp | 42 ++++++++-------- source/Gui/MainWindow.h | 1 - source/Gui/NetworkSettingsDialog.cpp | 9 ++-- source/Gui/NetworkSettingsDialog.h | 3 +- source/Gui/NewPasswordDialog.cpp | 9 ++-- source/Gui/NewPasswordDialog.h | 3 +- source/Gui/OverlayMessageController.cpp | 2 +- source/Gui/ResetPasswordDialog.cpp | 7 +-- source/Gui/ResetPasswordDialog.h | 3 +- source/Gui/SimulationView.cpp | 2 +- source/Gui/StartupController.cpp | 2 +- source/Gui/StyleRepository.h | 1 + source/Gui/UploadSimulationDialog.cpp | 8 +-- source/Gui/UploadSimulationDialog.h | 2 - source/Network/Definitions.h | 3 +- source/Network/NetworkService.cpp | 66 ++++++++++++++----------- source/Network/NetworkService.h | 10 ++-- 29 files changed, 158 insertions(+), 140 deletions(-) diff --git a/source/Base/LoggingService.h b/source/Base/LoggingService.h index 8bc513d46..5b3badeda 100644 --- a/source/Base/LoggingService.h +++ b/source/Base/LoggingService.h @@ -27,6 +27,8 @@ class LoggingService void unregisterCallBack(LoggingCallBack* callback); private: + LoggingService() = default; + std::vector _callbacks; std::mutex _mutex; }; diff --git a/source/Gui/ActivateUserDialog.cpp b/source/Gui/ActivateUserDialog.cpp index 8a43d2dd9..e9966984e 100644 --- a/source/Gui/ActivateUserDialog.cpp +++ b/source/Gui/ActivateUserDialog.cpp @@ -13,12 +13,10 @@ _ActivateUserDialog::_ActivateUserDialog( SimulationController const& simController, - BrowserWindow const& browserWindow, - NetworkService const& networkController) + BrowserWindow const& browserWindow) : _AlienDialog("Activate user") , _simController(simController) , _browserWindow(browserWindow) - , _networkService(networkController) {} _ActivateUserDialog::~_ActivateUserDialog() {} @@ -81,10 +79,11 @@ void _ActivateUserDialog::processIntern() void _ActivateUserDialog::onActivateUser() { - auto result = _networkService->activateUser(_userName, _password, _userInfo, _confirmationCode); + auto& networkService = NetworkService::getInstance(); + auto result = networkService.activateUser(_userName, _password, _userInfo, _confirmationCode); if (result) { LoginErrorCode errorCode; - result |= _networkService->login(errorCode, _userName, _password, _userInfo); + result |= networkService.login(errorCode, _userName, _password, _userInfo); } if (!result) { MessageDialog::getInstance().information("Error", "An error occurred on the server. Your entered code may be incorrect.\nPlease try to register again."); diff --git a/source/Gui/ActivateUserDialog.h b/source/Gui/ActivateUserDialog.h index 88b97ca76..305f091d4 100644 --- a/source/Gui/ActivateUserDialog.h +++ b/source/Gui/ActivateUserDialog.h @@ -8,7 +8,7 @@ class _ActivateUserDialog : public _AlienDialog { public: - _ActivateUserDialog(SimulationController const& simController, BrowserWindow const& browserWindow, NetworkService const& networkController); + _ActivateUserDialog(SimulationController const& simController, BrowserWindow const& browserWindow); ~_ActivateUserDialog(); void registerCyclicReferences(CreateUserDialogWeakPtr const& createUserDialog); @@ -21,7 +21,6 @@ class _ActivateUserDialog : public _AlienDialog SimulationController _simController; BrowserWindow _browserWindow; - NetworkService _networkService; CreateUserDialogWeakPtr _createUserDialog; std::string _userName; diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 8837db2dc..91da8e033 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -54,14 +54,12 @@ namespace _BrowserWindow::_BrowserWindow( SimulationController const& simController, - NetworkService const& networkController, StatisticsWindow const& statisticsWindow, Viewport const& viewport, TemporalControlWindow const& temporalControlWindow, EditorController const& editorController) : _AlienWindow("Browser", "windows.browser", true) , _simController(simController) - , _networkService(networkController) , _statisticsWindow(statisticsWindow) , _viewport(viewport) , _temporalControlWindow(temporalControlWindow) @@ -84,6 +82,7 @@ _BrowserWindow::~_BrowserWindow() GlobalSettings::getInstance().setBoolState("windows.browser.show community creations", _showCommunityCreations); GlobalSettings::getInstance().setBoolState("windows.browser.first start", false); GlobalSettings::getInstance().setFloatState("windows.browser.user table width", _userTableWidth); + NetworkService::getInstance().shutdown(); } void _BrowserWindow::registerCyclicReferences(LoginDialogWeakPtr const& loginDialog, UploadSimulationDialogWeakPtr const& uploadSimulationDialog) @@ -103,10 +102,11 @@ void _BrowserWindow::onRefresh() void _BrowserWindow::refreshIntern(bool withRetry) { try { - _networkService->refreshLogin(); + auto& networkService = NetworkService::getInstance(); + networkService.refreshLogin(); - bool success = _networkService->getRemoteSimulationList(_rawNetworkDataTOs, withRetry); - success &= _networkService->getUserList(_userTOs, withRetry); + bool success = networkService.getRemoteSimulationList(_rawNetworkDataTOs, withRetry); + success &= networkService.getUserList(_userTOs, withRetry); if (!success) { if (withRetry) { @@ -126,8 +126,8 @@ void _BrowserWindow::refreshIntern(bool withRetry) calcFilteredSimulationAndGenomeLists(); _scheduleCreateBrowserData = true; - if (_networkService->getLoggedInUserName()) { - if (!_networkService->getEmojiTypeBySimId(_ownEmojiTypeBySimId)) { + if (networkService.getLoggedInUserName()) { + if (!networkService.getEmojiTypeBySimId(_ownEmojiTypeBySimId)) { MessageDialog::getInstance().information("Error", "Failed to retrieve browser data. Please try again."); } } else { @@ -211,13 +211,15 @@ void _BrowserWindow::processBackground() void _BrowserWindow::processToolbar() { + auto& networkService = NetworkService::getInstance(); + if (AlienImGui::ToolbarButton(ICON_FA_SYNC)) { onRefresh(); } AlienImGui::Tooltip("Refresh"); ImGui::SameLine(); - ImGui::BeginDisabled(_networkService->getLoggedInUserName().has_value()); + ImGui::BeginDisabled(networkService.getLoggedInUserName().has_value()); if (AlienImGui::ToolbarButton(ICON_FA_SIGN_IN_ALT)) { if (auto loginDialog = _loginDialog.lock()) { loginDialog->open(); @@ -227,10 +229,10 @@ void _BrowserWindow::processToolbar() AlienImGui::Tooltip("Login or register"); ImGui::SameLine(); - ImGui::BeginDisabled(!_networkService->getLoggedInUserName()); + ImGui::BeginDisabled(!networkService.getLoggedInUserName()); if (AlienImGui::ToolbarButton(ICON_FA_SIGN_OUT_ALT)) { if (auto loginDialog = _loginDialog.lock()) { - _networkService->logout(); + networkService.logout(); onRefresh(); } } @@ -265,7 +267,7 @@ void _BrowserWindow::processSimulationList() { ImGui::PushID("SimulationList"); _selectedDataType = DataType_Simulation; - auto styleRepository = StyleRepository::getInstance(); + auto& styleRepository = StyleRepository::getInstance(); static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Sortable | ImGuiTableFlags_SortMulti | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX; @@ -377,7 +379,7 @@ void _BrowserWindow::processGenomeList() { ImGui::PushID("GenomeList"); _selectedDataType = DataType_Genome; - auto styleRepository = StyleRepository::getInstance(); + auto& styleRepository = StyleRepository::getInstance(); static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Sortable | ImGuiTableFlags_SortMulti | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX; @@ -486,8 +488,10 @@ namespace void _BrowserWindow::processUserList() { + auto& networkService = NetworkService::getInstance(); + ImGui::PushID("UserTable"); - auto styleRepository = StyleRepository::getInstance(); + auto& styleRepository = StyleRepository::getInstance(); static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX; @@ -495,7 +499,7 @@ void _BrowserWindow::processUserList() AlienImGui::Group("Simulators"); if (ImGui::BeginTable("Browser", 5, flags, ImVec2(0, 0), 0.0f)) { ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, scale(90.0f)); - auto isLoggedIn = _networkService->getLoggedInUserName().has_value(); + auto isLoggedIn = networkService.getLoggedInUserName().has_value(); ImGui::TableSetupColumn( isLoggedIn ? "GPU model" : "GPU (visible if logged in)", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, @@ -517,7 +521,7 @@ void _BrowserWindow::processUserList() ImGui::TableNextRow(0, scale(RowHeight)); ImGui::TableNextColumn(); - auto isBoldFont = isLoggedIn && *_networkService->getLoggedInUserName() == item->userName; + auto isBoldFont = isLoggedIn && *networkService.getLoggedInUserName() == item->userName; if (item->online) { AlienImGui::OnlineSymbol(); @@ -554,7 +558,8 @@ void _BrowserWindow::processUserList() void _BrowserWindow::processStatus() { - auto styleRepository = StyleRepository::getInstance(); + auto& styleRepository = StyleRepository::getInstance(); + auto& networkService = NetworkService::getInstance(); if (ImGui::BeginChild("##", ImVec2(0, styleRepository.scale(33.0f)), true)) { ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::MonospaceColor); @@ -569,13 +574,13 @@ void _BrowserWindow::processStatus() statusText += std::to_string(_userTOs.size()) + " simulators found"; statusText += std::string(" " ICON_FA_INFO_CIRCLE " "); - if (auto userName = _networkService->getLoggedInUserName()) { - statusText += "Logged in as " + *userName + " @ " + _networkService->getServerAddress();// + ": "; + if (auto userName = networkService.getLoggedInUserName()) { + statusText += "Logged in as " + *userName + " @ " + networkService.getServerAddress();// + ": "; } else { - statusText += "Not logged in to " + _networkService->getServerAddress();// + ": "; + statusText += "Not logged in to " + networkService.getServerAddress();// + ": "; } - if (!_networkService->getLoggedInUserName()) { + if (!networkService.getLoggedInUserName()) { statusText += std::string(" " ICON_FA_INFO_CIRCLE " "); statusText += "In order to share and upvote simulations you need to log in."; } @@ -742,7 +747,9 @@ void _BrowserWindow::processEmojiList(BrowserDataTO const& to) void _BrowserWindow::processActionButtons(BrowserDataTO const& to) { + auto& networkService = NetworkService::getInstance(); //like button + if (to->isLeaf()) { auto const& leaf = to->getLeaf(); auto liked = isLiked(leaf.id); @@ -771,7 +778,7 @@ void _BrowserWindow::processActionButtons(BrowserDataTO const& to) ImGui::SameLine(); //delete button - if (leaf.userName == _networkService->getLoggedInUserName().value_or("")) { + if (leaf.userName == networkService.getLoggedInUserName().value_or("")) { ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DeleteButtonTextColor); auto deleteButtonResult = processActionButton(ICON_FA_TRASH); ImGui::PopStyleColor(); @@ -798,7 +805,7 @@ void _BrowserWindow::processShortenedText(std::string const& text, bool bold) { if (substrings.empty()) { return; } - auto styleRepository = StyleRepository::getInstance(); + auto& styleRepository = StyleRepository::getInstance(); auto textSize = ImGui::CalcTextSize(substrings.at(0).c_str()); auto needDetailButton = textSize.x > ImGui::GetContentRegionAvailWidth() || substrings.size() > 1; auto cursorPos = ImGui::GetCursorPosX() + ImGui::GetContentRegionAvailWidth() - styleRepository.scale(15.0f); @@ -864,9 +871,10 @@ void _BrowserWindow::onDownloadItem(BrowserLeaf const& leaf) printOverlayMessage("Downloading ..."); delayedExecution([=, this] { + auto& networkService = NetworkService::getInstance(); std::string dataTypeString = _selectedDataType == DataType_Simulation ? "simulation" : "genome"; SerializedSimulation serializedSim; - if (!_networkService->downloadSimulation(serializedSim.mainData, serializedSim.auxiliaryData, serializedSim.statistics, leaf.id)) { + if (!networkService.downloadSimulation(serializedSim.mainData, serializedSim.auxiliaryData, serializedSim.statistics, leaf.id)) { MessageDialog::getInstance().information("Error", "Failed to download " + dataTypeString + "."); return; } @@ -928,7 +936,8 @@ void _BrowserWindow::onDeleteItem(BrowserLeaf const& leaf) printOverlayMessage("Deleting ..."); delayedExecution([leafCopy = leaf, this] { - if (!_networkService->deleteSimulation(leafCopy.id)) { + auto& networkService = NetworkService::getInstance(); + if (!networkService.deleteSimulation(leafCopy.id)) { MessageDialog::getInstance().information("Error", "Failed to delete item. Please try again later."); return; } @@ -941,7 +950,8 @@ void _BrowserWindow::onToggleLike(BrowserDataTO const& to, int emojiType) { CHECK(to->isLeaf()); auto& leaf = to->getLeaf(); - if (_networkService->getLoggedInUserName()) { + auto& networkService = NetworkService::getInstance(); + if (networkService.getLoggedInUserName()) { //remove existing like auto findResult = _ownEmojiTypeBySimId.find(leaf.id); @@ -967,7 +977,7 @@ void _BrowserWindow::onToggleLike(BrowserDataTO const& to, int emojiType) } _userNamesByEmojiTypeBySimIdCache.erase(std::make_pair(leaf.id, emojiType)); //invalidate cache entry - _networkService->toggleLikeSimulation(leaf.id, emojiType); + networkService.toggleLikeSimulation(leaf.id, emojiType); //_scheduleCreateBrowserData = true; } else { _loginDialog.lock()->open(); @@ -988,13 +998,15 @@ bool _BrowserWindow::isLiked(std::string const& simId) std::string _BrowserWindow::getUserNamesToEmojiType(std::string const& simId, int emojiType) { + auto& networkService = NetworkService::getInstance(); + std::set userNames; auto findResult = _userNamesByEmojiTypeBySimIdCache.find(std::make_pair(simId, emojiType)); if (findResult != _userNamesByEmojiTypeBySimIdCache.end()) { userNames = findResult->second; } else { - _networkService->getUserNamesForSimulationAndEmojiType(userNames, simId, emojiType); + networkService.getUserNamesForSimulationAndEmojiType(userNames, simId, emojiType); _userNamesByEmojiTypeBySimIdCache.emplace(std::make_pair(simId, emojiType), userNames); } diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index a3bcb30f2..0412479af 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -16,7 +16,6 @@ class _BrowserWindow : public _AlienWindow public: _BrowserWindow( SimulationController const& simController, - NetworkService const& networkController, StatisticsWindow const& statisticsWindow, Viewport const& viewport, TemporalControlWindow const& temporalControlWindow, @@ -97,7 +96,6 @@ class _BrowserWindow : public _AlienWindow std::optional _lastRefreshTime; SimulationController _simController; - NetworkService _networkService; StatisticsWindow _statisticsWindow; Viewport _viewport; TemporalControlWindow _temporalControlWindow; diff --git a/source/Gui/CreateUserDialog.cpp b/source/Gui/CreateUserDialog.cpp index abb77a8e1..ecaf02416 100644 --- a/source/Gui/CreateUserDialog.cpp +++ b/source/Gui/CreateUserDialog.cpp @@ -9,9 +9,8 @@ #include "MessageDialog.h" #include "ActivateUserDialog.h" -_CreateUserDialog::_CreateUserDialog(ActivateUserDialog const& activateUserDialog, NetworkService const& networkController) +_CreateUserDialog::_CreateUserDialog(ActivateUserDialog const& activateUserDialog) : _AlienDialog("Create user") - , _networkService(networkController) , _activateUserDialog(activateUserDialog) { } @@ -62,7 +61,9 @@ void _CreateUserDialog::processIntern() void _CreateUserDialog::onCreateUser() { - if (_networkService->createUser(_userName, _password, _email)) { + auto& networkService = NetworkService::getInstance(); + + if (networkService.createUser(_userName, _password, _email)) { _activateUserDialog->open(_userName, _password, _userInfo); } else { MessageDialog::getInstance().information( diff --git a/source/Gui/CreateUserDialog.h b/source/Gui/CreateUserDialog.h index c2417706f..5ed7a18fb 100644 --- a/source/Gui/CreateUserDialog.h +++ b/source/Gui/CreateUserDialog.h @@ -8,7 +8,7 @@ class _CreateUserDialog : public _AlienDialog { public: - _CreateUserDialog(ActivateUserDialog const& activateUserDialog, NetworkService const& networkController); + _CreateUserDialog(ActivateUserDialog const& activateUserDialog); ~_CreateUserDialog(); void open(std::string const& userName, std::string const& password, UserInfo const& userInfo); @@ -17,7 +17,6 @@ class _CreateUserDialog : public _AlienDialog private: void processIntern(); - NetworkService _networkService; ActivateUserDialog _activateUserDialog; std::string _userName; diff --git a/source/Gui/DeleteUserDialog.cpp b/source/Gui/DeleteUserDialog.cpp index b8354838e..b733136e3 100644 --- a/source/Gui/DeleteUserDialog.cpp +++ b/source/Gui/DeleteUserDialog.cpp @@ -9,17 +9,18 @@ #include "CreateUserDialog.h" #include "MessageDialog.h" -_DeleteUserDialog::_DeleteUserDialog(BrowserWindow const& browserWindow, NetworkService const& networkController) +_DeleteUserDialog::_DeleteUserDialog(BrowserWindow const& browserWindow) : _AlienDialog("Delete user") , _browserWindow(browserWindow) - , _networkService(networkController) { } void _DeleteUserDialog::processIntern() { + auto& networkService = NetworkService::getInstance(); + AlienImGui::Text( - "Warning: All the data of the user '" + *_networkService->getLoggedInUserName() + "Warning: All the data of the user '" + *networkService.getLoggedInUserName() + "' will be deleted on the server side.\nThese include the likes, the simulations and the account data."); AlienImGui::Separator(); @@ -29,7 +30,7 @@ void _DeleteUserDialog::processIntern() ImGui::BeginDisabled(_reenteredPassword.empty()); if (AlienImGui::Button("Delete")) { close(); - if (_reenteredPassword == *_networkService->getPassword()) { + if (_reenteredPassword == *networkService.getPassword()) { onDelete(); } else { MessageDialog::getInstance().information("Error", "The password does not match."); @@ -48,8 +49,9 @@ void _DeleteUserDialog::processIntern() void _DeleteUserDialog::onDelete() { - auto userName = *_networkService->getLoggedInUserName(); - if (_networkService->deleteUser()) { + auto& networkService = NetworkService::getInstance(); + auto userName = *networkService.getLoggedInUserName(); + if (networkService.deleteUser()) { _browserWindow->onRefresh(); MessageDialog::getInstance().information("Information", "The user '" + userName + "' has been deleted.\nYou are logged out."); } else { diff --git a/source/Gui/DeleteUserDialog.h b/source/Gui/DeleteUserDialog.h index eb90b3020..de93b8b6f 100644 --- a/source/Gui/DeleteUserDialog.h +++ b/source/Gui/DeleteUserDialog.h @@ -8,14 +8,13 @@ class _DeleteUserDialog : public _AlienDialog { public: - _DeleteUserDialog(BrowserWindow const& browserWindow, NetworkService const& networkController); + _DeleteUserDialog(BrowserWindow const& browserWindow); private: void processIntern(); void onDelete(); BrowserWindow _browserWindow; - NetworkService _networkService; std::string _reenteredPassword; }; diff --git a/source/Gui/LogWindow.cpp b/source/Gui/LogWindow.cpp index f6ef87248..cef034a53 100644 --- a/source/Gui/LogWindow.cpp +++ b/source/Gui/LogWindow.cpp @@ -24,7 +24,7 @@ _LogWindow::~_LogWindow() void _LogWindow::processIntern() { - auto styleRepository = StyleRepository::getInstance(); + auto& styleRepository = StyleRepository::getInstance(); if (ImGui::BeginChild( "##", ImVec2(0, ImGui::GetContentRegionAvail().y - styleRepository.scale(40.0f)), true, ImGuiWindowFlags_HorizontalScrollbar)) { ImGui::PushFont(StyleRepository::getInstance().getMonospaceMediumFont()); diff --git a/source/Gui/LoginDialog.cpp b/source/Gui/LoginDialog.cpp index 0b1302d46..cd9505c5e 100644 --- a/source/Gui/LoginDialog.cpp +++ b/source/Gui/LoginDialog.cpp @@ -20,17 +20,16 @@ _LoginDialog::_LoginDialog( BrowserWindow const& browserWindow, CreateUserDialog const& createUserDialog, ActivateUserDialog const& activateUserDialog, - ResetPasswordDialog const& resetPasswordDialog, - NetworkService const& networkController) + ResetPasswordDialog const& resetPasswordDialog) : _AlienDialog("Login") , _simController(simController) , _browserWindow(browserWindow) , _createUserDialog(createUserDialog) , _activateUserDialog(activateUserDialog) - , _networkService(networkController) , _resetPasswordDialog(resetPasswordDialog) { + auto& networkService = NetworkService::getInstance(); auto& settings = GlobalSettings::getInstance(); _remember = settings.getBoolState("dialogs.login.remember", _remember); _shareGpuInfo = settings.getBoolState("dialogs.login.share gpu info", _shareGpuInfo); @@ -40,7 +39,7 @@ _LoginDialog::_LoginDialog( _password = settings.getStringState("dialogs.login.password", ""); if (!_userName.empty()) { LoginErrorCode errorCode; - if (!_networkService->login(errorCode, _userName, _password, getUserInfo())) { + if (!networkService.login(errorCode, _userName, _password, getUserInfo())) { if (errorCode != LoginErrorCode_UnconfirmedUser) { MessageDialog::getInstance().information("Error", "Login failed."); } @@ -131,8 +130,9 @@ void _LoginDialog::onLogin() LoginErrorCode errorCode; auto userInfo = getUserInfo(); + auto& networkService = NetworkService::getInstance(); - if (!_networkService->login(errorCode, _userName, _password, userInfo)) { + if (!networkService.login(errorCode, _userName, _password, userInfo)) { switch (errorCode) { case LoginErrorCode_UnconfirmedUser: { _activateUserDialog->open(_userName, _password, userInfo); diff --git a/source/Gui/LoginDialog.h b/source/Gui/LoginDialog.h index 1dd8719cf..8b687e0b4 100644 --- a/source/Gui/LoginDialog.h +++ b/source/Gui/LoginDialog.h @@ -13,8 +13,7 @@ class _LoginDialog : public _AlienDialog BrowserWindow const& browserWindow, CreateUserDialog const& createUserDialog, ActivateUserDialog const& activateUserDialog, - ResetPasswordDialog const& resetPasswordDialog, - NetworkService const& networkController); + ResetPasswordDialog const& resetPasswordDialog); ~_LoginDialog(); bool isShareGpuInfo() const; @@ -31,7 +30,6 @@ class _LoginDialog : public _AlienDialog BrowserWindow _browserWindow; CreateUserDialog _createUserDialog; ActivateUserDialog _activateUserDialog; - NetworkService _networkService; ResetPasswordDialog _resetPasswordDialog; bool _shareGpuInfo = true; diff --git a/source/Gui/MainWindow.cpp b/source/Gui/MainWindow.cpp index 2b4de53a6..2f761a3bc 100644 --- a/source/Gui/MainWindow.cpp +++ b/source/Gui/MainWindow.cpp @@ -121,7 +121,6 @@ _MainWindow::_MainWindow(SimulationController const& simController, GuiLogger co _editorController = std::make_shared<_EditorController>(_simController, _viewport); _modeController = std::make_shared<_ModeController>(_editorController); - _networkService = std::make_shared<_NetworkService>(); _simulationView = std::make_shared<_SimulationView>(_simController, _modeController, _viewport, _editorController->getEditorModel()); simulationViewPtr = _simulationView.get(); _statisticsWindow = std::make_shared<_StatisticsWindow>(_simController); @@ -141,16 +140,16 @@ _MainWindow::_MainWindow(SimulationController const& simController, GuiLogger co _patternAnalysisDialog = std::make_shared<_PatternAnalysisDialog>(_simController); _fpsController = std::make_shared<_FpsController>(); _browserWindow = - std::make_shared<_BrowserWindow>(_simController, _networkService, _statisticsWindow, _viewport, _temporalControlWindow, _editorController); - _activateUserDialog = std::make_shared<_ActivateUserDialog>(_simController, _browserWindow, _networkService); - _createUserDialog = std::make_shared<_CreateUserDialog>(_activateUserDialog, _networkService); - _newPasswordDialog = std::make_shared<_NewPasswordDialog>(_simController, _browserWindow, _networkService); - _resetPasswordDialog = std::make_shared<_ResetPasswordDialog>(_newPasswordDialog, _networkService); - _loginDialog = std::make_shared<_LoginDialog>(_simController, _browserWindow, _createUserDialog, _activateUserDialog, _resetPasswordDialog, _networkService); + std::make_shared<_BrowserWindow>(_simController, _statisticsWindow, _viewport, _temporalControlWindow, _editorController); + _activateUserDialog = std::make_shared<_ActivateUserDialog>(_simController, _browserWindow); + _createUserDialog = std::make_shared<_CreateUserDialog>(_activateUserDialog); + _newPasswordDialog = std::make_shared<_NewPasswordDialog>(_simController, _browserWindow); + _resetPasswordDialog = std::make_shared<_ResetPasswordDialog>(_newPasswordDialog); + _loginDialog = std::make_shared<_LoginDialog>(_simController, _browserWindow, _createUserDialog, _activateUserDialog, _resetPasswordDialog); _uploadSimulationDialog = std::make_shared<_UploadSimulationDialog>( - _browserWindow, _loginDialog, _simController, _networkService, _viewport, _editorController->getGenomeEditorWindow()); - _deleteUserDialog = std::make_shared<_DeleteUserDialog>(_browserWindow, _networkService); - _networkSettingsDialog = std::make_shared<_NetworkSettingsDialog>(_browserWindow, _networkService); + _browserWindow, _loginDialog, _simController, _viewport, _editorController->getGenomeEditorWindow()); + _deleteUserDialog = std::make_shared<_DeleteUserDialog>(_browserWindow); + _networkSettingsDialog = std::make_shared<_NetworkSettingsDialog>(_browserWindow); _imageToPatternDialog = std::make_shared<_ImageToPatternDialog>(_viewport, _simController); _shaderWindow = std::make_shared<_ShaderWindow>(_simulationView); @@ -357,6 +356,7 @@ void _MainWindow::processMenubar() auto creatorWindow = _editorController->getCreatorWindow(); auto multiplierWindow = _editorController->getMultiplierWindow(); auto genomeEditorWindow = _editorController->getGenomeEditorWindow(); + auto& networkService = NetworkService::getInstance(); if (ImGui::BeginMainMenuBar()) { if (AlienImGui::ShutdownButton()) { @@ -395,30 +395,30 @@ void _MainWindow::processMenubar() _browserWindow->setOn(!_browserWindow->isOn()); } ImGui::Separator(); - ImGui::BeginDisabled((bool)_networkService->getLoggedInUserName()); + ImGui::BeginDisabled((bool)networkService.getLoggedInUserName()); if (ImGui::MenuItem("Login", "ALT+L")) { _loginDialog->open(); } ImGui::EndDisabled(); - ImGui::BeginDisabled(!_networkService->getLoggedInUserName()); + ImGui::BeginDisabled(!networkService.getLoggedInUserName()); if (ImGui::MenuItem("Logout", "ALT+T")) { - _networkService->logout(); + networkService.logout(); _browserWindow->onRefresh(); } ImGui::EndDisabled(); - ImGui::BeginDisabled(!_networkService->getLoggedInUserName()); + ImGui::BeginDisabled(!networkService.getLoggedInUserName()); if (ImGui::MenuItem("Upload simulation", "ALT+D")) { _uploadSimulationDialog->open(DataType_Simulation); } ImGui::EndDisabled(); - ImGui::BeginDisabled(!_networkService->getLoggedInUserName()); + ImGui::BeginDisabled(!networkService.getLoggedInUserName()); if (ImGui::MenuItem("Upload genome", "ALT+Q")) { _uploadSimulationDialog->open(DataType_Genome); } ImGui::EndDisabled(); ImGui::Separator(); - ImGui::BeginDisabled(!_networkService->getLoggedInUserName()); + ImGui::BeginDisabled(!networkService.getLoggedInUserName()); if (ImGui::MenuItem("Delete user", "ALT+J")) { _deleteUserDialog->open(); } @@ -589,20 +589,20 @@ void _MainWindow::processMenubar() if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_W)) { _browserWindow->setOn(!_browserWindow->isOn()); } - if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_L) && !_networkService->getLoggedInUserName()) { + if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_L) && !networkService.getLoggedInUserName()) { _loginDialog->open(); } if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_T)) { - _networkService->logout(); + networkService.logout(); _browserWindow->onRefresh(); } - if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_D) && _networkService->getLoggedInUserName()) { + if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_D) && networkService.getLoggedInUserName()) { _uploadSimulationDialog->open(DataType_Simulation); } - if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_Q) && _networkService->getLoggedInUserName()) { + if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_Q) && networkService.getLoggedInUserName()) { _uploadSimulationDialog->open(DataType_Genome); } - if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_J) && _networkService->getLoggedInUserName()) { + if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_J) && networkService.getLoggedInUserName()) { _deleteUserDialog->open(); } diff --git a/source/Gui/MainWindow.h b/source/Gui/MainWindow.h index 31b0b83c9..a443fb72d 100644 --- a/source/Gui/MainWindow.h +++ b/source/Gui/MainWindow.h @@ -73,7 +73,6 @@ class _MainWindow UiController _uiController; EditorController _editorController; FpsController _fpsController; - NetworkService _networkService; bool _onExit = false; bool _simulationMenuToggled = false; diff --git a/source/Gui/NetworkSettingsDialog.cpp b/source/Gui/NetworkSettingsDialog.cpp index d411be08f..4be87dde7 100644 --- a/source/Gui/NetworkSettingsDialog.cpp +++ b/source/Gui/NetworkSettingsDialog.cpp @@ -13,10 +13,9 @@ namespace auto const RightColumnWidth = 150.0f; } -_NetworkSettingsDialog::_NetworkSettingsDialog(BrowserWindow const& browserWindow, NetworkService const& networkController) +_NetworkSettingsDialog::_NetworkSettingsDialog(BrowserWindow const& browserWindow) : _AlienDialog("Network settings") , _browserWindow(browserWindow) - , _networkService(networkController) { } @@ -42,12 +41,14 @@ void _NetworkSettingsDialog::processIntern() void _NetworkSettingsDialog::openIntern() { - _origServerAddress = _networkService->getServerAddress(); + auto& networkService = NetworkService::getInstance(); + _origServerAddress = networkService.getServerAddress(); _serverAddress = _origServerAddress; } void _NetworkSettingsDialog::onChangeSettings() { - _networkService->setServerAddress(_serverAddress); + auto& networkService = NetworkService::getInstance(); + networkService.setServerAddress(_serverAddress); _browserWindow->onRefresh(); } diff --git a/source/Gui/NetworkSettingsDialog.h b/source/Gui/NetworkSettingsDialog.h index 553d6a89c..790fbe461 100644 --- a/source/Gui/NetworkSettingsDialog.h +++ b/source/Gui/NetworkSettingsDialog.h @@ -8,7 +8,7 @@ class _NetworkSettingsDialog : public _AlienDialog { public: - _NetworkSettingsDialog(BrowserWindow const& browserWindow, NetworkService const& networkController); + _NetworkSettingsDialog(BrowserWindow const& browserWindow); private: void processIntern(); @@ -17,7 +17,6 @@ class _NetworkSettingsDialog : public _AlienDialog void onChangeSettings(); BrowserWindow _browserWindow; - NetworkService _networkService; std::string _serverAddress; std::string _origServerAddress; diff --git a/source/Gui/NewPasswordDialog.cpp b/source/Gui/NewPasswordDialog.cpp index d5173f139..a7015d5e5 100644 --- a/source/Gui/NewPasswordDialog.cpp +++ b/source/Gui/NewPasswordDialog.cpp @@ -11,12 +11,10 @@ _NewPasswordDialog::_NewPasswordDialog( SimulationController const& simController, - BrowserWindow const& browserWindow, - NetworkService const& networkController) + BrowserWindow const& browserWindow) : _AlienDialog("New password") , _simController(simController) , _browserWindow(browserWindow) - , _networkService(networkController) {} void _NewPasswordDialog::open(std::string const& userName, UserInfo const& userInfo) @@ -60,10 +58,11 @@ void _NewPasswordDialog::processIntern() void _NewPasswordDialog::onNewPassword() { - auto result = _networkService->setNewPassword(_userName, _newPassword, _confirmationCode); + auto& networkService = NetworkService::getInstance(); + auto result = networkService.setNewPassword(_userName, _newPassword, _confirmationCode); if (result) { LoginErrorCode errorCode; - result |= _networkService->login(errorCode, _userName, _newPassword, _userInfo); + result |= networkService.login(errorCode, _userName, _newPassword, _userInfo); } if (!result) { MessageDialog::getInstance().information("Error", "An error occurred on the server. Your entered code may be incorrect.\nPlease try to reset the password again."); diff --git a/source/Gui/NewPasswordDialog.h b/source/Gui/NewPasswordDialog.h index a5a96f60b..36ca4b5af 100644 --- a/source/Gui/NewPasswordDialog.h +++ b/source/Gui/NewPasswordDialog.h @@ -8,7 +8,7 @@ class _NewPasswordDialog : public _AlienDialog { public: - _NewPasswordDialog(SimulationController const& simController, BrowserWindow const& browserWindow, NetworkService const& networkController); + _NewPasswordDialog(SimulationController const& simController, BrowserWindow const& browserWindow); void open(std::string const& userName, UserInfo const& userInfo); @@ -19,7 +19,6 @@ class _NewPasswordDialog : public _AlienDialog SimulationController _simController; BrowserWindow _browserWindow; - NetworkService _networkService; std::string _userName; std::string _newPassword; diff --git a/source/Gui/OverlayMessageController.cpp b/source/Gui/OverlayMessageController.cpp index 88a552f58..7c397979b 100644 --- a/source/Gui/OverlayMessageController.cpp +++ b/source/Gui/OverlayMessageController.cpp @@ -36,7 +36,7 @@ void OverlayMessageController::process() ImDrawList* drawList = ImGui::GetForegroundDrawList(); - auto styleRep = StyleRepository::getInstance(); + auto& styleRep = StyleRepository::getInstance(); auto center = ImGui::GetMainViewport()->Size; center.x /= 2; auto textColorFront = ImColor::HSV(0.5f, 0.0f, 1.0f, alpha); diff --git a/source/Gui/ResetPasswordDialog.cpp b/source/Gui/ResetPasswordDialog.cpp index fd22127d3..6c09d8c8b 100644 --- a/source/Gui/ResetPasswordDialog.cpp +++ b/source/Gui/ResetPasswordDialog.cpp @@ -6,9 +6,8 @@ #include "MessageDialog.h" #include "NewPasswordDialog.h" -_ResetPasswordDialog::_ResetPasswordDialog(NewPasswordDialog const& newPasswordDialog, NetworkService const& networkController) +_ResetPasswordDialog::_ResetPasswordDialog(NewPasswordDialog const& newPasswordDialog) : _AlienDialog("Reset password") - , _networkService(networkController) , _newPasswordDialog(newPasswordDialog) {} @@ -53,7 +52,9 @@ void _ResetPasswordDialog::processIntern() void _ResetPasswordDialog::onResetPassword() { - if (_networkService->resetPassword(_userName, _email)) { + auto& networkService = NetworkService::getInstance(); + + if (networkService.resetPassword(_userName, _email)) { _newPasswordDialog->open(_userName, _userInfo); } else { MessageDialog::getInstance().information( diff --git a/source/Gui/ResetPasswordDialog.h b/source/Gui/ResetPasswordDialog.h index bb454ae3b..f051ac3e4 100644 --- a/source/Gui/ResetPasswordDialog.h +++ b/source/Gui/ResetPasswordDialog.h @@ -8,7 +8,7 @@ class _ResetPasswordDialog : public _AlienDialog { public: - _ResetPasswordDialog(NewPasswordDialog const& newPasswordDialog, NetworkService const& networkController); + _ResetPasswordDialog(NewPasswordDialog const& newPasswordDialog); void open(std::string const& userName, UserInfo const& userInfo); @@ -18,7 +18,6 @@ class _ResetPasswordDialog : public _AlienDialog void onResetPassword(); NewPasswordDialog _newPasswordDialog; - NetworkService _networkService; std::string _userName; std::string _email; diff --git a/source/Gui/SimulationView.cpp b/source/Gui/SimulationView.cpp index c4e7e4610..d9e25788e 100644 --- a/source/Gui/SimulationView.cpp +++ b/source/Gui/SimulationView.cpp @@ -331,7 +331,7 @@ void _SimulationView::draw(bool renderSimulation) auto textWidth = scale(300.0f); auto textHeight = scale(80.0f); ImDrawList* drawList = ImGui::GetBackgroundDrawList(); - auto styleRep = StyleRepository::getInstance(); + auto& styleRep = StyleRepository::getInstance(); auto right = ImGui::GetMainViewport()->Pos.x + ImGui::GetMainViewport()->Size.x; auto bottom = ImGui::GetMainViewport()->Pos.y + ImGui::GetMainViewport()->Size.y; auto maxLength = std::max(right, bottom); diff --git a/source/Gui/StartupController.cpp b/source/Gui/StartupController.cpp index 37289b28e..5c8621b66 100644 --- a/source/Gui/StartupController.cpp +++ b/source/Gui/StartupController.cpp @@ -125,7 +125,7 @@ void _StartupController::activate() void _StartupController::processLoadingScreen() { - auto styleRep = StyleRepository::getInstance(); + auto& styleRep = StyleRepository::getInstance(); auto center = ImGui::GetMainViewport()->GetCenter(); auto bottom = ImGui::GetMainViewport()->Pos.y + ImGui::GetMainViewport()->Size.y; ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); diff --git a/source/Gui/StyleRepository.h b/source/Gui/StyleRepository.h index a5c92a5ef..b83eebf82 100644 --- a/source/Gui/StyleRepository.h +++ b/source/Gui/StyleRepository.h @@ -90,6 +90,7 @@ class StyleRepository { public: static StyleRepository& getInstance(); + StyleRepository(StyleRepository const&) = delete; void init(); diff --git a/source/Gui/UploadSimulationDialog.cpp b/source/Gui/UploadSimulationDialog.cpp index e26b6540a..dcb39e777 100644 --- a/source/Gui/UploadSimulationDialog.cpp +++ b/source/Gui/UploadSimulationDialog.cpp @@ -32,12 +32,10 @@ _UploadSimulationDialog::_UploadSimulationDialog( BrowserWindow const& browserWindow, LoginDialog const& loginDialog, SimulationController const& simController, - NetworkService const& networkController, Viewport const& viewport, GenomeEditorWindow const& genomeEditorWindow) : _AlienDialog("") , _simController(simController) - , _networkService(networkController) , _browserWindow(browserWindow) , _loginDialog(loginDialog) , _viewport(viewport) @@ -57,7 +55,8 @@ _UploadSimulationDialog::~_UploadSimulationDialog() void _UploadSimulationDialog::open(DataType dataType) { - if (_networkService->getLoggedInUserName()) { + auto& networkService = NetworkService::getInstance(); + if (networkService.getLoggedInUserName()) { changeTitle("Upload " + BrowserDataTypeToLowerString.at(dataType)); _dataType = dataType; _AlienDialog::open(); @@ -154,7 +153,8 @@ void _UploadSimulationDialog::onUpload() } } - if (!_networkService->uploadSimulation(_simName, _simDescription, size, numObjects, mainData, settings, statistics, _dataType)) { + auto& networkService = NetworkService::getInstance(); + if (!networkService.uploadSimulation(_simName, _simDescription, size, numObjects, mainData, settings, statistics, _dataType)) { showMessage("Error", "Failed to upload " + BrowserDataTypeToLowerString.at(_dataType) + "."); return; } diff --git a/source/Gui/UploadSimulationDialog.h b/source/Gui/UploadSimulationDialog.h index de91447b2..156267fb2 100644 --- a/source/Gui/UploadSimulationDialog.h +++ b/source/Gui/UploadSimulationDialog.h @@ -13,7 +13,6 @@ class _UploadSimulationDialog : public _AlienDialog BrowserWindow const& browserWindow, LoginDialog const& loginDialog, SimulationController const& simController, - NetworkService const& networkController, Viewport const& viewport, GenomeEditorWindow const& genomeEditorWindow); ~_UploadSimulationDialog(); @@ -38,6 +37,5 @@ class _UploadSimulationDialog : public _AlienDialog LoginDialog _loginDialog; SimulationController _simController; Viewport _viewport; - NetworkService _networkService; GenomeEditorWindow _genomeEditorWindow; }; \ No newline at end of file diff --git a/source/Network/Definitions.h b/source/Network/Definitions.h index f6be24b8f..130f526e2 100644 --- a/source/Network/Definitions.h +++ b/source/Network/Definitions.h @@ -2,8 +2,7 @@ #include "Base/Definitions.h" -class _NetworkService; -using NetworkService = std::shared_ptr<_NetworkService>; +class NetworkService; using DataType = int; enum DataType_ diff --git a/source/Network/NetworkService.cpp b/source/Network/NetworkService.cpp index 0f7c1e701..05cdd06e5 100644 --- a/source/Network/NetworkService.cpp +++ b/source/Network/NetworkService.cpp @@ -57,39 +57,34 @@ namespace } } -_NetworkService::_NetworkService() +NetworkService& NetworkService::getInstance() { - _serverAddress = GlobalSettings::getInstance().getStringState("settings.server", "alien-project.org"); + static NetworkService instance; + return instance; } -_NetworkService::~_NetworkService() -{ - GlobalSettings::getInstance().setStringState("settings.server", _serverAddress); - logout(); -} - -std::string _NetworkService::getServerAddress() const +std::string NetworkService::getServerAddress() const { return _serverAddress; } -void _NetworkService::setServerAddress(std::string const& value) +void NetworkService::setServerAddress(std::string const& value) { _serverAddress = value; logout(); } -std::optional _NetworkService::getLoggedInUserName() const +std::optional NetworkService::getLoggedInUserName() const { return _loggedInUserName; } -std::optional _NetworkService::getPassword() const +std::optional NetworkService::getPassword() const { return _password; } -bool _NetworkService::createUser(std::string const& userName, std::string const& password, std::string const& email) +bool NetworkService::createUser(std::string const& userName, std::string const& password, std::string const& email) { log(Priority::Important, "network: create user '" + userName + "'"); @@ -110,7 +105,7 @@ bool _NetworkService::createUser(std::string const& userName, std::string const& } } -bool _NetworkService::activateUser(std::string const& userName, std::string const& password, UserInfo const& userInfo, std::string const& confirmationCode) +bool NetworkService::activateUser(std::string const& userName, std::string const& password, UserInfo const& userInfo, std::string const& confirmationCode) { log(Priority::Important, "network: activate user '" + userName + "'"); @@ -134,7 +129,7 @@ bool _NetworkService::activateUser(std::string const& userName, std::string cons } } -bool _NetworkService::login(LoginErrorCode& errorCode, std::string const& userName, std::string const& password, UserInfo const& userInfo) +bool NetworkService::login(LoginErrorCode& errorCode, std::string const& userName, std::string const& password, UserInfo const& userInfo) { log(Priority::Important, "network: login user '" + userName + "'"); @@ -170,7 +165,7 @@ bool _NetworkService::login(LoginErrorCode& errorCode, std::string const& userNa } } -bool _NetworkService::logout() +bool NetworkService::logout() { log(Priority::Important, "network: logout"); bool result = true; @@ -196,7 +191,13 @@ bool _NetworkService::logout() return result; } -void _NetworkService::refreshLogin() +void NetworkService::shutdown() +{ + GlobalSettings::getInstance().setStringState("settings.server", _serverAddress); + logout(); +} + +void NetworkService::refreshLogin() { if (_loggedInUserName && _password) { log(Priority::Important, "network: refresh login"); @@ -215,7 +216,7 @@ void _NetworkService::refreshLogin() } } -bool _NetworkService::deleteUser() +bool NetworkService::deleteUser() { log(Priority::Important, "network: delete user '" + *_loggedInUserName + "'"); @@ -240,7 +241,7 @@ bool _NetworkService::deleteUser() } } -bool _NetworkService::resetPassword(std::string const& userName, std::string const& email) +bool NetworkService::resetPassword(std::string const& userName, std::string const& email) { log(Priority::Important, "network: reset password of user '" + userName + "'"); @@ -260,7 +261,7 @@ bool _NetworkService::resetPassword(std::string const& userName, std::string con } } -bool _NetworkService::setNewPassword(std::string const& userName, std::string const& newPassword, std::string const& confirmationCode) +bool NetworkService::setNewPassword(std::string const& userName, std::string const& newPassword, std::string const& confirmationCode) { log(Priority::Important, "network: set new password for user '" + userName + "'"); @@ -281,7 +282,7 @@ bool _NetworkService::setNewPassword(std::string const& userName, std::string co } } -bool _NetworkService::getRemoteSimulationList(std::vector& result, bool withRetry) const +bool NetworkService::getRemoteSimulationList(std::vector& result, bool withRetry) const { log(Priority::Important, "network: get simulation list"); @@ -305,7 +306,7 @@ bool _NetworkService::getRemoteSimulationList(std::vector& result } } -bool _NetworkService::getUserList(std::vector& result, bool withRetry) const +bool NetworkService::getUserList(std::vector& result, bool withRetry) const { log(Priority::Important, "network: get user list"); @@ -331,7 +332,7 @@ bool _NetworkService::getUserList(std::vector& result, bool withRetry) c } } -bool _NetworkService::getEmojiTypeBySimId(std::unordered_map& result) const +bool NetworkService::getEmojiTypeBySimId(std::unordered_map& result) const { log(Priority::Important, "network: get liked simulations"); @@ -360,7 +361,7 @@ bool _NetworkService::getEmojiTypeBySimId(std::unordered_map& } } -bool _NetworkService::getUserNamesForSimulationAndEmojiType(std::set& result, std::string const& simId, int likeType) +bool NetworkService::getUserNamesForSimulationAndEmojiType(std::set& result, std::string const& simId, int likeType) { log(Priority::Important, "network: get user likes for simulation with id=" + simId + " and likeType=" + std::to_string(likeType)); @@ -389,7 +390,7 @@ bool _NetworkService::getUserNamesForSimulationAndEmojiType(std::set gpu; }; -class _NetworkService +class NetworkService { public: - _NetworkService(); - ~_NetworkService(); + static NetworkService& getInstance(); + NetworkService(NetworkService const&) = delete; std::string getServerAddress() const; void setServerAddress(std::string const& value); @@ -34,6 +34,7 @@ class _NetworkService bool login(LoginErrorCode& errorCode, std::string const& userName, std::string const& password, UserInfo const& userInfo); bool logout(); + void shutdown(); void refreshLogin(); bool deleteUser(); bool resetPassword(std::string const& userName, std::string const& email); @@ -58,6 +59,9 @@ class _NetworkService bool deleteSimulation(std::string const& simId); private: + NetworkService(); + ~NetworkService(); + std::string _serverAddress; std::optional _loggedInUserName; std::optional _password; From e70a9c842418a14257c435eccb66963c8cf9dd65 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Thu, 21 Dec 2023 21:03:50 +0100 Subject: [PATCH 11/40] libraries renamed --- source/Base/CMakeLists.txt | 6 +++--- source/Cli/CMakeLists.txt | 8 ++++---- source/EngineGpuKernels/CMakeLists.txt | 8 ++++---- source/EngineImpl/CMakeLists.txt | 12 ++++++------ source/EngineInterface/CMakeLists.txt | 10 +++++----- source/EngineTests/CMakeLists.txt | 8 ++++---- source/Gui/CMakeLists.txt | 10 +++++----- source/Network/CMakeLists.txt | 12 ++++++------ source/NetworkTests/CMakeLists.txt | 6 +++--- 9 files changed, 40 insertions(+), 40 deletions(-) diff --git a/source/Base/CMakeLists.txt b/source/Base/CMakeLists.txt index 981d3388e..e673863b7 100644 --- a/source/Base/CMakeLists.txt +++ b/source/Base/CMakeLists.txt @@ -1,5 +1,5 @@ -add_library(BaseLib +add_library(Base Definitions.cpp Definitions.h Exceptions.h @@ -25,8 +25,8 @@ add_library(BaseLib VersionChecker.cpp VersionChecker.h) -target_link_libraries(BaseLib Boost::boost) +target_link_libraries(Base Boost::boost) if (MSVC) - target_compile_options(BaseLib PRIVATE "/MP") + target_compile_options(Base PRIVATE "/MP") endif() diff --git a/source/Cli/CMakeLists.txt b/source/Cli/CMakeLists.txt index f7501812b..50f6ee80c 100644 --- a/source/Cli/CMakeLists.txt +++ b/source/Cli/CMakeLists.txt @@ -2,10 +2,10 @@ target_sources(cli PUBLIC Main.cpp) -target_link_libraries(cli BaseLib) -target_link_libraries(cli EngineGpuKernelsLib) -target_link_libraries(cli EngineImplLib) -target_link_libraries(cli EngineInterfaceLib) +target_link_libraries(cli Base) +target_link_libraries(cli EngineGpuKernels) +target_link_libraries(cli EngineImpl) +target_link_libraries(cli EngineInterface) target_link_libraries(cli CUDA::cudart_static) target_link_libraries(cli CUDA::cuda_driver) diff --git a/source/EngineGpuKernels/CMakeLists.txt b/source/EngineGpuKernels/CMakeLists.txt index a00d8d762..4a2474816 100644 --- a/source/EngineGpuKernels/CMakeLists.txt +++ b/source/EngineGpuKernels/CMakeLists.txt @@ -1,5 +1,5 @@ -add_library(EngineGpuKernelsLib +add_library(EngineGpuKernels Array.cuh AttackerProcessor.cuh Base.cuh @@ -92,8 +92,8 @@ add_library(EngineGpuKernelsLib Util.cuh ) -target_link_libraries(EngineGpuKernelsLib BaseLib) -target_link_libraries(EngineGpuKernelsLib EngineInterfaceLib) +target_link_libraries(EngineGpuKernels Base) +target_link_libraries(EngineGpuKernels EngineInterface) # See https://gitlab.kitware.com/cmake/cmake/-/issues/17520 -set_property(TARGET EngineGpuKernelsLib PROPERTY CUDA_RESOLVE_DEVICE_SYMBOLS ON) \ No newline at end of file +set_property(TARGET EngineGpuKernels PROPERTY CUDA_RESOLVE_DEVICE_SYMBOLS ON) \ No newline at end of file diff --git a/source/EngineImpl/CMakeLists.txt b/source/EngineImpl/CMakeLists.txt index 43d870409..4965191d8 100644 --- a/source/EngineImpl/CMakeLists.txt +++ b/source/EngineImpl/CMakeLists.txt @@ -1,5 +1,5 @@ -add_library(EngineImplLib +add_library(EngineImpl AccessDataTOCache.cpp AccessDataTOCache.h DescriptionConverter.cpp @@ -10,12 +10,12 @@ add_library(EngineImplLib SimulationControllerImpl.cpp SimulationControllerImpl.h) -target_link_libraries(EngineImplLib BaseLib) -target_link_libraries(EngineImplLib EngineGpuKernelsLib) +target_link_libraries(EngineImpl Base) +target_link_libraries(EngineImpl EngineGpuKernels) -target_link_libraries(EngineImplLib CUDA::cudart_static) -target_link_libraries(EngineImplLib Boost::boost) +target_link_libraries(EngineImpl CUDA::cudart_static) +target_link_libraries(EngineImpl Boost::boost) if (MSVC) - target_compile_options(EngineImplLib PRIVATE "/MP") + target_compile_options(EngineImpl PRIVATE "/MP") endif() diff --git a/source/EngineInterface/CMakeLists.txt b/source/EngineInterface/CMakeLists.txt index 46c657895..4318deeeb 100644 --- a/source/EngineInterface/CMakeLists.txt +++ b/source/EngineInterface/CMakeLists.txt @@ -1,5 +1,5 @@ -add_library(EngineInterfaceLib +add_library(EngineInterface ArraySizes.h AuxiliaryData.h AuxiliaryDataParserService.cpp @@ -49,13 +49,13 @@ add_library(EngineInterfaceLib StatisticsHistory.h ZoomLevels.h) -target_link_libraries(EngineInterfaceLib Boost::boost) -target_link_libraries(EngineInterfaceLib cereal) +target_link_libraries(EngineInterface Boost::boost) +target_link_libraries(EngineInterface cereal) target_link_libraries(alien ZLIB::ZLIB) find_path(ZSTR_INCLUDE_DIRS "zstr.hpp") -target_include_directories(EngineInterfaceLib PRIVATE ${ZSTR_INCLUDE_DIRS}) +target_include_directories(EngineInterface PRIVATE ${ZSTR_INCLUDE_DIRS}) if (MSVC) - target_compile_options(EngineInterfaceLib PRIVATE "/MP") + target_compile_options(EngineInterface PRIVATE "/MP") endif() diff --git a/source/EngineTests/CMakeLists.txt b/source/EngineTests/CMakeLists.txt index 51fe41478..7b456d593 100644 --- a/source/EngineTests/CMakeLists.txt +++ b/source/EngineTests/CMakeLists.txt @@ -20,10 +20,10 @@ PUBLIC Testsuite.cpp TransmitterTests.cpp) -target_link_libraries(EngineTests BaseLib) -target_link_libraries(EngineTests EngineGpuKernelsLib) -target_link_libraries(EngineTests EngineImplLib) -target_link_libraries(EngineTests EngineInterfaceLib) +target_link_libraries(EngineTests Base) +target_link_libraries(EngineTests EngineGpuKernels) +target_link_libraries(EngineTests EngineImpl) +target_link_libraries(EngineTests EngineInterface) target_link_libraries(EngineTests CUDA::cudart_static) target_link_libraries(EngineTests CUDA::cuda_driver) diff --git a/source/Gui/CMakeLists.txt b/source/Gui/CMakeLists.txt index 545775e2d..5ac073049 100644 --- a/source/Gui/CMakeLists.txt +++ b/source/Gui/CMakeLists.txt @@ -120,11 +120,11 @@ PUBLIC WindowController.cpp WindowController.h) -target_link_libraries(alien BaseLib) -target_link_libraries(alien EngineGpuKernelsLib) -target_link_libraries(alien EngineImplLib) -target_link_libraries(alien EngineInterfaceLib) -target_link_libraries(alien NetworkLib) +target_link_libraries(alien Base) +target_link_libraries(alien EngineGpuKernels) +target_link_libraries(alien EngineImpl) +target_link_libraries(alien EngineInterface) +target_link_libraries(alien Network) target_link_libraries(alien im_file_dialog) target_link_libraries(alien CUDA::cudart_static) diff --git a/source/Network/CMakeLists.txt b/source/Network/CMakeLists.txt index b53ccc6e9..aaed67917 100644 --- a/source/Network/CMakeLists.txt +++ b/source/Network/CMakeLists.txt @@ -1,21 +1,21 @@ -add_library(NetworkLib +add_library(Network BrowserDataService.cpp BrowserDataService.h BrowserDataTO.cpp BrowserDataTO.h Definitions.h - NetworkController.cpp - NetworkController.h + NetworkService.cpp + NetworkService.h NetworkDataParserService.cpp NetworkDataParserService.h NetworkDataTO.cpp NetworkDataTO.h UserTO.h) -target_link_libraries(NetworkLib BaseLib) -target_link_libraries(NetworkLib Boost::boost) +target_link_libraries(Network Base) +target_link_libraries(Network Boost::boost) if (MSVC) - target_compile_options(NetworkLib PRIVATE "/MP") + target_compile_options(Network PRIVATE "/MP") endif() diff --git a/source/NetworkTests/CMakeLists.txt b/source/NetworkTests/CMakeLists.txt index 26f45d155..6267ee9dd 100644 --- a/source/NetworkTests/CMakeLists.txt +++ b/source/NetworkTests/CMakeLists.txt @@ -3,9 +3,9 @@ PUBLIC BrowserDataServiceTests.cpp Testsuite.cpp) -target_link_libraries(NetworkTests BaseLib) -target_link_libraries(NetworkTests EngineInterfaceLib) -target_link_libraries(NetworkTests NetworkLib) +target_link_libraries(NetworkTests Base) +target_link_libraries(NetworkTests EngineInterface) +target_link_libraries(NetworkTests Network) target_link_libraries(NetworkTests Boost::boost) target_link_libraries(NetworkTests OpenGL::GL OpenGL::GLU) From c4701b4acad74ef4558275225967aa571b8fa5cf Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Thu, 21 Dec 2023 21:26:34 +0100 Subject: [PATCH 12/40] further tests and corrections to automatic folder generation --- source/Network/BrowserDataService.cpp | 26 ++++---- .../NetworkTests/BrowserDataServiceTests.cpp | 60 ++++++++++++++++++- 2 files changed, 74 insertions(+), 12 deletions(-) diff --git a/source/Network/BrowserDataService.cpp b/source/Network/BrowserDataService.cpp index ae3c49481..363e31cae 100644 --- a/source/Network/BrowserDataService.cpp +++ b/source/Network/BrowserDataService.cpp @@ -17,12 +17,14 @@ std::vector BrowserDataService::createBrowserData(std::vector::iterator bestMatchIter; + int bestMatchEqualFolders; if (!result.empty()) { //find matching node auto searchIter = result.end(); - auto bestMatchIter = searchIter; - int bestMatchEqualFolders = -1; + bestMatchIter = searchIter; + bestMatchEqualFolders = -1; for (int i = 0; i < result.size(); ++i) { --searchIter; auto otherEntry = *searchIter; @@ -45,15 +47,17 @@ std::vector BrowserDataService::createBrowserData(std::vector(); - browserData->location = std::vector(location.begin(), location.begin() + i + 1); - browserData->type = entry->type; - browserData->node = BrowserFolder(); - result.insert(bestMatchIter, browserData); - } + } else { + bestMatchIter = result.begin(); + bestMatchEqualFolders = 0; + } + //insert folders + for (int i = bestMatchEqualFolders; i < location.size(); ++i) { + auto browserData = std::make_shared<_BrowserDataTO>(); + browserData->location = std::vector(location.begin(), location.begin() + i + 1); + browserData->type = entry->type; + browserData->node = BrowserFolder(); + result.insert(bestMatchIter, browserData); } auto browserData = std::make_shared<_BrowserDataTO>(); diff --git a/source/NetworkTests/BrowserDataServiceTests.cpp b/source/NetworkTests/BrowserDataServiceTests.cpp index d13baa885..4b3ffcb1e 100644 --- a/source/NetworkTests/BrowserDataServiceTests.cpp +++ b/source/NetworkTests/BrowserDataServiceTests.cpp @@ -4,6 +4,8 @@ #include "Network/NetworkDataTO.h" #include "Network/BrowserDataService.h" +#include "Network/BrowserDataTO.h" + class BrowserDataServiceTests : public ::testing::Test { public: @@ -12,7 +14,7 @@ class BrowserDataServiceTests : public ::testing::Test ~BrowserDataServiceTests() = default; }; -TEST_F(BrowserDataServiceTests, singleLeaf) +TEST_F(BrowserDataServiceTests, nameWithoutFolder) { std::vector inputTOs; auto inputTO = std::make_shared<_NetworkDataTO>(); @@ -23,3 +25,59 @@ TEST_F(BrowserDataServiceTests, singleLeaf) ASSERT_EQ(1, outputTOs.size()); } + +TEST_F(BrowserDataServiceTests, nameWithFolder) +{ + std::vector inputTOs; + auto inputTO = std::make_shared<_NetworkDataTO>(); + inputTO->simName = "folder/test"; + inputTOs.emplace_back(inputTO); + + auto outputTOs = BrowserDataService::createBrowserData(inputTOs); + + ASSERT_EQ(2, outputTOs.size()); + { + auto outputTO = outputTOs.front(); + EXPECT_FALSE(outputTO->isLeaf()); + EXPECT_EQ(1, outputTO->location.size()); + EXPECT_EQ(std::string("folder"), outputTO->location.front()); + } + { + auto outputTO = outputTOs.back(); + EXPECT_TRUE(outputTO->isLeaf()); + EXPECT_EQ(1, outputTO->location.size()); + EXPECT_EQ(std::string("folder"), outputTO->location.front()); + } +} + +TEST_F(BrowserDataServiceTests, nameWithTwoFolders) +{ + std::vector inputTOs; + auto inputTO = std::make_shared<_NetworkDataTO>(); + inputTO->simName = "folder1/folder2/test"; + inputTOs.emplace_back(inputTO); + + auto outputTOs = BrowserDataService::createBrowserData(inputTOs); + + ASSERT_EQ(3, outputTOs.size()); + { + auto outputTO = outputTOs.at(0); + EXPECT_FALSE(outputTO->isLeaf()); + EXPECT_EQ(1, outputTO->location.size()); + EXPECT_EQ(std::string("folder1"), outputTO->location.at(0)); + } + { + auto outputTO = outputTOs.at(1); + EXPECT_FALSE(outputTO->isLeaf()); + EXPECT_EQ(2, outputTO->location.size()); + EXPECT_EQ(std::string("folder1"), outputTO->location.at(0)); + EXPECT_EQ(std::string("folder2"), outputTO->location.at(1)); + } + { + auto outputTO = outputTOs.at(2); + EXPECT_TRUE(outputTO->isLeaf()); + EXPECT_EQ(2, outputTO->location.size()); + EXPECT_EQ(std::string("folder1"), outputTO->location.at(0)); + EXPECT_EQ(std::string("folder2"), outputTO->location.at(1)); + } +} From e8f8b312a89498c3e11b1b21f6328eb8f27512e7 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Fri, 22 Dec 2023 12:07:19 +0100 Subject: [PATCH 13/40] draw folders --- source/Gui/BrowserWindow.cpp | 35 +++++++- source/Network/BrowserDataService.cpp | 28 +++--- source/Network/BrowserDataTO.h | 2 +- .../NetworkTests/BrowserDataServiceTests.cpp | 88 ++++++++++++++++--- 4 files changed, 126 insertions(+), 27 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 91da8e033..3be31fe79 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -263,6 +263,31 @@ void _BrowserWindow::processToolbar() AlienImGui::Separator(); } +namespace +{ + void drawFolderLines(int count) + { + ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); + for (int i = 0; i < count; ++i) { + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImGuiStyle& style = ImGui::GetStyle(); + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight)), + ImColor::HSV(0, 0, 0.5f)); + if (i == count - 1) { + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2), + ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), + ImColor::HSV(0, 0, 0.5f)); + } + ImGui::Dummy({scale(20.0f), 0}); + ImGui::SameLine(); + } + ImGui::PopStyleColor(1); + } +} + void _BrowserWindow::processSimulationList() { ImGui::PushID("SimulationList"); @@ -336,6 +361,8 @@ void _BrowserWindow::processSimulationList() ImGui::TableNextColumn(); processActionButtons(item); ImGui::TableNextColumn(); + drawFolderLines(item->folders.size()); + processShortenedText(leaf.simName); ImGui::TableNextColumn(); pushTextColor(item); @@ -364,9 +391,13 @@ void _BrowserWindow::processSimulationList() } else { ImGui::TableNextColumn(); ImGui::TableNextColumn(); - AlienImGui::CollapseButton(false); + ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); + drawFolderLines(item->folders.size() - 1); + AlienImGui::Button(ICON_FA_MINUS_SQUARE, 20.0f); + ImGui::PopStyleColor(1); + ImGui::SameLine(); - processShortenedText(item->location.back()); + processShortenedText(item->folders.back()); } ImGui::PopID(); } diff --git a/source/Network/BrowserDataService.cpp b/source/Network/BrowserDataService.cpp index 363e31cae..ef94c9200 100644 --- a/source/Network/BrowserDataService.cpp +++ b/source/Network/BrowserDataService.cpp @@ -11,10 +11,12 @@ std::vector BrowserDataService::createBrowserData(std::vector location; - boost::split(location, entry->simName, boost::is_any_of("/")); - if (!location.empty()) { - location.pop_back(); + std::vector folders; + std::string nameWithoutFolders; + boost::split(folders, entry->simName, boost::is_any_of("/")); + if (!folders.empty()) { + nameWithoutFolders = folders.back(); + folders.pop_back(); } std::list::iterator bestMatchIter; @@ -30,9 +32,9 @@ std::vector BrowserDataService::createBrowserData(std::vectorlocation.size()); + int numFolders = std::min(folders.size(), otherEntry->folders.size()); for (int i = 0; i < numFolders; ++i) { - if (location[i] == otherEntry->location[i]) { + if (folders[i] == otherEntry->folders[i]) { ++equalFolders; } else { break; @@ -47,17 +49,19 @@ std::vector BrowserDataService::createBrowserData(std::vector(); - browserData->location = std::vector(location.begin(), location.begin() + i + 1); + browserData->folders = std::vector(folders.begin(), folders.begin() + i + 1); browserData->type = entry->type; browserData->node = BrowserFolder(); - result.insert(bestMatchIter, browserData); + bestMatchIter = result.insert(bestMatchIter, browserData); + ++bestMatchIter; } auto browserData = std::make_shared<_BrowserDataTO>(); @@ -65,7 +69,7 @@ std::vector BrowserDataService::createBrowserData(std::vectorid, .timestamp = entry->timestamp, .userName = entry->userName, - .simName = entry->simName, + .simName = nameWithoutFolders, .numLikesByEmojiType = entry->numLikesByEmojiType, .numDownloads = entry->numDownloads, .width = entry->width, @@ -77,10 +81,10 @@ std::vector BrowserDataService::createBrowserData(std::vectortype = entry->type; - browserData->location = location; + browserData->folders = folders; browserData->node = leaf; - result.emplace_back(browserData); + result.insert(bestMatchIter, browserData); } return std::vector(result.begin(), result.end()); } diff --git a/source/Network/BrowserDataTO.h b/source/Network/BrowserDataTO.h index e82333622..8b63dece3 100644 --- a/source/Network/BrowserDataTO.h +++ b/source/Network/BrowserDataTO.h @@ -36,7 +36,7 @@ struct BrowserLeaf struct _BrowserDataTO { BrowserDataType type; - std::vector location; + std::vector folders; std::variant node; bool isLeaf(); diff --git a/source/NetworkTests/BrowserDataServiceTests.cpp b/source/NetworkTests/BrowserDataServiceTests.cpp index 4b3ffcb1e..890cd0616 100644 --- a/source/NetworkTests/BrowserDataServiceTests.cpp +++ b/source/NetworkTests/BrowserDataServiceTests.cpp @@ -39,14 +39,15 @@ TEST_F(BrowserDataServiceTests, nameWithFolder) { auto outputTO = outputTOs.front(); EXPECT_FALSE(outputTO->isLeaf()); - EXPECT_EQ(1, outputTO->location.size()); - EXPECT_EQ(std::string("folder"), outputTO->location.front()); + EXPECT_EQ(1, outputTO->folders.size()); + EXPECT_EQ(std::string("folder"), outputTO->folders.front()); } { auto outputTO = outputTOs.back(); EXPECT_TRUE(outputTO->isLeaf()); - EXPECT_EQ(1, outputTO->location.size()); - EXPECT_EQ(std::string("folder"), outputTO->location.front()); + EXPECT_EQ(1, outputTO->folders.size()); + EXPECT_EQ(std::string("folder"), outputTO->folders.front()); + EXPECT_EQ(std::string("test"), outputTO->getLeaf().simName); } } @@ -63,21 +64,84 @@ TEST_F(BrowserDataServiceTests, nameWithTwoFolders) { auto outputTO = outputTOs.at(0); EXPECT_FALSE(outputTO->isLeaf()); - EXPECT_EQ(1, outputTO->location.size()); - EXPECT_EQ(std::string("folder1"), outputTO->location.at(0)); + EXPECT_EQ(1, outputTO->folders.size()); + EXPECT_EQ(std::string("folder1"), outputTO->folders.at(0)); } { auto outputTO = outputTOs.at(1); EXPECT_FALSE(outputTO->isLeaf()); - EXPECT_EQ(2, outputTO->location.size()); - EXPECT_EQ(std::string("folder1"), outputTO->location.at(0)); - EXPECT_EQ(std::string("folder2"), outputTO->location.at(1)); + EXPECT_EQ(2, outputTO->folders.size()); + EXPECT_EQ(std::string("folder1"), outputTO->folders.at(0)); + EXPECT_EQ(std::string("folder2"), outputTO->folders.at(1)); } { auto outputTO = outputTOs.at(2); EXPECT_TRUE(outputTO->isLeaf()); - EXPECT_EQ(2, outputTO->location.size()); - EXPECT_EQ(std::string("folder1"), outputTO->location.at(0)); - EXPECT_EQ(std::string("folder2"), outputTO->location.at(1)); + EXPECT_EQ(2, outputTO->folders.size()); + EXPECT_EQ(std::string("folder1"), outputTO->folders.at(0)); + EXPECT_EQ(std::string("folder2"), outputTO->folders.at(1)); + EXPECT_EQ(std::string("test"), outputTO->getLeaf().simName); + } +} + + +TEST_F(BrowserDataServiceTests, twoNamesWithTwoFolders) +{ + std::vector inputTOs; + { + auto inputTO = std::make_shared<_NetworkDataTO>(); + inputTO->simName = "A/B/C"; + inputTOs.emplace_back(inputTO); + } + { + auto inputTO = std::make_shared<_NetworkDataTO>(); + inputTO->simName = "X/Y/Z"; + inputTOs.emplace_back(inputTO); + } + + auto outputTOs = BrowserDataService::createBrowserData(inputTOs); + + ASSERT_EQ(6, outputTOs.size()); + { + auto outputTO = outputTOs.at(0); + EXPECT_FALSE(outputTO->isLeaf()); + EXPECT_EQ(1, outputTO->folders.size()); + EXPECT_EQ(std::string("A"), outputTO->folders.at(0)); + } + { + auto outputTO = outputTOs.at(1); + EXPECT_FALSE(outputTO->isLeaf()); + EXPECT_EQ(2, outputTO->folders.size()); + EXPECT_EQ(std::string("A"), outputTO->folders.at(0)); + EXPECT_EQ(std::string("B"), outputTO->folders.at(1)); + } + { + auto outputTO = outputTOs.at(2); + EXPECT_TRUE(outputTO->isLeaf()); + EXPECT_EQ(2, outputTO->folders.size()); + EXPECT_EQ(std::string("A"), outputTO->folders.at(0)); + EXPECT_EQ(std::string("B"), outputTO->folders.at(1)); + EXPECT_EQ(std::string("C"), outputTO->getLeaf().simName); + } + { + auto outputTO = outputTOs.at(3); + EXPECT_FALSE(outputTO->isLeaf()); + EXPECT_EQ(1, outputTO->folders.size()); + EXPECT_EQ(std::string("X"), outputTO->folders.at(0)); + } + { + auto outputTO = outputTOs.at(4); + EXPECT_FALSE(outputTO->isLeaf()); + EXPECT_EQ(2, outputTO->folders.size()); + EXPECT_EQ(std::string("X"), outputTO->folders.at(0)); + EXPECT_EQ(std::string("Y"), outputTO->folders.at(1)); + } + { + auto outputTO = outputTOs.at(5); + EXPECT_TRUE(outputTO->isLeaf()); + EXPECT_EQ(2, outputTO->folders.size()); + EXPECT_EQ(std::string("X"), outputTO->folders.at(0)); + EXPECT_EQ(std::string("Y"), outputTO->folders.at(1)); + EXPECT_EQ(std::string("Z"), outputTO->getLeaf().simName); } } From b97f1c1cc6a325e5752f03a46c8ec201ca0ed85f Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Fri, 22 Dec 2023 17:20:22 +0100 Subject: [PATCH 14/40] tree view in browser corrected --- source/Gui/BrowserWindow.cpp | 44 ++++-- source/Network/BrowserDataService.cpp | 138 ++++++++++++++---- source/Network/BrowserDataTO.h | 12 +- .../NetworkTests/BrowserDataServiceTests.cpp | 56 +++---- 4 files changed, 180 insertions(+), 70 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 3be31fe79..48844f298 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -265,21 +265,41 @@ void _BrowserWindow::processToolbar() namespace { - void drawFolderLines(int count) + void drawFolderLines(std::vector const& folderLines, int count) { ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); - for (int i = 0; i < count; ++i) { + for (auto const& folderLine : folderLines | std::views::take(count)) { ImVec2 pos = ImGui::GetCursorScreenPos(); ImGuiStyle& style = ImGui::GetStyle(); - ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), - ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight)), - ImColor::HSV(0, 0, 0.5f)); - if (i == count - 1) { + switch (folderLine) { + case FolderLine::Continue: { + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight)), + ImColor::HSV(0, 0, 0.5f)); + } break; + case FolderLine::Branch: { + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight)), + ImColor::HSV(0, 0, 0.5f)); ImGui::GetWindowDrawList()->AddRectFilled( ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2), ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), ImColor::HSV(0, 0, 0.5f)); + } break; + case FolderLine::End: { + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), + ImColor::HSV(0, 0, 0.5f)); + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2), + ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), + ImColor::HSV(0, 0, 0.5f)); + } break; + default: { + } break; } ImGui::Dummy({scale(20.0f), 0}); ImGui::SameLine(); @@ -304,9 +324,9 @@ void _BrowserWindow::processSimulationList() scale(90.0f), NetworkDataColumnId_Actions); ImGui::TableSetupColumn( - "Simulation name", + "Simulation folder/name", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, - styleRepository.scale(160.0f), + styleRepository.scale(190.0f), NetworkDataColumnId_SimulationName); ImGui::TableSetupColumn( "Timestamp", @@ -361,7 +381,7 @@ void _BrowserWindow::processSimulationList() ImGui::TableNextColumn(); processActionButtons(item); ImGui::TableNextColumn(); - drawFolderLines(item->folders.size()); + drawFolderLines(item->folderLines, item->folderLines.size()); processShortenedText(leaf.simName); ImGui::TableNextColumn(); @@ -392,12 +412,12 @@ void _BrowserWindow::processSimulationList() ImGui::TableNextColumn(); ImGui::TableNextColumn(); ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); - drawFolderLines(item->folders.size() - 1); + drawFolderLines(item->folderLines, item->folderLines.size() - 1); AlienImGui::Button(ICON_FA_MINUS_SQUARE, 20.0f); ImGui::PopStyleColor(1); ImGui::SameLine(); - processShortenedText(item->folders.back()); + processShortenedText(item->folderNames.back()); } ImGui::PopID(); } diff --git a/source/Network/BrowserDataService.cpp b/source/Network/BrowserDataService.cpp index ef94c9200..2f2647611 100644 --- a/source/Network/BrowserDataService.cpp +++ b/source/Network/BrowserDataService.cpp @@ -5,42 +5,49 @@ #include "BrowserDataTO.h" +namespace +{ + int getNumEqualFolders(std::vector const& folderNames, std::vector const& otherfolderNames) + { + auto equalFolders = 0; + auto numFolders = std::min(folderNames.size(), otherfolderNames.size()); + for (int i = 0; i < numFolders; ++i) { + if (folderNames[i] == otherfolderNames[i]) { + ++equalFolders; + } else { + return equalFolders; + } + } + return equalFolders; + } +} + std::vector BrowserDataService::createBrowserData(std::vector const& networkTOs) { - std::list result; + std::list browserDataToList; for (auto const& entry : networkTOs) { - //parse folder - std::vector folders; + //parse folder names + std::vector folderNames; std::string nameWithoutFolders; - boost::split(folders, entry->simName, boost::is_any_of("/")); - if (!folders.empty()) { - nameWithoutFolders = folders.back(); - folders.pop_back(); + boost::split(folderNames, entry->simName, boost::is_any_of("/")); + if (!folderNames.empty()) { + nameWithoutFolders = folderNames.back(); + folderNames.pop_back(); } std::list::iterator bestMatchIter; int bestMatchEqualFolders; - if (!result.empty()) { + if (!browserDataToList.empty()) { //find matching node - auto searchIter = result.end(); + auto searchIter = browserDataToList.end(); bestMatchIter = searchIter; bestMatchEqualFolders = -1; - for (int i = 0; i < result.size(); ++i) { + for (int i = 0; i < browserDataToList.size(); ++i) { --searchIter; auto otherEntry = *searchIter; - - int equalFolders = 0; - int numFolders = std::min(folders.size(), otherEntry->folders.size()); - for (int i = 0; i < numFolders; ++i) { - if (folders[i] == otherEntry->folders[i]) { - ++equalFolders; - } else { - break; - } - } - + auto equalFolders = getNumEqualFolders(folderNames, otherEntry->folderNames); if (equalFolders < bestMatchEqualFolders) { break; } @@ -51,19 +58,21 @@ std::vector BrowserDataService::createBrowserData(std::vector(); - browserData->folders = std::vector(folders.begin(), folders.begin() + i + 1); + browserData->folderNames = std::vector(folderNames.begin(), folderNames.begin() + i + 1); browserData->type = entry->type; browserData->node = BrowserFolder(); - bestMatchIter = result.insert(bestMatchIter, browserData); + bestMatchIter = browserDataToList.insert(bestMatchIter, browserData); ++bestMatchIter; } + //insert leaf auto browserData = std::make_shared<_BrowserDataTO>(); BrowserLeaf leaf{ .id = entry->id, @@ -79,12 +88,83 @@ std::vector BrowserDataService::createBrowserData(std::vectordescription, .version = entry->version }; - browserData->type = entry->type; - browserData->folders = folders; + browserData->folderNames = folderNames; browserData->node = leaf; + browserDataToList.insert(bestMatchIter, browserData); + } + + //calc folder lines + std::vector result(browserDataToList.begin(), browserDataToList.end()); + for (int i = 0; i < result.size(); ++i) { + auto& entry = result.at(i); + + if (i == 0) { + if (!entry->isLeaf()) { + entry->folderLines.emplace_back(FolderLine::Start); + } + } else { + auto const& prevEntry = result.at(i - 1); + auto numEqualFolders = getNumEqualFolders(entry->folderNames, prevEntry->folderNames); - result.insert(bestMatchIter, browserData); + entry->folderLines.resize(entry->folderNames.size(), FolderLine::None); + + //process until numEqualFolders - 1 + if (numEqualFolders > 0) { + int f = numEqualFolders - 1; + if (prevEntry->folderLines.at(f) == FolderLine::Start) { + entry->folderLines.at(f) = FolderLine::End; + } else if (prevEntry->folderLines.at(f) == FolderLine::End) { + prevEntry->folderLines.at(f) = FolderLine::Branch; + entry->folderLines.at(f) = FolderLine::End; + } else if (prevEntry->folderLines.at(f) == FolderLine::Branch) { + entry->folderLines.at(f) = FolderLine::End; + } else if (prevEntry->folderLines.at(f) == FolderLine::None) { + for (int j = i - 1; j >= 0; --j) { + auto& otherEntry = result.at(j); + if (otherEntry->folderLines.at(f) == FolderLine::None) { + otherEntry->folderLines.at(f) = FolderLine::Continue; + } else if (otherEntry->folderLines.at(f) == FolderLine::End) { + otherEntry->folderLines.at(f) = FolderLine::Branch; + } else { + break; + } + } + + } + + } + + for (int f = 0; f < numEqualFolders - 1; ++f) { + if (prevEntry->folderLines.at(f) == FolderLine::Branch) { + entry->folderLines.at(f) = FolderLine::None; + } + } + + if (numEqualFolders < entry->folderNames.size()) { + CHECK(numEqualFolders + 1 == entry->folderNames.size()); + entry->folderLines.back() = FolderLine::Start; + + if (numEqualFolders > 0 && numEqualFolders < prevEntry->folderNames.size()) { + entry->folderLines.at(numEqualFolders - 1) = FolderLine::End; + bool noneFound = false; + for (int j = i - 1; j >= 0; --j) { + auto& otherEntry = result.at(j); + if (otherEntry->folderLines.at(numEqualFolders - 1) == FolderLine::None) { + otherEntry->folderLines.at(numEqualFolders - 1) = FolderLine::Continue; + noneFound = true; + } else if (noneFound && otherEntry->folderLines.at(numEqualFolders - 1) == FolderLine::End) { + otherEntry->folderLines.at(numEqualFolders - 1) = FolderLine::Branch; + } else { + break; + } + } + } + } + if (numEqualFolders > 0 && numEqualFolders < prevEntry->folderNames.size() && numEqualFolders == entry->folderNames.size()) { + entry->folderLines.back() = FolderLine::End; + } + } } - return std::vector(result.begin(), result.end()); + return result; } diff --git a/source/Network/BrowserDataTO.h b/source/Network/BrowserDataTO.h index 8b63dece3..6b3e4d54b 100644 --- a/source/Network/BrowserDataTO.h +++ b/source/Network/BrowserDataTO.h @@ -33,10 +33,20 @@ struct BrowserLeaf std::string version; }; +enum class FolderLine +{ + Start, + Continue, + Branch, + End, + None +}; + struct _BrowserDataTO { BrowserDataType type; - std::vector folders; + std::vector folderNames; + std::vector folderLines; std::variant node; bool isLeaf(); diff --git a/source/NetworkTests/BrowserDataServiceTests.cpp b/source/NetworkTests/BrowserDataServiceTests.cpp index 890cd0616..d7fc7e8e0 100644 --- a/source/NetworkTests/BrowserDataServiceTests.cpp +++ b/source/NetworkTests/BrowserDataServiceTests.cpp @@ -39,14 +39,14 @@ TEST_F(BrowserDataServiceTests, nameWithFolder) { auto outputTO = outputTOs.front(); EXPECT_FALSE(outputTO->isLeaf()); - EXPECT_EQ(1, outputTO->folders.size()); - EXPECT_EQ(std::string("folder"), outputTO->folders.front()); + EXPECT_EQ(1, outputTO->folderNames.size()); + EXPECT_EQ(std::string("folder"), outputTO->folderNames.front()); } { auto outputTO = outputTOs.back(); EXPECT_TRUE(outputTO->isLeaf()); - EXPECT_EQ(1, outputTO->folders.size()); - EXPECT_EQ(std::string("folder"), outputTO->folders.front()); + EXPECT_EQ(1, outputTO->folderNames.size()); + EXPECT_EQ(std::string("folder"), outputTO->folderNames.front()); EXPECT_EQ(std::string("test"), outputTO->getLeaf().simName); } } @@ -64,22 +64,22 @@ TEST_F(BrowserDataServiceTests, nameWithTwoFolders) { auto outputTO = outputTOs.at(0); EXPECT_FALSE(outputTO->isLeaf()); - EXPECT_EQ(1, outputTO->folders.size()); - EXPECT_EQ(std::string("folder1"), outputTO->folders.at(0)); + EXPECT_EQ(1, outputTO->folderNames.size()); + EXPECT_EQ(std::string("folder1"), outputTO->folderNames.at(0)); } { auto outputTO = outputTOs.at(1); EXPECT_FALSE(outputTO->isLeaf()); - EXPECT_EQ(2, outputTO->folders.size()); - EXPECT_EQ(std::string("folder1"), outputTO->folders.at(0)); - EXPECT_EQ(std::string("folder2"), outputTO->folders.at(1)); + EXPECT_EQ(2, outputTO->folderNames.size()); + EXPECT_EQ(std::string("folder1"), outputTO->folderNames.at(0)); + EXPECT_EQ(std::string("folder2"), outputTO->folderNames.at(1)); } { auto outputTO = outputTOs.at(2); EXPECT_TRUE(outputTO->isLeaf()); - EXPECT_EQ(2, outputTO->folders.size()); - EXPECT_EQ(std::string("folder1"), outputTO->folders.at(0)); - EXPECT_EQ(std::string("folder2"), outputTO->folders.at(1)); + EXPECT_EQ(2, outputTO->folderNames.size()); + EXPECT_EQ(std::string("folder1"), outputTO->folderNames.at(0)); + EXPECT_EQ(std::string("folder2"), outputTO->folderNames.at(1)); EXPECT_EQ(std::string("test"), outputTO->getLeaf().simName); } } @@ -105,43 +105,43 @@ TEST_F(BrowserDataServiceTests, twoNamesWithTwoFolders) { auto outputTO = outputTOs.at(0); EXPECT_FALSE(outputTO->isLeaf()); - EXPECT_EQ(1, outputTO->folders.size()); - EXPECT_EQ(std::string("A"), outputTO->folders.at(0)); + EXPECT_EQ(1, outputTO->folderNames.size()); + EXPECT_EQ(std::string("A"), outputTO->folderNames.at(0)); } { auto outputTO = outputTOs.at(1); EXPECT_FALSE(outputTO->isLeaf()); - EXPECT_EQ(2, outputTO->folders.size()); - EXPECT_EQ(std::string("A"), outputTO->folders.at(0)); - EXPECT_EQ(std::string("B"), outputTO->folders.at(1)); + EXPECT_EQ(2, outputTO->folderNames.size()); + EXPECT_EQ(std::string("A"), outputTO->folderNames.at(0)); + EXPECT_EQ(std::string("B"), outputTO->folderNames.at(1)); } { auto outputTO = outputTOs.at(2); EXPECT_TRUE(outputTO->isLeaf()); - EXPECT_EQ(2, outputTO->folders.size()); - EXPECT_EQ(std::string("A"), outputTO->folders.at(0)); - EXPECT_EQ(std::string("B"), outputTO->folders.at(1)); + EXPECT_EQ(2, outputTO->folderNames.size()); + EXPECT_EQ(std::string("A"), outputTO->folderNames.at(0)); + EXPECT_EQ(std::string("B"), outputTO->folderNames.at(1)); EXPECT_EQ(std::string("C"), outputTO->getLeaf().simName); } { auto outputTO = outputTOs.at(3); EXPECT_FALSE(outputTO->isLeaf()); - EXPECT_EQ(1, outputTO->folders.size()); - EXPECT_EQ(std::string("X"), outputTO->folders.at(0)); + EXPECT_EQ(1, outputTO->folderNames.size()); + EXPECT_EQ(std::string("X"), outputTO->folderNames.at(0)); } { auto outputTO = outputTOs.at(4); EXPECT_FALSE(outputTO->isLeaf()); - EXPECT_EQ(2, outputTO->folders.size()); - EXPECT_EQ(std::string("X"), outputTO->folders.at(0)); - EXPECT_EQ(std::string("Y"), outputTO->folders.at(1)); + EXPECT_EQ(2, outputTO->folderNames.size()); + EXPECT_EQ(std::string("X"), outputTO->folderNames.at(0)); + EXPECT_EQ(std::string("Y"), outputTO->folderNames.at(1)); } { auto outputTO = outputTOs.at(5); EXPECT_TRUE(outputTO->isLeaf()); - EXPECT_EQ(2, outputTO->folders.size()); - EXPECT_EQ(std::string("X"), outputTO->folders.at(0)); - EXPECT_EQ(std::string("Y"), outputTO->folders.at(1)); + EXPECT_EQ(2, outputTO->folderNames.size()); + EXPECT_EQ(std::string("X"), outputTO->folderNames.at(0)); + EXPECT_EQ(std::string("Y"), outputTO->folderNames.at(1)); EXPECT_EQ(std::string("Z"), outputTO->getLeaf().simName); } } From d047b2470a44a334ae11f6593c53784fe09d43e6 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Fri, 22 Dec 2023 19:21:34 +0100 Subject: [PATCH 15/40] folder layout tweaks --- source/EngineInterface/Colors.h | 2 +- source/Gui/BrowserWindow.cpp | 14 +++++++------- source/Gui/StyleRepository.h | 2 ++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/source/EngineInterface/Colors.h b/source/EngineInterface/Colors.h index e307ab94a..cd63613ed 100644 --- a/source/EngineInterface/Colors.h +++ b/source/EngineInterface/Colors.h @@ -27,7 +27,7 @@ namespace Const uint32_t const CellFunctionInfoColor = 0x404090; uint32_t const BranchNumberInfoColor = 0x000000; - uint32_t const NothingnessColor = 0x000000; + uint32_t const VoidColor = 0x000000; } template diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 48844f298..5dc41eed8 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -275,28 +275,28 @@ namespace case FolderLine::Continue: { ImGui::GetWindowDrawList()->AddRectFilled( ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), - ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight)), - ImColor::HSV(0, 0, 0.5f)); + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) + style.FramePadding.y), + Const::BrowserFolderLineColor); } break; case FolderLine::Branch: { ImGui::GetWindowDrawList()->AddRectFilled( ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), - ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight)), - ImColor::HSV(0, 0, 0.5f)); + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) + style.FramePadding.y), + Const::BrowserFolderLineColor); ImGui::GetWindowDrawList()->AddRectFilled( ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2), ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), - ImColor::HSV(0, 0, 0.5f)); + Const::BrowserFolderLineColor); } break; case FolderLine::End: { ImGui::GetWindowDrawList()->AddRectFilled( ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), - ImColor::HSV(0, 0, 0.5f)); + Const::BrowserFolderLineColor); ImGui::GetWindowDrawList()->AddRectFilled( ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2), ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), - ImColor::HSV(0, 0, 0.5f)); + Const::BrowserFolderLineColor); } break; default: { } break; diff --git a/source/Gui/StyleRepository.h b/source/Gui/StyleRepository.h index b83eebf82..9c4114506 100644 --- a/source/Gui/StyleRepository.h +++ b/source/Gui/StyleRepository.h @@ -82,6 +82,8 @@ namespace Const ImColor const NeuronEditorZeroLinePlotColor = ImColor::HSV(0.6f, 1.0f, 0.7f); ImColor const NeuronEditorPlotColor = ImColor::HSV(0.0f, 0.0f, 1.0f); + ImColor const BrowserFolderLineColor = ImColor::HSV(0.0f, 0.0f, 0.5f); + float const WindowAlpha = 0.9f; float const SliderBarWidth = 30.0f; } From 9a165d1bd68eefdda37dcc124bc3c72bc5966941 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Fri, 22 Dec 2023 21:13:09 +0100 Subject: [PATCH 16/40] renamings --- source/Gui/BrowserWindow.cpp | 87 ++++++++++--------- source/Gui/BrowserWindow.h | 28 +++--- source/Gui/GenomeEditorWindow.cpp | 2 +- source/Gui/MainWindow.cpp | 8 +- source/Gui/UploadSimulationDialog.cpp | 16 ++-- source/Gui/UploadSimulationDialog.h | 4 +- source/Network/BrowserDataService.h | 12 --- source/Network/BrowserDataTO.cpp | 16 ---- source/Network/CMakeLists.txt | 16 ++-- source/Network/Definitions.h | 17 ++-- source/Network/NetworkDataTO.h | 54 ------------ ...e.cpp => NetworkResourceParserService.cpp} | 14 +-- ...rvice.h => NetworkResourceParserService.h} | 4 +- ...orkDataTO.cpp => NetworkResourceRawTO.cpp} | 30 +++---- source/Network/NetworkResourceRawTO.h | 47 ++++++++++ ...Service.cpp => NetworkResourceService.cpp} | 14 +-- source/Network/NetworkResourceService.h | 12 +++ source/Network/NetworkResourceTreeTO.cpp | 16 ++++ ...rowserDataTO.h => NetworkResourceTreeTO.h} | 12 +-- source/Network/NetworkService.cpp | 10 +-- source/Network/NetworkService.h | 6 +- .../NetworkTests/BrowserDataServiceTests.cpp | 32 +++---- 22 files changed, 223 insertions(+), 234 deletions(-) delete mode 100644 source/Network/BrowserDataService.h delete mode 100644 source/Network/BrowserDataTO.cpp delete mode 100644 source/Network/NetworkDataTO.h rename source/Network/{NetworkDataParserService.cpp => NetworkResourceParserService.cpp} (80%) rename source/Network/{NetworkDataParserService.h => NetworkResourceParserService.h} (60%) rename source/Network/{NetworkDataTO.cpp => NetworkResourceRawTO.cpp} (75%) create mode 100644 source/Network/NetworkResourceRawTO.h rename source/Network/{BrowserDataService.cpp => NetworkResourceService.cpp} (93%) create mode 100644 source/Network/NetworkResourceService.h create mode 100644 source/Network/NetworkResourceTreeTO.cpp rename source/Network/{BrowserDataTO.h => NetworkResourceTreeTO.h} (81%) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 5dc41eed8..64859fe44 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -21,9 +21,10 @@ #include "EngineInterface/GenomeDescriptionService.h" #include "EngineInterface/SerializerService.h" #include "EngineInterface/SimulationController.h" -#include "Network/BrowserDataService.h" +#include "Network/NetworkResourceService.h" #include "Network/NetworkService.h" -#include "Network/NetworkDataParserService.h" +#include "Network/NetworkResourceParserService.h" +#include "Network/NetworkResourceTreeTO.h" #include "AlienImGui.h" #include "StyleRepository.h" @@ -105,7 +106,7 @@ void _BrowserWindow::refreshIntern(bool withRetry) auto& networkService = NetworkService::getInstance(); networkService.refreshLogin(); - bool success = networkService.getRemoteSimulationList(_rawNetworkDataTOs, withRetry); + bool success = networkService.getRemoteSimulationList(_rawNetworkResourceRawTOs, withRetry); success &= networkService.getUserList(_userTOs, withRetry); if (!success) { @@ -115,8 +116,8 @@ void _BrowserWindow::refreshIntern(bool withRetry) } else { _numSimulations = 0; _numGenomes = 0; - for (auto const& entry : _rawNetworkDataTOs) { - if (entry->type == DataType_Simulation) { + for (auto const& entry : _rawNetworkResourceRawTOs) { + if (entry->type == NetworkResourceType_Simulation) { ++_numSimulations; } else { ++_numGenomes; @@ -246,7 +247,7 @@ void _BrowserWindow::processToolbar() if (AlienImGui::ToolbarButton(ICON_FA_SHARE_ALT)) { _uploadSimulationDialog.lock()->open(_selectedDataType); } - std::string dataType = _selectedDataType == DataType_Simulation + std::string dataType = _selectedDataType == NetworkResourceType_Simulation ? "simulation" : "genome"; AlienImGui::Tooltip( @@ -311,7 +312,7 @@ namespace void _BrowserWindow::processSimulationList() { ImGui::PushID("SimulationList"); - _selectedDataType = DataType_Simulation; + _selectedDataType = NetworkResourceType_Simulation; auto& styleRepository = StyleRepository::getInstance(); static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Sortable | ImGuiTableFlags_SortMulti | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_NoBordersInBody @@ -322,38 +323,38 @@ void _BrowserWindow::processSimulationList() "Actions", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, scale(90.0f), - NetworkDataColumnId_Actions); + NetworkResourceColumnId_Actions); ImGui::TableSetupColumn( "Simulation folder/name", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(190.0f), - NetworkDataColumnId_SimulationName); + NetworkResourceColumnId_SimulationName); ImGui::TableSetupColumn( "Timestamp", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_PreferSortDescending, scale(135.0f), - NetworkDataColumnId_Timestamp); + NetworkResourceColumnId_Timestamp); ImGui::TableSetupColumn( "User name", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), - NetworkDataColumnId_UserName); + NetworkResourceColumnId_UserName); ImGui::TableSetupColumn( "Description", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), - NetworkDataColumnId_Description); + NetworkResourceColumnId_Description); ImGui::TableSetupColumn( "Reactions", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), - NetworkDataColumnId_Likes); - ImGui::TableSetupColumn("Downloads", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_NumDownloads); - ImGui::TableSetupColumn("Width", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_Width); - ImGui::TableSetupColumn("Height", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_Height); - ImGui::TableSetupColumn("Objects", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_Particles); - ImGui::TableSetupColumn("File size", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_FileSize); - ImGui::TableSetupColumn("Version", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_Version); + NetworkResourceColumnId_Likes); + ImGui::TableSetupColumn("Downloads", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_NumDownloads); + ImGui::TableSetupColumn("Width", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Width); + ImGui::TableSetupColumn("Height", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Height); + ImGui::TableSetupColumn("Objects", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Particles); + ImGui::TableSetupColumn("File size", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_FileSize); + ImGui::TableSetupColumn("Version", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Version); ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableHeadersRow(); @@ -364,7 +365,7 @@ void _BrowserWindow::processSimulationList() sortSpecs->SpecsDirty = false; _scheduleCreateBrowserData = false; - _browserSimulationTOs = BrowserDataService::createBrowserData(_filteredNetworkSimulationTOs); + _browserSimulationTOs = NetworkResourceService::createBrowserData(_filteredNetworkSimulationTOs); } } ImGuiListClipper clipper; @@ -429,7 +430,7 @@ void _BrowserWindow::processSimulationList() void _BrowserWindow::processGenomeList() { ImGui::PushID("GenomeList"); - _selectedDataType = DataType_Genome; + _selectedDataType = NetworkResourceType_Genome; auto& styleRepository = StyleRepository::getInstance(); static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Sortable | ImGuiTableFlags_SortMulti | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_NoBordersInBody @@ -437,37 +438,37 @@ void _BrowserWindow::processGenomeList() if (ImGui::BeginTable("Browser", 10, flags, ImVec2(0, 0), 0.0f)) { ImGui::TableSetupColumn( - "Actions", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, scale(90.0f), NetworkDataColumnId_Actions); + "Actions", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, scale(90.0f), NetworkResourceColumnId_Actions); ImGui::TableSetupColumn( "Genome name", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(160.0f), - NetworkDataColumnId_SimulationName); + NetworkResourceColumnId_SimulationName); ImGui::TableSetupColumn( "Timestamp", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_PreferSortDescending, scale(135.0f), - NetworkDataColumnId_Timestamp); + NetworkResourceColumnId_Timestamp); ImGui::TableSetupColumn( "User name", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), - NetworkDataColumnId_UserName); + NetworkResourceColumnId_UserName); ImGui::TableSetupColumn( "Description", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), - NetworkDataColumnId_Description); + NetworkResourceColumnId_Description); ImGui::TableSetupColumn( "Reactions", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), - NetworkDataColumnId_Likes); + NetworkResourceColumnId_Likes); ImGui::TableSetupColumn( - "Downloads", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_NumDownloads); - ImGui::TableSetupColumn("Cells", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_Particles); - ImGui::TableSetupColumn("File size", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_FileSize); - ImGui::TableSetupColumn("Version", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkDataColumnId_Version); + "Downloads", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_NumDownloads); + ImGui::TableSetupColumn("Cells", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Particles); + ImGui::TableSetupColumn("File size", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_FileSize); + ImGui::TableSetupColumn("Version", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Version); ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableHeadersRow(); @@ -478,7 +479,7 @@ void _BrowserWindow::processGenomeList() sortSpecs->SpecsDirty = false; _scheduleCreateBrowserData = false; - _browserGenomeTOs = BrowserDataService::createBrowserData(_filteredNetworkGenomeTOs); + _browserGenomeTOs = NetworkResourceService::createBrowserData(_filteredNetworkGenomeTOs); } } ImGuiListClipper clipper; @@ -730,7 +731,7 @@ void _BrowserWindow::processEmojiButton(int emojiType) } } -void _BrowserWindow::processEmojiList(BrowserDataTO const& to) +void _BrowserWindow::processEmojiList(NetworkResourceTreeTO const& to) { //calc remap which allows to show most frequent like type first std::map remap; @@ -796,7 +797,7 @@ void _BrowserWindow::processEmojiList(BrowserDataTO const& to) } } -void _BrowserWindow::processActionButtons(BrowserDataTO const& to) +void _BrowserWindow::processActionButtons(NetworkResourceTreeTO const& to) { auto& networkService = NetworkService::getInstance(); //like button @@ -903,11 +904,11 @@ void _BrowserWindow::processActivated() onRefresh(); } -void _BrowserWindow::sortRemoteSimulationData(std::vector& remoteData, ImGuiTableSortSpecs* sortSpecs) +void _BrowserWindow::sortRemoteSimulationData(std::vector& remoteData, ImGuiTableSortSpecs* sortSpecs) { if (remoteData.size() > 1) { std::sort(remoteData.begin(), remoteData.end(), [&](auto const& left, auto const& right) { - return _NetworkDataTO::compare(left, right, sortSpecs) < 0; + return _NetworkResourceRawTO::compare(left, right, sortSpecs) < 0; }); } } @@ -923,14 +924,14 @@ void _BrowserWindow::onDownloadItem(BrowserLeaf const& leaf) delayedExecution([=, this] { auto& networkService = NetworkService::getInstance(); - std::string dataTypeString = _selectedDataType == DataType_Simulation ? "simulation" : "genome"; + std::string dataTypeString = _selectedDataType == NetworkResourceType_Simulation ? "simulation" : "genome"; SerializedSimulation serializedSim; if (!networkService.downloadSimulation(serializedSim.mainData, serializedSim.auxiliaryData, serializedSim.statistics, leaf.id)) { MessageDialog::getInstance().information("Error", "Failed to download " + dataTypeString + "."); return; } - if (_selectedDataType == DataType_Simulation) { + if (_selectedDataType == NetworkResourceType_Simulation) { DeserializedSimulation deserializedSim; if (!SerializerService::deserializeSimulationFromStrings(deserializedSim, serializedSim)) { MessageDialog::getInstance().information("Error", "Failed to load simulation. Your program version may not match."); @@ -997,7 +998,7 @@ void _BrowserWindow::onDeleteItem(BrowserLeaf const& leaf) }); } -void _BrowserWindow::onToggleLike(BrowserDataTO const& to, int emojiType) +void _BrowserWindow::onToggleLike(NetworkResourceTreeTO const& to, int emojiType) { CHECK(to->isLeaf()); auto& leaf = to->getLeaf(); @@ -1064,7 +1065,7 @@ std::string _BrowserWindow::getUserNamesToEmojiType(std::string const& simId, in return boost::algorithm::join(userNames, ", "); } -void _BrowserWindow::pushTextColor(BrowserDataTO const& to) +void _BrowserWindow::pushTextColor(NetworkResourceTreeTO const& to) { if (to->isLeaf()) { auto const& leaf = to->getLeaf(); @@ -1083,12 +1084,12 @@ void _BrowserWindow::pushTextColor(BrowserDataTO const& to) void _BrowserWindow::calcFilteredSimulationAndGenomeLists() { _filteredNetworkSimulationTOs.clear(); - _filteredNetworkSimulationTOs.reserve(_rawNetworkDataTOs.size()); + _filteredNetworkSimulationTOs.reserve(_rawNetworkResourceRawTOs.size()); _filteredNetworkGenomeTOs.clear(); _filteredNetworkGenomeTOs.reserve(_filteredNetworkGenomeTOs.size()); - for (auto const& to : _rawNetworkDataTOs) { + for (auto const& to : _rawNetworkResourceRawTOs) { if (to->matchWithFilter(_filter) &&_showCommunityCreations != to->fromRelease) { - if (to->type == NetworkDataType_Simulation) { + if (to->type == NetworkResourceType_Simulation) { _filteredNetworkSimulationTOs.emplace_back(to); } else { _filteredNetworkGenomeTOs.emplace_back(to); diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index 0412479af..0f0082c66 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -4,8 +4,8 @@ #include "Base/Hashes.h" #include "EngineInterface/Definitions.h" -#include "Network/BrowserDataTO.h" -#include "Network/NetworkDataTO.h" +#include "Network/NetworkResourceTreeTO.h" +#include "Network/NetworkResourceRawTO.h" #include "Network/UserTO.h" #include "AlienWindow.h" @@ -42,9 +42,9 @@ class _BrowserWindow : public _AlienWindow void processEmojiWindow(); void processEmojiButton(int emojiType); - void processEmojiList(BrowserDataTO const& to); + void processEmojiList(NetworkResourceTreeTO const& to); - void processActionButtons(BrowserDataTO const& to); + void processActionButtons(NetworkResourceTreeTO const& to); void processShortenedText(std::string const& text, bool bold = false); bool processActionButton(std::string const& text); @@ -52,21 +52,21 @@ class _BrowserWindow : public _AlienWindow void processActivated() override; - void sortRemoteSimulationData(std::vector& remoteData, ImGuiTableSortSpecs* sortSpecs); + void sortRemoteSimulationData(std::vector& remoteData, ImGuiTableSortSpecs* sortSpecs); void sortUserList(); void onDownloadItem(BrowserLeaf const& leaf); void onDeleteItem(BrowserLeaf const& leaf); - void onToggleLike(BrowserDataTO const& to, int emojiType); + void onToggleLike(NetworkResourceTreeTO const& to, int emojiType); void openWeblink(std::string const& link); bool isLiked(std::string const& simId); std::string getUserNamesToEmojiType(std::string const& simId, int emojiType); - void pushTextColor(BrowserDataTO const& to); + void pushTextColor(NetworkResourceTreeTO const& to); void calcFilteredSimulationAndGenomeLists(); - DataType _selectedDataType = DataType_Simulation; + NetworkResourceType _selectedDataType = NetworkResourceType_Simulation; bool _scheduleRefresh = false; bool _scheduleCreateBrowserData = false; std::string _filter; @@ -78,12 +78,12 @@ class _BrowserWindow : public _AlienWindow int _numSimulations = 0; int _numGenomes = 0; - std::vector _rawNetworkDataTOs; - std::vector _filteredNetworkSimulationTOs; - std::vector _filteredNetworkGenomeTOs; + std::vector _rawNetworkResourceRawTOs; + std::vector _filteredNetworkSimulationTOs; + std::vector _filteredNetworkGenomeTOs; - std::vector _browserSimulationTOs; - std::vector _browserGenomeTOs; + std::vector _browserSimulationTOs; + std::vector _browserGenomeTOs; std::vector _userTOs; @@ -91,7 +91,7 @@ class _BrowserWindow : public _AlienWindow bool _activateEmojiPopup = false; bool _showAllEmojis = false; - BrowserDataTO _emojiPopupTO; + NetworkResourceTreeTO _emojiPopupTO; std::optional _lastRefreshTime; diff --git a/source/Gui/GenomeEditorWindow.cpp b/source/Gui/GenomeEditorWindow.cpp index abda9b8b5..a981e50f4 100644 --- a/source/Gui/GenomeEditorWindow.cpp +++ b/source/Gui/GenomeEditorWindow.cpp @@ -831,7 +831,7 @@ void _GenomeEditorWindow::onSaveGenome() void _GenomeEditorWindow::onUploadGenome() { - _uploadSimulationDialog.lock()->open(DataType_Genome); + _uploadSimulationDialog.lock()->open(NetworkResourceType_Genome); } void _GenomeEditorWindow::onAddNode() diff --git a/source/Gui/MainWindow.cpp b/source/Gui/MainWindow.cpp index 2f761a3bc..a1ed8e875 100644 --- a/source/Gui/MainWindow.cpp +++ b/source/Gui/MainWindow.cpp @@ -408,12 +408,12 @@ void _MainWindow::processMenubar() ImGui::EndDisabled(); ImGui::BeginDisabled(!networkService.getLoggedInUserName()); if (ImGui::MenuItem("Upload simulation", "ALT+D")) { - _uploadSimulationDialog->open(DataType_Simulation); + _uploadSimulationDialog->open(NetworkResourceType_Simulation); } ImGui::EndDisabled(); ImGui::BeginDisabled(!networkService.getLoggedInUserName()); if (ImGui::MenuItem("Upload genome", "ALT+Q")) { - _uploadSimulationDialog->open(DataType_Genome); + _uploadSimulationDialog->open(NetworkResourceType_Genome); } ImGui::EndDisabled(); @@ -597,10 +597,10 @@ void _MainWindow::processMenubar() _browserWindow->onRefresh(); } if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_D) && networkService.getLoggedInUserName()) { - _uploadSimulationDialog->open(DataType_Simulation); + _uploadSimulationDialog->open(NetworkResourceType_Simulation); } if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_Q) && networkService.getLoggedInUserName()) { - _uploadSimulationDialog->open(DataType_Genome); + _uploadSimulationDialog->open(NetworkResourceType_Genome); } if (io.KeyAlt && ImGui::IsKeyPressed(GLFW_KEY_J) && networkService.getLoggedInUserName()) { _deleteUserDialog->open(); diff --git a/source/Gui/UploadSimulationDialog.cpp b/source/Gui/UploadSimulationDialog.cpp index dcb39e777..e4a80d011 100644 --- a/source/Gui/UploadSimulationDialog.cpp +++ b/source/Gui/UploadSimulationDialog.cpp @@ -20,12 +20,12 @@ namespace { - std::map const BrowserDataTypeToLowerString = { - {DataType_Simulation, "simulation"}, - {DataType_Genome, "genome"}}; - std::map const BrowserDataTypeToUpperString = { - {DataType_Simulation, "Simulation"}, - {DataType_Genome, "Genome"}}; + std::map const BrowserDataTypeToLowerString = { + {NetworkResourceType_Simulation, "simulation"}, + {NetworkResourceType_Genome, "genome"}}; + std::map const BrowserDataTypeToUpperString = { + {NetworkResourceType_Simulation, "Simulation"}, + {NetworkResourceType_Genome, "Genome"}}; } _UploadSimulationDialog::_UploadSimulationDialog( @@ -53,7 +53,7 @@ _UploadSimulationDialog::~_UploadSimulationDialog() settings.setStringState("dialogs.upload.simulation description", _simDescription); } -void _UploadSimulationDialog::open(DataType dataType) +void _UploadSimulationDialog::open(NetworkResourceType dataType) { auto& networkService = NetworkService::getInstance(); if (networkService.getLoggedInUserName()) { @@ -117,7 +117,7 @@ void _UploadSimulationDialog::onUpload() IntVector2D size; int numObjects = 0; - if (_dataType == DataType_Simulation) { + if (_dataType == NetworkResourceType_Simulation) { DeserializedSimulation deserializedSim; deserializedSim.auxiliaryData.timestep = static_cast(_simController->getCurrentTimestep()); deserializedSim.auxiliaryData.zoom = _viewport->getZoomFactor(); diff --git a/source/Gui/UploadSimulationDialog.h b/source/Gui/UploadSimulationDialog.h index 156267fb2..f3dc0371c 100644 --- a/source/Gui/UploadSimulationDialog.h +++ b/source/Gui/UploadSimulationDialog.h @@ -17,7 +17,7 @@ class _UploadSimulationDialog : public _AlienDialog GenomeEditorWindow const& genomeEditorWindow); ~_UploadSimulationDialog(); - void open(DataType dataType); + void open(NetworkResourceType dataType); private: void processIntern(); @@ -31,7 +31,7 @@ class _UploadSimulationDialog : public _AlienDialog std::string _origSimName; std::string _origSimDescription; - DataType _dataType = DataType_Simulation; + NetworkResourceType _dataType = NetworkResourceType_Simulation; BrowserWindow _browserWindow; LoginDialog _loginDialog; diff --git a/source/Network/BrowserDataService.h b/source/Network/BrowserDataService.h deleted file mode 100644 index a7b9dcd45..000000000 --- a/source/Network/BrowserDataService.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include - -#include "Definitions.h" -#include "NetworkDataTO.h" - -class BrowserDataService -{ -public: - static std::vector createBrowserData(std::vector const& browserData); -}; diff --git a/source/Network/BrowserDataTO.cpp b/source/Network/BrowserDataTO.cpp deleted file mode 100644 index dbcc5cc2f..000000000 --- a/source/Network/BrowserDataTO.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "BrowserDataTO.h" - -bool _BrowserDataTO::isLeaf() -{ - return std::holds_alternative(node); -} - -BrowserLeaf& _BrowserDataTO::getLeaf() -{ - return std::get(node); -} - -BrowserFolder& _BrowserDataTO::getFolder() -{ - return std::get(node); -} diff --git a/source/Network/CMakeLists.txt b/source/Network/CMakeLists.txt index aaed67917..d2fb0bce3 100644 --- a/source/Network/CMakeLists.txt +++ b/source/Network/CMakeLists.txt @@ -1,16 +1,16 @@ add_library(Network - BrowserDataService.cpp - BrowserDataService.h - BrowserDataTO.cpp - BrowserDataTO.h Definitions.h NetworkService.cpp NetworkService.h - NetworkDataParserService.cpp - NetworkDataParserService.h - NetworkDataTO.cpp - NetworkDataTO.h + NetworkResourceParserService.cpp + NetworkResourceParserService.h + NetworkResourceRawTO.cpp + NetworkResourceRawTO.h + NetworkResourceService.cpp + NetworkResourceService.h + NetworkResourceTreeTO.cpp + NetworkResourceTreeTO.h UserTO.h) target_link_libraries(Network Base) diff --git a/source/Network/Definitions.h b/source/Network/Definitions.h index 130f526e2..706cc3e8d 100644 --- a/source/Network/Definitions.h +++ b/source/Network/Definitions.h @@ -4,15 +4,16 @@ class NetworkService; -using DataType = int; -enum DataType_ +using NetworkResourceType = int; +enum NetworkResourceType_ { - DataType_Simulation, - DataType_Genome + NetworkResourceType_Simulation, + NetworkResourceType_Genome }; -struct _BrowserDataTO; -using BrowserDataTO = std::shared_ptr<_BrowserDataTO>; -struct _NetworkDataTO; -using NetworkDataTO = std::shared_ptr<_NetworkDataTO>; +struct _NetworkResourceTreeTO; +using NetworkResourceTreeTO = std::shared_ptr<_NetworkResourceTreeTO>; + +struct _NetworkResourceRawTO; +using NetworkResourceRawTO = std::shared_ptr<_NetworkResourceRawTO>; diff --git a/source/Network/NetworkDataTO.h b/source/Network/NetworkDataTO.h deleted file mode 100644 index 3afee8913..000000000 --- a/source/Network/NetworkDataTO.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include -#include - -#include "Definitions.h" - -class ImGuiTableSortSpecs; - -enum NetworkDataColumnId -{ - NetworkDataColumnId_Timestamp, - NetworkDataColumnId_UserName, - NetworkDataColumnId_SimulationName, - NetworkDataColumnId_Description, - NetworkDataColumnId_Likes, - NetworkDataColumnId_NumDownloads, - NetworkDataColumnId_Width, - NetworkDataColumnId_Height, - NetworkDataColumnId_Particles, - NetworkDataColumnId_FileSize, - NetworkDataColumnId_Version, - NetworkDataColumnId_Actions -}; - -using NetworkDataType = int; -enum NetworkDataType_ -{ - NetworkDataType_Simulation, - NetworkDataType_Genome -}; - -struct _NetworkDataTO -{ - std::string id; - std::string timestamp; - std::string userName; - std::string simName; - std::map numLikesByEmojiType; - int numDownloads; - int width; - int height; - int particles; - uint64_t contentSize; - std::string description; - std::string version; - bool fromRelease; - NetworkDataType type; - - static int compare(NetworkDataTO const& left, NetworkDataTO const& right, ImGuiTableSortSpecs const* specs); - bool matchWithFilter(std::string const& filter) const; - - int getTotalLikes() const; -}; diff --git a/source/Network/NetworkDataParserService.cpp b/source/Network/NetworkResourceParserService.cpp similarity index 80% rename from source/Network/NetworkDataParserService.cpp rename to source/Network/NetworkResourceParserService.cpp index 0f88e96d5..044b6782d 100644 --- a/source/Network/NetworkDataParserService.cpp +++ b/source/Network/NetworkResourceParserService.cpp @@ -1,12 +1,12 @@ -#include "NetworkDataParserService.h" +#include "NetworkResourceParserService.h" -#include "NetworkDataTO.h" +#include "NetworkResourceRawTO.h" -std::vector NetworkDataParserService::decodeRemoteSimulationData(boost::property_tree::ptree const& tree) +std::vector NetworkResourceParserService::decodeRemoteSimulationData(boost::property_tree::ptree const& tree) { - std::vector result; + std::vector result; for (auto const& [key, subTree] : tree) { - auto entry = std::make_shared<_NetworkDataTO>(); + auto entry = std::make_shared<_NetworkResourceRawTO>(); entry->id = subTree.get("id"); entry->userName = subTree.get("userName"); entry->simName = subTree.get("simulationName"); @@ -31,13 +31,13 @@ std::vector NetworkDataParserService::decodeRemoteSimulationData( } entry->numDownloads = subTree.get("numDownloads"); entry->fromRelease = subTree.get("fromRelease") == 1; - entry->type = subTree.get("type"); + entry->type = subTree.get("type"); result.emplace_back(entry); } return result; } -std::vector NetworkDataParserService::decodeUserData(boost::property_tree::ptree const& tree) +std::vector NetworkResourceParserService::decodeUserData(boost::property_tree::ptree const& tree) { std::vector result; for (auto const& [key, subTree] : tree) { diff --git a/source/Network/NetworkDataParserService.h b/source/Network/NetworkResourceParserService.h similarity index 60% rename from source/Network/NetworkDataParserService.h rename to source/Network/NetworkResourceParserService.h index e8b077b22..5029e6f0c 100644 --- a/source/Network/NetworkDataParserService.h +++ b/source/Network/NetworkResourceParserService.h @@ -6,9 +6,9 @@ #include "UserTO.h" #include "Definitions.h" -class NetworkDataParserService +class NetworkResourceParserService { public: - static std::vector decodeRemoteSimulationData(boost::property_tree::ptree const& tree); + static std::vector decodeRemoteSimulationData(boost::property_tree::ptree const& tree); static std::vector decodeUserData(boost::property_tree::ptree const& tree); }; \ No newline at end of file diff --git a/source/Network/NetworkDataTO.cpp b/source/Network/NetworkResourceRawTO.cpp similarity index 75% rename from source/Network/NetworkDataTO.cpp rename to source/Network/NetworkResourceRawTO.cpp index 62dda063c..c8e69b4ec 100644 --- a/source/Network/NetworkDataTO.cpp +++ b/source/Network/NetworkResourceRawTO.cpp @@ -1,45 +1,45 @@ -#include "NetworkDataTO.h" +#include "NetworkResourceRawTO.h" #include #include -int _NetworkDataTO::compare(NetworkDataTO const& left, NetworkDataTO const& right, ImGuiTableSortSpecs const* specs) +int _NetworkResourceRawTO::compare(NetworkResourceRawTO const& left, NetworkResourceRawTO const& right, ImGuiTableSortSpecs const* specs) { for (int n = 0; n < specs->SpecsCount; n++) { const ImGuiTableColumnSortSpecs* sortSpec = &specs->Specs[n]; int delta = 0; switch (sortSpec->ColumnUserID) { - case NetworkDataColumnId_Timestamp: + case NetworkResourceColumnId_Timestamp: delta = left->timestamp.compare(right->timestamp); break; - case NetworkDataColumnId_UserName: + case NetworkResourceColumnId_UserName: delta = left->userName.compare(right->userName); break; - case NetworkDataColumnId_SimulationName: + case NetworkResourceColumnId_SimulationName: delta = left->simName.compare(right->simName); break; - case NetworkDataColumnId_Description: + case NetworkResourceColumnId_Description: delta = left->description.compare(right->description); break; - case NetworkDataColumnId_Likes: + case NetworkResourceColumnId_Likes: delta = left->getTotalLikes() - right->getTotalLikes(); break; - case NetworkDataColumnId_NumDownloads: + case NetworkResourceColumnId_NumDownloads: delta = left->numDownloads - right->numDownloads; break; - case NetworkDataColumnId_Width: + case NetworkResourceColumnId_Width: delta = left->width - right->width; break; - case NetworkDataColumnId_Height: + case NetworkResourceColumnId_Height: delta = left->height - right->height; break; - case NetworkDataColumnId_Particles: + case NetworkResourceColumnId_Particles: delta = left->particles - right->particles; break; - case NetworkDataColumnId_FileSize: + case NetworkResourceColumnId_FileSize: delta = static_cast(left->contentSize / 1024) - static_cast(right->contentSize / 1024); break; - case NetworkDataColumnId_Version: + case NetworkResourceColumnId_Version: delta = left->version.compare(right->version); break; } @@ -54,7 +54,7 @@ int _NetworkDataTO::compare(NetworkDataTO const& left, NetworkDataTO const& righ return 0; } -bool _NetworkDataTO::matchWithFilter(std::string const& filter) const +bool _NetworkResourceRawTO::matchWithFilter(std::string const& filter) const { auto match = false; if (timestamp.find(filter) != std::string::npos) { @@ -90,7 +90,7 @@ bool _NetworkDataTO::matchWithFilter(std::string const& filter) const return match; } -int _NetworkDataTO::getTotalLikes() const +int _NetworkResourceRawTO::getTotalLikes() const { int result = 0; for (auto const& numReactions : numLikesByEmojiType | std::views::values) { diff --git a/source/Network/NetworkResourceRawTO.h b/source/Network/NetworkResourceRawTO.h new file mode 100644 index 000000000..a18710d8a --- /dev/null +++ b/source/Network/NetworkResourceRawTO.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include + +#include "Definitions.h" + +class ImGuiTableSortSpecs; + +enum NetworkResourceColumnId +{ + NetworkResourceColumnId_Timestamp, + NetworkResourceColumnId_UserName, + NetworkResourceColumnId_SimulationName, + NetworkResourceColumnId_Description, + NetworkResourceColumnId_Likes, + NetworkResourceColumnId_NumDownloads, + NetworkResourceColumnId_Width, + NetworkResourceColumnId_Height, + NetworkResourceColumnId_Particles, + NetworkResourceColumnId_FileSize, + NetworkResourceColumnId_Version, + NetworkResourceColumnId_Actions +}; + +struct _NetworkResourceRawTO +{ + std::string id; + std::string timestamp; + std::string userName; + std::string simName; + std::map numLikesByEmojiType; + int numDownloads; + int width; + int height; + int particles; + uint64_t contentSize; + std::string description; + std::string version; + bool fromRelease; + NetworkResourceType type; + + static int compare(NetworkResourceRawTO const& left, NetworkResourceRawTO const& right, ImGuiTableSortSpecs const* specs); + bool matchWithFilter(std::string const& filter) const; + + int getTotalLikes() const; +}; diff --git a/source/Network/BrowserDataService.cpp b/source/Network/NetworkResourceService.cpp similarity index 93% rename from source/Network/BrowserDataService.cpp rename to source/Network/NetworkResourceService.cpp index 2f2647611..35af7b81e 100644 --- a/source/Network/BrowserDataService.cpp +++ b/source/Network/NetworkResourceService.cpp @@ -1,9 +1,9 @@ -#include "BrowserDataService.h" +#include "NetworkResourceService.h" #include #include -#include "BrowserDataTO.h" +#include "NetworkResourceTreeTO.h" namespace { @@ -22,9 +22,9 @@ namespace } } -std::vector BrowserDataService::createBrowserData(std::vector const& networkTOs) +std::vector NetworkResourceService::createBrowserData(std::vector const& networkTOs) { - std::list browserDataToList; + std::list browserDataToList; for (auto const& entry : networkTOs) { //parse folder names @@ -36,7 +36,7 @@ std::vector BrowserDataService::createBrowserData(std::vector::iterator bestMatchIter; + std::list::iterator bestMatchIter; int bestMatchEqualFolders; if (!browserDataToList.empty()) { @@ -64,7 +64,7 @@ std::vector BrowserDataService::createBrowserData(std::vector(); + auto browserData = std::make_shared<_NetworkResourceTreeTO>(); browserData->folderNames = std::vector(folderNames.begin(), folderNames.begin() + i + 1); browserData->type = entry->type; browserData->node = BrowserFolder(); @@ -73,7 +73,7 @@ std::vector BrowserDataService::createBrowserData(std::vector(); + auto browserData = std::make_shared<_NetworkResourceTreeTO>(); BrowserLeaf leaf{ .id = entry->id, .timestamp = entry->timestamp, diff --git a/source/Network/NetworkResourceService.h b/source/Network/NetworkResourceService.h new file mode 100644 index 000000000..b9d3c3444 --- /dev/null +++ b/source/Network/NetworkResourceService.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +#include "Definitions.h" +#include "NetworkResourceRawTO.h" + +class NetworkResourceService +{ +public: + static std::vector createBrowserData(std::vector const& browserData); +}; diff --git a/source/Network/NetworkResourceTreeTO.cpp b/source/Network/NetworkResourceTreeTO.cpp new file mode 100644 index 000000000..aaeeed274 --- /dev/null +++ b/source/Network/NetworkResourceTreeTO.cpp @@ -0,0 +1,16 @@ +#include "NetworkResourceTreeTO.h" + +bool _NetworkResourceTreeTO::isLeaf() +{ + return std::holds_alternative(node); +} + +BrowserLeaf& _NetworkResourceTreeTO::getLeaf() +{ + return std::get(node); +} + +BrowserFolder& _NetworkResourceTreeTO::getFolder() +{ + return std::get(node); +} diff --git a/source/Network/BrowserDataTO.h b/source/Network/NetworkResourceTreeTO.h similarity index 81% rename from source/Network/BrowserDataTO.h rename to source/Network/NetworkResourceTreeTO.h index 6b3e4d54b..b12252ebb 100644 --- a/source/Network/BrowserDataTO.h +++ b/source/Network/NetworkResourceTreeTO.h @@ -5,13 +5,7 @@ #include #include "Definitions.h" - -using BrowserDataType = int; -enum BrowserDataType_ -{ - BrowserDataType_Simulation, - BrowserDataType_Genome -}; +#include "NetworkResourceRawTO.h" struct BrowserFolder { @@ -42,9 +36,9 @@ enum class FolderLine None }; -struct _BrowserDataTO +struct _NetworkResourceTreeTO { - BrowserDataType type; + NetworkResourceType type; std::vector folderNames; std::vector folderLines; std::variant node; diff --git a/source/Network/NetworkService.cpp b/source/Network/NetworkService.cpp index 05cdd06e5..70acb2fd4 100644 --- a/source/Network/NetworkService.cpp +++ b/source/Network/NetworkService.cpp @@ -9,7 +9,7 @@ #include "Base/LoggingService.h" #include "Base/Resources.h" -#include "NetworkDataParserService.h" +#include "NetworkResourceParserService.h" namespace { @@ -282,7 +282,7 @@ bool NetworkService::setNewPassword(std::string const& userName, std::string con } } -bool NetworkService::getRemoteSimulationList(std::vector& result, bool withRetry) const +bool NetworkService::getRemoteSimulationList(std::vector& result, bool withRetry) const { log(Priority::Important, "network: get simulation list"); @@ -298,7 +298,7 @@ bool NetworkService::getRemoteSimulationList(std::vector& result, std::stringstream stream(postResult->body); boost::property_tree::ptree tree; boost::property_tree::read_json(stream, tree); - result = NetworkDataParserService::decodeRemoteSimulationData(tree); + result = NetworkResourceParserService::decodeRemoteSimulationData(tree); return true; } catch (...) { logNetworkError(); @@ -321,7 +321,7 @@ bool NetworkService::getUserList(std::vector& result, bool withRetry) co boost::property_tree::ptree tree; boost::property_tree::read_json(stream, tree); result.clear(); - result = NetworkDataParserService::decodeUserData(tree); + result = NetworkResourceParserService::decodeUserData(tree); for (UserTO& userData : result) { userData.timeSpent = userData.timeSpent * RefreshInterval / 60; } @@ -421,7 +421,7 @@ bool NetworkService::uploadSimulation( std::string const& mainData, std::string const& settings, std::string const& statistics, - NetworkDataType type) + NetworkResourceType type) { log(Priority::Important, "network: upload simulation with name='" + simulationName + "'"); diff --git a/source/Network/NetworkService.h b/source/Network/NetworkService.h index 6d996951d..1724a4473 100644 --- a/source/Network/NetworkService.h +++ b/source/Network/NetworkService.h @@ -2,7 +2,7 @@ #include -#include "NetworkDataTO.h" +#include "NetworkResourceRawTO.h" #include "UserTO.h" #include "Definitions.h" @@ -40,7 +40,7 @@ class NetworkService bool resetPassword(std::string const& userName, std::string const& email); bool setNewPassword(std::string const& userName, std::string const& newPassword, std::string const& confirmationCode); - bool getRemoteSimulationList(std::vector& result, bool withRetry) const; + bool getRemoteSimulationList(std::vector& result, bool withRetry) const; bool getUserList(std::vector& result, bool withRetry) const; bool getEmojiTypeBySimId(std::unordered_map& result) const; bool getUserNamesForSimulationAndEmojiType(std::set& result, std::string const& simId, int likeType); @@ -54,7 +54,7 @@ class NetworkService std::string const& data, std::string const& settings, std::string const& statistics, - NetworkDataType type); + NetworkResourceType type); bool downloadSimulation(std::string& mainData, std::string& auxiliaryData, std::string& statistics, std::string const& simId); bool deleteSimulation(std::string const& simId); diff --git a/source/NetworkTests/BrowserDataServiceTests.cpp b/source/NetworkTests/BrowserDataServiceTests.cpp index d7fc7e8e0..66d3e534b 100644 --- a/source/NetworkTests/BrowserDataServiceTests.cpp +++ b/source/NetworkTests/BrowserDataServiceTests.cpp @@ -1,10 +1,10 @@ #include #include "Base/NumberGenerator.h" -#include "Network/NetworkDataTO.h" -#include "Network/BrowserDataService.h" +#include "Network/NetworkResourceRawTO.h" +#include "Network/NetworkResourceService.h" -#include "Network/BrowserDataTO.h" +#include "Network/NetworkResourceTreeTO.h" class BrowserDataServiceTests : public ::testing::Test { @@ -16,24 +16,24 @@ class BrowserDataServiceTests : public ::testing::Test TEST_F(BrowserDataServiceTests, nameWithoutFolder) { - std::vector inputTOs; - auto inputTO = std::make_shared<_NetworkDataTO>(); + std::vector inputTOs; + auto inputTO = std::make_shared<_NetworkResourceRawTO>(); inputTO->simName = "test"; inputTOs.emplace_back(inputTO); - auto outputTOs = BrowserDataService::createBrowserData(inputTOs); + auto outputTOs = NetworkResourceService::createBrowserData(inputTOs); ASSERT_EQ(1, outputTOs.size()); } TEST_F(BrowserDataServiceTests, nameWithFolder) { - std::vector inputTOs; - auto inputTO = std::make_shared<_NetworkDataTO>(); + std::vector inputTOs; + auto inputTO = std::make_shared<_NetworkResourceRawTO>(); inputTO->simName = "folder/test"; inputTOs.emplace_back(inputTO); - auto outputTOs = BrowserDataService::createBrowserData(inputTOs); + auto outputTOs = NetworkResourceService::createBrowserData(inputTOs); ASSERT_EQ(2, outputTOs.size()); { @@ -53,12 +53,12 @@ TEST_F(BrowserDataServiceTests, nameWithFolder) TEST_F(BrowserDataServiceTests, nameWithTwoFolders) { - std::vector inputTOs; - auto inputTO = std::make_shared<_NetworkDataTO>(); + std::vector inputTOs; + auto inputTO = std::make_shared<_NetworkResourceRawTO>(); inputTO->simName = "folder1/folder2/test"; inputTOs.emplace_back(inputTO); - auto outputTOs = BrowserDataService::createBrowserData(inputTOs); + auto outputTOs = NetworkResourceService::createBrowserData(inputTOs); ASSERT_EQ(3, outputTOs.size()); { @@ -87,19 +87,19 @@ TEST_F(BrowserDataServiceTests, nameWithTwoFolders) TEST_F(BrowserDataServiceTests, twoNamesWithTwoFolders) { - std::vector inputTOs; + std::vector inputTOs; { - auto inputTO = std::make_shared<_NetworkDataTO>(); + auto inputTO = std::make_shared<_NetworkResourceRawTO>(); inputTO->simName = "A/B/C"; inputTOs.emplace_back(inputTO); } { - auto inputTO = std::make_shared<_NetworkDataTO>(); + auto inputTO = std::make_shared<_NetworkResourceRawTO>(); inputTO->simName = "X/Y/Z"; inputTOs.emplace_back(inputTO); } - auto outputTOs = BrowserDataService::createBrowserData(inputTOs); + auto outputTOs = NetworkResourceService::createBrowserData(inputTOs); ASSERT_EQ(6, outputTOs.size()); { From eb16221ca34123f70b391a870d314bd73b3b2e95 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Sat, 23 Dec 2023 08:16:53 +0100 Subject: [PATCH 17/40] interaction for browser tree prepared + code cleanded --- source/Gui/BrowserWindow.cpp | 22 ++-- source/Gui/BrowserWindow.h | 5 +- source/Network/NetworkResourceService.cpp | 115 ++++++++++-------- source/Network/NetworkResourceService.h | 4 +- source/Network/NetworkResourceTreeTO.h | 12 +- source/NetworkTests/CMakeLists.txt | 2 +- ...ts.cpp => NetworkResourceServiceTests.cpp} | 22 ++-- 7 files changed, 102 insertions(+), 80 deletions(-) rename source/NetworkTests/{BrowserDataServiceTests.cpp => NetworkResourceServiceTests.cpp} (87%) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 64859fe44..8f68fd2f8 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -266,20 +266,22 @@ void _BrowserWindow::processToolbar() namespace { - void drawFolderLines(std::vector const& folderLines, int count) + void drawFolderLines(std::vector const& folderLines, int count) { ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); for (auto const& folderLine : folderLines | std::views::take(count)) { ImVec2 pos = ImGui::GetCursorScreenPos(); ImGuiStyle& style = ImGui::GetStyle(); switch (folderLine) { - case FolderLine::Continue: { + case FolderSymbols::ExpandedFolder: { + } break; + case FolderSymbols::ContinueFolder: { ImGui::GetWindowDrawList()->AddRectFilled( ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) + style.FramePadding.y), Const::BrowserFolderLineColor); } break; - case FolderLine::Branch: { + case FolderSymbols::BranchFolder: { ImGui::GetWindowDrawList()->AddRectFilled( ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) + style.FramePadding.y), @@ -289,7 +291,7 @@ namespace ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), Const::BrowserFolderLineColor); } break; - case FolderLine::End: { + case FolderSymbols::EndFolder: { ImGui::GetWindowDrawList()->AddRectFilled( ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), @@ -365,14 +367,14 @@ void _BrowserWindow::processSimulationList() sortSpecs->SpecsDirty = false; _scheduleCreateBrowserData = false; - _browserSimulationTOs = NetworkResourceService::createBrowserData(_filteredNetworkSimulationTOs); + _simulationTreeTOs = NetworkResourceService::createTreeTOs(_filteredNetworkSimulationTOs, _expandedFolderNames); } } ImGuiListClipper clipper; - clipper.Begin(_browserSimulationTOs.size()); + clipper.Begin(_simulationTreeTOs.size()); while (clipper.Step()) for (int row = clipper.DisplayStart; row < clipper.DisplayEnd; row++) { - auto item = _browserSimulationTOs[row]; + auto item = _simulationTreeTOs[row]; ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); @@ -479,15 +481,15 @@ void _BrowserWindow::processGenomeList() sortSpecs->SpecsDirty = false; _scheduleCreateBrowserData = false; - _browserGenomeTOs = NetworkResourceService::createBrowserData(_filteredNetworkGenomeTOs); + _genomeTreeTOs = NetworkResourceService::createTreeTOs(_filteredNetworkGenomeTOs, _expandedFolderNames); } } ImGuiListClipper clipper; - clipper.Begin(_browserGenomeTOs.size()); + clipper.Begin(_genomeTreeTOs.size()); while (clipper.Step()) for (int row = clipper.DisplayStart; row < clipper.DisplayEnd; row++) { - auto& item = _browserGenomeTOs[row]; + auto& item = _genomeTreeTOs[row]; ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index 0f0082c66..9ecad46c7 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -81,9 +81,10 @@ class _BrowserWindow : public _AlienWindow std::vector _rawNetworkResourceRawTOs; std::vector _filteredNetworkSimulationTOs; std::vector _filteredNetworkGenomeTOs; + std::vector> _expandedFolderNames; - std::vector _browserSimulationTOs; - std::vector _browserGenomeTOs; + std::vector _simulationTreeTOs; + std::vector _genomeTreeTOs; std::vector _userTOs; diff --git a/source/Network/NetworkResourceService.cpp b/source/Network/NetworkResourceService.cpp index 35af7b81e..5e68ecbce 100644 --- a/source/Network/NetworkResourceService.cpp +++ b/source/Network/NetworkResourceService.cpp @@ -7,12 +7,12 @@ namespace { - int getNumEqualFolders(std::vector const& folderNames, std::vector const& otherfolderNames) + int getNumEqualFolders(std::vector const& folderNames, std::vector const& otherFolderNames) { auto equalFolders = 0; - auto numFolders = std::min(folderNames.size(), otherfolderNames.size()); + auto numFolders = std::min(folderNames.size(), otherFolderNames.size()); for (int i = 0; i < numFolders; ++i) { - if (folderNames[i] == otherfolderNames[i]) { + if (folderNames[i] == otherFolderNames[i]) { ++equalFolders; } else { return equalFolders; @@ -22,9 +22,11 @@ namespace } } -std::vector NetworkResourceService::createBrowserData(std::vector const& networkTOs) +std::vector NetworkResourceService::createTreeTOs( + std::vector const& networkTOs, + std::vector> const& expandedFolderNames) { - std::list browserDataToList; + std::list treeToList; for (auto const& entry : networkTOs) { //parse folder names @@ -38,13 +40,13 @@ std::vector NetworkResourceService::createBrowserData(std std::list::iterator bestMatchIter; int bestMatchEqualFolders; - if (!browserDataToList.empty()) { + if (!treeToList.empty()) { //find matching node - auto searchIter = browserDataToList.end(); + auto searchIter = treeToList.end(); bestMatchIter = searchIter; bestMatchEqualFolders = -1; - for (int i = 0; i < browserDataToList.size(); ++i) { + for (int i = 0; i < treeToList.size(); ++i) { --searchIter; auto otherEntry = *searchIter; auto equalFolders = getNumEqualFolders(folderNames, otherEntry->folderNames); @@ -58,22 +60,22 @@ std::vector NetworkResourceService::createBrowserData(std } ++bestMatchIter; } else { - bestMatchIter = browserDataToList.begin(); + bestMatchIter = treeToList.begin(); bestMatchEqualFolders = 0; } //insert folders for (int i = bestMatchEqualFolders; i < folderNames.size(); ++i) { - auto browserData = std::make_shared<_NetworkResourceTreeTO>(); - browserData->folderNames = std::vector(folderNames.begin(), folderNames.begin() + i + 1); - browserData->type = entry->type; - browserData->node = BrowserFolder(); - bestMatchIter = browserDataToList.insert(bestMatchIter, browserData); + auto treeTO = std::make_shared<_NetworkResourceTreeTO>(); + treeTO->folderNames = std::vector(folderNames.begin(), folderNames.begin() + i + 1); + treeTO->type = entry->type; + treeTO->node = BrowserFolder(); + bestMatchIter = treeToList.insert(bestMatchIter, treeTO); ++bestMatchIter; } //insert leaf - auto browserData = std::make_shared<_NetworkResourceTreeTO>(); + auto treeTO = std::make_shared<_NetworkResourceTreeTO>(); BrowserLeaf leaf{ .id = entry->id, .timestamp = entry->timestamp, @@ -88,44 +90,44 @@ std::vector NetworkResourceService::createBrowserData(std .description = entry->description, .version = entry->version }; - browserData->type = entry->type; - browserData->folderNames = folderNames; - browserData->node = leaf; - browserDataToList.insert(bestMatchIter, browserData); + treeTO->type = entry->type; + treeTO->folderNames = folderNames; + treeTO->node = leaf; + treeToList.insert(bestMatchIter, treeTO); } //calc folder lines - std::vector result(browserDataToList.begin(), browserDataToList.end()); - for (int i = 0; i < result.size(); ++i) { - auto& entry = result.at(i); + std::vector treeTOs(treeToList.begin(), treeToList.end()); + for (int i = 0; i < treeTOs.size(); ++i) { + auto& entry = treeTOs.at(i); if (i == 0) { if (!entry->isLeaf()) { - entry->folderLines.emplace_back(FolderLine::Start); + entry->folderLines.emplace_back(FolderSymbols::ExpandedFolder); } } else { - auto const& prevEntry = result.at(i - 1); + auto const& prevEntry = treeTOs.at(i - 1); auto numEqualFolders = getNumEqualFolders(entry->folderNames, prevEntry->folderNames); - entry->folderLines.resize(entry->folderNames.size(), FolderLine::None); + entry->folderLines.resize(entry->folderNames.size(), FolderSymbols::None); //process until numEqualFolders - 1 if (numEqualFolders > 0) { int f = numEqualFolders - 1; - if (prevEntry->folderLines.at(f) == FolderLine::Start) { - entry->folderLines.at(f) = FolderLine::End; - } else if (prevEntry->folderLines.at(f) == FolderLine::End) { - prevEntry->folderLines.at(f) = FolderLine::Branch; - entry->folderLines.at(f) = FolderLine::End; - } else if (prevEntry->folderLines.at(f) == FolderLine::Branch) { - entry->folderLines.at(f) = FolderLine::End; - } else if (prevEntry->folderLines.at(f) == FolderLine::None) { + if (prevEntry->folderLines.at(f) == FolderSymbols::ExpandedFolder) { + entry->folderLines.at(f) = FolderSymbols::EndFolder; + } else if (prevEntry->folderLines.at(f) == FolderSymbols::EndFolder) { + prevEntry->folderLines.at(f) = FolderSymbols::BranchFolder; + entry->folderLines.at(f) = FolderSymbols::EndFolder; + } else if (prevEntry->folderLines.at(f) == FolderSymbols::BranchFolder) { + entry->folderLines.at(f) = FolderSymbols::EndFolder; + } else if (prevEntry->folderLines.at(f) == FolderSymbols::None) { for (int j = i - 1; j >= 0; --j) { - auto& otherEntry = result.at(j); - if (otherEntry->folderLines.at(f) == FolderLine::None) { - otherEntry->folderLines.at(f) = FolderLine::Continue; - } else if (otherEntry->folderLines.at(f) == FolderLine::End) { - otherEntry->folderLines.at(f) = FolderLine::Branch; + auto& otherEntry = treeTOs.at(j); + if (otherEntry->folderLines.at(f) == FolderSymbols::None) { + otherEntry->folderLines.at(f) = FolderSymbols::ContinueFolder; + } else if (otherEntry->folderLines.at(f) == FolderSymbols::EndFolder) { + otherEntry->folderLines.at(f) = FolderSymbols::BranchFolder; } else { break; } @@ -136,25 +138,25 @@ std::vector NetworkResourceService::createBrowserData(std } for (int f = 0; f < numEqualFolders - 1; ++f) { - if (prevEntry->folderLines.at(f) == FolderLine::Branch) { - entry->folderLines.at(f) = FolderLine::None; + if (prevEntry->folderLines.at(f) == FolderSymbols::BranchFolder) { + entry->folderLines.at(f) = FolderSymbols::None; } } if (numEqualFolders < entry->folderNames.size()) { CHECK(numEqualFolders + 1 == entry->folderNames.size()); - entry->folderLines.back() = FolderLine::Start; + entry->folderLines.back() = FolderSymbols::ExpandedFolder; if (numEqualFolders > 0 && numEqualFolders < prevEntry->folderNames.size()) { - entry->folderLines.at(numEqualFolders - 1) = FolderLine::End; + entry->folderLines.at(numEqualFolders - 1) = FolderSymbols::EndFolder; bool noneFound = false; for (int j = i - 1; j >= 0; --j) { - auto& otherEntry = result.at(j); - if (otherEntry->folderLines.at(numEqualFolders - 1) == FolderLine::None) { - otherEntry->folderLines.at(numEqualFolders - 1) = FolderLine::Continue; + auto& otherEntry = treeTOs.at(j); + if (otherEntry->folderLines.at(numEqualFolders - 1) == FolderSymbols::None) { + otherEntry->folderLines.at(numEqualFolders - 1) = FolderSymbols::ContinueFolder; noneFound = true; - } else if (noneFound && otherEntry->folderLines.at(numEqualFolders - 1) == FolderLine::End) { - otherEntry->folderLines.at(numEqualFolders - 1) = FolderLine::Branch; + } else if (noneFound && otherEntry->folderLines.at(numEqualFolders - 1) == FolderSymbols::EndFolder) { + otherEntry->folderLines.at(numEqualFolders - 1) = FolderSymbols::BranchFolder; } else { break; } @@ -162,9 +164,24 @@ std::vector NetworkResourceService::createBrowserData(std } } if (numEqualFolders > 0 && numEqualFolders < prevEntry->folderNames.size() && numEqualFolders == entry->folderNames.size()) { - entry->folderLines.back() = FolderLine::End; + entry->folderLines.back() = FolderSymbols::EndFolder; } } } - return result; + + //collapse items + std::unordered_set expandedFolderStrings; + for(auto const& folderNames : expandedFolderNames) { + expandedFolderStrings.insert(boost::join(folderNames, "/")); + } + + std::vector result; + result.reserve(treeTOs.size()); + for (auto const& entry : treeTOs) { + auto folderString = boost::join(entry->folderNames, "/"); + if (!expandedFolderStrings.contains(folderString)) { + + } + } + return treeTOs; } diff --git a/source/Network/NetworkResourceService.h b/source/Network/NetworkResourceService.h index b9d3c3444..66bed6587 100644 --- a/source/Network/NetworkResourceService.h +++ b/source/Network/NetworkResourceService.h @@ -8,5 +8,7 @@ class NetworkResourceService { public: - static std::vector createBrowserData(std::vector const& browserData); + static std::vector createTreeTOs( + std::vector const& browserData, + std::vector> const& expandedFolderNames); }; diff --git a/source/Network/NetworkResourceTreeTO.h b/source/Network/NetworkResourceTreeTO.h index b12252ebb..9f6975300 100644 --- a/source/Network/NetworkResourceTreeTO.h +++ b/source/Network/NetworkResourceTreeTO.h @@ -27,12 +27,12 @@ struct BrowserLeaf std::string version; }; -enum class FolderLine +enum class FolderSymbols { - Start, - Continue, - Branch, - End, + ExpandedFolder, + ContinueFolder, + BranchFolder, + EndFolder, None }; @@ -40,7 +40,7 @@ struct _NetworkResourceTreeTO { NetworkResourceType type; std::vector folderNames; - std::vector folderLines; + std::vector folderLines; std::variant node; bool isLeaf(); diff --git a/source/NetworkTests/CMakeLists.txt b/source/NetworkTests/CMakeLists.txt index 6267ee9dd..659e2c157 100644 --- a/source/NetworkTests/CMakeLists.txt +++ b/source/NetworkTests/CMakeLists.txt @@ -1,6 +1,6 @@ target_sources(NetworkTests PUBLIC - BrowserDataServiceTests.cpp + NetworkResourceServiceTests.cpp Testsuite.cpp) target_link_libraries(NetworkTests Base) diff --git a/source/NetworkTests/BrowserDataServiceTests.cpp b/source/NetworkTests/NetworkResourceServiceTests.cpp similarity index 87% rename from source/NetworkTests/BrowserDataServiceTests.cpp rename to source/NetworkTests/NetworkResourceServiceTests.cpp index 66d3e534b..2d2fcf05a 100644 --- a/source/NetworkTests/BrowserDataServiceTests.cpp +++ b/source/NetworkTests/NetworkResourceServiceTests.cpp @@ -6,34 +6,34 @@ #include "Network/NetworkResourceTreeTO.h" -class BrowserDataServiceTests : public ::testing::Test +class NetworkResourceServiceTests : public ::testing::Test { public: - BrowserDataServiceTests() + NetworkResourceServiceTests() {} - ~BrowserDataServiceTests() = default; + ~NetworkResourceServiceTests() = default; }; -TEST_F(BrowserDataServiceTests, nameWithoutFolder) +TEST_F(NetworkResourceServiceTests, nameWithoutFolder) { std::vector inputTOs; auto inputTO = std::make_shared<_NetworkResourceRawTO>(); inputTO->simName = "test"; inputTOs.emplace_back(inputTO); - auto outputTOs = NetworkResourceService::createBrowserData(inputTOs); + auto outputTOs = NetworkResourceService::createTreeTOs(inputTOs); ASSERT_EQ(1, outputTOs.size()); } -TEST_F(BrowserDataServiceTests, nameWithFolder) +TEST_F(NetworkResourceServiceTests, nameWithFolder) { std::vector inputTOs; auto inputTO = std::make_shared<_NetworkResourceRawTO>(); inputTO->simName = "folder/test"; inputTOs.emplace_back(inputTO); - auto outputTOs = NetworkResourceService::createBrowserData(inputTOs); + auto outputTOs = NetworkResourceService::createTreeTOs(inputTOs); ASSERT_EQ(2, outputTOs.size()); { @@ -51,14 +51,14 @@ TEST_F(BrowserDataServiceTests, nameWithFolder) } } -TEST_F(BrowserDataServiceTests, nameWithTwoFolders) +TEST_F(NetworkResourceServiceTests, nameWithTwoFolders) { std::vector inputTOs; auto inputTO = std::make_shared<_NetworkResourceRawTO>(); inputTO->simName = "folder1/folder2/test"; inputTOs.emplace_back(inputTO); - auto outputTOs = NetworkResourceService::createBrowserData(inputTOs); + auto outputTOs = NetworkResourceService::createTreeTOs(inputTOs); ASSERT_EQ(3, outputTOs.size()); { @@ -85,7 +85,7 @@ TEST_F(BrowserDataServiceTests, nameWithTwoFolders) } -TEST_F(BrowserDataServiceTests, twoNamesWithTwoFolders) +TEST_F(NetworkResourceServiceTests, twoNamesWithTwoFolders) { std::vector inputTOs; { @@ -99,7 +99,7 @@ TEST_F(BrowserDataServiceTests, twoNamesWithTwoFolders) inputTOs.emplace_back(inputTO); } - auto outputTOs = NetworkResourceService::createBrowserData(inputTOs); + auto outputTOs = NetworkResourceService::createTreeTOs(inputTOs); ASSERT_EQ(6, outputTOs.size()); { From 6093fabc4e880bb10a354c3b50592c56fa45ed9f Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Sat, 23 Dec 2023 08:27:49 +0100 Subject: [PATCH 18/40] code for drawing tree symbols simplified --- source/Gui/BrowserWindow.cpp | 26 +++++++------ source/Network/NetworkResourceService.cpp | 46 +++++++++++------------ source/Network/NetworkResourceTreeTO.h | 12 +++--- 3 files changed, 44 insertions(+), 40 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 8f68fd2f8..e93a12ad2 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -266,22 +266,24 @@ void _BrowserWindow::processToolbar() namespace { - void drawFolderLines(std::vector const& folderLines, int count) + void drawFolderTreeSymbols(std::vector const& folderLines) { ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); - for (auto const& folderLine : folderLines | std::views::take(count)) { + for (auto const& folderLine : folderLines) { ImVec2 pos = ImGui::GetCursorScreenPos(); ImGuiStyle& style = ImGui::GetStyle(); switch (folderLine) { - case FolderSymbols::ExpandedFolder: { + case FolderTreeSymbols::Expanded: { + AlienImGui::Button(ICON_FA_MINUS_SQUARE, 20.0f); } break; - case FolderSymbols::ContinueFolder: { + case FolderTreeSymbols::Continue: { ImGui::GetWindowDrawList()->AddRectFilled( ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) + style.FramePadding.y), Const::BrowserFolderLineColor); + ImGui::Dummy({scale(20.0f), 0}); } break; - case FolderSymbols::BranchFolder: { + case FolderTreeSymbols::Branch: { ImGui::GetWindowDrawList()->AddRectFilled( ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) + style.FramePadding.y), @@ -290,8 +292,9 @@ namespace ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2), ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), Const::BrowserFolderLineColor); + ImGui::Dummy({scale(20.0f), 0}); } break; - case FolderSymbols::EndFolder: { + case FolderTreeSymbols::End: { ImGui::GetWindowDrawList()->AddRectFilled( ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), @@ -300,11 +303,14 @@ namespace ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2), ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), Const::BrowserFolderLineColor); + ImGui::Dummy({scale(20.0f), 0}); + } break; + case FolderTreeSymbols::None: { + ImGui::Dummy({scale(20.0f), 0}); } break; default: { } break; } - ImGui::Dummy({scale(20.0f), 0}); ImGui::SameLine(); } ImGui::PopStyleColor(1); @@ -384,7 +390,7 @@ void _BrowserWindow::processSimulationList() ImGui::TableNextColumn(); processActionButtons(item); ImGui::TableNextColumn(); - drawFolderLines(item->folderLines, item->folderLines.size()); + drawFolderTreeSymbols(item->treeSymbols); processShortenedText(leaf.simName); ImGui::TableNextColumn(); @@ -415,11 +421,9 @@ void _BrowserWindow::processSimulationList() ImGui::TableNextColumn(); ImGui::TableNextColumn(); ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); - drawFolderLines(item->folderLines, item->folderLines.size() - 1); - AlienImGui::Button(ICON_FA_MINUS_SQUARE, 20.0f); + drawFolderTreeSymbols(item->treeSymbols); ImGui::PopStyleColor(1); - ImGui::SameLine(); processShortenedText(item->folderNames.back()); } ImGui::PopID(); diff --git a/source/Network/NetworkResourceService.cpp b/source/Network/NetworkResourceService.cpp index 5e68ecbce..82f8e37fd 100644 --- a/source/Network/NetworkResourceService.cpp +++ b/source/Network/NetworkResourceService.cpp @@ -103,31 +103,31 @@ std::vector NetworkResourceService::createTreeTOs( if (i == 0) { if (!entry->isLeaf()) { - entry->folderLines.emplace_back(FolderSymbols::ExpandedFolder); + entry->treeSymbols.emplace_back(FolderTreeSymbols::Expanded); } } else { auto const& prevEntry = treeTOs.at(i - 1); auto numEqualFolders = getNumEqualFolders(entry->folderNames, prevEntry->folderNames); - entry->folderLines.resize(entry->folderNames.size(), FolderSymbols::None); + entry->treeSymbols.resize(entry->folderNames.size(), FolderTreeSymbols::None); //process until numEqualFolders - 1 if (numEqualFolders > 0) { int f = numEqualFolders - 1; - if (prevEntry->folderLines.at(f) == FolderSymbols::ExpandedFolder) { - entry->folderLines.at(f) = FolderSymbols::EndFolder; - } else if (prevEntry->folderLines.at(f) == FolderSymbols::EndFolder) { - prevEntry->folderLines.at(f) = FolderSymbols::BranchFolder; - entry->folderLines.at(f) = FolderSymbols::EndFolder; - } else if (prevEntry->folderLines.at(f) == FolderSymbols::BranchFolder) { - entry->folderLines.at(f) = FolderSymbols::EndFolder; - } else if (prevEntry->folderLines.at(f) == FolderSymbols::None) { + if (prevEntry->treeSymbols.at(f) == FolderTreeSymbols::Expanded) { + entry->treeSymbols.at(f) = FolderTreeSymbols::End; + } else if (prevEntry->treeSymbols.at(f) == FolderTreeSymbols::End) { + prevEntry->treeSymbols.at(f) = FolderTreeSymbols::Branch; + entry->treeSymbols.at(f) = FolderTreeSymbols::End; + } else if (prevEntry->treeSymbols.at(f) == FolderTreeSymbols::Branch) { + entry->treeSymbols.at(f) = FolderTreeSymbols::End; + } else if (prevEntry->treeSymbols.at(f) == FolderTreeSymbols::None) { for (int j = i - 1; j >= 0; --j) { auto& otherEntry = treeTOs.at(j); - if (otherEntry->folderLines.at(f) == FolderSymbols::None) { - otherEntry->folderLines.at(f) = FolderSymbols::ContinueFolder; - } else if (otherEntry->folderLines.at(f) == FolderSymbols::EndFolder) { - otherEntry->folderLines.at(f) = FolderSymbols::BranchFolder; + if (otherEntry->treeSymbols.at(f) == FolderTreeSymbols::None) { + otherEntry->treeSymbols.at(f) = FolderTreeSymbols::Continue; + } else if (otherEntry->treeSymbols.at(f) == FolderTreeSymbols::End) { + otherEntry->treeSymbols.at(f) = FolderTreeSymbols::Branch; } else { break; } @@ -138,25 +138,25 @@ std::vector NetworkResourceService::createTreeTOs( } for (int f = 0; f < numEqualFolders - 1; ++f) { - if (prevEntry->folderLines.at(f) == FolderSymbols::BranchFolder) { - entry->folderLines.at(f) = FolderSymbols::None; + if (prevEntry->treeSymbols.at(f) == FolderTreeSymbols::Branch) { + entry->treeSymbols.at(f) = FolderTreeSymbols::None; } } if (numEqualFolders < entry->folderNames.size()) { CHECK(numEqualFolders + 1 == entry->folderNames.size()); - entry->folderLines.back() = FolderSymbols::ExpandedFolder; + entry->treeSymbols.back() = FolderTreeSymbols::Expanded; if (numEqualFolders > 0 && numEqualFolders < prevEntry->folderNames.size()) { - entry->folderLines.at(numEqualFolders - 1) = FolderSymbols::EndFolder; + entry->treeSymbols.at(numEqualFolders - 1) = FolderTreeSymbols::End; bool noneFound = false; for (int j = i - 1; j >= 0; --j) { auto& otherEntry = treeTOs.at(j); - if (otherEntry->folderLines.at(numEqualFolders - 1) == FolderSymbols::None) { - otherEntry->folderLines.at(numEqualFolders - 1) = FolderSymbols::ContinueFolder; + if (otherEntry->treeSymbols.at(numEqualFolders - 1) == FolderTreeSymbols::None) { + otherEntry->treeSymbols.at(numEqualFolders - 1) = FolderTreeSymbols::Continue; noneFound = true; - } else if (noneFound && otherEntry->folderLines.at(numEqualFolders - 1) == FolderSymbols::EndFolder) { - otherEntry->folderLines.at(numEqualFolders - 1) = FolderSymbols::BranchFolder; + } else if (noneFound && otherEntry->treeSymbols.at(numEqualFolders - 1) == FolderTreeSymbols::End) { + otherEntry->treeSymbols.at(numEqualFolders - 1) = FolderTreeSymbols::Branch; } else { break; } @@ -164,7 +164,7 @@ std::vector NetworkResourceService::createTreeTOs( } } if (numEqualFolders > 0 && numEqualFolders < prevEntry->folderNames.size() && numEqualFolders == entry->folderNames.size()) { - entry->folderLines.back() = FolderSymbols::EndFolder; + entry->treeSymbols.back() = FolderTreeSymbols::End; } } } diff --git a/source/Network/NetworkResourceTreeTO.h b/source/Network/NetworkResourceTreeTO.h index 9f6975300..ff121d676 100644 --- a/source/Network/NetworkResourceTreeTO.h +++ b/source/Network/NetworkResourceTreeTO.h @@ -27,12 +27,12 @@ struct BrowserLeaf std::string version; }; -enum class FolderSymbols +enum class FolderTreeSymbols { - ExpandedFolder, - ContinueFolder, - BranchFolder, - EndFolder, + Expanded, + Continue, + Branch, + End, None }; @@ -40,7 +40,7 @@ struct _NetworkResourceTreeTO { NetworkResourceType type; std::vector folderNames; - std::vector folderLines; + std::vector treeSymbols; std::variant node; bool isLeaf(); From 49e0914684e5b496d519427fd0a40e28d7378c07 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Sat, 23 Dec 2023 09:01:07 +0100 Subject: [PATCH 19/40] allow expanding/collapsing folder nodes --- source/Gui/BrowserWindow.cpp | 117 ++++++++++++---------- source/Gui/BrowserWindow.h | 5 +- source/Network/NetworkResourceService.cpp | 42 ++++++-- source/Network/NetworkResourceService.h | 2 +- source/Network/NetworkResourceTreeTO.h | 1 + 5 files changed, 102 insertions(+), 65 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index e93a12ad2..ef5c93487 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -264,59 +264,6 @@ void _BrowserWindow::processToolbar() AlienImGui::Separator(); } -namespace -{ - void drawFolderTreeSymbols(std::vector const& folderLines) - { - ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); - for (auto const& folderLine : folderLines) { - ImVec2 pos = ImGui::GetCursorScreenPos(); - ImGuiStyle& style = ImGui::GetStyle(); - switch (folderLine) { - case FolderTreeSymbols::Expanded: { - AlienImGui::Button(ICON_FA_MINUS_SQUARE, 20.0f); - } break; - case FolderTreeSymbols::Continue: { - ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), - ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) + style.FramePadding.y), - Const::BrowserFolderLineColor); - ImGui::Dummy({scale(20.0f), 0}); - } break; - case FolderTreeSymbols::Branch: { - ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), - ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) + style.FramePadding.y), - Const::BrowserFolderLineColor); - ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2), - ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), - Const::BrowserFolderLineColor); - ImGui::Dummy({scale(20.0f), 0}); - } break; - case FolderTreeSymbols::End: { - ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), - ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), - Const::BrowserFolderLineColor); - ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2), - ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), - Const::BrowserFolderLineColor); - ImGui::Dummy({scale(20.0f), 0}); - } break; - case FolderTreeSymbols::None: { - ImGui::Dummy({scale(20.0f), 0}); - } break; - default: { - } break; - } - ImGui::SameLine(); - } - ImGui::PopStyleColor(1); - } -} - void _BrowserWindow::processSimulationList() { ImGui::PushID("SimulationList"); @@ -390,7 +337,7 @@ void _BrowserWindow::processSimulationList() ImGui::TableNextColumn(); processActionButtons(item); ImGui::TableNextColumn(); - drawFolderTreeSymbols(item->treeSymbols); + drawFolderTreeSymbols(item); processShortenedText(leaf.simName); ImGui::TableNextColumn(); @@ -421,7 +368,7 @@ void _BrowserWindow::processSimulationList() ImGui::TableNextColumn(); ImGui::TableNextColumn(); ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); - drawFolderTreeSymbols(item->treeSymbols); + drawFolderTreeSymbols(item); ImGui::PopStyleColor(1); processShortenedText(item->folderNames.back()); @@ -1103,3 +1050,63 @@ void _BrowserWindow::calcFilteredSimulationAndGenomeLists() } } } + +void _BrowserWindow::drawFolderTreeSymbols(NetworkResourceTreeTO& entry) +{ + auto const& treeSymbols = entry->treeSymbols; + ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); + for (auto const& folderLine : treeSymbols) { + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImGuiStyle& style = ImGui::GetStyle(); + switch (folderLine) { + case FolderTreeSymbols::Collapsed: { + if (AlienImGui::Button(ICON_FA_PLUS_SQUARE, 20.0f)) { + _expandedFolderNames.emplace(entry->folderNames); + _scheduleCreateBrowserData = true; + } + } break; + case FolderTreeSymbols::Expanded: { + if (AlienImGui::Button(ICON_FA_MINUS_SQUARE, 20.0f)) { + _expandedFolderNames.erase(entry->folderNames); + _scheduleCreateBrowserData = true; + } + } break; + case FolderTreeSymbols::Continue: { + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) + style.FramePadding.y), + Const::BrowserFolderLineColor); + ImGui::Dummy({scale(20.0f), 0}); + } break; + case FolderTreeSymbols::Branch: { + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) + style.FramePadding.y), + Const::BrowserFolderLineColor); + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2), + ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), + Const::BrowserFolderLineColor); + ImGui::Dummy({scale(20.0f), 0}); + } break; + case FolderTreeSymbols::End: { + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), + Const::BrowserFolderLineColor); + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2), + ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), + Const::BrowserFolderLineColor); + ImGui::Dummy({scale(20.0f), 0}); + } break; + case FolderTreeSymbols::None: { + ImGui::Dummy({scale(20.0f), 0}); + } break; + default: { + } break; + } + ImGui::SameLine(); + } + ImGui::PopStyleColor(1); +} diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index 9ecad46c7..9d301613b 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -66,6 +66,9 @@ class _BrowserWindow : public _AlienWindow void pushTextColor(NetworkResourceTreeTO const& to); void calcFilteredSimulationAndGenomeLists(); + void drawFolderTreeSymbols(NetworkResourceTreeTO& entry); + + NetworkResourceType _selectedDataType = NetworkResourceType_Simulation; bool _scheduleRefresh = false; bool _scheduleCreateBrowserData = false; @@ -81,7 +84,7 @@ class _BrowserWindow : public _AlienWindow std::vector _rawNetworkResourceRawTOs; std::vector _filteredNetworkSimulationTOs; std::vector _filteredNetworkGenomeTOs; - std::vector> _expandedFolderNames; + std::set> _expandedFolderNames; std::vector _simulationTreeTOs; std::vector _genomeTreeTOs; diff --git a/source/Network/NetworkResourceService.cpp b/source/Network/NetworkResourceService.cpp index 82f8e37fd..ec0caf3c5 100644 --- a/source/Network/NetworkResourceService.cpp +++ b/source/Network/NetworkResourceService.cpp @@ -1,5 +1,7 @@ #include "NetworkResourceService.h" +#include + #include #include @@ -24,7 +26,7 @@ namespace std::vector NetworkResourceService::createTreeTOs( std::vector const& networkTOs, - std::vector> const& expandedFolderNames) + std::set> const& expandedFolderNames) { std::list treeToList; for (auto const& entry : networkTOs) { @@ -103,7 +105,7 @@ std::vector NetworkResourceService::createTreeTOs( if (i == 0) { if (!entry->isLeaf()) { - entry->treeSymbols.emplace_back(FolderTreeSymbols::Expanded); + entry->treeSymbols.emplace_back(FolderTreeSymbols::Collapsed); } } else { auto const& prevEntry = treeTOs.at(i - 1); @@ -114,7 +116,7 @@ std::vector NetworkResourceService::createTreeTOs( //process until numEqualFolders - 1 if (numEqualFolders > 0) { int f = numEqualFolders - 1; - if (prevEntry->treeSymbols.at(f) == FolderTreeSymbols::Expanded) { + if (prevEntry->treeSymbols.at(f) == FolderTreeSymbols::Collapsed) { entry->treeSymbols.at(f) = FolderTreeSymbols::End; } else if (prevEntry->treeSymbols.at(f) == FolderTreeSymbols::End) { prevEntry->treeSymbols.at(f) = FolderTreeSymbols::Branch; @@ -145,7 +147,7 @@ std::vector NetworkResourceService::createTreeTOs( if (numEqualFolders < entry->folderNames.size()) { CHECK(numEqualFolders + 1 == entry->folderNames.size()); - entry->treeSymbols.back() = FolderTreeSymbols::Expanded; + entry->treeSymbols.back() = FolderTreeSymbols::Collapsed; if (numEqualFolders > 0 && numEqualFolders < prevEntry->folderNames.size()) { entry->treeSymbols.at(numEqualFolders - 1) = FolderTreeSymbols::End; @@ -178,10 +180,34 @@ std::vector NetworkResourceService::createTreeTOs( std::vector result; result.reserve(treeTOs.size()); for (auto const& entry : treeTOs) { - auto folderString = boost::join(entry->folderNames, "/"); - if (!expandedFolderStrings.contains(folderString)) { - + auto isVisible = false; + if (entry->isLeaf()) { + if (entry->folderNames.empty()) { + isVisible = true; + } + auto folderString = boost::join(entry->folderNames, "/"); + if (expandedFolderStrings.contains(folderString)) { + isVisible = true; + } + } else { + auto size = entry->folderNames.size(); + if (size == 1) { + isVisible = true; + } + if (size > 1) { + auto folderString = boost::join(std::vector(entry->folderNames.begin(), entry->folderNames.end() - 1), "/"); + if (expandedFolderStrings.contains(folderString)) { + isVisible = true; + } + } + auto folderString = boost::join(entry->folderNames, "/"); + if (expandedFolderStrings.contains(folderString)) { + entry->treeSymbols.back() = FolderTreeSymbols::Expanded; + } + } + if (isVisible) { + result.emplace_back(entry); } } - return treeTOs; + return result; } diff --git a/source/Network/NetworkResourceService.h b/source/Network/NetworkResourceService.h index 66bed6587..8c0b41fe7 100644 --- a/source/Network/NetworkResourceService.h +++ b/source/Network/NetworkResourceService.h @@ -10,5 +10,5 @@ class NetworkResourceService public: static std::vector createTreeTOs( std::vector const& browserData, - std::vector> const& expandedFolderNames); + std::set> const& expandedFolderNames); }; diff --git a/source/Network/NetworkResourceTreeTO.h b/source/Network/NetworkResourceTreeTO.h index ff121d676..7df2f7cfd 100644 --- a/source/Network/NetworkResourceTreeTO.h +++ b/source/Network/NetworkResourceTreeTO.h @@ -29,6 +29,7 @@ struct BrowserLeaf enum class FolderTreeSymbols { + Collapsed, Expanded, Continue, Branch, From b9e3c6a9649e00823bcb0a1e2759ed5764dd6f77 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Sat, 23 Dec 2023 09:14:08 +0100 Subject: [PATCH 20/40] collapsing tree nodes corrected --- source/Gui/BrowserWindow.cpp | 27 ++++++++++++++++++----- source/Gui/BrowserWindow.h | 4 ++-- source/Network/NetworkResourceService.cpp | 2 +- source/Network/NetworkResourceService.h | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index ef5c93487..4ba562320 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -337,7 +337,7 @@ void _BrowserWindow::processSimulationList() ImGui::TableNextColumn(); processActionButtons(item); ImGui::TableNextColumn(); - drawFolderTreeSymbols(item); + processFolderTreeSymbols(item); processShortenedText(leaf.simName); ImGui::TableNextColumn(); @@ -368,7 +368,7 @@ void _BrowserWindow::processSimulationList() ImGui::TableNextColumn(); ImGui::TableNextColumn(); ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); - drawFolderTreeSymbols(item); + processFolderTreeSymbols(item); ImGui::PopStyleColor(1); processShortenedText(item->folderNames.back()); @@ -1051,7 +1051,7 @@ void _BrowserWindow::calcFilteredSimulationAndGenomeLists() } } -void _BrowserWindow::drawFolderTreeSymbols(NetworkResourceTreeTO& entry) +void _BrowserWindow::processFolderTreeSymbols(NetworkResourceTreeTO& entry) { auto const& treeSymbols = entry->treeSymbols; ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); @@ -1061,13 +1061,30 @@ void _BrowserWindow::drawFolderTreeSymbols(NetworkResourceTreeTO& entry) switch (folderLine) { case FolderTreeSymbols::Collapsed: { if (AlienImGui::Button(ICON_FA_PLUS_SQUARE, 20.0f)) { - _expandedFolderNames.emplace(entry->folderNames); + _expandedFolderNames.emplace_back(entry->folderNames); _scheduleCreateBrowserData = true; } } break; case FolderTreeSymbols::Expanded: { if (AlienImGui::Button(ICON_FA_MINUS_SQUARE, 20.0f)) { - _expandedFolderNames.erase(entry->folderNames); + std::vector> newExpandedFolderNames; + auto const& folderNamesToCollapse = entry->folderNames; + for (auto const& expandedFolderNames : _expandedFolderNames) { + auto adopt = false; + if (expandedFolderNames.size() < folderNamesToCollapse.size()) { + adopt = true; + } else { + for (int i = 0; i < folderNamesToCollapse.size(); ++i) { + if (expandedFolderNames.at(i) != folderNamesToCollapse.at(i)) { + adopt = true; + } + } + } + if (adopt) { + newExpandedFolderNames.emplace_back(expandedFolderNames); + } + } + _expandedFolderNames = newExpandedFolderNames; _scheduleCreateBrowserData = true; } } break; diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index 9d301613b..21b704d18 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -66,7 +66,7 @@ class _BrowserWindow : public _AlienWindow void pushTextColor(NetworkResourceTreeTO const& to); void calcFilteredSimulationAndGenomeLists(); - void drawFolderTreeSymbols(NetworkResourceTreeTO& entry); + void processFolderTreeSymbols(NetworkResourceTreeTO& entry); NetworkResourceType _selectedDataType = NetworkResourceType_Simulation; @@ -84,7 +84,7 @@ class _BrowserWindow : public _AlienWindow std::vector _rawNetworkResourceRawTOs; std::vector _filteredNetworkSimulationTOs; std::vector _filteredNetworkGenomeTOs; - std::set> _expandedFolderNames; + std::vector> _expandedFolderNames; std::vector _simulationTreeTOs; std::vector _genomeTreeTOs; diff --git a/source/Network/NetworkResourceService.cpp b/source/Network/NetworkResourceService.cpp index ec0caf3c5..1f60c050e 100644 --- a/source/Network/NetworkResourceService.cpp +++ b/source/Network/NetworkResourceService.cpp @@ -26,7 +26,7 @@ namespace std::vector NetworkResourceService::createTreeTOs( std::vector const& networkTOs, - std::set> const& expandedFolderNames) + std::vector> const& expandedFolderNames) { std::list treeToList; for (auto const& entry : networkTOs) { diff --git a/source/Network/NetworkResourceService.h b/source/Network/NetworkResourceService.h index 8c0b41fe7..66bed6587 100644 --- a/source/Network/NetworkResourceService.h +++ b/source/Network/NetworkResourceService.h @@ -10,5 +10,5 @@ class NetworkResourceService public: static std::vector createTreeTOs( std::vector const& browserData, - std::set> const& expandedFolderNames); + std::vector> const& expandedFolderNames); }; From 14eafcb597305cc97e3a7c6350bc415aba93c6a9 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Sun, 24 Dec 2023 10:25:33 +0100 Subject: [PATCH 21/40] new layout tests --- source/Gui/BrowserWindow.cpp | 89 ++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 4ba562320..823485576 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -275,15 +275,19 @@ void _BrowserWindow::processSimulationList() if (ImGui::BeginTable("Browser", 12, flags, ImVec2(0, 0), 0.0f)) { ImGui::TableSetupColumn( - "Actions", - ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, - scale(90.0f), - NetworkResourceColumnId_Actions); - ImGui::TableSetupColumn( - "Simulation folder/name", + "Simulation", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(190.0f), NetworkResourceColumnId_SimulationName); + ImGui::TableSetupColumn( + "Description", + ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, + styleRepository.scale(120.0f), + NetworkResourceColumnId_Description); + ImGui::TableSetupColumn( + "Reactions", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), NetworkResourceColumnId_Likes); + //ImGui::TableSetupColumn( + // "Actions", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, scale(90.0f), NetworkResourceColumnId_Actions); ImGui::TableSetupColumn( "Timestamp", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_PreferSortDescending, @@ -294,16 +298,6 @@ void _BrowserWindow::processSimulationList() ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), NetworkResourceColumnId_UserName); - ImGui::TableSetupColumn( - "Description", - ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, - styleRepository.scale(120.0f), - NetworkResourceColumnId_Description); - ImGui::TableSetupColumn( - "Reactions", - ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, - styleRepository.scale(120.0f), - NetworkResourceColumnId_Likes); ImGui::TableSetupColumn("Downloads", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_NumDownloads); ImGui::TableSetupColumn("Width", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Width); ImGui::TableSetupColumn("Height", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Height); @@ -335,20 +329,29 @@ void _BrowserWindow::processSimulationList() if (item->isLeaf()) { auto& leaf = item->getLeaf(); ImGui::TableNextColumn(); - processActionButtons(item); - ImGui::TableNextColumn(); processFolderTreeSymbols(item); + ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DownloadButtonTextColor); + auto downloadButtonResult = processActionButton(ICON_FA_DOWNLOAD); + ImGui::PopStyleColor(); + if (downloadButtonResult) { + onDownloadItem(leaf); + } + AlienImGui::Tooltip("Download"); + ImGui::SameLine(); + processShortenedText(leaf.simName); ImGui::TableNextColumn(); + processShortenedText(leaf.description); + ImGui::TableNextColumn(); + processEmojiList(item); + //ImGui::TableNextColumn(); + //processActionButtons(item); + ImGui::TableNextColumn(); pushTextColor(item); AlienImGui::Text(leaf.timestamp); ImGui::TableNextColumn(); processShortenedText(leaf.userName); - ImGui::TableNextColumn(); - processShortenedText(leaf.description); - ImGui::TableNextColumn(); - processEmojiList(item); ImGui::TableNextColumn(); AlienImGui::Text(std::to_string(leaf.numDownloads)); @@ -365,7 +368,6 @@ void _BrowserWindow::processSimulationList() ImGui::PopStyleColor(); } else { - ImGui::TableNextColumn(); ImGui::TableNextColumn(); ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); processFolderTreeSymbols(item); @@ -391,12 +393,19 @@ void _BrowserWindow::processGenomeList() if (ImGui::BeginTable("Browser", 10, flags, ImVec2(0, 0), 0.0f)) { ImGui::TableSetupColumn( - "Actions", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, scale(90.0f), NetworkResourceColumnId_Actions); - ImGui::TableSetupColumn( - "Genome name", + "Genome", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(160.0f), NetworkResourceColumnId_SimulationName); + ImGui::TableSetupColumn( + "Description", + ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, + styleRepository.scale(120.0f), + NetworkResourceColumnId_Description); + ImGui::TableSetupColumn( + "Reactions", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), NetworkResourceColumnId_Likes); + //ImGui::TableSetupColumn( + // "Actions", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, scale(90.0f), NetworkResourceColumnId_Actions); ImGui::TableSetupColumn( "Timestamp", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_PreferSortDescending, @@ -407,16 +416,6 @@ void _BrowserWindow::processGenomeList() ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), NetworkResourceColumnId_UserName); - ImGui::TableSetupColumn( - "Description", - ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, - styleRepository.scale(120.0f), - NetworkResourceColumnId_Description); - ImGui::TableSetupColumn( - "Reactions", - ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, - styleRepository.scale(120.0f), - NetworkResourceColumnId_Likes); ImGui::TableSetupColumn( "Downloads", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_NumDownloads); ImGui::TableSetupColumn("Cells", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Particles); @@ -444,24 +443,26 @@ void _BrowserWindow::processGenomeList() ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); - if (item->isLeaf()) { auto& leaf = item->getLeaf(); ImGui::TableNextColumn(); - processActionButtons(item); - ImGui::TableNextColumn(); + ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap; + static bool selected = true; + ImGui::Selectable("", &selected, selectable_flags, ImVec2(0, 22.0f)); + ImGui::SameLine(); processShortenedText(leaf.simName); ImGui::TableNextColumn(); + processShortenedText(leaf.description); + ImGui::TableNextColumn(); + processEmojiList(item); + //ImGui::TableNextColumn(); + //processActionButtons(item); + ImGui::TableNextColumn(); pushTextColor(item); AlienImGui::Text(leaf.timestamp); ImGui::TableNextColumn(); processShortenedText(leaf.userName); - ImGui::TableNextColumn(); - processShortenedText(leaf.description); - ImGui::TableNextColumn(); - processEmojiList(item); - ImGui::TableNextColumn(); AlienImGui::Text(std::to_string(leaf.numDownloads)); ImGui::TableNextColumn(); From 90fb240b47e087a334db0f324cb1ef1b4522a466 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Mon, 25 Dec 2023 09:56:11 +0100 Subject: [PATCH 22/40] selection of tree entries in browser [test] --- source/Gui/BrowserWindow.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 823485576..1ac9b438a 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -326,9 +326,15 @@ void _BrowserWindow::processSimulationList() ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); + ImGui::TableNextColumn(); + ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap; + static bool selected = true; + ImGui::Selectable("", &selected, selectable_flags, ImVec2(0, scale(RowHeight - 3.0f))); + ImGui::SameLine(); + if (item->isLeaf()) { auto& leaf = item->getLeaf(); - ImGui::TableNextColumn(); + processFolderTreeSymbols(item); ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DownloadButtonTextColor); @@ -368,7 +374,6 @@ void _BrowserWindow::processSimulationList() ImGui::PopStyleColor(); } else { - ImGui::TableNextColumn(); ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); processFolderTreeSymbols(item); ImGui::PopStyleColor(1); @@ -447,10 +452,6 @@ void _BrowserWindow::processGenomeList() auto& leaf = item->getLeaf(); ImGui::TableNextColumn(); - ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap; - static bool selected = true; - ImGui::Selectable("", &selected, selectable_flags, ImVec2(0, 22.0f)); - ImGui::SameLine(); processShortenedText(leaf.simName); ImGui::TableNextColumn(); processShortenedText(leaf.description); From 068a60a1044ad92564420face34fc9b2f37ef686 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Thu, 28 Dec 2023 09:34:39 +0100 Subject: [PATCH 23/40] collapsing/expanding nodes fixed --- source/Gui/BrowserWindow.cpp | 59 ++++++++++++----------- source/Gui/BrowserWindow.h | 2 +- source/Network/NetworkResourceService.cpp | 52 +++++++++----------- source/Network/NetworkResourceService.h | 2 +- 4 files changed, 56 insertions(+), 59 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 1ac9b438a..5358f5897 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -314,7 +314,7 @@ void _BrowserWindow::processSimulationList() sortSpecs->SpecsDirty = false; _scheduleCreateBrowserData = false; - _simulationTreeTOs = NetworkResourceService::createTreeTOs(_filteredNetworkSimulationTOs, _expandedFolderNames); + _simulationTreeTOs = NetworkResourceService::createTreeTOs(_filteredNetworkSimulationTOs, _collapsedFolderNames); } } ImGuiListClipper clipper; @@ -327,10 +327,10 @@ void _BrowserWindow::processSimulationList() ImGui::TableNextRow(0, scale(RowHeight)); ImGui::TableNextColumn(); - ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap; - static bool selected = true; - ImGui::Selectable("", &selected, selectable_flags, ImVec2(0, scale(RowHeight - 3.0f))); - ImGui::SameLine(); + //ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap; + //static bool selected = true; + //ImGui::Selectable("", &selected, selectable_flags, ImVec2(0, scale(RowHeight - 3.0f))); + //ImGui::SameLine(); if (item->isLeaf()) { auto& leaf = item->getLeaf(); @@ -436,7 +436,7 @@ void _BrowserWindow::processGenomeList() sortSpecs->SpecsDirty = false; _scheduleCreateBrowserData = false; - _genomeTreeTOs = NetworkResourceService::createTreeTOs(_filteredNetworkGenomeTOs, _expandedFolderNames); + _genomeTreeTOs = NetworkResourceService::createTreeTOs(_filteredNetworkGenomeTOs, _collapsedFolderNames); } } ImGuiListClipper clipper; @@ -1061,32 +1061,33 @@ void _BrowserWindow::processFolderTreeSymbols(NetworkResourceTreeTO& entry) ImVec2 pos = ImGui::GetCursorScreenPos(); ImGuiStyle& style = ImGui::GetStyle(); switch (folderLine) { - case FolderTreeSymbols::Collapsed: { - if (AlienImGui::Button(ICON_FA_PLUS_SQUARE, 20.0f)) { - _expandedFolderNames.emplace_back(entry->folderNames); + case FolderTreeSymbols::Expanded: { + if (AlienImGui::Button(ICON_FA_MINUS_SQUARE, 20.0f)) { + _collapsedFolderNames.insert(entry->folderNames); _scheduleCreateBrowserData = true; } } break; - case FolderTreeSymbols::Expanded: { - if (AlienImGui::Button(ICON_FA_MINUS_SQUARE, 20.0f)) { - std::vector> newExpandedFolderNames; - auto const& folderNamesToCollapse = entry->folderNames; - for (auto const& expandedFolderNames : _expandedFolderNames) { - auto adopt = false; - if (expandedFolderNames.size() < folderNamesToCollapse.size()) { - adopt = true; - } else { - for (int i = 0; i < folderNamesToCollapse.size(); ++i) { - if (expandedFolderNames.at(i) != folderNamesToCollapse.at(i)) { - adopt = true; - } - } - } - if (adopt) { - newExpandedFolderNames.emplace_back(expandedFolderNames); - } - } - _expandedFolderNames = newExpandedFolderNames; + case FolderTreeSymbols::Collapsed: { + if (AlienImGui::Button(ICON_FA_PLUS_SQUARE, 20.0f)) { + _collapsedFolderNames.erase(entry->folderNames); + //std::vector> newExpandedFolderNames; + //auto const& folderNamesToCollapse = entry->folderNames; + //for (auto const& expandedFolderNames : _collapsedFolderNames) { + // auto adopt = false; + // if (expandedFolderNames.size() < folderNamesToCollapse.size()) { + // adopt = true; + // } else { + // for (int i = 0; i < folderNamesToCollapse.size(); ++i) { + // if (expandedFolderNames.at(i) != folderNamesToCollapse.at(i)) { + // adopt = true; + // } + // } + // } + // if (adopt) { + // newExpandedFolderNames.emplace_back(expandedFolderNames); + // } + //} + //_collapsedFolderNames = newExpandedFolderNames; _scheduleCreateBrowserData = true; } } break; diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index 21b704d18..cd1d80d0b 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -84,7 +84,7 @@ class _BrowserWindow : public _AlienWindow std::vector _rawNetworkResourceRawTOs; std::vector _filteredNetworkSimulationTOs; std::vector _filteredNetworkGenomeTOs; - std::vector> _expandedFolderNames; + std::set> _collapsedFolderNames; std::vector _simulationTreeTOs; std::vector _genomeTreeTOs; diff --git a/source/Network/NetworkResourceService.cpp b/source/Network/NetworkResourceService.cpp index 1f60c050e..c12c87a54 100644 --- a/source/Network/NetworkResourceService.cpp +++ b/source/Network/NetworkResourceService.cpp @@ -26,7 +26,7 @@ namespace std::vector NetworkResourceService::createTreeTOs( std::vector const& networkTOs, - std::vector> const& expandedFolderNames) + std::set> const& collapsedFolderNames) { std::list treeToList; for (auto const& entry : networkTOs) { @@ -105,7 +105,7 @@ std::vector NetworkResourceService::createTreeTOs( if (i == 0) { if (!entry->isLeaf()) { - entry->treeSymbols.emplace_back(FolderTreeSymbols::Collapsed); + entry->treeSymbols.emplace_back(FolderTreeSymbols::Expanded); } } else { auto const& prevEntry = treeTOs.at(i - 1); @@ -113,10 +113,10 @@ std::vector NetworkResourceService::createTreeTOs( entry->treeSymbols.resize(entry->folderNames.size(), FolderTreeSymbols::None); - //process until numEqualFolders - 1 + //calc symbols at position numEqualFolders - 1 if (numEqualFolders > 0) { int f = numEqualFolders - 1; - if (prevEntry->treeSymbols.at(f) == FolderTreeSymbols::Collapsed) { + if (prevEntry->treeSymbols.at(f) == FolderTreeSymbols::Expanded) { entry->treeSymbols.at(f) = FolderTreeSymbols::End; } else if (prevEntry->treeSymbols.at(f) == FolderTreeSymbols::End) { prevEntry->treeSymbols.at(f) = FolderTreeSymbols::Branch; @@ -139,6 +139,7 @@ std::vector NetworkResourceService::createTreeTOs( } + //calc symbols before position numEqualFolders - 1 for (int f = 0; f < numEqualFolders - 1; ++f) { if (prevEntry->treeSymbols.at(f) == FolderTreeSymbols::Branch) { entry->treeSymbols.at(f) = FolderTreeSymbols::None; @@ -147,7 +148,7 @@ std::vector NetworkResourceService::createTreeTOs( if (numEqualFolders < entry->folderNames.size()) { CHECK(numEqualFolders + 1 == entry->folderNames.size()); - entry->treeSymbols.back() = FolderTreeSymbols::Collapsed; + entry->treeSymbols.back() = FolderTreeSymbols::Expanded; if (numEqualFolders > 0 && numEqualFolders < prevEntry->folderNames.size()) { entry->treeSymbols.at(numEqualFolders - 1) = FolderTreeSymbols::End; @@ -172,37 +173,32 @@ std::vector NetworkResourceService::createTreeTOs( } //collapse items - std::unordered_set expandedFolderStrings; - for(auto const& folderNames : expandedFolderNames) { - expandedFolderStrings.insert(boost::join(folderNames, "/")); + std::unordered_set collapsedFolderStrings; + for(auto const& folderNames : collapsedFolderNames) { + collapsedFolderStrings.insert(boost::join(folderNames, "/")); } std::vector result; result.reserve(treeTOs.size()); for (auto const& entry : treeTOs) { - auto isVisible = false; - if (entry->isLeaf()) { - if (entry->folderNames.empty()) { - isVisible = true; - } - auto folderString = boost::join(entry->folderNames, "/"); - if (expandedFolderStrings.contains(folderString)) { - isVisible = true; + auto isVisible = true; + + std::string folderString; + auto numSolderToCheck = entry->isLeaf() ? entry->folderNames.size() : entry->folderNames.size() - 1; + for (size_t i = 0; i < numSolderToCheck; ++i) { + folderString.append(entry->folderNames.at(i)); + if (collapsedFolderStrings.contains(folderString)) { + isVisible = false; } - } else { - auto size = entry->folderNames.size(); - if (size == 1) { - isVisible = true; - } - if (size > 1) { - auto folderString = boost::join(std::vector(entry->folderNames.begin(), entry->folderNames.end() - 1), "/"); - if (expandedFolderStrings.contains(folderString)) { - isVisible = true; - } + if (i < numSolderToCheck) { + folderString.append("/"); } + } + + if (!entry->isLeaf()) { auto folderString = boost::join(entry->folderNames, "/"); - if (expandedFolderStrings.contains(folderString)) { - entry->treeSymbols.back() = FolderTreeSymbols::Expanded; + if (collapsedFolderStrings.contains(folderString)) { + entry->treeSymbols.back() = FolderTreeSymbols::Collapsed; } } if (isVisible) { diff --git a/source/Network/NetworkResourceService.h b/source/Network/NetworkResourceService.h index 66bed6587..0f11e009c 100644 --- a/source/Network/NetworkResourceService.h +++ b/source/Network/NetworkResourceService.h @@ -10,5 +10,5 @@ class NetworkResourceService public: static std::vector createTreeTOs( std::vector const& browserData, - std::vector> const& expandedFolderNames); + std::set> const& collapsedFolderNames); }; From 28475f83ec4638bbcab33170f54d4a37f8f5851d Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Thu, 28 Dec 2023 09:56:17 +0100 Subject: [PATCH 24/40] displaying number of simulations for each folder --- source/Gui/BrowserWindow.cpp | 6 ++++++ source/Network/Definitions.h | 6 +++--- source/Network/NetworkResourceService.cpp | 17 +++++++++++++++++ source/Network/NetworkResourceTreeTO.h | 1 + 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 5358f5897..eababfbd9 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -374,11 +374,17 @@ void _BrowserWindow::processSimulationList() ImGui::PopStyleColor(); } else { + auto& folder = item->getFolder(); + ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); processFolderTreeSymbols(item); ImGui::PopStyleColor(1); processShortenedText(item->folderNames.back()); + ImGui::SameLine(); + ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)ImColor::HSV(0.0f, 0.0f, 0.5f, 1.0f)); + AlienImGui::Text("(" + std::to_string(folder.numLeafs) + ")"); + ImGui::PopStyleColor(); } ImGui::PopID(); } diff --git a/source/Network/Definitions.h b/source/Network/Definitions.h index 706cc3e8d..17ff974c3 100644 --- a/source/Network/Definitions.h +++ b/source/Network/Definitions.h @@ -12,8 +12,8 @@ enum NetworkResourceType_ }; -struct _NetworkResourceTreeTO; -using NetworkResourceTreeTO = std::shared_ptr<_NetworkResourceTreeTO>; - struct _NetworkResourceRawTO; using NetworkResourceRawTO = std::shared_ptr<_NetworkResourceRawTO>; + +struct _NetworkResourceTreeTO; +using NetworkResourceTreeTO = std::shared_ptr<_NetworkResourceTreeTO>; diff --git a/source/Network/NetworkResourceService.cpp b/source/Network/NetworkResourceService.cpp index c12c87a54..c9cff462b 100644 --- a/source/Network/NetworkResourceService.cpp +++ b/source/Network/NetworkResourceService.cpp @@ -172,6 +172,23 @@ std::vector NetworkResourceService::createTreeTOs( } } + //calc numLeafs for folders + for (int i = toInt(treeTOs.size()) - 1; i > 0; --i) { + auto& entry = treeTOs.at(i); + if (entry->isLeaf()) { + for (int j = i - 1; j >= 0; --j) { + auto& otherEntry = treeTOs.at(j); + auto numEqualFolders = getNumEqualFolders(entry->folderNames, otherEntry->folderNames); + if (numEqualFolders == 0) { + break; + } + if (numEqualFolders == otherEntry->folderNames.size() && !otherEntry->isLeaf()) { + ++otherEntry->getFolder().numLeafs; + } + } + } + } + //collapse items std::unordered_set collapsedFolderStrings; for(auto const& folderNames : collapsedFolderNames) { diff --git a/source/Network/NetworkResourceTreeTO.h b/source/Network/NetworkResourceTreeTO.h index 7df2f7cfd..18c6a44e0 100644 --- a/source/Network/NetworkResourceTreeTO.h +++ b/source/Network/NetworkResourceTreeTO.h @@ -9,6 +9,7 @@ struct BrowserFolder { + int numLeafs; }; struct BrowserLeaf From f12708bcf4d9c7789d2a8b6c8aebb08a3ec8627f Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Thu, 28 Dec 2023 10:10:40 +0100 Subject: [PATCH 25/40] better symbol for folder branches + code cleaned --- source/Gui/BrowserWindow.cpp | 38 +++++++++++++----------------------- source/Gui/StyleRepository.h | 1 + 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index eababfbd9..26c780a5d 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -382,7 +382,7 @@ void _BrowserWindow::processSimulationList() processShortenedText(item->folderNames.back()); ImGui::SameLine(); - ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)ImColor::HSV(0.0f, 0.0f, 0.5f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserFolderNumSimsColor); AlienImGui::Text("(" + std::to_string(folder.numLeafs) + ")"); ImGui::PopStyleColor(); } @@ -1076,24 +1076,6 @@ void _BrowserWindow::processFolderTreeSymbols(NetworkResourceTreeTO& entry) case FolderTreeSymbols::Collapsed: { if (AlienImGui::Button(ICON_FA_PLUS_SQUARE, 20.0f)) { _collapsedFolderNames.erase(entry->folderNames); - //std::vector> newExpandedFolderNames; - //auto const& folderNamesToCollapse = entry->folderNames; - //for (auto const& expandedFolderNames : _collapsedFolderNames) { - // auto adopt = false; - // if (expandedFolderNames.size() < folderNamesToCollapse.size()) { - // adopt = true; - // } else { - // for (int i = 0; i < folderNamesToCollapse.size(); ++i) { - // if (expandedFolderNames.at(i) != folderNamesToCollapse.at(i)) { - // adopt = true; - // } - // } - // } - // if (adopt) { - // newExpandedFolderNames.emplace_back(expandedFolderNames); - // } - //} - //_collapsedFolderNames = newExpandedFolderNames; _scheduleCreateBrowserData = true; } } break; @@ -1110,19 +1092,27 @@ void _BrowserWindow::processFolderTreeSymbols(NetworkResourceTreeTO& entry) ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) + style.FramePadding.y), Const::BrowserFolderLineColor); ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2), - ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y), + ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y + scale(1.5f)), + Const::BrowserFolderLineColor); + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(20.0f - 0.5f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y - scale(0.5f)), + ImVec2(pos.x + style.FramePadding.x + scale(20.0f + 2.0f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y + scale(2.0f)), Const::BrowserFolderLineColor); ImGui::Dummy({scale(20.0f), 0}); } break; case FolderTreeSymbols::End: { ImGui::GetWindowDrawList()->AddRectFilled( ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), - ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y + scale(1.5f)), + Const::BrowserFolderLineColor); + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y), + ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y + scale(1.5f)), Const::BrowserFolderLineColor); ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2), - ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 + scale(1.5f)), + ImVec2(pos.x + style.FramePadding.x + scale(20.0f - 0.5f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y - scale(0.5f)), + ImVec2(pos.x + style.FramePadding.x + scale(20.0f + 2.0f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y + scale(2.0f)), Const::BrowserFolderLineColor); ImGui::Dummy({scale(20.0f), 0}); } break; diff --git a/source/Gui/StyleRepository.h b/source/Gui/StyleRepository.h index 9c4114506..5d4e14f31 100644 --- a/source/Gui/StyleRepository.h +++ b/source/Gui/StyleRepository.h @@ -83,6 +83,7 @@ namespace Const ImColor const NeuronEditorPlotColor = ImColor::HSV(0.0f, 0.0f, 1.0f); ImColor const BrowserFolderLineColor = ImColor::HSV(0.0f, 0.0f, 0.5f); + ImColor const BrowserFolderNumSimsColor = ImColor::HSV(0.0f, 0.0f, 0.5f, 1.0f); float const WindowAlpha = 0.9f; float const SliderBarWidth = 30.0f; From 133f2171dc6beb446f197aade343dbb8c967b77f Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Thu, 28 Dec 2023 11:47:17 +0100 Subject: [PATCH 26/40] show accumulated reactions --- source/Gui/BrowserWindow.cpp | 145 ++++++++++++---------- source/Gui/BrowserWindow.h | 3 +- source/Gui/StyleRepository.h | 5 +- source/Network/NetworkResourceService.cpp | 10 +- source/Network/NetworkResourceTreeTO.h | 1 + 5 files changed, 93 insertions(+), 71 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 26c780a5d..2a35669a8 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -277,17 +277,15 @@ void _BrowserWindow::processSimulationList() ImGui::TableSetupColumn( "Simulation", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, - styleRepository.scale(190.0f), + styleRepository.scale(210.0f), NetworkResourceColumnId_SimulationName); ImGui::TableSetupColumn( "Description", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, - styleRepository.scale(120.0f), + styleRepository.scale(200.0f), NetworkResourceColumnId_Description); ImGui::TableSetupColumn( "Reactions", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), NetworkResourceColumnId_Likes); - //ImGui::TableSetupColumn( - // "Actions", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, scale(90.0f), NetworkResourceColumnId_Actions); ImGui::TableSetupColumn( "Timestamp", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_PreferSortDescending, @@ -336,23 +334,14 @@ void _BrowserWindow::processSimulationList() auto& leaf = item->getLeaf(); processFolderTreeSymbols(item); - - ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DownloadButtonTextColor); - auto downloadButtonResult = processActionButton(ICON_FA_DOWNLOAD); - ImGui::PopStyleColor(); - if (downloadButtonResult) { - onDownloadItem(leaf); - } - AlienImGui::Tooltip("Download"); + processDownloadButton(leaf); ImGui::SameLine(); - processShortenedText(leaf.simName); + ImGui::TableNextColumn(); processShortenedText(leaf.description); ImGui::TableNextColumn(); - processEmojiList(item); - //ImGui::TableNextColumn(); - //processActionButtons(item); + processReactionList(item); ImGui::TableNextColumn(); pushTextColor(item); AlienImGui::Text(leaf.timestamp); @@ -376,15 +365,21 @@ void _BrowserWindow::processSimulationList() } else { auto& folder = item->getFolder(); - ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); processFolderTreeSymbols(item); - ImGui::PopStyleColor(1); - processShortenedText(item->folderNames.back()); ImGui::SameLine(); - ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserFolderNumSimsColor); - AlienImGui::Text("(" + std::to_string(folder.numLeafs) + ")"); + ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserFolderPropertiesTextColor); + std::string numSimsString = folder.numLeafs == 1 ? "sim" : "sims"; + AlienImGui::Text("(" + std::to_string(folder.numLeafs) + " " + numSimsString + ")"); ImGui::PopStyleColor(); + ImGui::TableNextColumn(); + ImGui::TableNextColumn(); + //ImGui::Dummy({scale(18.0f), 0}); + //ImGui::SameLine(); + ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserFolderPropertiesTextColor); + AlienImGui::Text("(" + std::to_string(folder.numReactions) + ")"); + ImGui::PopStyleColor(); + } ImGui::PopID(); } @@ -462,7 +457,7 @@ void _BrowserWindow::processGenomeList() ImGui::TableNextColumn(); processShortenedText(leaf.description); ImGui::TableNextColumn(); - processEmojiList(item); + processReactionList(item); //ImGui::TableNextColumn(); //processActionButtons(item); ImGui::TableNextColumn(); @@ -692,8 +687,17 @@ void _BrowserWindow::processEmojiButton(int emojiType) } } -void _BrowserWindow::processEmojiList(NetworkResourceTreeTO const& to) +void _BrowserWindow::processReactionList(NetworkResourceTreeTO const& to) { + ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DownloadButtonTextColor); + auto isAddReaction = processActionButton(ICON_FA_PLUS); + ImGui::PopStyleColor(); + AlienImGui::Tooltip("Add a reaction"); + if (isAddReaction) { + _activateEmojiPopup = true; + _emojiPopupTO = to; + } + //calc remap which allows to show most frequent like type first std::map remap; std::set processedEmojiTypes; @@ -720,6 +724,7 @@ void _BrowserWindow::processEmojiList(NetworkResourceTreeTO const& to) for (auto const& emojiType : remap | std::views::values) { auto numLikes = leaf.numLikesByEmojiType.at(emojiType); + ImGui::SameLine(); AlienImGui::Text(std::to_string(numLikes)); ImGui::SameLine(); if (emojiType < _emojis.size()) { @@ -749,7 +754,6 @@ void _BrowserWindow::processEmojiList(NetworkResourceTreeTO const& to) //separator except for last element if (++counter < leaf.numLikesByEmojiType.size()) { - ImGui::SameLine(); ImGui::SetCursorPosX(ImGui::GetCursorPosX() - scale(4.0f)); } } @@ -758,49 +762,60 @@ void _BrowserWindow::processEmojiList(NetworkResourceTreeTO const& to) } } -void _BrowserWindow::processActionButtons(NetworkResourceTreeTO const& to) +void _BrowserWindow::processDownloadButton(BrowserLeaf const& leaf) { - auto& networkService = NetworkService::getInstance(); - //like button - - if (to->isLeaf()) { - auto const& leaf = to->getLeaf(); - auto liked = isLiked(leaf.id); - if (liked) { - ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::LikeButtonTextColor); - } else { - ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::NoLikeButtonTextColor); - } - auto likeButtonResult = processActionButton(ICON_FA_SMILE); - ImGui::PopStyleColor(); - if (likeButtonResult) { - _activateEmojiPopup = true; - _emojiPopupTO = to; - } - AlienImGui::Tooltip("Choose a reaction"); - ImGui::SameLine(); - - //download button - ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DownloadButtonTextColor); - auto downloadButtonResult = processActionButton(ICON_FA_DOWNLOAD); - ImGui::PopStyleColor(); - if (downloadButtonResult) { - onDownloadItem(leaf); - } - AlienImGui::Tooltip("Download"); - ImGui::SameLine(); - - //delete button - if (leaf.userName == networkService.getLoggedInUserName().value_or("")) { - ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DeleteButtonTextColor); - auto deleteButtonResult = processActionButton(ICON_FA_TRASH); - ImGui::PopStyleColor(); - if (deleteButtonResult) { - onDeleteItem(leaf); - } - AlienImGui::Tooltip("Delete"); - } + ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DownloadButtonTextColor); + auto downloadButtonResult = processActionButton(ICON_FA_DOWNLOAD); + ImGui::PopStyleColor(); + if (downloadButtonResult) { + onDownloadItem(leaf); } + AlienImGui::Tooltip("Download"); +} + +void _BrowserWindow::processActionButtons(NetworkResourceTreeTO const& to) +{ + //auto& networkService = NetworkService::getInstance(); + ////like button + + //if (to->isLeaf()) { + // auto const& leaf = to->getLeaf(); + // auto liked = isLiked(leaf.id); + // if (liked) { + // ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::AddReactionButtonTextColor); + // } else { + // ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::NoLikeButtonTextColor); + // } + // auto likeButtonResult = processActionButton(ICON_FA_STAR); + // ImGui::PopStyleColor(); + // if (likeButtonResult) { + // _activateEmojiPopup = true; + // _emojiPopupTO = to; + // } + // AlienImGui::Tooltip("Choose a reaction"); + // ImGui::SameLine(); + + // //download button + // ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DownloadButtonTextColor); + // auto downloadButtonResult = processActionButton(ICON_FA_DOWNLOAD); + // ImGui::PopStyleColor(); + // if (downloadButtonResult) { + // onDownloadItem(leaf); + // } + // AlienImGui::Tooltip("Download"); + // ImGui::SameLine(); + + // //delete button + // if (leaf.userName == networkService.getLoggedInUserName().value_or("")) { + // ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DeleteButtonTextColor); + // auto deleteButtonResult = processActionButton(ICON_FA_TRASH); + // ImGui::PopStyleColor(); + // if (deleteButtonResult) { + // onDeleteItem(leaf); + // } + // AlienImGui::Tooltip("Delete"); + // } + //} } namespace diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index cd1d80d0b..cbcc8ad30 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -42,8 +42,9 @@ class _BrowserWindow : public _AlienWindow void processEmojiWindow(); void processEmojiButton(int emojiType); - void processEmojiList(NetworkResourceTreeTO const& to); + void processReactionList(NetworkResourceTreeTO const& to); + void processDownloadButton(BrowserLeaf const& leaf); void processActionButtons(NetworkResourceTreeTO const& to); void processShortenedText(std::string const& text, bool bold = false); diff --git a/source/Gui/StyleRepository.h b/source/Gui/StyleRepository.h index 5d4e14f31..d6826b89f 100644 --- a/source/Gui/StyleRepository.h +++ b/source/Gui/StyleRepository.h @@ -55,8 +55,7 @@ namespace Const ImColor const InspectorLineColor = ImColor::HSV(0.54f, 0.0f, 1.0f, 1.0f); ImColor const InspectorRectColor = ImColor::HSV(0.54f, 0.0f, 0.5f, 1.0f); - ImColor const LikeButtonTextColor = ImColor::HSV(0.16f, 1.0f, 1.0f, 1.0f); - ImColor const NoLikeButtonTextColor = ImColor::HSV(0.16f, 0.5f, 0.5f, 1.0f); + ImColor const AddReactionButtonTextColor = ImColor::HSV(0.375f, 0.6f, 0.7f, 1.0f); ImColor const DownloadButtonTextColor = ImColor::HSV(0.55f, 0.6f, 1.0f, 1.0f); ImColor const DeleteButtonTextColor = ImColor::HSV(0.0f, 0.6f, 0.8f, 1.0f); @@ -83,7 +82,7 @@ namespace Const ImColor const NeuronEditorPlotColor = ImColor::HSV(0.0f, 0.0f, 1.0f); ImColor const BrowserFolderLineColor = ImColor::HSV(0.0f, 0.0f, 0.5f); - ImColor const BrowserFolderNumSimsColor = ImColor::HSV(0.0f, 0.0f, 0.5f, 1.0f); + ImColor const BrowserFolderPropertiesTextColor = ImColor::HSV(0.0f, 0.0f, 0.5f, 1.0f); float const WindowAlpha = 0.9f; float const SliderBarWidth = 30.0f; diff --git a/source/Network/NetworkResourceService.cpp b/source/Network/NetworkResourceService.cpp index c9cff462b..56951138b 100644 --- a/source/Network/NetworkResourceService.cpp +++ b/source/Network/NetworkResourceService.cpp @@ -172,10 +172,14 @@ std::vector NetworkResourceService::createTreeTOs( } } - //calc numLeafs for folders + //calc numLeafs and numReactions for folders for (int i = toInt(treeTOs.size()) - 1; i > 0; --i) { auto& entry = treeTOs.at(i); if (entry->isLeaf()) { + int numReactions = 0; + for (auto const& count : entry->getLeaf().numLikesByEmojiType | std::views::values) { + numReactions += count; + } for (int j = i - 1; j >= 0; --j) { auto& otherEntry = treeTOs.at(j); auto numEqualFolders = getNumEqualFolders(entry->folderNames, otherEntry->folderNames); @@ -183,7 +187,9 @@ std::vector NetworkResourceService::createTreeTOs( break; } if (numEqualFolders == otherEntry->folderNames.size() && !otherEntry->isLeaf()) { - ++otherEntry->getFolder().numLeafs; + auto& folder = otherEntry->getFolder(); + ++folder.numLeafs; + folder.numReactions += numReactions; } } } diff --git a/source/Network/NetworkResourceTreeTO.h b/source/Network/NetworkResourceTreeTO.h index 18c6a44e0..d1539503e 100644 --- a/source/Network/NetworkResourceTreeTO.h +++ b/source/Network/NetworkResourceTreeTO.h @@ -10,6 +10,7 @@ struct BrowserFolder { int numLeafs; + int numReactions; }; struct BrowserLeaf From f1e8cbc7c456400d801f52451d70c9bf97cafd21 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Thu, 28 Dec 2023 13:43:03 +0100 Subject: [PATCH 27/40] set default sort spec to timestamp --- source/Gui/BrowserWindow.cpp | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 2a35669a8..f65e4d24b 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -274,34 +274,21 @@ void _BrowserWindow::processSimulationList() | ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX; if (ImGui::BeginTable("Browser", 12, flags, ImVec2(0, 0), 0.0f)) { - ImGui::TableSetupColumn( - "Simulation", - ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, - styleRepository.scale(210.0f), - NetworkResourceColumnId_SimulationName); - ImGui::TableSetupColumn( - "Description", - ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, - styleRepository.scale(200.0f), - NetworkResourceColumnId_Description); - ImGui::TableSetupColumn( - "Reactions", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), NetworkResourceColumnId_Likes); + ImGui::TableSetupColumn("Simulation", ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(210.0f), NetworkResourceColumnId_SimulationName); + ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(200.0f), NetworkResourceColumnId_Description); + ImGui::TableSetupColumn("Reactions", ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), NetworkResourceColumnId_Likes); ImGui::TableSetupColumn( "Timestamp", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_PreferSortDescending, scale(135.0f), NetworkResourceColumnId_Timestamp); - ImGui::TableSetupColumn( - "User name", - ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, - styleRepository.scale(120.0f), - NetworkResourceColumnId_UserName); - ImGui::TableSetupColumn("Downloads", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_NumDownloads); - ImGui::TableSetupColumn("Width", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Width); - ImGui::TableSetupColumn("Height", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Height); - ImGui::TableSetupColumn("Objects", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Particles); - ImGui::TableSetupColumn("File size", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_FileSize); - ImGui::TableSetupColumn("Version", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Version); + ImGui::TableSetupColumn("User name", ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), NetworkResourceColumnId_UserName); + ImGui::TableSetupColumn("Downloads", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_NumDownloads); + ImGui::TableSetupColumn("Width", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Width); + ImGui::TableSetupColumn("Height", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Height); + ImGui::TableSetupColumn("Objects", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Particles); + ImGui::TableSetupColumn("File size", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_FileSize); + ImGui::TableSetupColumn("Version", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Version); ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableHeadersRow(); From ff3f4c8dcd17fd734d97a703314ab04a1257b0c1 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Thu, 28 Dec 2023 14:04:19 +0100 Subject: [PATCH 28/40] refactor browser data structures --- imgui.ini | 4 +- source/Gui/BrowserWindow.cpp | 194 +++++++++++++++++------------------ source/Gui/BrowserWindow.h | 23 +++-- 3 files changed, 110 insertions(+), 111 deletions(-) diff --git a/imgui.ini b/imgui.ini index 04b4cd510..80e1f9297 100644 --- a/imgui.ini +++ b/imgui.ini @@ -274,8 +274,8 @@ Size=556,448 Collapsed=0 [Window][Browser] -Pos=177,203 -Size=1287,597 +Pos=172,78 +Size=1252,825 Collapsed=0 [Window][Login] diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index f65e4d24b..1bc844b3f 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -106,7 +106,7 @@ void _BrowserWindow::refreshIntern(bool withRetry) auto& networkService = NetworkService::getInstance(); networkService.refreshLogin(); - bool success = networkService.getRemoteSimulationList(_rawNetworkResourceRawTOs, withRetry); + bool success = networkService.getRemoteSimulationList(_unfilteredRawTOs, withRetry); success &= networkService.getUserList(_userTOs, withRetry); if (!success) { @@ -114,13 +114,13 @@ void _BrowserWindow::refreshIntern(bool withRetry) MessageDialog::getInstance().information("Error", "Failed to retrieve browser data. Please try again."); } } else { - _numSimulations = 0; - _numGenomes = 0; - for (auto const& entry : _rawNetworkResourceRawTOs) { + _simulations.numResources = 0; + _genomes.numResources = 0; + for (auto const& entry : _unfilteredRawTOs) { if (entry->type == NetworkResourceType_Simulation) { - ++_numSimulations; + ++_simulations.numResources; } else { - ++_numGenomes; + ++_genomes.numResources; } } } @@ -268,21 +268,20 @@ void _BrowserWindow::processSimulationList() { ImGui::PushID("SimulationList"); _selectedDataType = NetworkResourceType_Simulation; - auto& styleRepository = StyleRepository::getInstance(); static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Sortable | ImGuiTableFlags_SortMulti | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX; if (ImGui::BeginTable("Browser", 12, flags, ImVec2(0, 0), 0.0f)) { - ImGui::TableSetupColumn("Simulation", ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(210.0f), NetworkResourceColumnId_SimulationName); - ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(200.0f), NetworkResourceColumnId_Description); - ImGui::TableSetupColumn("Reactions", ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), NetworkResourceColumnId_Likes); + ImGui::TableSetupColumn("Simulation", ImGuiTableColumnFlags_WidthFixed, scale(210.0f), NetworkResourceColumnId_SimulationName); + ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthFixed, scale(200.0f), NetworkResourceColumnId_Description); + ImGui::TableSetupColumn("Reactions", ImGuiTableColumnFlags_WidthFixed, scale(120.0f), NetworkResourceColumnId_Likes); ImGui::TableSetupColumn( "Timestamp", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_PreferSortDescending, scale(135.0f), NetworkResourceColumnId_Timestamp); - ImGui::TableSetupColumn("User name", ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), NetworkResourceColumnId_UserName); + ImGui::TableSetupColumn("User name", ImGuiTableColumnFlags_WidthFixed, scale(120.0f), NetworkResourceColumnId_UserName); ImGui::TableSetupColumn("Downloads", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_NumDownloads); ImGui::TableSetupColumn("Width", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Width); ImGui::TableSetupColumn("Height", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Height); @@ -295,18 +294,18 @@ void _BrowserWindow::processSimulationList() //create table data if necessary if (ImGuiTableSortSpecs* sortSpecs = ImGui::TableGetSortSpecs()) { if (sortSpecs->SpecsDirty || _scheduleCreateBrowserData) { - sortRemoteSimulationData(_filteredNetworkSimulationTOs, sortSpecs); + sortRemoteSimulationData(_simulations.rawTOs, sortSpecs); sortSpecs->SpecsDirty = false; _scheduleCreateBrowserData = false; - _simulationTreeTOs = NetworkResourceService::createTreeTOs(_filteredNetworkSimulationTOs, _collapsedFolderNames); + _simulations.treeTOs = NetworkResourceService::createTreeTOs(_simulations.rawTOs, _simulations.collapsedFolderNames); } } ImGuiListClipper clipper; - clipper.Begin(_simulationTreeTOs.size()); + clipper.Begin(_simulations.treeTOs.size()); while (clipper.Step()) for (int row = clipper.DisplayStart; row < clipper.DisplayEnd; row++) { - auto item = _simulationTreeTOs[row]; + auto item = _simulations.treeTOs[row]; ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); @@ -320,7 +319,7 @@ void _BrowserWindow::processSimulationList() if (item->isLeaf()) { auto& leaf = item->getLeaf(); - processFolderTreeSymbols(item); + processFolderTreeSymbols(item, _simulations.collapsedFolderNames); processDownloadButton(leaf); ImGui::SameLine(); processShortenedText(leaf.simName); @@ -352,7 +351,7 @@ void _BrowserWindow::processSimulationList() } else { auto& folder = item->getFolder(); - processFolderTreeSymbols(item); + processFolderTreeSymbols(item, _simulations.collapsedFolderNames); processShortenedText(item->folderNames.back()); ImGui::SameLine(); ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserFolderPropertiesTextColor); @@ -420,19 +419,19 @@ void _BrowserWindow::processGenomeList() //create table data if necessary if (ImGuiTableSortSpecs* sortSpecs = ImGui::TableGetSortSpecs()) { if (sortSpecs->SpecsDirty || _scheduleCreateBrowserData) { - sortRemoteSimulationData(_filteredNetworkGenomeTOs, sortSpecs); + sortRemoteSimulationData(_genomes.rawTOs, sortSpecs); sortSpecs->SpecsDirty = false; _scheduleCreateBrowserData = false; - _genomeTreeTOs = NetworkResourceService::createTreeTOs(_filteredNetworkGenomeTOs, _collapsedFolderNames); + _genomes.treeTOs = NetworkResourceService::createTreeTOs(_genomes.rawTOs, _simulations.collapsedFolderNames); } } ImGuiListClipper clipper; - clipper.Begin(_genomeTreeTOs.size()); + clipper.Begin(_genomes.treeTOs.size()); while (clipper.Step()) for (int row = clipper.DisplayStart; row < clipper.DisplayEnd; row++) { - auto& item = _genomeTreeTOs[row]; + auto& item = _genomes.treeTOs[row]; ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); @@ -560,10 +559,10 @@ void _BrowserWindow::processStatus() ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::MonospaceColor); std::string statusText; statusText += std::string(" " ICON_FA_INFO_CIRCLE " "); - statusText += std::to_string(_numSimulations) + " simulations found"; + statusText += std::to_string(_simulations.numResources) + " simulations found"; statusText += std::string(" " ICON_FA_INFO_CIRCLE " "); - statusText += std::to_string(_numGenomes) + " genomes found"; + statusText += std::to_string(_genomes.numResources) + " genomes found"; statusText += std::string(" " ICON_FA_INFO_CIRCLE " "); statusText += std::to_string(_userTOs.size()) + " simulators found"; @@ -599,6 +598,73 @@ void _BrowserWindow::processFilter() } } +void _BrowserWindow::processFolderTreeSymbols(NetworkResourceTreeTO const& entry, std::set>& collapsedFolderNames) +{ + auto const& treeSymbols = entry->treeSymbols; + ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); + for (auto const& folderLine : treeSymbols) { + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImGuiStyle& style = ImGui::GetStyle(); + switch (folderLine) { + case FolderTreeSymbols::Expanded: { + if (AlienImGui::Button(ICON_FA_MINUS_SQUARE, 20.0f)) { + collapsedFolderNames.insert(entry->folderNames); + _scheduleCreateBrowserData = true; + } + } break; + case FolderTreeSymbols::Collapsed: { + if (AlienImGui::Button(ICON_FA_PLUS_SQUARE, 20.0f)) { + collapsedFolderNames.erase(entry->folderNames); + _scheduleCreateBrowserData = true; + } + } break; + case FolderTreeSymbols::Continue: { + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) + style.FramePadding.y), + Const::BrowserFolderLineColor); + ImGui::Dummy({scale(20.0f), 0}); + } break; + case FolderTreeSymbols::Branch: { + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) + style.FramePadding.y), + Const::BrowserFolderLineColor); + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y), + ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y + scale(1.5f)), + Const::BrowserFolderLineColor); + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(20.0f - 0.5f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y - scale(0.5f)), + ImVec2(pos.x + style.FramePadding.x + scale(20.0f + 2.0f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y + scale(2.0f)), + Const::BrowserFolderLineColor); + ImGui::Dummy({scale(20.0f), 0}); + } break; + case FolderTreeSymbols::End: { + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y + scale(1.5f)), + Const::BrowserFolderLineColor); + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y), + ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y + scale(1.5f)), + Const::BrowserFolderLineColor); + ImGui::GetWindowDrawList()->AddRectFilled( + ImVec2(pos.x + style.FramePadding.x + scale(20.0f - 0.5f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y - scale(0.5f)), + ImVec2(pos.x + style.FramePadding.x + scale(20.0f + 2.0f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y + scale(2.0f)), + Const::BrowserFolderLineColor); + ImGui::Dummy({scale(20.0f), 0}); + } break; + case FolderTreeSymbols::None: { + ImGui::Dummy({scale(20.0f), 0}); + } break; + default: { + } break; + } + ImGui::SameLine(); + } + ImGui::PopStyleColor(1); +} void _BrowserWindow::processEmojiWindow() { @@ -1046,85 +1112,17 @@ void _BrowserWindow::pushTextColor(NetworkResourceTreeTO const& to) void _BrowserWindow::calcFilteredSimulationAndGenomeLists() { - _filteredNetworkSimulationTOs.clear(); - _filteredNetworkSimulationTOs.reserve(_rawNetworkResourceRawTOs.size()); - _filteredNetworkGenomeTOs.clear(); - _filteredNetworkGenomeTOs.reserve(_filteredNetworkGenomeTOs.size()); - for (auto const& to : _rawNetworkResourceRawTOs) { + _simulations.rawTOs.clear(); + _simulations.rawTOs.reserve(_unfilteredRawTOs.size()); + _genomes.rawTOs.clear(); + _genomes.rawTOs.reserve(_genomes.rawTOs.size()); + for (auto const& to : _unfilteredRawTOs) { if (to->matchWithFilter(_filter) &&_showCommunityCreations != to->fromRelease) { if (to->type == NetworkResourceType_Simulation) { - _filteredNetworkSimulationTOs.emplace_back(to); + _simulations.rawTOs.emplace_back(to); } else { - _filteredNetworkGenomeTOs.emplace_back(to); + _genomes.rawTOs.emplace_back(to); } } } } - -void _BrowserWindow::processFolderTreeSymbols(NetworkResourceTreeTO& entry) -{ - auto const& treeSymbols = entry->treeSymbols; - ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); - for (auto const& folderLine : treeSymbols) { - ImVec2 pos = ImGui::GetCursorScreenPos(); - ImGuiStyle& style = ImGui::GetStyle(); - switch (folderLine) { - case FolderTreeSymbols::Expanded: { - if (AlienImGui::Button(ICON_FA_MINUS_SQUARE, 20.0f)) { - _collapsedFolderNames.insert(entry->folderNames); - _scheduleCreateBrowserData = true; - } - } break; - case FolderTreeSymbols::Collapsed: { - if (AlienImGui::Button(ICON_FA_PLUS_SQUARE, 20.0f)) { - _collapsedFolderNames.erase(entry->folderNames); - _scheduleCreateBrowserData = true; - } - } break; - case FolderTreeSymbols::Continue: { - ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), - ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) + style.FramePadding.y), - Const::BrowserFolderLineColor); - ImGui::Dummy({scale(20.0f), 0}); - } break; - case FolderTreeSymbols::Branch: { - ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), - ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) + style.FramePadding.y), - Const::BrowserFolderLineColor); - ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y), - ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y + scale(1.5f)), - Const::BrowserFolderLineColor); - ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(pos.x + style.FramePadding.x + scale(20.0f - 0.5f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y - scale(0.5f)), - ImVec2(pos.x + style.FramePadding.x + scale(20.0f + 2.0f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y + scale(2.0f)), - Const::BrowserFolderLineColor); - ImGui::Dummy({scale(20.0f), 0}); - } break; - case FolderTreeSymbols::End: { - ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(pos.x + style.FramePadding.x + scale(6.0f), pos.y), - ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y + scale(1.5f)), - Const::BrowserFolderLineColor); - ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(pos.x + style.FramePadding.x + scale(7.5f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y), - ImVec2(pos.x + style.FramePadding.x + scale(20.0f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y + scale(1.5f)), - Const::BrowserFolderLineColor); - ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(pos.x + style.FramePadding.x + scale(20.0f - 0.5f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y - scale(0.5f)), - ImVec2(pos.x + style.FramePadding.x + scale(20.0f + 2.0f), pos.y + scale(RowHeight) / 2 - style.FramePadding.y + scale(2.0f)), - Const::BrowserFolderLineColor); - ImGui::Dummy({scale(20.0f), 0}); - } break; - case FolderTreeSymbols::None: { - ImGui::Dummy({scale(20.0f), 0}); - } break; - default: { - } break; - } - ImGui::SameLine(); - } - ImGui::PopStyleColor(1); -} diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index cbcc8ad30..e7787d068 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -40,6 +40,7 @@ class _BrowserWindow : public _AlienWindow void processFilter(); void processToolbar(); + void processFolderTreeSymbols(NetworkResourceTreeTO const& entry, std::set>& collapsedFolderNames); void processEmojiWindow(); void processEmojiButton(int emojiType); void processReactionList(NetworkResourceTreeTO const& to); @@ -67,8 +68,6 @@ class _BrowserWindow : public _AlienWindow void pushTextColor(NetworkResourceTreeTO const& to); void calcFilteredSimulationAndGenomeLists(); - void processFolderTreeSymbols(NetworkResourceTreeTO& entry); - NetworkResourceType _selectedDataType = NetworkResourceType_Simulation; bool _scheduleRefresh = false; @@ -80,15 +79,17 @@ class _BrowserWindow : public _AlienWindow std::unordered_map _ownEmojiTypeBySimId; std::unordered_map, std::set> _userNamesByEmojiTypeBySimIdCache; - int _numSimulations = 0; - int _numGenomes = 0; - std::vector _rawNetworkResourceRawTOs; - std::vector _filteredNetworkSimulationTOs; - std::vector _filteredNetworkGenomeTOs; - std::set> _collapsedFolderNames; - - std::vector _simulationTreeTOs; - std::vector _genomeTreeTOs; + struct ResourceData + { + int numResources = 0; + std::vector rawTOs; + std::vector treeTOs; + std::set> collapsedFolderNames; + }; + + std::vector _unfilteredRawTOs; + ResourceData _genomes; + ResourceData _simulations; std::vector _userTOs; From 46086b68a1ab2857dc3273ff59a5abb31a0f2f18 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Thu, 28 Dec 2023 14:37:32 +0100 Subject: [PATCH 29/40] initial collapsed state for folders --- source/Gui/BrowserWindow.cpp | 72 +++++------ source/Gui/BrowserWindow.h | 25 ++-- source/Network/NetworkResourceService.cpp | 143 ++++++++++++---------- source/Network/NetworkResourceService.h | 4 +- 4 files changed, 131 insertions(+), 113 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 1bc844b3f..4e63af754 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -93,6 +93,8 @@ void _BrowserWindow::registerCyclicReferences(LoginDialogWeakPtr const& loginDia auto firstStart = GlobalSettings::getInstance().getBoolState("windows.browser.first start", true); refreshIntern(firstStart); + _simulations.collapsedFolderNames = NetworkResourceService::calcInitialCollapsedFolderNames(_simulations.rawTOs); + _genomes.collapsedFolderNames = NetworkResourceService::calcInitialCollapsedFolderNames(_genomes.rawTOs); } void _BrowserWindow::onRefresh() @@ -124,8 +126,8 @@ void _BrowserWindow::refreshIntern(bool withRetry) } } } - calcFilteredSimulationAndGenomeLists(); - _scheduleCreateBrowserData = true; + filteredRawTOs(); + _scheduleCreateTreeTOs = true; if (networkService.getLoggedInUserName()) { if (!networkService.getEmojiTypeBySimId(_ownEmojiTypeBySimId)) { @@ -293,10 +295,10 @@ void _BrowserWindow::processSimulationList() //create table data if necessary if (ImGuiTableSortSpecs* sortSpecs = ImGui::TableGetSortSpecs()) { - if (sortSpecs->SpecsDirty || _scheduleCreateBrowserData) { - sortRemoteSimulationData(_simulations.rawTOs, sortSpecs); + if (sortSpecs->SpecsDirty || _scheduleCreateTreeTOs) { + sortRawTOs(_simulations.rawTOs, sortSpecs); sortSpecs->SpecsDirty = false; - _scheduleCreateBrowserData = false; + _scheduleCreateTreeTOs = false; _simulations.treeTOs = NetworkResourceService::createTreeTOs(_simulations.rawTOs, _simulations.collapsedFolderNames); } @@ -418,10 +420,10 @@ void _BrowserWindow::processGenomeList() //create table data if necessary if (ImGuiTableSortSpecs* sortSpecs = ImGui::TableGetSortSpecs()) { - if (sortSpecs->SpecsDirty || _scheduleCreateBrowserData) { - sortRemoteSimulationData(_genomes.rawTOs, sortSpecs); + if (sortSpecs->SpecsDirty || _scheduleCreateTreeTOs) { + sortRawTOs(_genomes.rawTOs, sortSpecs); sortSpecs->SpecsDirty = false; - _scheduleCreateBrowserData = false; + _scheduleCreateTreeTOs = false; _genomes.treeTOs = NetworkResourceService::createTreeTOs(_genomes.rawTOs, _simulations.collapsedFolderNames); } @@ -588,13 +590,13 @@ void _BrowserWindow::processFilter() { ImGui::Spacing(); if (AlienImGui::ToggleButton(AlienImGui::ToggleButtonParameters().name("Community creations"), _showCommunityCreations)) { - calcFilteredSimulationAndGenomeLists(); - _scheduleCreateBrowserData = true; + filteredRawTOs(); + _scheduleCreateTreeTOs = true; } ImGui::SameLine(); if (AlienImGui::InputText(AlienImGui::InputTextParameters().name("Filter"), _filter)) { - calcFilteredSimulationAndGenomeLists(); - _scheduleCreateBrowserData = true; + filteredRawTOs(); + _scheduleCreateTreeTOs = true; } } @@ -609,13 +611,13 @@ void _BrowserWindow::processFolderTreeSymbols(NetworkResourceTreeTO const& entry case FolderTreeSymbols::Expanded: { if (AlienImGui::Button(ICON_FA_MINUS_SQUARE, 20.0f)) { collapsedFolderNames.insert(entry->folderNames); - _scheduleCreateBrowserData = true; + _scheduleCreateTreeTOs = true; } } break; case FolderTreeSymbols::Collapsed: { if (AlienImGui::Button(ICON_FA_PLUS_SQUARE, 20.0f)) { collapsedFolderNames.erase(entry->folderNames); - _scheduleCreateBrowserData = true; + _scheduleCreateTreeTOs = true; } } break; case FolderTreeSymbols::Continue: { @@ -933,10 +935,10 @@ void _BrowserWindow::processActivated() onRefresh(); } -void _BrowserWindow::sortRemoteSimulationData(std::vector& remoteData, ImGuiTableSortSpecs* sortSpecs) +void _BrowserWindow::sortRawTOs(std::vector& tos, ImGuiTableSortSpecs* sortSpecs) { - if (remoteData.size() > 1) { - std::sort(remoteData.begin(), remoteData.end(), [&](auto const& left, auto const& right) { + if (tos.size() > 1) { + std::sort(tos.begin(), tos.end(), [&](auto const& left, auto const& right) { return _NetworkResourceRawTO::compare(left, right, sortSpecs) < 0; }); } @@ -947,6 +949,23 @@ void _BrowserWindow::sortUserList() std::sort(_userTOs.begin(), _userTOs.end(), [&](auto const& left, auto const& right) { return UserTO::compareOnlineAndTimestamp(left, right) > 0; }); } +void _BrowserWindow::filteredRawTOs() +{ + _simulations.rawTOs.clear(); + _simulations.rawTOs.reserve(_unfilteredRawTOs.size()); + _genomes.rawTOs.clear(); + _genomes.rawTOs.reserve(_genomes.rawTOs.size()); + for (auto const& to : _unfilteredRawTOs) { + if (to->matchWithFilter(_filter) && _showCommunityCreations != to->fromRelease) { + if (to->type == NetworkResourceType_Simulation) { + _simulations.rawTOs.emplace_back(to); + } else { + _genomes.rawTOs.emplace_back(to); + } + } + } +} + void _BrowserWindow::onDownloadItem(BrowserLeaf const& leaf) { printOverlayMessage("Downloading ..."); @@ -1059,7 +1078,7 @@ void _BrowserWindow::onToggleLike(NetworkResourceTreeTO const& to, int emojiType _userNamesByEmojiTypeBySimIdCache.erase(std::make_pair(leaf.id, emojiType)); //invalidate cache entry networkService.toggleLikeSimulation(leaf.id, emojiType); - //_scheduleCreateBrowserData = true; + //_scheduleCreateTreeTOs = true; } else { _loginDialog.lock()->open(); } @@ -1109,20 +1128,3 @@ void _BrowserWindow::pushTextColor(NetworkResourceTreeTO const& to) ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::DirectoryColor); } } - -void _BrowserWindow::calcFilteredSimulationAndGenomeLists() -{ - _simulations.rawTOs.clear(); - _simulations.rawTOs.reserve(_unfilteredRawTOs.size()); - _genomes.rawTOs.clear(); - _genomes.rawTOs.reserve(_genomes.rawTOs.size()); - for (auto const& to : _unfilteredRawTOs) { - if (to->matchWithFilter(_filter) &&_showCommunityCreations != to->fromRelease) { - if (to->type == NetworkResourceType_Simulation) { - _simulations.rawTOs.emplace_back(to); - } else { - _genomes.rawTOs.emplace_back(to); - } - } - } -} diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index e7787d068..5bb215eca 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -27,6 +27,14 @@ class _BrowserWindow : public _AlienWindow void onRefresh(); private: + struct ResourceData + { + int numResources = 0; + std::vector rawTOs; + std::vector treeTOs; + std::set> collapsedFolderNames; + }; + void refreshIntern(bool withRetry); void processIntern() override; @@ -54,9 +62,11 @@ class _BrowserWindow : public _AlienWindow void processActivated() override; - void sortRemoteSimulationData(std::vector& remoteData, ImGuiTableSortSpecs* sortSpecs); + void sortRawTOs(std::vector& tos, ImGuiTableSortSpecs* sortSpecs); void sortUserList(); + void filteredRawTOs(); + void onDownloadItem(BrowserLeaf const& leaf); void onDeleteItem(BrowserLeaf const& leaf); void onToggleLike(NetworkResourceTreeTO const& to, int emojiType); @@ -66,12 +76,11 @@ class _BrowserWindow : public _AlienWindow std::string getUserNamesToEmojiType(std::string const& simId, int emojiType); void pushTextColor(NetworkResourceTreeTO const& to); - void calcFilteredSimulationAndGenomeLists(); - NetworkResourceType _selectedDataType = NetworkResourceType_Simulation; bool _scheduleRefresh = false; - bool _scheduleCreateBrowserData = false; + bool _scheduleCreateTreeTOs = false; + std::string _filter; bool _showCommunityCreations = false; float _userTableWidth = 0; @@ -79,14 +88,6 @@ class _BrowserWindow : public _AlienWindow std::unordered_map _ownEmojiTypeBySimId; std::unordered_map, std::set> _userNamesByEmojiTypeBySimIdCache; - struct ResourceData - { - int numResources = 0; - std::vector rawTOs; - std::vector treeTOs; - std::set> collapsedFolderNames; - }; - std::vector _unfilteredRawTOs; ResourceData _genomes; ResourceData _simulations; diff --git a/source/Network/NetworkResourceService.cpp b/source/Network/NetworkResourceService.cpp index 56951138b..d5b871fb3 100644 --- a/source/Network/NetworkResourceService.cpp +++ b/source/Network/NetworkResourceService.cpp @@ -25,16 +25,16 @@ namespace } std::vector NetworkResourceService::createTreeTOs( - std::vector const& networkTOs, + std::vector const& rawTOs, std::set> const& collapsedFolderNames) { std::list treeToList; - for (auto const& entry : networkTOs) { + for (auto const& rawTO : rawTOs) { //parse folder names std::vector folderNames; std::string nameWithoutFolders; - boost::split(folderNames, entry->simName, boost::is_any_of("/")); + boost::split(folderNames, rawTO->simName, boost::is_any_of("/")); if (!folderNames.empty()) { nameWithoutFolders = folderNames.back(); folderNames.pop_back(); @@ -50,8 +50,8 @@ std::vector NetworkResourceService::createTreeTOs( bestMatchEqualFolders = -1; for (int i = 0; i < treeToList.size(); ++i) { --searchIter; - auto otherEntry = *searchIter; - auto equalFolders = getNumEqualFolders(folderNames, otherEntry->folderNames); + auto otherRawTO = *searchIter; + auto equalFolders = getNumEqualFolders(folderNames, otherRawTO->folderNames); if (equalFolders < bestMatchEqualFolders) { break; } @@ -70,7 +70,7 @@ std::vector NetworkResourceService::createTreeTOs( for (int i = bestMatchEqualFolders; i < folderNames.size(); ++i) { auto treeTO = std::make_shared<_NetworkResourceTreeTO>(); treeTO->folderNames = std::vector(folderNames.begin(), folderNames.begin() + i + 1); - treeTO->type = entry->type; + treeTO->type = rawTO->type; treeTO->node = BrowserFolder(); bestMatchIter = treeToList.insert(bestMatchIter, treeTO); ++bestMatchIter; @@ -79,20 +79,20 @@ std::vector NetworkResourceService::createTreeTOs( //insert leaf auto treeTO = std::make_shared<_NetworkResourceTreeTO>(); BrowserLeaf leaf{ - .id = entry->id, - .timestamp = entry->timestamp, - .userName = entry->userName, + .id = rawTO->id, + .timestamp = rawTO->timestamp, + .userName = rawTO->userName, .simName = nameWithoutFolders, - .numLikesByEmojiType = entry->numLikesByEmojiType, - .numDownloads = entry->numDownloads, - .width = entry->width, - .height = entry->height, - .particles = entry->particles, - .contentSize = entry->contentSize, - .description = entry->description, - .version = entry->version + .numLikesByEmojiType = rawTO->numLikesByEmojiType, + .numDownloads = rawTO->numDownloads, + .width = rawTO->width, + .height = rawTO->height, + .particles = rawTO->particles, + .contentSize = rawTO->contentSize, + .description = rawTO->description, + .version = rawTO->version }; - treeTO->type = entry->type; + treeTO->type = rawTO->type; treeTO->folderNames = folderNames; treeTO->node = leaf; treeToList.insert(bestMatchIter, treeTO); @@ -101,35 +101,35 @@ std::vector NetworkResourceService::createTreeTOs( //calc folder lines std::vector treeTOs(treeToList.begin(), treeToList.end()); for (int i = 0; i < treeTOs.size(); ++i) { - auto& entry = treeTOs.at(i); + auto& treeTO = treeTOs.at(i); if (i == 0) { - if (!entry->isLeaf()) { - entry->treeSymbols.emplace_back(FolderTreeSymbols::Expanded); + if (!treeTO->isLeaf()) { + treeTO->treeSymbols.emplace_back(FolderTreeSymbols::Expanded); } } else { - auto const& prevEntry = treeTOs.at(i - 1); - auto numEqualFolders = getNumEqualFolders(entry->folderNames, prevEntry->folderNames); + auto const& prevTreeTO = treeTOs.at(i - 1); + auto numEqualFolders = getNumEqualFolders(treeTO->folderNames, prevTreeTO->folderNames); - entry->treeSymbols.resize(entry->folderNames.size(), FolderTreeSymbols::None); + treeTO->treeSymbols.resize(treeTO->folderNames.size(), FolderTreeSymbols::None); //calc symbols at position numEqualFolders - 1 if (numEqualFolders > 0) { int f = numEqualFolders - 1; - if (prevEntry->treeSymbols.at(f) == FolderTreeSymbols::Expanded) { - entry->treeSymbols.at(f) = FolderTreeSymbols::End; - } else if (prevEntry->treeSymbols.at(f) == FolderTreeSymbols::End) { - prevEntry->treeSymbols.at(f) = FolderTreeSymbols::Branch; - entry->treeSymbols.at(f) = FolderTreeSymbols::End; - } else if (prevEntry->treeSymbols.at(f) == FolderTreeSymbols::Branch) { - entry->treeSymbols.at(f) = FolderTreeSymbols::End; - } else if (prevEntry->treeSymbols.at(f) == FolderTreeSymbols::None) { + if (prevTreeTO->treeSymbols.at(f) == FolderTreeSymbols::Expanded) { + treeTO->treeSymbols.at(f) = FolderTreeSymbols::End; + } else if (prevTreeTO->treeSymbols.at(f) == FolderTreeSymbols::End) { + prevTreeTO->treeSymbols.at(f) = FolderTreeSymbols::Branch; + treeTO->treeSymbols.at(f) = FolderTreeSymbols::End; + } else if (prevTreeTO->treeSymbols.at(f) == FolderTreeSymbols::Branch) { + treeTO->treeSymbols.at(f) = FolderTreeSymbols::End; + } else if (prevTreeTO->treeSymbols.at(f) == FolderTreeSymbols::None) { for (int j = i - 1; j >= 0; --j) { - auto& otherEntry = treeTOs.at(j); - if (otherEntry->treeSymbols.at(f) == FolderTreeSymbols::None) { - otherEntry->treeSymbols.at(f) = FolderTreeSymbols::Continue; - } else if (otherEntry->treeSymbols.at(f) == FolderTreeSymbols::End) { - otherEntry->treeSymbols.at(f) = FolderTreeSymbols::Branch; + auto& otherTreeTO = treeTOs.at(j); + if (otherTreeTO->treeSymbols.at(f) == FolderTreeSymbols::None) { + otherTreeTO->treeSymbols.at(f) = FolderTreeSymbols::Continue; + } else if (otherTreeTO->treeSymbols.at(f) == FolderTreeSymbols::End) { + otherTreeTO->treeSymbols.at(f) = FolderTreeSymbols::Branch; } else { break; } @@ -141,53 +141,53 @@ std::vector NetworkResourceService::createTreeTOs( //calc symbols before position numEqualFolders - 1 for (int f = 0; f < numEqualFolders - 1; ++f) { - if (prevEntry->treeSymbols.at(f) == FolderTreeSymbols::Branch) { - entry->treeSymbols.at(f) = FolderTreeSymbols::None; + if (prevTreeTO->treeSymbols.at(f) == FolderTreeSymbols::Branch) { + treeTO->treeSymbols.at(f) = FolderTreeSymbols::None; } } - if (numEqualFolders < entry->folderNames.size()) { - CHECK(numEqualFolders + 1 == entry->folderNames.size()); - entry->treeSymbols.back() = FolderTreeSymbols::Expanded; + if (numEqualFolders < treeTO->folderNames.size()) { + CHECK(numEqualFolders + 1 == treeTO->folderNames.size()); + treeTO->treeSymbols.back() = FolderTreeSymbols::Expanded; - if (numEqualFolders > 0 && numEqualFolders < prevEntry->folderNames.size()) { - entry->treeSymbols.at(numEqualFolders - 1) = FolderTreeSymbols::End; + if (numEqualFolders > 0 && numEqualFolders < prevTreeTO->folderNames.size()) { + treeTO->treeSymbols.at(numEqualFolders - 1) = FolderTreeSymbols::End; bool noneFound = false; for (int j = i - 1; j >= 0; --j) { - auto& otherEntry = treeTOs.at(j); - if (otherEntry->treeSymbols.at(numEqualFolders - 1) == FolderTreeSymbols::None) { - otherEntry->treeSymbols.at(numEqualFolders - 1) = FolderTreeSymbols::Continue; + auto& otherTreeTO = treeTOs.at(j); + if (otherTreeTO->treeSymbols.at(numEqualFolders - 1) == FolderTreeSymbols::None) { + otherTreeTO->treeSymbols.at(numEqualFolders - 1) = FolderTreeSymbols::Continue; noneFound = true; - } else if (noneFound && otherEntry->treeSymbols.at(numEqualFolders - 1) == FolderTreeSymbols::End) { - otherEntry->treeSymbols.at(numEqualFolders - 1) = FolderTreeSymbols::Branch; + } else if (noneFound && otherTreeTO->treeSymbols.at(numEqualFolders - 1) == FolderTreeSymbols::End) { + otherTreeTO->treeSymbols.at(numEqualFolders - 1) = FolderTreeSymbols::Branch; } else { break; } } } } - if (numEqualFolders > 0 && numEqualFolders < prevEntry->folderNames.size() && numEqualFolders == entry->folderNames.size()) { - entry->treeSymbols.back() = FolderTreeSymbols::End; + if (numEqualFolders > 0 && numEqualFolders < prevTreeTO->folderNames.size() && numEqualFolders == treeTO->folderNames.size()) { + treeTO->treeSymbols.back() = FolderTreeSymbols::End; } } } //calc numLeafs and numReactions for folders for (int i = toInt(treeTOs.size()) - 1; i > 0; --i) { - auto& entry = treeTOs.at(i); - if (entry->isLeaf()) { + auto& treeTO = treeTOs.at(i); + if (treeTO->isLeaf()) { int numReactions = 0; - for (auto const& count : entry->getLeaf().numLikesByEmojiType | std::views::values) { + for (auto const& count : treeTO->getLeaf().numLikesByEmojiType | std::views::values) { numReactions += count; } for (int j = i - 1; j >= 0; --j) { - auto& otherEntry = treeTOs.at(j); - auto numEqualFolders = getNumEqualFolders(entry->folderNames, otherEntry->folderNames); + auto& otherTreeTO = treeTOs.at(j); + auto numEqualFolders = getNumEqualFolders(treeTO->folderNames, otherTreeTO->folderNames); if (numEqualFolders == 0) { break; } - if (numEqualFolders == otherEntry->folderNames.size() && !otherEntry->isLeaf()) { - auto& folder = otherEntry->getFolder(); + if (numEqualFolders == otherTreeTO->folderNames.size() && !otherTreeTO->isLeaf()) { + auto& folder = otherTreeTO->getFolder(); ++folder.numLeafs; folder.numReactions += numReactions; } @@ -203,13 +203,13 @@ std::vector NetworkResourceService::createTreeTOs( std::vector result; result.reserve(treeTOs.size()); - for (auto const& entry : treeTOs) { + for (auto const& treeTO : treeTOs) { auto isVisible = true; std::string folderString; - auto numSolderToCheck = entry->isLeaf() ? entry->folderNames.size() : entry->folderNames.size() - 1; + auto numSolderToCheck = treeTO->isLeaf() ? treeTO->folderNames.size() : treeTO->folderNames.size() - 1; for (size_t i = 0; i < numSolderToCheck; ++i) { - folderString.append(entry->folderNames.at(i)); + folderString.append(treeTO->folderNames.at(i)); if (collapsedFolderStrings.contains(folderString)) { isVisible = false; } @@ -218,14 +218,27 @@ std::vector NetworkResourceService::createTreeTOs( } } - if (!entry->isLeaf()) { - auto folderString = boost::join(entry->folderNames, "/"); + if (!treeTO->isLeaf()) { + auto folderString = boost::join(treeTO->folderNames, "/"); if (collapsedFolderStrings.contains(folderString)) { - entry->treeSymbols.back() = FolderTreeSymbols::Collapsed; + treeTO->treeSymbols.back() = FolderTreeSymbols::Collapsed; } } if (isVisible) { - result.emplace_back(entry); + result.emplace_back(treeTO); + } + } + return result; +} + +std::set> NetworkResourceService::calcInitialCollapsedFolderNames(std::vector const& rawTOs) +{ + std::set> result; + for (auto const& rawTO : rawTOs) { + std::vector folderNames; + boost::split(folderNames, rawTO->simName, boost::is_any_of("/")); + for (int i = 0; i < toInt(folderNames.size()) - 2; ++i) { + result.insert(std::vector(folderNames.begin(), folderNames.begin() + 2 + i)); } } return result; diff --git a/source/Network/NetworkResourceService.h b/source/Network/NetworkResourceService.h index 0f11e009c..d75309611 100644 --- a/source/Network/NetworkResourceService.h +++ b/source/Network/NetworkResourceService.h @@ -9,6 +9,8 @@ class NetworkResourceService { public: static std::vector createTreeTOs( - std::vector const& browserData, + std::vector const& rawTOs, std::set> const& collapsedFolderNames); + + static std::set> calcInitialCollapsedFolderNames(std::vector const& browserData); }; From a5a434ef1c072c81100e3841c921e7df0654d79c Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Thu, 28 Dec 2023 15:08:04 +0100 Subject: [PATCH 30/40] saving and loading collapsed items to settings --- source/Gui/BrowserWindow.cpp | 32 +++++++++++++------ source/Gui/BrowserWindow.h | 2 +- source/Network/NetworkResourceService.cpp | 23 +++++++++++++ source/Network/NetworkResourceService.h | 3 ++ .../NetworkResourceServiceTests.cpp | 8 ++--- 5 files changed, 53 insertions(+), 15 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 4e63af754..cb64f8a3b 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -83,6 +83,10 @@ _BrowserWindow::~_BrowserWindow() GlobalSettings::getInstance().setBoolState("windows.browser.show community creations", _showCommunityCreations); GlobalSettings::getInstance().setBoolState("windows.browser.first start", false); GlobalSettings::getInstance().setFloatState("windows.browser.user table width", _userTableWidth); + GlobalSettings::getInstance().setStringState( + "windows.browser.simulations.collapsed folders", NetworkResourceService::convertFolderNamesToSettings(_simulations.collapsedFolderNames)); + GlobalSettings::getInstance().setStringState( + "windows.browser.genomes.collapsed folders", NetworkResourceService::convertFolderNamesToSettings(_genomes.collapsedFolderNames)); NetworkService::getInstance().shutdown(); } @@ -93,8 +97,16 @@ void _BrowserWindow::registerCyclicReferences(LoginDialogWeakPtr const& loginDia auto firstStart = GlobalSettings::getInstance().getBoolState("windows.browser.first start", true); refreshIntern(firstStart); - _simulations.collapsedFolderNames = NetworkResourceService::calcInitialCollapsedFolderNames(_simulations.rawTOs); - _genomes.collapsedFolderNames = NetworkResourceService::calcInitialCollapsedFolderNames(_genomes.rawTOs); + + auto initialCollapsedSimulationFolders = NetworkResourceService::convertFolderNamesToSettings(NetworkResourceService::calcInitialCollapsedFolderNames(_simulations.rawTOs)); + auto collapsedSimulationFolders = GlobalSettings::getInstance().getStringState("windows.browser.simulations.collapsed folders", initialCollapsedSimulationFolders); + _simulations.collapsedFolderNames = NetworkResourceService::convertSettingsToFolderNames(collapsedSimulationFolders); + + auto initialCollapsedGenomeFolders = + NetworkResourceService::convertFolderNamesToSettings(NetworkResourceService::calcInitialCollapsedFolderNames(_simulations.rawTOs)); + auto collapsedGenomeFolders = + GlobalSettings::getInstance().getStringState("windows.browser.genomes.collapsed folders", initialCollapsedGenomeFolders); + _genomes.collapsedFolderNames = NetworkResourceService::convertSettingsToFolderNames(collapsedGenomeFolders); } void _BrowserWindow::onRefresh() @@ -126,7 +138,7 @@ void _BrowserWindow::refreshIntern(bool withRetry) } } } - filteredRawTOs(); + filterRawTOs(); _scheduleCreateTreeTOs = true; if (networkService.getLoggedInUserName()) { @@ -274,7 +286,7 @@ void _BrowserWindow::processSimulationList() | ImGuiTableFlags_SortMulti | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX; - if (ImGui::BeginTable("Browser", 12, flags, ImVec2(0, 0), 0.0f)) { + if (ImGui::BeginTable("Browser", 11, flags, ImVec2(0, 0), 0.0f)) { ImGui::TableSetupColumn("Simulation", ImGuiTableColumnFlags_WidthFixed, scale(210.0f), NetworkResourceColumnId_SimulationName); ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthFixed, scale(200.0f), NetworkResourceColumnId_Description); ImGui::TableSetupColumn("Reactions", ImGuiTableColumnFlags_WidthFixed, scale(120.0f), NetworkResourceColumnId_Likes); @@ -362,8 +374,8 @@ void _BrowserWindow::processSimulationList() ImGui::PopStyleColor(); ImGui::TableNextColumn(); ImGui::TableNextColumn(); - //ImGui::Dummy({scale(18.0f), 0}); - //ImGui::SameLine(); + auto pos = ImGui::GetCursorScreenPos(); + ImGui::SetCursorScreenPos({pos.x + scale(3.0f), pos.y}); ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserFolderPropertiesTextColor); AlienImGui::Text("(" + std::to_string(folder.numReactions) + ")"); ImGui::PopStyleColor(); @@ -385,7 +397,7 @@ void _BrowserWindow::processGenomeList() | ImGuiTableFlags_SortMulti | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX; - if (ImGui::BeginTable("Browser", 10, flags, ImVec2(0, 0), 0.0f)) { + if (ImGui::BeginTable("Browser", 9, flags, ImVec2(0, 0), 0.0f)) { ImGui::TableSetupColumn( "Genome", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, @@ -590,12 +602,12 @@ void _BrowserWindow::processFilter() { ImGui::Spacing(); if (AlienImGui::ToggleButton(AlienImGui::ToggleButtonParameters().name("Community creations"), _showCommunityCreations)) { - filteredRawTOs(); + filterRawTOs(); _scheduleCreateTreeTOs = true; } ImGui::SameLine(); if (AlienImGui::InputText(AlienImGui::InputTextParameters().name("Filter"), _filter)) { - filteredRawTOs(); + filterRawTOs(); _scheduleCreateTreeTOs = true; } } @@ -949,7 +961,7 @@ void _BrowserWindow::sortUserList() std::sort(_userTOs.begin(), _userTOs.end(), [&](auto const& left, auto const& right) { return UserTO::compareOnlineAndTimestamp(left, right) > 0; }); } -void _BrowserWindow::filteredRawTOs() +void _BrowserWindow::filterRawTOs() { _simulations.rawTOs.clear(); _simulations.rawTOs.reserve(_unfilteredRawTOs.size()); diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index 5bb215eca..1d9566bc4 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -65,7 +65,7 @@ class _BrowserWindow : public _AlienWindow void sortRawTOs(std::vector& tos, ImGuiTableSortSpecs* sortSpecs); void sortUserList(); - void filteredRawTOs(); + void filterRawTOs(); void onDownloadItem(BrowserLeaf const& leaf); void onDeleteItem(BrowserLeaf const& leaf); diff --git a/source/Network/NetworkResourceService.cpp b/source/Network/NetworkResourceService.cpp index d5b871fb3..d2a73cb66 100644 --- a/source/Network/NetworkResourceService.cpp +++ b/source/Network/NetworkResourceService.cpp @@ -243,3 +243,26 @@ std::set> NetworkResourceService::calcInitialCollapsedF } return result; } + +std::string NetworkResourceService::convertFolderNamesToSettings(std::set> const& data) +{ + std::vector parts; + for (auto const& folderNames : data) { + parts.emplace_back(boost::join(folderNames, "/")); + } + return boost::join(parts, "\\"); +} + +std::set> NetworkResourceService::convertSettingsToFolderNames(std::string const& data) +{ + std::vector parts; + boost::split(parts, data, boost::is_any_of("\\")); + + std::set> result; + for (auto const& part : parts) { + std::vector splittedParts; + boost::split(splittedParts, part, boost::is_any_of("/")); + result.insert(splittedParts); + } + return result; +} diff --git a/source/Network/NetworkResourceService.h b/source/Network/NetworkResourceService.h index d75309611..5673da4c0 100644 --- a/source/Network/NetworkResourceService.h +++ b/source/Network/NetworkResourceService.h @@ -13,4 +13,7 @@ class NetworkResourceService std::set> const& collapsedFolderNames); static std::set> calcInitialCollapsedFolderNames(std::vector const& browserData); + + static std::string convertFolderNamesToSettings(std::set> const& data); + static std::set> convertSettingsToFolderNames(std::string const& data); }; diff --git a/source/NetworkTests/NetworkResourceServiceTests.cpp b/source/NetworkTests/NetworkResourceServiceTests.cpp index 2d2fcf05a..3def6967c 100644 --- a/source/NetworkTests/NetworkResourceServiceTests.cpp +++ b/source/NetworkTests/NetworkResourceServiceTests.cpp @@ -21,7 +21,7 @@ TEST_F(NetworkResourceServiceTests, nameWithoutFolder) inputTO->simName = "test"; inputTOs.emplace_back(inputTO); - auto outputTOs = NetworkResourceService::createTreeTOs(inputTOs); + auto outputTOs = NetworkResourceService::createTreeTOs(inputTOs, {}); ASSERT_EQ(1, outputTOs.size()); } @@ -33,7 +33,7 @@ TEST_F(NetworkResourceServiceTests, nameWithFolder) inputTO->simName = "folder/test"; inputTOs.emplace_back(inputTO); - auto outputTOs = NetworkResourceService::createTreeTOs(inputTOs); + auto outputTOs = NetworkResourceService::createTreeTOs(inputTOs, {}); ASSERT_EQ(2, outputTOs.size()); { @@ -58,7 +58,7 @@ TEST_F(NetworkResourceServiceTests, nameWithTwoFolders) inputTO->simName = "folder1/folder2/test"; inputTOs.emplace_back(inputTO); - auto outputTOs = NetworkResourceService::createTreeTOs(inputTOs); + auto outputTOs = NetworkResourceService::createTreeTOs(inputTOs, {}); ASSERT_EQ(3, outputTOs.size()); { @@ -99,7 +99,7 @@ TEST_F(NetworkResourceServiceTests, twoNamesWithTwoFolders) inputTOs.emplace_back(inputTO); } - auto outputTOs = NetworkResourceService::createTreeTOs(inputTOs); + auto outputTOs = NetworkResourceService::createTreeTOs(inputTOs, {}); ASSERT_EQ(6, outputTOs.size()); { From bdba2764f7953e927dfbf024dee0b00903ce56b3 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Fri, 29 Dec 2023 09:01:30 +0100 Subject: [PATCH 31/40] processing table fields refactored --- source/Gui/BrowserWindow.cpp | 359 ++++++++++++++++++++++------------- source/Gui/BrowserWindow.h | 16 +- source/Gui/StyleRepository.h | 19 +- 3 files changed, 245 insertions(+), 149 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index cb64f8a3b..ca7d42c54 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -319,7 +319,7 @@ void _BrowserWindow::processSimulationList() clipper.Begin(_simulations.treeTOs.size()); while (clipper.Step()) for (int row = clipper.DisplayStart; row < clipper.DisplayEnd; row++) { - auto item = _simulations.treeTOs[row]; + auto treeTO = _simulations.treeTOs[row]; ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); @@ -330,57 +330,32 @@ void _BrowserWindow::processSimulationList() //ImGui::Selectable("", &selected, selectable_flags, ImVec2(0, scale(RowHeight - 3.0f))); //ImGui::SameLine(); - if (item->isLeaf()) { - auto& leaf = item->getLeaf(); - - processFolderTreeSymbols(item, _simulations.collapsedFolderNames); - processDownloadButton(leaf); - ImGui::SameLine(); - processShortenedText(leaf.simName); - - ImGui::TableNextColumn(); - processShortenedText(leaf.description); - ImGui::TableNextColumn(); - processReactionList(item); - ImGui::TableNextColumn(); - pushTextColor(item); - AlienImGui::Text(leaf.timestamp); - ImGui::TableNextColumn(); - processShortenedText(leaf.userName); - - ImGui::TableNextColumn(); - AlienImGui::Text(std::to_string(leaf.numDownloads)); - ImGui::TableNextColumn(); - AlienImGui::Text(std::to_string(leaf.width)); - ImGui::TableNextColumn(); - AlienImGui::Text(std::to_string(leaf.height)); - ImGui::TableNextColumn(); - AlienImGui::Text(StringHelper::format(leaf.particles / 1000) + " K"); - ImGui::TableNextColumn(); - AlienImGui::Text(StringHelper::format(leaf.contentSize / 1024) + " KB"); - ImGui::TableNextColumn(); - AlienImGui::Text(leaf.version); + pushTextColor(treeTO); - ImGui::PopStyleColor(); - } else { - auto& folder = item->getFolder(); + processResourceNameField(treeTO, _simulations.collapsedFolderNames); + ImGui::TableNextColumn(); + processDescriptionField(treeTO); + ImGui::TableNextColumn(); + processReactionList(treeTO); + ImGui::TableNextColumn(); + processTimestampField(treeTO); + ImGui::TableNextColumn(); + processUserNameField(treeTO); + ImGui::TableNextColumn(); + processNumDownloadsField(treeTO); + ImGui::TableNextColumn(); + processWidthField(treeTO); + ImGui::TableNextColumn(); + processHeightField(treeTO); + ImGui::TableNextColumn(); + processNumParticlesField(treeTO); + ImGui::TableNextColumn(); + processSizeField(treeTO); + ImGui::TableNextColumn(); + processVersionField(treeTO); - processFolderTreeSymbols(item, _simulations.collapsedFolderNames); - processShortenedText(item->folderNames.back()); - ImGui::SameLine(); - ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserFolderPropertiesTextColor); - std::string numSimsString = folder.numLeafs == 1 ? "sim" : "sims"; - AlienImGui::Text("(" + std::to_string(folder.numLeafs) + " " + numSimsString + ")"); - ImGui::PopStyleColor(); - ImGui::TableNextColumn(); - ImGui::TableNextColumn(); - auto pos = ImGui::GetCursorScreenPos(); - ImGui::SetCursorScreenPos({pos.x + scale(3.0f), pos.y}); - ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserFolderPropertiesTextColor); - AlienImGui::Text("(" + std::to_string(folder.numReactions) + ")"); - ImGui::PopStyleColor(); + popTextColor(); - } ImGui::PopID(); } ImGui::EndTable(); @@ -612,23 +587,203 @@ void _BrowserWindow::processFilter() } } -void _BrowserWindow::processFolderTreeSymbols(NetworkResourceTreeTO const& entry, std::set>& collapsedFolderNames) +void _BrowserWindow::processResourceNameField(NetworkResourceTreeTO const& treeTO, std::set>& collapsedFolderNames) +{ + if (treeTO->isLeaf()) { + auto& leaf = treeTO->getLeaf(); + + processFolderTreeSymbols(treeTO, _simulations.collapsedFolderNames); + processDownloadButton(leaf); + ImGui::SameLine(); + processShortenedText(leaf.simName); + } else { + auto& folder = treeTO->getFolder(); + + processFolderTreeSymbols(treeTO, _simulations.collapsedFolderNames); + processShortenedText(treeTO->folderNames.back()); + ImGui::SameLine(); + ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserFolderPropertiesTextColor); + std::string numSimsString = folder.numLeafs == 1 ? "sim" : "sims"; + AlienImGui::Text("(" + std::to_string(folder.numLeafs) + " " + numSimsString + ")"); + ImGui::PopStyleColor(); + } +} + +void _BrowserWindow::processDescriptionField(NetworkResourceTreeTO const& treeTO) +{ + if (treeTO->isLeaf()) { + auto& leaf = treeTO->getLeaf(); + processShortenedText(leaf.description); + } +} + +void _BrowserWindow::processReactionList(NetworkResourceTreeTO const& treeTO) +{ + if (treeTO->isLeaf()) { + auto& leaf = treeTO->getLeaf(); + ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserDownloadButtonTextColor); + auto isAddReaction = processActionButton(ICON_FA_PLUS); + ImGui::PopStyleColor(); + AlienImGui::Tooltip("Add a reaction"); + if (isAddReaction) { + _activateEmojiPopup = true; + _emojiPopupTO = treeTO; + } + + //calc remap which allows to show most frequent like type first + std::map remap; + std::set processedEmojiTypes; + + int index = 0; + while (processedEmojiTypes.size() < leaf.numLikesByEmojiType.size()) { + int maxLikes = 0; + std::optional maxEmojiType; + for (auto const& [emojiType, numLikes] : leaf.numLikesByEmojiType) { + if (!processedEmojiTypes.contains(emojiType) && numLikes > maxLikes) { + maxLikes = numLikes; + maxEmojiType = emojiType; + } + } + processedEmojiTypes.insert(*maxEmojiType); + remap.emplace(index, *maxEmojiType); + ++index; + } + + //show like types with count + int counter = 0; + std::optional toggleEmojiType; + for (auto const& emojiType : remap | std::views::values) { + auto numLikes = leaf.numLikesByEmojiType.at(emojiType); + + ImGui::SameLine(); + AlienImGui::Text(std::to_string(numLikes)); + ImGui::SameLine(); + if (emojiType < _emojis.size()) { + auto const& emoji = _emojis.at(emojiType); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - scale(7.0f)); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + scale(1.0f)); + ImGui::PushStyleColor(ImGuiCol_Button, static_cast(Const::ToolbarButtonBackgroundColor)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, static_cast(Const::ToolbarButtonHoveredColor)); + auto cursorPos = ImGui::GetCursorScreenPos(); + auto emojiWidth = scale(toFloat(emoji.width) / 2.5f); + auto emojiHeight = scale(toFloat(emoji.height) / 2.5f); + if (ImGui::ImageButton((void*)(intptr_t)emoji.textureId, {emojiWidth, emojiHeight}, ImVec2(0, 0), ImVec2(1, 1), 0)) { + toggleEmojiType = emojiType; + } + bool isLiked = _ownEmojiTypeBySimId.contains(leaf.id) && _ownEmojiTypeBySimId.at(leaf.id) == emojiType; + if (isLiked) { + ImDrawList* drawList = ImGui::GetWindowDrawList(); + drawList->AddRect( + ImVec2(cursorPos.x, cursorPos.y), + ImVec2(cursorPos.x + emojiWidth, cursorPos.y + emojiHeight), + (ImU32)ImColor::HSV(0, 0, 1, 0.5f), + 1.0f); + } + ImGui::PopStyleColor(2); + AlienImGui::Tooltip([=, this] { return getUserNamesToEmojiType(leaf.id, emojiType); }, false); + } + + //separator except for last element + if (++counter < leaf.numLikesByEmojiType.size()) { + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - scale(4.0f)); + } + } + if (toggleEmojiType) { + onToggleLike(treeTO, *toggleEmojiType); + } + } else { + auto& folder = treeTO->getFolder(); + + auto pos = ImGui::GetCursorScreenPos(); + ImGui::SetCursorScreenPos({pos.x + scale(3.0f), pos.y}); + ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserFolderPropertiesTextColor); + AlienImGui::Text("(" + std::to_string(folder.numReactions) + ")"); + ImGui::PopStyleColor(); + } +} + +void _BrowserWindow::processTimestampField(NetworkResourceTreeTO const& treeTO) +{ + if (treeTO->isLeaf()) { + auto& leaf = treeTO->getLeaf(); + AlienImGui::Text(leaf.timestamp); + } +} + +void _BrowserWindow::processUserNameField(NetworkResourceTreeTO const& treeTO) +{ + if (treeTO->isLeaf()) { + auto& leaf = treeTO->getLeaf(); + processShortenedText(leaf.userName); + } +} + +void _BrowserWindow::processNumDownloadsField(NetworkResourceTreeTO const& treeTO) +{ + if (treeTO->isLeaf()) { + auto& leaf = treeTO->getLeaf(); + AlienImGui::Text(std::to_string(leaf.numDownloads)); + } +} + +void _BrowserWindow::processWidthField(NetworkResourceTreeTO const& treeTO) +{ + if (treeTO->isLeaf()) { + auto& leaf = treeTO->getLeaf(); + AlienImGui::Text(std::to_string(leaf.width)); + } +} + +void _BrowserWindow::processHeightField(NetworkResourceTreeTO const& treeTO) +{ + if (treeTO->isLeaf()) { + auto& leaf = treeTO->getLeaf(); + AlienImGui::Text(std::to_string(leaf.height)); + } +} + +void _BrowserWindow::processNumParticlesField(NetworkResourceTreeTO const& treeTO) +{ + if (treeTO->isLeaf()) { + auto& leaf = treeTO->getLeaf(); + AlienImGui::Text(StringHelper::format(leaf.particles / 1000) + " K"); + } +} + +void _BrowserWindow::processSizeField(NetworkResourceTreeTO const& treeTO) +{ + if (treeTO->isLeaf()) { + auto& leaf = treeTO->getLeaf(); + AlienImGui::Text(StringHelper::format(leaf.contentSize / 1024) + " KB"); + } +} + +void _BrowserWindow::processVersionField(NetworkResourceTreeTO const& treeTO) { - auto const& treeSymbols = entry->treeSymbols; + if (treeTO->isLeaf()) { + auto& leaf = treeTO->getLeaf(); + AlienImGui::Text(leaf.version); + } +} + +void _BrowserWindow::processFolderTreeSymbols(NetworkResourceTreeTO const& treeTO, std::set>& collapsedFolderNames) +{ + ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserFolderSymbolColor); ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0, 0, 0, 0)); + auto const& treeSymbols = treeTO->treeSymbols; for (auto const& folderLine : treeSymbols) { ImVec2 pos = ImGui::GetCursorScreenPos(); ImGuiStyle& style = ImGui::GetStyle(); switch (folderLine) { case FolderTreeSymbols::Expanded: { if (AlienImGui::Button(ICON_FA_MINUS_SQUARE, 20.0f)) { - collapsedFolderNames.insert(entry->folderNames); + collapsedFolderNames.insert(treeTO->folderNames); _scheduleCreateTreeTOs = true; } } break; case FolderTreeSymbols::Collapsed: { if (AlienImGui::Button(ICON_FA_PLUS_SQUARE, 20.0f)) { - collapsedFolderNames.erase(entry->folderNames); + collapsedFolderNames.erase(treeTO->folderNames); _scheduleCreateTreeTOs = true; } } break; @@ -677,7 +832,7 @@ void _BrowserWindow::processFolderTreeSymbols(NetworkResourceTreeTO const& entry } ImGui::SameLine(); } - ImGui::PopStyleColor(1); + ImGui::PopStyleColor(2); } void _BrowserWindow::processEmojiWindow() @@ -754,84 +909,9 @@ void _BrowserWindow::processEmojiButton(int emojiType) } } -void _BrowserWindow::processReactionList(NetworkResourceTreeTO const& to) -{ - ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DownloadButtonTextColor); - auto isAddReaction = processActionButton(ICON_FA_PLUS); - ImGui::PopStyleColor(); - AlienImGui::Tooltip("Add a reaction"); - if (isAddReaction) { - _activateEmojiPopup = true; - _emojiPopupTO = to; - } - - //calc remap which allows to show most frequent like type first - std::map remap; - std::set processedEmojiTypes; - - int index = 0; - auto& leaf = to->getLeaf(); - while (processedEmojiTypes.size() < leaf.numLikesByEmojiType.size()) { - int maxLikes = 0; - std::optional maxEmojiType; - for (auto const& [emojiType, numLikes] : leaf.numLikesByEmojiType) { - if (!processedEmojiTypes.contains(emojiType) && numLikes > maxLikes) { - maxLikes = numLikes; - maxEmojiType = emojiType; - } - } - processedEmojiTypes.insert(*maxEmojiType); - remap.emplace(index, *maxEmojiType); - ++index; - } - - //show like types with count - int counter = 0; - std::optional toggleEmojiType; - for (auto const& emojiType : remap | std::views::values) { - auto numLikes = leaf.numLikesByEmojiType.at(emojiType); - - ImGui::SameLine(); - AlienImGui::Text(std::to_string(numLikes)); - ImGui::SameLine(); - if (emojiType < _emojis.size()) { - auto const& emoji = _emojis.at(emojiType); - ImGui::SetCursorPosX(ImGui::GetCursorPosX() - scale(7.0f)); - ImGui::SetCursorPosY(ImGui::GetCursorPosY() + scale(1.0f)); - ImGui::PushStyleColor(ImGuiCol_Button, static_cast(Const::ToolbarButtonBackgroundColor)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, static_cast(Const::ToolbarButtonHoveredColor)); - auto cursorPos = ImGui::GetCursorScreenPos(); - auto emojiWidth = scale(toFloat(emoji.width) / 2.5f); - auto emojiHeight = scale(toFloat(emoji.height) / 2.5f); - if (ImGui::ImageButton((void*)(intptr_t)emoji.textureId, {emojiWidth, emojiHeight}, - ImVec2(0, 0), - ImVec2(1, 1), - 0)) { - toggleEmojiType = emojiType; - } - bool isLiked = _ownEmojiTypeBySimId.contains(leaf.id) && _ownEmojiTypeBySimId.at(leaf.id) == emojiType; - if (isLiked) { - ImDrawList* drawList = ImGui::GetWindowDrawList(); - drawList->AddRect( - ImVec2(cursorPos.x, cursorPos.y), ImVec2(cursorPos.x + emojiWidth, cursorPos.y + emojiHeight), (ImU32)ImColor::HSV(0, 0, 1, 0.5f), 1.0f); - } - ImGui::PopStyleColor(2); - AlienImGui::Tooltip([=, this] { return getUserNamesToEmojiType(leaf.id, emojiType); }, false); - } - - //separator except for last element - if (++counter < leaf.numLikesByEmojiType.size()) { - ImGui::SetCursorPosX(ImGui::GetCursorPosX() - scale(4.0f)); - } - } - if (toggleEmojiType) { - onToggleLike(to, *toggleEmojiType); - } -} - void _BrowserWindow::processDownloadButton(BrowserLeaf const& leaf) { - ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DownloadButtonTextColor); + ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserDownloadButtonTextColor); auto downloadButtonResult = processActionButton(ICON_FA_DOWNLOAD); ImGui::PopStyleColor(); if (downloadButtonResult) { @@ -849,7 +929,7 @@ void _BrowserWindow::processActionButtons(NetworkResourceTreeTO const& to) // auto const& leaf = to->getLeaf(); // auto liked = isLiked(leaf.id); // if (liked) { - // ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::AddReactionButtonTextColor); + // ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserAddReactionButtonTextColor); // } else { // ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::NoLikeButtonTextColor); // } @@ -863,7 +943,7 @@ void _BrowserWindow::processActionButtons(NetworkResourceTreeTO const& to) // ImGui::SameLine(); // //download button - // ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DownloadButtonTextColor); + // ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserDownloadButtonTextColor); // auto downloadButtonResult = processActionButton(ICON_FA_DOWNLOAD); // ImGui::PopStyleColor(); // if (downloadButtonResult) { @@ -874,7 +954,7 @@ void _BrowserWindow::processActionButtons(NetworkResourceTreeTO const& to) // //delete button // if (leaf.userName == networkService.getLoggedInUserName().value_or("")) { - // ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::DeleteButtonTextColor); + // ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserDeleteButtonTextColor); // auto deleteButtonResult = processActionButton(ICON_FA_TRASH); // ImGui::PopStyleColor(); // if (deleteButtonResult) { @@ -1130,13 +1210,18 @@ void _BrowserWindow::pushTextColor(NetworkResourceTreeTO const& to) if (to->isLeaf()) { auto const& leaf = to->getLeaf(); if (VersionChecker::isVersionOutdated(leaf.version)) { - ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::VersionOutdatedColor); + ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::BrowserVersionOutdatedTextColor); } else if (VersionChecker::isVersionNewer(leaf.version)) { - ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::VersionNewerColor); + ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::BrowserVersionNewerTextColor); } else { - ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::VersionOkColor); + ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::BrowserVersionOkTextColor); } } else { - ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::DirectoryColor); + ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::BrowserFolderTextColor); } } + +void _BrowserWindow::popTextColor() +{ + ImGui::PopStyleColor(); +} diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index 1d9566bc4..d88fed869 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -48,10 +48,21 @@ class _BrowserWindow : public _AlienWindow void processFilter(); void processToolbar(); - void processFolderTreeSymbols(NetworkResourceTreeTO const& entry, std::set>& collapsedFolderNames); + void processResourceNameField(NetworkResourceTreeTO const& treeTO, std::set>& collapsedFolderNames); + void processDescriptionField(NetworkResourceTreeTO const& treeTO); + void processReactionList(NetworkResourceTreeTO const& treeTO); + void processTimestampField(NetworkResourceTreeTO const& treeTO); + void processUserNameField(NetworkResourceTreeTO const& treeTO); + void processNumDownloadsField(NetworkResourceTreeTO const& treeTO); + void processWidthField(NetworkResourceTreeTO const& treeTO); + void processHeightField(NetworkResourceTreeTO const& treeTO); + void processNumParticlesField(NetworkResourceTreeTO const& treeTO); + void processSizeField(NetworkResourceTreeTO const& treeTO); + void processVersionField(NetworkResourceTreeTO const& treeTO); + + void processFolderTreeSymbols(NetworkResourceTreeTO const& treeTO, std::set>& collapsedFolderNames); void processEmojiWindow(); void processEmojiButton(int emojiType); - void processReactionList(NetworkResourceTreeTO const& to); void processDownloadButton(BrowserLeaf const& leaf); void processActionButtons(NetworkResourceTreeTO const& to); @@ -76,6 +87,7 @@ class _BrowserWindow : public _AlienWindow std::string getUserNamesToEmojiType(std::string const& simId, int emojiType); void pushTextColor(NetworkResourceTreeTO const& to); + void popTextColor(); NetworkResourceType _selectedDataType = NetworkResourceType_Simulation; bool _scheduleRefresh = false; diff --git a/source/Gui/StyleRepository.h b/source/Gui/StyleRepository.h index d6826b89f..ab3bfdb42 100644 --- a/source/Gui/StyleRepository.h +++ b/source/Gui/StyleRepository.h @@ -55,19 +55,9 @@ namespace Const ImColor const InspectorLineColor = ImColor::HSV(0.54f, 0.0f, 1.0f, 1.0f); ImColor const InspectorRectColor = ImColor::HSV(0.54f, 0.0f, 0.5f, 1.0f); - ImColor const AddReactionButtonTextColor = ImColor::HSV(0.375f, 0.6f, 0.7f, 1.0f); - ImColor const DownloadButtonTextColor = ImColor::HSV(0.55f, 0.6f, 1.0f, 1.0f); - ImColor const DeleteButtonTextColor = ImColor::HSV(0.0f, 0.6f, 0.8f, 1.0f); - ImColor const NavigationCursorColor = ImColor::HSV(0, 0.0f, 1.0f, 0.4f); ImColor const EditCursorColor = ImColor::HSV(0.6, 0.6f, 1.0f, 0.7f); - ImColor const VersionOkColor = ImColor::HSV(0.58f, 0.0f, 1.0f); - ImColor const VersionOutdatedColor = ImColor::HSV(0.0f, 0.0f, 0.6f); - ImColor const VersionNewerColor = ImColor::HSV(0.0f, 0.2f, 1.0f); - - ImColor const DirectoryColor = ImColor::HSV(0.58f, 0.3f, 1.0f); - ImColor const GenomePreviewConnectionColor = ImColor::HSV(0, 0, 0.5f); ImColor const GenomePreviewDotSymbolColor = ImColor::HSV(0, 0, 0.7f); ImColor const GenomePreviewInfinitySymbolColor = ImColor::HSV(0, 0, 0.7f); @@ -81,8 +71,17 @@ namespace Const ImColor const NeuronEditorZeroLinePlotColor = ImColor::HSV(0.6f, 1.0f, 0.7f); ImColor const NeuronEditorPlotColor = ImColor::HSV(0.0f, 0.0f, 1.0f); + ImColor const BrowserAddReactionButtonTextColor = ImColor::HSV(0.375f, 0.6f, 0.7f, 1.0f); + ImColor const BrowserDownloadButtonTextColor = ImColor::HSV(0.55f, 0.6f, 1.0f, 1.0f); + ImColor const BrowserDeleteButtonTextColor = ImColor::HSV(0.0f, 0.6f, 0.8f, 1.0f); + ImColor const BrowserFolderTextColor = ImColor::HSV(0.0f, 0.0f, 1.0f); ImColor const BrowserFolderLineColor = ImColor::HSV(0.0f, 0.0f, 0.5f); ImColor const BrowserFolderPropertiesTextColor = ImColor::HSV(0.0f, 0.0f, 0.5f, 1.0f); + ImColor const BrowserFolderSymbolColor = ImColor::HSV(0.0f, 0.0f, 1.0f, 1.0f); + + ImColor const BrowserVersionOkTextColor = ImColor::HSV(0.58f, 0.0f, 1.0f); + ImColor const BrowserVersionOutdatedTextColor = ImColor::HSV(0.0f, 0.0f, 0.6f); + ImColor const BrowserVersionNewerTextColor = ImColor::HSV(0.0f, 0.2f, 1.0f); float const WindowAlpha = 0.9f; float const SliderBarWidth = 30.0f; From 8012d4c1d4d2e10f5e4b6b7a92a91fda95bae74d Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Fri, 29 Dec 2023 09:26:38 +0100 Subject: [PATCH 32/40] processing table fields refactored, part 2 + layout improvements --- source/Gui/BrowserWindow.cpp | 99 +++++++++++++++--------------------- source/Gui/BrowserWindow.h | 2 +- source/Gui/StyleRepository.h | 2 +- 3 files changed, 44 insertions(+), 59 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index ca7d42c54..1308c894d 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -324,7 +324,6 @@ void _BrowserWindow::processSimulationList() ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); - ImGui::TableNextColumn(); //ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap; //static bool selected = true; //ImGui::Selectable("", &selected, selectable_flags, ImVec2(0, scale(RowHeight - 3.0f))); @@ -332,6 +331,7 @@ void _BrowserWindow::processSimulationList() pushTextColor(treeTO); + ImGui::TableNextColumn(); processResourceNameField(treeTO, _simulations.collapsedFolderNames); ImGui::TableNextColumn(); processDescriptionField(treeTO); @@ -350,7 +350,7 @@ void _BrowserWindow::processSimulationList() ImGui::TableNextColumn(); processNumParticlesField(treeTO); ImGui::TableNextColumn(); - processSizeField(treeTO); + processSizeField(treeTO, true); ImGui::TableNextColumn(); processVersionField(treeTO); @@ -373,35 +373,19 @@ void _BrowserWindow::processGenomeList() | ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX; if (ImGui::BeginTable("Browser", 9, flags, ImVec2(0, 0), 0.0f)) { - ImGui::TableSetupColumn( - "Genome", - ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, - styleRepository.scale(160.0f), - NetworkResourceColumnId_SimulationName); - ImGui::TableSetupColumn( - "Description", - ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, - styleRepository.scale(120.0f), - NetworkResourceColumnId_Description); - ImGui::TableSetupColumn( - "Reactions", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), NetworkResourceColumnId_Likes); - //ImGui::TableSetupColumn( - // "Actions", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed, scale(90.0f), NetworkResourceColumnId_Actions); + ImGui::TableSetupColumn("Genome", ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(210.0f), NetworkResourceColumnId_SimulationName); + ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(200.0f), NetworkResourceColumnId_Description); + ImGui::TableSetupColumn("Reactions", ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), NetworkResourceColumnId_Likes); ImGui::TableSetupColumn( "Timestamp", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_PreferSortDescending, scale(135.0f), NetworkResourceColumnId_Timestamp); - ImGui::TableSetupColumn( - "User name", - ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, - styleRepository.scale(120.0f), - NetworkResourceColumnId_UserName); - ImGui::TableSetupColumn( - "Downloads", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_NumDownloads); - ImGui::TableSetupColumn("Cells", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Particles); - ImGui::TableSetupColumn("File size", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_FileSize); - ImGui::TableSetupColumn("Version", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Version); + ImGui::TableSetupColumn("User name", ImGuiTableColumnFlags_WidthFixed, styleRepository.scale(120.0f), NetworkResourceColumnId_UserName); + ImGui::TableSetupColumn("Downloads", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_NumDownloads); + ImGui::TableSetupColumn("Cells", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Particles); + ImGui::TableSetupColumn("File size", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_FileSize); + ImGui::TableSetupColumn("Version", ImGuiTableColumnFlags_WidthFixed, 0.0f, NetworkResourceColumnId_Version); ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableHeadersRow(); @@ -420,37 +404,34 @@ void _BrowserWindow::processGenomeList() while (clipper.Step()) for (int row = clipper.DisplayStart; row < clipper.DisplayEnd; row++) { - auto& item = _genomes.treeTOs[row]; + auto& treeTO = _genomes.treeTOs[row]; ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); - if (item->isLeaf()) { - auto& leaf = item->getLeaf(); - - ImGui::TableNextColumn(); - processShortenedText(leaf.simName); - ImGui::TableNextColumn(); - processShortenedText(leaf.description); - ImGui::TableNextColumn(); - processReactionList(item); - //ImGui::TableNextColumn(); - //processActionButtons(item); - ImGui::TableNextColumn(); - pushTextColor(item); - AlienImGui::Text(leaf.timestamp); - ImGui::TableNextColumn(); - processShortenedText(leaf.userName); - ImGui::TableNextColumn(); - AlienImGui::Text(std::to_string(leaf.numDownloads)); - ImGui::TableNextColumn(); - AlienImGui::Text(StringHelper::format(leaf.particles)); - ImGui::TableNextColumn(); - AlienImGui::Text(StringHelper::format(leaf.contentSize) + " Bytes"); - ImGui::TableNextColumn(); - AlienImGui::Text(leaf.version); - - ImGui::PopStyleColor(); - } + + pushTextColor(treeTO); + + ImGui::TableNextColumn(); + processResourceNameField(treeTO, _genomes.collapsedFolderNames); + ImGui::TableNextColumn(); + processDescriptionField(treeTO); + ImGui::TableNextColumn(); + processReactionList(treeTO); + ImGui::TableNextColumn(); + processTimestampField(treeTO); + ImGui::TableNextColumn(); + processUserNameField(treeTO); + ImGui::TableNextColumn(); + processNumDownloadsField(treeTO); + ImGui::TableNextColumn(); + processNumParticlesField(treeTO); + ImGui::TableNextColumn(); + processSizeField(treeTO, false); + ImGui::TableNextColumn(); + processVersionField(treeTO); + + popTextColor(); + ImGui::PopID(); } ImGui::EndTable(); @@ -595,7 +576,7 @@ void _BrowserWindow::processResourceNameField(NetworkResourceTreeTO const& treeT processFolderTreeSymbols(treeTO, _simulations.collapsedFolderNames); processDownloadButton(leaf); ImGui::SameLine(); - processShortenedText(leaf.simName); + processShortenedText(leaf.simName, true); } else { auto& folder = treeTO->getFolder(); @@ -750,11 +731,15 @@ void _BrowserWindow::processNumParticlesField(NetworkResourceTreeTO const& treeT } } -void _BrowserWindow::processSizeField(NetworkResourceTreeTO const& treeTO) +void _BrowserWindow::processSizeField(NetworkResourceTreeTO const& treeTO, bool kbyte) { if (treeTO->isLeaf()) { auto& leaf = treeTO->getLeaf(); - AlienImGui::Text(StringHelper::format(leaf.contentSize / 1024) + " KB"); + if (kbyte) { + AlienImGui::Text(StringHelper::format(leaf.contentSize / 1024) + " KB"); + } else { + AlienImGui::Text(StringHelper::format(leaf.contentSize) + " Bytes"); + } } } diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index d88fed869..7e656235d 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -57,7 +57,7 @@ class _BrowserWindow : public _AlienWindow void processWidthField(NetworkResourceTreeTO const& treeTO); void processHeightField(NetworkResourceTreeTO const& treeTO); void processNumParticlesField(NetworkResourceTreeTO const& treeTO); - void processSizeField(NetworkResourceTreeTO const& treeTO); + void processSizeField(NetworkResourceTreeTO const& treeTO, bool kbyte); void processVersionField(NetworkResourceTreeTO const& treeTO); void processFolderTreeSymbols(NetworkResourceTreeTO const& treeTO, std::set>& collapsedFolderNames); diff --git a/source/Gui/StyleRepository.h b/source/Gui/StyleRepository.h index ab3bfdb42..fa70621c9 100644 --- a/source/Gui/StyleRepository.h +++ b/source/Gui/StyleRepository.h @@ -79,7 +79,7 @@ namespace Const ImColor const BrowserFolderPropertiesTextColor = ImColor::HSV(0.0f, 0.0f, 0.5f, 1.0f); ImColor const BrowserFolderSymbolColor = ImColor::HSV(0.0f, 0.0f, 1.0f, 1.0f); - ImColor const BrowserVersionOkTextColor = ImColor::HSV(0.58f, 0.0f, 1.0f); + ImColor const BrowserVersionOkTextColor = ImColor::HSV(0.58f, 0.2f, 1.0f); ImColor const BrowserVersionOutdatedTextColor = ImColor::HSV(0.0f, 0.0f, 0.6f); ImColor const BrowserVersionNewerTextColor = ImColor::HSV(0.0f, 0.2f, 1.0f); From a8584e59e183ec6b3f8ae9c4f7013b25f2e93134 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Fri, 29 Dec 2023 10:04:41 +0100 Subject: [PATCH 33/40] simplifying code: treeTOs refer to rawTOs --- source/Gui/BrowserWindow.cpp | 72 +++++++++++------------ source/Network/NetworkResourceService.cpp | 17 +----- source/Network/NetworkResourceTreeTO.h | 13 +--- 3 files changed, 38 insertions(+), 64 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 1308c894d..c5157bf50 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -576,7 +576,7 @@ void _BrowserWindow::processResourceNameField(NetworkResourceTreeTO const& treeT processFolderTreeSymbols(treeTO, _simulations.collapsedFolderNames); processDownloadButton(leaf); ImGui::SameLine(); - processShortenedText(leaf.simName, true); + processShortenedText(leaf.rawTO->simName, true); } else { auto& folder = treeTO->getFolder(); @@ -594,7 +594,7 @@ void _BrowserWindow::processDescriptionField(NetworkResourceTreeTO const& treeTO { if (treeTO->isLeaf()) { auto& leaf = treeTO->getLeaf(); - processShortenedText(leaf.description); + processShortenedText(leaf.rawTO->description); } } @@ -616,10 +616,10 @@ void _BrowserWindow::processReactionList(NetworkResourceTreeTO const& treeTO) std::set processedEmojiTypes; int index = 0; - while (processedEmojiTypes.size() < leaf.numLikesByEmojiType.size()) { + while (processedEmojiTypes.size() < leaf.rawTO->numLikesByEmojiType.size()) { int maxLikes = 0; std::optional maxEmojiType; - for (auto const& [emojiType, numLikes] : leaf.numLikesByEmojiType) { + for (auto const& [emojiType, numLikes] : leaf.rawTO->numLikesByEmojiType) { if (!processedEmojiTypes.contains(emojiType) && numLikes > maxLikes) { maxLikes = numLikes; maxEmojiType = emojiType; @@ -634,15 +634,14 @@ void _BrowserWindow::processReactionList(NetworkResourceTreeTO const& treeTO) int counter = 0; std::optional toggleEmojiType; for (auto const& emojiType : remap | std::views::values) { - auto numLikes = leaf.numLikesByEmojiType.at(emojiType); + auto numLikes = leaf.rawTO->numLikesByEmojiType.at(emojiType); ImGui::SameLine(); AlienImGui::Text(std::to_string(numLikes)); - ImGui::SameLine(); if (emojiType < _emojis.size()) { + ImGui::SameLine(); auto const& emoji = _emojis.at(emojiType); ImGui::SetCursorPosX(ImGui::GetCursorPosX() - scale(7.0f)); - ImGui::SetCursorPosY(ImGui::GetCursorPosY() + scale(1.0f)); ImGui::PushStyleColor(ImGuiCol_Button, static_cast(Const::ToolbarButtonBackgroundColor)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, static_cast(Const::ToolbarButtonHoveredColor)); auto cursorPos = ImGui::GetCursorScreenPos(); @@ -651,21 +650,20 @@ void _BrowserWindow::processReactionList(NetworkResourceTreeTO const& treeTO) if (ImGui::ImageButton((void*)(intptr_t)emoji.textureId, {emojiWidth, emojiHeight}, ImVec2(0, 0), ImVec2(1, 1), 0)) { toggleEmojiType = emojiType; } - bool isLiked = _ownEmojiTypeBySimId.contains(leaf.id) && _ownEmojiTypeBySimId.at(leaf.id) == emojiType; + bool isLiked = _ownEmojiTypeBySimId.contains(leaf.rawTO->id) && _ownEmojiTypeBySimId.at(leaf.rawTO->id) == emojiType; if (isLiked) { - ImDrawList* drawList = ImGui::GetWindowDrawList(); - drawList->AddRect( + ImGui::GetWindowDrawList()->AddRect( ImVec2(cursorPos.x, cursorPos.y), ImVec2(cursorPos.x + emojiWidth, cursorPos.y + emojiHeight), (ImU32)ImColor::HSV(0, 0, 1, 0.5f), 1.0f); } ImGui::PopStyleColor(2); - AlienImGui::Tooltip([=, this] { return getUserNamesToEmojiType(leaf.id, emojiType); }, false); + AlienImGui::Tooltip([=, this] { return getUserNamesToEmojiType(leaf.rawTO->id, emojiType); }, false); } //separator except for last element - if (++counter < leaf.numLikesByEmojiType.size()) { + if (++counter < leaf.rawTO->numLikesByEmojiType.size()) { ImGui::SetCursorPosX(ImGui::GetCursorPosX() - scale(4.0f)); } } @@ -687,7 +685,7 @@ void _BrowserWindow::processTimestampField(NetworkResourceTreeTO const& treeTO) { if (treeTO->isLeaf()) { auto& leaf = treeTO->getLeaf(); - AlienImGui::Text(leaf.timestamp); + AlienImGui::Text(leaf.rawTO->timestamp); } } @@ -695,7 +693,7 @@ void _BrowserWindow::processUserNameField(NetworkResourceTreeTO const& treeTO) { if (treeTO->isLeaf()) { auto& leaf = treeTO->getLeaf(); - processShortenedText(leaf.userName); + processShortenedText(leaf.rawTO->userName); } } @@ -703,7 +701,7 @@ void _BrowserWindow::processNumDownloadsField(NetworkResourceTreeTO const& treeT { if (treeTO->isLeaf()) { auto& leaf = treeTO->getLeaf(); - AlienImGui::Text(std::to_string(leaf.numDownloads)); + AlienImGui::Text(std::to_string(leaf.rawTO->numDownloads)); } } @@ -711,7 +709,7 @@ void _BrowserWindow::processWidthField(NetworkResourceTreeTO const& treeTO) { if (treeTO->isLeaf()) { auto& leaf = treeTO->getLeaf(); - AlienImGui::Text(std::to_string(leaf.width)); + AlienImGui::Text(std::to_string(leaf.rawTO->width)); } } @@ -719,7 +717,7 @@ void _BrowserWindow::processHeightField(NetworkResourceTreeTO const& treeTO) { if (treeTO->isLeaf()) { auto& leaf = treeTO->getLeaf(); - AlienImGui::Text(std::to_string(leaf.height)); + AlienImGui::Text(std::to_string(leaf.rawTO->height)); } } @@ -727,7 +725,7 @@ void _BrowserWindow::processNumParticlesField(NetworkResourceTreeTO const& treeT { if (treeTO->isLeaf()) { auto& leaf = treeTO->getLeaf(); - AlienImGui::Text(StringHelper::format(leaf.particles / 1000) + " K"); + AlienImGui::Text(StringHelper::format(leaf.rawTO->particles / 1000) + " K"); } } @@ -736,9 +734,9 @@ void _BrowserWindow::processSizeField(NetworkResourceTreeTO const& treeTO, bool if (treeTO->isLeaf()) { auto& leaf = treeTO->getLeaf(); if (kbyte) { - AlienImGui::Text(StringHelper::format(leaf.contentSize / 1024) + " KB"); + AlienImGui::Text(StringHelper::format(leaf.rawTO->contentSize / 1024) + " KB"); } else { - AlienImGui::Text(StringHelper::format(leaf.contentSize) + " Bytes"); + AlienImGui::Text(StringHelper::format(leaf.rawTO->contentSize) + " Bytes"); } } } @@ -747,7 +745,7 @@ void _BrowserWindow::processVersionField(NetworkResourceTreeTO const& treeTO) { if (treeTO->isLeaf()) { auto& leaf = treeTO->getLeaf(); - AlienImGui::Text(leaf.version); + AlienImGui::Text(leaf.rawTO->version); } } @@ -882,7 +880,7 @@ void _BrowserWindow::processEmojiButton(int emojiType) } ImGui::PopStyleColor(2); - bool isLiked = _ownEmojiTypeBySimId.contains(leaf.id) && _ownEmojiTypeBySimId.at(leaf.id) == emojiType; + bool isLiked = _ownEmojiTypeBySimId.contains(leaf.rawTO->id) && _ownEmojiTypeBySimId.at(leaf.rawTO->id) == emojiType; if (isLiked) { ImDrawList* drawList = ImGui::GetWindowDrawList(); auto& style = ImGui::GetStyle(); @@ -1051,7 +1049,7 @@ void _BrowserWindow::onDownloadItem(BrowserLeaf const& leaf) auto& networkService = NetworkService::getInstance(); std::string dataTypeString = _selectedDataType == NetworkResourceType_Simulation ? "simulation" : "genome"; SerializedSimulation serializedSim; - if (!networkService.downloadSimulation(serializedSim.mainData, serializedSim.auxiliaryData, serializedSim.statistics, leaf.id)) { + if (!networkService.downloadSimulation(serializedSim.mainData, serializedSim.auxiliaryData, serializedSim.statistics, leaf.rawTO->id)) { MessageDialog::getInstance().information("Error", "Failed to download " + dataTypeString + "."); return; } @@ -1097,7 +1095,7 @@ void _BrowserWindow::onDownloadItem(BrowserLeaf const& leaf) _editorController->setOn(true); _editorController->getGenomeEditorWindow()->openTab(GenomeDescriptionService::convertBytesToDescription(genome)); } - if (VersionChecker::isVersionNewer(leaf.version)) { + if (VersionChecker::isVersionNewer(leaf.rawTO->version)) { MessageDialog::getInstance().information( "Warning", "The download was successful but the " + dataTypeString +" was generated using a more recent\n" @@ -1114,7 +1112,7 @@ void _BrowserWindow::onDeleteItem(BrowserLeaf const& leaf) delayedExecution([leafCopy = leaf, this] { auto& networkService = NetworkService::getInstance(); - if (!networkService.deleteSimulation(leafCopy.id)) { + if (!networkService.deleteSimulation(leafCopy.rawTO->id)) { MessageDialog::getInstance().information("Error", "Failed to delete item. Please try again later."); return; } @@ -1131,30 +1129,30 @@ void _BrowserWindow::onToggleLike(NetworkResourceTreeTO const& to, int emojiType if (networkService.getLoggedInUserName()) { //remove existing like - auto findResult = _ownEmojiTypeBySimId.find(leaf.id); + auto findResult = _ownEmojiTypeBySimId.find(leaf.rawTO->id); auto onlyRemoveLike = false; if (findResult != _ownEmojiTypeBySimId.end()) { auto origEmojiType = findResult->second; - if (--leaf.numLikesByEmojiType[origEmojiType] == 0) { - leaf.numLikesByEmojiType.erase(origEmojiType); + if (--leaf.rawTO->numLikesByEmojiType[origEmojiType] == 0) { + leaf.rawTO->numLikesByEmojiType.erase(origEmojiType); } _ownEmojiTypeBySimId.erase(findResult); - _userNamesByEmojiTypeBySimIdCache.erase(std::make_pair(leaf.id, origEmojiType)); //invalidate cache entry + _userNamesByEmojiTypeBySimIdCache.erase(std::make_pair(leaf.rawTO->id, origEmojiType)); //invalidate cache entry onlyRemoveLike = origEmojiType == emojiType; //remove like if same like icon has been clicked } //create new like if (!onlyRemoveLike) { - _ownEmojiTypeBySimId[leaf.id] = emojiType; - if (leaf.numLikesByEmojiType.contains(emojiType)) { - ++leaf.numLikesByEmojiType[emojiType]; + _ownEmojiTypeBySimId[leaf.rawTO->id] = emojiType; + if (leaf.rawTO->numLikesByEmojiType.contains(emojiType)) { + ++leaf.rawTO->numLikesByEmojiType[emojiType]; } else { - leaf.numLikesByEmojiType[emojiType] = 1; + leaf.rawTO->numLikesByEmojiType[emojiType] = 1; } } - _userNamesByEmojiTypeBySimIdCache.erase(std::make_pair(leaf.id, emojiType)); //invalidate cache entry - networkService.toggleLikeSimulation(leaf.id, emojiType); + _userNamesByEmojiTypeBySimIdCache.erase(std::make_pair(leaf.rawTO->id, emojiType)); //invalidate cache entry + networkService.toggleLikeSimulation(leaf.rawTO->id, emojiType); //_scheduleCreateTreeTOs = true; } else { _loginDialog.lock()->open(); @@ -1194,9 +1192,9 @@ void _BrowserWindow::pushTextColor(NetworkResourceTreeTO const& to) { if (to->isLeaf()) { auto const& leaf = to->getLeaf(); - if (VersionChecker::isVersionOutdated(leaf.version)) { + if (VersionChecker::isVersionOutdated(leaf.rawTO->version)) { ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::BrowserVersionOutdatedTextColor); - } else if (VersionChecker::isVersionNewer(leaf.version)) { + } else if (VersionChecker::isVersionNewer(leaf.rawTO->version)) { ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::BrowserVersionNewerTextColor); } else { ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)Const::BrowserVersionOkTextColor); diff --git a/source/Network/NetworkResourceService.cpp b/source/Network/NetworkResourceService.cpp index d2a73cb66..f5f3cc834 100644 --- a/source/Network/NetworkResourceService.cpp +++ b/source/Network/NetworkResourceService.cpp @@ -78,20 +78,7 @@ std::vector NetworkResourceService::createTreeTOs( //insert leaf auto treeTO = std::make_shared<_NetworkResourceTreeTO>(); - BrowserLeaf leaf{ - .id = rawTO->id, - .timestamp = rawTO->timestamp, - .userName = rawTO->userName, - .simName = nameWithoutFolders, - .numLikesByEmojiType = rawTO->numLikesByEmojiType, - .numDownloads = rawTO->numDownloads, - .width = rawTO->width, - .height = rawTO->height, - .particles = rawTO->particles, - .contentSize = rawTO->contentSize, - .description = rawTO->description, - .version = rawTO->version - }; + BrowserLeaf leaf{.rawTO = rawTO}; treeTO->type = rawTO->type; treeTO->folderNames = folderNames; treeTO->node = leaf; @@ -177,7 +164,7 @@ std::vector NetworkResourceService::createTreeTOs( auto& treeTO = treeTOs.at(i); if (treeTO->isLeaf()) { int numReactions = 0; - for (auto const& count : treeTO->getLeaf().numLikesByEmojiType | std::views::values) { + for (auto const& count : treeTO->getLeaf().rawTO->numLikesByEmojiType | std::views::values) { numReactions += count; } for (int j = i - 1; j >= 0; --j) { diff --git a/source/Network/NetworkResourceTreeTO.h b/source/Network/NetworkResourceTreeTO.h index d1539503e..947b26a7b 100644 --- a/source/Network/NetworkResourceTreeTO.h +++ b/source/Network/NetworkResourceTreeTO.h @@ -15,18 +15,7 @@ struct BrowserFolder struct BrowserLeaf { - std::string id; - std::string timestamp; - std::string userName; - std::string simName; - std::map numLikesByEmojiType; - int numDownloads; - int width; - int height; - int particles; - uint64_t contentSize; - std::string description; - std::string version; + NetworkResourceRawTO rawTO; }; enum class FolderTreeSymbols From 21b2b2f862349d38feaddf8613b2cbfd6faad2e9 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Fri, 29 Dec 2023 10:47:03 +0100 Subject: [PATCH 34/40] make browser items selectable --- source/Gui/BrowserWindow.cpp | 37 +++++++++++++++---- source/Gui/BrowserWindow.h | 1 + source/Gui/MainWindow.cpp | 14 ++++--- source/Gui/StyleRepository.h | 6 +++ .../NetworkResourceServiceTests.cpp | 8 ++-- 5 files changed, 49 insertions(+), 17 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index c5157bf50..3b47ff816 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -323,15 +323,20 @@ void _BrowserWindow::processSimulationList() ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); + ImGui::TableNextColumn(); - //ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap; - //static bool selected = true; - //ImGui::Selectable("", &selected, selectable_flags, ImVec2(0, scale(RowHeight - 3.0f))); - //ImGui::SameLine(); + auto selected = _simulations.selected == treeTO; + if (ImGui::Selectable( + "", + &selected, + ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap, + ImVec2(0, scale(RowHeight) - ImGui::GetStyle().FramePadding.y))) { + _simulations.selected = selected ? treeTO : nullptr; + } + ImGui::SameLine(); pushTextColor(treeTO); - ImGui::TableNextColumn(); processResourceNameField(treeTO, _simulations.collapsedFolderNames); ImGui::TableNextColumn(); processDescriptionField(treeTO); @@ -408,10 +413,20 @@ void _BrowserWindow::processGenomeList() ImGui::PushID(row); ImGui::TableNextRow(0, scale(RowHeight)); + ImGui::TableNextColumn(); + + auto selected = _genomes.selected == treeTO; + if (ImGui::Selectable( + "", + &selected, + ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap, + ImVec2(0, scale(RowHeight) - ImGui::GetStyle().FramePadding.y))) { + _genomes.selected = selected ? treeTO : nullptr; + } + ImGui::SameLine(); pushTextColor(treeTO); - ImGui::TableNextColumn(); processResourceNameField(treeTO, _genomes.collapsedFolderNames); ImGui::TableNextColumn(); processDescriptionField(treeTO); @@ -584,8 +599,14 @@ void _BrowserWindow::processResourceNameField(NetworkResourceTreeTO const& treeT processShortenedText(treeTO->folderNames.back()); ImGui::SameLine(); ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserFolderPropertiesTextColor); - std::string numSimsString = folder.numLeafs == 1 ? "sim" : "sims"; - AlienImGui::Text("(" + std::to_string(folder.numLeafs) + " " + numSimsString + ")"); + std::string resourceTypeString = [&] { + if (treeTO->type == NetworkResourceType_Simulation) { + return folder.numLeafs == 1 ? "sim" : "sims"; + } else { + return folder.numLeafs == 1 ? "genome" : "genomes"; + } + }(); + AlienImGui::Text("(" + std::to_string(folder.numLeafs) + " " + resourceTypeString + ")"); ImGui::PopStyleColor(); } } diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index 7e656235d..8058b887f 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -33,6 +33,7 @@ class _BrowserWindow : public _AlienWindow std::vector rawTOs; std::vector treeTOs; std::set> collapsedFolderNames; + NetworkResourceTreeTO selected; }; void refreshIntern(bool withRetry); diff --git a/source/Gui/MainWindow.cpp b/source/Gui/MainWindow.cpp index a1ed8e875..69e3467c7 100644 --- a/source/Gui/MainWindow.cpp +++ b/source/Gui/MainWindow.cpp @@ -195,6 +195,12 @@ void _MainWindow::mainLoop() // ImGui::ShowDemoWindow(NULL); + ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, Const::SliderBarWidth); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, Const::WindowsRounding); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, (ImVec4)Const::HeaderHoveredColor); + ImGui::PushStyleColor(ImGuiCol_HeaderActive, (ImVec4)Const::HeaderActiveColor); + ImGui::PushStyleColor(ImGuiCol_Header, (ImVec4)Const::HeaderColor); + switch (_startupController->getState()) { case _StartupController::State::Unintialized: processUninitialized(); @@ -214,6 +220,9 @@ void _MainWindow::mainLoop() default: THROW_NOT_IMPLEMENTED(); } + ImGui::PopStyleColor(3); + ImGui::PopStyleVar(2); + } } @@ -320,9 +329,6 @@ void _MainWindow::processLoadingControls() void _MainWindow::processReady() { - ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, Const::SliderBarWidth); - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 10); - processMenubar(); processDialogs(); processWindows(); @@ -330,8 +336,6 @@ void _MainWindow::processReady() _uiController->process(); _simulationView->processControls(_renderSimulation); - ImGui::PopStyleVar(2); - renderSimulation(); } diff --git a/source/Gui/StyleRepository.h b/source/Gui/StyleRepository.h index fa70621c9..733bed14f 100644 --- a/source/Gui/StyleRepository.h +++ b/source/Gui/StyleRepository.h @@ -17,6 +17,11 @@ namespace Const int64_t const TextDecentColor = 0xff909090; int64_t const TextInfoColor = 0xff308787; + ImColor const HeaderColor = ImColor::HSV(0.58f, 0.7f, 0.3f); + ImColor const HeaderActiveColor = ImColor::HSV(0.58f, 0.7f, 0.5f); + ImColor const HeaderHoveredColor = ImColor::HSV(0.58f, 0.7f, 0.4f); + + ImColor const MenuButtonColor = ImColor::HSV(0.6f, 0.6f, 0.5f); ImColor const MenuButtonHoveredColor = ImColor::HSV(0.6f, 1.0f, 1.0f); ImColor const MenuButtonActiveColor = ImColor::HSV(0.6f, 0.8f, 0.7f); @@ -85,6 +90,7 @@ namespace Const float const WindowAlpha = 0.9f; float const SliderBarWidth = 30.0f; + float const WindowsRounding = 10.0f; } class StyleRepository diff --git a/source/NetworkTests/NetworkResourceServiceTests.cpp b/source/NetworkTests/NetworkResourceServiceTests.cpp index 3def6967c..244c88230 100644 --- a/source/NetworkTests/NetworkResourceServiceTests.cpp +++ b/source/NetworkTests/NetworkResourceServiceTests.cpp @@ -47,7 +47,7 @@ TEST_F(NetworkResourceServiceTests, nameWithFolder) EXPECT_TRUE(outputTO->isLeaf()); EXPECT_EQ(1, outputTO->folderNames.size()); EXPECT_EQ(std::string("folder"), outputTO->folderNames.front()); - EXPECT_EQ(std::string("test"), outputTO->getLeaf().simName); + EXPECT_EQ(std::string("test"), outputTO->getLeaf().rawTO->simName); } } @@ -80,7 +80,7 @@ TEST_F(NetworkResourceServiceTests, nameWithTwoFolders) EXPECT_EQ(2, outputTO->folderNames.size()); EXPECT_EQ(std::string("folder1"), outputTO->folderNames.at(0)); EXPECT_EQ(std::string("folder2"), outputTO->folderNames.at(1)); - EXPECT_EQ(std::string("test"), outputTO->getLeaf().simName); + EXPECT_EQ(std::string("test"), outputTO->getLeaf().rawTO->simName); } } @@ -121,7 +121,7 @@ TEST_F(NetworkResourceServiceTests, twoNamesWithTwoFolders) EXPECT_EQ(2, outputTO->folderNames.size()); EXPECT_EQ(std::string("A"), outputTO->folderNames.at(0)); EXPECT_EQ(std::string("B"), outputTO->folderNames.at(1)); - EXPECT_EQ(std::string("C"), outputTO->getLeaf().simName); + EXPECT_EQ(std::string("C"), outputTO->getLeaf().rawTO->simName); } { auto outputTO = outputTOs.at(3); @@ -142,6 +142,6 @@ TEST_F(NetworkResourceServiceTests, twoNamesWithTwoFolders) EXPECT_EQ(2, outputTO->folderNames.size()); EXPECT_EQ(std::string("X"), outputTO->folderNames.at(0)); EXPECT_EQ(std::string("Y"), outputTO->folderNames.at(1)); - EXPECT_EQ(std::string("Z"), outputTO->getLeaf().simName); + EXPECT_EQ(std::string("Z"), outputTO->getLeaf().rawTO->simName); } } From ba6f643182482d7b08ad6d2028e0e239b87cb7ba Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Fri, 29 Dec 2023 11:13:06 +0100 Subject: [PATCH 35/40] allow deletion of selected browser items --- source/Gui/BrowserWindow.cpp | 29 ++++++++++++++++++++--------- source/Gui/BrowserWindow.h | 2 +- source/Gui/GenomeEditorWindow.cpp | 2 +- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 3b47ff816..81b9e2eff 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -227,6 +227,7 @@ void _BrowserWindow::processBackground() void _BrowserWindow::processToolbar() { auto& networkService = NetworkService::getInstance(); + std::string resourceTypeString = _selectedDataType == NetworkResourceType_Simulation ? "simulation" : "genome"; if (AlienImGui::ToolbarButton(ICON_FA_SYNC)) { onRefresh(); @@ -258,16 +259,26 @@ void _BrowserWindow::processToolbar() AlienImGui::ToolbarSeparator(); ImGui::SameLine(); - if (AlienImGui::ToolbarButton(ICON_FA_SHARE_ALT)) { + if (AlienImGui::ToolbarButton(ICON_FA_UPLOAD)) { _uploadSimulationDialog.lock()->open(_selectedDataType); } - std::string dataType = _selectedDataType == NetworkResourceType_Simulation - ? "simulation" - : "genome"; AlienImGui::Tooltip( - "Share your " + dataType + " with other users:\nYour current " + dataType + " will be uploaded to the server and made visible in the browser."); + "Share your current " + resourceTypeString + " with other users:\nYour current " + resourceTypeString + " will be uploaded to the server and made visible in the browser."); + + ImGui::SameLine(); + ImGui::BeginDisabled( + _selectedResource == nullptr || !_selectedResource->isLeaf() + || _selectedResource->getLeaf().rawTO->userName != networkService.getLoggedInUserName().value_or("")); + if (AlienImGui::ToolbarButton(ICON_FA_TRASH)) { + onDeleteItem(_selectedResource->getLeaf()); + } + ImGui::EndDisabled(); + AlienImGui::Tooltip("Delete selected " + resourceTypeString); #ifdef _WIN32 + ImGui::SameLine(); + AlienImGui::ToolbarSeparator(); + ImGui::SameLine(); if (AlienImGui::ToolbarButton(ICON_FA_COMMENTS)) { openWeblink(Const::DiscordLink); @@ -325,13 +336,13 @@ void _BrowserWindow::processSimulationList() ImGui::TableNextRow(0, scale(RowHeight)); ImGui::TableNextColumn(); - auto selected = _simulations.selected == treeTO; + auto selected = _selectedResource == treeTO; if (ImGui::Selectable( "", &selected, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap, ImVec2(0, scale(RowHeight) - ImGui::GetStyle().FramePadding.y))) { - _simulations.selected = selected ? treeTO : nullptr; + _selectedResource = selected ? treeTO : nullptr; } ImGui::SameLine(); @@ -415,13 +426,13 @@ void _BrowserWindow::processGenomeList() ImGui::TableNextRow(0, scale(RowHeight)); ImGui::TableNextColumn(); - auto selected = _genomes.selected == treeTO; + auto selected = _selectedResource == treeTO; if (ImGui::Selectable( "", &selected, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap, ImVec2(0, scale(RowHeight) - ImGui::GetStyle().FramePadding.y))) { - _genomes.selected = selected ? treeTO : nullptr; + _selectedResource = selected ? treeTO : nullptr; } ImGui::SameLine(); diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index 8058b887f..51e3072d1 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -33,7 +33,6 @@ class _BrowserWindow : public _AlienWindow std::vector rawTOs; std::vector treeTOs; std::set> collapsedFolderNames; - NetworkResourceTreeTO selected; }; void refreshIntern(bool withRetry); @@ -102,6 +101,7 @@ class _BrowserWindow : public _AlienWindow std::unordered_map, std::set> _userNamesByEmojiTypeBySimIdCache; std::vector _unfilteredRawTOs; + NetworkResourceTreeTO _selectedResource; ResourceData _genomes; ResourceData _simulations; diff --git a/source/Gui/GenomeEditorWindow.cpp b/source/Gui/GenomeEditorWindow.cpp index a981e50f4..81cb78e78 100644 --- a/source/Gui/GenomeEditorWindow.cpp +++ b/source/Gui/GenomeEditorWindow.cpp @@ -138,7 +138,7 @@ void _GenomeEditorWindow::processToolbar() AlienImGui::Tooltip("Save genome to file"); ImGui::SameLine(); - if (AlienImGui::ToolbarButton(ICON_FA_SHARE_ALT)) { + if (AlienImGui::ToolbarButton(ICON_FA_UPLOAD)) { onUploadGenome(); } AlienImGui::Tooltip("Share your genome with other users:\nYour current genome will be uploaded to the server and made visible in the browser."); From 217eb4a6cbe423825c6ad3f74014d11d1ee26b5c Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Fri, 29 Dec 2023 12:09:25 +0100 Subject: [PATCH 36/40] + obsolete code removed + deselect after deletion --- source/Gui/BrowserWindow.cpp | 56 +++---------------- source/Gui/BrowserWindow.h | 1 - source/Gui/MainWindow.cpp | 33 +++++++---- source/Gui/MainWindow.h | 3 + source/Gui/UploadSimulationDialog.cpp | 34 ++++++----- source/Gui/UploadSimulationDialog.h | 11 ++-- .../Network/NetworkResourceParserService.cpp | 2 +- source/Network/NetworkResourceRawTO.cpp | 4 +- source/Network/NetworkResourceRawTO.h | 2 +- source/Network/NetworkResourceService.cpp | 17 ++++-- source/Network/NetworkResourceService.h | 1 + source/Network/NetworkResourceTreeTO.h | 1 + .../NetworkResourceServiceTests.cpp | 10 ++-- 13 files changed, 84 insertions(+), 91 deletions(-) diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 81b9e2eff..6eca7e749 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -260,7 +260,13 @@ void _BrowserWindow::processToolbar() ImGui::SameLine(); if (AlienImGui::ToolbarButton(ICON_FA_UPLOAD)) { - _uploadSimulationDialog.lock()->open(_selectedDataType); + std::string prefix = [&] { + if (_selectedResource == nullptr || _selectedResource->isLeaf()) { + return std::string(); + } + return NetworkResourceService::concatenateFolderNames(_selectedResource->folderNames, true); + }(); + _uploadSimulationDialog.lock()->open(_selectedDataType, prefix); } AlienImGui::Tooltip( "Share your current " + resourceTypeString + " with other users:\nYour current " + resourceTypeString + " will be uploaded to the server and made visible in the browser."); @@ -271,6 +277,7 @@ void _BrowserWindow::processToolbar() || _selectedResource->getLeaf().rawTO->userName != networkService.getLoggedInUserName().value_or("")); if (AlienImGui::ToolbarButton(ICON_FA_TRASH)) { onDeleteItem(_selectedResource->getLeaf()); + _selectedResource = nullptr; } ImGui::EndDisabled(); AlienImGui::Tooltip("Delete selected " + resourceTypeString); @@ -602,7 +609,7 @@ void _BrowserWindow::processResourceNameField(NetworkResourceTreeTO const& treeT processFolderTreeSymbols(treeTO, _simulations.collapsedFolderNames); processDownloadButton(leaf); ImGui::SameLine(); - processShortenedText(leaf.rawTO->simName, true); + processShortenedText(leaf.leafName, true); } else { auto& folder = treeTO->getFolder(); @@ -935,51 +942,6 @@ void _BrowserWindow::processDownloadButton(BrowserLeaf const& leaf) AlienImGui::Tooltip("Download"); } -void _BrowserWindow::processActionButtons(NetworkResourceTreeTO const& to) -{ - //auto& networkService = NetworkService::getInstance(); - ////like button - - //if (to->isLeaf()) { - // auto const& leaf = to->getLeaf(); - // auto liked = isLiked(leaf.id); - // if (liked) { - // ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserAddReactionButtonTextColor); - // } else { - // ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::NoLikeButtonTextColor); - // } - // auto likeButtonResult = processActionButton(ICON_FA_STAR); - // ImGui::PopStyleColor(); - // if (likeButtonResult) { - // _activateEmojiPopup = true; - // _emojiPopupTO = to; - // } - // AlienImGui::Tooltip("Choose a reaction"); - // ImGui::SameLine(); - - // //download button - // ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserDownloadButtonTextColor); - // auto downloadButtonResult = processActionButton(ICON_FA_DOWNLOAD); - // ImGui::PopStyleColor(); - // if (downloadButtonResult) { - // onDownloadItem(leaf); - // } - // AlienImGui::Tooltip("Download"); - // ImGui::SameLine(); - - // //delete button - // if (leaf.userName == networkService.getLoggedInUserName().value_or("")) { - // ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserDeleteButtonTextColor); - // auto deleteButtonResult = processActionButton(ICON_FA_TRASH); - // ImGui::PopStyleColor(); - // if (deleteButtonResult) { - // onDeleteItem(leaf); - // } - // AlienImGui::Tooltip("Delete"); - // } - //} -} - namespace { std::vector splitString(const std::string& str) diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index 51e3072d1..37d213681 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -65,7 +65,6 @@ class _BrowserWindow : public _AlienWindow void processEmojiButton(int emojiType); void processDownloadButton(BrowserLeaf const& leaf); - void processActionButtons(NetworkResourceTreeTO const& to); void processShortenedText(std::string const& text, bool bold = false); bool processActionButton(std::string const& text); diff --git a/source/Gui/MainWindow.cpp b/source/Gui/MainWindow.cpp index 69e3467c7..378284e54 100644 --- a/source/Gui/MainWindow.cpp +++ b/source/Gui/MainWindow.cpp @@ -195,12 +195,6 @@ void _MainWindow::mainLoop() // ImGui::ShowDemoWindow(NULL); - ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, Const::SliderBarWidth); - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, Const::WindowsRounding); - ImGui::PushStyleColor(ImGuiCol_HeaderHovered, (ImVec4)Const::HeaderHoveredColor); - ImGui::PushStyleColor(ImGuiCol_HeaderActive, (ImVec4)Const::HeaderActiveColor); - ImGui::PushStyleColor(ImGuiCol_Header, (ImVec4)Const::HeaderColor); - switch (_startupController->getState()) { case _StartupController::State::Unintialized: processUninitialized(); @@ -220,9 +214,6 @@ void _MainWindow::mainLoop() default: THROW_NOT_IMPLEMENTED(); } - ImGui::PopStyleColor(3); - ImGui::PopStyleVar(2); - } } @@ -310,8 +301,7 @@ void _MainWindow::processLoadingSimulation() void _MainWindow::processLoadingControls() { - ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, Const::SliderBarWidth); - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 10); + pushGlobalStyle(); processMenubar(); processDialogs(); @@ -322,13 +312,15 @@ void _MainWindow::processLoadingControls() _simulationView->processControls(_renderSimulation); _startupController->process(); - ImGui::PopStyleVar(2); + popGlobalStyle(); renderSimulation(); } void _MainWindow::processReady() { + pushGlobalStyle(); + processMenubar(); processDialogs(); processWindows(); @@ -336,6 +328,8 @@ void _MainWindow::processReady() _uiController->process(); _simulationView->processControls(_renderSimulation); + popGlobalStyle(); + renderSimulation(); } @@ -836,3 +830,18 @@ void _MainWindow::onPauseSimulation() { _simController->pauseSimulation(); } + +void _MainWindow::pushGlobalStyle() +{ + ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, Const::SliderBarWidth); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, Const::WindowsRounding); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, (ImVec4)Const::HeaderHoveredColor); + ImGui::PushStyleColor(ImGuiCol_HeaderActive, (ImVec4)Const::HeaderActiveColor); + ImGui::PushStyleColor(ImGuiCol_Header, (ImVec4)Const::HeaderColor); +} + +void _MainWindow::popGlobalStyle() +{ + ImGui::PopStyleColor(3); + ImGui::PopStyleVar(2); +} diff --git a/source/Gui/MainWindow.h b/source/Gui/MainWindow.h index a443fb72d..c4bace529 100644 --- a/source/Gui/MainWindow.h +++ b/source/Gui/MainWindow.h @@ -33,6 +33,9 @@ class _MainWindow void onRunSimulation(); void onPauseSimulation(); + void pushGlobalStyle(); + void popGlobalStyle(); + GLFWwindow* _window; GuiLogger _logger; diff --git a/source/Gui/UploadSimulationDialog.cpp b/source/Gui/UploadSimulationDialog.cpp index e4a80d011..7eafb4b36 100644 --- a/source/Gui/UploadSimulationDialog.cpp +++ b/source/Gui/UploadSimulationDialog.cpp @@ -42,23 +42,24 @@ _UploadSimulationDialog::_UploadSimulationDialog( , _genomeEditorWindow(genomeEditorWindow) { auto& settings = GlobalSettings::getInstance(); - _simName = settings.getStringState("dialogs.upload.simulation name", ""); - _simDescription = settings.getStringState("dialogs.upload.simulation description", ""); + _resourceName = settings.getStringState("dialogs.upload.simulation name", ""); + _resourceDescription = settings.getStringState("dialogs.upload.simulation description", ""); } _UploadSimulationDialog::~_UploadSimulationDialog() { auto& settings = GlobalSettings::getInstance(); - settings.setStringState("dialogs.upload.simulation name", _simName); - settings.setStringState("dialogs.upload.simulation description", _simDescription); + settings.setStringState("dialogs.upload.simulation name", _resourceName); + settings.setStringState("dialogs.upload.simulation description", _resourceDescription); } -void _UploadSimulationDialog::open(NetworkResourceType dataType) +void _UploadSimulationDialog::open(NetworkResourceType dataType, std::string const& folder) { auto& networkService = NetworkService::getInstance(); if (networkService.getLoggedInUserName()) { changeTitle("Upload " + BrowserDataTypeToLowerString.at(dataType)); _dataType = dataType; + _folder = folder; _AlienDialog::open(); } else { _loginDialog->open(); @@ -71,20 +72,27 @@ void _UploadSimulationDialog::processIntern() AlienImGui::HelpMarker( "The " + BrowserDataTypeToLowerString.at(_dataType) + " file, name and description are stored on the server. It cannot be guaranteed that the data will not be deleted."); + + AlienImGui::Separator(); + + AlienImGui::InputText(AlienImGui::InputTextParameters().hint(BrowserDataTypeToUpperString.at(_dataType) + " name").textWidth(0), _resourceName); + ImGui::BeginDisabled(); + std::string text = "The simulation will be uploaded into the following folder:\n" + _folder; + AlienImGui::InputText(AlienImGui::InputTextParameters().hint(_folder).textWidth(0).readOnly(true), text); + ImGui::EndDisabled(); AlienImGui::Separator(); - AlienImGui::InputText(AlienImGui::InputTextParameters().hint(BrowserDataTypeToUpperString.at(_dataType) + " name").textWidth(0), _simName); AlienImGui::Separator(); AlienImGui::InputTextMultiline( AlienImGui::InputTextMultilineParameters() .hint("Description (optional)") .textWidth(0) .height(ImGui::GetContentRegionAvail().y - StyleRepository::getInstance().scale(50.0f)), - _simDescription); + _resourceDescription); AlienImGui::Separator(); - ImGui::BeginDisabled(_simName.empty()); + ImGui::BeginDisabled(_resourceName.empty()); if (AlienImGui::Button("OK")) { close(); onUpload(); @@ -95,15 +103,15 @@ void _UploadSimulationDialog::processIntern() ImGui::SameLine(); if (AlienImGui::Button("Cancel")) { close(); - _simName = _origSimName; - _simDescription = _origSimDescription; + _resourceName = _origResourceName; + _resourceDescription = _origResourceDescription; } } void _UploadSimulationDialog::openIntern() { - _origSimName = _simName; - _origSimDescription = _simDescription; + _origResourceName = _resourceName; + _origResourceDescription = _resourceDescription; } void _UploadSimulationDialog::onUpload() @@ -154,7 +162,7 @@ void _UploadSimulationDialog::onUpload() } auto& networkService = NetworkService::getInstance(); - if (!networkService.uploadSimulation(_simName, _simDescription, size, numObjects, mainData, settings, statistics, _dataType)) { + if (!networkService.uploadSimulation(_resourceName, _resourceDescription, size, numObjects, mainData, settings, statistics, _dataType)) { showMessage("Error", "Failed to upload " + BrowserDataTypeToLowerString.at(_dataType) + "."); return; } diff --git a/source/Gui/UploadSimulationDialog.h b/source/Gui/UploadSimulationDialog.h index f3dc0371c..c5f091fc5 100644 --- a/source/Gui/UploadSimulationDialog.h +++ b/source/Gui/UploadSimulationDialog.h @@ -17,7 +17,7 @@ class _UploadSimulationDialog : public _AlienDialog GenomeEditorWindow const& genomeEditorWindow); ~_UploadSimulationDialog(); - void open(NetworkResourceType dataType); + void open(NetworkResourceType dataType, std::string const& folder = ""); private: void processIntern(); @@ -25,11 +25,12 @@ class _UploadSimulationDialog : public _AlienDialog void onUpload(); - std::string _simName; - std::string _simDescription; + std::string _folder; + std::string _resourceName; + std::string _resourceDescription; - std::string _origSimName; - std::string _origSimDescription; + std::string _origResourceName; + std::string _origResourceDescription; NetworkResourceType _dataType = NetworkResourceType_Simulation; diff --git a/source/Network/NetworkResourceParserService.cpp b/source/Network/NetworkResourceParserService.cpp index 044b6782d..f5b6e0261 100644 --- a/source/Network/NetworkResourceParserService.cpp +++ b/source/Network/NetworkResourceParserService.cpp @@ -9,7 +9,7 @@ std::vector NetworkResourceParserService::decodeRemoteSimu auto entry = std::make_shared<_NetworkResourceRawTO>(); entry->id = subTree.get("id"); entry->userName = subTree.get("userName"); - entry->simName = subTree.get("simulationName"); + entry->resourceName = subTree.get("simulationName"); entry->description= subTree.get("description"); entry->width = subTree.get("width"); entry->height = subTree.get("height"); diff --git a/source/Network/NetworkResourceRawTO.cpp b/source/Network/NetworkResourceRawTO.cpp index c8e69b4ec..8fa36b148 100644 --- a/source/Network/NetworkResourceRawTO.cpp +++ b/source/Network/NetworkResourceRawTO.cpp @@ -16,7 +16,7 @@ int _NetworkResourceRawTO::compare(NetworkResourceRawTO const& left, NetworkReso delta = left->userName.compare(right->userName); break; case NetworkResourceColumnId_SimulationName: - delta = left->simName.compare(right->simName); + delta = left->resourceName.compare(right->resourceName); break; case NetworkResourceColumnId_Description: delta = left->description.compare(right->description); @@ -63,7 +63,7 @@ bool _NetworkResourceRawTO::matchWithFilter(std::string const& filter) const if (userName.find(filter) != std::string::npos) { match = true; } - if (simName.find(filter) != std::string::npos) { + if (resourceName.find(filter) != std::string::npos) { match = true; } if (std::to_string(numDownloads).find(filter) != std::string::npos) { diff --git a/source/Network/NetworkResourceRawTO.h b/source/Network/NetworkResourceRawTO.h index a18710d8a..0067791d2 100644 --- a/source/Network/NetworkResourceRawTO.h +++ b/source/Network/NetworkResourceRawTO.h @@ -28,7 +28,7 @@ struct _NetworkResourceRawTO std::string id; std::string timestamp; std::string userName; - std::string simName; + std::string resourceName; std::map numLikesByEmojiType; int numDownloads; int width; diff --git a/source/Network/NetworkResourceService.cpp b/source/Network/NetworkResourceService.cpp index f5f3cc834..6cc9ee7de 100644 --- a/source/Network/NetworkResourceService.cpp +++ b/source/Network/NetworkResourceService.cpp @@ -34,7 +34,7 @@ std::vector NetworkResourceService::createTreeTOs( //parse folder names std::vector folderNames; std::string nameWithoutFolders; - boost::split(folderNames, rawTO->simName, boost::is_any_of("/")); + boost::split(folderNames, rawTO->resourceName, boost::is_any_of("/")); if (!folderNames.empty()) { nameWithoutFolders = folderNames.back(); folderNames.pop_back(); @@ -78,7 +78,7 @@ std::vector NetworkResourceService::createTreeTOs( //insert leaf auto treeTO = std::make_shared<_NetworkResourceTreeTO>(); - BrowserLeaf leaf{.rawTO = rawTO}; + BrowserLeaf leaf{.leafName = nameWithoutFolders, .rawTO = rawTO}; treeTO->type = rawTO->type; treeTO->folderNames = folderNames; treeTO->node = leaf; @@ -223,7 +223,7 @@ std::set> NetworkResourceService::calcInitialCollapsedF std::set> result; for (auto const& rawTO : rawTOs) { std::vector folderNames; - boost::split(folderNames, rawTO->simName, boost::is_any_of("/")); + boost::split(folderNames, rawTO->resourceName, boost::is_any_of("/")); for (int i = 0; i < toInt(folderNames.size()) - 2; ++i) { result.insert(std::vector(folderNames.begin(), folderNames.begin() + 2 + i)); } @@ -231,11 +231,20 @@ std::set> NetworkResourceService::calcInitialCollapsedF return result; } +std::string NetworkResourceService::concatenateFolderNames(std::vector const& folderNames, bool withSlash) +{ + auto result = boost::join(folderNames, "/"); + if (withSlash) { + result.append("/"); + } + return result; +} + std::string NetworkResourceService::convertFolderNamesToSettings(std::set> const& data) { std::vector parts; for (auto const& folderNames : data) { - parts.emplace_back(boost::join(folderNames, "/")); + parts.emplace_back(concatenateFolderNames(folderNames, false)); } return boost::join(parts, "\\"); } diff --git a/source/Network/NetworkResourceService.h b/source/Network/NetworkResourceService.h index 5673da4c0..d0d97da79 100644 --- a/source/Network/NetworkResourceService.h +++ b/source/Network/NetworkResourceService.h @@ -14,6 +14,7 @@ class NetworkResourceService static std::set> calcInitialCollapsedFolderNames(std::vector const& browserData); + static std::string concatenateFolderNames(std::vector const& folderNames, bool withSlash); static std::string convertFolderNamesToSettings(std::set> const& data); static std::set> convertSettingsToFolderNames(std::string const& data); }; diff --git a/source/Network/NetworkResourceTreeTO.h b/source/Network/NetworkResourceTreeTO.h index 947b26a7b..2a415b196 100644 --- a/source/Network/NetworkResourceTreeTO.h +++ b/source/Network/NetworkResourceTreeTO.h @@ -15,6 +15,7 @@ struct BrowserFolder struct BrowserLeaf { + std::string leafName; NetworkResourceRawTO rawTO; }; diff --git a/source/NetworkTests/NetworkResourceServiceTests.cpp b/source/NetworkTests/NetworkResourceServiceTests.cpp index 244c88230..5ba14f0e6 100644 --- a/source/NetworkTests/NetworkResourceServiceTests.cpp +++ b/source/NetworkTests/NetworkResourceServiceTests.cpp @@ -18,7 +18,7 @@ TEST_F(NetworkResourceServiceTests, nameWithoutFolder) { std::vector inputTOs; auto inputTO = std::make_shared<_NetworkResourceRawTO>(); - inputTO->simName = "test"; + inputTO->resourceName = "test"; inputTOs.emplace_back(inputTO); auto outputTOs = NetworkResourceService::createTreeTOs(inputTOs, {}); @@ -30,7 +30,7 @@ TEST_F(NetworkResourceServiceTests, nameWithFolder) { std::vector inputTOs; auto inputTO = std::make_shared<_NetworkResourceRawTO>(); - inputTO->simName = "folder/test"; + inputTO->resourceName = "folder/test"; inputTOs.emplace_back(inputTO); auto outputTOs = NetworkResourceService::createTreeTOs(inputTOs, {}); @@ -55,7 +55,7 @@ TEST_F(NetworkResourceServiceTests, nameWithTwoFolders) { std::vector inputTOs; auto inputTO = std::make_shared<_NetworkResourceRawTO>(); - inputTO->simName = "folder1/folder2/test"; + inputTO->resourceName = "folder1/folder2/test"; inputTOs.emplace_back(inputTO); auto outputTOs = NetworkResourceService::createTreeTOs(inputTOs, {}); @@ -90,12 +90,12 @@ TEST_F(NetworkResourceServiceTests, twoNamesWithTwoFolders) std::vector inputTOs; { auto inputTO = std::make_shared<_NetworkResourceRawTO>(); - inputTO->simName = "A/B/C"; + inputTO->resourceName = "A/B/C"; inputTOs.emplace_back(inputTO); } { auto inputTO = std::make_shared<_NetworkResourceRawTO>(); - inputTO->simName = "X/Y/Z"; + inputTO->resourceName = "X/Y/Z"; inputTOs.emplace_back(inputTO); } From 8431df6828fbdb47a7b1e7aae1391f53ae8ba076 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Fri, 29 Dec 2023 13:04:21 +0100 Subject: [PATCH 37/40] allow uploading simulations to a selected folder + tests fixed --- imgui.ini | 4 +-- source/Gui/BrowserWindow.cpp | 4 ++- source/Gui/UploadSimulationDialog.cpp | 30 ++++++++++++++----- .../NetworkResourceServiceTests.cpp | 8 ++--- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/imgui.ini b/imgui.ini index 80e1f9297..8a6b7f398 100644 --- a/imgui.ini +++ b/imgui.ini @@ -294,8 +294,8 @@ Size=463,153 Collapsed=0 [Window][Upload simulation] -Pos=733,403 -Size=400,218 +Pos=641,346 +Size=454,354 Collapsed=0 [Window][Upload genome] diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 6eca7e749..2da1bfc76 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -269,7 +269,9 @@ void _BrowserWindow::processToolbar() _uploadSimulationDialog.lock()->open(_selectedDataType, prefix); } AlienImGui::Tooltip( - "Share your current " + resourceTypeString + " with other users:\nYour current " + resourceTypeString + " will be uploaded to the server and made visible in the browser."); + "Share your current " + resourceTypeString + " with other users:\nThe " + resourceTypeString + + " will be uploaded to the server and made visible in the browser.\nIf you have already selected a folder, your " + resourceTypeString + + " will be uploaded there."); ImGui::SameLine(); ImGui::BeginDisabled( diff --git a/source/Gui/UploadSimulationDialog.cpp b/source/Gui/UploadSimulationDialog.cpp index 7eafb4b36..70c53e81b 100644 --- a/source/Gui/UploadSimulationDialog.cpp +++ b/source/Gui/UploadSimulationDialog.cpp @@ -20,6 +20,8 @@ namespace { + auto constexpr FolderWidgetHeight = 50.0f; + std::map const BrowserDataTypeToLowerString = { {NetworkResourceType_Simulation, "simulation"}, {NetworkResourceType_Genome, "genome"}}; @@ -68,27 +70,39 @@ void _UploadSimulationDialog::open(NetworkResourceType dataType, std::string con void _UploadSimulationDialog::processIntern() { + auto resourceTypeString = BrowserDataTypeToLowerString.at(_dataType); AlienImGui::Text("Data privacy policy"); AlienImGui::HelpMarker( - "The " + BrowserDataTypeToLowerString.at(_dataType) - + " file, name and description are stored on the server. It cannot be guaranteed that the data will not be deleted."); + "The " + resourceTypeString + " file, name and description are stored on the server. It cannot be guaranteed that the data will not be deleted."); + + AlienImGui::Text("How to use folders?"); + AlienImGui::HelpMarker("If you want to upload the " + resourceTypeString + + " to a folder, you can use the `/`-notation. The folder will be created automatically if it does not exist.\nFor instance, naming a simulation as `Biome/Water " + "world/Initial/Variant 1` will create the nested folders `Biome`, `Water world` and `Initial`."); AlienImGui::Separator(); + if (!_folder.empty()) { + std::string text = "The following folder has been selected and will used for the upload: \n" + _folder; + ImGui::PushID(1); + ImGui::BeginDisabled(); + AlienImGui::InputTextMultiline(AlienImGui::InputTextMultilineParameters().hint(_folder).textWidth(0).height(FolderWidgetHeight), text); + ImGui::EndDisabled(); + ImGui::PopID(); + } + AlienImGui::InputText(AlienImGui::InputTextParameters().hint(BrowserDataTypeToUpperString.at(_dataType) + " name").textWidth(0), _resourceName); - ImGui::BeginDisabled(); - std::string text = "The simulation will be uploaded into the following folder:\n" + _folder; - AlienImGui::InputText(AlienImGui::InputTextParameters().hint(_folder).textWidth(0).readOnly(true), text); - ImGui::EndDisabled(); - AlienImGui::Separator(); AlienImGui::Separator(); + + ImGui::PushID(2); AlienImGui::InputTextMultiline( AlienImGui::InputTextMultilineParameters() .hint("Description (optional)") .textWidth(0) .height(ImGui::GetContentRegionAvail().y - StyleRepository::getInstance().scale(50.0f)), _resourceDescription); + ImGui::PopID(); AlienImGui::Separator(); @@ -162,7 +176,7 @@ void _UploadSimulationDialog::onUpload() } auto& networkService = NetworkService::getInstance(); - if (!networkService.uploadSimulation(_resourceName, _resourceDescription, size, numObjects, mainData, settings, statistics, _dataType)) { + if (!networkService.uploadSimulation(_folder + _resourceName, _resourceDescription, size, numObjects, mainData, settings, statistics, _dataType)) { showMessage("Error", "Failed to upload " + BrowserDataTypeToLowerString.at(_dataType) + "."); return; } diff --git a/source/NetworkTests/NetworkResourceServiceTests.cpp b/source/NetworkTests/NetworkResourceServiceTests.cpp index 5ba14f0e6..300b56bd2 100644 --- a/source/NetworkTests/NetworkResourceServiceTests.cpp +++ b/source/NetworkTests/NetworkResourceServiceTests.cpp @@ -47,7 +47,7 @@ TEST_F(NetworkResourceServiceTests, nameWithFolder) EXPECT_TRUE(outputTO->isLeaf()); EXPECT_EQ(1, outputTO->folderNames.size()); EXPECT_EQ(std::string("folder"), outputTO->folderNames.front()); - EXPECT_EQ(std::string("test"), outputTO->getLeaf().rawTO->simName); + EXPECT_EQ(std::string("test"), outputTO->getLeaf().rawTO->resourceName); } } @@ -80,7 +80,7 @@ TEST_F(NetworkResourceServiceTests, nameWithTwoFolders) EXPECT_EQ(2, outputTO->folderNames.size()); EXPECT_EQ(std::string("folder1"), outputTO->folderNames.at(0)); EXPECT_EQ(std::string("folder2"), outputTO->folderNames.at(1)); - EXPECT_EQ(std::string("test"), outputTO->getLeaf().rawTO->simName); + EXPECT_EQ(std::string("test"), outputTO->getLeaf().rawTO->resourceName); } } @@ -121,7 +121,7 @@ TEST_F(NetworkResourceServiceTests, twoNamesWithTwoFolders) EXPECT_EQ(2, outputTO->folderNames.size()); EXPECT_EQ(std::string("A"), outputTO->folderNames.at(0)); EXPECT_EQ(std::string("B"), outputTO->folderNames.at(1)); - EXPECT_EQ(std::string("C"), outputTO->getLeaf().rawTO->simName); + EXPECT_EQ(std::string("C"), outputTO->getLeaf().rawTO->resourceName); } { auto outputTO = outputTOs.at(3); @@ -142,6 +142,6 @@ TEST_F(NetworkResourceServiceTests, twoNamesWithTwoFolders) EXPECT_EQ(2, outputTO->folderNames.size()); EXPECT_EQ(std::string("X"), outputTO->folderNames.at(0)); EXPECT_EQ(std::string("Y"), outputTO->folderNames.at(1)); - EXPECT_EQ(std::string("Z"), outputTO->getLeaf().rawTO->simName); + EXPECT_EQ(std::string("Z"), outputTO->getLeaf().rawTO->resourceName); } } From a5a3343eca8568a09c557f9a7249a6a77250de44 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Fri, 29 Dec 2023 13:28:50 +0100 Subject: [PATCH 38/40] RELEASE-NOTES.md --- RELEASE-NOTES.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 7bcd40622..ff1a251ab 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,5 +1,19 @@ # Release notes +## [4.6.0] - 2023-12-29 +### Added +- gui/browser: support for displaying folders and subfolders +- gui/browser: folders for simulations and genomes are automatically created by parsing their names for `/` +- gui/browser: allow uploading to a selected folder +- gui/browser: show number of simulations per folder + +### Changed +- gui/browser: tree view instead of a pure table view +- gui/browser: simulations and genomes can be selected for user actions (e.g. deletion) + +### Removed +- gui/browser: column for actions removed + ## [4.5.1] - 2023-12-16 ### Added - new simulation parameters to reduce energy particle absorption for cells with fewer connections From 5256bf4db3380201343f2e750ff786227a455956 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Fri, 29 Dec 2023 17:10:27 +0100 Subject: [PATCH 39/40] browser tab switching bug fixed --- source/Gui/AlienImGui.cpp | 2 +- source/Gui/BrowserWindow.cpp | 34 +++++++++++-------- source/Gui/BrowserWindow.h | 5 ++- source/Gui/UploadSimulationDialog.cpp | 8 ++--- .../NetworkResourceServiceTests.cpp | 8 ++--- 5 files changed, 32 insertions(+), 25 deletions(-) diff --git a/source/Gui/AlienImGui.cpp b/source/Gui/AlienImGui.cpp index 7b321b795..789eceb80 100644 --- a/source/Gui/AlienImGui.cpp +++ b/source/Gui/AlienImGui.cpp @@ -181,7 +181,7 @@ void AlienImGui::InputFloat2(InputFloat2Parameters const& parameters, float& val ImGuiInputTextFlags flags = parameters._readOnly ? ImGuiInputTextFlags_ReadOnly : ImGuiInputTextFlags_None; ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - textWidth); - float value[2]; + static float value[2]; value[0] = value1; value[1] = value2; ImGui::InputFloat2(("##" + parameters._name).c_str(), value, parameters._format.c_str(), flags); diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index 2da1bfc76..5a285a492 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -139,7 +139,7 @@ void _BrowserWindow::refreshIntern(bool withRetry) } } filterRawTOs(); - _scheduleCreateTreeTOs = true; + scheduleCreateTreeTOs(); if (networkService.getLoggedInUserName()) { if (!networkService.getEmojiTypeBySimId(_ownEmojiTypeBySimId)) { @@ -148,7 +148,6 @@ void _BrowserWindow::refreshIntern(bool withRetry) } else { _ownEmojiTypeBySimId.clear(); } - sortUserList(); } catch (std::exception const& e) { if (withRetry) { @@ -327,10 +326,10 @@ void _BrowserWindow::processSimulationList() //create table data if necessary if (ImGuiTableSortSpecs* sortSpecs = ImGui::TableGetSortSpecs()) { - if (sortSpecs->SpecsDirty || _scheduleCreateTreeTOs) { + if (sortSpecs->SpecsDirty || _scheduleCreateSimulationTreeTOs) { sortRawTOs(_simulations.rawTOs, sortSpecs); sortSpecs->SpecsDirty = false; - _scheduleCreateTreeTOs = false; + _scheduleCreateSimulationTreeTOs = false; _simulations.treeTOs = NetworkResourceService::createTreeTOs(_simulations.rawTOs, _simulations.collapsedFolderNames); } @@ -416,10 +415,10 @@ void _BrowserWindow::processGenomeList() //create table data if necessary if (ImGuiTableSortSpecs* sortSpecs = ImGui::TableGetSortSpecs()) { - if (sortSpecs->SpecsDirty || _scheduleCreateTreeTOs) { + if (sortSpecs->SpecsDirty || _scheduleCreateGenomeTreeTOs) { sortRawTOs(_genomes.rawTOs, sortSpecs); sortSpecs->SpecsDirty = false; - _scheduleCreateTreeTOs = false; + _scheduleCreateGenomeTreeTOs = false; _genomes.treeTOs = NetworkResourceService::createTreeTOs(_genomes.rawTOs, _simulations.collapsedFolderNames); } @@ -489,7 +488,7 @@ void _BrowserWindow::processUserList() { auto& networkService = NetworkService::getInstance(); - ImGui::PushID("UserTable"); + ImGui::PushID("User list"); auto& styleRepository = StyleRepository::getInstance(); static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_NoBordersInBody @@ -594,12 +593,12 @@ void _BrowserWindow::processFilter() ImGui::Spacing(); if (AlienImGui::ToggleButton(AlienImGui::ToggleButtonParameters().name("Community creations"), _showCommunityCreations)) { filterRawTOs(); - _scheduleCreateTreeTOs = true; + scheduleCreateTreeTOs(); } ImGui::SameLine(); if (AlienImGui::InputText(AlienImGui::InputTextParameters().name("Filter"), _filter)) { filterRawTOs(); - _scheduleCreateTreeTOs = true; + scheduleCreateTreeTOs(); } } @@ -802,13 +801,13 @@ void _BrowserWindow::processFolderTreeSymbols(NetworkResourceTreeTO const& treeT case FolderTreeSymbols::Expanded: { if (AlienImGui::Button(ICON_FA_MINUS_SQUARE, 20.0f)) { collapsedFolderNames.insert(treeTO->folderNames); - _scheduleCreateTreeTOs = true; + scheduleCreateTreeTOs(); } } break; case FolderTreeSymbols::Collapsed: { if (AlienImGui::Button(ICON_FA_PLUS_SQUARE, 20.0f)) { collapsedFolderNames.erase(treeTO->folderNames); - _scheduleCreateTreeTOs = true; + scheduleCreateTreeTOs(); } } break; case FolderTreeSymbols::Continue: { @@ -870,7 +869,7 @@ void _BrowserWindow::processEmojiWindow() ImGui::Spacing(); ImGui::Spacing(); if (_showAllEmojis) { - if (ImGui::BeginChild("##emojichild", ImVec2(scale(335), scale(300)), false)) { + if (ImGui::BeginChild("##reactionchild", ImVec2(scale(335), scale(300)), false)) { int offset = 0; for (int i = 0; i < NumEmojiBlocks; ++i) { for (int j = 0; j < NumEmojisPerBlock[i]; ++j) { @@ -885,7 +884,7 @@ void _BrowserWindow::processEmojiWindow() } ImGui::EndChild(); } else { - if (ImGui::BeginChild("##emojichild", ImVec2(scale(335), scale(90)), false)) { + if (ImGui::BeginChild("##reactionchild", ImVec2(scale(335), scale(90)), false)) { for (int i = 0; i < NumEmojisPerRow; ++i) { if (i % NumEmojisPerRow != 0) { ImGui::SameLine(); @@ -1006,6 +1005,12 @@ void _BrowserWindow::processActivated() onRefresh(); } +void _BrowserWindow::scheduleCreateTreeTOs() +{ + _scheduleCreateSimulationTreeTOs = true; + _scheduleCreateGenomeTreeTOs = true; +} + void _BrowserWindow::sortRawTOs(std::vector& tos, ImGuiTableSortSpecs* sortSpecs) { if (tos.size() > 1) { @@ -1025,7 +1030,7 @@ void _BrowserWindow::filterRawTOs() _simulations.rawTOs.clear(); _simulations.rawTOs.reserve(_unfilteredRawTOs.size()); _genomes.rawTOs.clear(); - _genomes.rawTOs.reserve(_genomes.rawTOs.size()); + _genomes.rawTOs.reserve(_unfilteredRawTOs.size()); for (auto const& to : _unfilteredRawTOs) { if (to->matchWithFilter(_filter) && _showCommunityCreations != to->fromRelease) { if (to->type == NetworkResourceType_Simulation) { @@ -1149,7 +1154,6 @@ void _BrowserWindow::onToggleLike(NetworkResourceTreeTO const& to, int emojiType _userNamesByEmojiTypeBySimIdCache.erase(std::make_pair(leaf.rawTO->id, emojiType)); //invalidate cache entry networkService.toggleLikeSimulation(leaf.rawTO->id, emojiType); - //_scheduleCreateTreeTOs = true; } else { _loginDialog.lock()->open(); } diff --git a/source/Gui/BrowserWindow.h b/source/Gui/BrowserWindow.h index 37d213681..2ffb95e23 100644 --- a/source/Gui/BrowserWindow.h +++ b/source/Gui/BrowserWindow.h @@ -72,6 +72,8 @@ class _BrowserWindow : public _AlienWindow void processActivated() override; + void scheduleCreateTreeTOs(); + void sortRawTOs(std::vector& tos, ImGuiTableSortSpecs* sortSpecs); void sortUserList(); @@ -90,7 +92,8 @@ class _BrowserWindow : public _AlienWindow NetworkResourceType _selectedDataType = NetworkResourceType_Simulation; bool _scheduleRefresh = false; - bool _scheduleCreateTreeTOs = false; + bool _scheduleCreateSimulationTreeTOs = false; + bool _scheduleCreateGenomeTreeTOs = false; std::string _filter; bool _showCommunityCreations = false; diff --git a/source/Gui/UploadSimulationDialog.cpp b/source/Gui/UploadSimulationDialog.cpp index 70c53e81b..ea9bc19ba 100644 --- a/source/Gui/UploadSimulationDialog.cpp +++ b/source/Gui/UploadSimulationDialog.cpp @@ -75,7 +75,7 @@ void _UploadSimulationDialog::processIntern() AlienImGui::HelpMarker( "The " + resourceTypeString + " file, name and description are stored on the server. It cannot be guaranteed that the data will not be deleted."); - AlienImGui::Text("How to use folders?"); + AlienImGui::Text("How to use or create folders?"); AlienImGui::HelpMarker("If you want to upload the " + resourceTypeString + " to a folder, you can use the `/`-notation. The folder will be created automatically if it does not exist.\nFor instance, naming a simulation as `Biome/Water " "world/Initial/Variant 1` will create the nested folders `Biome`, `Water world` and `Initial`."); @@ -83,8 +83,8 @@ void _UploadSimulationDialog::processIntern() AlienImGui::Separator(); if (!_folder.empty()) { - std::string text = "The following folder has been selected and will used for the upload: \n" + _folder; - ImGui::PushID(1); + std::string text = "The following folder has been selected and will used for the upload:\n" + _folder; + ImGui::PushID("folder info"); ImGui::BeginDisabled(); AlienImGui::InputTextMultiline(AlienImGui::InputTextMultilineParameters().hint(_folder).textWidth(0).height(FolderWidgetHeight), text); ImGui::EndDisabled(); @@ -95,7 +95,7 @@ void _UploadSimulationDialog::processIntern() AlienImGui::Separator(); - ImGui::PushID(2); + ImGui::PushID("description"); AlienImGui::InputTextMultiline( AlienImGui::InputTextMultilineParameters() .hint("Description (optional)") diff --git a/source/NetworkTests/NetworkResourceServiceTests.cpp b/source/NetworkTests/NetworkResourceServiceTests.cpp index 300b56bd2..30214f5e8 100644 --- a/source/NetworkTests/NetworkResourceServiceTests.cpp +++ b/source/NetworkTests/NetworkResourceServiceTests.cpp @@ -47,7 +47,7 @@ TEST_F(NetworkResourceServiceTests, nameWithFolder) EXPECT_TRUE(outputTO->isLeaf()); EXPECT_EQ(1, outputTO->folderNames.size()); EXPECT_EQ(std::string("folder"), outputTO->folderNames.front()); - EXPECT_EQ(std::string("test"), outputTO->getLeaf().rawTO->resourceName); + EXPECT_EQ(std::string("test"), outputTO->getLeaf().leafName); } } @@ -80,7 +80,7 @@ TEST_F(NetworkResourceServiceTests, nameWithTwoFolders) EXPECT_EQ(2, outputTO->folderNames.size()); EXPECT_EQ(std::string("folder1"), outputTO->folderNames.at(0)); EXPECT_EQ(std::string("folder2"), outputTO->folderNames.at(1)); - EXPECT_EQ(std::string("test"), outputTO->getLeaf().rawTO->resourceName); + EXPECT_EQ(std::string("test"), outputTO->getLeaf().leafName); } } @@ -121,7 +121,7 @@ TEST_F(NetworkResourceServiceTests, twoNamesWithTwoFolders) EXPECT_EQ(2, outputTO->folderNames.size()); EXPECT_EQ(std::string("A"), outputTO->folderNames.at(0)); EXPECT_EQ(std::string("B"), outputTO->folderNames.at(1)); - EXPECT_EQ(std::string("C"), outputTO->getLeaf().rawTO->resourceName); + EXPECT_EQ(std::string("C"), outputTO->getLeaf().leafName); } { auto outputTO = outputTOs.at(3); @@ -142,6 +142,6 @@ TEST_F(NetworkResourceServiceTests, twoNamesWithTwoFolders) EXPECT_EQ(2, outputTO->folderNames.size()); EXPECT_EQ(std::string("X"), outputTO->folderNames.at(0)); EXPECT_EQ(std::string("Y"), outputTO->folderNames.at(1)); - EXPECT_EQ(std::string("Z"), outputTO->getLeaf().rawTO->resourceName); + EXPECT_EQ(std::string("Z"), outputTO->getLeaf().leafName); } } From 825c6df4794f2e3891269c2be5b102fd5cafecc5 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Fri, 29 Dec 2023 17:46:30 +0100 Subject: [PATCH 40/40] RELEASE-NOTES.md and README.md updated --- README.md | 2 +- RELEASE-NOTES.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4586b4ab4..9dc023122 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ Further information and artwork: An Nvidia graphics card with compute capability 6.0 or higher is needed. Please check [https://en.wikipedia.org/wiki/CUDA#GPUs_supported](https://en.wikipedia.org/wiki/CUDA#GPUs_supported). # 💽 Installer -Installer for Windows: [alien-installer.msi](https://alien-project.org/media/files/alien-installer.msi) (Updated: 2023-12-16) +Installer for Windows: [alien-installer.msi](https://alien-project.org/media/files/alien-installer.msi) (Updated: 2023-12-29) In the case that the program crashes for an unknown reason, please refer to the troubleshooting section in [alien-project.org/downloads.html](https://alien-project.org/downloads.html). diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index ff1a251ab..e88e22aba 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -8,7 +8,7 @@ - gui/browser: show number of simulations per folder ### Changed -- gui/browser: tree view instead of a pure table view +- gui/browser: tree view instead of a pure tabular view - gui/browser: simulations and genomes can be selected for user actions (e.g. deletion) ### Removed