Add Native File Dialog support and enhance file dialog management
- Introduced a feature flag to toggle between Native File Dialog (NFD) and bespoke file dialog implementations. - Updated FileDialogWrapper to utilize the feature flag for opening files and folders, improving cross-platform compatibility. - Enhanced the UI to allow users to configure the file dialog mode, providing better user control over file handling. - Added new methods for testing both NFD and bespoke implementations directly from the UI, improving testing capabilities. - Updated test management to include options for enabling/disabling individual tests, enhancing flexibility in test execution.
This commit is contained in:
@@ -38,6 +38,9 @@ class FeatureFlags {
|
||||
// Log to the console.
|
||||
bool kLogToConsole = false;
|
||||
|
||||
// Use NFD (Native File Dialog) instead of bespoke file dialog implementation.
|
||||
bool kUseNativeFileDialog = true;
|
||||
|
||||
// Overworld flags
|
||||
struct Overworld {
|
||||
// Load and render overworld sprites to the screen. Unstable.
|
||||
@@ -100,6 +103,8 @@ class FeatureFlags {
|
||||
std::to_string(get().overworld.kLoadCustomOverworld) + "\n";
|
||||
result += "kApplyZSCustomOverworldASM: " +
|
||||
std::to_string(get().overworld.kApplyZSCustomOverworldASM) + "\n";
|
||||
result += "kUseNativeFileDialog: " +
|
||||
std::to_string(get().kUseNativeFileDialog) + "\n";
|
||||
return result;
|
||||
}
|
||||
};
|
||||
@@ -145,6 +150,7 @@ struct FlagsMenu {
|
||||
Checkbox("Enable Console Logging", &FeatureFlags::get().kLogToConsole);
|
||||
Checkbox("Log Instructions to Emulator Debugger",
|
||||
&FeatureFlags::get().kLogInstructions);
|
||||
Checkbox("Use Native File Dialog (NFD)", &FeatureFlags::get().kUseNativeFileDialog);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
|
||||
#include "app/core/features.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace core {
|
||||
|
||||
@@ -222,6 +224,15 @@ std::vector<std::string> FileDialogWrapper::GetFilesInFolder(
|
||||
#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() {
|
||||
#ifdef YAZE_ENABLE_NFD
|
||||
NFD_Init();
|
||||
nfdu8char_t *out_path = NULL;
|
||||
@@ -242,12 +253,27 @@ std::string FileDialogWrapper::ShowOpenFileDialog() {
|
||||
NFD_Quit();
|
||||
return "Error: NFD_OpenDialog";
|
||||
#else
|
||||
// NFD not available - return empty string or implement fallback
|
||||
return "";
|
||||
// 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 macOS implementation
|
||||
return ""; // Placeholder for bespoke implementation
|
||||
}
|
||||
|
||||
std::string FileDialogWrapper::ShowOpenFolderDialog() {
|
||||
// Use global feature flag to choose implementation
|
||||
if (FeatureFlags::get().kUseNativeFileDialog) {
|
||||
return ShowOpenFolderDialogNFD();
|
||||
} else {
|
||||
return ShowOpenFolderDialogBespoke();
|
||||
}
|
||||
}
|
||||
|
||||
std::string FileDialogWrapper::ShowOpenFolderDialogNFD() {
|
||||
#ifdef YAZE_ENABLE_NFD
|
||||
NFD_Init();
|
||||
nfdu8char_t *out_path = NULL;
|
||||
@@ -264,11 +290,17 @@ std::string FileDialogWrapper::ShowOpenFolderDialog() {
|
||||
NFD_Quit();
|
||||
return "Error: NFD_PickFolder";
|
||||
#else
|
||||
// NFD not available - return empty string or implement fallback
|
||||
return "";
|
||||
// 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;
|
||||
|
||||
@@ -11,15 +11,21 @@ class FileDialogWrapper {
|
||||
public:
|
||||
/**
|
||||
* @brief ShowOpenFileDialog opens a file dialog and returns the selected
|
||||
* filepath.
|
||||
* filepath. Uses global feature flag to choose implementation.
|
||||
*/
|
||||
static std::string ShowOpenFileDialog();
|
||||
|
||||
/**
|
||||
* @brief ShowOpenFolderDialog opens a file dialog and returns the selected
|
||||
* folder path.
|
||||
* folder path. Uses global feature flag to choose implementation.
|
||||
*/
|
||||
static std::string ShowOpenFolderDialog();
|
||||
|
||||
// Specific implementations for testing
|
||||
static std::string ShowOpenFileDialogNFD();
|
||||
static std::string ShowOpenFileDialogBespoke();
|
||||
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(
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "app/core/features.h"
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
/* Apple OSX and iOS (Darwin). */
|
||||
#include <Foundation/Foundation.h>
|
||||
@@ -65,13 +67,25 @@ std::string yaze::core::GetBundleResourcePath() {
|
||||
/* macOS */
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
|
||||
|
||||
std::string yaze::core::FileDialogWrapper::ShowOpenFileDialog() {
|
||||
std::string yaze::core::FileDialogWrapper::ShowOpenFileDialogBespoke() {
|
||||
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
|
||||
[openPanel setCanChooseFiles:YES];
|
||||
[openPanel setCanChooseDirectories:NO];
|
||||
[openPanel setAllowsMultipleSelection:NO];
|
||||
[openPanel setAllowedFileTypes:@[ @"sfc", @"smc", @"yaze" ]];
|
||||
|
||||
// Use modern allowedContentTypes for macOS 12.0+ compatibility
|
||||
if (@available(macOS 12.0, *)) {
|
||||
[openPanel setAllowedContentTypes:@[
|
||||
[UTType typeWithFilenameExtension:@"sfc"],
|
||||
[UTType typeWithFilenameExtension:@"smc"],
|
||||
[UTType typeWithFilenameExtension:@"yaze"]
|
||||
]];
|
||||
} else {
|
||||
// Fallback for older macOS versions
|
||||
[openPanel setAllowedFileTypes:@[ @"sfc", @"smc", @"yaze" ]];
|
||||
}
|
||||
|
||||
if ([openPanel runModal] == NSModalResponseOK) {
|
||||
NSURL* url = [[openPanel URLs] objectAtIndex:0];
|
||||
@@ -82,7 +96,47 @@ std::string yaze::core::FileDialogWrapper::ShowOpenFileDialog() {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Global feature flag-based dispatch methods
|
||||
std::string yaze::core::FileDialogWrapper::ShowOpenFileDialog() {
|
||||
if (FeatureFlags::get().kUseNativeFileDialog) {
|
||||
return ShowOpenFileDialogNFD();
|
||||
} else {
|
||||
return ShowOpenFileDialogBespoke();
|
||||
}
|
||||
}
|
||||
|
||||
std::string yaze::core::FileDialogWrapper::ShowOpenFolderDialog() {
|
||||
if (FeatureFlags::get().kUseNativeFileDialog) {
|
||||
return ShowOpenFolderDialogNFD();
|
||||
} else {
|
||||
return ShowOpenFolderDialogBespoke();
|
||||
}
|
||||
}
|
||||
|
||||
// NFD implementation for macOS (fallback to bespoke if NFD not available)
|
||||
std::string yaze::core::FileDialogWrapper::ShowOpenFileDialogNFD() {
|
||||
#ifdef YAZE_ENABLE_NFD
|
||||
// NFD implementation would go here when available
|
||||
// For now, fallback to bespoke implementation
|
||||
return ShowOpenFileDialogBespoke();
|
||||
#else
|
||||
// NFD not compiled in, use bespoke
|
||||
return ShowOpenFileDialogBespoke();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string yaze::core::FileDialogWrapper::ShowOpenFolderDialogNFD() {
|
||||
#ifdef YAZE_ENABLE_NFD
|
||||
// NFD folder implementation would go here when available
|
||||
// For now, fallback to bespoke implementation
|
||||
return ShowOpenFolderDialogBespoke();
|
||||
#else
|
||||
// NFD not compiled in, use bespoke
|
||||
return ShowOpenFolderDialogBespoke();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string yaze::core::FileDialogWrapper::ShowOpenFolderDialogBespoke() {
|
||||
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
|
||||
[openPanel setCanChooseFiles:NO];
|
||||
[openPanel setCanChooseDirectories:YES];
|
||||
|
||||
Reference in New Issue
Block a user