From 4e88a677d000b53d02a180f8dcecc5be4583eb9b Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 2 Dec 2022 16:52:47 -0500 Subject: [PATCH] GUI; mobile file dialog improvements --- .../org/tildearrow/furnace/MainActivity.java | 12 ++++++---- extern/igfd/ImGuiFileDialog.cpp | 8 ++++--- extern/igfd/ImGuiFileDialog.h | 1 + src/gui/fileDialog.cpp | 10 ++++---- src/gui/fileDialog.h | 4 +++- src/gui/gui.cpp | 23 +++++++++++++++++-- src/gui/gui.h | 11 +++++++-- src/gui/pattern.cpp | 12 +++++----- src/gui/settings.cpp | 1 + 9 files changed, 60 insertions(+), 22 deletions(-) diff --git a/android/app/src/main/java/org/tildearrow/furnace/MainActivity.java b/android/app/src/main/java/org/tildearrow/furnace/MainActivity.java index 0ac1448f..f1bc8bfd 100644 --- a/android/app/src/main/java/org/tildearrow/furnace/MainActivity.java +++ b/android/app/src/main/java/org/tildearrow/furnace/MainActivity.java @@ -1,25 +1,29 @@ package org.tildearrow.furnace; +import android.content.Context; import android.content.Intent; +import android.widget.Toast; import org.libsdl.app.SDLActivity; public class MainActivity extends SDLActivity { static final int TA_FILE_REQUEST=1000; - public boolean showFileDialog() { + public void showFileDialog() { Intent picker=new Intent(Intent.ACTION_GET_CONTENT); picker.setType("*/*"); picker=Intent.createChooser(picker,"test"); startActivityForResult(picker,TA_FILE_REQUEST); - - return true; } @Override protected void onActivityResult(int request, int result, Intent intent) { super.onActivityResult(request,result,intent); if (request==TA_FILE_REQUEST) { - // TODO: fire an event here + if (result==RESULT_OK) { + Context context=getApplicationContext(); + Toast toast=Toast.makeText(context,"Got a file",Toast.LENGTH_SHORT); + toast.show(); + } } } } diff --git a/extern/igfd/ImGuiFileDialog.cpp b/extern/igfd/ImGuiFileDialog.cpp index 3a30ac2b..5717785d 100644 --- a/extern/igfd/ImGuiFileDialog.cpp +++ b/extern/igfd/ImGuiFileDialog.cpp @@ -79,6 +79,8 @@ SOFTWARE. #include #include +#define DOUBLE_CLICKED ((singleClickSel && ImGui::IsMouseReleased(0)) || (!singleClickSel && ImGui::IsMouseDoubleClicked(0))) + #ifdef USE_THUMBNAILS #ifndef DONT_DEFINE_AGAIN__STB_IMAGE_IMPLEMENTATION #ifndef STB_IMAGE_IMPLEMENTATION @@ -3319,7 +3321,7 @@ namespace IGFD //// FILE DIALOG CONSTRUCTOR / DESTRUCTOR /////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// - IGFD::FileDialog::FileDialog() : BookMarkFeature(), KeyExplorerFeature(), ThumbnailFeature() {DpiScale=1.0f;} + IGFD::FileDialog::FileDialog() : BookMarkFeature(), KeyExplorerFeature(), ThumbnailFeature() {DpiScale=1.0f; singleClickSel=false;} IGFD::FileDialog::~FileDialog() = default; ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -3972,7 +3974,7 @@ namespace IGFD } else // no nav system => classic behavior { - if (ImGui::IsMouseDoubleClicked(0)) // 0 -> left mouse button double click + if (DOUBLE_CLICKED) // 0 -> left mouse button double click { isSelectingDir=true; fdi.puPathClicked = fdi.SelectDirectory(vInfos); @@ -3987,7 +3989,7 @@ namespace IGFD } else { - if (ImGui::IsMouseDoubleClicked(0)) { + if (DOUBLE_CLICKED) { fdi.SelectFileName(prFileDialogInternal, vInfos); prFileDialogInternal.puIsOk = true; return 2; diff --git a/extern/igfd/ImGuiFileDialog.h b/extern/igfd/ImGuiFileDialog.h index e5ba92d0..5b55a9ea 100644 --- a/extern/igfd/ImGuiFileDialog.h +++ b/extern/igfd/ImGuiFileDialog.h @@ -1142,6 +1142,7 @@ namespace IGFD public: bool puAnyWindowsHovered = false; // not remember why haha :) todo : to check if we can remove double DpiScale; + bool singleClickSel; public: static FileDialog* Instance() // Singleton for easier accces form anywhere but only one dialog at a time diff --git a/src/gui/fileDialog.cpp b/src/gui/fileDialog.cpp index 9b13fff0..3c913d74 100644 --- a/src/gui/fileDialog.cpp +++ b/src/gui/fileDialog.cpp @@ -116,7 +116,7 @@ bool FurnaceGUIFileDialog::openLoad(String header, std::vector filter, c } jclass class_=jniEnv->GetObjectClass(activity); - jmethodID showFileDialog=jniEnv->GetMethodID(class_,"showFileDialog","()B"); + jmethodID showFileDialog=jniEnv->GetMethodID(class_,"showFileDialog","()V"); if (showFileDialog==NULL) { logE("method showFileDialog not found!"); @@ -126,12 +126,12 @@ bool FurnaceGUIFileDialog::openLoad(String header, std::vector filter, c return false; } - jboolean mret=jniEnv->CallBooleanMethod(activity,showFileDialog); + jniEnv->CallVoidMethod(activity,showFileDialog); - if (!(bool)mret) { + /*if (!(bool)mret) { hasError=true; logW("could not open Android file picker..."); - } + }*/ jniEnv->DeleteLocalRef(class_); jniEnv->DeleteLocalRef(activity); @@ -142,6 +142,7 @@ bool FurnaceGUIFileDialog::openLoad(String header, std::vector filter, c #endif } else { hasError=false; + ImGuiFileDialog::Instance()->singleClickSel=singleClickSel; ImGuiFileDialog::Instance()->DpiScale=dpiScale; ImGuiFileDialog::Instance()->OpenModal("FileDialog",header,noSysFilter,path,allowMultiple?999:1,nullptr,0,clickCallback); } @@ -178,6 +179,7 @@ bool FurnaceGUIFileDialog::openSave(String header, std::vector filter, c #endif } else { hasError=false; + ImGuiFileDialog::Instance()->singleClickSel=false; ImGuiFileDialog::Instance()->DpiScale=dpiScale; ImGuiFileDialog::Instance()->OpenModal("FileDialog",header,noSysFilter,path,1,nullptr,ImGuiFileDialogFlags_ConfirmOverwrite); } diff --git a/src/gui/fileDialog.h b/src/gui/fileDialog.h index 0fbeeb46..a88c2873 100644 --- a/src/gui/fileDialog.h +++ b/src/gui/fileDialog.h @@ -47,6 +47,7 @@ class FurnaceGUIFileDialog { pfd::save_file* dialogS; #endif public: + bool singleClickSel; bool openLoad(String header, std::vector filter, const char* noSysFilter, String path, double dpiScale, FileDialogSelectCallback clickCallback=NULL, bool allowMultiple=false); bool openSave(String header, std::vector filter, const char* noSysFilter, String path, double dpiScale); bool accepted(); @@ -65,5 +66,6 @@ class FurnaceGUIFileDialog { jniEnv(NULL), #endif dialogO(NULL), - dialogS(NULL) {} + dialogS(NULL), + singleClickSel(false) {} }; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index eadac6d4..34a429e7 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -2630,10 +2630,12 @@ void FurnaceGUI::toggleMobileUI(bool enable, bool force) { if (mobileUI) { ImGui::GetIO().IniFilename=NULL; ImGui::GetIO().ConfigFlags|=ImGuiConfigFlags_InertialScrollEnable; + fileDialog->singleClickSel=true; } else { ImGui::GetIO().IniFilename=NULL; ImGui::LoadIniSettingsFromDisk(finalLayoutPath); ImGui::GetIO().ConfigFlags&=~ImGuiConfigFlags_InertialScrollEnable; + fileDialog->singleClickSel=false; } } } @@ -5225,7 +5227,7 @@ bool FurnaceGUI::init() { #endif // initialize SDL - SDL_Init(SDL_INIT_VIDEO); + SDL_Init(SDL_INIT_VIDEO|SDL_INIT_HAPTIC); const char* videoBackend=SDL_GetCurrentVideoDriver(); if (videoBackend!=NULL) { @@ -5448,6 +5450,17 @@ bool FurnaceGUI::init() { return curIns; }); + vibrator=SDL_HapticOpen(0); + if (vibrator==NULL) { + logD("could not open vibration device: %s",SDL_GetError()); + } else { + if (SDL_HapticRumbleInit(vibrator)==0) { + vibratorAvailable=true; + } else { + logD("vibration not available: %s",SDL_GetError()); + } + } + return true; } @@ -5578,6 +5591,10 @@ bool FurnaceGUI::finish() { SDL_DestroyRenderer(sdlRend); SDL_DestroyWindow(sdlWin); + if (vibrator) { + SDL_HapticClose(vibrator); + } + for (int i=0; istd.waveMacro.vScroll=-1; \ } -#define CHECK_LONG_HOLD (mobileUI && ImGui::GetIO().MouseDown[ImGuiMouseButton_Left] && ImGui::GetIO().MouseDownDuration[ImGuiMouseButton_Left]>longThreshold && !ImGui::IsInertialScroll()) +#define CHECK_LONG_HOLD (mobileUI && ImGui::GetIO().MouseDown[ImGuiMouseButton_Left] && ImGui::GetIO().MouseDownDuration[ImGuiMouseButton_Left]>=longThreshold && ImGui::GetIO().MouseDownDurationPrev[ImGuiMouseButton_Left]