refactor: Restructure file dialog handling and introduce utility classes

- Updated file dialog references across the application to utilize a new `util::FileDialogWrapper` for consistent file handling.
- Refactored existing code to replace direct calls to `core::FileDialogWrapper` with the new utility class, enhancing modularity and maintainability.
- Introduced `util::PlatformPaths` for cross-platform directory management, ensuring consistent access to user directories and application data paths.
- Added new utility functions for file operations, improving the overall file handling capabilities within the application.
- Updated CMake configurations to include new utility source files, streamlining the build process.
This commit is contained in:
scawful
2025-10-04 23:26:42 -04:00
parent 429506e503
commit bcc8f8e8f9
39 changed files with 385 additions and 144 deletions

View File

@@ -7,7 +7,7 @@
#include "app/editor/editor_manager.h"
#include "app/gui/background_renderer.h"
#include "app/gui/theme_manager.h"
#include "app/gui/widget_id_registry.h"
#include "app/gui/widgets/widget_id_registry.h"
#include "imgui/backends/imgui_impl_sdl2.h"
#include "imgui/backends/imgui_impl_sdlrenderer2.h"
#include "imgui/imgui.h"

View File

@@ -10,13 +10,11 @@ set(
if (WIN32 OR MINGW OR (UNIX AND NOT APPLE))
list(APPEND YAZE_APP_CORE_SRC
app/core/platform/font_loader.cc
app/core/platform/file_dialog.cc
)
endif()
if(APPLE)
list(APPEND YAZE_APP_CORE_SRC
app/core/platform/file_dialog.cc
app/core/platform/file_dialog.mm
app/core/platform/app_delegate.mm
app/core/platform/font_loader.cc

View File

@@ -208,7 +208,7 @@
- (void)openFileAction:(id)sender {
// TODO: Re-implmenent this without the SharedRom singleton
// if (!yaze::SharedRom::shared_rom_
// ->LoadFromFile(yaze::core::FileDialogWrapper::ShowOpenFileDialog())
// ->LoadFromFile(yaze::util::FileDialogWrapper::ShowOpenFileDialog())
// .ok()) {
// NSAlert *alert = [[NSAlert alloc] init];
// [alert setMessageText:@"Error"];

View File

@@ -1,727 +0,0 @@
#include "file_dialog.h"
#ifdef _WIN32
// Include Windows-specific headers
#include <shobjidl.h>
#include <windows.h>
#else // Linux and MacOS
#include <dirent.h>
#include <sys/stat.h>
#include <cerrno>
#endif
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <cstring>
#include "app/core/features.h"
namespace yaze {
namespace core {
std::string GetFileExtension(const std::string &filename) {
size_t dot = filename.find_last_of('.');
if (dot == std::string::npos) {
return "";
}
return filename.substr(dot + 1);
}
std::string GetFileName(const std::string &filename) {
size_t slash = filename.find_last_of('/');
if (slash == std::string::npos) {
return filename;
}
return filename.substr(slash + 1);
}
std::string LoadFile(const std::string &filename) {
std::string contents;
std::ifstream file(filename);
if (file.is_open()) {
std::stringstream buffer;
buffer << file.rdbuf();
contents = buffer.str();
file.close();
} else {
// Throw an exception
throw std::runtime_error("Could not open file: " + filename);
}
return contents;
}
std::string LoadConfigFile(const std::string &filename) {
std::string contents;
std::string filepath = GetConfigDirectory() + "/" + filename;
std::ifstream file(filepath);
if (file.is_open()) {
std::stringstream buffer;
buffer << file.rdbuf();
contents = buffer.str();
file.close();
}
return contents;
}
void SaveFile(const std::string &filename, const std::string &contents) {
std::string filepath = GetConfigDirectory() + "/" + filename;
std::ofstream file(filepath);
if (file.is_open()) {
file << contents;
file.close();
}
}
std::string GetResourcePath(const std::string &resource_path) {
#ifdef __APPLE__
#if TARGET_OS_IOS == 1
const std::string kBundlePath = GetBundleResourcePath();
return kBundlePath + resource_path;
#else
return GetBundleResourcePath() + "Contents/Resources/" + resource_path;
#endif
#else
return resource_path; // On Linux/Windows, resources are relative to executable
#endif
}
std::string ExpandHomePath(const std::string& path) {
if (path.empty() || path[0] != '~') {
return path;
}
const char* home = nullptr;
#ifdef _WIN32
home = std::getenv("USERPROFILE");
if (!home) {
home = std::getenv("HOMEDRIVE");
const char* homePath = std::getenv("HOMEPATH");
if (home && homePath) {
static std::string full_path;
full_path = std::string(home) + std::string(homePath);
home = full_path.c_str();
}
}
#else
home = std::getenv("HOME");
#endif
if (!home) {
return path; // Fallback to original path if HOME not found
}
// Replace ~ with home directory
if (path.size() == 1 || path[1] == '/') {
return std::string(home) + path.substr(1);
}
return path;
}
bool EnsureConfigDirectoryExists() {
std::string config_dir = GetConfigDirectory();
#ifdef _WIN32
// Windows directory creation
DWORD attr = GetFileAttributesA(config_dir.c_str());
if (attr == INVALID_FILE_ATTRIBUTES) {
// Directory doesn't exist, create it
if (!CreateDirectoryA(config_dir.c_str(), NULL)) {
DWORD error = GetLastError();
if (error != ERROR_ALREADY_EXISTS) {
return false;
}
}
}
#else
// Unix-like directory creation
struct stat st;
if (stat(config_dir.c_str(), &st) != 0) {
// Directory doesn't exist, create it with 0755 permissions
if (mkdir(config_dir.c_str(), 0755) != 0) {
if (errno != EEXIST) {
return false;
}
}
}
#endif
return true;
}
std::string GetConfigDirectory() {
std::string config_directory = ".yaze";
Platform platform;
#if defined(__APPLE__) && defined(__MACH__)
#if TARGET_IPHONE_SIMULATOR == 1 || TARGET_OS_IPHONE == 1
platform = Platform::kiOS;
#elif TARGET_OS_MAC == 1
platform = Platform::kMacOS;
#else
platform = Platform::kMacOS; // Default for macOS
#endif
#elif defined(_WIN32)
platform = Platform::kWindows;
#elif defined(__linux__)
platform = Platform::kLinux;
#else
platform = Platform::kUnknown;
#endif
switch (platform) {
case Platform::kWindows:
config_directory = "~/AppData/Roaming/yaze";
break;
case Platform::kMacOS:
case Platform::kLinux:
config_directory = "~/.config/yaze";
break;
default:
break;
}
// Expand the home directory path
return ExpandHomePath(config_directory);
}
#ifdef _WIN32
#if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD
#include <nfd.h>
#endif
std::string FileDialogWrapper::ShowOpenFileDialog() {
// Use global feature flag to choose implementation
if (FeatureFlags::get().kUseNativeFileDialog) {
return ShowOpenFileDialogNFD();
} else {
return ShowOpenFileDialogBespoke();
}
}
std::string FileDialogWrapper::ShowOpenFileDialogNFD() {
#if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD
NFD_Init();
nfdu8char_t *out_path = NULL;
nfdu8filteritem_t filters[1] = {{"ROM Files", "sfc,smc"}};
nfdopendialogu8args_t args = {0};
args.filterList = filters;
args.filterCount = 1;
nfdresult_t result = NFD_OpenDialogU8_With(&out_path, &args);
if (result == NFD_OKAY) {
std::string file_path(out_path);
NFD_FreePath(out_path);
NFD_Quit();
return file_path;
} else if (result == NFD_CANCEL) {
NFD_Quit();
return "";
}
NFD_Quit();
return "";
#else
// NFD not available - fallback to bespoke
return ShowOpenFileDialogBespoke();
#endif
}
std::string FileDialogWrapper::ShowOpenFileDialogBespoke() {
// Use Windows COM-based IFileOpenDialog as fallback when NFD not available
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (FAILED(hr)) {
return "";
}
std::string result;
IFileOpenDialog *pFileOpen = NULL;
// Create the FileOpenDialog object
hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));
if (SUCCEEDED(hr)) {
// Set file type filters
COMDLG_FILTERSPEC rgSpec[] = {
{L"ROM Files", L"*.sfc;*.smc"},
{L"All Files", L"*.*"}
};
pFileOpen->SetFileTypes(ARRAYSIZE(rgSpec), rgSpec);
pFileOpen->SetFileTypeIndex(1);
pFileOpen->SetDefaultExtension(L"sfc");
// Show the Open dialog
hr = pFileOpen->Show(NULL);
if (SUCCEEDED(hr)) {
// Get the file name from the dialog
IShellItem *pItem;
hr = pFileOpen->GetResult(&pItem);
if (SUCCEEDED(hr)) {
PWSTR pszFilePath;
hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
if (SUCCEEDED(hr)) {
// Convert wide string to narrow string
int size_needed = WideCharToMultiByte(CP_UTF8, 0, pszFilePath, -1, NULL, 0, NULL, NULL);
if (size_needed > 0) {
std::vector<char> buffer(size_needed);
WideCharToMultiByte(CP_UTF8, 0, pszFilePath, -1, buffer.data(), size_needed, NULL, NULL);
result = std::string(buffer.data());
}
CoTaskMemFree(pszFilePath);
}
pItem->Release();
}
}
pFileOpen->Release();
}
CoUninitialize();
return result;
}
std::string FileDialogWrapper::ShowSaveFileDialog(const std::string& default_name,
const std::string& default_extension) {
// Use global feature flag to choose implementation
if (FeatureFlags::get().kUseNativeFileDialog) {
return ShowSaveFileDialogNFD(default_name, default_extension);
} else {
return ShowSaveFileDialogBespoke(default_name, default_extension);
}
}
std::string FileDialogWrapper::ShowSaveFileDialogNFD(const std::string& default_name,
const std::string& default_extension) {
#if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD
NFD_Init();
nfdu8char_t *out_path = NULL;
nfdsavedialogu8args_t args = {0};
if (!default_extension.empty()) {
// Create filter for the save dialog
static nfdu8filteritem_t filters[3] = {
{"Theme Files", "theme"},
{"YAZE Project Files", "yaze"},
{"ROM Files", "sfc,smc"}
};
if (default_extension == "theme") {
args.filterList = &filters[0];
args.filterCount = 1;
} else if (default_extension == "yaze") {
args.filterList = &filters[1];
args.filterCount = 1;
} else if (default_extension == "sfc" || default_extension == "smc") {
args.filterList = &filters[2];
args.filterCount = 1;
}
}
if (!default_name.empty()) {
args.defaultName = default_name.c_str();
}
nfdresult_t result = NFD_SaveDialogU8_With(&out_path, &args);
if (result == NFD_OKAY) {
std::string file_path(out_path);
NFD_FreePath(out_path);
NFD_Quit();
return file_path;
} else if (result == NFD_CANCEL) {
NFD_Quit();
return "";
}
NFD_Quit();
return "";
#else
// NFD not available - fallback to bespoke
return ShowSaveFileDialogBespoke(default_name, default_extension);
#endif
}
std::string FileDialogWrapper::ShowSaveFileDialogBespoke(const std::string& default_name,
const std::string& default_extension) {
// Use Windows COM-based IFileSaveDialog as fallback when NFD not available
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (FAILED(hr)) {
return "";
}
std::string result;
IFileSaveDialog *pFileSave = NULL;
// Create the FileSaveDialog object
hr = CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_ALL,
IID_IFileSaveDialog, reinterpret_cast<void**>(&pFileSave));
if (SUCCEEDED(hr)) {
// Set file type filters based on extension
if (default_extension == "theme") {
COMDLG_FILTERSPEC rgSpec[] = {{L"Theme Files", L"*.theme"}};
pFileSave->SetFileTypes(ARRAYSIZE(rgSpec), rgSpec);
pFileSave->SetDefaultExtension(L"theme");
} else if (default_extension == "yaze") {
COMDLG_FILTERSPEC rgSpec[] = {{L"YAZE Project Files", L"*.yaze"}};
pFileSave->SetFileTypes(ARRAYSIZE(rgSpec), rgSpec);
pFileSave->SetDefaultExtension(L"yaze");
} else if (default_extension == "sfc" || default_extension == "smc") {
COMDLG_FILTERSPEC rgSpec[] = {
{L"SFC ROM Files", L"*.sfc"},
{L"SMC ROM Files", L"*.smc"}
};
pFileSave->SetFileTypes(ARRAYSIZE(rgSpec), rgSpec);
pFileSave->SetDefaultExtension(default_extension == "sfc" ? L"sfc" : L"smc");
}
// Set default filename if provided
if (!default_name.empty()) {
int size_needed = MultiByteToWideChar(CP_UTF8, 0, default_name.c_str(), -1, NULL, 0);
if (size_needed > 0) {
std::vector<wchar_t> wname(size_needed);
MultiByteToWideChar(CP_UTF8, 0, default_name.c_str(), -1, wname.data(), size_needed);
pFileSave->SetFileName(wname.data());
}
}
// Show the Save dialog
hr = pFileSave->Show(NULL);
if (SUCCEEDED(hr)) {
// Get the file name from the dialog
IShellItem *pItem;
hr = pFileSave->GetResult(&pItem);
if (SUCCEEDED(hr)) {
PWSTR pszFilePath;
hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
if (SUCCEEDED(hr)) {
// Convert wide string to narrow string
int size_needed = WideCharToMultiByte(CP_UTF8, 0, pszFilePath, -1, NULL, 0, NULL, NULL);
if (size_needed > 0) {
std::vector<char> buffer(size_needed);
WideCharToMultiByte(CP_UTF8, 0, pszFilePath, -1, buffer.data(), size_needed, NULL, NULL);
result = std::string(buffer.data());
}
CoTaskMemFree(pszFilePath);
}
pItem->Release();
}
}
pFileSave->Release();
}
CoUninitialize();
return result;
}
std::string FileDialogWrapper::ShowOpenFolderDialog() {
// Use global feature flag to choose implementation
if (FeatureFlags::get().kUseNativeFileDialog) {
return ShowOpenFolderDialogNFD();
} else {
return ShowOpenFolderDialogBespoke();
}
}
std::string FileDialogWrapper::ShowOpenFolderDialogNFD() {
#if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD
NFD_Init();
nfdu8char_t *out_path = NULL;
nfdresult_t result = NFD_PickFolderU8(&out_path, NULL);
if (result == NFD_OKAY) {
std::string folder_path(out_path);
NFD_FreePath(out_path);
NFD_Quit();
return folder_path;
} else if (result == NFD_CANCEL) {
NFD_Quit();
return "";
}
NFD_Quit();
return "";
#else
// NFD not available - fallback to bespoke
return ShowOpenFolderDialogBespoke();
#endif
}
std::string FileDialogWrapper::ShowOpenFolderDialogBespoke() {
// Use Windows COM-based IFileOpenDialog in folder-picking mode as fallback
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (FAILED(hr)) {
return "";
}
std::string result;
IFileOpenDialog *pFileOpen = NULL;
// Create the FileOpenDialog object
hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));
if (SUCCEEDED(hr)) {
// Set options to pick folders instead of files
DWORD dwOptions;
hr = pFileOpen->GetOptions(&dwOptions);
if (SUCCEEDED(hr)) {
hr = pFileOpen->SetOptions(dwOptions | FOS_PICKFOLDERS);
}
if (SUCCEEDED(hr)) {
// Show the Open dialog
hr = pFileOpen->Show(NULL);
if (SUCCEEDED(hr)) {
// Get the folder path from the dialog
IShellItem *pItem;
hr = pFileOpen->GetResult(&pItem);
if (SUCCEEDED(hr)) {
PWSTR pszFolderPath;
hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFolderPath);
if (SUCCEEDED(hr)) {
// Convert wide string to narrow string
int size_needed = WideCharToMultiByte(CP_UTF8, 0, pszFolderPath, -1, NULL, 0, NULL, NULL);
if (size_needed > 0) {
std::vector<char> buffer(size_needed);
WideCharToMultiByte(CP_UTF8, 0, pszFolderPath, -1, buffer.data(), size_needed, NULL, NULL);
result = std::string(buffer.data());
}
CoTaskMemFree(pszFolderPath);
}
pItem->Release();
}
}
}
pFileOpen->Release();
}
CoUninitialize();
return result;
}
std::vector<std::string> FileDialogWrapper::GetSubdirectoriesInFolder(
const std::string &folder_path) {
std::vector<std::string> subdirectories;
WIN32_FIND_DATA findFileData;
HANDLE hFind = FindFirstFile((folder_path + "\\*").c_str(), &findFileData);
if (hFind != INVALID_HANDLE_VALUE) {
do {
if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (strcmp(findFileData.cFileName, ".") != 0 &&
strcmp(findFileData.cFileName, "..") != 0) {
subdirectories.emplace_back(findFileData.cFileName);
}
}
} while (FindNextFile(hFind, &findFileData) != 0);
FindClose(hFind);
}
return subdirectories;
}
std::vector<std::string> FileDialogWrapper::GetFilesInFolder(
const std::string &folder_path) {
std::vector<std::string> files;
WIN32_FIND_DATA findFileData;
HANDLE hFind = FindFirstFile((folder_path + "\\*").c_str(), &findFileData);
if (hFind != INVALID_HANDLE_VALUE) {
do {
if (!(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
files.emplace_back(findFileData.cFileName);
}
} while (FindNextFile(hFind, &findFileData) != 0);
FindClose(hFind);
}
return files;
}
#elif defined(__linux__)
#if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD
#include <nfd.h>
#endif
std::string FileDialogWrapper::ShowOpenFileDialog() {
// Use global feature flag to choose implementation
if (FeatureFlags::get().kUseNativeFileDialog) {
return ShowOpenFileDialogNFD();
} else {
return ShowOpenFileDialogBespoke();
}
}
std::string FileDialogWrapper::ShowOpenFileDialogNFD() {
#if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD
NFD_Init();
nfdu8char_t *out_path = NULL;
nfdu8filteritem_t filters[1] = {{"Rom File", "sfc,smc"}};
nfdopendialogu8args_t args = {0};
args.filterList = filters;
args.filterCount = 1;
nfdresult_t result = NFD_OpenDialogU8_With(&out_path, &args);
if (result == NFD_OKAY) {
std::string file_path_linux(out_path);
NFD_FreePath(out_path);
NFD_Quit();
return file_path_linux;
} else if (result == NFD_CANCEL) {
NFD_Quit();
return "";
}
NFD_Quit();
return "Error: NFD_OpenDialog";
#else
// NFD not available - fallback to bespoke
return ShowOpenFileDialogBespoke();
#endif
}
std::string FileDialogWrapper::ShowOpenFileDialogBespoke() {
// Implement bespoke file dialog or return placeholder
// This would contain the custom Linux implementation
return ""; // Placeholder for bespoke implementation
}
std::string FileDialogWrapper::ShowSaveFileDialogNFD(const std::string& default_name,
const std::string& default_extension) {
#if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD
NFD_Init();
nfdu8char_t *out_path = NULL;
nfdsavedialogu8args_t args = {0};
if (!default_extension.empty()) {
// Create filter for the save dialog
static nfdu8filteritem_t filters[3] = {
{"Theme File", "theme"},
{"Project File", "yaze"},
{"ROM File", "sfc,smc"}
};
if (default_extension == "theme") {
args.filterList = &filters[0];
args.filterCount = 1;
} else if (default_extension == "yaze") {
args.filterList = &filters[1];
args.filterCount = 1;
} else if (default_extension == "sfc" || default_extension == "smc") {
args.filterList = &filters[2];
args.filterCount = 1;
}
}
if (!default_name.empty()) {
args.defaultName = default_name.c_str();
}
nfdresult_t result = NFD_SaveDialogU8_With(&out_path, &args);
if (result == NFD_OKAY) {
std::string file_path(out_path);
NFD_FreePath(out_path);
NFD_Quit();
return file_path;
} else if (result == NFD_CANCEL) {
NFD_Quit();
return "";
}
NFD_Quit();
return "";
#else
// NFD not available - fallback to bespoke
return ShowSaveFileDialogBespoke(default_name, default_extension);
#endif
}
std::string FileDialogWrapper::ShowSaveFileDialogBespoke(const std::string& default_name,
const std::string& default_extension) {
// Basic Linux implementation using system command
// For CI/CD, just return a placeholder path
if (!default_name.empty() && !default_extension.empty()) {
return default_name + "." + default_extension;
}
return ""; // For now return empty - full implementation can be added later
}
std::string FileDialogWrapper::ShowSaveFileDialog(const std::string& default_name,
const std::string& default_extension) {
// Use global feature flag to choose implementation
if (FeatureFlags::get().kUseNativeFileDialog) {
return ShowSaveFileDialogNFD(default_name, default_extension);
} else {
return ShowSaveFileDialogBespoke(default_name, default_extension);
}
}
std::string FileDialogWrapper::ShowOpenFolderDialog() {
// Use global feature flag to choose implementation
if (FeatureFlags::get().kUseNativeFileDialog) {
return ShowOpenFolderDialogNFD();
} else {
return ShowOpenFolderDialogBespoke();
}
}
std::string FileDialogWrapper::ShowOpenFolderDialogNFD() {
#if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD
NFD_Init();
nfdu8char_t *out_path = NULL;
nfdresult_t result = NFD_PickFolderU8(&out_path, NULL);
if (result == NFD_OKAY) {
std::string folder_path_linux(out_path);
NFD_FreePath(out_path);
NFD_Quit();
return folder_path_linux;
} else if (result == NFD_CANCEL) {
NFD_Quit();
return "";
}
NFD_Quit();
return "Error: NFD_PickFolder";
#else
// NFD not available - fallback to bespoke
return ShowOpenFolderDialogBespoke();
#endif
}
std::string FileDialogWrapper::ShowOpenFolderDialogBespoke() {
// Implement bespoke folder dialog or return placeholder
// This would contain the custom macOS implementation
return ""; // Placeholder for bespoke implementation
}
std::vector<std::string> FileDialogWrapper::GetSubdirectoriesInFolder(
const std::string &folder_path) {
std::vector<std::string> subdirectories;
DIR *dir;
struct dirent *ent;
if ((dir = opendir(folder_path.c_str())) != NULL) {
while ((ent = readdir(dir)) != NULL) {
if (ent->d_type == DT_DIR) {
if (strcmp(ent->d_name, ".") != 0 && strcmp(ent->d_name, "..") != 0) {
subdirectories.push_back(ent->d_name);
}
}
}
closedir(dir);
}
return subdirectories;
}
std::vector<std::string> FileDialogWrapper::GetFilesInFolder(
const std::string &folder_path) {
std::vector<std::string> files;
DIR *dir;
struct dirent *ent;
if ((dir = opendir(folder_path.c_str())) != NULL) {
while ((ent = readdir(dir)) != NULL) {
if (ent->d_type == DT_REG) {
files.push_back(ent->d_name);
}
}
closedir(dir);
}
return files;
}
#endif
} // namespace core
} // namespace yaze

