Can someone help me translating this from Carbon to Cocoa?

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

Hello everyone,

I'm doing some tests wrapping one of my plug-ins into a standalone application (statically compiled, not loading the plugin as a dynamic lib), I've got it to work on Windows, my plug-in GUI shows up and responds correctly to the user interactions and the audio processing works fine using RTAudio.

Now, my problem is that I've never coded on OSX using their GUI API so I'm having a hard time to do the same thing on Mac.
So far I've been able to make it work using Carbon and pretty much doing the same thing as the minieditor.cpp in the MiniHost project bundled into the VST2.4 SDK, but since Carbon has been ditched I'd like to create a simple wrapper using Cocoa too, but I have pretty much zero experience with it.

The idea would be to just create the NSWindow to be supplied to the GUI library (my framework uses VSTGUI for this) for drawing and then running a timer thread that calls my editor's idle() function in order to redraw when needed, then destroying and cleaning up everything as soon as the GUI is closed.

This is the actual code for the Carbon version:

Code: Select all

#include "../StandalonePlugInWrapper.h"

#include "graphics/editors/types/AudioApplicationEditor.h"

#include <CoreFoundation/CoreFoundation.h>
#include <Carbon/Carbon.h>
#include <stdio.h>

namespace VSTGUI
{
    void* gBundleRef = CFBundleGetMainBundle ();
}

static OSStatus windowHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void* inUserData);
static void idleTimerProc(EventLoopTimerRef inTimer, void* inUserData);

bool checkEffectEditor(StandalonePlugInWrapper* applicationWrapper)
{
	if (!applicationWrapper->getAudioApplication()->hasEditor())
	{
		printf("This application does not have an editor!\n");
		return false;
	}

	AudioApplicationEditor* editor = applicationWrapper->getAudioApplication()->getEditor();

	WindowRef window;
	Rect mRect = { 0, 0, 300, 300 };
	OSStatus err = CreateNewWindow(kDocumentWindowClass, kWindowCloseBoxAttribute | kWindowCompositingAttribute | kWindowAsyncDragAttribute | kWindowStandardHandlerAttribute, &mRect, &window);
	
	if (err != noErr)
	{
		printf("HOST> Could not create mac window !\n");
		return false;
	}

	static EventTypeSpec eventTypes[] = {
		{ kEventClassWindow, kEventWindowClose }
	};

	InstallWindowEventHandler(window, windowHandler, GetEventTypeCount(eventTypes), eventTypes, window, NULL);

	printf("HOST> Open editor...\n");
	editor->open(window);

	printf("HOST> Get editor rect..\n");

	if (editor)
	{
		int width = editor->getWidth();
		int height = editor->getHeight();

		Rect bounds;
		GetWindowBounds(window, kWindowContentRgn, &bounds);
		
		bounds.right = bounds.left + width;
		bounds.bottom = bounds.top + height;
		
		SetWindowBounds(window, kWindowContentRgn, &bounds);
	}

	RepositionWindow(window, NULL, kWindowCenterOnMainScreen);
	ShowWindow(window);

	EventLoopTimerRef idleEventLoopTimer;
	InstallEventLoopTimer(GetCurrentEventLoop(), kEventDurationSecond / 25., kEventDurationSecond / 25., idleTimerProc, applicationWrapper, &idleEventLoopTimer);

	RunAppModalLoopForWindow(window);
	RemoveEventLoopTimer(idleEventLoopTimer);

	printf("HOST> Close editor..\n");
	editor->close();

	ReleaseWindow(window);

	applicationWrapper->requestTermination();

	return true;
}

void idleTimerProc(EventLoopTimerRef inTimer, void *inUserData)
{
	AudioApplicationEditor* editor = ((StandalonePlugInWrapper*)inUserData)->getAudioApplication()->getEditor();
	editor->idle();
}

OSStatus windowHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
{
	OSStatus result = eventNotHandledErr;
	WindowRef window = (WindowRef)inUserData;
	UInt32 eventClass = GetEventClass(inEvent);
	UInt32 eventKind = GetEventKind(inEvent);

	switch (eventClass)
	{
	case kEventClassWindow:
	{
		switch (eventKind)
		{
		case kEventWindowClose:
		{
			QuitAppModalLoopForWindow(window);
			break;
		}
		}
		break;
	}
	}

	return result;
}

void StandalonePlugInWrapper::GUIThread::run()
{
	checkEffectEditor(&applicationWrapper);
}
Can someone help me out a bit with this or point me to the right direction with some existing code or projects that I could use as a reference?
Unless I'm underestimating the task, my apologies if that's the case.

Thanks in advance,
Federico

Post

Nevermind, got it to work! :party:

Post Reply

Return to “DSP and Plugin Development”