From ab230ef88d67c69b7e4577c921ada2cb198d2e1a Mon Sep 17 00:00:00 2001 From: falkTX Date: Thu, 6 Feb 2014 10:19:11 +0000 Subject: [PATCH] More juce-patchbay work. Mostly all set now --- source/bridges/Makefile | 2 +- .../daz-plugins/juce-host/FilterGraph.cpp | 43 ++++- .../daz-plugins/juce-host/FilterGraph.h | 7 +- .../juce-host/GraphEditorPanel.cpp | 155 +++++++++--------- .../daz-plugins/juce-host/GraphEditorPanel.h | 78 +++++---- .../daz-plugins/juce-host/InternalFilters.cpp | 9 + .../daz-plugins/juce-host/InternalFilters.h | 2 + .../daz-plugins/juce-host/MainHostWindow.cpp | 95 +++++------ .../daz-plugins/juce-host/MainHostWindow.h | 17 +- source/modules/daz-plugins/juce-patchbay.cpp | 68 +++++--- source/modules/daz-plugins/vex-fx.cpp | 2 +- 11 files changed, 281 insertions(+), 197 deletions(-) diff --git a/source/bridges/Makefile b/source/bridges/Makefile index a4ab60b35..a07d7cff9 100644 --- a/source/bridges/Makefile +++ b/source/bridges/Makefile @@ -120,7 +120,7 @@ endif # -------------------------------------------------------------- -TARGETS = jackplugin native +TARGETS = native # -------------------------------------------------------------- # UI bridges diff --git a/source/modules/daz-plugins/juce-host/FilterGraph.cpp b/source/modules/daz-plugins/juce-host/FilterGraph.cpp index 37de5d04c..c7c6330e1 100644 --- a/source/modules/daz-plugins/juce-host/FilterGraph.cpp +++ b/source/modules/daz-plugins/juce-host/FilterGraph.cpp @@ -22,10 +22,9 @@ ============================================================================== */ -//#include "MainHostWindow.h" #include "FilterGraph.h" #include "InternalFilters.h" -//#include "GraphEditorPanel.h" +#include "GraphEditorPanel.h" //============================================================================== @@ -36,7 +35,7 @@ FilterGraph::FilterGraph (AudioPluginFormatManager& formatManager_) filenameWildcard, "Load a filter graph", "Save a filter graph"), - formatManager (formatManager_), lastUID (0) + formatManager (formatManager_), lastUID (0), appProperties (nullptr), panel (nullptr) { setChangedFlag (false); } @@ -46,13 +45,21 @@ FilterGraph::~FilterGraph() graph.clear(); } -void FilterGraph::ready() +void FilterGraph::ready(ApplicationProperties* ap) { + appProperties = ap; + InternalPluginFormat internalFormat; addFilter (internalFormat.getDescriptionFor (InternalPluginFormat::audioInputFilter), 0.5f, 0.1f); addFilter (internalFormat.getDescriptionFor (InternalPluginFormat::midiInputFilter), 0.25f, 0.1f); addFilter (internalFormat.getDescriptionFor (InternalPluginFormat::audioOutputFilter), 0.5f, 0.9f); + addFilter (internalFormat.getDescriptionFor (InternalPluginFormat::midiOutputFilter), 0.25f, 0.9f); +} + +void FilterGraph::setPanel(GraphEditorPanel* p) +{ + panel = p; } uint32 FilterGraph::getNextUID() noexcept @@ -104,7 +111,8 @@ void FilterGraph::addFilter (const PluginDescription* desc, double x, double y) void FilterGraph::removeFilter (const uint32 id) { - //PluginWindow::closeCurrentlyOpenWindowsFor (id); + if (panel != nullptr) + panel->closeCurrentlyOpenWindowsFor (id); if (graph.removeNode (id)) changed(); @@ -199,7 +207,8 @@ void FilterGraph::removeConnection (uint32 sourceFilterUID, int sourceFilterChan void FilterGraph::clear() { - //PluginWindow::closeAllCurrentlyOpenWindows(); + if (panel != nullptr) + panel->closeAllCurrentlyOpenWindows(); graph.clear(); changed(); @@ -238,11 +247,29 @@ Result FilterGraph::saveDocument (const File& file) File FilterGraph::getLastDocumentOpened() { - return File(); + if (appProperties == nullptr) + return File(); + + RecentlyOpenedFilesList recentFiles; + recentFiles.restoreFromString (appProperties->getUserSettings() + ->getValue ("recentFilterGraphFiles")); + + return recentFiles.getFile (0); } -void FilterGraph::setLastDocumentOpened (const File&) +void FilterGraph::setLastDocumentOpened (const File& file) { + if (appProperties == nullptr) + return; + + RecentlyOpenedFilesList recentFiles; + recentFiles.restoreFromString (appProperties->getUserSettings() + ->getValue ("recentFilterGraphFiles")); + + recentFiles.addFile (file); + + appProperties->getUserSettings() + ->setValue ("recentFilterGraphFiles", recentFiles.toString()); } //============================================================================== diff --git a/source/modules/daz-plugins/juce-host/FilterGraph.h b/source/modules/daz-plugins/juce-host/FilterGraph.h index c3e6586f4..15897ef63 100644 --- a/source/modules/daz-plugins/juce-host/FilterGraph.h +++ b/source/modules/daz-plugins/juce-host/FilterGraph.h @@ -27,6 +27,7 @@ class FilterInGraph; class FilterGraph; +class GraphEditorPanel; const char* const filenameSuffix = ".filtergraph"; const char* const filenameWildcard = "*.filtergraph"; @@ -41,7 +42,8 @@ public: //============================================================================== FilterGraph (AudioPluginFormatManager& formatManager); ~FilterGraph(); - void ready(); + void ready(ApplicationProperties* appProperties); + void setPanel(GraphEditorPanel* panel); //============================================================================== AudioProcessorGraph& getGraph() noexcept { return graph; } @@ -107,6 +109,9 @@ private: void createNodeFromXml (const XmlElement& xml); + ApplicationProperties* appProperties; + GraphEditorPanel* panel; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilterGraph) }; diff --git a/source/modules/daz-plugins/juce-host/GraphEditorPanel.cpp b/source/modules/daz-plugins/juce-host/GraphEditorPanel.cpp index 73fe0a3f3..7e5ce058b 100644 --- a/source/modules/daz-plugins/juce-host/GraphEditorPanel.cpp +++ b/source/modules/daz-plugins/juce-host/GraphEditorPanel.cpp @@ -22,53 +22,31 @@ ============================================================================== */ -#include "juce_gui_basics.h" #include "GraphEditorPanel.h" #include "InternalFilters.h" -//#include "MainHostWindow.h" //============================================================================== -class PluginWindow; -static Array activePluginWindows; - -PluginWindow::PluginWindow (Component* const pluginEditor, +PluginWindow::PluginWindow (GraphEditorPanel* const p, + Component* const pluginEditor, AudioProcessorGraph::Node* const o, WindowFormatType t) : DocumentWindow (pluginEditor->getName(), Colours::lightblue, DocumentWindow::minimiseButton | DocumentWindow::closeButton), owner (o), - type (t) + type (t), + panel (p) { setSize (400, 300); setContentOwned (pluginEditor, true); + setUsingNativeTitleBar (true); setTopLeftPosition (owner->properties.getWithDefault ("uiLastX", Random::getSystemRandom().nextInt (500)), owner->properties.getWithDefault ("uiLastY", Random::getSystemRandom().nextInt (500))); setVisible (true); - activePluginWindows.add (this); -} - -void PluginWindow::closeCurrentlyOpenWindowsFor (const uint32 nodeId) -{ - for (int i = activePluginWindows.size(); --i >= 0;) - if (activePluginWindows.getUnchecked(i)->owner->nodeId == nodeId) - delete activePluginWindows.getUnchecked (i); -} - -void PluginWindow::closeAllCurrentlyOpenWindows() -{ - if (activePluginWindows.size() > 0) - { - for (int i = activePluginWindows.size(); --i >= 0;) - delete activePluginWindows.getUnchecked (i); - - Component dummyModalComp; - dummyModalComp.enterModalState(); - MessageManager::getInstance()->runDispatchLoopUntil (50); - } + panel->activePluginWindows.add (this); } //============================================================================== @@ -149,50 +127,9 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProgramAudioProcessorEditor) }; -//============================================================================== -PluginWindow* PluginWindow::getWindowFor (AudioProcessorGraph::Node* const node, - WindowFormatType type) -{ - jassert (node != nullptr); - - for (int i = activePluginWindows.size(); --i >= 0;) - if (activePluginWindows.getUnchecked(i)->owner == node - && activePluginWindows.getUnchecked(i)->type == type) - return activePluginWindows.getUnchecked(i); - - AudioProcessor* processor = node->getProcessor(); - AudioProcessorEditor* ui = nullptr; - - if (type == Normal) - { - ui = processor->createEditorIfNeeded(); - - if (ui == nullptr) - type = Generic; - } - - if (ui == nullptr) - { - if (type == Generic || type == Parameters) - ui = new GenericAudioProcessorEditor (processor); - else if (type == Programs) - ui = new ProgramAudioProcessorEditor (processor); - } - - if (ui != nullptr) - { - if (AudioPluginInstance* const plugin = dynamic_cast (processor)) - ui->setName (plugin->getName()); - - return new PluginWindow (ui, node, type); - } - - return nullptr; -} - PluginWindow::~PluginWindow() { - activePluginWindows.removeFirstMatchingValue (this); + panel->activePluginWindows.removeFirstMatchingValue (this); clearContentComponent(); } @@ -372,7 +309,7 @@ public: default: break; }; - if (PluginWindow* const w = PluginWindow::getWindowFor (f, type)) + if (PluginWindow* const w = getGraphPanel()->getWindowFor (f, type)) w->toFront (true); } } @@ -402,7 +339,7 @@ public: if (e.mouseWasClicked() && e.getNumberOfClicks() == 2) { if (const AudioProcessorGraph::Node::Ptr f = graph.getNodeForId (filterID)) - if (PluginWindow* const w = PluginWindow::getWindowFor (f, PluginWindow::Normal)) + if (PluginWindow* const w = getGraphPanel()->getWindowFor (f, PluginWindow::Normal)) w->toFront (true); } else if (! e.mouseWasClicked()) @@ -814,7 +751,6 @@ void GraphEditorPanel::mouseDown (const MouseEvent& e) { if (e.mods.isPopupMenu()) { -#if 0 PopupMenu m; if (MainHostWindow* const mainWindow = findParentComponentOfClass()) @@ -825,7 +761,6 @@ void GraphEditorPanel::mouseDown (const MouseEvent& e) createNewPlugin (mainWindow->getChosenType (r), e.x, e.y); } -#endif } } @@ -1041,6 +976,67 @@ void GraphEditorPanel::endDraggingConnector (const MouseEvent& e) } } +//============================================================================== +PluginWindow* GraphEditorPanel::getWindowFor (AudioProcessorGraph::Node* const node, + PluginWindow::WindowFormatType type) +{ + jassert (node != nullptr); + + for (int i = activePluginWindows.size(); --i >= 0;) + if (activePluginWindows.getUnchecked(i)->owner == node + && activePluginWindows.getUnchecked(i)->type == type) + return activePluginWindows.getUnchecked(i); + + AudioProcessor* processor = node->getProcessor(); + AudioProcessorEditor* ui = nullptr; + + if (type == PluginWindow::Normal) + { + ui = processor->createEditorIfNeeded(); + + if (ui == nullptr) + type = PluginWindow::Generic; + } + + if (ui == nullptr) + { + if (type == PluginWindow::Generic || type == PluginWindow::Parameters) + ui = new GenericAudioProcessorEditor (processor); + else if (type == PluginWindow::Programs) + ui = new ProgramAudioProcessorEditor (processor); + } + + if (ui != nullptr) + { + if (AudioPluginInstance* const plugin = dynamic_cast (processor)) + ui->setName (plugin->getName()); + + return new PluginWindow (this, ui, node, type); + } + + return nullptr; +} + +void GraphEditorPanel::closeCurrentlyOpenWindowsFor (const uint32 nodeId) +{ + for (int i = activePluginWindows.size(); --i >= 0;) + if (activePluginWindows.getUnchecked(i)->owner->nodeId == nodeId) + delete activePluginWindows.getUnchecked (i); +} + +void GraphEditorPanel::closeAllCurrentlyOpenWindows() +{ + if (activePluginWindows.size() > 0) + { + for (int i = activePluginWindows.size(); --i >= 0;) + delete activePluginWindows.getUnchecked (i); + + Component dummyModalComp; + dummyModalComp.enterModalState(); + MessageManager::getInstance()->runDispatchLoopUntil (50); + } +} + //============================================================================== class TooltipBar : public Component, @@ -1088,6 +1084,7 @@ GraphDocumentComponent::GraphDocumentComponent (FilterGraph& g) { addAndMakeVisible (graphPanel = new GraphEditorPanel (graph)); + // listen for audio/midi count change //deviceManager->addChangeListener (graphPanel); //keyState.addListener (&graphPlayer.getMidiMessageCollector()); @@ -1098,10 +1095,15 @@ GraphDocumentComponent::GraphDocumentComponent (FilterGraph& g) addAndMakeVisible (statusBar = new TooltipBar()); graphPanel->updateComponents(); + + graph.setPanel(graphPanel); } GraphDocumentComponent::~GraphDocumentComponent() { + graph.setPanel(nullptr); + + // listen for audio/midi count change //deviceManager->removeChangeListener (graphPanel); deleteAllChildren(); @@ -1123,3 +1125,8 @@ void GraphDocumentComponent::createNewPlugin (const PluginDescription* desc, int { graphPanel->createNewPlugin (desc, x, y); } + +void GraphDocumentComponent::closeAllCurrentlyOpenWindows() +{ + graphPanel->closeAllCurrentlyOpenWindows(); +} diff --git a/source/modules/daz-plugins/juce-host/GraphEditorPanel.h b/source/modules/daz-plugins/juce-host/GraphEditorPanel.h index e9b78581c..44aa86026 100644 --- a/source/modules/daz-plugins/juce-host/GraphEditorPanel.h +++ b/source/modules/daz-plugins/juce-host/GraphEditorPanel.h @@ -30,6 +30,39 @@ class FilterComponent; class ConnectorComponent; class PinComponent; +class GraphEditorPanel; + + +//============================================================================== +/** A desktop window containing a plugin's UI. */ +class PluginWindow : public DocumentWindow +{ +public: + enum WindowFormatType + { + Normal = 0, + Generic, + Programs, + Parameters + }; + + PluginWindow (GraphEditorPanel* const panel, Component* pluginEditor, AudioProcessorGraph::Node*, WindowFormatType); + ~PluginWindow(); + + void moved() override; + void closeButtonPressed() override; + +private: + AudioProcessorGraph::Node* owner; + WindowFormatType type; + + float getDesktopScaleFactor() const override { return 1.0f; } + + GraphEditorPanel* const panel; + friend class GraphEditorPanel; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginWindow) +}; //============================================================================== @@ -64,6 +97,15 @@ public: void endDraggingConnector (const MouseEvent& e); //============================================================================== + + Array activePluginWindows; + + PluginWindow* getWindowFor (AudioProcessorGraph::Node*, PluginWindow::WindowFormatType); + + void closeCurrentlyOpenWindowsFor (const uint32 nodeId); + void closeAllCurrentlyOpenWindows(); + + //============================================================================== private: FilterGraph& graph; ScopedPointer draggingConnector; @@ -94,6 +136,9 @@ public: //============================================================================== void resized(); + //============================================================================== + void closeAllCurrentlyOpenWindows(); + private: //============================================================================== MidiKeyboardState keyState; @@ -105,37 +150,4 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GraphDocumentComponent) }; -//============================================================================== -/** A desktop window containing a plugin's UI. */ -class PluginWindow : public DocumentWindow -{ -public: - enum WindowFormatType - { - Normal = 0, - Generic, - Programs, - Parameters - }; - - PluginWindow (Component* pluginEditor, AudioProcessorGraph::Node*, WindowFormatType); - ~PluginWindow(); - - static PluginWindow* getWindowFor (AudioProcessorGraph::Node*, WindowFormatType); - - static void closeCurrentlyOpenWindowsFor (const uint32 nodeId); - static void closeAllCurrentlyOpenWindows(); - - void moved() override; - void closeButtonPressed() override; - -private: - AudioProcessorGraph::Node* owner; - WindowFormatType type; - - float getDesktopScaleFactor() const override { return 1.0f; } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginWindow) -}; - #endif // __GRAPHEDITORPANEL_JUCEHEADER__ diff --git a/source/modules/daz-plugins/juce-host/InternalFilters.cpp b/source/modules/daz-plugins/juce-host/InternalFilters.cpp index 9c6645206..fb4407596 100644 --- a/source/modules/daz-plugins/juce-host/InternalFilters.cpp +++ b/source/modules/daz-plugins/juce-host/InternalFilters.cpp @@ -43,6 +43,11 @@ InternalPluginFormat::InternalPluginFormat() AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode); p.fillInPluginDescription (midiInDesc); } + + { + AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::midiOutputNode); + p.fillInPluginDescription (midiOutDesc); + } } AudioPluginInstance* InternalPluginFormat::createInstanceFromDescription (const PluginDescription& desc, @@ -57,6 +62,9 @@ AudioPluginInstance* InternalPluginFormat::createInstanceFromDescription (const if (desc.name == midiInDesc.name) return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode); + if (desc.name == midiOutDesc.name) + return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::midiOutputNode); + return 0; } @@ -67,6 +75,7 @@ const PluginDescription* InternalPluginFormat::getDescriptionFor (const Internal case audioInputFilter: return &audioInDesc; case audioOutputFilter: return &audioOutDesc; case midiInputFilter: return &midiInDesc; + case midiOutputFilter: return &midiOutDesc; default: break; } diff --git a/source/modules/daz-plugins/juce-host/InternalFilters.h b/source/modules/daz-plugins/juce-host/InternalFilters.h index 189be003f..729123d91 100644 --- a/source/modules/daz-plugins/juce-host/InternalFilters.h +++ b/source/modules/daz-plugins/juce-host/InternalFilters.h @@ -45,6 +45,7 @@ public: audioInputFilter = 0, audioOutputFilter, midiInputFilter, + midiOutputFilter, endOfFilterTypes }; @@ -70,6 +71,7 @@ private: PluginDescription audioInDesc; PluginDescription audioOutDesc; PluginDescription midiInDesc; + PluginDescription midiOutDesc; }; diff --git a/source/modules/daz-plugins/juce-host/MainHostWindow.cpp b/source/modules/daz-plugins/juce-host/MainHostWindow.cpp index e86d1045c..692d67fc6 100644 --- a/source/modules/daz-plugins/juce-host/MainHostWindow.cpp +++ b/source/modules/daz-plugins/juce-host/MainHostWindow.cpp @@ -22,7 +22,6 @@ ============================================================================== */ -#include "juce_gui_basics.h" #include "MainHostWindow.h" #include "InternalFilters.h" @@ -36,25 +35,27 @@ public: DocumentWindow::minimiseButton | DocumentWindow::closeButton), owner (owner_) { - const File deadMansPedalFile (getAppProperties().getUserSettings() - ->getFile().getSiblingFile ("RecentlyCrashedPluginsList")); + const File deadMansPedalFile (owner.appProperties.getUserSettings() + ->getFile().getSiblingFile ("RecentlyCrashedPluginsList")); setContentOwned (new PluginListComponent (formatManager, owner.knownPluginList, deadMansPedalFile, - getAppProperties().getUserSettings()), true); + owner.appProperties.getUserSettings()), true); + setOpaque (true); setResizable (true, false); setResizeLimits (300, 400, 800, 1500); setTopLeftPosition (60, 60); - restoreWindowStateFromString (getAppProperties().getUserSettings()->getValue ("listWindowPos")); + restoreWindowStateFromString (owner.appProperties.getUserSettings()->getValue ("listWindowPos")); + setUsingNativeTitleBar (true); setVisible (true); } ~PluginListWindow() { - getAppProperties().getUserSettings()->setValue ("listWindowPos", getWindowStateAsString()); + owner.appProperties.getUserSettings()->setValue ("listWindowPos", getWindowStateAsString()); clearContentComponent(); } @@ -71,44 +72,42 @@ private: }; //============================================================================== -MainHostWindow::MainHostWindow() - : DocumentWindow (JUCEApplication::getInstance()->getApplicationName(), Colours::lightgrey, - DocumentWindow::allButtons) +MainHostWindow::MainHostWindow (AudioPluginFormatManager& fm, FilterGraph& graph, ApplicationProperties& ap) + : DocumentWindow ("Juce Patchbay", Colours::lightgrey, DocumentWindow::allButtons), + formatManager (fm), + appProperties (ap), + closed (false) { - formatManager.addDefaultFormats(); - formatManager.addFormat (new InternalPluginFormat()); - - ScopedPointer savedAudioState (getAppProperties().getUserSettings() - ->getXmlValue ("audioDeviceState")); - - //deviceManager.initialise (256, 256, savedAudioState, true); + LookAndFeel::setDefaultLookAndFeel (&lookAndFeel); + setOpaque (true); setResizable (true, false); setResizeLimits (500, 400, 10000, 10000); centreWithSize (800, 600); - //setContentOwned (new GraphDocumentComponent (formatManager, &deviceManager), false); + setContentOwned (new GraphDocumentComponent (graph), false); + setUsingNativeTitleBar (true); - restoreWindowStateFromString (getAppProperties().getUserSettings()->getValue ("mainWindowPos")); + restoreWindowStateFromString (appProperties.getUserSettings()->getValue ("mainWindowPos")); setVisible (true); InternalPluginFormat internalFormat; internalFormat.getAllTypes (internalTypes); - ScopedPointer savedPluginList (getAppProperties().getUserSettings()->getXmlValue ("pluginList")); + ScopedPointer savedPluginList (appProperties.getUserSettings()->getXmlValue ("pluginList")); if (savedPluginList != nullptr) knownPluginList.recreateFromXml (*savedPluginList); - pluginSortMethod = (KnownPluginList::SortMethod) getAppProperties().getUserSettings() + pluginSortMethod = (KnownPluginList::SortMethod) appProperties.getUserSettings() ->getIntValue ("pluginSortMethod", KnownPluginList::sortByManufacturer); knownPluginList.addChangeListener (this); - addKeyListener (getCommandManager().getKeyMappings()); + addKeyListener (commandManager.getKeyMappings()); - Process::setPriority (Process::HighPriority); + //Process::setPriority (Process::HighPriority); #if JUCE_MAC setMacMainMenu (this); @@ -116,7 +115,10 @@ MainHostWindow::MainHostWindow() setMenuBar (this); #endif - getCommandManager().setFirstCommandTarget (this); + commandManager.setFirstCommandTarget (this); + commandManager.registerAllCommandsForTarget (this); + + menuItemsChanged(); } MainHostWindow::~MainHostWindow() @@ -131,27 +133,17 @@ MainHostWindow::~MainHostWindow() knownPluginList.removeChangeListener (this); - getAppProperties().getUserSettings()->setValue ("mainWindowPos", getWindowStateAsString()); + appProperties.getUserSettings()->setValue ("mainWindowPos", getWindowStateAsString()); clearContentComponent(); -} -void MainHostWindow::closeButtonPressed() -{ - tryToQuitApplication(); + LookAndFeel::setDefaultLookAndFeel (nullptr); } -bool MainHostWindow::tryToQuitApplication() +void MainHostWindow::closeButtonPressed() { - PluginWindow::closeAllCurrentlyOpenWindows(); + getGraphEditor()->closeAllCurrentlyOpenWindows(); - if (getGraphEditor() == nullptr - || getGraphEditor()->graph.saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk) - { - JUCEApplication::quit(); - return true; - } - - return false; + closed = true; } void MainHostWindow::changeListenerCallback (ChangeBroadcaster*) @@ -164,8 +156,8 @@ void MainHostWindow::changeListenerCallback (ChangeBroadcaster*) if (savedPluginList != nullptr) { - getAppProperties().getUserSettings()->setValue ("pluginList", savedPluginList); - getAppProperties().saveIfNeeded(); + appProperties.getUserSettings()->setValue ("pluginList", savedPluginList); + appProperties.saveIfNeeded(); } } @@ -183,20 +175,18 @@ PopupMenu MainHostWindow::getMenuForIndex (int topLevelMenuIndex, const String& if (topLevelMenuIndex == 0) { // "File" menu - menu.addCommandItem (&getCommandManager(), CommandIDs::open); + menu.addCommandItem (&commandManager, CommandIDs::open); RecentlyOpenedFilesList recentFiles; - recentFiles.restoreFromString (getAppProperties().getUserSettings() + recentFiles.restoreFromString (appProperties.getUserSettings() ->getValue ("recentFilterGraphFiles")); PopupMenu recentFilesMenu; recentFiles.createPopupMenuItems (recentFilesMenu, 100, true, true); menu.addSubMenu ("Open recent file", recentFilesMenu); - menu.addCommandItem (&getCommandManager(), CommandIDs::save); - menu.addCommandItem (&getCommandManager(), CommandIDs::saveAs); - menu.addSeparator(); - menu.addCommandItem (&getCommandManager(), StandardApplicationCommandIDs::quit); + menu.addCommandItem (&commandManager, CommandIDs::save); + menu.addCommandItem (&commandManager, CommandIDs::saveAs); } else if (topLevelMenuIndex == 1) { @@ -211,7 +201,7 @@ PopupMenu MainHostWindow::getMenuForIndex (int topLevelMenuIndex, const String& { // "Options" menu - menu.addCommandItem (&getCommandManager(), CommandIDs::showPluginListEditor); + menu.addCommandItem (&commandManager, CommandIDs::showPluginListEditor); PopupMenu sortTypeMenu; sortTypeMenu.addItem (200, "List plugins in default order", true, pluginSortMethod == KnownPluginList::defaultOrder); @@ -222,7 +212,7 @@ PopupMenu MainHostWindow::getMenuForIndex (int topLevelMenuIndex, const String& menu.addSubMenu ("Plugin menu type", sortTypeMenu); menu.addSeparator(); - menu.addCommandItem (&getCommandManager(), CommandIDs::aboutBox); + menu.addCommandItem (&commandManager, CommandIDs::aboutBox); } return menu; @@ -240,7 +230,7 @@ void MainHostWindow::menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/ else if (menuItemID >= 100 && menuItemID < 200) { RecentlyOpenedFilesList recentFiles; - recentFiles.restoreFromString (getAppProperties().getUserSettings() + recentFiles.restoreFromString (appProperties.getUserSettings() ->getValue ("recentFilterGraphFiles")); if (graphEditor != nullptr && graphEditor->graph.saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk) @@ -254,7 +244,7 @@ void MainHostWindow::menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/ else if (menuItemID == 203) pluginSortMethod = KnownPluginList::sortByManufacturer; else if (menuItemID == 204) pluginSortMethod = KnownPluginList::sortByFileSystemLocation; - getAppProperties().getUserSettings()->setValue ("pluginSortMethod", (int) pluginSortMethod); + appProperties.getUserSettings()->setValue ("pluginSortMethod", (int) pluginSortMethod); menuItemsChanged(); } @@ -437,3 +427,8 @@ GraphDocumentComponent* MainHostWindow::getGraphEditor() const { return dynamic_cast (getContentComponent()); } + +bool MainHostWindow::wasClosedByUser() const noexcept +{ + return closed; +} diff --git a/source/modules/daz-plugins/juce-host/MainHostWindow.h b/source/modules/daz-plugins/juce-host/MainHostWindow.h index dd02735de..7566ef550 100644 --- a/source/modules/daz-plugins/juce-host/MainHostWindow.h +++ b/source/modules/daz-plugins/juce-host/MainHostWindow.h @@ -36,7 +36,7 @@ namespace CommandIDs static const int save = 0x30001; static const int saveAs = 0x30002; static const int showPluginListEditor = 0x30100; - static const int aboutBox = 0x30300; + static const int aboutBox = 0x30200; } //============================================================================== @@ -50,7 +50,7 @@ class MainHostWindow : public DocumentWindow, { public: //============================================================================== - MainHostWindow(); + MainHostWindow (AudioPluginFormatManager& formatManager, FilterGraph& graph, ApplicationProperties& appProperties); ~MainHostWindow(); //============================================================================== @@ -71,8 +71,6 @@ public: void getCommandInfo (CommandID commandID, ApplicationCommandInfo& result); bool perform (const InvocationInfo& info); - bool tryToQuitApplication(); - void createPlugin (const PluginDescription* desc, int x, int y); void addPluginsToMenu (PopupMenu& m) const; @@ -80,10 +78,11 @@ public: GraphDocumentComponent* getGraphEditor() const; + bool wasClosedByUser() const noexcept; + private: //============================================================================== - //AudioDeviceManager deviceManager; - AudioPluginFormatManager formatManager; + AudioPluginFormatManager& formatManager; OwnedArray internalTypes; KnownPluginList knownPluginList; @@ -92,6 +91,12 @@ private: class PluginListWindow; ScopedPointer pluginListWindow; + ApplicationCommandManager commandManager; + ApplicationProperties& appProperties; + LookAndFeel_V3 lookAndFeel; + + bool closed; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainHostWindow) }; diff --git a/source/modules/daz-plugins/juce-patchbay.cpp b/source/modules/daz-plugins/juce-patchbay.cpp index 3f679ae30..c5ed028a2 100644 --- a/source/modules/daz-plugins/juce-patchbay.cpp +++ b/source/modules/daz-plugins/juce-patchbay.cpp @@ -20,8 +20,6 @@ #include "juce_audio_processors.h" #include "juce_gui_extra.h" -#include "JucePluginWindow.hpp" - using namespace juce; // ----------------------------------------------------------------------- @@ -29,6 +27,7 @@ using namespace juce; #include "juce-host/FilterGraph.h" #include "juce-host/InternalFilters.h" #include "juce-host/GraphEditorPanel.h" +#include "juce-host/MainHostWindow.h" // ----------------------------------------------------------------------- @@ -40,9 +39,17 @@ public: graph(formatManager), fAudioBuffer(1, 0) { + PropertiesFile::Options options; + options.applicationName = "Juce Audio Plugin Host"; + options.filenameSuffix = "settings"; + options.osxLibrarySubFolder = "Preferences"; + + fAppProperties = new ApplicationProperties(); + fAppProperties->setStorageParameters (options); + formatManager.addDefaultFormats(); formatManager.addFormat(new InternalPluginFormat()); - graph.ready(); + graph.ready(fAppProperties); graph.getGraph().setPlayConfigDetails(2, 2, getSampleRate(), static_cast(getBufferSize())); @@ -52,6 +59,7 @@ public: ~JucePatchbayPlugin() override { + fAppProperties = nullptr; } protected: @@ -70,13 +78,40 @@ protected: graph.getGraph().releaseResources(); } - void process(float** inBuffer, float** const outBuffer, const uint32_t frames, const NativeMidiEvent* const, const uint32_t) override + void process(float** inBuffer, float** const outBuffer, const uint32_t frames, const NativeMidiEvent* const midiEvents, const uint32_t midiEventCount) override { fAudioBuffer.copyFrom(0, 0, inBuffer[0], static_cast(frames)); fAudioBuffer.copyFrom(1, 0, inBuffer[1], static_cast(frames)); + fMidiBuffer.clear(); + + for (uint32_t i=0; i < midiEventCount; ++i) + { + const NativeMidiEvent* const midiEvent(&midiEvents[i]); + fMidiBuffer.addEvent(midiEvent->data, midiEvent->size, midiEvent->time); + } + graph.getGraph().processBlock(fAudioBuffer, fMidiBuffer); + MidiBuffer::Iterator outBufferIterator(fMidiBuffer); + const uint8_t* midiData; + int numBytes; + int sampleNumber; + + NativeMidiEvent tmpEvent; + tmpEvent.port = 0; + + for (; outBufferIterator.getNextEvent(midiData, numBytes, sampleNumber);) + { + if (numBytes <= 0 || numBytes > 4) + continue; + + tmpEvent.size = numBytes; + tmpEvent.time = sampleNumber; + + std::memcpy(tmpEvent.data, midiData, sizeof(uint8_t)*tmpEvent.size); + writeMidiEvent(&tmpEvent); + } FloatVectorOperations::copy(outBuffer[0], fAudioBuffer.getSampleData(0), static_cast(frames)); FloatVectorOperations::copy(outBuffer[1], fAudioBuffer.getSampleData(1), static_cast(frames)); } @@ -90,24 +125,14 @@ protected: { if (fWindow == nullptr) { - fWindow = new JucePluginWindow(); + fWindow = new MainHostWindow(formatManager, graph, *fAppProperties); fWindow->setName(getUiName()); - fWindow->setResizable(true, false); - } - - if (fComponent == nullptr) - { - fComponent = new GraphDocumentComponent(graph); - fComponent->setSize(300, 300); } - - fWindow->show(fComponent); + fWindow->toFront(true); } else if (fWindow != nullptr) { - fWindow->hide(); - - fComponent = nullptr; + fWindow->setVisible(false); fWindow = nullptr; } } @@ -131,12 +156,8 @@ private: AudioSampleBuffer fAudioBuffer; MidiBuffer fMidiBuffer; - ScopedPointer fComponent; - ScopedPointer fWindow; - - //OwnedArray internalTypes; - //KnownPluginList knownPluginList; - //KnownPluginList::SortMethod pluginSortMethod; + ScopedPointer fAppProperties; + ScopedPointer fWindow; PluginClassEND(JucePatchbayPlugin) CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JucePatchbayPlugin) @@ -177,5 +198,6 @@ void carla_register_native_plugin_jucePatchbay() #include "juce-host/FilterGraph.cpp" #include "juce-host/InternalFilters.cpp" #include "juce-host/GraphEditorPanel.cpp" +#include "juce-host/MainHostWindow.cpp" // ----------------------------------------------------------------------- diff --git a/source/modules/daz-plugins/vex-fx.cpp b/source/modules/daz-plugins/vex-fx.cpp index f80d953b1..588baee25 100644 --- a/source/modules/daz-plugins/vex-fx.cpp +++ b/source/modules/daz-plugins/vex-fx.cpp @@ -312,7 +312,7 @@ protected: NativeMidiEvent tmpEvent; tmpEvent.port = 0; - while (outBufferIterator.getNextEvent(midiData, numBytes, sampleNumber)) + for (; outBufferIterator.getNextEvent(midiData, numBytes, sampleNumber);) { if (numBytes <= 0 || numBytes > 4) continue;