1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

ScopedMessageBox: Replace old AlertWindow uses with new API

This commit is contained in:
reuk 2023-02-22 20:54:45 +00:00
parent 79ed81c24a
commit 39a731de46
No known key found for this signature in database
GPG key ID: FCB43929F012EE5C
55 changed files with 893 additions and 677 deletions

View file

@ -596,13 +596,17 @@ private:
const auto u = fc.getURLResult();
if (! audioFileReader.loadURL (u))
NativeMessageBox::showAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::WarningIcon)
.withTitle ("Error loading file")
.withMessage ("Unable to load audio file"),
nullptr);
{
auto options = MessageBoxOptions().withIconType (MessageBoxIconType::WarningIcon)
.withTitle ("Error loading file")
.withMessage ("Unable to load audio file")
.withButton ("OK");
messageBox = NativeMessageBox::showScopedAsync (options, nullptr);
}
else
{
thumbnailComp.setCurrentURL (u);
}
}
fileChooser = nullptr;
@ -629,6 +633,7 @@ private:
AudioFileReaderComponent& audioFileReader;
std::unique_ptr<FileChooser> fileChooser;
ScopedMessageBox messageBox;
};
//==============================================================================

View file

@ -279,13 +279,14 @@ private:
return legacyStartChannel.getText().getIntValue() <= legacyEndChannel.getText().getIntValue();
}
void handleInvalidLegacyModeParameters() const
void handleInvalidLegacyModeParameters()
{
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
"Invalid legacy mode channel layout",
"Cannot set legacy mode start/end channel:\n"
"The end channel must not be less than the start channel!",
"Got it");
auto options = MessageBoxOptions::makeOptionsOk (MessageBoxIconType::WarningIcon,
"Invalid legacy mode channel layout",
"Cannot set legacy mode start/end channel:\n"
"The end channel must not be less than the start channel!",
"Got it");
messageBox = AlertWindow::showScopedAsync (options, nullptr);
}
Range<int> getLegacyModeChannelRange() const
@ -338,6 +339,8 @@ private:
ComboBox numberOfVoices;
Label numberOfVoicesLabel { {}, "Number of synth voices"};
ScopedMessageBox messageBox;
static constexpr int defaultMemberChannels = 15,
defaultMasterPitchbendRange = 2,
defaultNotePitchbendRange = 48;

View file

@ -195,7 +195,13 @@ private:
addAndMakeVisible (textButton);
shapeButton.setShape (getJUCELogoPath(), false, true, false);
shapeButton.onClick = [] { AlertWindow::showMessageBoxAsync (MessageBoxIconType::InfoIcon, "Alert", "This is an AlertWindow"); };
shapeButton.onClick = [this]
{
auto options = MessageBoxOptions::makeOptionsOk (MessageBoxIconType::InfoIcon,
"Alert",
"This is an AlertWindow");
messageBox = AlertWindow::showScopedAsync (options, nullptr);
};
shapeButton.setHasFocusOutline (true);
addAndMakeVisible (shapeButton);
}
@ -250,6 +256,7 @@ private:
Colours::darkorange,
Colours::darkorange.brighter (0.5f),
Colours::darkorange.brighter (0.75f) };
ScopedMessageBox messageBox;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ButtonsComponent)

View file

@ -252,8 +252,10 @@ private:
}
else
{
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon, "Camera open failed",
"Camera open failed, reason: " + error);
auto options = MessageBoxOptions::makeOptionsOk (MessageBoxIconType::WarningIcon,
"Camera open failed",
"Camera open failed, reason: " + error);
messageBox = AlertWindow::showScopedAsync (options, nullptr);
}
snapshotButton .setEnabled (cameraDevice.get() != nullptr && ! contentSharingPending);
@ -365,9 +367,10 @@ private:
void errorOccurred (const String& error)
{
AlertWindow::showMessageBoxAsync (MessageBoxIconType::InfoIcon,
"Camera Device Error",
"An error has occurred: " + error + " Camera will be closed.");
auto options = MessageBoxOptions::makeOptionsOk (MessageBoxIconType::InfoIcon,
"Camera Device Error",
"An error has occurred: " + error + " Camera will be closed.");
messageBox = AlertWindow::showScopedAsync (options, nullptr);
cameraDevice.reset();
@ -378,14 +381,17 @@ private:
void sharingFinished (bool success, bool isCapture)
{
AlertWindow::showMessageBoxAsync (MessageBoxIconType::InfoIcon,
isCapture ? "Image sharing result" : "Video sharing result",
success ? "Success!" : "Failed!");
auto options = MessageBoxOptions::makeOptionsOk (MessageBoxIconType::InfoIcon,
isCapture ? "Image sharing result" : "Video sharing result",
success ? "Success!" : "Failed!");
messageBox = AlertWindow::showScopedAsync (options, nullptr);
contentSharingPending = false;
snapshotButton .setEnabled (true);
recordMovieButton.setEnabled (true);
}
ScopedMessageBox messageBox;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CameraDemo)
};

