Jelajahi Sumber

WIP: macOS port
- Added file/folder browse/save dialogs

Marko Pintera 8 tahun lalu
induk
melakukan
587bef9778

+ 3 - 1
Source/BansheeEditor/CMakeLists.txt

@@ -29,10 +29,12 @@ target_link_libraries(BansheeEditor PUBLIC BansheeUtility BansheeCore BansheeEng
 if(WIN32)
 	## OS libs
 	target_link_libraries(BansheeEditor PRIVATE Advapi32)
-else()
+elseif(LINUX)
 	## External lib: GTK+ 3.0
 	include_directories(${GTK3_INCLUDE_DIRS})
 	target_link_libraries(BansheeEditor PRIVATE ${GTK3_LIBRARIES})
+elseif(APPLE) # MacOS
+	target_link_framework(BansheeEditor AppKit)
 endif()
 
 # IDE specific

+ 6 - 4
Source/BansheeEditor/CMakeSources.cmake

@@ -246,19 +246,21 @@ set(BS_BANSHEEEDITOR_SRC_WIN32
 	"Win32/BsWin32BrowseDialogs.cpp"
 )
 
-set(BS_BANSHEEEDITOR_INC_LINUX
-)
-
 set(BS_BANSHEEEDITOR_SRC_LINUX
 	"Linux/BsLinuxBrowseDialogs.cpp"
 )
 
+set(BS_BANSHEEEDITOR_SRC_MACOS
+	"MacOS/BsMacOSBrowseDialogs.mm"
+	)
+
 if(WIN32)
 	list(APPEND BS_BANSHEEEDITOR_INC_PLATFORM ${BS_BANSHEEEDITOR_INC_WIN32})
 	list(APPEND BS_BANSHEEEDITOR_SRC_PLATFORM ${BS_BANSHEEEDITOR_SRC_WIN32})
 elseif(LINUX)
-	list(APPEND BS_BANSHEEEDITOR_INC_PLATFORM ${BS_BANSHEEEDITOR_INC_LINUX})
 	list(APPEND BS_BANSHEEEDITOR_SRC_PLATFORM ${BS_BANSHEEEDITOR_SRC_LINUX})
+elseif(APPLE)
+	list(APPEND BS_BANSHEEEDITOR_SRC_PLATFORM ${BS_BANSHEEEDITOR_SRC_MACOS})
 endif()
 
 source_group("Header Files\\Settings" FILES ${BS_BANSHEEEDITOR_INC_SETTINGS})

+ 116 - 0
Source/BansheeEditor/MacOS/BsMacOSBrowseDialogs.mm

@@ -0,0 +1,116 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#import <AppKit/AppKit.h>
+#include "Utility/BsEditorUtility.h"
+
+namespace bs
+{
+	bool EditorUtility::openBrowseDialog(FileDialogType type, const Path& defaultPath, const String& filterList,
+									Vector<Path>& paths)
+	{
+		Vector<String> extensions;
+		if(!filterList.empty())
+		{
+			extensions = StringUtil::split(filterList, ";");
+			for(auto& entry : extensions)
+			{
+				String output;
+				output.reserve(entry.size());
+
+				bool foundLeadingDot = false;
+				for(auto& curChar : entry)
+				{
+					// Skip leading dot
+					if(curChar == '.' && !foundLeadingDot)
+					{
+						foundLeadingDot = true;
+						continue;
+					}
+
+					// Skip wildcard character
+					if(curChar == '*')
+						continue;
+
+					output += curChar;
+				}
+
+				entry = output;
+			}
+		}
+
+		@autoreleasepool
+		{
+			bool save = ((UINT32) type & (UINT32) FileDialogType::Save) != 0;
+			String path = defaultPath.toString();
+
+			if (save)
+			{
+				bool file = ((UINT32) type & (UINT32) FileDialogType::OpenFile) != 0;
+				bool folder = ((UINT32) type & (UINT32) FileDialogType::OpenFolder) != 0;
+				bool multiselect = ((UINT32) type & (UINT32) FileDialogType::Multiselect) != 0;
+
+				NSOpenPanel* openDlg = [NSOpenPanel openPanel];
+
+				[openDlg setCanChooseFiles:file];
+				[openDlg setCanChooseDirectories:folder];
+				[openDlg setAllowsMultipleSelection:multiselect];
+
+				NSString* pathString = [[NSString stringWithUTF8String:path.c_str()] stringByResolvingSymlinksInPath];
+				[openDlg setDirectoryURL:[NSURL fileURLWithPath:pathString]];
+
+				NSMutableArray* fileTypes = [[NSMutableArray alloc] init];
+				for (UINT32 i = 0; i < (UINT32) extensions.size(); i++)
+				{
+					NSString* extensionString = [NSString stringWithUTF8String:extensions[i].c_str()];
+					[fileTypes addObject:extensionString];
+				}
+
+				[openDlg setAllowedFileTypes:fileTypes];
+
+				if ([openDlg runModal] == NSModalResponseOK)
+				{
+					NSArray* files = [openDlg URLs];
+
+					for (NSURL* file in files)
+					{
+						String fileStr = String([[file path] cStringUsingEncoding:kCFStringEncodingUTF8]);
+						paths.push_back(fileStr);
+					}
+
+					return true;
+				}
+			}
+			else
+			{
+				NSSavePanel* openDlg = [NSSavePanel savePanel];
+
+				[openDlg setCanCreateDirectories:YES];
+
+				NSString* pathString = [[NSString stringWithUTF8String:path.c_str()] stringByResolvingSymlinksInPath];
+				[openDlg setDirectoryURL:[NSURL fileURLWithPath:pathString]];
+
+				NSMutableArray* fileTypes = [[NSMutableArray alloc] init];
+				for(UINT32 i = 0; i < (UINT32)extensions.size(); i++)
+				{
+					NSString* extensionString = [NSString stringWithUTF8String:extensions[i].c_str()];
+					[fileTypes addObject:extensionString];
+				}
+
+				[openDlg setAllowedFileTypes:fileTypes];
+
+				if([openDlg runModal] == NSModalResponseOK)
+				{
+					NSURL* file = [openDlg URL];
+
+					String fileStr = String([[file path] cStringUsingEncoding:kCFStringEncodingUTF8]);
+					paths.push_back(fileStr);
+					return true;
+				}
+
+				return false;
+			}
+
+			return false;
+		}
+	}
+}

+ 2 - 1
Source/BansheeEditor/Utility/BsEditorUtility.h

@@ -78,7 +78,8 @@ namespace bs
 		 * @param[in]	type		Type of dialog to open.
 		 * @param[in]	defaultPath	Initial path the dialog will be set to once opened.
 		 * @param[in]	filterList	Semi-colon separated list of file names or types to display in the dialog,
-		 *							for example "exe;txt;png". Ignored if dialog is to display folders instead of files.
+		 *							for example "*.exe;*.txt;*.png". Ignored if dialog is to display folders instead of
+		 *							files.
 		 * @param[out]	paths		Output list of selected file or folder paths (if any).
 		 * @return					True if file was selected and false if selection was canceled.
 		 */

+ 1 - 1
Source/SBansheeEditor/Wrappers/GUI/BsScriptGUIEnumField.cpp

@@ -171,7 +171,7 @@ namespace bs
 		ScriptArray outStates = ScriptArray::create<bool>(numElements);
 
 		for (UINT32 i = 0; i < numElements; i++)
-			outStates.set(i, states[i]);
+			outStates.set(i, (bool)states[i]);
 
 		return outStates.getInternal();
 	}

+ 1 - 1
Source/SBansheeEditor/Wrappers/GUI/BsScriptGUIListBoxField.cpp

@@ -155,7 +155,7 @@ namespace bs
 		ScriptArray outStates = ScriptArray::create<bool>(numElements);
 
 		for (UINT32 i = 0; i < numElements; i++)
-			outStates.set(i, states[i]);
+			outStates.set(i, (bool)states[i]);
 
 		return outStates.getInternal();
 	}