diff --git a/modules/juce_core/native/java/JuceAppActivity.java b/modules/juce_core/native/java/JuceAppActivity.java index 0485176f28..86b4fa85cc 100644 --- a/modules/juce_core/native/java/JuceAppActivity.java +++ b/modules/juce_core/native/java/JuceAppActivity.java @@ -490,13 +490,14 @@ public class JuceAppActivity extends Activity builder.create().show(); } - public final void showOkCancelBox (String title, String message, final long callback) + public final void showOkCancelBox (String title, String message, final long callback, + String okButtonText, String cancelButtonText) { AlertDialog.Builder builder = new AlertDialog.Builder (this); builder.setTitle (title) .setMessage (message) .setCancelable (true) - .setPositiveButton ("OK", new DialogInterface.OnClickListener() + .setPositiveButton (okButtonText.isEmpty() ? "OK" : okButtonText, new DialogInterface.OnClickListener() { public void onClick (DialogInterface dialog, int id) { @@ -504,7 +505,7 @@ public class JuceAppActivity extends Activity JuceAppActivity.this.alertDismissed (callback, 1); } }) - .setNegativeButton ("Cancel", new DialogInterface.OnClickListener() + .setNegativeButton (cancelButtonText.isEmpty() ? "Cancel" : cancelButtonText, new DialogInterface.OnClickListener() { public void onClick (DialogInterface dialog, int id) { diff --git a/modules/juce_core/native/juce_android_JNIHelpers.h b/modules/juce_core/native/juce_android_JNIHelpers.h index 872b3c3a91..dc36557667 100644 --- a/modules/juce_core/native/juce_android_JNIHelpers.h +++ b/modules/juce_core/native/juce_android_JNIHelpers.h @@ -276,7 +276,7 @@ extern AndroidSystem android; STATICMETHOD (createHTTPStream, "createHTTPStream", "(Ljava/lang/String;Z[BLjava/lang/String;I[ILjava/lang/StringBuffer;ILjava/lang/String;)L" JUCE_ANDROID_ACTIVITY_CLASSPATH "$HTTPStream;") \ METHOD (launchURL, "launchURL", "(Ljava/lang/String;)V") \ METHOD (showMessageBox, "showMessageBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \ - METHOD (showOkCancelBox, "showOkCancelBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \ + METHOD (showOkCancelBox, "showOkCancelBox", "(Ljava/lang/String;Ljava/lang/String;JLjava/lang/String;Ljava/lang/String;)V") \ METHOD (showYesNoCancelBox, "showYesNoCancelBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \ STATICMETHOD (getLocaleValue, "getLocaleValue", "(Z)Ljava/lang/String;") \ STATICMETHOD (getDocumentsFolder, "getDocumentsFolder", "()Ljava/lang/String;") \ diff --git a/modules/juce_gui_basics/native/juce_android_Windowing.cpp b/modules/juce_gui_basics/native/juce_android_Windowing.cpp index 39ee549ed3..9f1b8d4033 100644 --- a/modules/juce_gui_basics/native/juce_android_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_android_Windowing.cpp @@ -737,7 +737,8 @@ bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType jassert (callback != nullptr); // on android, all alerts must be non-modal!! android.activity.callVoidMethod (JuceAppActivity.showOkCancelBox, javaString (title).get(), - javaString (message).get(), (jlong) (pointer_sized_int) callback); + javaString (message).get(), (jlong) (pointer_sized_int) callback, + javaString (TRANS ("OK")).get(), javaString (TRANS ("Cancel")).get()); return false; } @@ -753,6 +754,19 @@ int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconTy return 0; } +int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType /*iconType*/, + const String& title, const String& message, + Component* /*associatedComponent*/, + ModalComponentManager::Callback* callback) +{ + jassert (callback != nullptr); // on android, all alerts must be non-modal!! + + android.activity.callVoidMethod (JuceAppActivity.showOkCancelBox, javaString (title).get(), + javaString (message).get(), (jlong) (pointer_sized_int) callback, + javaString (TRANS ("Yes")).get(), javaString (TRANS ("No")).get()); + return 0; +} + JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, alertDismissed, void, (JNIEnv* env, jobject /*activity*/, jlong callbackAsLong, jint result)) { diff --git a/modules/juce_gui_basics/native/juce_ios_Windowing.mm b/modules/juce_gui_basics/native/juce_ios_Windowing.mm index bcdac9ff8e..bc5d455c66 100644 --- a/modules/juce_gui_basics/native/juce_ios_Windowing.mm +++ b/modules/juce_gui_basics/native/juce_ios_Windowing.mm @@ -360,6 +360,20 @@ int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconTy return 0; } +int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType /*iconType*/, + const String& title, const String& message, + Component* /*associatedComponent*/, + ModalComponentManager::Callback* callback) +{ + ScopedPointer mb (new iOSMessageBox (title, message, @"No", @"Yes", nil, callback, callback != nullptr)); + + if (callback == nullptr) + return mb->getResult(); + + mb.release(); + return 0; +} + //============================================================================== bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray&, bool) { diff --git a/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp b/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp index 406e85173d..8ab561504e 100644 --- a/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp @@ -3958,6 +3958,15 @@ int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconTy associatedComponent, callback); } +int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent, + ModalComponentManager::Callback* callback) +{ + return AlertWindow::showOkCancelBox (iconType, title, message, TRANS ("Yes"), TRANS ("No"), + associatedComponent, callback); +} + //============================== X11 - MouseCursor ============================= void* CustomMouseCursorInfo::create() const diff --git a/modules/juce_gui_basics/native/juce_mac_Windowing.mm b/modules/juce_gui_basics/native/juce_mac_Windowing.mm index 802c5572b1..dd6c1c22e8 100644 --- a/modules/juce_gui_basics/native/juce_mac_Windowing.mm +++ b/modules/juce_gui_basics/native/juce_mac_Windowing.mm @@ -147,6 +147,15 @@ int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconTy "Yes", "Cancel", "No", callback != nullptr); } +int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* /*associatedComponent*/, + ModalComponentManager::Callback* callback) +{ + return OSXMessageBox::show (iconType, title, message, callback, + "Yes", "No", nullptr, callback != nullptr); +} + //============================================================================== static NSRect getDragRect (NSView* view, NSEvent* event) diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index 8fbdcf7de1..f454483b80 100644 --- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -3464,7 +3464,7 @@ public: int getResult() const { const int r = MessageBox (owner, message.toWideCharPointer(), title.toWideCharPointer(), flags); - return (r == IDYES || r == IDOK) ? 1 : (r == IDNO ? 2 : 0); + return (r == IDYES || r == IDOK) ? 1 : (r == IDNO && (flags & 1) != 0 ? 2 : 0); } void handleAsyncUpdate() override @@ -3550,6 +3550,20 @@ int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconTy return 0; } +int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent, + ModalComponentManager::Callback* callback) +{ + ScopedPointer mb (new WindowsMessageBox (iconType, title, message, associatedComponent, + MB_YESNO, callback, callback != nullptr)); + if (callback == nullptr) + return mb->getResult(); + + mb.release(); + return 0; +} + //============================================================================== bool MouseInputSource::SourceList::addSource() { diff --git a/modules/juce_gui_basics/windows/juce_NativeMessageBox.h b/modules/juce_gui_basics/windows/juce_NativeMessageBox.h index 4d535ff7cc..acaf7edc44 100644 --- a/modules/juce_gui_basics/windows/juce_NativeMessageBox.h +++ b/modules/juce_gui_basics/windows/juce_NativeMessageBox.h @@ -155,6 +155,48 @@ public: ModalComponentManager::Callback* callback); #endif + /** Shows a dialog box with three buttons. + + Ideal for yes/no boxes. + + The escape key can be used to trigger the no button. + + If the callback parameter is null, the box is shown modally, and the method will + block until the user has clicked the button (or pressed the escape or return keys). + If the callback parameter is non-null, the box will be displayed and placed into a + modal state, but this method will return immediately, and the callback will be invoked + later when the user dismisses the box. + + @param iconType the type of icon to show + @param title the headline to show at the top of the box + @param message a longer, more descriptive message to show underneath the title + @param associatedComponent if this is non-null, it specifies the component that the + alert window should be associated with. Depending on the look + and feel, this might be used for positioning of the alert window. + @param callback if this is non-null, the box will be launched asynchronously, + returning immediately, and the callback will receive a call to its + modalStateFinished() when the box is dismissed, with its parameter + being 1 if the "yes" button was pressed or 0 for the "no" button was + pressed. The callback object will be owned and deleted by the + system, so make sure that it works safely and doesn't keep any references + to objects that might be deleted before it gets called. + + @returns If the callback parameter has been set, this returns 0. Otherwise, it returns one + of the following values: + - 0 if 'no' was pressed + - 1 if 'yes' was pressed + */ + static int JUCE_CALLTYPE showYesNoBox (AlertWindow::AlertIconType iconType, + const String& title, + const String& message, + #if JUCE_MODAL_LOOPS_PERMITTED + Component* associatedComponent = nullptr, + ModalComponentManager::Callback* callback = nullptr); + #else + Component* associatedComponent, + ModalComponentManager::Callback* callback); + #endif + private: NativeMessageBox() JUCE_DELETED_FUNCTION; JUCE_DECLARE_NON_COPYABLE (NativeMessageBox)