2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-10-21 22:05:51 +00:00
Files
OpenAssetTools/src/ModMan/Web/Platform/Linux/DialogHandlerLinux.cpp
2025-10-10 09:49:40 +02:00

184 lines
5.1 KiB
C++

#include "Web/Platform/DialogHandler.h"
#ifdef __linux__
#include <cassert>
#include <cstdint>
#include <gtk/gtk.h>
namespace
{
enum class DialogOperation : std::uint8_t
{
OPEN_FILE,
SAVE_FILE,
SELECT_FOLDER
};
class DialogData
{
public:
DialogData(DialogOperation operation, ui::DialogWithCallback::callback_t callback)
: m_operation(operation),
m_callback(std::move(callback))
{
}
DialogOperation m_operation;
ui::DialogWithCallback::callback_t m_callback;
};
bool InitGtk()
{
#if GTK_MAJOR_VERSION >= 4
return gtk_init_check();
#else
return gtk_init_check(nullptr, nullptr);
#endif
}
void OpenFileDialog() {}
void SetFilters(GtkFileDialog* pDialog, const std::vector<ui::FileDialogFilter>& filters)
{
if (filters.empty())
return;
auto* listStore = g_list_store_new(GTK_TYPE_FILE_FILTER);
for (auto& filter : filters)
{
auto* fileFilter = gtk_file_filter_new();
gtk_file_filter_set_name(fileFilter, filter.m_name.c_str());
gtk_file_filter_add_pattern(fileFilter, filter.m_filter.c_str());
g_list_store_append(listStore, fileFilter);
g_object_unref(fileFilter);
}
auto* wildcardFilter = gtk_file_filter_new();
gtk_file_filter_set_name(wildcardFilter, "All files");
gtk_file_filter_add_pattern(wildcardFilter, "*.*");
g_list_store_append(listStore, wildcardFilter);
g_object_unref(wildcardFilter);
gtk_file_dialog_set_filters(pDialog, G_LIST_MODEL(listStore));
g_object_unref(listStore);
}
void OnDialogResult(GObject* source, GAsyncResult* asyncResult, gpointer userData)
{
auto* dialogData = reinterpret_cast<DialogData*>(userData);
GError* error = nullptr;
GFile* file = nullptr;
if (dialogData->m_operation == DialogOperation::OPEN_FILE)
{
file = gtk_file_dialog_open_finish(GTK_FILE_DIALOG(source), asyncResult, &error);
}
else if (dialogData->m_operation == DialogOperation::SAVE_FILE)
{
file = gtk_file_dialog_save_finish(GTK_FILE_DIALOG(source), asyncResult, &error);
}
else if (dialogData->m_operation == DialogOperation::SELECT_FOLDER)
{
file = gtk_file_dialog_select_folder_finish(GTK_FILE_DIALOG(source), asyncResult, &error);
}
else
{
assert(false);
}
std::optional<std::string> result;
ui::DialogCallbackResultType resultType;
if (error)
{
if (error->code == GTK_DIALOG_ERROR_DISMISSED)
resultType = ui::DialogCallbackResultType::CANCELLED;
else
resultType = ui::DialogCallbackResultType::FAILED;
g_error_free(error);
}
else
{
resultType = ui::DialogCallbackResultType::SUCCESSFUL;
result = std::string(g_file_get_path(file));
}
if (file)
{
g_object_unref(file);
}
dialogData->m_callback(resultType, result);
delete dialogData;
}
std::optional<std::string> ShowFileDialog()
{
std::optional<std::string> result = std::nullopt;
return result;
}
} // namespace
namespace ui
{
#if GTK_MAJOR_VERSION >= 4
OpenFileDialog::OpenFileDialog() = default;
void OpenFileDialog::OpenAsync()
{
if (!InitGtk())
return m_callback(DialogCallbackResultType::FAILED, std::nullopt);
auto* dialog = gtk_file_dialog_new();
SetFilters(dialog, m_filters);
// Move data out of the dialog object since it may be destroyed
auto* dialogData = new DialogData(DialogOperation::OPEN_FILE, std::move(m_callback));
gtk_file_dialog_open(dialog, nullptr, nullptr, OnDialogResult, dialogData);
g_object_unref(dialog);
}
SaveFileDialog::SaveFileDialog() = default;
void SaveFileDialog::OpenAsync()
{
if (!InitGtk())
return m_callback(DialogCallbackResultType::FAILED, std::nullopt);
auto* dialog = gtk_file_dialog_new();
SetFilters(dialog, m_filters);
// Move data out of the dialog object since it may be destroyed
auto* dialogData = new DialogData(DialogOperation::SAVE_FILE, std::move(m_callback));
gtk_file_dialog_save(dialog, nullptr, nullptr, OnDialogResult, dialogData);
g_object_unref(dialog);
}
FolderSelectDialog::FolderSelectDialog() = default;
void FolderSelectDialog::OpenAsync()
{
if (!InitGtk())
return m_callback(DialogCallbackResultType::FAILED, std::nullopt);
auto* dialog = gtk_file_dialog_new();
// Move data out of the dialog object since it may be destroyed
auto* dialogData = new DialogData(DialogOperation::SELECT_FOLDER, std::move(m_callback));
gtk_file_dialog_select_folder(dialog, nullptr, nullptr, OnDialogResult, dialogData);
g_object_unref(dialog);
}
#endif
} // namespace ui
#endif