View file

@ -48,12 +48,19 @@
#include "../Assets/DemoUtilities.h"
//==============================================================================
struct MessageBoxOwnerComponent : public Component
{
ScopedMessageBox messageBox;
};
//==============================================================================
class DemoBackgroundThread : public ThreadWithProgressWindow
{
public:
DemoBackgroundThread()
: ThreadWithProgressWindow ("busy doing some important things...", true, true)
explicit DemoBackgroundThread (MessageBoxOwnerComponent& comp)
: ThreadWithProgressWindow ("busy doing some important things...", true, true),
owner (&comp)
{
setStatusMessage ("Getting ready...");
}
@ -91,21 +98,26 @@ public:
{
const String messageString (userPressedCancel ? "You pressed cancel!" : "Thread finished ok!");
AlertWindow::showAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Progress window")
.withMessage (messageString)
.withButton ("OK"),
nullptr);
if (owner != nullptr)
{
owner->messageBox = AlertWindow::showScopedAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Progress window")
.withMessage (messageString)
.withButton ("OK"),
nullptr);
}
// ..and clean up by deleting our thread object..
delete this;
}
Component::SafePointer<MessageBoxOwnerComponent> owner;
};
//==============================================================================
class DialogsDemo : public Component
class DialogsDemo : public MessageBoxOwnerComponent
{
public:
enum DialogType
@ -114,7 +126,7 @@ public:
warningAlertWindow,
infoAlertWindow,
questionAlertWindow,
okCancelAlertWindow,
yesNoCancelAlertWindow,
extraComponentsAlertWindow,
calloutBoxWindow,
progressWindow,
@ -140,7 +152,7 @@ public:
"Alert Window With Warning Icon",
"Alert Window With Info Icon",
"Alert Window With Question Icon",
"OK Cancel Alert Window",
"Yes No Cancel Alert Window",
"Alert Window With Extra Components",
"CalloutBox",
"Thread With Progress Window",
@ -168,18 +180,19 @@ public:
setSize (500, 500);
RuntimePermissions::request (RuntimePermissions::readExternalStorage,
[] (bool granted)
{
if (! granted)
AlertWindow::showAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::WarningIcon)
.withTitle ("Permissions warning")
.withMessage ("External storage access permission not granted, some files"
" may be inaccessible.")
.withButton ("OK"),
nullptr);
});
RuntimePermissions::request (RuntimePermissions::readExternalStorage, [ptr = Component::SafePointer (this)] (bool granted)
{
if (granted || ptr == nullptr)
return;
ptr->messageBox = AlertWindow::showScopedAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::WarningIcon)
.withTitle ("Permissions warning")
.withMessage ("External storage access permission not granted, some files"
" may be inaccessible.")
.withButton ("OK"),
nullptr);
});
}
//==============================================================================
@ -214,49 +227,51 @@ private:
OwnedArray<TextButton> windowButtons;
ToggleButton nativeButton;
struct AlertBoxResultChosen
auto getAlertBoxResultChosen()
{
void operator() (int result) const noexcept
return [ptr = Component::SafePointer (this)] (int result)
{
AlertWindow::showAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Alert Box")
.withMessage ("Result code: " + String (result))
.withButton ("OK"),
nullptr);
}
};
if (ptr != nullptr)
ptr->messageBox = AlertWindow::showScopedAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Alert Box")
.withMessage ("Result code: " + String (result))
.withButton ("OK"),
nullptr);
};
}
struct AsyncAlertBoxResultChosen
auto getAsyncAlertBoxResultChosen()
{
void operator() (int result) const noexcept
return [ptr = Component::SafePointer (this)] (int result)
{
auto& aw = *demo.asyncAlertWindow;
if (ptr == nullptr)
return;
auto& aw = *ptr->asyncAlertWindow;
aw.exitModalState (result);
aw.setVisible (false);
if (result == 0)
{
AlertBoxResultChosen{} (result);
ptr->getAlertBoxResultChosen() (result);
return;
}
auto optionIndexChosen = aw.getComboBoxComponent ("option")->getSelectedItemIndex();
auto text = aw.getTextEditorContents ("text");
AlertWindow::showAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Alert Box")
.withMessage ("Result code: " + String (result) + newLine
+ "Option index chosen: " + String (optionIndexChosen) + newLine
+ "Text: " + text)
.withButton ("OK"),
nullptr);
}
DialogsDemo& demo;
};
ptr->messageBox = AlertWindow::showScopedAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Alert Box")
.withMessage ("Result code: " + String (result) + newLine
+ "Option index chosen: " + String (optionIndexChosen) + newLine
+ "Text: " + text)
.withButton ("OK"),
nullptr);
};
}
void showWindow (Component& button, DialogType type)
{
@ -268,16 +283,19 @@ private:
if (type == infoAlertWindow) icon = MessageBoxIconType::InfoIcon;
if (type == questionAlertWindow) icon = MessageBoxIconType::QuestionIcon;
AlertWindow::showMessageBoxAsync (icon, "This is an AlertWindow",
"And this is the AlertWindow's message. Blah blah blah blah blah blah blah blah blah blah blah blah blah.",
"OK");
auto options = MessageBoxOptions::makeOptionsOk (icon,
"This is an AlertWindow",
"And this is the AlertWindow's message. "
"Blah blah blah blah blah blah blah blah blah blah blah blah blah.");
messageBox = AlertWindow::showScopedAsync (options, nullptr);
}
else if (type == okCancelAlertWindow)
else if (type == yesNoCancelAlertWindow)
{
AlertWindow::showOkCancelBox (MessageBoxIconType::QuestionIcon, "This is an ok/cancel AlertWindow",
"And this is the AlertWindow's message. Blah blah blah blah blah blah blah blah blah blah blah blah blah.",
{}, {}, {},
ModalCallbackFunction::create (AlertBoxResultChosen{}));
auto options = MessageBoxOptions::makeOptionsYesNoCancel (MessageBoxIconType::QuestionIcon,
"This is a yes/no/cancel AlertWindow",
"And this is the AlertWindow's message. "
"Blah blah blah blah blah blah blah blah blah blah blah blah blah.");
messageBox = AlertWindow::showScopedAsync (options, getAlertBoxResultChosen());
}
else if (type == calloutBoxWindow)
{
@ -301,13 +319,13 @@ private:
asyncAlertWindow->addButton ("OK", 1, KeyPress (KeyPress::returnKey, 0, 0));
asyncAlertWindow->addButton ("Cancel", 0, KeyPress (KeyPress::escapeKey, 0, 0));
asyncAlertWindow->enterModalState (true, ModalCallbackFunction::create (AsyncAlertBoxResultChosen { *this }));
asyncAlertWindow->enterModalState (true, ModalCallbackFunction::create (getAsyncAlertBoxResultChosen()));
}
else if (type == progressWindow)
{
// This will launch our ThreadWithProgressWindow in a modal state. (Our subclass
// will take care of deleting the object when the task has finished)
(new DemoBackgroundThread())->launchThread();
(new DemoBackgroundThread (*this))->launchThread();
}
else if (type >= loadChooser && type <= saveChooser)
{
@ -318,9 +336,10 @@ private:
fc.reset (new FileChooser ("Choose a file to open...", File::getCurrentWorkingDirectory(),
"*", useNativeVersion));
fc->launchAsync (FileBrowserComponent::canSelectMultipleItems | FileBrowserComponent::openMode
| FileBrowserComponent::canSelectFiles,
[] (const FileChooser& chooser)
fc->launchAsync (FileBrowserComponent::canSelectMultipleItems
| FileBrowserComponent::openMode
| FileBrowserComponent::canSelectFiles,
[this] (const FileChooser& chooser)
{
String chosen;
auto results = chooser.getURLResults();
@ -329,12 +348,12 @@ private:
chosen << (result.isLocalFile() ? result.getLocalFile().getFullPathName()
: result.toString (false)) << "\n";
AlertWindow::showAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("File Chooser...")
.withMessage ("You picked: " + chosen)
.withButton ("OK"),
nullptr);
messageBox = AlertWindow::showScopedAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("File Chooser...")
.withMessage ("You picked: " + chosen)
.withButton ("OK"),
nullptr);
});
}
else if (type == loadWithPreviewChooser)
@ -344,9 +363,10 @@ private:
fc.reset (new FileChooser ("Choose an image to open...", File::getCurrentWorkingDirectory(),
"*.jpg;*.jpeg;*.png;*.gif", useNativeVersion));
fc->launchAsync (FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles
| FileBrowserComponent::canSelectMultipleItems,
[] (const FileChooser& chooser)
fc->launchAsync (FileBrowserComponent::openMode
| FileBrowserComponent::canSelectFiles
| FileBrowserComponent::canSelectMultipleItems,
[this] (const FileChooser& chooser)
{
String chosen;
auto results = chooser.getURLResults();
@ -355,12 +375,12 @@ private:
chosen << (result.isLocalFile() ? result.getLocalFile().getFullPathName()
: result.toString (false)) << "\n";
AlertWindow::showAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("File Chooser...")
.withMessage ("You picked: " + chosen)
.withButton ("OK"),
nullptr);
messageBox = AlertWindow::showScopedAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("File Chooser...")
.withMessage ("You picked: " + chosen)
.withButton ("OK"),
nullptr);
},
&imagePreview);
}
@ -385,7 +405,7 @@ private:
"*", useNativeVersion));
fc->launchAsync (FileBrowserComponent::saveMode | FileBrowserComponent::canSelectFiles,
[fileToSave] (const FileChooser& chooser)
[this, fileToSave] (const FileChooser& chooser)
{
auto result = chooser.getURLResult();
auto name = result.isEmpty() ? String()
@ -409,12 +429,12 @@ private:
}
#endif
AlertWindow::showAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("File Chooser...")
.withMessage ("You picked: " + name)
.withButton ("OK"),
nullptr);
messageBox = AlertWindow::showScopedAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("File Chooser...")
.withMessage ("You picked: " + name)
.withButton ("OK"),
nullptr);
});
}
else if (type == directoryChooser)
@ -425,35 +445,37 @@ private:
useNativeVersion));
fc->launchAsync (FileBrowserComponent::openMode | FileBrowserComponent::canSelectDirectories,
[] (const FileChooser& chooser)
[this] (const FileChooser& chooser)
{
auto result = chooser.getURLResult();
auto name = result.isLocalFile() ? result.getLocalFile().getFullPathName()
: result.toString (true);
AlertWindow::showAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("File Chooser...")
.withMessage ("You picked: " + name)
.withButton ("OK"),
nullptr);
messageBox = AlertWindow::showScopedAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("File Chooser...")
.withMessage ("You picked: " + name)
.withButton ("OK"),
nullptr);
});
}
}
else if (type == shareText)
{
ContentSharer::getInstance()->shareText ("I love JUCE!",
[] (bool success, const String& error)
{
auto resultString = success ? String ("success") : ("failure\n (error: " + error + ")");
ContentSharer::getInstance()->shareText ("I love JUCE!", [ptr = Component::SafePointer (this)] (bool success, const String& error)
{
if (ptr == nullptr)
return;
AlertWindow::showAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Sharing Text Result")
.withMessage ("Sharing text finished\nwith " + resultString)
.withButton ("OK"),
nullptr);
});
auto resultString = success ? String ("success") : ("failure\n (error: " + error + ")");
ptr->messageBox = AlertWindow::showScopedAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Sharing Text Result")
.withMessage ("Sharing text finished\nwith " + resultString)
.withButton ("OK"),
nullptr);
});
}
else if (type == shareFile)
{
@ -467,18 +489,20 @@ private:
Array<URL> urls;
urls.add (URL (fileToSave));
ContentSharer::getInstance()->shareFiles (urls,
[] (bool success, const String& error)
{
auto resultString = success ? String ("success") : ("failure\n (error: " + error + ")");
ContentSharer::getInstance()->shareFiles (urls, [ptr = Component::SafePointer (this)] (bool success, const String& error)
{
if (ptr == nullptr)
return;
AlertWindow::showAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Sharing Files Result")
.withMessage ("Sharing files finished\nwith " + resultString)
.withButton ("OK"),
nullptr);
});
auto resultString = success ? String ("success") : ("failure\n (error: " + error + ")");
ptr->messageBox = AlertWindow::showScopedAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Sharing Files Result")
.withMessage ("Sharing files finished\nwith " + resultString)
.withButton ("OK"),
nullptr);
});
}
}
@ -495,19 +519,21 @@ private:
Array<Image> images { myImage, myImage2 };
ContentSharer::getInstance()->shareImages (images,
[] (bool success, const String& error)
{
String resultString = success ? String ("success")
: ("failure\n (error: " + error + ")");
ContentSharer::getInstance()->shareImages (images, [ptr = Component::SafePointer (this)] (bool success, const String& error)
{
if (ptr == nullptr)
return;
AlertWindow::showAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Sharing Images Result")
.withMessage ("Sharing images finished\nwith " + resultString)
.withButton ("OK"),
nullptr);
});
String resultString = success ? String ("success")
: ("failure\n (error: " + error + ")");
ptr->messageBox = AlertWindow::showScopedAsync (MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Sharing Images Result")
.withMessage ("Sharing images finished\nwith " + resultString)
.withButton ("OK"),
nullptr);
});
}
}

