mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-11 16:45:48 -04:00
Improve open file dialog API
Allows filetype description on Windows/Linux Avoids Menus.c needing to call internal webclient interop_SaveNode function For texture packs in webclient: Avoid saving into temp file, then reading into a copy in memory, then writing the copy into texpacks folder. Now just saves directly into texpacks folder
This commit is contained in:
parent
ff6f40d953
commit
5d8f9bf6da
23
src/Menus.c
23
src/Menus.c
@ -1572,15 +1572,11 @@ static void TexturePackScreen_LoadEntries(struct ListScreen* s) {
|
||||
StringsBuffer_Sort(&s->entries);
|
||||
}
|
||||
|
||||
extern void interop_UploadTexPack(const char* path);
|
||||
static void TexturePackScreen_UploadCallback(const cc_string* path) {
|
||||
#ifdef CC_BUILD_WEB
|
||||
char str[NATIVE_STR_LEN];
|
||||
cc_string relPath = *path;
|
||||
Platform_EncodeUtf8(str, path);
|
||||
Utils_UNSAFE_GetFilename(&relPath);
|
||||
|
||||
interop_UploadTexPack(str);
|
||||
ListScreen_Reload(&ListScreen);
|
||||
TexturePack_SetDefault(&relPath);
|
||||
#else
|
||||
@ -1590,8 +1586,15 @@ static void TexturePackScreen_UploadCallback(const cc_string* path) {
|
||||
}
|
||||
|
||||
static void TexturePackScreen_UploadFunc(void* s, void* w) {
|
||||
static const char* const filters[] = { ".zip", NULL };
|
||||
Window_OpenFileDialog(filters, TexturePackScreen_UploadCallback);
|
||||
static const char* const filters[] = {
|
||||
".zip", NULL
|
||||
};
|
||||
static struct OpenFileDialogArgs args = {
|
||||
"Texture packs", filters,
|
||||
TexturePackScreen_UploadCallback,
|
||||
OFD_UPLOAD_PERSIST, "texpacks"
|
||||
};
|
||||
Window_OpenFileDialog(&args);
|
||||
}
|
||||
|
||||
void TexturePackScreen_Show(void) {
|
||||
@ -1770,7 +1773,13 @@ static void LoadLevelScreen_UploadFunc(void* s, void* w) {
|
||||
static const char* const filters[] = {
|
||||
".cw", ".dat", ".lvl", ".mine", ".fcm", NULL
|
||||
};
|
||||
cc_result res = Window_OpenFileDialog(filters, LoadLevelScreen_UploadCallback);
|
||||
static struct OpenFileDialogArgs args = {
|
||||
"Classic map files", filters,
|
||||
LoadLevelScreen_UploadCallback,
|
||||
OFD_UPLOAD_DELETE, "tmp"
|
||||
};
|
||||
|
||||
cc_result res = Window_OpenFileDialog(&args);
|
||||
if (res) Logger_SimpleWarn(res, "showing open file dialog");
|
||||
}
|
||||
|
||||
|
15
src/Window.h
15
src/Window.h
@ -128,9 +128,20 @@ void Window_ProcessEvents(void);
|
||||
void Cursor_SetPosition(int x, int y);
|
||||
/* Shows a dialog box window. */
|
||||
CC_API void Window_ShowDialog(const char* title, const char* msg);
|
||||
|
||||
#define OFD_UPLOAD_DELETE 0 /* (webclient) Deletes the uploaded file after invoking callback function */
|
||||
#define OFD_UPLOAD_PERSIST 1 /* (webclient) Saves the uploded file into IndexedDB */
|
||||
typedef void (*OpenFileDialogCallback)(const cc_string* path);
|
||||
/* Shows an 'load file' dialog window. */
|
||||
cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback);
|
||||
|
||||
struct OpenFileDialogArgs {
|
||||
const char* description; /* Describes the types of files supported (e.g. "Texture packs") */
|
||||
const char* const* filters;
|
||||
OpenFileDialogCallback Callback;
|
||||
int uploadAction; /* Action webclient takes after invoking callback function */
|
||||
const char* uploadFolder; /* For webclient, folder to upload the file to */
|
||||
};
|
||||
/* Shows an 'load file' dialog window */
|
||||
cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args);
|
||||
|
||||
/* Allocates a framebuffer that can be drawn/transferred to the window. */
|
||||
/* NOTE: Do NOT free bmp->Scan0, use Window_FreeFramebuffer. */
|
||||
|
@ -359,7 +359,7 @@ static void ShowDialogCore(const char* title, const char* msg) {
|
||||
(*env)->DeleteLocalRef(env, args[1].l);
|
||||
}
|
||||
|
||||
cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) {
|
||||
cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
@ -591,7 +591,7 @@ static void ShowDialogCore(const char* title, const char* msg) {
|
||||
showingDialog = false;
|
||||
}
|
||||
|
||||
cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) {
|
||||
cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
@ -526,7 +526,7 @@ static void CallOpenFileCallback(const char* rawPath) {
|
||||
open_callback = NULL;
|
||||
}
|
||||
|
||||
cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) {
|
||||
cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args) {
|
||||
if (!open_panel) {
|
||||
open_panel = new BFilePanel(B_OPEN_PANEL);
|
||||
open_panel->SetRefFilter(new CC_BRefFilter());
|
||||
@ -534,8 +534,8 @@ cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallba
|
||||
// so this is technically a memory leak.. but meh
|
||||
}
|
||||
|
||||
open_callback = callback;
|
||||
open_filters = filters;
|
||||
open_callback = args->Callback;
|
||||
open_filters = args->filters;
|
||||
open_panel->Show();
|
||||
return 0;
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ static void ShowDialogCore(const char* title, const char* msg) {
|
||||
SDL_ShowSimpleMessageBox(0, title, msg, win_handle);
|
||||
}
|
||||
|
||||
cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) {
|
||||
cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
@ -544,24 +544,24 @@ EMSCRIPTEN_KEEPALIVE void Window_OnFileUploaded(const char* src) {
|
||||
uploadCallback = NULL;
|
||||
}
|
||||
|
||||
extern void interop_OpenFileDialog(const char* filter);
|
||||
cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) {
|
||||
cc_string path; char pathBuffer[NATIVE_STR_LEN];
|
||||
char filter[NATIVE_STR_LEN];
|
||||
extern void interop_OpenFileDialog(const char* filter, int action, const char* folder);
|
||||
cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args) {
|
||||
const char* const* filters = args->filters;
|
||||
cc_string filter; char filterBuffer[1024];
|
||||
int i;
|
||||
|
||||
/* Filter tokens are , separated - e.g. ".cw,.dat */
|
||||
String_InitArray(path, pathBuffer);
|
||||
String_InitArray_NT(filter, filterBuffer);
|
||||
for (i = 0; filters[i]; i++)
|
||||
{
|
||||
if (i) String_Append(&path, ',');
|
||||
String_AppendConst(&path, filters[i]);
|
||||
if (i) String_Append(&filter, ',');
|
||||
String_AppendConst(&filter, filters[i]);
|
||||
}
|
||||
Platform_EncodeUtf8(filter, &path);
|
||||
filter.buffer[filter.length] = '\0';
|
||||
|
||||
uploadCallback = callback;
|
||||
uploadCallback = args->Callback;
|
||||
/* Calls Window_OnFileUploaded on success */
|
||||
interop_OpenFileDialog(filter);
|
||||
interop_OpenFileDialog(filter.buffer, args->uploadAction, args->uploadFolder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -551,7 +551,8 @@ static void ShowDialogCore(const char* title, const char* msg) {
|
||||
MessageBoxA(win_handle, msg, title, 0);
|
||||
}
|
||||
|
||||
cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) {
|
||||
cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args) {
|
||||
const char* const* filters = args->filters;
|
||||
cc_string path; char pathBuffer[NATIVE_STR_LEN];
|
||||
WCHAR str[MAX_PATH] = { 0 };
|
||||
OPENFILENAMEW ofn = { 0 };
|
||||
@ -560,7 +561,7 @@ cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallba
|
||||
|
||||
/* Filter tokens are \0 separated - e.g. "Maps (*.cw;*.dat)\0*.cw;*.dat\0 */
|
||||
String_InitArray(path, pathBuffer);
|
||||
String_AppendConst(&path, "All supported files (");
|
||||
String_Format1(&path, "%c (", args->description);
|
||||
for (i = 0; filters[i]; i++)
|
||||
{
|
||||
if (i) String_Append(&path, ';');
|
||||
@ -592,7 +593,7 @@ cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallba
|
||||
for (i = 0; i < MAX_PATH && str[i]; i++) {
|
||||
String_Append(&path, Convert_CodepointToCP437(str[i]));
|
||||
}
|
||||
callback(&path);
|
||||
args->Callback(&path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -967,14 +967,15 @@ static void ShowDialogCore(const char* title, const char* msg) {
|
||||
XFlush(m.dpy); /* flush so window disappears immediately */
|
||||
}
|
||||
|
||||
cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) {
|
||||
cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args) {
|
||||
const char* const* filters = args->filters;
|
||||
cc_string path; char pathBuffer[1024];
|
||||
char result[4096] = { 0 };
|
||||
int len, i;
|
||||
FILE* fp;
|
||||
|
||||
String_InitArray_NT(path, pathBuffer);
|
||||
String_AppendConst(&path, "zenity --file-selection --file-filter='All supported files (");
|
||||
String_Format1(&path, "zenity --file-selection --file-filter='%c (", args->description);
|
||||
|
||||
for (i = 0; filters[i]; i++)
|
||||
{
|
||||
@ -1001,7 +1002,7 @@ cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallba
|
||||
if (len) {
|
||||
String_InitArray(path, pathBuffer);
|
||||
String_AppendUtf8(&path, result, len);
|
||||
callback(&path);
|
||||
args->Callback(&path);
|
||||
}
|
||||
pclose(fp);
|
||||
return 0;
|
||||
|
@ -515,7 +515,8 @@ void ShowDialogCore(const char* title, const char* msg) {
|
||||
CFRelease(msgCF);
|
||||
}
|
||||
|
||||
cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) {
|
||||
cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args) {
|
||||
const char* const* filters = args->filters;
|
||||
NSOpenPanel* dlg = [NSOpenPanel openPanel];
|
||||
NSArray* files;
|
||||
NSString* str;
|
||||
@ -547,7 +548,7 @@ cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallba
|
||||
cc_string path; char pathBuffer[NATIVE_STR_LEN];
|
||||
String_InitArray(path, pathBuffer);
|
||||
String_AppendUtf8(&path, src, len);
|
||||
callback(&path);
|
||||
args->Callback(&path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -478,8 +478,8 @@ void Window_LockLandscapeOrientation(cc_bool lock) {
|
||||
[UIViewController attemptRotationToDeviceOrientation];
|
||||
}
|
||||
|
||||
cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) {
|
||||
NSArray<NSString*>* types = @[ @"public.png" ]; // TODO fill in
|
||||
cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args) {
|
||||
NSArray<NSString*>* types = @[ @"public.png" ]; // TODO fill in with args->filters
|
||||
|
||||
UIDocumentPickerViewController* dlg;
|
||||
dlg = [UIDocumentPickerViewController alloc];
|
||||
|
@ -107,14 +107,6 @@ mergeInto(LibraryManager.library, {
|
||||
}
|
||||
},
|
||||
interop_DownloadMap__deps: ['interop_SaveBlob'],
|
||||
interop_UploadTexPack: function(path) {
|
||||
// Move from temp into texpacks folder
|
||||
// TODO: This is pretty awful and should be rewritten
|
||||
var name = UTF8ToString(path);
|
||||
var data = CCFS.readFile(name);
|
||||
CCFS.writeFile('texpacks/' + name.substring(1), data);
|
||||
_interop_SaveNode('texpacks/' + name.substring(1));
|
||||
},
|
||||
|
||||
|
||||
//########################################################################################################################
|
||||
@ -835,8 +827,10 @@ mergeInto(LibraryManager.library, {
|
||||
window.cc_divElem = null;
|
||||
window.cc_inputElem = null;
|
||||
},
|
||||
interop_OpenFileDialog: function(filter) {
|
||||
interop_OpenFileDialog: function(filter, action, folder) {
|
||||
var elem = window.cc_uploadElem;
|
||||
var root = UTF8ToString(folder);
|
||||
|
||||
if (!elem) {
|
||||
elem = document.createElement('input');
|
||||
elem.setAttribute('type', 'file');
|
||||
@ -852,9 +846,12 @@ mergeInto(LibraryManager.library, {
|
||||
|
||||
reader.onload = function(e) {
|
||||
var data = new Uint8Array(e.target.result);
|
||||
CCFS.writeFile('/' + name, data);
|
||||
ccall('Window_OnFileUploaded', 'void', ['string'], ['/' + name]);
|
||||
CCFS.unlink('/' + name);
|
||||
var path = root + '/' + name;
|
||||
CCFS.writeFile(path, data);
|
||||
ccall('Window_OnFileUploaded', 'void', ['string'], [path]);
|
||||
|
||||
if (action == 0) CCFS.unlink(path); // OFD_UPLOAD_DELETE
|
||||
if (action == 1) _interop_SaveNode(path); // OFD_UPLOAD_PERSIST
|
||||
};
|
||||
reader.readAsArrayBuffer(files[i]);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user