diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8bf25992..1ef3b180 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,6 +34,8 @@ foreach (FILE ${YAZE_RESOURCE_FILES}) ) endforeach() +add_subdirectory(lib/nativefiledialog-extended) + if (YAZE_BUILD_APP) include(app/app.cmake) endif() diff --git a/src/app/app.cmake b/src/app/app.cmake index b93f3aa7..3d9e3fb7 100644 --- a/src/app/app.cmake +++ b/src/app/app.cmake @@ -48,6 +48,11 @@ target_include_directories( ${PROJECT_BINARY_DIR} ) +target_link_libraries( + yaze PRIVATE + nfd +) + target_link_libraries( yaze PUBLIC asar-static diff --git a/src/app/core/controller.cc b/src/app/core/controller.cc index e3fb8132..1280ab1c 100644 --- a/src/app/core/controller.cc +++ b/src/app/core/controller.cc @@ -10,7 +10,7 @@ #include "app/core/platform/font_loader.h" #include "app/editor/editor_manager.h" #include "app/gui/style.h" -#include "core/utils/file_util.h" +#include "app/core/platform/file_dialog.h" #include "imgui/backends/imgui_impl_sdl2.h" #include "imgui/backends/imgui_impl_sdlrenderer2.h" #include "imgui/imgui.h" diff --git a/src/app/core/controller.h b/src/app/core/controller.h index 41f22106..21602eb3 100644 --- a/src/app/core/controller.h +++ b/src/app/core/controller.h @@ -7,7 +7,7 @@ #include "absl/status/status.h" #include "app/core/platform/renderer.h" -#include "app/core/utils/file_util.h" +#include "app/core/platform/file_dialog.h" #include "app/editor/editor.h" #include "app/editor/editor_manager.h" #include "imgui/backends/imgui_impl_sdl2.h" diff --git a/src/app/core/core.cmake b/src/app/core/core.cmake index ebb8bcc2..ba1b4140 100644 --- a/src/app/core/core.cmake +++ b/src/app/core/core.cmake @@ -4,7 +4,6 @@ set( app/core/controller.cc app/emu/emulator.cc app/core/project.cc - app/core/utils/file_util.cc ) if (WIN32 OR MINGW OR UNIX AND NOT APPLE) @@ -17,12 +16,12 @@ 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 app/core/platform/font_loader.mm app/core/platform/clipboard.mm - app/core/platform/file_path.mm ) find_library(COCOA_LIBRARY Cocoa) diff --git a/src/app/core/platform/file_dialog.cc b/src/app/core/platform/file_dialog.cc index 6b552e71..41baaa84 100644 --- a/src/app/core/platform/file_dialog.cc +++ b/src/app/core/platform/file_dialog.cc @@ -4,11 +4,95 @@ // Include Windows-specific headers #include #include -#endif // _WIN32 +#else // Linux and MacOS +#include +#include +#endif + +#include +#include 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; + Platform platform; +#if defined(_WIN32) + platform = Platform::kWindows; +#elif defined(__APPLE__) + platform = Platform::kMacOS; +#else + platform = Platform::kLinux; +#endif + std::string filepath = GetConfigDirectory(platform) + "/" + 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, + Platform platform) { + std::string filepath = GetConfigDirectory(platform) + "/" + filename; + std::ofstream file(filepath); + if (file.is_open()) { + file << contents; + file.close(); + } +} + +std::string GetConfigDirectory(Platform platform) { + std::string config_directory = ".yaze"; + switch (platform) { + case Platform::kWindows: + config_directory = "~/AppData/Roaming/yaze"; + break; + case Platform::kMacOS: + case Platform::kLinux: + config_directory = "~/.config/yaze"; + break; + default: + break; + } + return config_directory; +} + #ifdef _WIN32 std::string FileDialogWrapper::ShowOpenFileDialog() { @@ -119,8 +203,27 @@ std::vector FileDialogWrapper::GetFilesInFolder( #elif defined(__linux__) +#include + std::string FileDialogWrapper::ShowOpenFileDialog() { - return "Linux: Open file dialog"; + NFD_Init(); + nfdu8char_t *out_path = NULL; + nfdu8filter_item_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_Free(out_path); + NFD_Quit(); + return file_path_linux; + } else if (result == NFD_CANCEL) { + NFD_Quit(); + return ""; + } + NFD_Quit(); + return "Error: NFD_OpenDialog"; } std::string FileDialogWrapper::ShowOpenFolderDialog() { diff --git a/src/app/core/platform/file_dialog.h b/src/app/core/platform/file_dialog.h index 3e405aa6..d9c43738 100644 --- a/src/app/core/platform/file_dialog.h +++ b/src/app/core/platform/file_dialog.h @@ -21,11 +21,28 @@ class FileDialogWrapper { */ static std::string ShowOpenFolderDialog(); static std::vector GetSubdirectoriesInFolder( - const std::string& folder_path); + const std::string &folder_path); static std::vector GetFilesInFolder( - const std::string& folder_path); + 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(Platform platform); + +void SaveFile(const std::string &filename, const std::string &data, + Platform platform); + } // namespace core } // namespace yaze diff --git a/src/app/core/platform/file_dialog.mm b/src/app/core/platform/file_dialog.mm index 3709b44f..ea64973e 100644 --- a/src/app/core/platform/file_dialog.mm +++ b/src/app/core/platform/file_dialog.mm @@ -1,11 +1,12 @@ #include "app/core/platform/file_dialog.h" +#include #include #include -#include "imgui/imgui.h" #if defined(__APPLE__) && defined(__MACH__) /* Apple OSX and iOS (Darwin). */ +#include #include #import @@ -53,6 +54,13 @@ std::vector yaze::core::FileDialogWrapper::GetSubdirectoriesInFolde return {}; } +std::string yaze::core::GetBundleResourcePath() { + NSBundle* bundle = [NSBundle mainBundle]; + NSString* resourceDirectoryPath = [bundle bundlePath]; + NSString* path = [resourceDirectoryPath stringByAppendingString:@"/"]; + return [path UTF8String]; +} + #elif TARGET_OS_MAC == 1 /* macOS */ @@ -125,6 +133,14 @@ std::vector yaze::core::FileDialogWrapper::GetSubdirectoriesInFolde } return subdirectories; } + +std::string yaze::core::GetBundleResourcePath() { + NSBundle* bundle = [NSBundle mainBundle]; + NSString* resourceDirectoryPath = [bundle bundlePath]; + NSString* path = [resourceDirectoryPath stringByAppendingString:@"/"]; + return [path UTF8String]; +} + #else // Unsupported platform #endif // TARGET_OS_MAC diff --git a/src/app/core/platform/file_path.h b/src/app/core/platform/file_path.h deleted file mode 100644 index b5bbf87d..00000000 --- a/src/app/core/platform/file_path.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef YAZE_APP_CORE_PLATFORM_FILE_PATH_H -#define YAZE_APP_CORE_PLATFORM_FILE_PATH_H - -#include - -namespace yaze { -namespace core { - -/** - * @brief GetBundleResourcePath returns the path to the bundle resource - * directory. Specific to MacOS. - */ -std::string GetBundleResourcePath(); - -} // namespace core -} // namespace yaze - -#endif // YAZE_APP_CORE_PLATFORM_FILE_PATH_H diff --git a/src/app/core/platform/file_path.mm b/src/app/core/platform/file_path.mm deleted file mode 100644 index 0f3dc248..00000000 --- a/src/app/core/platform/file_path.mm +++ /dev/null @@ -1,26 +0,0 @@ -#include "file_path.h" - -#include -#include - -#if defined(__APPLE__) && defined(__MACH__) -#include -#include - -#if TARGET_IPHONE_SIMULATOR == 1 || TARGET_OS_IPHONE == 1 -std::string yaze::core::GetBundleResourcePath() { - NSBundle* bundle = [NSBundle mainBundle]; - NSString* resourceDirectoryPath = [bundle bundlePath]; - NSString* path = [resourceDirectoryPath stringByAppendingString:@"/"]; - return [path UTF8String]; -} -#elif TARGET_OS_MAC == 1 -std::string yaze::core::GetBundleResourcePath() { - NSBundle* bundle = [NSBundle mainBundle]; - NSString* resourceDirectoryPath = [bundle bundlePath]; - NSString* path = [resourceDirectoryPath stringByAppendingString:@"/"]; - return [path UTF8String]; -} - -#endif -#endif diff --git a/src/app/core/platform/font_loader.cc b/src/app/core/platform/font_loader.cc index 1ff30a64..306a53c9 100644 --- a/src/app/core/platform/font_loader.cc +++ b/src/app/core/platform/font_loader.cc @@ -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_path.h" +#include "app/core/platform/file_dialog.h" #include "app/gui/icons.h" #include "imgui/imgui.h" diff --git a/src/app/core/project.h b/src/app/core/project.h index b12cc3a7..31bc0265 100644 --- a/src/app/core/project.h +++ b/src/app/core/project.h @@ -8,7 +8,7 @@ #include "absl/status/status.h" #include "app/core/common.h" -#include "app/core/utils/file_util.h" +#include "app/core/platform/file_dialog.h" namespace yaze { diff --git a/src/app/core/utils/file_util.cc b/src/app/core/utils/file_util.cc deleted file mode 100644 index 6f2be10e..00000000 --- a/src/app/core/utils/file_util.cc +++ /dev/null @@ -1,95 +0,0 @@ -#include "file_util.h" - -#if defined(_WIN32) -#include -#else -#include -#include -#endif - -#include -#include - -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; - Platform platform; -#if defined(_WIN32) - platform = Platform::kWindows; -#elif defined(__APPLE__) - platform = Platform::kMacOS; -#else - platform = Platform::kLinux; -#endif - std::string filepath = GetConfigDirectory(platform) + "/" + 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, - Platform platform) { - std::string filepath = GetConfigDirectory(platform) + "/" + filename; - std::ofstream file(filepath); - if (file.is_open()) { - file << contents; - file.close(); - } -} - -std::string GetConfigDirectory(Platform platform) { - std::string config_directory = ".yaze"; - switch (platform) { - case Platform::kWindows: - config_directory = "~/AppData/Roaming/yaze"; - break; - case Platform::kMacOS: - case Platform::kLinux: - config_directory = "~/.config/yaze"; - break; - default: - break; - } - return config_directory; -} - -} // namespace core -} // namespace yaze diff --git a/src/app/core/utils/file_util.h b/src/app/core/utils/file_util.h deleted file mode 100644 index be446313..00000000 --- a/src/app/core/utils/file_util.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef YAZE_APP_CORE_UTILS_FILE_UTIL_H -#define YAZE_APP_CORE_UTILS_FILE_UTIL_H - -#include - -namespace yaze { -namespace core { - -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(Platform platform); - -void SaveFile(const std::string &filename, const std::string &data, - Platform platform); - -} // namespace core -} // namespace yaze - -#endif // YAZE_APP_CORE_UTILS_FILE_UTIL_H diff --git a/src/app/gui/style.cc b/src/app/gui/style.cc index a63860b1..e1459142 100644 --- a/src/app/gui/style.cc +++ b/src/app/gui/style.cc @@ -1,6 +1,6 @@ #include "style.h" -#include "app/core/utils/file_util.h" +#include "app/core/platform/file_dialog.h" #include "gui/color.h" #include "imgui/imgui.h" #include "imgui/imgui_internal.h" diff --git a/src/app/gui/zeml.cc b/src/app/gui/zeml.cc index a83210a4..6550fed0 100644 --- a/src/app/gui/zeml.cc +++ b/src/app/gui/zeml.cc @@ -9,7 +9,7 @@ #include #include -#include "app/core/platform/file_path.h" +#include "app/core/platform/file_dialog.h" #include "app/gui/canvas.h" #include "app/gui/input.h" #include "imgui/imgui.h" diff --git a/src/cli/z3ed.cmake b/src/cli/z3ed.cmake index 592aa217..51e6aa5f 100644 --- a/src/cli/z3ed.cmake +++ b/src/cli/z3ed.cmake @@ -21,8 +21,7 @@ add_executable( app/rom.cc app/core/common.cc app/core/project.cc - app/core/platform/file_path.mm - app/core/utils/file_util.cc + app/core/platform/file_dialog.mm ${YAZE_APP_EMU_SRC} ${YAZE_APP_GFX_SRC} ${YAZE_APP_ZELDA3_SRC}