View file

@ -61,8 +61,10 @@ public:
void buttonClicked() override
{
++counter;
AlertWindow::showMessageBoxAsync (MessageBoxIconType::InfoIcon, "Action Button Pressed",
"Pressing this type of property component can trigger an action such as showing an alert window!");
auto options = MessageBoxOptions::makeOptionsOk (MessageBoxIconType::InfoIcon,
"Action Button Pressed",
"Pressing this type of property component can trigger an action such as showing an alert window!");
messageBox = AlertWindow::showScopedAsync (options, nullptr);
refresh();
}
@ -73,6 +75,7 @@ public:
private:
int counter = 0;
ScopedMessageBox messageBox;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DemoButtonPropertyComponent)
};

View file

@ -134,12 +134,15 @@ private:
}
else
{
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
"Couldn't load the file!",
result.getErrorMessage());
auto options = MessageBoxOptions::makeOptionsOk (MessageBoxIconType::WarningIcon,
"Couldn't load the file!",
result.getErrorMessage());
messageBox = AlertWindow::showScopedAsync (options, nullptr);
}
}
ScopedMessageBox messageBox;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MovieComponentWithFileBrowser)
};

View file

@ -213,11 +213,10 @@ public:
{
if (error.isNotEmpty())
{
NativeMessageBox::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
"Plugin Load Failed",
error,
nullptr,
nullptr);
auto options = MessageBoxOptions::makeOptionsOk (MessageBoxIconType::WarningIcon,
"Plugin Load Failed",
error);
messageBox = AlertWindow::showScopedAsync (options, nullptr);
return;
}
@ -281,6 +280,7 @@ private:
std::unique_ptr<AudioPluginInstance> inner;
EditorStyle editorStyle = EditorStyle{};
bool active = false;
ScopedMessageBox messageBox;
static constexpr const char* innerStateTag = "inner_state";
static constexpr const char* editorStyleTag = "editor_style";
@ -298,7 +298,6 @@ private:
}
};
constexpr const char* HostAudioProcessorImpl::innerStateTag;
constexpr const char* HostAudioProcessorImpl::editorStyleTag;