View File

@@ -1,67 +0,0 @@
#ifndef YAZE_APP_CORE_PLATFORM_FILE_DIALOG_H
#define YAZE_APP_CORE_PLATFORM_FILE_DIALOG_H
#include <string>
#include <vector>
namespace yaze {
namespace core {
class FileDialogWrapper {
public:
/**
* @brief ShowOpenFileDialog opens a file dialog and returns the selected
* filepath. Uses global feature flag to choose implementation.
*/
static std::string ShowOpenFileDialog();
/**
* @brief ShowOpenFolderDialog opens a file dialog and returns the selected
* folder path. Uses global feature flag to choose implementation.
*/
static std::string ShowOpenFolderDialog();
/**
* @brief ShowSaveFileDialog opens a save file dialog and returns the selected
* filepath. Uses global feature flag to choose implementation.
*/
static std::string ShowSaveFileDialog(const std::string& default_name = "",
const std::string& default_extension = "");
// Specific implementations for testing
static std::string ShowOpenFileDialogNFD();
static std::string ShowOpenFileDialogBespoke();
static std::string ShowSaveFileDialogNFD(const std::string& default_name = "",
const std::string& default_extension = "");
static std::string ShowSaveFileDialogBespoke(const std::string& default_name = "",
const std::string& default_extension = "");
static std::string ShowOpenFolderDialogNFD();
static std::string ShowOpenFolderDialogBespoke();
static std::vector<std::string> GetSubdirectoriesInFolder(
const std::string &folder_path);
static std::vector<std::string> GetFilesInFolder(
const std::string &folder_path);
};
/**
* @brief GetBundleResourcePath returns the path to the bundle resource
* directory. Specific to MacOS.
*/
std::string GetBundleResourcePath();
enum class Platform { kUnknown, kMacOS, kiOS, kWindows, kLinux };
std::string GetFileExtension(const std::string &filename);
std::string GetFileName(const std::string &filename);
std::string LoadFile(const std::string &filename);
std::string LoadConfigFile(const std::string &filename);
std::string GetConfigDirectory();
bool EnsureConfigDirectoryExists();
std::string ExpandHomePath(const std::string& path);
std::string GetResourcePath(const std::string &resource_path);
void SaveFile(const std::string &filename, const std::string &data);
} // namespace core
} // namespace yaze
#endif // YAZE_APP_CORE_PLATFORM_FILE_DIALOG_H

