276 lines
8.4 KiB
Plaintext
276 lines
8.4 KiB
Plaintext
//------------------------------------------------------------------------
|
|
// Project : VST SDK
|
|
//
|
|
// Category : Helpers
|
|
// Filename : public.sdk/source/vst/auwrapper/aucocoaview.mm
|
|
// Created by : Steinberg, 12/2007
|
|
// Description : VST 3 -> AU Wrapper
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// This file is part of a Steinberg SDK. It is subject to the license terms
|
|
// in the LICENSE file found in the top-level directory of this distribution
|
|
// and at www.steinberg.net/sdklicenses.
|
|
// No part of the SDK, including this file, may be copied, modified, propagated,
|
|
// or distributed except according to the terms contained in the LICENSE file.
|
|
//-----------------------------------------------------------------------------
|
|
/// \cond ignore
|
|
|
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
|
|
#import "aucocoaview.h"
|
|
#import "auwrapper.h"
|
|
#import "public.sdk/source/vst/utility/objcclassbuilder.h"
|
|
#import "pluginterfaces/base/funknownimpl.h"
|
|
#import "pluginterfaces/gui/iplugview.h"
|
|
#import "pluginterfaces/vst/ivsteditcontroller.h"
|
|
|
|
//------------------------------------------------------------------------
|
|
@interface NSObject (SMTG_AUView)
|
|
- (id)initWithEditController:(Steinberg::Vst::IEditController*)editController
|
|
audioUnit:(AudioUnit)au
|
|
preferredSize:(NSSize)size;
|
|
@end
|
|
|
|
//------------------------------------------------------------------------
|
|
namespace Steinberg {
|
|
namespace {
|
|
|
|
//------------------------------------------------------------------------
|
|
struct AUPlugFrame : U::Implements<U::Directly<IPlugFrame>>
|
|
{
|
|
AUPlugFrame (NSView* parent) : parent (parent) {}
|
|
tresult PLUGIN_API resizeView (IPlugView* view, ViewRect* vr) override
|
|
{
|
|
NSRect newSize = NSMakeRect ([parent frame].origin.x, [parent frame].origin.y,
|
|
vr->right - vr->left, vr->bottom - vr->top);
|
|
[parent setFrame:newSize];
|
|
return kResultTrue;
|
|
}
|
|
|
|
NSView* parent;
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
struct AUView
|
|
{
|
|
static constexpr auto VarNamePlugView = "plugView";
|
|
static constexpr auto VarNameEditController = "editController";
|
|
static constexpr auto VarNameAudioUnit = "audioUnit";
|
|
static constexpr auto VarNameDynlib = "dynlib";
|
|
static constexpr auto VarNamePlugFrame = "plugFrame";
|
|
static constexpr auto VarNameIsAttached = "isAttached";
|
|
|
|
struct Instance : ObjCInstance
|
|
{
|
|
using PlugViewVar = std::optional<ObjCVariable<IPlugView*>>;
|
|
using EditControllerVar = std::optional<ObjCVariable<Vst::IEditController*>>;
|
|
using AudioUnitVar = std::optional<ObjCVariable<AudioUnit>>;
|
|
using DynlibVar = std::optional<ObjCVariable<FObject*>>;
|
|
using PlugFrameVar = std::optional<ObjCVariable<AUPlugFrame*>>;
|
|
using IsAttachedVar = std::optional<ObjCVariable<BOOL>>;
|
|
|
|
Instance (__unsafe_unretained id obj) : ObjCInstance (obj, [NSView class])
|
|
{
|
|
plugView = getVariable<IPlugView*> (VarNamePlugView);
|
|
editController = getVariable<Vst::IEditController*> (VarNameEditController);
|
|
audioUnit = getVariable<AudioUnit> (VarNamePlugView);
|
|
dynlib = getVariable<FObject*> (VarNameDynlib);
|
|
plugFrame = getVariable<AUPlugFrame*> (VarNamePlugFrame);
|
|
isAttached = getVariable<BOOL> (VarNameIsAttached);
|
|
}
|
|
|
|
PlugViewVar plugView;
|
|
EditControllerVar editController;
|
|
AudioUnitVar audioUnit;
|
|
DynlibVar dynlib;
|
|
PlugFrameVar plugFrame;
|
|
IsAttachedVar isAttached;
|
|
};
|
|
|
|
static id alloc ()
|
|
{
|
|
static ObjCClass gInstance;
|
|
return [gInstance.cl alloc];
|
|
}
|
|
|
|
private:
|
|
struct ObjCClass
|
|
{
|
|
Class cl;
|
|
|
|
ObjCClass ()
|
|
{
|
|
cl = ObjCClassBuilder ()
|
|
.init ("SMTG_AUView", [NSView class])
|
|
.addIvar<IPlugView*> (VarNamePlugView)
|
|
.addIvar<Vst::IEditController*> (VarNameEditController)
|
|
.addIvar<AudioUnit> (VarNameAudioUnit)
|
|
.addIvar<FObject*> (VarNameDynlib)
|
|
.addIvar<AUPlugFrame*> (VarNamePlugFrame)
|
|
.addIvar<BOOL> (VarNameIsAttached)
|
|
.addMethod (@selector (initWithEditController:audioUnit:preferredSize:),
|
|
initWithEditController)
|
|
.addMethod (@selector (setFrame:), setFrame)
|
|
.addMethod (@selector (isFlipped), isFlipped)
|
|
.addMethod (@selector (viewDidMoveToSuperview), viewDidMoveToSuperview)
|
|
.addMethod (@selector (dealloc), dealloc)
|
|
.finalize ();
|
|
}
|
|
|
|
static id initWithEditController (id self, SEL cmd, Vst::IEditController* editController,
|
|
AudioUnit au, NSSize size)
|
|
{
|
|
ObjCInstance obj (self);
|
|
self = obj.callSuper<id (NSRect), id> (@selector (initWithFrame:),
|
|
NSMakeRect (0, 0, size.width, size.height));
|
|
if (self)
|
|
{
|
|
Instance inst (self);
|
|
inst.editController->set (editController);
|
|
editController->addRef ();
|
|
inst.audioUnit->set (au);
|
|
auto plugView = editController->createView (Vst::ViewType::kEditor);
|
|
if (!plugView ||
|
|
plugView->isPlatformTypeSupported (kPlatformTypeNSView) != kResultTrue)
|
|
{
|
|
[self dealloc];
|
|
return nil;
|
|
}
|
|
inst.plugView->set (plugView);
|
|
auto plugFrame = NEW AUPlugFrame (self);
|
|
inst.plugFrame->set (plugFrame);
|
|
plugView->setFrame (plugFrame);
|
|
|
|
if (plugView->attached (self, kPlatformTypeNSView) != kResultTrue)
|
|
{
|
|
[self dealloc];
|
|
return nil;
|
|
}
|
|
ViewRect vr;
|
|
if (plugView->getSize (&vr) == kResultTrue)
|
|
{
|
|
NSRect newSize = NSMakeRect (0, 0, vr.right - vr.left, vr.bottom - vr.top);
|
|
[self setFrame:newSize];
|
|
}
|
|
inst.isAttached->set (YES);
|
|
FObject* fObject = nullptr;
|
|
UInt32 size = sizeof (FObject*);
|
|
if (AudioUnitGetProperty (au, 64001, kAudioUnitScope_Global, 0, &fObject, &size) ==
|
|
noErr)
|
|
{
|
|
fObject->addRef ();
|
|
inst.dynlib->set (fObject);
|
|
}
|
|
}
|
|
return self;
|
|
}
|
|
|
|
static void setFrame (id self, SEL cmd, NSRect newSize)
|
|
{
|
|
Instance inst (self);
|
|
inst.callSuper<void (NSRect)> (@selector (setFrame:), newSize);
|
|
ViewRect viewRect (0, 0, newSize.size.width, newSize.size.height);
|
|
|
|
if (inst.plugView->get ())
|
|
inst.plugView->get ()->onSize (&viewRect);
|
|
}
|
|
|
|
static BOOL isFlipped (id self, SEL cmd) { return YES; }
|
|
|
|
static void viewDidMoveToSuperview (id self, SEL cmd)
|
|
{
|
|
Instance inst (self);
|
|
if (inst.plugView->get ())
|
|
{
|
|
if ([self superview])
|
|
{
|
|
if (!inst.isAttached->get ())
|
|
{
|
|
if (inst.plugView->get ()->attached (self, kPlatformTypeNSView) ==
|
|
kResultTrue)
|
|
{
|
|
inst.isAttached->set (YES);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (inst.isAttached->get ())
|
|
{
|
|
inst.plugView->get ()->removed ();
|
|
inst.isAttached->set (NO);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void dealloc (id self, SEL cmd)
|
|
{
|
|
Instance inst (self);
|
|
if (auto plugView = inst.plugView->get ())
|
|
{
|
|
if (inst.isAttached->get ())
|
|
{
|
|
plugView->setFrame (0);
|
|
plugView->removed ();
|
|
}
|
|
plugView->release ();
|
|
if (auto plugFrame = inst.plugFrame->get ())
|
|
plugFrame->release ();
|
|
|
|
if (auto editController = inst.editController->get ())
|
|
{
|
|
auto refCount = editController->addRef ();
|
|
if (refCount == 2)
|
|
editController->terminate ();
|
|
|
|
editController->release ();
|
|
editController->release ();
|
|
inst.editController->set (nullptr);
|
|
}
|
|
}
|
|
if (auto dynlib = inst.dynlib->get ())
|
|
dynlib->release ();
|
|
inst.callSuper<void ()> (@selector (dealloc));
|
|
}
|
|
};
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
} // anonymous
|
|
} // Steinberg
|
|
|
|
//------------------------------------------------------------------------
|
|
@implementation SMTG_AUCocoaUIBase_CLASS_NAME
|
|
|
|
//------------------------------------------------------------------------
|
|
- (unsigned)interfaceVersion
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
- (NSString*)description
|
|
{
|
|
return @"Cocoa View";
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
- (NSView*)uiViewForAudioUnit:(AudioUnit)inAU withSize:(NSSize)inPreferredSize
|
|
{
|
|
using namespace Steinberg;
|
|
|
|
Vst::IEditController* editController = 0;
|
|
UInt32 size = sizeof (Vst::IEditController*);
|
|
if (AudioUnitGetProperty (inAU, 64000, kAudioUnitScope_Global, 0, &editController, &size) !=
|
|
noErr)
|
|
return nil;
|
|
return [[AUView::alloc () initWithEditController:editController
|
|
audioUnit:inAU
|
|
preferredSize:inPreferredSize] autorelease];
|
|
}
|
|
|
|
@end
|
|
|
|
/// \endcond
|