gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

commit 1c7fc3fcede7f3e9460c18fed87297c083afcef9
parent 42f7fe5f79b6b28da28b55750fa5ac476b149f3a
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Sat,  8 Feb 2025 16:11:56 +0100

replace all message box calls with own versions that don't require modal loops

Diffstat:
Msource/juce.cmake | 1-
Msource/jucePluginEditorLib/midiPorts.cpp | 5+++--
Msource/jucePluginEditorLib/partbutton.cpp | 4++--
Msource/jucePluginEditorLib/patchmanager/datasourcetreeitem.cpp | 23++++++++++++++++++-----
Msource/jucePluginEditorLib/patchmanager/grouptreeitem.cpp | 16++++++++--------
Msource/jucePluginEditorLib/patchmanager/listitem.cpp | 14+++++++++-----
Msource/jucePluginEditorLib/patchmanager/listmodel.cpp | 15+++++++++------
Msource/jucePluginEditorLib/patchmanager/listmodel.h | 4+++-
Msource/jucePluginEditorLib/patchmanager/patchmanager.cpp | 40++++++++++++++++++++++++++++------------
Msource/jucePluginEditorLib/pluginEditor.cpp | 23+++++++++++++++--------
Msource/jucePluginEditorLib/pluginEditorState.cpp | 24++++++++++++++----------
Msource/jucePluginLib/controller.cpp | 7+++----
Msource/jucePluginLib/processor.cpp | 18++++++++++--------
Msource/juceUiLib/CMakeLists.txt | 1-
Msource/juceUiLib/messageBox.cpp | 8++++----
Msource/juceUiLib/messageBox.h | 4++--
Msource/virusJucePlugin/CMakeLists.txt | 1-
Msource/virusJucePlugin/VirusEditor.cpp | 14+++++++++++---
Msource/virusJucePlugin/VirusProcessor.cpp | 4+++-
Msource/xtJucePlugin/weTablesTreeItem.cpp | 6++++--
Msource/xtJucePlugin/weWaveTreeItem.cpp | 6++++--
Msource/xtJucePlugin/xtPatchManager.cpp | 8+++++---
22 files changed, 155 insertions(+), 91 deletions(-)

