From 14ef18c5b93a98b8b27b191aabd053408432edd6 Mon Sep 17 00:00:00 2001 From: reuk Date: Tue, 19 Aug 2025 19:59:47 +0100 Subject: [PATCH] NSViewComponentWithParent: Move to new file --- .../format_types/juce_LV2PluginFormat.cpp | 1 + .../format_types/juce_VST3PluginFormat.cpp | 1 + .../format_types/juce_VSTPluginFormat.cpp | 1 + .../juce_audio_processors.cpp | 97 ------------- .../juce_NSViewComponentWithParent.h | 131 ++++++++++++++++++ 5 files changed, 134 insertions(+), 97 deletions(-) create mode 100644 modules/juce_audio_processors/utilities/juce_NSViewComponentWithParent.h diff --git a/modules/juce_audio_processors/format_types/juce_LV2PluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_LV2PluginFormat.cpp index 1c85a00d36..80563cc5a8 100644 --- a/modules/juce_audio_processors/format_types/juce_LV2PluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_LV2PluginFormat.cpp @@ -36,6 +36,7 @@ #include #include +#include namespace juce { diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp index a0d7216559..a417045c53 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp @@ -35,6 +35,7 @@ #if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_BSD) #include +#include namespace juce { diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp index 11e921ed4b..4849054dcc 100644 --- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp @@ -35,6 +35,7 @@ #if JUCE_PLUGINHOST_VST #include +#include namespace juce { diff --git a/modules/juce_audio_processors/juce_audio_processors.cpp b/modules/juce_audio_processors/juce_audio_processors.cpp index 7ed671f56e..a099cc9e68 100644 --- a/modules/juce_audio_processors/juce_audio_processors.cpp +++ b/modules/juce_audio_processors/juce_audio_processors.cpp @@ -69,103 +69,6 @@ #include #endif -namespace juce -{ - -#if JUCE_MAC - -//============================================================================== -/* This is an NSViewComponent which holds a long-lived NSView which acts - as the parent view for plugin editors. - - Note that this component does not auto-resize depending on the bounds - of the owned view. VST2 and VST3 plugins have dedicated interfaces to - request that the editor bounds are updated. We can call `setSize` on this - component from inside those dedicated callbacks. -*/ -struct NSViewComponentWithParent : public NSViewComponent, - private AsyncUpdater -{ - enum class WantsNudge { no, yes }; - - explicit NSViewComponentWithParent (WantsNudge shouldNudge) - : wantsNudge (shouldNudge) - { - auto* view = [[getViewClass().createInstance() init] autorelease]; - object_setInstanceVariable (view, "owner", this); - setView (view); - } - - explicit NSViewComponentWithParent (AudioPluginInstance& instance) - : NSViewComponentWithParent (getWantsNudge (instance)) {} - - ~NSViewComponentWithParent() override - { - if (auto* view = static_cast (getView())) - object_setInstanceVariable (view, "owner", nullptr); - - cancelPendingUpdate(); - } - - JUCE_DECLARE_NON_COPYABLE (NSViewComponentWithParent) - JUCE_DECLARE_NON_MOVEABLE (NSViewComponentWithParent) - -private: - WantsNudge wantsNudge = WantsNudge::no; - - static WantsNudge getWantsNudge (AudioPluginInstance& instance) - { - PluginDescription pd; - instance.fillInPluginDescription (pd); - return pd.manufacturerName == "FabFilter" ? WantsNudge::yes : WantsNudge::no; - } - - void handleAsyncUpdate() override - { - if (auto* peer = getTopLevelComponent()->getPeer()) - { - auto* view = static_cast (getView()); - const auto newArea = peer->getAreaCoveredBy (*this); - [view setFrame: makeCGRect (newArea.withHeight (newArea.getHeight() + 1))]; - [view setFrame: makeCGRect (newArea)]; - } - } - - struct InnerNSView final : public ObjCClass - { - InnerNSView() - : ObjCClass ("JuceInnerNSView_") - { - addIvar ("owner"); - - addMethod (@selector (isOpaque), [] (id, SEL) { return YES; }); - - addMethod (@selector (didAddSubview:), [] (id self, SEL, NSView*) - { - if (auto* owner = getIvar (self, "owner")) - if (owner->wantsNudge == WantsNudge::yes) - owner->triggerAsyncUpdate(); - }); - - JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") - addMethod (@selector (clipsToBounds), [] (id, SEL) { return YES; }); - JUCE_END_IGNORE_WARNINGS_GCC_LIKE - - registerClass(); - } - }; - - static InnerNSView& getViewClass() - { - static InnerNSView result; - return result; - } -}; - -#endif - -} // namespace juce - #include "format/juce_AudioPluginFormatManagerHelpers.cpp" #include "processors/juce_AudioProcessorEditor.cpp" #include "processors/juce_GenericAudioProcessorEditor.cpp" diff --git a/modules/juce_audio_processors/utilities/juce_NSViewComponentWithParent.h b/modules/juce_audio_processors/utilities/juce_NSViewComponentWithParent.h new file mode 100644 index 0000000000..128e873d5f --- /dev/null +++ b/modules/juce_audio_processors/utilities/juce_NSViewComponentWithParent.h @@ -0,0 +1,131 @@ +/* + ============================================================================== + + This file is part of the JUCE framework. + Copyright (c) Raw Material Software Limited + + JUCE is an open source framework subject to commercial or open source + licensing. + + By downloading, installing, or using the JUCE framework, or combining the + JUCE framework with any other source code, object code, content or any other + copyrightable work, you agree to the terms of the JUCE End User Licence + Agreement, and all incorporated terms including the JUCE Privacy Policy and + the JUCE Website Terms of Service, as applicable, which will bind you. If you + do not agree to the terms of these agreements, we will not license the JUCE + framework to you, and you must discontinue the installation or download + process and cease use of the JUCE framework. + + JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/ + JUCE Privacy Policy: https://juce.com/juce-privacy-policy + JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/ + + Or: + + You may also use this code under the terms of the AGPLv3: + https://www.gnu.org/licenses/agpl-3.0.en.html + + THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL + WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + +#if JUCE_MAC + +namespace juce +{ + +/* This is an NSViewComponent which holds a long-lived NSView which acts + as the parent view for plugin editors. + + Note that this component does not auto-resize depending on the bounds + of the owned view. VST2 and VST3 plugins have dedicated interfaces to + request that the editor bounds are updated. We can call `setSize` on this + component from inside those dedicated callbacks. +*/ +struct NSViewComponentWithParent : public NSViewComponent, + private AsyncUpdater +{ + enum class WantsNudge { no, yes }; + + explicit NSViewComponentWithParent (WantsNudge shouldNudge) + : wantsNudge (shouldNudge) + { + auto* view = [[getViewClass().createInstance() init] autorelease]; + object_setInstanceVariable (view, "owner", this); + setView (view); + } + + explicit NSViewComponentWithParent (AudioPluginInstance& instance) + : NSViewComponentWithParent (getWantsNudge (instance)) {} + + ~NSViewComponentWithParent() override + { + if (auto* view = static_cast (getView())) + object_setInstanceVariable (view, "owner", nullptr); + + cancelPendingUpdate(); + } + + JUCE_DECLARE_NON_COPYABLE (NSViewComponentWithParent) + JUCE_DECLARE_NON_MOVEABLE (NSViewComponentWithParent) + +private: + WantsNudge wantsNudge = WantsNudge::no; + + static WantsNudge getWantsNudge (AudioPluginInstance& instance) + { + PluginDescription pd; + instance.fillInPluginDescription (pd); + return pd.manufacturerName == "FabFilter" ? WantsNudge::yes : WantsNudge::no; + } + + void handleAsyncUpdate() override + { + if (auto* peer = getTopLevelComponent()->getPeer()) + { + auto* view = static_cast (getView()); + const auto newArea = peer->getAreaCoveredBy (*this); + [view setFrame: makeCGRect (newArea.withHeight (newArea.getHeight() + 1))]; + [view setFrame: makeCGRect (newArea)]; + } + } + + struct InnerNSView final : public ObjCClass + { + InnerNSView() + : ObjCClass ("JuceInnerNSView_") + { + addIvar ("owner"); + + addMethod (@selector (isOpaque), [] (id, SEL) { return YES; }); + + addMethod (@selector (didAddSubview:), [] (id self, SEL, NSView*) + { + if (auto* owner = getIvar (self, "owner")) + if (owner->wantsNudge == WantsNudge::yes) + owner->triggerAsyncUpdate(); + }); + + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") + addMethod (@selector (clipsToBounds), [] (id, SEL) { return YES; }); + JUCE_END_IGNORE_WARNINGS_GCC_LIKE + + registerClass(); + } + }; + + static InnerNSView& getViewClass() + { + static InnerNSView result; + return result; + } +}; + +} // namespace juce + +#endif