1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Refactored some NSView wrapper classes. Should fix some plugin host window resizing issues.

This commit is contained in:
jules 2014-02-13 21:53:11 +00:00
parent b153a92bae
commit f3cca83dc8
4 changed files with 116 additions and 53 deletions

View file

@ -1220,7 +1220,6 @@ public:
#if JUCE_MAC
dummyComponent.setView (nullptr);
[pluginHandle release];
#endif
view = nullptr;
@ -1337,14 +1336,14 @@ private:
ScopedPointer<ComponentPeer> peer;
typedef HWND HandleFormat;
#elif JUCE_MAC
NSViewComponent dummyComponent;
AutoResizingNSViewComponentWithParent dummyComponent;
typedef NSView* HandleFormat;
#else
Component dummyComponent;
typedef void* HandleFormat;
#endif
HandleFormat pluginHandle; // Don't delete this
HandleFormat pluginHandle;
bool recursiveResize;
//==============================================================================
@ -1370,8 +1369,8 @@ private:
#elif JUCE_MAC
dummyComponent.setBounds (getBounds().withZeroOrigin());
addAndMakeVisible (dummyComponent);
pluginHandle = [[NSView alloc] init];
dummyComponent.setView (pluginHandle);
pluginHandle = (NSView*) dummyComponent.getView();
jassert (pluginHandle != nil);
#endif
if (pluginHandle != nullptr)

View file

@ -1927,17 +1927,10 @@ public:
#elif JUCE_MAC
#if JUCE_SUPPORT_CARBON
if (! plug.usesCocoaNSView)
{
addAndMakeVisible (carbonWrapper = new CarbonWrapperComponent (*this));
}
else
#endif
{
addAndMakeVisible (cocoaWrapper = new AutoResizingNSViewComponent());
NSView* innerView = [[NSView alloc] init];
cocoaWrapper->setView (innerView);
[innerView release];
}
addAndMakeVisible (cocoaWrapper = new AutoResizingNSViewComponentWithParent());
#endif
activeVSTWindows.add (this);
@ -2600,7 +2593,7 @@ private:
ScopedPointer<CarbonWrapperComponent> carbonWrapper;
#endif
ScopedPointer<NSViewComponent> cocoaWrapper;
ScopedPointer<AutoResizingNSViewComponentWithParent> cocoaWrapper;
void resized() override
{

View file

@ -77,6 +77,7 @@ static inline bool arrayContainsPlugin (const OwnedArray<PluginDescription>& lis
}
#if JUCE_MAC
//==============================================================================
struct AutoResizingNSViewComponent : public NSViewComponent,
private AsyncUpdater
{
@ -100,6 +101,38 @@ struct AutoResizingNSViewComponent : public NSViewComponent,
bool recursive;
};
//==============================================================================
struct AutoResizingNSViewComponentWithParent : public AutoResizingNSViewComponent,
private Timer
{
AutoResizingNSViewComponentWithParent()
{
NSView* v = [[NSView alloc] init];
setView (v);
[v release];
startTimer (100);
}
void timerCallback() override
{
if (NSView* parent = (NSView*) getView())
{
if (NSView* child = [[parent subviews] firstObject])
{
NSRect f = [parent frame];
NSSize newSize = [child frame].size;
if (f.size.width != newSize.width || f.size.height != newSize.height)
{
f.size = newSize;
[parent setFrame: f];
}
}
}
}
};
#endif
#if JUCE_CLANG

View file

@ -22,14 +22,82 @@
==============================================================================
*/
struct NSViewResizeWatcher
{
NSViewResizeWatcher() : callback (nil) {}
virtual ~NSViewResizeWatcher()
{
// must call detachViewWatcher() first
jassert (callback == nil);
}
void attachViewWatcher (NSView* view)
{
static ViewFrameChangeCallbackClass cls;
callback = [cls.createInstance() init];
ViewFrameChangeCallbackClass::setTarget (callback, this);
[[NSNotificationCenter defaultCenter] addObserver: callback
selector: @selector (frameChanged:)
name: NSViewFrameDidChangeNotification
object: view];
}
void detachViewWatcher()
{
if (callback != nil)
{
[[NSNotificationCenter defaultCenter] removeObserver: callback];
[callback release];
callback = nil;
}
}
virtual void viewResized() = 0;
private:
id callback;
//==============================================================================
struct ViewFrameChangeCallbackClass : public ObjCClass<NSObject>
{
ViewFrameChangeCallbackClass() : ObjCClass<NSObject> ("JUCE_NSViewCallback_")
{
addIvar<NSViewResizeWatcher*> ("target");
addMethod (@selector (frameChanged:), frameChanged, "v@:@");
registerClass();
}
static void setTarget (id self, NSViewResizeWatcher* c)
{
object_setInstanceVariable (self, "target", c);
}
private:
static void frameChanged (id self, SEL, NSNotification*)
{
if (NSViewResizeWatcher* const target = getIvar<NSViewResizeWatcher*> (self, "target"))
target->viewResized();
}
JUCE_DECLARE_NON_COPYABLE (ViewFrameChangeCallbackClass);
};
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NSViewResizeWatcher)
};
//==============================================================================
class NSViewAttachment : public ReferenceCountedObject,
public ComponentMovementWatcher
public ComponentMovementWatcher,
private NSViewResizeWatcher
{
public:
NSViewAttachment (NSView* const v, Component& comp)
: ComponentMovementWatcher (&comp),
view (v), owner (comp),
currentPeer (nullptr), frameChangeCallback (nullptr)
currentPeer (nullptr)
{
[view retain];
[view setPostsFrameChangedNotifications: YES];
@ -37,21 +105,12 @@ public:
if (owner.isShowing())
componentPeerChanged();
static ViewFrameChangeCallbackClass cls;
frameChangeCallback = [cls.createInstance() init];
ViewFrameChangeCallbackClass::setTarget (frameChangeCallback, &owner);
[[NSNotificationCenter defaultCenter] addObserver: frameChangeCallback
selector: @selector (frameChanged:)
name: NSViewFrameDidChangeNotification
object: view];
attachViewWatcher (view);
}
~NSViewAttachment()
{
[[NSNotificationCenter defaultCenter] removeObserver: frameChangeCallback];
[frameChangeCallback release];
detachViewWatcher();
removeFromParent();
[view release];
}
@ -103,12 +162,16 @@ public:
componentPeerChanged();
}
void viewResized() override
{
owner.childBoundsChanged (nullptr);
}
NSView* const view;
private:
Component& owner;
ComponentPeer* currentPeer;
id frameChangeCallback;
void removeFromParent()
{
@ -117,31 +180,6 @@ private:
// override the call and use it as a sign that they're being deleted, which breaks everything..
}
//==============================================================================
struct ViewFrameChangeCallbackClass : public ObjCClass<NSObject>
{
ViewFrameChangeCallbackClass() : ObjCClass<NSObject> ("JUCE_NSViewCallback_")
{
addIvar<Component*> ("target");
addMethod (@selector (frameChanged:), frameChanged, "v@:@");
registerClass();
}
static void setTarget (id self, Component* c)
{
object_setInstanceVariable (self, "target", c);
}
private:
static void frameChanged (id self, SEL, NSNotification*)
{
if (Component* const target = getIvar<Component*> (self, "target"))
target->childBoundsChanged (nullptr);
}
JUCE_DECLARE_NON_COPYABLE (ViewFrameChangeCallbackClass);
};
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NSViewAttachment)
};