View file

@ -1192,7 +1192,7 @@ private:
}
}
bool isLegacyModeValid() const
bool isLegacyModeValid()
{
if (! areLegacyModeParametersValid())
{
@ -1233,13 +1233,14 @@ private:
return getFirstChannel() <= getLastChannel();
}
void handleInvalidLegacyModeParameters() const
void handleInvalidLegacyModeParameters()
{
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
"Invalid legacy mode channel layout",
"Cannot set legacy mode start/end channel:\n"
"The end channel must not be less than the start channel!",
"Got it");
auto options = MessageBoxOptions::makeOptionsOk (AlertWindow::WarningIcon,
"Invalid legacy mode channel layout",
"Cannot set legacy mode start/end channel:\n"
"The end channel must not be less than the start channel!",
"Got it");
messageBox = AlertWindow::showScopedAsync (options, nullptr);
}
MPESettingsDataModel dataModel;
@ -1251,6 +1252,7 @@ private:
legacyPitchbendRangeLabel { {}, "Pitchbend range (semitones)" };
UndoManager* undoManager;
ScopedMessageBox messageBox;
};
//==============================================================================

View file

@ -156,12 +156,13 @@ private:
voiceProduct.purchasePrice = "In-App purchases unavailable";
}
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
"In-app purchase is unavailable!",
"In-App purchases are not available. This either means you are trying "
"to use IAP on a platform that does not support IAP or you haven't setup "
"your app correctly to work with IAP.",
"OK");
auto options = MessageBoxOptions::makeOptionsOk (MessageBoxIconType::WarningIcon,
"In-app purchase is unavailable!",
"In-App purchases are not available. This either means you are trying "
"to use IAP on a platform that does not support IAP or you haven't setup "
"your app correctly to work with IAP.",
"OK");
messageBox = AlertWindow::showScopedAsync (options, nullptr);
}
else
{
@ -178,11 +179,12 @@ private:
}
}
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
"Your credit card will be charged!",
"You are running the sample code for JUCE In-App purchases. "
"Although this is only sample code, it will still CHARGE YOUR CREDIT CARD!",
"Understood!");
auto options = MessageBoxOptions::makeOptionsOk (MessageBoxIconType::WarningIcon,
"Your credit card will be charged!",
"You are running the sample code for JUCE In-App purchases. "
"Although this is only sample code, it will still CHARGE YOUR CREDIT CARD!",
"Understood!");
messageBox = AlertWindow::showScopedAsync (options, nullptr);
}
guiUpdater.triggerAsyncUpdate();
@ -264,6 +266,7 @@ private:
AsyncUpdater& guiUpdater;
bool havePurchasesBeenRestored = false, havePricesBeenFetched = false, purchaseInProgress = false;
Array<VoiceProduct> voiceProducts;
ScopedMessageBox messageBox;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VoicePurchases)
};

