mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-22 12:01:42 +00:00
added file open/save dialog GUI logic
This commit is contained in:
parent
14f9d18075
commit
d1c19fbe2a
2 changed files with 168 additions and 3 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2022-2023 Gian 'myT' Schellenbaum
|
||||
Copyright (C) 2022-2024 Gian 'myT' Schellenbaum
|
||||
|
||||
This file is part of Challenge Quake 3 (CNQ3).
|
||||
|
||||
|
@ -99,6 +99,161 @@ void ToggleBooleanWithShortcut(bool& value, ImGuiKey key)
|
|||
}
|
||||
}
|
||||
|
||||
struct FileDialog
|
||||
{
|
||||
char folder[MAX_QPATH];
|
||||
char fileName[MAX_QPATH];
|
||||
char filePath[MAX_QPATH];
|
||||
char extension[MAX_QPATH];
|
||||
const char* dialogName;
|
||||
char** filePaths;
|
||||
int fileCount;
|
||||
int selectedFileIndex;
|
||||
bool saveMode;
|
||||
};
|
||||
|
||||
static FileDialog saveFile;
|
||||
static FileDialog openFile;
|
||||
|
||||
static bool PathHasExtension(const char* path, const char* extension)
|
||||
{
|
||||
Q_assert(extension[0] == '.');
|
||||
|
||||
const int pathLength = strlen(path);
|
||||
const int extLength = strlen(extension);
|
||||
if(extLength >= pathLength)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Q_stricmpn(path + pathLength - extLength, extension, extLength) == 0;
|
||||
}
|
||||
|
||||
static void OpenFileDialog(FileDialog& dialog, const char* folder, const char* extension)
|
||||
{
|
||||
if(ImGui::IsPopupOpen(dialog.dialogName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dialog.fileName[0] = '\0';
|
||||
Q_strncpyz(dialog.folder, folder, sizeof(dialog.folder));
|
||||
Q_strncpyz(dialog.extension, extension, sizeof(dialog.extension));
|
||||
dialog.filePaths = FS_ListFiles(folder, extension, &dialog.fileCount);
|
||||
dialog.selectedFileIndex = -1;
|
||||
ImGui::OpenPopup(dialog.dialogName);
|
||||
}
|
||||
|
||||
static bool DoFileDialog(FileDialog& dialog)
|
||||
{
|
||||
bool success = false;
|
||||
if(ImGui::BeginPopupModal(dialog.dialogName, NULL, ImGuiWindowFlags_AlwaysAutoResize))
|
||||
{
|
||||
if(BeginTable("Files", 1))
|
||||
{
|
||||
for(int i = 0; i < dialog.fileCount; i++)
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
if(ImGui::Selectable(dialog.filePaths[i], i == dialog.selectedFileIndex,
|
||||
ImGuiSelectableFlags_DontClosePopups))
|
||||
{
|
||||
dialog.selectedFileIndex = i;
|
||||
Q_strncpyz(dialog.fileName, dialog.filePaths[i], sizeof(dialog.fileName));
|
||||
}
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if(dialog.saveMode)
|
||||
{
|
||||
if(ImGui::InputText("File path", dialog.fileName, sizeof(dialog.fileName)))
|
||||
{
|
||||
dialog.selectedFileIndex = -1;
|
||||
}
|
||||
|
||||
if(ImGui::Button("Save") &&
|
||||
dialog.fileName[0] != '\0' &&
|
||||
dialog.fileName[0] != '.')
|
||||
{
|
||||
if(!PathHasExtension(dialog.fileName, dialog.extension))
|
||||
{
|
||||
const int lastCharIndex = strlen(dialog.fileName) - 1;
|
||||
if(dialog.fileName[lastCharIndex] == '.')
|
||||
{
|
||||
dialog.fileName[lastCharIndex] = '\0';
|
||||
}
|
||||
Q_strcat(dialog.fileName, sizeof(dialog.fileName), dialog.extension);
|
||||
}
|
||||
Com_sprintf(dialog.filePath, sizeof(dialog.filePath),
|
||||
"%s/%s", dialog.folder, dialog.fileName);
|
||||
FS_FreeFileList(dialog.filePaths);
|
||||
dialog.filePaths = NULL;
|
||||
ImGui::CloseCurrentPopup();
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ImGui::Button("Open") &&
|
||||
dialog.selectedFileIndex >= 0 &&
|
||||
dialog.selectedFileIndex < dialog.fileCount)
|
||||
{
|
||||
Com_sprintf(dialog.filePath, sizeof(dialog.filePath),
|
||||
"%s/%s", dialog.folder, dialog.filePaths[dialog.selectedFileIndex]);
|
||||
FS_FreeFileList(dialog.filePaths);
|
||||
dialog.filePaths = NULL;
|
||||
ImGui::CloseCurrentPopup();
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if(ImGui::Button("Cancel"))
|
||||
{
|
||||
FS_FreeFileList(dialog.filePaths);
|
||||
dialog.filePaths = NULL;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void OpenSaveFileDialog(const char* folder, const char* extension)
|
||||
{
|
||||
Q_assert(extension[0] == '.');
|
||||
OpenFileDialog(saveFile, folder, extension);
|
||||
}
|
||||
|
||||
bool SaveFileDialog()
|
||||
{
|
||||
return DoFileDialog(saveFile);
|
||||
}
|
||||
|
||||
const char* GetSaveFileDialogPath()
|
||||
{
|
||||
return saveFile.filePath;
|
||||
}
|
||||
|
||||
void OpenOpenFileDialog(const char* folder, const char* extension)
|
||||
{
|
||||
Q_assert(extension[0] == '.');
|
||||
OpenFileDialog(openFile, folder, extension);
|
||||
}
|
||||
|
||||
bool OpenFileDialog()
|
||||
{
|
||||
return DoFileDialog(openFile);
|
||||
}
|
||||
|
||||
const char* GetOpenFileDialogPath()
|
||||
{
|
||||
return openFile.filePath;
|
||||
}
|
||||
|
||||
struct MainMenuItem
|
||||
{
|
||||
GUI_MainMenu::Id menu;
|
||||
|
@ -235,7 +390,7 @@ static void ImGUI_ApplyTheme()
|
|||
colors[ImGuiCol_NavHighlight] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 0.00f, 0.00f, 0.70f);
|
||||
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(1.00f, 0.00f, 0.00f, 0.20f);
|
||||
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(1.00f, 0.00f, 0.00f, 0.35f);
|
||||
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.00f, 0.00f, 0.10f, 0.35f);
|
||||
|
||||
const ImVec4 hover(0.49f, 0.75f, 0.75f, 0.35f);
|
||||
const ImVec4 active(0.49f, 1.00f, 1.00f, 0.55f);
|
||||
|
@ -454,6 +609,10 @@ void CL_IMGUI_Init()
|
|||
{
|
||||
keyMap[K_F1 + i] = ImGuiKey_F1 + i;
|
||||
}
|
||||
|
||||
saveFile.saveMode = true;
|
||||
saveFile.dialogName = "Save file";
|
||||
openFile.dialogName = "Open file";
|
||||
}
|
||||
|
||||
void CL_IMGUI_Frame()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2022-2023 Gian 'myT' Schellenbaum
|
||||
Copyright (C) 2022-2024 Gian 'myT' Schellenbaum
|
||||
|
||||
This file is part of Challenge Quake 3 (CNQ3).
|
||||
|
||||
|
@ -36,6 +36,12 @@ void TableRow2(const char* item0, int item1);
|
|||
void TableRow2(const char* item0, float item1, const char* format = "%g");
|
||||
bool IsShortcutPressed(ImGuiKey key);
|
||||
void ToggleBooleanWithShortcut(bool& value, ImGuiKey key);
|
||||
void OpenSaveFileDialog(const char* folder, const char* extension);
|
||||
bool SaveFileDialog(); // true when the user clicked the save button
|
||||
const char* GetSaveFileDialogPath();
|
||||
void OpenOpenFileDialog(const char* folder, const char* extension);
|
||||
bool OpenFileDialog(); // true when the user clicked the open button
|
||||
const char* GetOpenFileDialogPath();
|
||||
|
||||
#define MAIN_MENU_LIST(M) \
|
||||
M(Tools, "Tools") \
|
||||
|
|
Loading…
Reference in a new issue