View File

@@ -1,4 +1,4 @@
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include <iostream>
#include <string>
@@ -46,21 +46,21 @@ std::string ShowOpenFileDialogSync() {
}
} // namespace
std::string yaze::core::FileDialogWrapper::ShowOpenFileDialog() { return ShowOpenFileDialogSync(); }
std::string yaze::util::FileDialogWrapper::ShowOpenFileDialog() { return ShowOpenFileDialogSync(); }
std::string yaze::core::FileDialogWrapper::ShowOpenFolderDialog() { return ""; }
std::string yaze::util::FileDialogWrapper::ShowOpenFolderDialog() { return ""; }
std::vector<std::string> yaze::core::FileDialogWrapper::GetFilesInFolder(
std::vector<std::string> yaze::util::FileDialogWrapper::GetFilesInFolder(
const std::string &folder) {
return {};
}
std::vector<std::string> yaze::core::FileDialogWrapper::GetSubdirectoriesInFolder(
std::vector<std::string> yaze::util::FileDialogWrapper::GetSubdirectoriesInFolder(
const std::string &folder) {
return {};
}
std::string yaze::core::GetBundleResourcePath() {
std::string yaze::util::GetBundleResourcePath() {
NSBundle* bundle = [NSBundle mainBundle];
NSString* resourceDirectoryPath = [bundle bundlePath];
NSString* path = [resourceDirectoryPath stringByAppendingString:@"/"];
@@ -73,7 +73,7 @@ std::string yaze::core::GetBundleResourcePath() {
#import <Cocoa/Cocoa.h>
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
std::string yaze::core::FileDialogWrapper::ShowOpenFileDialogBespoke() {
std::string yaze::util::FileDialogWrapper::ShowOpenFileDialogBespoke() {
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
[openPanel setCanChooseFiles:YES];
[openPanel setCanChooseDirectories:NO];
@@ -88,7 +88,7 @@ std::string yaze::core::FileDialogWrapper::ShowOpenFileDialogBespoke() {
return "";
}
std::string yaze::core::FileDialogWrapper::ShowSaveFileDialogBespoke(const std::string& default_name,
std::string yaze::util::FileDialogWrapper::ShowSaveFileDialogBespoke(const std::string& default_name,
const std::string& default_extension) {
NSSavePanel* savePanel = [NSSavePanel savePanel];
@@ -111,7 +111,7 @@ std::string yaze::core::FileDialogWrapper::ShowSaveFileDialogBespoke(const std::
}
// Global feature flag-based dispatch methods
std::string yaze::core::FileDialogWrapper::ShowOpenFileDialog() {
std::string yaze::util::FileDialogWrapper::ShowOpenFileDialog() {
if (FeatureFlags::get().kUseNativeFileDialog) {
return ShowOpenFileDialogNFD();
} else {
@@ -119,7 +119,7 @@ std::string yaze::core::FileDialogWrapper::ShowOpenFileDialog() {
}
}
std::string yaze::core::FileDialogWrapper::ShowOpenFolderDialog() {
std::string yaze::util::FileDialogWrapper::ShowOpenFolderDialog() {
if (FeatureFlags::get().kUseNativeFileDialog) {
return ShowOpenFolderDialogNFD();
} else {
@@ -127,7 +127,7 @@ std::string yaze::core::FileDialogWrapper::ShowOpenFolderDialog() {
}
}
std::string yaze::core::FileDialogWrapper::ShowSaveFileDialog(const std::string& default_name,
std::string yaze::util::FileDialogWrapper::ShowSaveFileDialog(const std::string& default_name,
const std::string& default_extension) {
if (FeatureFlags::get().kUseNativeFileDialog) {
return ShowSaveFileDialogNFD(default_name, default_extension);
@@ -137,7 +137,7 @@ std::string yaze::core::FileDialogWrapper::ShowSaveFileDialog(const std::string&
}
// NFD implementation for macOS (fallback to bespoke if NFD not available)
std::string yaze::core::FileDialogWrapper::ShowOpenFileDialogNFD() {
std::string yaze::util::FileDialogWrapper::ShowOpenFileDialogNFD() {
#if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD
NFD_Init();
nfdu8char_t *out_path = NULL;
@@ -164,7 +164,7 @@ std::string yaze::core::FileDialogWrapper::ShowOpenFileDialogNFD() {
#endif
}
std::string yaze::core::FileDialogWrapper::ShowOpenFolderDialogNFD() {
std::string yaze::util::FileDialogWrapper::ShowOpenFolderDialogNFD() {
#if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD
NFD_Init();
nfdu8char_t *out_path = NULL;
@@ -187,7 +187,7 @@ std::string yaze::core::FileDialogWrapper::ShowOpenFolderDialogNFD() {
#endif
}
std::string yaze::core::FileDialogWrapper::ShowSaveFileDialogNFD(const std::string& default_name,
std::string yaze::util::FileDialogWrapper::ShowSaveFileDialogNFD(const std::string& default_name,
const std::string& default_extension) {
#if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD
NFD_Init();
@@ -236,7 +236,7 @@ std::string yaze::core::FileDialogWrapper::ShowSaveFileDialogNFD(const std::stri
#endif
}
std::string yaze::core::FileDialogWrapper::ShowOpenFolderDialogBespoke() {
std::string yaze::util::FileDialogWrapper::ShowOpenFolderDialogBespoke() {
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
[openPanel setCanChooseFiles:NO];
[openPanel setCanChooseDirectories:YES];
@@ -251,7 +251,7 @@ std::string yaze::core::FileDialogWrapper::ShowOpenFolderDialogBespoke() {
return "";
}
std::vector<std::string> yaze::core::FileDialogWrapper::GetFilesInFolder(
std::vector<std::string> yaze::util::FileDialogWrapper::GetFilesInFolder(
const std::string& folder) {
std::vector<std::string> filenames;
NSFileManager* fileManager = [NSFileManager defaultManager];
@@ -267,7 +267,7 @@ std::vector<std::string> yaze::core::FileDialogWrapper::GetFilesInFolder(
return filenames;
}
std::vector<std::string> yaze::core::FileDialogWrapper::GetSubdirectoriesInFolder(
std::vector<std::string> yaze::util::FileDialogWrapper::GetSubdirectoriesInFolder(
const std::string& folder) {
std::vector<std::string> subdirectories;
NSFileManager* fileManager = [NSFileManager defaultManager];
@@ -289,7 +289,7 @@ std::vector<std::string> yaze::core::FileDialogWrapper::GetSubdirectoriesInFolde
return subdirectories;
}
std::string yaze::core::GetBundleResourcePath() {
std::string yaze::util::GetBundleResourcePath() {
NSBundle* bundle = [NSBundle mainBundle];
NSString* resourceDirectoryPath = [bundle bundlePath];
NSString* path = [resourceDirectoryPath stringByAppendingString:@"/"];

View File

@@ -9,7 +9,7 @@
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include "app/gui/icons.h"
#include "imgui/imgui.h"
#include "util/macro.h"
@@ -33,10 +33,10 @@ namespace {
std::string SetFontPath(const std::string& font_path) {
#ifdef __APPLE__
#if TARGET_OS_IOS == 1
const std::string kBundlePath = GetBundleResourcePath();
const std::string kBundlePath = util::GetBundleResourcePath();
return kBundlePath + font_path;
#else
return absl::StrCat(GetBundleResourcePath(), "Contents/Resources/font/",
return absl::StrCat(util::GetBundleResourcePath(), "Contents/Resources/font/",
font_path);
#endif
#else

View File

@@ -1,38 +0,0 @@
#ifndef YAZE_APP_CORE_UTILS_SDL_DELETER_H_
#define YAZE_APP_CORE_UTILS_SDL_DELETER_H_
#include <SDL.h>
namespace yaze {
namespace core {
/**
* @brief Deleter for SDL_Window and SDL_Renderer.
*/
struct SDL_Deleter {
void operator()(SDL_Window* p) const { SDL_DestroyWindow(p); }
void operator()(SDL_Renderer* p) const { SDL_DestroyRenderer(p); }
};
// Custom deleter for SDL_Surface
struct SDL_Surface_Deleter {
void operator()(SDL_Surface* p) const {
if (p) {
SDL_FreeSurface(p);
}
}
};
// Custom deleter for SDL_Texture
struct SDL_Texture_Deleter {
void operator()(SDL_Texture* p) const {
if (p) {
SDL_DestroyTexture(p);
}
}
};
} // namespace core
} // namespace yaze
#endif // YAZE_APP_CORE_UTILS_SDL_DELETER_H_

View File

@@ -9,7 +9,7 @@
#include "absl/strings/str_format.h"
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include "app/gui/icons.h"
#include "app/zelda3/zelda3_labels.h"
#include "imgui/imgui.h"

View File

@@ -6,7 +6,7 @@
#include "absl/strings/string_view.h"
#include "app/core/proto/imgui_test_harness.pb.h"
#include "app/gui/widget_id_registry.h"
#include "app/gui/widgets/widget_id_registry.h"
#if defined(YAZE_ENABLE_IMGUI_TEST_ENGINE) && YAZE_ENABLE_IMGUI_TEST_ENGINE
#include "imgui_test_engine/imgui_te_context.h"

View File

@@ -3,7 +3,7 @@
#include "absl/status/status.h"
#include "absl/strings/str_format.h"
#include "app/core/platform/font_loader.h"
#include "app/core/platform/sdl_deleter.h"
#include "util/sdl_deleter.h"
#include "app/gfx/arena.h"
#include "app/gui/style.h"
#include "app/gui/theme_manager.h"

View File

@@ -7,7 +7,7 @@
#include "absl/status/status.h"
#include "absl/strings/str_format.h"
#include "app/core/platform/sdl_deleter.h"
#include "util/sdl_deleter.h"
#include "app/gfx/bitmap.h"
namespace yaze {

View File

@@ -14,7 +14,7 @@
#include "absl/strings/str_format.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include "app/editor/agent/agent_chat_history_codec.h"
#include "app/editor/system/proposal_drawer.h"
#include "app/editor/system/toast_manager.h"
@@ -48,7 +48,7 @@ std::filesystem::path ExpandUserPath(std::string path) {
}
std::filesystem::path ResolveHistoryPath(const std::string& session_id = "") {
std::filesystem::path base = ExpandUserPath(yaze::core::GetConfigDirectory());
std::filesystem::path base = ExpandUserPath(yaze::util::GetConfigDirectory());
if (base.empty()) {
base = ExpandUserPath(".yaze");
}
@@ -1723,7 +1723,7 @@ void AgentChatWidget::RenderSystemPromptEditor() {
// Save the current system prompt to project directory
for (auto& tab : open_files_) {
if (tab.is_system_prompt) {
auto save_path = core::FileDialogWrapper::ShowSaveFileDialog(
auto save_path = util::FileDialogWrapper::ShowSaveFileDialog(
"custom_system_prompt", "txt");
if (!save_path.empty()) {
std::ofstream file(save_path);
@@ -1760,7 +1760,7 @@ void AgentChatWidget::RenderSystemPromptEditor() {
ImGui::SameLine();
if (ImGui::Button(ICON_MD_FOLDER_OPEN " Load Custom")) {
auto filepath = core::FileDialogWrapper::ShowOpenFileDialog();
auto filepath = util::FileDialogWrapper::ShowOpenFileDialog();
if (!filepath.empty()) {
std::ifstream file(filepath);
if (file.is_open()) {
@@ -1832,7 +1832,7 @@ void AgentChatWidget::RenderFileEditorTabs() {
}
ImGui::SameLine();
if (ImGui::Button(ICON_MD_FOLDER_OPEN " Open File")) {
auto filepath = core::FileDialogWrapper::ShowOpenFileDialog();
auto filepath = util::FileDialogWrapper::ShowOpenFileDialog();
if (!filepath.empty()) {
OpenFileInEditor(filepath);
}
@@ -1890,7 +1890,7 @@ void AgentChatWidget::RenderFileEditorTabs() {
toast_manager_->Show("Failed to save file", ToastType::kError);
}
} else {
auto save_path = core::FileDialogWrapper::ShowSaveFileDialog(
auto save_path = util::FileDialogWrapper::ShowSaveFileDialog(
open_files_[i].filename, "");
if (!save_path.empty()) {
std::ofstream file(save_path);

View File

@@ -17,7 +17,7 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/strip.h"
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include "util/macro.h"
namespace yaze {

View File

@@ -6,13 +6,13 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/match.h"
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include "app/gui/icons.h"
#include "app/gui/modules/text_editor.h"
namespace yaze::editor {
using core::FileDialogWrapper;
using util::FileDialogWrapper;
namespace {
@@ -283,7 +283,7 @@ void AssemblyEditor::DrawFileTabView() {
void AssemblyEditor::DrawFileMenu() {
if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("Open", "Ctrl+O")) {
auto filename = core::FileDialogWrapper::ShowOpenFileDialog();
auto filename = util::FileDialogWrapper::ShowOpenFileDialog();
ChangeActiveFile(filename);
}
if (ImGui::MenuItem("Save", "Ctrl+S")) {

View File

@@ -1,7 +1,7 @@
#ifndef YAZE_APP_EDITOR_CODE_MEMORY_EDITOR_H
#define YAZE_APP_EDITOR_CODE_MEMORY_EDITOR_H
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include "app/gui/input.h"
#include "app/rom.h"
#include "app/snes.h"
@@ -25,7 +25,7 @@ struct MemoryEditorWithDiffChecker {
static Rom comparison_rom;
ImGui::Begin("Hex Editor", &show_memory_editor);
if (ImGui::Button("Compare Rom")) {
auto file_name = core::FileDialogWrapper::ShowOpenFileDialog();
auto file_name = util::FileDialogWrapper::ShowOpenFileDialog();
PRINT_IF_ERROR(comparison_rom.LoadFromFile(file_name));
show_compare_rom = true;
}

View File

@@ -6,7 +6,7 @@
#include "absl/strings/match.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_split.h"
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include "app/editor/system/toast_manager.h"
#include "app/gui/icons.h"
#include "imgui/imgui.h"
@@ -40,7 +40,7 @@ void ProjectFileEditor::Draw() {
ImGui::TableNextColumn();
if (ImGui::Button(absl::StrFormat("%s Open", ICON_MD_FOLDER_OPEN).c_str())) {
auto file = core::FileDialogWrapper::ShowOpenFileDialog();
auto file = util::FileDialogWrapper::ShowOpenFileDialog();
if (!file.empty()) {
auto status = LoadFile(file);
if (!status.ok() && toast_manager_) {
@@ -65,7 +65,7 @@ void ProjectFileEditor::Draw() {
ImGui::TableNextColumn();
if (ImGui::Button(absl::StrFormat("%s Save As", ICON_MD_SAVE_AS).c_str())) {
auto file = core::FileDialogWrapper::ShowSaveFileDialog(
auto file = util::FileDialogWrapper::ShowSaveFileDialog(
filepath_.empty() ? "project" : filepath_, "yaze");
if (!file.empty()) {
auto status = SaveFileAs(file);

View File

@@ -11,7 +11,7 @@
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "app/core/features.h"
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include "app/core/project.h"
#include "app/editor/code/assembly_editor.h"
#include "app/editor/dungeon/dungeon_editor.h"
@@ -62,7 +62,7 @@ namespace yaze {
namespace editor {
using namespace ImGui;
using core::FileDialogWrapper;
using util::FileDialogWrapper;
namespace {
@@ -1620,7 +1620,7 @@ void EditorManager::DrawMenuBar() {
gui::kDefaultModalSize)) {
// Use save file dialog for ROM files
auto file_path =
core::FileDialogWrapper::ShowSaveFileDialog(save_as_filename, "sfc");
util::FileDialogWrapper::ShowSaveFileDialog(save_as_filename, "sfc");
if (!file_path.empty()) {
save_as_filename = file_path;
}
@@ -1698,7 +1698,7 @@ void EditorManager::DrawMenuBar() {
.c_str(),
gui::kDefaultModalSize)) {
auto project_file_path =
core::FileDialogWrapper::ShowSaveFileDialog(save_as_filename, "yaze");
util::FileDialogWrapper::ShowSaveFileDialog(save_as_filename, "yaze");
if (!project_file_path.empty()) {
// Ensure .yaze extension
if (project_file_path.find(".yaze") == std::string::npos) {
@@ -1975,7 +1975,7 @@ absl::Status EditorManager::OpenRomOrProject(const std::string& filename) {
}
absl::Status EditorManager::CreateNewProject(const std::string& template_name) {
auto dialog_path = core::FileDialogWrapper::ShowOpenFolderDialog();
auto dialog_path = util::FileDialogWrapper::ShowOpenFolderDialog();
if (dialog_path.empty()) {
return absl::OkStatus(); // User cancelled
}
@@ -1986,7 +1986,7 @@ absl::Status EditorManager::CreateNewProject(const std::string& template_name) {
}
absl::Status EditorManager::OpenProject() {
auto file_path = core::FileDialogWrapper::ShowOpenFileDialog();
auto file_path = util::FileDialogWrapper::ShowOpenFileDialog();
if (file_path.empty()) {
return absl::OkStatus();
}
@@ -2101,7 +2101,7 @@ absl::Status EditorManager::SaveProjectAs() {
: "untitled_project";
auto file_path =
core::FileDialogWrapper::ShowSaveFileDialog(default_name, "yaze");
util::FileDialogWrapper::ShowSaveFileDialog(default_name, "yaze");
if (file_path.empty()) {
return absl::OkStatus();
}
@@ -3195,7 +3195,7 @@ void EditorManager::DrawWelcomeScreen() {
}
ImGui::SameLine();
if (ImGui::Button(ICON_MD_FOLDER_OPEN " Open Project", ImVec2(200, 40))) {
auto file_name = core::FileDialogWrapper::ShowOpenFileDialog();
auto file_name = util::FileDialogWrapper::ShowOpenFileDialog();
if (!file_name.empty()) {
status_ = OpenRomOrProject(file_name);
if (!status_.ok()) {

View File

@@ -5,7 +5,7 @@
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include "app/core/window.h"
#include "app/gfx/arena.h"
#include "app/gfx/bitmap.h"
@@ -549,7 +549,7 @@ absl::Status GraphicsEditor::DrawCgxImport() {
SameLine();
if (ImGui::Button("Open CGX")) {
auto filename = core::FileDialogWrapper::ShowOpenFileDialog();
auto filename = util::FileDialogWrapper::ShowOpenFileDialog();
cgx_file_name_ = filename;
cgx_file_path_ = std::filesystem::absolute(filename).string();
is_open_ = true;
@@ -578,7 +578,7 @@ absl::Status GraphicsEditor::DrawScrImport() {
InputText("##ScrFile", &scr_file_name_);
if (ImGui::Button("Open SCR")) {
auto filename = core::FileDialogWrapper::ShowOpenFileDialog();
auto filename = util::FileDialogWrapper::ShowOpenFileDialog();
scr_file_name_ = filename;
scr_file_path_ = std::filesystem::absolute(filename).string();
is_open_ = true;
@@ -610,7 +610,7 @@ absl::Status GraphicsEditor::DrawPaletteControls() {
SameLine();
if (ImGui::Button("Open COL")) {
auto filename = core::FileDialogWrapper::ShowOpenFileDialog();
auto filename = util::FileDialogWrapper::ShowOpenFileDialog();
col_file_name_ = filename;
col_file_path_ = std::filesystem::absolute(filename).string();
status_ = temp_rom_.LoadFromFile(col_file_path_,
@@ -659,7 +659,7 @@ absl::Status GraphicsEditor::DrawObjImport() {
SameLine();
if (ImGui::Button("Open OBJ")) {
auto filename = core::FileDialogWrapper::ShowOpenFileDialog();
auto filename = util::FileDialogWrapper::ShowOpenFileDialog();
obj_file_path_ = std::filesystem::absolute(filename).string();
status_ = temp_rom_.LoadFromFile(obj_file_path_);
is_open_ = true;
@@ -677,7 +677,7 @@ absl::Status GraphicsEditor::DrawTilemapImport() {
SameLine();
if (ImGui::Button("Open Tilemap")) {
auto filename = core::FileDialogWrapper::ShowOpenFileDialog();
auto filename = util::FileDialogWrapper::ShowOpenFileDialog();
tilemap_file_path_ = std::filesystem::absolute(filename).string();
status_ = tilemap_rom_.LoadFromFile(tilemap_file_path_);
status_ = tilemap_rom_.LoadFromFile(tilemap_file_path_);
@@ -700,7 +700,7 @@ absl::Status GraphicsEditor::DrawFileImport() {
SameLine();
if (ImGui::Button("Open BIN")) {
auto filename = core::FileDialogWrapper::ShowOpenFileDialog();
auto filename = util::FileDialogWrapper::ShowOpenFileDialog();
file_path_ = filename;
status_ = temp_rom_.LoadFromFile(file_path_);
is_open_ = true;

View File

@@ -7,7 +7,7 @@
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "app/gfx/performance_profiler.h"
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include "app/core/window.h"
#include "app/gfx/arena.h"
#include "app/gfx/atlas_renderer.h"
@@ -474,7 +474,7 @@ void ScreenEditor::DrawDungeonMapsEditor() {
}
void ScreenEditor::LoadBinaryGfx() {
std::string bin_file = core::FileDialogWrapper::ShowOpenFileDialog();
std::string bin_file = util::FileDialogWrapper::ShowOpenFileDialog();
if (!bin_file.empty()) {
std::ifstream file(bin_file, std::ios::binary);
if (file.is_open()) {

View File

@@ -7,7 +7,7 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "app/gfx/performance_profiler.h"
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include "app/core/window.h"
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_palette.h"
@@ -243,7 +243,7 @@ void MessageEditor::DrawExpandedMessageSettings() {
ImGui::Text("Expanded Messages");
static std::string expanded_message_path = "";
if (ImGui::Button("Load Expanded Message")) {
expanded_message_path = core::FileDialogWrapper::ShowOpenFileDialog();
expanded_message_path = util::FileDialogWrapper::ShowOpenFileDialog();
if (!expanded_message_path.empty()) {
if (!LoadExpandedMessages(expanded_message_path, parsed_messages_,
expanded_messages_,

View File

@@ -1,7 +1,7 @@
#include "sprite_editor.h"
#include "app/gfx/performance_profiler.h"
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include "app/editor/sprite/zsprite.h"
#include "app/gfx/arena.h"
#include "app/gui/icons.h"
@@ -254,7 +254,7 @@ void SpriteEditor::DrawCustomSpritesMetadata() {
// ZSprite Maker format open file dialog
if (ImGui::Button("Open ZSprite")) {
// Open ZSprite file
std::string file_path = core::FileDialogWrapper::ShowOpenFileDialog();
std::string file_path = util::FileDialogWrapper::ShowOpenFileDialog();
if (!file_path.empty()) {
zsprite::ZSprite zsprite;
status_ = zsprite.Load(file_path);

View File

@@ -11,11 +11,11 @@
#include "absl/debugging/failure_signal_handler.h"
#include "absl/debugging/symbolize.h"
#include "absl/status/status.h"
#include "app/core/platform/sdl_deleter.h"
#include "util/sdl_deleter.h"
#include "app/emu/snes.h"
#include "app/rom.h"
using yaze::core::SDL_Deleter;
using yaze::util::SDL_Deleter;
int main(int argc, char **argv) {
absl::InitializeSymbolizer(argv[0]);

View File

@@ -4,7 +4,7 @@
#include <fstream>
#include <vector>
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include "app/core/window.h"
#include "app/emu/cpu/internal/opcodes.h"
#include "app/gui/icons.h"
@@ -316,7 +316,7 @@ void Emulator::RenderNavBar() {
}
if (open_file) {
auto file_name = core::FileDialogWrapper::ShowOpenFileDialog();
auto file_name = util::FileDialogWrapper::ShowOpenFileDialog();
if (!file_name.empty()) {
std::ifstream file(file_name, std::ios::binary);
// Load the data directly into rom_data

View File

@@ -2,7 +2,7 @@
#include <SDL.h>
#include "app/core/platform/sdl_deleter.h"
#include "util/sdl_deleter.h"
namespace yaze {
namespace gfx {
@@ -58,7 +58,7 @@ SDL_Texture* Arena::AllocateTexture(SDL_Renderer* renderer, int width,
// Store in hash map with automatic cleanup
textures_[texture] =
std::unique_ptr<SDL_Texture, core::SDL_Texture_Deleter>(texture);
std::unique_ptr<SDL_Texture, util::SDL_Texture_Deleter>(texture);
return texture;
}
}
@@ -146,9 +146,9 @@ void Arena::UpdateTexture(SDL_Texture* texture, SDL_Surface* surface) {
// Convert surface to RGBA8888 format for texture compatibility
auto converted_surface =
std::unique_ptr<SDL_Surface, core::SDL_Surface_Deleter>(
std::unique_ptr<SDL_Surface, util::SDL_Surface_Deleter>(
SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA8888, 0),
core::SDL_Surface_Deleter());
util::SDL_Surface_Deleter());
if (!converted_surface) {
SDL_Log("SDL_ConvertSurfaceFormat failed: %s", SDL_GetError());
@@ -228,7 +228,7 @@ SDL_Surface* Arena::AllocateSurface(int width, int height, int depth,
// Store in hash map with automatic cleanup
surfaces_[surface] =
std::unique_ptr<SDL_Surface, core::SDL_Surface_Deleter>(surface);
std::unique_ptr<SDL_Surface, util::SDL_Surface_Deleter>(surface);
return surface;
}
}
@@ -278,7 +278,7 @@ SDL_Texture* Arena::CreateNewTexture(SDL_Renderer* renderer, int width, int heig
// Store in hash map with automatic cleanup
textures_[texture] =
std::unique_ptr<SDL_Texture, core::SDL_Texture_Deleter>(texture);
std::unique_ptr<SDL_Texture, util::SDL_Texture_Deleter>(texture);
return texture;
}
@@ -300,7 +300,7 @@ SDL_Surface* Arena::CreateNewSurface(int width, int height, int depth, int forma
// Store in hash map with automatic cleanup
surfaces_[surface] =
std::unique_ptr<SDL_Surface, core::SDL_Surface_Deleter>(surface);
std::unique_ptr<SDL_Surface, util::SDL_Surface_Deleter>(surface);
return surface;
}
@@ -327,9 +327,9 @@ void Arena::UpdateTextureRegion(SDL_Texture* texture, SDL_Surface* surface, SDL_
// Convert surface to RGBA8888 format for texture compatibility
auto converted_surface =
std::unique_ptr<SDL_Surface, core::SDL_Surface_Deleter>(
std::unique_ptr<SDL_Surface, util::SDL_Surface_Deleter>(
SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA8888, 0),
core::SDL_Surface_Deleter());
util::SDL_Surface_Deleter());
if (!converted_surface) {
return;

View File

@@ -8,7 +8,7 @@
#include <unordered_map>
#include <vector>
#include "app/core/platform/sdl_deleter.h"
#include "util/sdl_deleter.h"
#include "app/gfx/background_buffer.h"
namespace yaze {
@@ -177,11 +177,11 @@ class Arena {
std::array<gfx::Bitmap, 223> gfx_sheets_;
std::unordered_map<SDL_Texture*,
std::unique_ptr<SDL_Texture, core::SDL_Texture_Deleter>>
std::unique_ptr<SDL_Texture, util::SDL_Texture_Deleter>>
textures_;
std::unordered_map<SDL_Surface*,
std::unique_ptr<SDL_Surface, core::SDL_Surface_Deleter>>
std::unique_ptr<SDL_Surface, util::SDL_Surface_Deleter>>
surfaces_;
// Resource pooling for efficient memory management

View File

@@ -2,7 +2,7 @@
#include <algorithm>
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include "app/gui/theme_manager.h"
#include "app/gui/background_renderer.h"
#include "app/core/platform/font_loader.h"

View File

@@ -9,7 +9,7 @@
#include "absl/strings/str_format.h"
#include "absl/strings/str_split.h"
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include "app/gui/icons.h"
#include "app/gui/style.h" // For ColorsYaze function
#include "imgui/imgui.h"
@@ -466,7 +466,7 @@ void ThemeManager::ShowThemeSelector(bool* p_open) {
ImGui::SameLine();
if (ImGui::Button(absl::StrFormat("%s Load Custom Theme", ICON_MD_FOLDER_OPEN).c_str())) {
auto file_path = core::FileDialogWrapper::ShowOpenFileDialog();
auto file_path = util::FileDialogWrapper::ShowOpenFileDialog();
if (!file_path.empty()) {
auto status = LoadThemeFromFile(file_path);
if (!status.ok()) {
@@ -1007,7 +1007,7 @@ void ThemeManager::ShowSimpleThemeEditor(bool* p_open) {
ApplyClassicYazeTheme();
}
if (ImGui::MenuItem(absl::StrFormat("%s Load Theme", ICON_MD_FOLDER_OPEN).c_str())) {
auto file_path = core::FileDialogWrapper::ShowOpenFileDialog();
auto file_path = util::FileDialogWrapper::ShowOpenFileDialog();
if (!file_path.empty()) {
LoadThemeFromFile(file_path);
}
@@ -1023,7 +1023,7 @@ void ThemeManager::ShowSimpleThemeEditor(bool* p_open) {
}
} else {
// No existing file, prompt for new location
auto file_path = core::FileDialogWrapper::ShowSaveFileDialog(current_theme_.name, "theme");
auto file_path = util::FileDialogWrapper::ShowSaveFileDialog(current_theme_.name, "theme");
if (!file_path.empty()) {
auto status = SaveThemeToFile(current_theme_, file_path);
if (!status.ok()) {
@@ -1034,7 +1034,7 @@ void ThemeManager::ShowSimpleThemeEditor(bool* p_open) {
}
if (ImGui::MenuItem(absl::StrFormat("%s Save As...", ICON_MD_SAVE_AS).c_str())) {
// Save theme to new file
auto file_path = core::FileDialogWrapper::ShowSaveFileDialog(current_theme_.name, "theme");
auto file_path = util::FileDialogWrapper::ShowSaveFileDialog(current_theme_.name, "theme");
if (!file_path.empty()) {
auto status = SaveThemeToFile(current_theme_, file_path);
if (!status.ok()) {
@@ -1859,7 +1859,7 @@ void ThemeManager::ShowSimpleThemeEditor(bool* p_open) {
// Use save file dialog with proper defaults
std::string safe_name = edit_theme.name.empty() ? "custom_theme" : edit_theme.name;
auto file_path = core::FileDialogWrapper::ShowSaveFileDialog(safe_name, "theme");
auto file_path = util::FileDialogWrapper::ShowSaveFileDialog(safe_name, "theme");
if (!file_path.empty()) {
// Ensure .theme extension
@@ -1957,7 +1957,7 @@ std::vector<std::string> ThemeManager::DiscoverAvailableThemeFiles() const {
try {
// Use platform-specific file discovery instead of glob
#ifdef __APPLE__
auto files_in_folder = core::FileDialogWrapper::GetFilesInFolder(search_path);
auto files_in_folder = util::FileDialogWrapper::GetFilesInFolder(search_path);
for (const auto& file : files_in_folder) {
if (file.length() > 6 && file.substr(file.length() - 6) == ".theme") {
std::string full_path = search_path + file;

View File

@@ -1,4 +1,4 @@
#include "app/gui/widget_auto_register.h"
#include "app/gui/widgets/widget_auto_register.h"
#include <vector>

View File

@@ -1,10 +1,10 @@
#ifndef YAZE_APP_GUI_WIDGET_AUTO_REGISTER_H_
#define YAZE_APP_GUI_WIDGET_AUTO_REGISTER_H_
#ifndef YAZE_APP_GUI_WIDGETS_WIDGET_AUTO_REGISTER_H_
#define YAZE_APP_GUI_WIDGETS_WIDGET_AUTO_REGISTER_H_
#include <string>
#include "imgui/imgui.h"
#include "app/gui/widget_id_registry.h"
#include "app/gui/widgets/widget_id_registry.h"
#include "absl/strings/str_cat.h"
/**
@@ -260,5 +260,5 @@ inline void RegisterTable(const char* table_name, const std::string& description
} // namespace gui
} // namespace yaze
#endif // YAZE_APP_GUI_WIDGET_AUTO_REGISTER_H_
#endif // YAZE_APP_GUI_WIDGETS_WIDGET_AUTO_REGISTER_H_

View File

@@ -1,4 +1,4 @@
#include "widget_id_registry.h"
#include "app/gui/widgets/widget_id_registry.h"
#include <algorithm>
#include <chrono>

View File

@@ -1,5 +1,5 @@
#ifndef YAZE_APP_GUI_WIDGET_ID_REGISTRY_H_
#define YAZE_APP_GUI_WIDGET_ID_REGISTRY_H_
#ifndef YAZE_APP_GUI_WIDGETS_WIDGET_ID_REGISTRY_H_
#define YAZE_APP_GUI_WIDGETS_WIDGET_ID_REGISTRY_H_
#include <cstdint>
#include <optional>
@@ -173,4 +173,4 @@ class WidgetIdRegistry {
} // namespace gui
} // namespace yaze
#endif // YAZE_APP_GUI_WIDGET_ID_REGISTRY_H_
#endif // YAZE_APP_GUI_WIDGETS_WIDGET_ID_REGISTRY_H_

View File

@@ -14,7 +14,7 @@
#include "app/core/service/screenshot_utils.h"
#include "app/gui/widgets/widget_state_capture.h"
#include "app/core/features.h"
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include "app/gfx/arena.h"
#include "app/gui/icons.h"
#if defined(YAZE_ENABLE_IMGUI_TEST_ENGINE) && YAZE_ENABLE_IMGUI_TEST_ENGINE
@@ -1011,7 +1011,7 @@ void TestManager::DrawTestDashboard(bool* show_dashboard) {
: "Bespoke");
// Actually test the file dialog
auto result = core::FileDialogWrapper::ShowOpenFileDialog();
auto result = util::FileDialogWrapper::ShowOpenFileDialog();
if (!result.empty()) {
LOG_INFO("TestManager", "File dialog test successful: %s",
result.c_str());
@@ -1023,7 +1023,7 @@ void TestManager::DrawTestDashboard(bool* show_dashboard) {
ImGui::SameLine();
if (ImGui::Button("Test NFD Directly")) {
auto result = core::FileDialogWrapper::ShowOpenFileDialogNFD();
auto result = util::FileDialogWrapper::ShowOpenFileDialogNFD();
if (!result.empty()) {
LOG_INFO("TestManager", "NFD test successful: %s", result.c_str());
} else {
@@ -1035,7 +1035,7 @@ void TestManager::DrawTestDashboard(bool* show_dashboard) {
ImGui::SameLine();
if (ImGui::Button("Test Bespoke Directly")) {
auto result = core::FileDialogWrapper::ShowOpenFileDialogBespoke();
auto result = util::FileDialogWrapper::ShowOpenFileDialogBespoke();
if (!result.empty()) {
LOG_INFO("TestManager", "Bespoke test successful: %s",
result.c_str());
@@ -1187,13 +1187,13 @@ void TestManager::DrawTestDashboard(bool* show_dashboard) {
ImGui::Text("Test Both Implementations:");
if (ImGui::Button("Quick Test NFD")) {
auto result = core::FileDialogWrapper::ShowOpenFileDialogNFD();
auto result = util::FileDialogWrapper::ShowOpenFileDialogNFD();
LOG_INFO("TestManager", "NFD test result: %s",
result.empty() ? "Failed/Canceled" : result.c_str());
}
ImGui::SameLine();
if (ImGui::Button("Quick Test Bespoke")) {
auto result = core::FileDialogWrapper::ShowOpenFileDialogBespoke();
auto result = util::FileDialogWrapper::ShowOpenFileDialogBespoke();
LOG_INFO("TestManager", "Bespoke test result: %s",
result.empty() ? "Failed/Not Implemented" : result.c_str());
}

View File

@@ -3,7 +3,7 @@
#include <fstream>
#include <vector>
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include "app/core/window.h"
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_tile.h"
@@ -165,7 +165,7 @@ absl::Status LoadDungeonMapGfxFromBinary(Rom &rom,
gfx::Tilemap &tile16_blockset,
std::array<gfx::Bitmap, 4> &sheets,
std::vector<uint8_t> &gfx_bin_data) {
std::string bin_file = core::FileDialogWrapper::ShowOpenFileDialog();
std::string bin_file = util::FileDialogWrapper::ShowOpenFileDialog();
if (bin_file.empty()) {
return absl::InternalError("No file selected");
}