View file

@ -222,16 +222,17 @@ private:
//==============================================================================
void showConnectionErrorMessage (const String& messageText)
{
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
"Connection error",
messageText,
"OK");
auto options = MessageBoxOptions::makeOptionsOk (MessageBoxIconType::WarningIcon,
"Connection error",
messageText);
messageBox = AlertWindow::showScopedAsync (options, nullptr);
}
//==============================================================================
Slider rotaryKnob;
OSCSender sender1, sender2;
Label senderLabel { {}, "Sender" };
ScopedMessageBox messageBox;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSCSenderDemo)
};
@ -273,15 +274,16 @@ private:
void showConnectionErrorMessage (const String& messageText)
{
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
"Connection error",
messageText,
"OK");
auto options = MessageBoxOptions::makeOptionsOk (MessageBoxIconType::WarningIcon,
"Connection error",
messageText);
messageBox = AlertWindow::showScopedAsync (options, nullptr);
}
//==============================================================================
Slider rotaryKnob;
Label receiverLabel { {}, "Receiver" };
ScopedMessageBox messageBox;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSCReceiverDemo)
};
@ -403,28 +405,28 @@ private:
//==============================================================================
void handleConnectError (int failedPort)
{
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
"OSC Connection error",
"Error: could not connect to port " + String (failedPort),
"OK");
auto options = MessageBoxOptions::makeOptionsOk (MessageBoxIconType::WarningIcon,
"OSC Connection error",
"Error: could not connect to port " + String (failedPort));
messageBox = AlertWindow::showScopedAsync (options, nullptr);
}
//==============================================================================
void handleDisconnectError()
{
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
"Unknown error",
"An unknown error occurred while trying to disconnect from UDP port.",
"OK");
auto options = MessageBoxOptions::makeOptionsOk (MessageBoxIconType::WarningIcon,
"Unknown error",
"An unknown error occurred while trying to disconnect from UDP port.");
messageBox = AlertWindow::showScopedAsync (options, nullptr);
}
//==============================================================================
void handleInvalidPortNumberEntered()
{
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
"Invalid port number",
"Error: you have entered an invalid UDP port number.",
"OK");
auto options = MessageBoxOptions::makeOptionsOk (MessageBoxIconType::WarningIcon,
"Invalid port number",
"Error: you have entered an invalid UDP port number.");
messageBox = AlertWindow::showScopedAsync (options, nullptr);
}
//==============================================================================
@ -457,6 +459,8 @@ private:
connectionStatusLabel.setJustificationType (Justification::centredRight);
}
ScopedMessageBox messageBox;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSCMonitorDemo)
};