diff --git a/source/juce.cmake b/source/juce.cmake @@ -62,7 +62,6 @@ target_compile_definitions(juce_plugin_modules PUBLIC JUCE_USE_CURL=0 # If you remove this, add `NEEDS_CURL TRUE` to the `juce_add_plugin` call JUCE_VST3_CAN_REPLACE_VST2=0 JUCE_WIN_PER_MONITOR_DPI_AWARE=1 - JUCE_MODAL_LOOPS_PERMITTED=1 JUCE_USE_OGGVORBIS=0 JUCE_USE_MP3AUDIOFORMAT=0 JUCE_USE_FLAC=0 diff --git a/source/jucePluginEditorLib/midiPorts.cpp b/source/jucePluginEditorLib/midiPorts.cpp @@ -3,6 +3,7 @@ #include "pluginProcessor.h" #include "juceUiLib/editor.h" +#include "juceUiLib/messageBox.h" namespace { @@ -108,9 +109,9 @@ namespace jucePluginEditorLib void MidiPorts::showMidiPortFailedMessage(const pluginLib::Processor& _processor, const char* _name) { - juce::NativeMessageBox::showMessageBoxAsync(juce::MessageBoxIconType::WarningIcon, _processor.getProperties().name, + genericUI::MessageBox::showOk(juce::MessageBoxIconType::WarningIcon, _processor.getProperties().name, std::string("Failed to open Midi ") + _name + ".\n\n" - "Make sure that the device is not already in use by another program.", nullptr, juce::ModalCallbackFunction::create([](int){})); + "Make sure that the device is not already in use by another program."); } void MidiPorts::updateMidiInput(int _index) const diff --git a/source/jucePluginEditorLib/partbutton.cpp b/source/jucePluginEditorLib/partbutton.cpp @@ -67,11 +67,11 @@ namespace jucePluginEditorLib if(!pm->activatePatch(_files.begin()->toStdString(), getPart())) { - juce::NativeMessageBox::showMessageBoxAsync(juce::MessageBoxIconType::WarningIcon, + genericUI::MessageBox::showOk(juce::MessageBoxIconType::WarningIcon, m_editor.getProcessor().getProperties().name, "Failed to load patch. Make sure that the format is supported and that the file only contains one patch.\n" "\n" - "Drag files with multiple patches onto the Patch Manager instead to import them", nullptr, juce::ModalCallbackFunction::create([](int){})); + "Drag files with multiple patches onto the Patch Manager instead to import them"); } } diff --git a/source/jucePluginEditorLib/patchmanager/datasourcetreeitem.cpp b/source/jucePluginEditorLib/patchmanager/datasourcetreeitem.cpp @@ -14,6 +14,8 @@ #include "jucePluginLib/patchdb/datasource.h" #include "jucePluginLib/patchdb/search.h" +#include "juceUiLib/messageBox.h" + #include "synthLib/buildconfig.h" namespace jucePluginEditorLib::patchManager @@ -92,8 +94,13 @@ namespace jucePluginEditorLib::patchManager if (juce::ModifierKeys::currentModifiers.isShiftDown()) { - if(ListModel::showDeleteConfirmationMessageBox()) - getPatchManager().removePatches(m_dataSource, _patches); + ListModel::showDeleteConfirmationMessageBox([this, _patches](const genericUI::MessageBox::Result _result) + { + if (_result == genericUI::MessageBox::Result::Yes) + { + getPatchManager().removePatches(m_dataSource, _patches); + } + }); } else { @@ -146,10 +153,16 @@ namespace jucePluginEditorLib::patchManager { menu.addItem("Delete", [this] { - if(1 == juce::NativeMessageBox::showYesNoBox(juce::AlertWindow::WarningIcon, + genericUI::MessageBox::showYesNo(juce::MessageBoxIconType::WarningIcon, "Patch Manager", - "Are you sure that you want to delete your user bank named '" + getDataSource()->name + "'?")) - getPatchManager().removeDataSource(*m_dataSource); + "Are you sure that you want to delete your user bank named '" + getDataSource()->name + "'?", + [this](const genericUI::MessageBox::Result _result) + { + if (_result == genericUI::MessageBox::Result::Yes) + { + getPatchManager().removeDataSource(*m_dataSource); + } + }); }); } if(m_dataSource->type == pluginLib::patchDB::SourceType::LocalStorage) diff --git a/source/jucePluginEditorLib/patchmanager/grouptreeitem.cpp b/source/jucePluginEditorLib/patchmanager/grouptreeitem.cpp @@ -140,13 +140,13 @@ namespace jucePluginEditorLib::patchManager { juce::FileChooser fc("Select Folders"); - if(fc.showDialog( + fc.launchAsync( juce::FileBrowserComponent::openMode | juce::FileBrowserComponent::canSelectDirectories | juce::FileBrowserComponent::canSelectMultipleItems - , nullptr)) + , [this](const juce::FileChooser& _fileChooser) { - for (const auto& r : fc.getResults()) + for (const auto& r : _fileChooser.getResults()) { const auto result = r.getFullPathName().toStdString(); pluginLib::patchDB::DataSource ds; @@ -155,19 +155,19 @@ namespace jucePluginEditorLib::patchManager ds.origin = pluginLib::patchDB::DataSourceOrigin::Manual; getPatchManager().addDataSource(ds); } - } + }); }); menu.addItem("Add files...", [this] { juce::FileChooser fc("Select Files"); - if(fc.showDialog( + fc.launchAsync( juce::FileBrowserComponent::openMode | juce::FileBrowserComponent::canSelectFiles | juce::FileBrowserComponent::canSelectMultipleItems, - nullptr)) + [this](const juce::FileChooser& _fileChooser) { - for (const auto&r : fc.getResults()) + for (const auto&r : _fileChooser.getResults()) { const auto result = r.getFullPathName().toStdString(); pluginLib::patchDB::DataSource ds; @@ -176,7 +176,7 @@ namespace jucePluginEditorLib::patchManager ds.origin = pluginLib::patchDB::DataSourceOrigin::Manual; getPatchManager().addDataSource(ds); } - } + }); }); } else if(m_type == GroupType::LocalStorage) diff --git a/source/jucePluginEditorLib/patchmanager/listitem.cpp b/source/jucePluginEditorLib/patchmanager/listitem.cpp @@ -113,12 +113,16 @@ namespace jucePluginEditorLib::patchManager if(existingPatch) { - if(1 == juce::NativeMessageBox::showYesNoBox(juce::AlertWindow::QuestionIcon, + genericUI::MessageBox::showYesNo(juce::MessageBoxIconType::QuestionIcon, "Replace Patch", - "Do you want to replace the existing patch '" + existingPatch->name + "' with contents of part " + std::to_string(savePatchDesc->getPart()+1) + "?")) - { - pm.replacePatch(existingPatch, patches.front()); - } + "Do you want to replace the existing patch '" + existingPatch->name + "' with contents of part " + std::to_string(savePatchDesc->getPart() + 1) + "?", + [this, existingPatch, patches](genericUI::MessageBox::Result _result) + { + if (_result == genericUI::MessageBox::Result::Yes) + { + m_list.getPatchManager().replacePatch(existingPatch, patches.front()); + } + }); return; } } diff --git a/source/jucePluginEditorLib/patchmanager/listmodel.cpp b/source/jucePluginEditorLib/patchmanager/listmodel.cpp @@ -173,11 +173,14 @@ namespace jucePluginEditorLib::patchManager { menu.addItem("Delete selected", [this, s = selectedPatches] { - if(showDeleteConfirmationMessageBox()) + showDeleteConfirmationMessageBox([this, s](genericUI::MessageBox::Result _result) { - const std::vector<pluginLib::patchDB::PatchPtr> patches(s.begin(), s.end()); - m_patchManager.removePatches(m_search->request.sourceNode, patches); - } + if (_result == genericUI::MessageBox::Result::Yes) + { + const std::vector<pluginLib::patchDB::PatchPtr> patches(s.begin(), s.end()); + m_patchManager.removePatches(m_search->request.sourceNode, patches); + } + }); }); } @@ -565,9 +568,9 @@ namespace jucePluginEditorLib::patchManager ListBoxModel::backgroundClicked(_mouseEvent); } - bool ListModel::showDeleteConfirmationMessageBox() + void ListModel::showDeleteConfirmationMessageBox(genericUI::MessageBox::Callback _callback) { - return 1 == juce::NativeMessageBox::showYesNoBox(juce::AlertWindow::WarningIcon, "Confirmation needed", "Delete selected patches from bank?"); + genericUI::MessageBox::showYesNo(juce::MessageBoxIconType::WarningIcon, "Confirmation needed", "Delete selected patches from bank?", std::move(_callback)); } pluginLib::patchDB::SourceType ListModel::getSourceType() const diff --git a/source/jucePluginEditorLib/patchmanager/listmodel.h b/source/jucePluginEditorLib/patchmanager/listmodel.h @@ -4,6 +4,8 @@ #include "jucePluginLib/patchdb/patchdbtypes.h" +#include "juceUiLib/messageBox.h" + #include "juce_gui_basics/juce_gui_basics.h" namespace jucePluginEditorLib @@ -85,7 +87,7 @@ namespace jucePluginEditorLib::patchManager void listBoxItemClicked(int _row, const juce::MouseEvent&) override; void backgroundClicked(const juce::MouseEvent&) override; - static bool showDeleteConfirmationMessageBox(); + static void showDeleteConfirmationMessageBox(genericUI::MessageBox::Callback _callback); pluginLib::patchDB::SourceType getSourceType() const; bool canReorderPatches() const; bool hasTagFilters() const; diff --git a/source/jucePluginEditorLib/patchmanager/patchmanager.cpp b/source/jucePluginEditorLib/patchmanager/patchmanager.cpp @@ -205,7 +205,7 @@ namespace jucePluginEditorLib::patchManager msg += "\n"; } - juce::NativeMessageBox::showMessageBox(juce::AlertWindow::WarningIcon, "Patch Manager Error", msg); + genericUI::MessageBox::showOk(juce::AlertWindow::WarningIcon, "Patch Manager Error", msg); } } @@ -626,26 +626,42 @@ namespace jucePluginEditorLib::patchManager } if(!Editor::savePresets(type, name, patchData)) - juce::NativeMessageBox::showMessageBox(juce::AlertWindow::WarningIcon, "Save failed", "Failed to write data to " + _file.getFullPathName().toStdString()); + genericUI::MessageBox::showOk(juce::AlertWindow::WarningIcon, "Save failed", "Failed to write data to " + _file.getFullPathName().toStdString()); #endif } bool PatchManager::exportPresets(std::vector<pluginLib::patchDB::PatchPtr>&& _patches, const FileType& _fileType) const { - if(_patches.size() > 128) + const auto patchCount = _patches.size(); + + auto exportPatches = [p = std::move(_patches), this, _fileType] { - if(1 != juce::NativeMessageBox::showOkCancelBox(juce::AlertWindow::WarningIcon, - "Patch Manager", - "You are trying to export more than 128 presets into a single file. Note that this dump exceeds the size of one bank and may not be compatible with your hardware")) - return true; - } + auto patches = p; + ListModel::sortPatches(patches, pluginLib::patchDB::SourceType::LocalStorage); + getEditor().savePreset([this, p = std::move(patches), _fileType](const juce::File& _file) + { + exportPresets(_file, p, _fileType); + }); + }; - ListModel::sortPatches(_patches, pluginLib::patchDB::SourceType::LocalStorage); + if(patchCount > 128) + { + genericUI::MessageBox::showOkCancel( + juce::MessageBoxIconType::WarningIcon, + "Patch Manager", + "You are trying to export more than 128 presets into a single file. Note that this dump exceeds the size of one bank and may not be compatible with your hardware", + [this, exportPatches](const genericUI::MessageBox::Result _result) + { + if (_result != genericUI::MessageBox::Result::Ok) + return; - getEditor().savePreset([this, p = std::move(_patches), _fileType](const juce::File& _file) + exportPatches(); + }); + } + else { - exportPresets(_file, p, _fileType); - }); + exportPatches(); + } return true; } diff --git a/source/jucePluginEditorLib/pluginEditor.cpp b/source/jucePluginEditorLib/pluginEditor.cpp @@ -10,6 +10,8 @@ #include "jucePluginLib/parameterbinding.h" #include "jucePluginLib/tools.h" +#include "juceUiLib/messageBox.h" + #include "synthLib/os.h" #include "synthLib/sysexToMidi.h" @@ -93,10 +95,19 @@ namespace jucePluginEditorLib const auto result = _chooser.getResult(); m_processor.getConfig().setValue("save_path", result.getParentDirectory().getFullPathName()); - if (!result.existsAsFile() || juce::NativeMessageBox::showYesNoBox(juce::AlertWindow::WarningIcon, "File exists", "Do you want to overwrite the existing file?") == 1) + if (!result.existsAsFile()) { _callback(result); } + else + { + genericUI::MessageBox::showYesNo(juce::MessageBoxIconType::WarningIcon, "File exists", "Do you want to overwrite the existing file?", + [this, _callback, result](const genericUI::MessageBox::Result _result) + { + if (_result == genericUI::MessageBox::Result::Yes) + _callback(result); + }); + } }; m_fileChooser->launchAsync(flags, onFileChosen); #else @@ -150,7 +161,7 @@ namespace jucePluginEditorLib void Editor::showDemoRestrictionMessageBox() const { const auto &[title, msg] = getDemoRestrictionText(); - juce::NativeMessageBox::showMessageBoxAsync(juce::AlertWindow::WarningIcon, title, msg); + genericUI::MessageBox::showOk(juce::AlertWindow::WarningIcon, title, msg); } void Editor::setPatchManager(patchManager::PatchManager* _patchManager) @@ -592,15 +603,11 @@ namespace jucePluginEditorLib const auto& name = m_processor.getProperties().name; - juce::NativeMessageBox::showMessageBoxAsync(juce::MessageBoxIconType::WarningIcon, + genericUI::MessageBox::showOk(juce::MessageBoxIconType::WarningIcon, name + " - Rosetta detected", name + " appears to be running in Rosetta mode.\n" "\n" - "The DSP emulation core will perform much worse when being executed under Rosetta. We strongly recommend to run your DAW as a native Apple Silicon application", - nullptr, juce::ModalCallbackFunction::create([this](int) - { - m_processor.getConfig().setValue("disclaimerSeen", true); - })); + "The DSP emulation core will perform much worse when being executed under Rosetta. We strongly recommend to run your DAW as a native Apple Silicon application"); } const char* Editor::getResourceByFilename(const std::string& _name, uint32_t& _dataSize) diff --git a/source/jucePluginEditorLib/pluginEditorState.cpp b/source/jucePluginEditorLib/pluginEditorState.cpp @@ -8,6 +8,7 @@ #include "patchmanager/patchmanager.h" #include "juceUiLib/editor.h" +#include "juceUiLib/messageBox.h" #include "dsp56kEmu/logging.h" @@ -159,7 +160,7 @@ bool PluginEditorState::loadSkin(const Skin& _skin, const uint32_t _fallbackInde { LOG("ERROR: Failed to create editor: " << _err.what()); - juce::NativeMessageBox::showMessageBoxAsync(juce::MessageBoxIconType::WarningIcon, m_processor.getProperties().name + " - Skin load failed", _err.what(), nullptr, juce::ModalCallbackFunction::create([](int){})); + genericUI::MessageBox::showOk(juce::MessageBoxIconType::WarningIcon, m_processor.getProperties().name + " - Skin load failed", _err.what()); m_parameterBinding.clear(); m_editor.reset(); @@ -301,7 +302,7 @@ void PluginEditorState::openMenu(const juce::MouseEvent* _event) { m_processor.setLatencyBlocks(_blocks); - juce::NativeMessageBox::showMessageBox(juce::AlertWindow::WarningIcon, "Warning", + genericUI::MessageBox::showOk(juce::AlertWindow::WarningIcon, "Warning", "Most hosts cannot handle if a plugin changes its latency while being in use.\n" "It is advised to save, close & reopen the project to prevent synchronization issues."); }; @@ -490,12 +491,15 @@ void PluginEditorState::openMenu(const juce::MouseEvent* _event) { if(!allowAdvanced) { - if(juce::NativeMessageBox::showOkCancelBox(juce::AlertWindow::WarningIcon, "Warning", - "Changing these settings may cause instability of the plugin.\n" - "\n" - "Please confirm to continue.") - ) - m_processor.getConfig().setValue("allow_advanced_options", true); + genericUI::MessageBox::showOkCancel( + juce::MessageBoxIconType::WarningIcon, + "Warning", + "Changing these settings may cause instability of the plugin.\n\nPlease confirm to continue.", + [this](const genericUI::MessageBox::Result _result) + { + if (_result == genericUI::MessageBox::Result::Ok) + m_processor.getConfig().setValue("allow_advanced_options", true); + }); } else { @@ -526,11 +530,11 @@ void PluginEditorState::exportCurrentSkin() const if(!res.empty()) { - juce::NativeMessageBox::showMessageBoxAsync(juce::MessageBoxIconType::WarningIcon, "Export failed", "Failed to export skin:\n\n" + res, editor, juce::ModalCallbackFunction::create([](int){})); + genericUI::MessageBox::showOk(juce::MessageBoxIconType::WarningIcon, "Export failed", "Failed to export skin:\n\n" + res, editor); } else { - juce::NativeMessageBox::showMessageBoxAsync(juce::MessageBoxIconType::InfoIcon, "Export finished", "Skin successfully exported", editor, juce::ModalCallbackFunction::create([](int){})); + genericUI::MessageBox::showOk(juce::MessageBoxIconType::InfoIcon, "Export finished", "Skin successfully exported", editor); } } diff --git a/source/jucePluginLib/controller.cpp b/source/jucePluginLib/controller.cpp @@ -8,7 +8,7 @@ #include "dsp56kEmu/logging.h" -#include "juce_gui_basics/juce_gui_basics.h" // juce::NativeMessageBox +#include "juceUiLib/messageBox.h" #include "synthLib/os.h" @@ -27,10 +27,9 @@ namespace pluginLib { if(!m_descriptions.isValid()) { - juce::NativeMessageBox::showMessageBoxAsync(juce::MessageBoxIconType::WarningIcon, + genericUI::MessageBox::showOk(juce::MessageBoxIconType::WarningIcon, _processor.getProperties().name + " - Failed to parse Parameter Descriptions json", - "Encountered errors while parsing parameter descriptions:\n\n" + m_descriptions.getErrors(), - nullptr, juce::ModalCallbackFunction::create([](int){})); + "Encountered errors while parsing parameter descriptions:\n\n" + m_descriptions.getErrors()); } } diff --git a/source/jucePluginLib/processor.cpp b/source/jucePluginLib/processor.cpp @@ -19,6 +19,8 @@ #include "dsp56kEmu/fastmath.h" #include "dsp56kEmu/logging.h" +#include "juceUiLib/messageBox.h" + namespace synthLib { class DeviceException; @@ -146,14 +148,14 @@ namespace pluginLib } juce::Timer::callAfterDelay(2000, [this, msg] { - juce::NativeMessageBox::showMessageBoxAsync(juce::AlertWindow::WarningIcon, - "Device Initialization failed", msg, nullptr, - juce::ModalCallbackFunction::create([this](int) + genericUI::MessageBox::showOk(juce::MessageBoxIconType::WarningIcon, + "Device Initialization failed", msg, + [this] { const auto path = juce::File(getPublicRomFolder()); (void)path.createDirectory(); path.revealToUser(); - }) + } ); }); } @@ -451,8 +453,8 @@ namespace pluginLib } catch(synthLib::DeviceException& e) { - juce::NativeMessageBox::showMessageBox(juce::MessageBoxIconType::WarningIcon, - getName() + " - Failed to switch device type", + genericUI::MessageBox::showOk(juce::MessageBoxIconType::WarningIcon, + getName().toStdString() + " - Failed to switch device type", std::string("Failed to create device:\n\n") + e.what() + "\n\n"); } @@ -867,7 +869,7 @@ namespace pluginLib { juce::MessageManager::callAsync([e] { - juce::NativeMessageBox::showMessageBox(juce::MessageBoxIconType::WarningIcon, + genericUI::MessageBox::showOk(juce::MessageBoxIconType::WarningIcon, "Device creation failed:", std::string("The connection to the remote server has been lost and a reconnect failed. Processing mode has been switched to local processing\n\n") + e.what() + "\n\n"); @@ -898,7 +900,7 @@ namespace pluginLib } catch(const synthLib::DeviceException& e) { - juce::NativeMessageBox::showMessageBox(juce::MessageBoxIconType::WarningIcon, + genericUI::MessageBox::showOk(juce::MessageBoxIconType::WarningIcon, "Device creation failed:", std::string("Failed to create device:\n\n") + e.what() + "\n\n"); diff --git a/source/juceUiLib/CMakeLists.txt b/source/juceUiLib/CMakeLists.txt @@ -34,7 +34,6 @@ target_link_libraries(juceUiLib PUBLIC baseLib) target_include_directories(juceUiLib PUBLIC ../JUCE/modules) target_compile_definitions(juceUiLib PRIVATE JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1) -target_compile_definitions(juceUiLib PUBLIC JUCE_MODAL_LOOPS_PERMITTED=1) set_property(TARGET juceUiLib PROPERTY FOLDER "Gearmulator") target_include_directories(juceUiLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..) diff --git a/source/juceUiLib/messageBox.cpp b/source/juceUiLib/messageBox.cpp @@ -27,14 +27,14 @@ namespace genericUI juce::NativeMessageBox::showOkCancelBox(_icon, _header.c_str(), _message.c_str(), nullptr, addCallback(std::move(_callback))); } - void MessageBox::showOk(const juce::MessageBoxIconType _icon, const std::string& _header, const std::string& _message) + void MessageBox::showOk(const juce::MessageBoxIconType _icon, const std::string& _header, const std::string& _message, juce::Component* _associatedComponent/* = nullptr*/) { - juce::NativeMessageBox::showMessageBoxAsync(_icon, _header.c_str(), _message.c_str()); + juce::NativeMessageBox::showMessageBoxAsync(_icon, _header.c_str(), _message.c_str(), _associatedComponent); } - void MessageBox::showOk(juce::MessageBoxIconType _icon, const std::string& _header, const std::string& _message, juce::Component* _owner, std::function<void()> _callback) + void MessageBox::showOk(juce::MessageBoxIconType _icon, const std::string& _header, const std::string& _message, juce::Component* _associatedComponent, std::function<void()> _callback) { - juce::NativeMessageBox::showMessageBoxAsync(_icon, _header.c_str(), _message.c_str(), _owner, + juce::NativeMessageBox::showMessageBoxAsync(_icon, _header.c_str(), _message.c_str(), _associatedComponent, juce::ModalCallbackFunction::create([_callback = std::move(_callback)](int) { _callback(); diff --git a/source/juceUiLib/messageBox.h b/source/juceUiLib/messageBox.h @@ -27,8 +27,8 @@ namespace genericUI static void showYesNo(juce::MessageBoxIconType _icon, const std::string& _header, const std::string& _message, Callback _callback); static void showOkCancel(juce::MessageBoxIconType _icon, const std::string& _header, const std::string& _message, Callback _callback); - static void showOk(juce::MessageBoxIconType _icon, const std::string& _header, const std::string& _message); - static void showOk(juce::MessageBoxIconType _icon, const std::string& _header, const std::string& _message, juce::Component* _owner, std::function<void()> _callback); + static void showOk(juce::MessageBoxIconType _icon, const std::string& _header, const std::string& _message, juce::Component* _associatedComponent = nullptr); + static void showOk(juce::MessageBoxIconType _icon, const std::string& _header, const std::string& _message, juce::Component* _associatedComponent, std::function<void()> _callback); static void showOk(juce::MessageBoxIconType _icon, const std::string& _header, const std::string& _message, std::function<void()> _callback); }; } diff --git a/source/virusJucePlugin/CMakeLists.txt b/source/virusJucePlugin/CMakeLists.txt @@ -39,7 +39,6 @@ target_link_libraries(virusJucePlugin PUBLIC jucePluginEditorLib virusLib) target_include_directories(virusJucePlugin PUBLIC ../JUCE/modules) target_compile_definitions(virusJucePlugin PRIVATE JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1) -target_compile_definitions(virusJucePlugin PUBLIC JUCE_MODAL_LOOPS_PERMITTED=1) if(UNIX AND NOT APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # strange GCC bug, a DeviceException that we throw is not caught in the catch block if LTO is enabled. diff --git a/source/virusJucePlugin/VirusEditor.cpp b/source/virusJucePlugin/VirusEditor.cpp @@ -13,6 +13,8 @@ #include "jucePluginEditorLib/filetype.h" #include "jucePluginEditorLib/patchmanager/savepatchdesc.h" +#include "juceUiLib/messageBox.h" + namespace genericVirusUI { VirusEditor::VirusEditor(pluginLib::ParameterBinding& _binding, virus::VirusProcessor& _processorRef, const jucePluginEditorLib::Skin& _skin) : @@ -400,8 +402,13 @@ namespace genericVirusUI const auto title = m_processor.getProductName(true) + " - Load Arrangement Dump?"; const auto message = "This file contains an arrangement dump, i.e. one Multi and 16 Singles.\nDo you want to replace the current state by this dump?"; - if(1 == juce::NativeMessageBox::showYesNoBox(juce::MessageBoxIconType::QuestionIcon, title, message, nullptr)) + genericUI::MessageBox::showYesNo(juce::MessageBoxIconType::QuestionIcon, title, message, [this, multi, singles](const genericUI::MessageBox::Result _result) { + if (_result != genericUI::MessageBox::Result::Yes) + return; + + auto& c = getController(); + setPlayMode(virusLib::PlayMode::PlayModeMulti); c.sendSysEx(multi); @@ -413,11 +420,12 @@ namespace genericVirusUI } c.requestArrangement(); - } + }); + return; } } - juce::NativeMessageBox::showMessageBox(juce::AlertWindow::InfoIcon, "Information", + genericUI::MessageBox::showOk(juce::AlertWindow::InfoIcon, "Information", "The selected file contains more than one patch. Please add this file as a data source in the Patch Manager instead.\n\n" "Go to the Patch Manager, right click the 'Data Sources' node and select 'Add File...' to import it." ); diff --git a/source/virusJucePlugin/VirusProcessor.cpp b/source/virusJucePlugin/VirusProcessor.cpp @@ -6,6 +6,8 @@ #include "baseLib/binarystream.h" #include "baseLib/filesystem.h" +#include "juceUiLib/messageBox.h" + #include "synthLib/deviceException.h" #include "synthLib/lv2PresetExport.h" @@ -60,7 +62,7 @@ namespace virus } catch(const synthLib::DeviceException& e) { - juce::NativeMessageBox::showMessageBox(juce::MessageBoxIconType::WarningIcon, + genericUI::MessageBox::showOk(juce::MessageBoxIconType::WarningIcon, "Device creation failed:", std::string("Failed to create device:\n\n") + e.what() + "\n\n" diff --git a/source/xtJucePlugin/weTablesTreeItem.cpp b/source/xtJucePlugin/weTablesTreeItem.cpp @@ -6,6 +6,8 @@ #include "xtEditor.h" #include "xtWaveEditor.h" +#include "juceUiLib/messageBox.h" + namespace xtJucePlugin { TablesTreeItem::TablesTreeItem(WaveEditor& _editor, const xt::TableId _tableIndex) : m_editor(_editor), m_index(_tableIndex) @@ -92,7 +94,7 @@ namespace xtJucePlugin if(sysex.empty()) { - juce::NativeMessageBox::showMessageBox(juce::AlertWindow::WarningIcon, errorTitle, "No Sysex data found in file"); + genericUI::MessageBox::showOk(juce::AlertWindow::WarningIcon, errorTitle, "No Sysex data found in file"); return; } @@ -111,7 +113,7 @@ namespace xtJucePlugin return; } - juce::NativeMessageBox::showMessageBox(juce::AlertWindow::WarningIcon, errorTitle, tables.empty() ? "No Control Table found in files" : "Multiple control tables found in file"); + genericUI::MessageBox::showOk(juce::AlertWindow::WarningIcon, errorTitle, tables.empty() ? "No Control Table found in files" : "Multiple control tables found in file"); } void TablesTreeItem::itemClicked(const juce::MouseEvent& _mouseEvent) diff --git a/source/xtJucePlugin/weWaveTreeItem.cpp b/source/xtJucePlugin/weWaveTreeItem.cpp @@ -5,6 +5,8 @@ #include "xtEditor.h" #include "xtWaveEditor.h" +#include "juceUiLib/messageBox.h" + #include "synthLib/midiToSysex.h" namespace xtJucePlugin @@ -129,7 +131,7 @@ namespace xtJucePlugin if(sysex.empty()) { - juce::NativeMessageBox::showMessageBoxAsync(juce::AlertWindow::WarningIcon, errorTitle, "No sysex data found in file"); + genericUI::MessageBox::showOk(juce::AlertWindow::WarningIcon, errorTitle, "No sysex data found in file"); return; } @@ -148,7 +150,7 @@ namespace xtJucePlugin return; } - juce::NativeMessageBox::showMessageBoxAsync(juce::AlertWindow::WarningIcon, errorTitle, waves.empty() ? "No wave data found in file" : "Multiple waves found in file"); + genericUI::MessageBox::showOk(juce::AlertWindow::WarningIcon, errorTitle, waves.empty() ? "No wave data found in file" : "Multiple waves found in file"); } std::vector<std::vector<uint8_t>> WaveTreeItem::getSysexFromFiles(const juce::StringArray& _files) diff --git a/source/xtJucePlugin/xtPatchManager.cpp b/source/xtJucePlugin/xtPatchManager.cpp @@ -5,6 +5,9 @@ #include "xtWaveEditor.h" #include "jucePluginEditorLib/pluginProcessor.h" + +#include "juceUiLib/messageBox.h" + #include "xtLib/xtMidiTypes.h" namespace xtJucePlugin @@ -169,12 +172,11 @@ namespace xtJucePlugin { if(!m_controller.sendSingle(applyModifications(_patch), static_cast<uint8_t>(_part))) { - juce::NativeMessageBox::showMessageBoxAsync(juce::MessageBoxIconType::WarningIcon, + genericUI::MessageBox::showOk(juce::MessageBoxIconType::WarningIcon, m_editor.getProcessor().getProperties().name + " - Unable to load patch", "MW1 patches can only be loaded to the first part.\n" "\n" - "If you want to load a MW1 patch to another part, first convert it by loading it to part 1, then save the loaded patch to a user bank." - , nullptr, juce::ModalCallbackFunction::create([](int){})); + "If you want to load a MW1 patch to another part, first convert it by loading it to part 1, then save the loaded patch to a user bank."); } return true; }