From f7561ebb2a95607578e7f1cdf6823d0fedf08fb3 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Wed, 19 Jan 2022 07:48:25 +1100 Subject: [PATCH 1/5] Initial 'Load file' map support for Windows 'Load file' opens a file dialog allowing you to load maps from anywhere on disc --- src/Menus.c | 10 ++++------ src/Window_Android.c | 4 ++++ src/Window_Carbon.c | 4 ++++ src/Window_SDL.c | 4 ++++ src/Window_Web.c | 2 +- src/Window_Win.c | 29 ++++++++++++++++++++++++++++- src/Window_X11.c | 4 ++++ src/interop_cocoa.m | 4 ++++ src/interop_ios.m | 4 ++++ 9 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/Menus.c b/src/Menus.c index a8292e658..94957f3bc 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -384,7 +384,7 @@ static void ListScreen_ContextRecreated(void* screen) { ListScreen_UpdatePage(s); if (!s->UploadClick) return; - ButtonWidget_SetConst(&s->upload, "Upload", &s->font); + ButtonWidget_SetConst(&s->upload, Input_TouchMode ? "Upload" : "Load file...", &s->font); } static void ListScreen_Reload(struct ListScreen* s) { @@ -1764,14 +1764,12 @@ static void LoadLevelScreen_LoadEntries(struct ListScreen* s) { StringsBuffer_Sort(&s->entries); } -#ifdef CC_BUILD_WEB static void LoadLevelScreen_UploadCallback(const cc_string* path) { Map_LoadFrom(path); } static void LoadLevelScreen_UploadFunc(void* s, void* w) { - Window_OpenFileDialog(".cw", LoadLevelScreen_UploadCallback); + Platform_LogConst("UPLOAD"); + cc_result res = Window_OpenFileDialog(".cw", LoadLevelScreen_UploadCallback); + if (res) Logger_SimpleWarn(res, "showing open file dialog"); } -#else -#define LoadLevelScreen_UploadFunc NULL -#endif void LoadLevelScreen_Show(void) { struct ListScreen* s = &ListScreen; diff --git a/src/Window_Android.c b/src/Window_Android.c index 04b21f3d9..39b381c59 100644 --- a/src/Window_Android.c +++ b/src/Window_Android.c @@ -363,6 +363,10 @@ static void ShowDialogCore(const char* title, const char* msg) { (*env)->DeleteLocalRef(env, args[1].l); } +cc_result Window_OpenFileDialog(const char* filter, OpenFileDialogCallback callback) { + return ERR_NOT_SUPPORTED; +} + static struct Bitmap fb_bmp; void Window_AllocFramebuffer(struct Bitmap* bmp) { bmp->scan0 = (BitmapCol*)Mem_Alloc(bmp->width * bmp->height, 4, "window pixels"); diff --git a/src/Window_Carbon.c b/src/Window_Carbon.c index 2f1dbc439..3b766b919 100644 --- a/src/Window_Carbon.c +++ b/src/Window_Carbon.c @@ -607,6 +607,10 @@ static void ShowDialogCore(const char* title, const char* msg) { showingDialog = false; } +cc_result Window_OpenFileDialog(const char* filter, OpenFileDialogCallback callback) { + return ERR_NOT_SUPPORTED; +} + static CGrafPtr fb_port; static struct Bitmap fb_bmp; static CGColorSpaceRef colorSpace; diff --git a/src/Window_SDL.c b/src/Window_SDL.c index 720415ee8..0adf80cca 100644 --- a/src/Window_SDL.c +++ b/src/Window_SDL.c @@ -272,6 +272,10 @@ static void ShowDialogCore(const char* title, const char* msg) { SDL_ShowSimpleMessageBox(0, title, msg, win_handle); } +cc_result Window_OpenFileDialog(const char* filter, OpenFileDialogCallback callback) { + return ERR_NOT_SUPPORTED; +} + static SDL_Surface* surface; void Window_AllocFramebuffer(struct Bitmap* bmp) { surface = SDL_GetWindowSurface(win_handle); diff --git a/src/Window_Web.c b/src/Window_Web.c index 571268927..e2f8d160f 100644 --- a/src/Window_Web.c +++ b/src/Window_Web.c @@ -549,7 +549,7 @@ cc_result Window_OpenFileDialog(const char* filter, OpenFileDialogCallback callb uploadCallback = callback; /* Calls Window_OnFileUploaded on success */ interop_OpenFileDialog(filter); - return ERR_NOT_SUPPORTED; + return 0; } void Window_AllocFramebuffer(struct Bitmap* bmp) { } diff --git a/src/Window_Win.c b/src/Window_Win.c index b4c53b4a8..303d90b8f 100644 --- a/src/Window_Win.c +++ b/src/Window_Win.c @@ -22,6 +22,7 @@ /* Hence the actual minimum supported OS is Windows 2000. This just avoids redeclaring structs. */ #endif #include +#include /* https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-setpixelformat */ #define CC_WIN_STYLE WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN @@ -136,7 +137,8 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara case WM_MOUSEMOVE: /* Set before position change, in case mouse buttons changed when outside window */ - Input_SetNonRepeatable(KEY_LMOUSE, wParam & 0x01); + if (!(wParam & 0x01)) Input_SetReleased(KEY_LMOUSE); + //Input_SetNonRepeatable(KEY_LMOUSE, wParam & 0x01); Input_SetNonRepeatable(KEY_RMOUSE, wParam & 0x02); Input_SetNonRepeatable(KEY_MMOUSE, wParam & 0x10); /* TODO: do we need to set XBUTTON1/XBUTTON2 here */ @@ -535,6 +537,31 @@ static void ShowDialogCore(const char* title, const char* msg) { MessageBoxA(win_handle, msg, title, 0); } +cc_result Window_OpenFileDialog(const char* filter, OpenFileDialogCallback callback) { + cc_string path; char pathBuffer[MAX_PATH]; + WCHAR str[MAX_PATH] = { 0 }; + OPENFILENAMEW ofn = { 0 }; + int i; + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = win_handle; + ofn.lpstrFile = str; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFilter = L"All\0*.*\0CW files\0*.cw\0"; // TODO rethink + ofn.nFilterIndex = 1; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR; + + if (!GetOpenFileNameW(&ofn)) + return CommDlgExtendedError(); + String_InitArray(path, pathBuffer); + + for (i = 0; i < MAX_PATH && str[i]; i++) { + String_Append(&path, Convert_CodepointToCP437(str[i])); + } + callback(&path); + return 0; +} + static HDC draw_DC; static HBITMAP draw_DIB; void Window_AllocFramebuffer(struct Bitmap* bmp) { diff --git a/src/Window_X11.c b/src/Window_X11.c index 8e694d9e8..8c971f9b0 100644 --- a/src/Window_X11.c +++ b/src/Window_X11.c @@ -966,6 +966,10 @@ static void ShowDialogCore(const char* title, const char* msg) { XFlush(m.dpy); /* flush so window disappears immediately */ } +cc_result Window_OpenFileDialog(const char* filter, OpenFileDialogCallback callback) { + return ERR_NOT_SUPPORTED; +} + static GC fb_gc; static XImage* fb_image; static struct Bitmap fb_bmp; diff --git a/src/interop_cocoa.m b/src/interop_cocoa.m index 1895c9594..767ea53ea 100644 --- a/src/interop_cocoa.m +++ b/src/interop_cocoa.m @@ -507,6 +507,10 @@ void ShowDialogCore(const char* title, const char* msg) { CFRelease(msgCF); } +cc_result Window_OpenFileDialog(const char* filter, OpenFileDialogCallback callback) { + return ERR_NOT_SUPPORTED; +} + static struct Bitmap fb_bmp; void Window_AllocFramebuffer(struct Bitmap* bmp) { bmp->scan0 = (BitmapCol*)Mem_Alloc(bmp->width * bmp->height, 4, "window pixels"); diff --git a/src/interop_ios.m b/src/interop_ios.m index 4646c6351..279c571fb 100644 --- a/src/interop_ios.m +++ b/src/interop_ios.m @@ -260,6 +260,10 @@ void Window_LockLandscapeOrientation(cc_bool lock) { [UIViewController attemptRotationToDeviceOrientation]; } +cc_result Window_OpenFileDialog(const char* filter, OpenFileDialogCallback callback) { + return ERR_NOT_SUPPORTED; +} + /*#########################################################################################################################* *--------------------------------------------------------2D window--------------------------------------------------------* From 41226b6d6736531b11ece46e08d822ac62017697 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Wed, 19 Jan 2022 12:04:53 +1100 Subject: [PATCH 2/5] Improve filter on Windows and webclient --- src/Menus.c | 9 ++++++--- src/Window.h | 2 +- src/Window_Android.c | 2 +- src/Window_Carbon.c | 2 +- src/Window_SDL.c | 2 +- src/Window_Web.c | 15 ++++++++++++++- src/Window_Win.c | 36 ++++++++++++++++++++++++++++-------- src/Window_X11.c | 2 +- src/interop_cocoa.m | 2 +- src/interop_ios.m | 2 +- 10 files changed, 55 insertions(+), 19 deletions(-) diff --git a/src/Menus.c b/src/Menus.c index 94957f3bc..d9df8c84c 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -1587,7 +1587,8 @@ static void TexturePackScreen_UploadCallback(const cc_string* path) { } static void TexturePackScreen_UploadFunc(void* s, void* w) { - Window_OpenFileDialog(".zip", TexturePackScreen_UploadCallback); + static const char* const filters[] = { ".zip", NULL }; + Window_OpenFileDialog(filters, TexturePackScreen_UploadCallback); } #else #define TexturePackScreen_UploadFunc NULL @@ -1766,8 +1767,10 @@ static void LoadLevelScreen_LoadEntries(struct ListScreen* s) { static void LoadLevelScreen_UploadCallback(const cc_string* path) { Map_LoadFrom(path); } static void LoadLevelScreen_UploadFunc(void* s, void* w) { - Platform_LogConst("UPLOAD"); - cc_result res = Window_OpenFileDialog(".cw", LoadLevelScreen_UploadCallback); + static const char* const filters[] = { + ".cw", ".dat", ".lvl", ".mine", ".fcm", NULL + }; + cc_result res = Window_OpenFileDialog(filters, LoadLevelScreen_UploadCallback); if (res) Logger_SimpleWarn(res, "showing open file dialog"); } diff --git a/src/Window.h b/src/Window.h index c2a26c90a..8334c0f74 100644 --- a/src/Window.h +++ b/src/Window.h @@ -133,7 +133,7 @@ void Cursor_SetVisible(cc_bool visible); CC_API void Window_ShowDialog(const char* title, const char* msg); typedef void (*OpenFileDialogCallback)(const cc_string* path); /* Shows an 'load file' dialog window. */ -cc_result Window_OpenFileDialog(const char* filter, OpenFileDialogCallback callback); +cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback); /* Allocates a framebuffer that can be drawn/transferred to the window. */ /* NOTE: Do NOT free bmp->Scan0, use Window_FreeFramebuffer. */ diff --git a/src/Window_Android.c b/src/Window_Android.c index 39b381c59..db17cc176 100644 --- a/src/Window_Android.c +++ b/src/Window_Android.c @@ -363,7 +363,7 @@ static void ShowDialogCore(const char* title, const char* msg) { (*env)->DeleteLocalRef(env, args[1].l); } -cc_result Window_OpenFileDialog(const char* filter, OpenFileDialogCallback callback) { +cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) { return ERR_NOT_SUPPORTED; } diff --git a/src/Window_Carbon.c b/src/Window_Carbon.c index 3b766b919..af81cceee 100644 --- a/src/Window_Carbon.c +++ b/src/Window_Carbon.c @@ -607,7 +607,7 @@ static void ShowDialogCore(const char* title, const char* msg) { showingDialog = false; } -cc_result Window_OpenFileDialog(const char* filter, OpenFileDialogCallback callback) { +cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) { return ERR_NOT_SUPPORTED; } diff --git a/src/Window_SDL.c b/src/Window_SDL.c index 0adf80cca..3132c1275 100644 --- a/src/Window_SDL.c +++ b/src/Window_SDL.c @@ -272,7 +272,7 @@ static void ShowDialogCore(const char* title, const char* msg) { SDL_ShowSimpleMessageBox(0, title, msg, win_handle); } -cc_result Window_OpenFileDialog(const char* filter, OpenFileDialogCallback callback) { +cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) { return ERR_NOT_SUPPORTED; } diff --git a/src/Window_Web.c b/src/Window_Web.c index e2f8d160f..fbe3d01cc 100644 --- a/src/Window_Web.c +++ b/src/Window_Web.c @@ -545,7 +545,20 @@ EMSCRIPTEN_KEEPALIVE void Window_OnFileUploaded(const char* src) { } extern void interop_OpenFileDialog(const char* filter); -cc_result Window_OpenFileDialog(const char* filter, OpenFileDialogCallback callback) { +cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) { + cc_string path; char pathBuffer[NATIVE_STR_LEN]; + char filter[NATIVE_STR_LEN]; + int i; + + /* Filter tokens are , separated - e.g. ".cw,.dat */ + String_InitArray(path, pathBuffer); + for (i = 0; filters[i]; i++) + { + if (i) String_Append(&path, ','); + String_AppendConst(&path, filters[i]); + } + Platform_EncodeUtf8(filter, &path); + uploadCallback = callback; /* Calls Window_OnFileUploaded on success */ interop_OpenFileDialog(filter); diff --git a/src/Window_Win.c b/src/Window_Win.c index 303d90b8f..5ee81cd20 100644 --- a/src/Window_Win.c +++ b/src/Window_Win.c @@ -537,18 +537,38 @@ static void ShowDialogCore(const char* title, const char* msg) { MessageBoxA(win_handle, msg, title, 0); } -cc_result Window_OpenFileDialog(const char* filter, OpenFileDialogCallback callback) { - cc_string path; char pathBuffer[MAX_PATH]; +cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) { + cc_string path; char pathBuffer[NATIVE_STR_LEN]; WCHAR str[MAX_PATH] = { 0 }; OPENFILENAMEW ofn = { 0 }; + WCHAR filter[MAX_PATH]; int i; - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = win_handle; - ofn.lpstrFile = str; - ofn.nMaxFile = MAX_PATH; - ofn.lpstrFilter = L"All\0*.*\0CW files\0*.cw\0"; // TODO rethink - ofn.nFilterIndex = 1; + /* Filter tokens are \0 separated - e.g. "Maps (*.cw;*.dat)\0*.cw;*.dat\0 */ + String_InitArray(path, pathBuffer); + String_AppendConst(&path, "All supported files ("); + for (i = 0; filters[i]; i++) + { + if (i) String_Append(&path, ';'); + String_Format1(&path, "*%c", filters[i]); + } + String_Append(&path, ')'); + String_Append(&path, '\0'); + + for (i = 0; filters[i]; i++) + { + if (i) String_Append(&path, ';'); + String_Format1(&path, "*%c", filters[i]); + } + String_Append(&path, '\0'); + Platform_EncodeUtf16(filter, &path); + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = win_handle; + ofn.lpstrFile = str; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFilter = filter; + ofn.nFilterIndex = 1; ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR; if (!GetOpenFileNameW(&ofn)) diff --git a/src/Window_X11.c b/src/Window_X11.c index 8c971f9b0..af32b01fb 100644 --- a/src/Window_X11.c +++ b/src/Window_X11.c @@ -966,7 +966,7 @@ static void ShowDialogCore(const char* title, const char* msg) { XFlush(m.dpy); /* flush so window disappears immediately */ } -cc_result Window_OpenFileDialog(const char* filter, OpenFileDialogCallback callback) { +cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) { return ERR_NOT_SUPPORTED; } diff --git a/src/interop_cocoa.m b/src/interop_cocoa.m index 767ea53ea..7f710612b 100644 --- a/src/interop_cocoa.m +++ b/src/interop_cocoa.m @@ -507,7 +507,7 @@ void ShowDialogCore(const char* title, const char* msg) { CFRelease(msgCF); } -cc_result Window_OpenFileDialog(const char* filter, OpenFileDialogCallback callback) { +cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) { return ERR_NOT_SUPPORTED; } diff --git a/src/interop_ios.m b/src/interop_ios.m index 279c571fb..f14cea482 100644 --- a/src/interop_ios.m +++ b/src/interop_ios.m @@ -260,7 +260,7 @@ void Window_LockLandscapeOrientation(cc_bool lock) { [UIViewController attemptRotationToDeviceOrientation]; } -cc_result Window_OpenFileDialog(const char* filter, OpenFileDialogCallback callback) { +cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) { return ERR_NOT_SUPPORTED; } From a2e6cedf426f6b3675ca6995a9a511554594f477 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Wed, 19 Jan 2022 19:21:37 +1100 Subject: [PATCH 3/5] add support to cocoa backend (64bit macOS) --- src/interop_cocoa.m | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/interop_cocoa.m b/src/interop_cocoa.m index 7f710612b..cf340d4e2 100644 --- a/src/interop_cocoa.m +++ b/src/interop_cocoa.m @@ -114,7 +114,7 @@ void Clipboard_SetText(const cc_string* value) { NSString* str; Platform_EncodeUtf8(raw, value); - str = [[NSString alloc] initWithUTF8String:raw]; + str = [NSString stringWithUTF8String:raw]; pasteboard = [NSPasteboard generalPasteboard]; [pasteboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; @@ -299,7 +299,7 @@ void Window_SetTitle(const cc_string* title) { NSString* str; Platform_EncodeUtf8(raw, title); - str = [[NSString alloc] initWithUTF8String:raw]; + str = [NSString stringWithUTF8String:raw]; [winHandle setTitle:str]; [str release]; } @@ -508,7 +508,36 @@ void ShowDialogCore(const char* title, const char* msg) { } cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) { - return ERR_NOT_SUPPORTED; + NSOpenPanel* dlg = [NSOpenPanel openPanel]; + NSArray* files; + NSString* str; + const char* src; + int len, i; + + NSMutableArray* types = [NSMutableArray array]; + for (i = 0; filters[i]; i++) + { + NSString* filter = [NSString stringWithUTF8String:filters[i]]; + filter = [filter substringFromIndex:1]; + [types addObject:filter]; + } + + [dlg setCanChooseFiles: YES]; + [dlg setAllowedFileTypes:types]; + if ([dlg runModal] != NSOKButton) return 0; + + files = [dlg URLs]; + if ([files count] < 1) return 0; + + str = [[files objectAtIndex:0] path]; + src = [str UTF8String]; + len = String_Length(src); + + cc_string path; char pathBuffer[NATIVE_STR_LEN]; + String_InitArray(path, pathBuffer); + String_AppendUtf8(&path, src, len); + callback(&path); + return 0; } static struct Bitmap fb_bmp; From 8b88d3e575ca7210dc356f3be81ae6af16f9a9f3 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Wed, 19 Jan 2022 20:52:36 +1100 Subject: [PATCH 4/5] Use Zenity to add Linux support --- src/Window_X11.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/Window_X11.c b/src/Window_X11.c index af32b01fb..50b6963cc 100644 --- a/src/Window_X11.c +++ b/src/Window_X11.c @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef X_HAVE_UTF8_STRING #define CC_BUILD_XIM @@ -967,7 +968,43 @@ static void ShowDialogCore(const char* title, const char* msg) { } cc_result Window_OpenFileDialog(const char* const* filters, OpenFileDialogCallback callback) { - return ERR_NOT_SUPPORTED; + 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 ("); + + for (i = 0; filters[i]; i++) + { + if (i) String_Append(&path, ','); + String_Format1(&path, "*%c", filters[i]); + } + String_AppendConst(&path, ") |"); + + for (i = 0; filters[i]; i++) + { + String_Format1(&path, " *%c", filters[i]); + } + String_AppendConst(&path, "'"); + path.buffer[path.length] = '\0'; + + /* TODO this doesn't detect when Zenity doesn't exist */ + fp = popen(path.buffer, "r"); + if (!fp) return 0; + + /* result is normally just one string */ + while (fgets(result, sizeof(result), fp)) { } + len = String_Length(result); + + if (len) { + String_InitArray(path, pathBuffer); + String_AppendUtf8(&path, result, len); + callback(&path); + } + pclose(fp); + return 0; } static GC fb_gc; From fc0397a7ed406ac6b656903d2f3d2b95d862c373 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Thu, 20 Jan 2022 18:23:21 +1100 Subject: [PATCH 5/5] Move 'Load file' onto its own line --- src/EnvRenderer.c | 1 - src/Menus.c | 12 +++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/EnvRenderer.c b/src/EnvRenderer.c index 6d8e00fc4..2b4e972f0 100644 --- a/src/EnvRenderer.c +++ b/src/EnvRenderer.c @@ -21,7 +21,6 @@ cc_bool EnvRenderer_Legacy, EnvRenderer_Minimal; -#define ENV_SMALL_VERTICES 4096 static float CalcBlendFactor(float x) { /* return -0.05 + 0.22 * (Math_Log(x) * 0.25f); */ double blend = -0.13 + 0.28 * (Math_Log(x) * 0.25); diff --git a/src/Menus.c b/src/Menus.c index d9df8c84c..512668fff 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -201,16 +201,18 @@ static struct Widget* list_widgets[10] = { static void ListScreen_Layout(void* screen) { struct ListScreen* s = (struct ListScreen*)screen; int i; + for (i = 0; i < LIST_SCREEN_ITEMS; i++) { Widget_SetLocation(&s->btns[i], ANCHOR_CENTRE, ANCHOR_CENTRE, 0, (i - 2) * 50); } - if (s->UploadClick) { + if (s->UploadClick && Input_TouchMode) { Widget_SetLocation(&s->done, ANCHOR_CENTRE_MIN, ANCHOR_MAX, -150, 25); Widget_SetLocation(&s->upload, ANCHOR_CENTRE_MAX, ANCHOR_MAX, -150, 25); } else { - Menu_LayoutBack(&s->done); + Widget_SetLocation(&s->done, ANCHOR_CENTRE, ANCHOR_MAX, 0, 25); + Widget_SetLocation(&s->upload, ANCHOR_CENTRE, ANCHOR_MAX, 0, 70); } Widget_SetLocation(&s->left, ANCHOR_CENTRE, ANCHOR_CENTRE, -220, 0); @@ -384,7 +386,11 @@ static void ListScreen_ContextRecreated(void* screen) { ListScreen_UpdatePage(s); if (!s->UploadClick) return; - ButtonWidget_SetConst(&s->upload, Input_TouchMode ? "Upload" : "Load file...", &s->font); +#ifdef CC_BUILD_WEB + ButtonWidget_SetConst(&s->upload, "Upload", &s->font); +#else + ButtonWidget_SetConst(&s->upload, "Load file...", &s->font); +#endif } static void ListScreen_Reload(struct ListScreen* s) {