1//------------------------------------------------------------------------ 2// Project : VST SDK 3// 4// Category : Helpers 5// Filename : public.sdk/source/vst/auwrapper/aucocoaview.mm 6// Created by : Steinberg, 12/2007 7// Description : VST 3 -> AU Wrapper 8// 9//----------------------------------------------------------------------------- 10// LICENSE 11// (c) 2020, Steinberg Media Technologies GmbH, All Rights Reserved 12//----------------------------------------------------------------------------- 13// Redistribution and use in source and binary forms, with or without modification, 14// are permitted provided that the following conditions are met: 15// 16// * Redistributions of source code must retain the above copyright notice, 17// this list of conditions and the following disclaimer. 18// * Redistributions in binary form must reproduce the above copyright notice, 19// this list of conditions and the following disclaimer in the documentation 20// and/or other materials provided with the distribution. 21// * Neither the name of the Steinberg Media Technologies nor the names of its 22// contributors may be used to endorse or promote products derived from this 23// software without specific prior written permission. 24// 25// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 29// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 30// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 33// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 34// OF THE POSSIBILITY OF SUCH DAMAGE. 35//----------------------------------------------------------------------------- 36 37/// \cond ignore 38 39#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 40 41#import "aucocoaview.h" 42#import "auwrapper.h" 43#import "pluginterfaces/vst/ivsteditcontroller.h" 44#import "pluginterfaces/gui/iplugview.h" 45#import "base/source/fobject.h" 46 47namespace Steinberg { 48 49//------------------------------------------------------------------------ 50class AUPlugFrame : public FObject, public IPlugFrame 51//------------------------------------------------------------------------ 52{ 53public: 54 AUPlugFrame (NSView* parent) : parent (parent) {} 55 tresult PLUGIN_API resizeView (IPlugView* view, ViewRect* vr) SMTG_OVERRIDE 56 { 57 NSRect newSize = NSMakeRect ([parent frame].origin.x, [parent frame].origin.y, vr->right - vr->left, vr->bottom - vr->top); 58 [parent setFrame:newSize]; 59 return kResultTrue; 60 } 61 62 OBJ_METHODS(AUPlugFrame, FObject) 63 DEF_INTERFACES_1(IPlugFrame, FObject) 64 REFCOUNT_METHODS(FObject) 65protected: 66 NSView* parent; 67}; 68 69} // namespace Steinberg 70 71using namespace Steinberg; 72 73//------------------------------------------------------------------------ 74#define SMTGCocoa_NSViewWrapperForAU SMTG_AU_PLUGIN_NAMESPACE (NSViewWrapperForAU) 75 76//------------------------------------------------------------------------ 77@interface SMTGCocoa_NSViewWrapperForAU : NSView { 78//------------------------------------------------------------------------ 79 IPlugView* plugView; 80 Vst::IEditController* editController; 81 AudioUnit audioUnit; 82 FObject* dynlib; 83 AUPlugFrame* plugFrame; 84 85 BOOL isAttached; 86} 87 88- (id) initWithEditController: (Vst::IEditController*) editController audioUnit: (AudioUnit) au preferredSize: (NSSize) size; 89 90@end 91 92//------------------------------------------------------------------------ 93// SMTG_AU_PLUGIN_NAMESPACE (SMTGAUPluginCocoaView) 94//------------------------------------------------------------------------ 95 96//------------------------------------------------------------------------ 97@implementation SMTG_AU_PLUGIN_NAMESPACE (SMTGAUPluginCocoaView) 98 99//------------------------------------------------------------------------ 100- (unsigned) interfaceVersion 101{ 102 return 0; 103} 104 105//------------------------------------------------------------------------ 106- (NSString *) description 107{ 108 return @"Cocoa View"; 109} 110 111//------------------------------------------------------------------------ 112- (NSView *)uiViewForAudioUnit:(AudioUnit)inAU withSize:(NSSize)inPreferredSize 113{ 114 Vst::IEditController* editController = 0; 115 UInt32 size = sizeof (Vst::IEditController*); 116 if (AudioUnitGetProperty (inAU, 64000, kAudioUnitScope_Global, 0, &editController, &size) != noErr) 117 return nil; 118 return [[[SMTGCocoa_NSViewWrapperForAU alloc] initWithEditController:editController audioUnit:inAU preferredSize:inPreferredSize] autorelease]; 119} 120 121@end 122 123//------------------------------------------------------------------------ 124@implementation SMTGCocoa_NSViewWrapperForAU 125//------------------------------------------------------------------------ 126- (id) initWithEditController: (Vst::IEditController*) _editController audioUnit: (AudioUnit) au preferredSize: (NSSize) size 127{ 128 self = [super initWithFrame: NSMakeRect (0, 0, size.width, size.height)]; 129 if (self) 130 { 131 editController = _editController; 132 editController->addRef (); 133 audioUnit = au; 134 plugView = editController->createView (Vst::ViewType::kEditor); 135 if (!plugView || plugView->isPlatformTypeSupported (kPlatformTypeNSView) != kResultTrue) 136 { 137 [self dealloc]; 138 return nil; 139 } 140 141 plugFrame = NEW AUPlugFrame (self); 142 plugView->setFrame (plugFrame); 143 144 if (plugView->attached (self, kPlatformTypeNSView) != kResultTrue) 145 { 146 [self dealloc]; 147 return nil; 148 } 149 ViewRect vr; 150 if (plugView->getSize (&vr) == kResultTrue) 151 { 152 NSRect newSize = NSMakeRect (0, 0, vr.right - vr.left, vr.bottom - vr.top); 153 [self setFrame:newSize]; 154 } 155 156 isAttached = YES; 157 UInt32 size = sizeof (FObject*); 158 if (AudioUnitGetProperty (audioUnit, 64001, kAudioUnitScope_Global, 0, &dynlib, &size) == noErr) 159 dynlib->addRef (); 160 } 161 return self; 162} 163 164 165//------------------------------------------------------------------------ 166- (void) setFrame: (NSRect) newSize 167{ 168 [super setFrame: newSize]; 169 ViewRect viewRect (0, 0, newSize.size.width, newSize.size.height); 170 171 if (plugView) 172 plugView->onSize (&viewRect); 173} 174 175 176//------------------------------------------------------------------------ 177- (BOOL)isFlipped { return YES; } 178 179//------------------------------------------------------------------------ 180- (void)viewDidMoveToSuperview 181{ 182 if (plugView) 183 { 184 if ([self superview]) 185 { 186 if (!isAttached) 187 { 188 isAttached = plugView->attached (self, kPlatformTypeNSView) == kResultTrue; 189 } 190 } 191 else 192 { 193 if (isAttached) 194 { 195 plugView->removed (); 196 isAttached = NO; 197 } 198 } 199 } 200} 201 202//------------------------------------------------------------------------ 203- (void) dealloc 204{ 205 if (plugView) 206 { 207 if (isAttached) 208 { 209 plugView->setFrame (0); 210 plugView->removed (); 211 } 212 plugView->release (); 213 if (plugFrame) 214 plugFrame->release (); 215 216 if (editController) 217 { 218 Steinberg::uint32 refCount= editController->addRef (); 219 if (refCount == 2) 220 editController->terminate (); 221 222 editController->release (); 223 editController->release (); 224 editController = 0; 225 } 226 } 227 if (dynlib) 228 dynlib->release (); 229 [super dealloc]; 230} 231 232@end 233 234/// \endcond 235