From 0e656f2a6a609b920693c1f7d049f851b4657fff Mon Sep 17 00:00:00 2001 From: Joshua Granick Date: Sat, 22 Aug 2015 14:32:35 -0700 Subject: [PATCH] Add lime.ui.FileDialog --- .gitmodules | 3 + lime/ui/FileDialog.hx | 80 ++++++++++++++++++++++++ lime/utils/Resource.hx | 31 +++++++++ project/Build.xml | 12 ++++ project/include/ui/FileDialog.h | 25 ++++++++ project/lib/nfd | 1 + project/src/ExternalInterface.cpp | 49 +++++++++++++++ project/src/ui/FileDialog.cpp | 100 ++++++++++++++++++++++++++++++ 8 files changed, 301 insertions(+) create mode 100644 lime/ui/FileDialog.hx create mode 100644 lime/utils/Resource.hx create mode 100644 project/include/ui/FileDialog.h create mode 160000 project/lib/nfd create mode 100644 project/src/ui/FileDialog.cpp diff --git a/.gitmodules b/.gitmodules index 2f0183a13..0db14a836 100644 --- a/.gitmodules +++ b/.gitmodules @@ -43,3 +43,6 @@ [submodule "project/lib/lzma"] path = project/lib/lzma url = https://github.com/native-toolkit/lzma +[submodule "project/lib/nfd"] + path = project/lib/nfd + url = https://github.com/native-toolkit/nfd diff --git a/lime/ui/FileDialog.hx b/lime/ui/FileDialog.hx new file mode 100644 index 000000000..bea075bb4 --- /dev/null +++ b/lime/ui/FileDialog.hx @@ -0,0 +1,80 @@ +package lime.ui; + + +import lime.system.System; +import lime.utils.Resource; + +#if sys +import sys.io.File; +#end + + +class FileDialog { + + + public static function openFile (filter = null, defaultPath:String = null):String { + + #if (cpp || neko || nodejs) + return lime_file_dialog_open_file (filter, defaultPath); + #else + return null; + #end + + } + + + public static function openFiles (filter = null, defaultPath:String = null):Array { + + #if (cpp || neko || nodejs) + return lime_file_dialog_open_files (filter, defaultPath); + #else + return []; + #end + + } + + + public static function saveFile (data:Resource, filter = null, defaultPath:String = null):String { + + var path = null; + + #if (cpp || neko || nodejs) + + path = lime_file_dialog_save_file (filter, defaultPath); + + if (path != null) { + + try { + + File.saveBytes (path, data); + + } catch (e:Dynamic) { + + path = null; + + } + + } + + #end + + return path; + + } + + + + + // Native Methods + + + + + #if (cpp || neko || nodejs) + private static var lime_file_dialog_open_file = System.load ("lime", "lime_file_dialog_open_file", 2); + private static var lime_file_dialog_open_files = System.load ("lime", "lime_file_dialog_open_files", 2); + private static var lime_file_dialog_save_file = System.load ("lime", "lime_file_dialog_save_file", 2); + #end + + +} \ No newline at end of file diff --git a/lime/utils/Resource.hx b/lime/utils/Resource.hx new file mode 100644 index 000000000..a38316053 --- /dev/null +++ b/lime/utils/Resource.hx @@ -0,0 +1,31 @@ +package lime.utils; + + +import haxe.io.Bytes; + + +abstract Resource(Bytes) from Bytes to Bytes { + + + public function new (size:Int = 0) { + + this = Bytes.alloc (size); + + } + + + @:from private static inline function __fromString (value:String):Resource { + + return Bytes.ofString (value); + + } + + + @:to private static inline function __toString (value:Resource):String { + + return (value:Bytes).toString (); + + } + + +} \ No newline at end of file diff --git a/project/Build.xml b/project/Build.xml index 40cf827b9..dff0c1c96 100644 --- a/project/Build.xml +++ b/project/Build.xml @@ -16,6 +16,7 @@ + @@ -112,6 +113,15 @@ +
+ + + + + + +
+
@@ -221,6 +231,7 @@ + @@ -245,6 +256,7 @@ + diff --git a/project/include/ui/FileDialog.h b/project/include/ui/FileDialog.h new file mode 100644 index 000000000..ea44b3aea --- /dev/null +++ b/project/include/ui/FileDialog.h @@ -0,0 +1,25 @@ +#ifndef LIME_UI_FILE_DIALOG_H +#define LIME_UI_FILE_DIALOG_H + + +#include + + +namespace lime { + + + class FileDialog { + + public: + + static const char* OpenFile (const char* filter = NULL, const char* defaultPath = NULL); + static void OpenFiles (QuickVec* files, const char* filter = NULL, const char* defaultPath = NULL); + static const char* SaveFile (const char* filter = NULL, const char* defaultPath = NULL); + + }; + + +} + + +#endif \ No newline at end of file diff --git a/project/lib/nfd b/project/lib/nfd new file mode 160000 index 000000000..d329ac023 --- /dev/null +++ b/project/lib/nfd @@ -0,0 +1 @@ +Subproject commit d329ac0237a6b4c10dc953d851b16d9a1f3d29d7 diff --git a/project/src/ExternalInterface.cpp b/project/src/ExternalInterface.cpp index 75da57232..ba415c3f5 100644 --- a/project/src/ExternalInterface.cpp +++ b/project/src/ExternalInterface.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -193,6 +194,51 @@ namespace lime { } + value lime_file_dialog_open_file (value filter, value defaultPath) { + + #ifdef LIME_NFD + const char* path = FileDialog::OpenFile (val_string (filter), val_string (defaultPath)); + if (path) return alloc_string (path); + #endif + + return alloc_null (); + + } + + + value lime_file_dialog_open_files (value filter, value defaultPath) { + + #ifdef LIME_NFD + QuickVec files; + + FileDialog::OpenFiles (&files, val_string (filter), val_string (defaultPath)); + value result = alloc_array (files.size ()); + + for (int i = 0; i < files.size (); i++) { + + val_array_set_i (result, i, alloc_string (files[i])); + + } + #else + value result = alloc_array (0); + #endif + + return result; + + } + + + value lime_file_dialog_save_file (value filter, value defaultPath) { + + #ifdef LIME_NFD + return alloc_string (FileDialog::SaveFile (val_string (filter), val_string (defaultPath))); + #else + return alloc_null (); + #endif + + } + + void lime_font_destroy (value handle) { #ifdef LIME_FREETYPE @@ -1238,6 +1284,9 @@ namespace lime { DEFINE_PRIM (lime_bytes_read_file, 1); DEFINE_PRIM (lime_clipboard_get_text, 0); DEFINE_PRIM (lime_clipboard_set_text, 1); + DEFINE_PRIM (lime_file_dialog_open_file, 2); + DEFINE_PRIM (lime_file_dialog_open_files, 2); + DEFINE_PRIM (lime_file_dialog_save_file, 2); DEFINE_PRIM (lime_font_get_ascender, 1); DEFINE_PRIM (lime_font_get_descender, 1); DEFINE_PRIM (lime_font_get_family_name, 1); diff --git a/project/src/ui/FileDialog.cpp b/project/src/ui/FileDialog.cpp new file mode 100644 index 000000000..f9cd4ecf7 --- /dev/null +++ b/project/src/ui/FileDialog.cpp @@ -0,0 +1,100 @@ +#include +#include + + +namespace lime { + + + const char* FileDialog::OpenFile (const char* filter, const char* defaultPath) { + + nfdchar_t *savePath = NULL; + nfdresult_t result = NFD_OpenDialog (filter, defaultPath, &savePath); + + switch (result) { + + case NFD_OKAY: + + return savePath; + break; + + case NFD_CANCEL: + + break; + + default: + + printf ("Error: %s\n", NFD_GetError ()); + break; + + } + + return savePath; + + } + + + void FileDialog::OpenFiles (QuickVec* files, const char* filter, const char* defaultPath) { + + nfdpathset_t pathSet; + nfdresult_t result = NFD_OpenDialogMultiple (filter, defaultPath, &pathSet); + + switch (result) { + + case NFD_OKAY: + { + printf("okay\n"); + printf("size: %d\n", NFD_PathSet_GetCount (&pathSet)); + for (int i = 0; i < NFD_PathSet_GetCount (&pathSet); i++) { + + printf ("%s\n", NFD_PathSet_GetPath (&pathSet, i)); + files->push_back (NFD_PathSet_GetPath (&pathSet, i)); + + } + + //NFD_PathSet_Free (&pathSet); + break; + } + + case NFD_CANCEL: + + break; + + default: + + printf ("Error: %s\n", NFD_GetError ()); + break; + + } + + } + + + const char* FileDialog::SaveFile (const char* filter, const char* defaultPath) { + + nfdchar_t *savePath = NULL; + nfdresult_t result = NFD_SaveDialog (filter, defaultPath, &savePath); + + switch (result) { + + case NFD_OKAY: + + return savePath; + break; + + case NFD_CANCEL: + + break; + + default: + + printf ("Error: %s\n", NFD_GetError ()); + break; + + } + + return savePath; + + } + + +} \ No newline at end of file