View file

@ -185,21 +185,25 @@ public:
{ PushNotifications::getInstance()->removeAllPendingLocalNotifications(); };
#endif
remoteView.getDeviceTokenButton.onClick = []
remoteView.getDeviceTokenButton.onClick = [this]
{
String token = PushNotifications::getInstance()->getDeviceToken();
DBG ("token = " + token);
if (token.isEmpty())
{
showRemoteInstructions();
}
else
NativeMessageBox::showAsync (MessageBoxOptions()
{
auto options = MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Device token")
.withMessage (token)
.withButton ("OK"),
nullptr);
.withButton ("OK");
messageBox = NativeMessageBox::showScopedAsync (options, nullptr);
}
};
#if JUCE_ANDROID
@ -313,12 +317,12 @@ private:
String requiredFields = "all required fields";
#endif
NativeMessageBox::showAsync (MessageBoxOptions()
auto options = MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Incorrect notifications setup")
.withMessage ("Please make sure that " + requiredFields + " are set.")
.withButton ("OK"),
nullptr);
.withButton ("OK");
messageBox = NativeMessageBox::showScopedAsync (options, nullptr);
return;
}
@ -565,14 +569,14 @@ private:
{
ignoreUnused (isLocalNotification);
NativeMessageBox::showAsync (MessageBoxOptions()
auto options = MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Received notification")
.withMessage ("ID: " + n.identifier
+ ", title: " + n.title
+ ", body: " + n.body)
.withButton ("OK"),
nullptr);
.withButton ("OK");
messageBox = NativeMessageBox::showScopedAsync (options, nullptr);
}
void handleNotificationAction (bool isLocalNotification,
@ -582,7 +586,7 @@ private:
{
ignoreUnused (isLocalNotification);
NativeMessageBox::showAsync (MessageBoxOptions()
auto options = MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Received notification action")
.withMessage ("ID: " + n.identifier
@ -590,22 +594,22 @@ private:
+ ", body: " + n.body
+ ", action: " + actionIdentifier
+ ", optionalResponse: " + optionalResponse)
.withButton ("OK"),
nullptr);
.withButton ("OK");
messageBox = NativeMessageBox::showScopedAsync (options, nullptr);
PushNotifications::getInstance()->removeDeliveredNotification (n.identifier);
}
void localNotificationDismissedByUser (const PushNotifications::Notification& n) override
{
NativeMessageBox::showAsync (MessageBoxOptions()
auto options = MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Notification dismissed by a user")
.withMessage ("ID: " + n.identifier
+ ", title: " + n.title
+ ", body: " + n.body)
.withButton ("OK"),
nullptr);
.withButton ("OK");
messageBox = NativeMessageBox::showScopedAsync (options, nullptr);
}
void deliveredNotificationsListReceived (const Array<PushNotifications::Notification>& notifs) override
@ -615,12 +619,12 @@ private:
for (auto& n : notifs)
text << "(" << n.identifier << ", " << n.title << ", " << n.body << "), ";
NativeMessageBox::showAsync (MessageBoxOptions()
auto options = MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Received notification list")
.withMessage (text)
.withButton ("OK"),
nullptr);
.withButton ("OK");
messageBox = NativeMessageBox::showScopedAsync (options, nullptr);
}
void pendingLocalNotificationsListReceived (const Array<PushNotifications::Notification>& notifs) override
@ -630,54 +634,54 @@ private:
for (auto& n : notifs)
text << "(" << n.identifier << ", " << n.title << ", " << n.body << "), ";
NativeMessageBox::showAsync (MessageBoxOptions()
auto options = MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Pending notification list")
.withMessage (text)
.withButton ("OK"),
nullptr);
.withButton ("OK");
messageBox = NativeMessageBox::showScopedAsync (options, nullptr);
}
void deviceTokenRefreshed (const String& token) override
{
NativeMessageBox::showAsync (MessageBoxOptions()
auto options = MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Device token refreshed")
.withMessage (token)
.withButton ("OK"),
nullptr);
.withButton ("OK");
messageBox = NativeMessageBox::showScopedAsync (options, nullptr);
}
#if JUCE_ANDROID
void remoteNotificationsDeleted() override
{
NativeMessageBox::showAsync (MessageBoxOptions()
auto options = MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Remote notifications deleted")
.withMessage ("Some of the pending messages were removed!")
.withButton ("OK"),
nullptr);
.withButton ("OK");
messageBox = NativeMessageBox::showScopedAsync (options, nullptr);
}
void upstreamMessageSent (const String& messageId) override
{
NativeMessageBox::showAsync (MessageBoxOptions()
auto options = MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Upstream message sent")
.withMessage ("Message id: " + messageId)
.withButton ("OK"),
nullptr);
.withButton ("OK");
messageBox = NativeMessageBox::showScopedAsync (options, nullptr);
}
void upstreamMessageSendingError (const String& messageId, const String& error) override
{
NativeMessageBox::showAsync (MessageBoxOptions()
auto options = MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Upstream message sending error")
.withMessage ("Message id: " + messageId
+ "\nerror: " + error)
.withButton ("OK"),
nullptr);
.withButton ("OK");
messageBox = NativeMessageBox::showScopedAsync (options, nullptr);
}
static Array<PushNotifications::Channel> getAndroidChannels()
@ -1207,8 +1211,8 @@ private:
struct DemoTabbedComponent : public TabbedComponent
{
explicit DemoTabbedComponent (TabbedButtonBar::Orientation orientation)
: TabbedComponent (orientation)
DemoTabbedComponent (PushNotificationsDemo& demoIn, TabbedButtonBar::Orientation orientation)
: TabbedComponent (orientation), demo (demoIn)
{
}
@ -1216,27 +1220,28 @@ private:
{
if (! showedRemoteInstructions && newCurrentTabName == "Remote")
{
PushNotificationsDemo::showRemoteInstructions();
demo.showRemoteInstructions();
showedRemoteInstructions = true;
}
}
private:
bool showedRemoteInstructions = false;
PushNotificationsDemo& demo;
};
static void showRemoteInstructions()
void showRemoteInstructions()
{
#if JUCE_IOS || JUCE_MAC
NativeMessageBox::showAsync (MessageBoxOptions()
auto options = MessageBoxOptions()
.withIconType (MessageBoxIconType::InfoIcon)
.withTitle ("Remote Notifications instructions")
.withMessage ("In order to be able to test remote notifications "
"ensure that the app is signed and that you register "
"the bundle ID for remote notifications in "
"Apple Developer Center.")
.withButton ("OK"),
nullptr);
.withButton ("OK");
messageBox = NativeMessageBox::showScopedAsync (options, nullptr);
#endif
}
@ -1246,10 +1251,11 @@ private:
AuxActionsView auxActionsView;
TabbedComponent localNotificationsTabs { TabbedButtonBar::TabsAtTop };
RemoteView remoteView;
DemoTabbedComponent mainTabs { TabbedButtonBar::TabsAtTop };
DemoTabbedComponent mainTabs { *this, TabbedButtonBar::TabsAtTop };
TextButton sendButton { "Send!" };
Label notAvailableYetLabel { "notAvailableYetLabel",
"Push Notifications feature is not available on this platform yet!" };
ScopedMessageBox messageBox;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PushNotificationsDemo)