As mentioned in the commit, something's wrong. Probably on ImGui's side, but I'll have to investigate more.
446 lines
17 KiB
C++
446 lines
17 KiB
C++
// MassBuilderSaveTool
|
|
// Copyright (C) 2021-2024 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 <https://www.gnu.org/licenses/>.
|
|
|
|
#include <Magnum/ImGuiIntegration/Integration.h>
|
|
|
|
#include <SDL_messagebox.h>
|
|
|
|
#include "../FontAwesome/IconsFontAwesome5.h"
|
|
|
|
#include "Application.h"
|
|
|
|
extern const ImVec2 center_pivot;
|
|
|
|
namespace mbst {
|
|
|
|
void
|
|
Application::drawProfileManager() {
|
|
static std::size_t profile_index = 0;
|
|
|
|
ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f} / dpiScaling()}, ImGuiCond_Always, center_pivot);
|
|
if(ImGui::Begin("Profile management##ProfileManager", nullptr,
|
|
ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoBringToFrontOnFocus|
|
|
ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_MenuBar))
|
|
{
|
|
if(ImGui::BeginMenuBar()) {
|
|
ImGui::TextUnformatted("Profile manager");
|
|
ImGui::EndMenuBar();
|
|
}
|
|
|
|
if(ImGui::BeginTable("##ManagerLayout", 2)) {
|
|
ImGui::TableSetupColumn("##Label", ImGuiTableColumnFlags_WidthStretch);
|
|
ImGui::TableSetupColumn("##Refresh", ImGuiTableColumnFlags_WidthFixed);
|
|
|
|
ImGui::TableNextRow();
|
|
ImGui::TableSetColumnIndex(0);
|
|
ImGui::TextUnformatted("Here are the detected profiles:");
|
|
|
|
ImGui::TableSetColumnIndex(1);
|
|
if(ImGui::SmallButton("Refresh")) {
|
|
if(!_profileManager->refreshProfiles()) {
|
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error",
|
|
_profileManager->lastError().data(), window());
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
ImGui::SameLine();
|
|
if(ImGui::SmallButton("Backups")) {
|
|
_backupManager->refresh();
|
|
ImGui::OpenPopup("Backups##BackupsModal");
|
|
}
|
|
drawBackupListPopup();
|
|
|
|
ImGui::EndTable();
|
|
}
|
|
|
|
if(ImGui::BeginTable("##Profiles", 3, ImGuiTableFlags_BordersOuter|ImGuiTableFlags_RowBg)) {
|
|
ImGui::TableSetupColumn("Company name", ImGuiTableColumnFlags_WidthStretch);
|
|
ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed);
|
|
ImGui::TableSetupColumn("##Buttons", ImGuiTableColumnFlags_WidthFixed);
|
|
|
|
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
|
ImGui::TableSetColumnIndex(0);
|
|
ImGui::TextUnformatted("Company name");
|
|
ImGui::TableSetColumnIndex(1);
|
|
ImGui::TextUnformatted("Type");
|
|
ImGui::TableSetColumnIndex(2);
|
|
ImGui::TextUnformatted("Actions");
|
|
|
|
for(std::size_t i = 0; i < _profileManager->profiles().size(); ++i) {
|
|
GameObjects::Profile& profile = _profileManager->profiles()[i];
|
|
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableSetColumnIndex(0);
|
|
ImGui::PushID(int(i));
|
|
if(ImGui::Selectable(profile.companyName().data(), false,
|
|
ImGuiSelectableFlags_SpanAllColumns|ImGuiSelectableFlags_AllowItemOverlap))
|
|
{
|
|
_currentProfile = _profileManager->getProfile(i);
|
|
initialiseMassManager();
|
|
initialiseFileWatcher();
|
|
_uiState = UiState::MainManager;
|
|
}
|
|
|
|
ImGui::TableSetColumnIndex(1);
|
|
ImGui::TextUnformatted(profile.isDemo() ? "Demo" : "Full");
|
|
|
|
ImGui::TableSetColumnIndex(2);
|
|
if(ImGui::SmallButton(ICON_FA_FILE_ARCHIVE)) {
|
|
if(!_backupManager->create(_profileManager->profiles()[i])) {
|
|
_queue.addToast(Toast::Type::Error, _backupManager->lastError(), std::chrono::seconds{5});
|
|
}
|
|
else {
|
|
_queue.addToast(Toast::Type::Success, "Backup created successfully!"_s);
|
|
}
|
|
}
|
|
drawTooltip("Backup");
|
|
ImGui::SameLine(0.0f, 2.0f);
|
|
if(drawUnsafeWidget(ImGui::SmallButton, ICON_FA_TRASH_ALT)) {
|
|
profile_index = i;
|
|
ImGui::OpenPopup("Confirmation##DeleteProfileConfirmation");
|
|
}
|
|
drawTooltip("Delete");
|
|
drawDeleteProfilePopup(profile_index);
|
|
ImGui::PopID();
|
|
}
|
|
ImGui::EndTable();
|
|
}
|
|
|
|
ImGui::TextUnformatted("Click a profile to manage it.");
|
|
}
|
|
|
|
ImGui::End();
|
|
}
|
|
|
|
void
|
|
Application::drawBackupListPopup() {
|
|
ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f} / dpiScaling()}, ImGuiCond_Always, center_pivot);
|
|
if(!ImGui::BeginPopupModal("Backups##BackupsModal", nullptr,
|
|
ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove))
|
|
{
|
|
return;
|
|
}
|
|
|
|
static std::size_t backup_index;
|
|
|
|
if(ImGui::BeginTable("##BackupsLabelLayout", 2)) {
|
|
ImGui::TableSetupColumn("##Label", ImGuiTableColumnFlags_WidthStretch);
|
|
ImGui::TableSetupColumn("##Refresh", ImGuiTableColumnFlags_WidthFixed);
|
|
|
|
ImGui::TableNextRow();
|
|
ImGui::TableSetColumnIndex(0);
|
|
ImGui::TextUnformatted("Here's a list of detected backups:");
|
|
|
|
ImGui::TableSetColumnIndex(1);
|
|
if(ImGui::SmallButton("Refresh")) {
|
|
_backupManager->refresh();
|
|
}
|
|
|
|
ImGui::EndTable();
|
|
}
|
|
|
|
if(_backupManager->backups().isEmpty()) {
|
|
ImGui::TextDisabled("No backups were found.");
|
|
}
|
|
else if(ImGui::BeginTable("##Backups", 4,
|
|
ImGuiTableFlags_BordersOuter|ImGuiTableFlags_RowBg))
|
|
{
|
|
ImGui::TableSetupScrollFreeze(0, 1);
|
|
ImGui::TableSetupColumn("##CompanyName", ImGuiTableColumnFlags_WidthFixed);
|
|
ImGui::TableSetupColumn("##BackupDate", ImGuiTableColumnFlags_WidthFixed);
|
|
ImGui::TableSetupColumn("##Type", ImGuiTableColumnFlags_WidthFixed);
|
|
ImGui::TableSetupColumn("##Actions", ImGuiTableColumnFlags_WidthFixed);
|
|
|
|
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
|
ImGui::TableSetColumnIndex(0);
|
|
ImGui::TextUnformatted("Company name");
|
|
ImGui::TableSetColumnIndex(1);
|
|
ImGui::TextUnformatted("Backup date");
|
|
ImGui::TableSetColumnIndex(2);
|
|
ImGui::TextUnformatted("Type");
|
|
ImGui::TableSetColumnIndex(3);
|
|
ImGui::TextUnformatted("Actions");
|
|
|
|
//drawBackupFolder(_backupManager->vfs());
|
|
|
|
for(std::size_t i = 0; i < _backupManager->backups().size(); ++i) {
|
|
auto& backup = _backupManager->backups()[i];
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableSetColumnIndex(0);
|
|
ImGui::TextUnformatted(backup.company.cbegin(), backup.company.cend());
|
|
if(ImGui::IsItemHovered() && ImGui::BeginTooltip()) {
|
|
for(const auto& file : backup.includedFiles) {
|
|
ImGui::TextUnformatted(file.cbegin());
|
|
}
|
|
ImGui::EndTooltip();
|
|
}
|
|
|
|
ImGui::TableSetColumnIndex(1);
|
|
ImGui::Text("%.4i-%.2i-%.2i %.2i:%.2i:%.2i",
|
|
backup.timestamp.year,
|
|
backup.timestamp.month,
|
|
backup.timestamp.day,
|
|
backup.timestamp.hour,
|
|
backup.timestamp.minute,
|
|
backup.timestamp.second);
|
|
|
|
ImGui::TableSetColumnIndex(2);
|
|
ImGui::TextUnformatted(backup.demo ? "Demo" : "Full");
|
|
|
|
ImGui::TableSetColumnIndex(3);
|
|
ImGui::PushID(int(i));
|
|
if(ImGui::SmallButton(ICON_FA_UNDO)) {
|
|
backup_index = i;
|
|
ImGui::OpenPopup("Restore backup##RestoreBackupModal");
|
|
}
|
|
drawTooltip("Restore");
|
|
drawBackupRestorePopup(backup_index);
|
|
ImGui::SameLine(0.0f, 2.0f);
|
|
if(ImGui::SmallButton(ICON_FA_TRASH_ALT)) {
|
|
backup_index = i;
|
|
ImGui::OpenPopup("Delete backup##DeleteBackupModal");
|
|
}
|
|
drawTooltip("Delete");
|
|
drawBackupDeletePopup(backup_index);
|
|
ImGui::PopID();
|
|
}
|
|
ImGui::EndTable();
|
|
}
|
|
|
|
ImGui::PushTextWrapPos(ImGui::GetContentRegionAvail().x);
|
|
ImGui::TextUnformatted("Hover over a company name to see which files are included in the backup.");
|
|
ImGui::PopTextWrapPos();
|
|
|
|
if(ImGui::BeginTable("##BackupListCloseLayout", 2)) {
|
|
ImGui::TableSetupColumn("##Dummy", ImGuiTableColumnFlags_WidthStretch);
|
|
ImGui::TableSetupColumn("##Close", ImGuiTableColumnFlags_WidthFixed);
|
|
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableSetColumnIndex(1);
|
|
if(ImGui::Button("Close")) {
|
|
ImGui::CloseCurrentPopup();
|
|
}
|
|
|
|
ImGui::EndTable();
|
|
}
|
|
|
|
ImGui::EndPopup();
|
|
}
|
|
|
|
void
|
|
Application::drawBackupFolder(const Managers::Vfs::Directory<Managers::Backup>& dir) {
|
|
if(dir.files().isEmpty() && dir.subdirs().isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
for(auto& subdir : dir.subdirs()) {
|
|
ImGui::TableNextRow();
|
|
ImGui::TableNextColumn();
|
|
bool open = ImGui::TreeNodeEx(subdir.name().cbegin(), ImGuiTreeNodeFlags_SpanAllColumns);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::TextDisabled("--");
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::TextDisabled("--");
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::TextDisabled("--");
|
|
|
|
if(open) {
|
|
drawBackupFolder(subdir);
|
|
ImGui::TreePop();
|
|
}
|
|
}
|
|
|
|
for(auto file : dir.files()) {
|
|
ImGui::TableNextRow();
|
|
ImGui::TableNextColumn();
|
|
ImGui::TreeNodeEx(file->company.cbegin(), ImGuiTreeNodeFlags_SpanAllColumns|ImGuiTreeNodeFlags_Leaf|
|
|
ImGuiTreeNodeFlags_NoTreePushOnOpen);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%.4i-%.2i-%.2i %.2i:%.2i:%.2i",
|
|
file->timestamp.year,
|
|
file->timestamp.month,
|
|
file->timestamp.day,
|
|
file->timestamp.hour,
|
|
file->timestamp.minute,
|
|
file->timestamp.second);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::TextUnformatted(file->demo ? "Demo" : "Full");
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::PushID(file);
|
|
if(ImGui::SmallButton(ICON_FA_UNDO)) {
|
|
//ImGui::OpenPopup("Restore backup##RestoreBackupModal");
|
|
}
|
|
drawTooltip("Restore");
|
|
//drawBackupRestorePopup(backup_index);
|
|
ImGui::SameLine(0.0f, 2.0f);
|
|
if(ImGui::SmallButton(ICON_FA_TRASH_ALT)) {
|
|
//ImGui::OpenPopup("Delete backup##DeleteBackupModal");
|
|
}
|
|
drawTooltip("Delete");
|
|
//drawBackupDeletePopup(backup_index);
|
|
ImGui::PopID();
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
Application::drawBackupRestorePopup(std::size_t backup_index) {
|
|
if(!ImGui::BeginPopupModal("Restore backup##RestoreBackupModal", nullptr,
|
|
ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_AlwaysAutoResize))
|
|
{
|
|
return;
|
|
}
|
|
|
|
ImGui::PushTextWrapPos(float(windowSize().x()) * 0.50f);
|
|
ImGui::Text("Are you sure you want to restore the %s backup from %.4i-%.2i-%.2i %.2i:%.2i:%.2i ?\n\n"
|
|
"Any existing data will be overwritten.",
|
|
_backupManager->backups()[backup_index].company.data(),
|
|
_backupManager->backups()[backup_index].timestamp.year,
|
|
_backupManager->backups()[backup_index].timestamp.month,
|
|
_backupManager->backups()[backup_index].timestamp.day,
|
|
_backupManager->backups()[backup_index].timestamp.hour,
|
|
_backupManager->backups()[backup_index].timestamp.minute,
|
|
_backupManager->backups()[backup_index].timestamp.second);
|
|
ImGui::PopTextWrapPos();
|
|
|
|
if(ImGui::BeginTable("##RestoreBackupLayout", 2)) {
|
|
ImGui::TableSetupColumn("##Dummy", ImGuiTableColumnFlags_WidthStretch);
|
|
ImGui::TableSetupColumn("##YesNo", ImGuiTableColumnFlags_WidthFixed);
|
|
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableSetColumnIndex(1);
|
|
if(ImGui::Button("Yes")) {
|
|
if(!_backupManager->restore(backup_index)) {
|
|
_queue.addToast(Toast::Type::Error, _profileManager->lastError());
|
|
}
|
|
if(!_profileManager->refreshProfiles()) {
|
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error",
|
|
_profileManager->lastError().data(), window());
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
ImGui::CloseCurrentPopup();
|
|
}
|
|
ImGui::SameLine();
|
|
if(ImGui::Button("No", ImGui::GetItemRectSize())) {
|
|
ImGui::CloseCurrentPopup();
|
|
}
|
|
|
|
ImGui::EndTable();
|
|
}
|
|
|
|
ImGui::EndPopup();
|
|
}
|
|
|
|
void
|
|
Application::drawBackupDeletePopup(std::size_t backup_index) {
|
|
if(!ImGui::BeginPopupModal("Delete backup##DeleteBackupModal", nullptr,
|
|
ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_AlwaysAutoResize))
|
|
{
|
|
return;
|
|
}
|
|
|
|
ImGui::PushTextWrapPos(float(windowSize().x()) * 0.50f);
|
|
ImGui::Text("Are you sure you want to delete the %s backup from %.4i-%.2i-%.2i %.2i:%.2i:%.2i ?\n\n"
|
|
"This operation is irreversible.",
|
|
_backupManager->backups()[backup_index].company.data(),
|
|
_backupManager->backups()[backup_index].timestamp.year,
|
|
_backupManager->backups()[backup_index].timestamp.month,
|
|
_backupManager->backups()[backup_index].timestamp.day,
|
|
_backupManager->backups()[backup_index].timestamp.hour,
|
|
_backupManager->backups()[backup_index].timestamp.minute,
|
|
_backupManager->backups()[backup_index].timestamp.second);
|
|
ImGui::PopTextWrapPos();
|
|
|
|
if(ImGui::BeginTable("##DeleteBackupLayout", 2)) {
|
|
ImGui::TableSetupColumn("##Dummy", ImGuiTableColumnFlags_WidthStretch);
|
|
ImGui::TableSetupColumn("##YesNo", ImGuiTableColumnFlags_WidthFixed);
|
|
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableSetColumnIndex(1);
|
|
if(ImGui::Button("Yes")) {
|
|
if(!_backupManager->remove(backup_index)) {
|
|
_queue.addToast(Toast::Type::Error, _profileManager->lastError());
|
|
}
|
|
ImGui::CloseCurrentPopup();
|
|
}
|
|
ImGui::SameLine();
|
|
if(ImGui::Button("No", ImGui::GetItemRectSize())) {
|
|
ImGui::CloseCurrentPopup();
|
|
}
|
|
|
|
ImGui::EndTable();
|
|
}
|
|
|
|
ImGui::EndPopup();
|
|
}
|
|
|
|
void
|
|
Application::drawDeleteProfilePopup(std::size_t profile_index) {
|
|
if(!ImGui::BeginPopupModal("Confirmation##DeleteProfileConfirmation", nullptr,
|
|
ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove))
|
|
{
|
|
return;
|
|
}
|
|
|
|
static bool delete_builds = false;
|
|
if(ImGui::IsWindowAppearing()) {
|
|
delete_builds = false;
|
|
}
|
|
|
|
ImGui::PushTextWrapPos(float(windowSize().x()) * 0.40f);
|
|
ImGui::Text("Are you sure you want to delete the %s profile named %s ? This operation is irreversible.",
|
|
_profileManager->profiles()[profile_index].isDemo() ? "demo" : "full game",
|
|
_profileManager->profiles()[profile_index].companyName().data());
|
|
ImGui::PopTextWrapPos();
|
|
|
|
if(ImGui::BeginTable("##DeleteProfileLayout", 2)) {
|
|
ImGui::TableSetupColumn("##Checkbox", ImGuiTableColumnFlags_WidthStretch);
|
|
ImGui::TableSetupColumn("##YesNo", ImGuiTableColumnFlags_WidthFixed);
|
|
|
|
ImGui::TableNextRow();
|
|
ImGui::TableSetColumnIndex(0);
|
|
ImGui::Checkbox("Delete builds", &delete_builds);
|
|
|
|
ImGui::TableSetColumnIndex(1);
|
|
if(ImGui::Button("Yes")) {
|
|
if(!_profileManager->deleteProfile(profile_index, delete_builds)) {
|
|
_queue.addToast(Toast::Type::Error, _profileManager->lastError());
|
|
}
|
|
ImGui::CloseCurrentPopup();
|
|
}
|
|
ImGui::SameLine();
|
|
if(ImGui::Button("No", ImGui::GetItemRectSize())) {
|
|
ImGui::CloseCurrentPopup();
|
|
}
|
|
|
|
ImGui::EndTable();
|
|
}
|
|
|
|
ImGui::EndPopup();
|
|
}
|
|
|
|
}
|