// MassBuilderSaveTool // Copyright (C) 2021 Guillaume Jacquemin // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "SaveTool.h" #include #include #include #include #include #include "../FontAwesome/IconsFontAwesome5.h" #include "../Maps/LastMissionId.h" #include "../Maps/StoryProgress.h" static const std::string empty_str; void SaveTool::drawManager() { ImGui::SetNextWindowPos({0.0f, ImGui::GetItemRectSize().y}, ImGuiCond_Always); ImGui::SetNextWindowSize({Float(windowSize().x()), Float(windowSize().y()) - ImGui::GetItemRectSize().y}, ImGuiCond_Always); if(!ImGui::Begin("##MainWindow", nullptr, ImGuiWindowFlags_NoDecoration|ImGuiWindowFlags_NoMove| ImGuiWindowFlags_NoBackground|ImGuiWindowFlags_NoBringToFrontOnFocus)) { ImGui::End(); return; } ImGui::AlignTextToFramePadding(); ImGui::Text("Current profile: %s (%s)", _currentProfile->companyName().c_str(), _currentProfile->type() == ProfileType::Demo ? "demo" : "full game"); ImGui::SameLine(); if(ImGui::Button("Close")) { _currentProfile = nullptr; _massManager.reset(); _fileWatcher.reset(); _uiState = UiState::ProfileManager; } if(ImGui::BeginChild("##ProfileInfo", {ImGui::GetContentRegionAvailWidth() * 0.60f, 0.0f}, true, ImGuiWindowFlags_MenuBar)) { if(ImGui::BeginMenuBar()) { ImGui::TextUnformatted("Profile information"); ImGui::EndMenuBar(); } if(ImGui::BeginTabBar("##ProfileTabBar")) { if(ImGui::BeginTabItem("General info")) { drawGeneralInfo(); ImGui::EndTabItem(); } if(ImGui::BeginTabItem("Research inventory")) { drawResearchInventory(); ImGui::EndTabItem(); } if(ImGui::BeginTabItem("Research tree")) { drawResearchTree(); ImGui::EndTabItem(); } ImGui::EndTabBar(); } } ImGui::EndChild(); ImGui::SameLine(); if(ImGui::BeginChild("##MASSManager", {0.0f, 0.0f}, true, ImGuiWindowFlags_MenuBar)) { if(ImGui::BeginMenuBar()) { ImGui::TextUnformatted("M.A.S.S. management"); drawHelpMarker("To move, import, or export builds, drag-and-drop them."); ImGui::EndMenuBar(); } drawMassManager(); } ImGui::EndChild(); ImGui::End(); } auto SaveTool::drawIntEditPopup(int* value_to_edit, int max) -> bool { bool apply = false; if(ImGui::BeginPopup("int_edit")) { ImGui::Text("Please enter a value between 0 and %i:", max); ImGui::AlignTextToFramePadding(); drawHelpMarker("You can either drag the widget left or right to change the value,\n" "or click on it while holding Ctrl to edit the value directly."); ImGui::SameLine(); drawUnsafeWidget([](auto... args){ return ImGui::DragInt("", args...); }, value_to_edit, 1.0f, 0, max, "%d", ImGuiSliderFlags_AlwaysClamp); ImGui::SameLine(); if(drawUnsafeWidget([]{ return ImGui::Button("Apply"); })) { apply = true; ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); } return apply; } auto SaveTool::drawRenamePopup(Containers::ArrayView name_view) -> bool { bool apply = false; if(ImGui::BeginPopup("name_edit")) { ImGui::TextUnformatted("Please enter a new name. Conditions:"); std::size_t len = std::strlen(name_view.data()); ImGui::BulletText("Length between 6 and 32 characters included. %s", (len >= 6 && len <= 32) ? ICON_FA_CHECK : ICON_FA_TIMES); ImGui::BulletText("Only A-Z, a-z, 0-9, -, and whitespaces. " ICON_FA_CHECK); ImGui::BulletText("No whitespace at the beginning or end. %s", (name_view[0] != ' ' && name_view[len - 1] != ' ') ? ICON_FA_CHECK : ICON_FA_TIMES); static auto callback = [](ImGuiInputTextCallbackData* data)->int { if(data->EventChar < 256 && std::strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789- ", char(data->EventChar))) { return 0; } return 1; }; drawUnsafeWidget([](auto... args){ return ImGui::InputText("", args...); }, name_view.data(), name_view.size(), ImGuiInputTextFlags_CallbackCharFilter, callback, nullptr); ImGui::SameLine(); GameState game_state = _gameState; if((!_unsafeMode && game_state != GameState::NotRunning) || !(len >= 6 && len <= 32) || !(name_view[0] != ' ' && name_view[len - 1] != ' ')) { ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.5f); } if(ImGui::Button("Apply")) { apply = true; ImGui::CloseCurrentPopup(); } if((!_unsafeMode && game_state != GameState::NotRunning) || !(len >= 6 && len <= 32) || !(name_view[0] != ' ' && name_view[len - 1] != ' ')) { ImGui::PopItemFlag(); ImGui::PopStyleVar(); } ImGui::EndPopup(); } return apply; } void SaveTool::drawGeneralInfo() { if(!_currentProfile) { return; } ImGui::Text("Credits: %i", _currentProfile->credits()); auto it = std::find_if(story_progress.begin(), story_progress.end(), [this](const StoryProgressPoint& p){ return p.id == _currentProfile->storyProgress(); }); if(it != story_progress.end()) { ImGui::TextUnformatted("Story progress:"); ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.x / 4.0f); if(std::strcmp(it->after, "") == 0) { ImGui::TextWrapped("%s - %s", it->chapter, it->point); } else { ImGui::TextWrapped("%s - %s - %s", it->chapter, it->after, it->point); } } else { ImGui::Text("Story progress: 0x%x", _currentProfile->storyProgress()); } if(mission_id_map.find(_currentProfile->lastMissionId()) != mission_id_map.cend()) { ImGui::Text("Last mission: %s", mission_id_map.at(_currentProfile->lastMissionId())); } else if(_currentProfile->lastMissionId() == -1) { ImGui::TextUnformatted("Last mission: none"); } else { ImGui::Text("Last mission: 0x%x", _currentProfile->lastMissionId()); } drawTooltip("This is the last mission selected in the mission selection screen, not the last mission played.", windowSize().x() * 0.35f); const Float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); ImGui::Dummy({ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y - footer_height_to_reserve}); ImGui::Separator(); static Containers::StaticArray<33, char> name_buf{ValueInit}; if(drawUnsafeWidget([]{ return ImGui::Button("Rename company"); })) { for(auto& c : name_buf) { c = '\0'; } std::strncpy(name_buf.data(), _currentProfile->companyName().c_str(), 32); ImGui::OpenPopup("name_edit"); } if(drawRenamePopup(name_buf)) { if(!_currentProfile->renameCompany(name_buf.data())) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", _currentProfile->lastError().c_str(), window()); } } if(!_cheatMode) { return; } ImGui::SameLine(); static Int credits; if(drawUnsafeWidget([]{ return ImGui::Button("Edit credits"); })) { credits = _currentProfile->credits(); ImGui::OpenPopup("int_edit"); } if(drawIntEditPopup(&credits, 20000000)) { if(!_currentProfile->setCredits(credits)) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", _currentProfile->lastError().c_str(), window()); } } ImGui::SameLine(); if(drawUnsafeWidget([]{ return ImGui::Button("Change story progression"); })) { ImGui::OpenPopup("StoryProgressMenu"); } drawTooltip("Story progress directly affects unlocked levels."); if(ImGui::BeginPopup("StoryProgressMenu")) { if(!_unsafeMode && _gameState != GameState::NotRunning) { ImGui::CloseCurrentPopup(); } for(const auto& sp : story_progress) { if(ImGui::BeginMenu(sp.chapter)) { if(std::strcmp(sp.after, "") == 0) { if(ImGui::MenuItem(sp.point)) { if(!_currentProfile->setStoryProgress(sp.id)) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", _currentProfile->lastError().c_str(), window()); } } } else { if(ImGui::BeginMenu(sp.after)) { if(ImGui::MenuItem(sp.point)) { if(!_currentProfile->setStoryProgress(sp.id)) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", _currentProfile->lastError().c_str(), window()); } } ImGui::EndMenu(); } } ImGui::EndMenu(); } } ImGui::EndPopup(); } } void SaveTool::drawResearchInventory() { if(!_currentProfile) { return; } #define unavRow(name) \ ImGui::TableNextRow(); \ ImGui::TableSetColumnIndex(0); \ ImGui::TextUnformatted(name); \ ImGui::TableSetColumnIndex(1); \ ImGui::TextDisabled("Unavailable as of M.A.S.S. Builder version " SUPPORTED_GAME_VERSION); #define matRow(name, var, getter, setter) \ ImGui::TableNextRow(); \ ImGui::TableSetColumnIndex(0); \ ImGui::TextUnformatted((name)); \ ImGui::TableSetColumnIndex(1); \ if(_currentProfile->getter() != -1) { \ ImGui::Text("%i", _currentProfile->getter()); \ if(_cheatMode) { \ ImGui::TableSetColumnIndex(2); \ ImGui::PushID(#setter); \ static Int var = _currentProfile->getter(); \ if(drawUnsafeWidget([]{ return ImGui::SmallButton(ICON_FA_EDIT); })) { \ (var) = _currentProfile->getter(); \ ImGui::OpenPopup("int_edit"); \ } \ if(drawIntEditPopup(&(var), 9999)) { \ if(!_currentProfile->set##setter((var))) { \ SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", \ _currentProfile->lastError().c_str(), window()); \ } \ } \ ImGui::PopID(); \ } \ } \ else { \ ImGui::TextDisabled("Not found in the save file"); \ } if(ImGui::BeginTable("##ResearchInventoryTable", 3, ImGuiTableFlags_BordersOuter|ImGuiTableFlags_ScrollY|ImGuiTableFlags_RowBg)) { ImGui::TableSetupColumn("##Name", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("##Value", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##Edit", ImGuiTableColumnFlags_WidthFixed); ImGui::TableNextRow(ImGuiTableRowFlags_Headers); ImGui::TableSetColumnIndex(0); ImGui::Text("Engine materials"); matRow("Verse steel", verse_steel, verseSteel, VerseSteel) matRow("Undinium", undinium, undinium, Undinium) matRow("Necrium alloy", necrium_alloy, necriumAlloy, NecriumAlloy) matRow("Lunarite", lunarite, lunarite, Lunarite) matRow("Asterite", asterite, asterite, Asterite) unavRow("Hallite fragma") unavRow("Unnoctinium") ImGui::TableNextRow(ImGuiTableRowFlags_Headers); ImGui::TableSetColumnIndex(0); ImGui::Text("OS materials"); matRow("Ednil", ednil, ednil, Ednil) matRow("Nuflalt", nuflalt, nuflalt, Nuflalt) matRow("Aurelene", aurelene, aurelene, Aurelene) matRow("Soldus", soldus, soldus, Soldus) matRow("Synthesized N", synthesized_n, synthesizedN, SynthesizedN) unavRow("Nanoc") unavRow("Abyssillite") ImGui::TableNextRow(ImGuiTableRowFlags_Headers); ImGui::TableSetColumnIndex(0); ImGui::Text("Architect materials"); matRow("Alcarbonite", alcarbonite, alcarbonite, Alcarbonite) matRow("Keriphene", keriphene, keriphene, Keriphene) matRow("Nitinol-CM", nitinol_cm, nitinolCM, NitinolCM) matRow("Quarkium", quarkium, quarkium, Quarkium) matRow("Alterene", alterene, alterene, Alterene) unavRow("Cosmium") unavRow("Purified quarkium") ImGui::TableNextRow(ImGuiTableRowFlags_Headers); ImGui::TableSetColumnIndex(0); ImGui::Text("Quark data"); matRow("Mixed composition", mixed_composition, mixedComposition, MixedComposition) matRow("Void residue", void_residue, voidResidue, VoidResidue) matRow("Muscular construction", muscular_construction, muscularConstruction, MuscularConstruction) matRow("Mineral exoskeletology", mineral_exoskeletology, mineralExoskeletology, MineralExoskeletology) matRow("Carbonized skin", carbonized_skin, carbonizedSkin, CarbonizedSkin) unavRow("Isolated void particle") unavRow("Weaponised physiology") ImGui::EndTable(); } #undef unavRow #undef matRow } void SaveTool::drawResearchTree() { if(!_tree) { _tree.emplace(); _tree->generateEngineTree(); _tree->readEngineUnlocks(_currentProfile->engineInventory(), _currentProfile->gearInventory()); _tree->generateOSTree(); _tree->generateArchTree(); } if(ImGui::BeginTabBar("##TreeTabBar")) { if(ImGui::BeginTabItem("Engine")) { if(ImGui::BeginTable("##EngineTable", 1, ImGuiTableFlags_RowBg)) { ImGui::TableSetupColumn("##Column", ImGuiTableColumnFlags_WidthStretch); drawNode(_tree->getEngineRootNode()); ImGui::EndTable(); } ImGui::EndTabItem(); } if(ImGui::BeginTabItem("OS")) { if(ImGui::BeginTable("##OSTable", 1, ImGuiTableFlags_RowBg)) { ImGui::TableSetupColumn("##Column", ImGuiTableColumnFlags_WidthStretch); drawNode(_tree->getOSRootNode()); ImGui::EndTable(); } ImGui::EndTabItem(); } if(ImGui::BeginTabItem("Architect")) { if(ImGui::BeginTable("##ArchTable", 1, ImGuiTableFlags_RowBg)) { ImGui::TableSetupColumn("##Column", ImGuiTableColumnFlags_WidthStretch); drawNode(_tree->getArchRootNode()); ImGui::EndTable(); } ImGui::EndTabItem(); } ImGui::EndTabBar(); } } void SaveTool::drawNode(Node& node) { auto nodeTooltip = [this, &node]{ if(ImGui::IsItemHovered()) { ImGui::BeginTooltip(); ImGui::Text("Tier %u", node.tier()); if(node.type() == Node::Type::Engine || node.type() == Node::Type::OS || node.type() == Node::Type::Architect) { ImGui::SameLine(); ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical); ImGui::SameLine(); switch(node.type()) { case Node::Type::Engine: ImGui::Text("%u gear slots", node.slots()); break; case Node::Type::OS: ImGui::Text("%u module slots", node.slots()); break; case Node::Type::Architect: ImGui::Text("%u tech slots", node.slots()); break; default: break; } } ImGui::Separator(); ImGui::PushTextWrapPos(windowSize().x() * 0.40f); ImGui::TextUnformatted(node.description()); if(std::strncmp("", node.activeEffect(), 3) != 0) { ImGui::Separator(); ImGui::Text("Active effect: %s", node.activeEffect()); } if(std::strncmp("", node.passiveEffect(), 3) != 0) { ImGui::Separator(); ImGui::Text("Passive effect: %s", node.passiveEffect()); } ImGui::PopTextWrapPos(); ImGui::EndTooltip(); } }; ImGui::TableNextRow(); ImGui::TableNextColumn(); bool has_children = (node.children().size() > 0); if(node.state() == Node::State::Unavailable) { ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyleColorVec4(ImGuiCol_TextDisabled)); } if(has_children) { bool open = ImGui::TreeNodeEx(node.name(), ImGuiTreeNodeFlags_SpanAvailWidth|(node.state() == Node::State::Unlocked ? ImGuiTreeNodeFlags_Selected : 0)); if(node.state() == Node::State::Unavailable) { ImGui::PopStyleColor(); } nodeTooltip(); if(open) { for(Node* child : node.children()) { drawNode(*child); } ImGui::TreePop(); } } else { ImGui::TreeNodeEx(node.name(), ImGuiTreeNodeFlags_SpanAvailWidth|ImGuiTreeNodeFlags_Leaf|ImGuiTreeNodeFlags_NoTreePushOnOpen| ImGuiTreeNodeFlags_Bullet|(node.state() == Node::State::Unlocked ? ImGuiTreeNodeFlags_Selected : 0)); if(node.state() == Node::State::Unavailable) { ImGui::PopStyleColor(); } nodeTooltip(); } } void SaveTool::drawMassManager() { if(!_massManager) { return; } static int mass_to_delete = 0; static ImGuiID mass_deletion_popup_ID = drawDeleteMassPopup(mass_to_delete); if(ImGui::BeginTable("##HangarsTable", 4, ImGuiTableFlags_BordersOuter|ImGuiTableFlags_RowBg|ImGuiTableFlags_ScrollY, {0.0f, ImGui::GetContentRegionAvail().y * 0.45f})) { ImGui::TableSetupColumn("##Hangar", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("##MASSName", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##Active", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("##DeleteButton", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableNextRow(ImGuiTableRowFlags_Headers); ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted("#"); ImGui::TableSetColumnIndex(1); ImGui::TextUnformatted("Name"); for(int i = 0; i < 32; i++) { ImGui::TableNextRow(); static int drag_drop_index = 0; ImGui::TableSetColumnIndex(0); ImGui::Selectable(Utility::formatString("{:.2d}", i + 1).c_str(), false, ImGuiSelectableFlags_SpanAllColumns|ImGuiSelectableFlags_AllowItemOverlap); if(_massManager->massState(i) == MassState::Valid && ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceNoHoldToOpenOthers)) { drag_drop_index = i; ImGui::SetDragDropPayload("Mass", &drag_drop_index, sizeof(int)); ImGui::Text("%s - Hangar %.2d", _massManager->massName(i).c_str(), i + 1); ImGui::EndDragDropSource(); } if((!_unsafeMode && _gameState == GameState::NotRunning) && ImGui::BeginDragDropTarget()) { if(const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("StagedMass")) { if(payload->DataSize != sizeof(std::string)) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal error", "payload->DataSize != sizeof(std::string) in SaveTool::drawMassManager()", window()); exit(EXIT_FAILURE); } std::string file = *(static_cast(payload->Data)); if(!_massManager->importMass(file, i)) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error importing M.A.S.S.", _massManager->lastError().c_str(), window()); } } else if(const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("Mass")) { if(payload->DataSize != sizeof(int)) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal error", "payload->DataSize != sizeof(int) in SaveTool::drawMassManager()", window()); exit(EXIT_FAILURE); } int index = *(static_cast(payload->Data)); if(!_massManager->moveMass(index, i)) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", _massManager->lastError().c_str(), window()); } } ImGui::EndDragDropTarget(); } ImGui::TableSetColumnIndex(1); switch(_massManager->massState(i)) { case MassState::Empty: ImGui::TextUnformatted(""); break; case MassState::Invalid: ImGui::TextUnformatted(""); break; case MassState::Valid: ImGui::TextUnformatted(_massManager->massName(i).c_str()); break; } if(i == _currentProfile->activeFrameSlot()) { ImGui::TableSetColumnIndex(2); ImGui::TextUnformatted(ICON_FA_CHECK); } if(_massManager->massState(i) != MassState::Empty) { ImGui::TableSetColumnIndex(3); ImGui::PushID(i); if(drawUnsafeWidget(ImGui::SmallButton, ICON_FA_TRASH_ALT)) { mass_to_delete = i; ImGui::OpenPopup(mass_deletion_popup_ID); } ImGui::PopID(); } } ImGui::EndTable(); } drawDeleteMassPopup(mass_to_delete); static ImGuiID staged_mass_deletion_popup_ID = drawDeleteStagedMassPopup(""); static Containers::Reference staged_mass_to_delete{empty_str}; if(ImGui::BeginTable("##StagingArea", 2, ImGuiTableFlags_ScrollY|ImGuiTableFlags_BordersOuter|ImGuiTableFlags_RowBg)) { ImGui::TableSetupColumn("##NameColumn", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##DeleteColumn", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableNextRow(ImGuiTableRowFlags_Headers); ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted("Staging area"); ImGui::SameLine(); if(ImGui::SmallButton(ICON_FA_FOLDER_OPEN " Open staging folder")) { openUri(Utility::Directory::toNativeSeparators(_stagingDir)); } for(const auto& pair : _massManager->stagedMasses()) { ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); std::string staged_formatted = Utility::formatString("{} ({})", pair.second, pair.first); ImGui::Selectable(staged_formatted.c_str()); if((ImGui::CalcTextSize(staged_formatted.c_str()).x + ImGui::GetStyle().FramePadding.x) > ImGui::GetContentRegionAvailWidth()) { drawTooltip(staged_formatted.c_str()); } if(ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceNoHoldToOpenOthers)) { ImGui::SetDragDropPayload("StagedMass", &(pair.first), sizeof(std::string)); ImGui::Text("%s - Staged", pair.second.c_str()); ImGui::EndDragDropSource(); } ImGui::TableSetColumnIndex(1); ImGui::PushID(pair.first.c_str()); if(ImGui::SmallButton(ICON_FA_TRASH_ALT)) { staged_mass_to_delete = Containers::Reference{pair.first}; ImGui::OpenPopup(staged_mass_deletion_popup_ID); } ImGui::PopID(); } ImGui::EndTable(); } if(ImGui::BeginDragDropTarget()) { if(const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("Mass")) { if(payload->DataSize != sizeof(int)) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal error", "payload->DataSize != sizeof(int) in SaveTool::drawMassManager()", window()); exit(EXIT_FAILURE); } int index = *(static_cast(payload->Data)); if(!_massManager->exportMass(index)) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", _massManager->lastError().c_str(), window()); } } ImGui::EndDragDropTarget(); } drawDeleteStagedMassPopup(staged_mass_to_delete.get()); } auto SaveTool::drawDeleteMassPopup(int mass_index) -> ImGuiID { if(!ImGui::BeginPopupModal("Confirmation##DeleteMassConfirmation", nullptr, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove)) { return ImGui::GetID("Confirmation##DeleteMassConfirmation"); } if(_massManager->massState(mass_index) == MassState::Empty) { ImGui::CloseCurrentPopup(); ImGui::EndPopup(); return 0; } if(_gameState != GameState::NotRunning) { ImGui::CloseCurrentPopup(); ImGui::EndPopup(); return 0; } ImGui::PushTextWrapPos(windowSize().x() * 0.40f); if(_massManager->massState(mass_index) == MassState::Invalid) { ImGui::Text("Are you sure you want to delete the invalid M.A.S.S. data in hangar %.2i ? This operation is irreversible.", mass_index + 1); } else { ImGui::Text("Are you sure you want to delete the M.A.S.S. named %s in hangar %.2i ? This operation is irreversible.", _massManager->massName(mass_index).c_str(), mass_index + 1); } ImGui::PopTextWrapPos(); if(ImGui::BeginTable("##DeleteMassLayout", 2)) { ImGui::TableSetupColumn("##Dummy", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##YesNo", ImGuiTableColumnFlags_WidthFixed); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(1); if(ImGui::Button("Yes")) { if(!_massManager->deleteMass(mass_index)) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error when deleting M.A.S.S.", _massManager->lastError().c_str(), window()); } ImGui::CloseCurrentPopup(); } ImGui::SameLine(); if(ImGui::Button("No", ImGui::GetItemRectSize())) { ImGui::CloseCurrentPopup(); } ImGui::EndTable(); } ImGui::EndPopup(); return 0; } auto SaveTool::drawDeleteStagedMassPopup(const std::string& filename) -> ImGuiID { if(!ImGui::BeginPopupModal("Confirmation##DeleteStagedMassConfirmation", nullptr, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove)) { return ImGui::GetID("Confirmation##DeleteStagedMassConfirmation"); } ImGui::PushTextWrapPos(windowSize().x() * 0.40f); ImGui::Text("Are you sure you want to delete the staged M.A.S.S. named %s ? This operation is irreversible.", _massManager->stagedMasses().at(filename).c_str()); ImGui::PopTextWrapPos(); if(ImGui::BeginTable("##DeleteStagedMassLayout", 2)) { ImGui::TableSetupColumn("##Dummy", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##YesNo", ImGuiTableColumnFlags_WidthFixed); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(1); if(ImGui::Button("Yes")) { if(!_massManager->deleteStagedMass(filename)) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error when deleting M.A.S.S.", _massManager->lastError().c_str(), window()); } ImGui::CloseCurrentPopup(); } ImGui::SameLine(); if(ImGui::Button("No", ImGui::GetItemRectSize())) { ImGui::CloseCurrentPopup(); } ImGui::EndTable(); } ImGui::EndPopup(); return 0; }