amuse/AudioUnit/AmuseContainingApp.mm

319 lines
8.8 KiB
Plaintext

#import <AppKit/AppKit.h>
#import <AudioUnit/AudioUnit.h>
#import <CoreAudioKit/AUViewController.h>
#import "AudioUnitViewController.hpp"
#import "AmuseContainingApp.hpp"
#include <amuse/amuse.hpp>
@class DataOutlineController;
@class SamplesTableController;
@class SFXTableController;
/* Blocks mousedown events (so button may be used as a visual element only) */
@interface InactiveButton : NSButton {}
@end
@implementation InactiveButton
- (void)mouseDown:(NSEvent *)theEvent {}
@end
/* Restricts mousedown to checkbox */
@interface RestrictedCheckButton : NSButtonCell {}
@end
@implementation RestrictedCheckButton
- (NSCellHitResult)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView
{
NSRect restrictFrame = cellFrame;
restrictFrame.size.width = 22;
if (NSPointInRect([controlView convertPoint:[event locationInWindow] fromView:nil], restrictFrame))
return NSCellHitTrackableArea;
return NSCellHitNone;
}
@end
@implementation DataOutlineView
- (id)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
[self registerForDraggedTypes:@[NSURLPboardType]];
return self;
}
- (id)initWithFrame:(NSRect)frameRect
{
self = [super initWithFrame:frameRect];
[self registerForDraggedTypes:@[NSURLPboardType]];
return self;
}
@end
@interface MainTabView : NSTabView
{}
- (IBAction)selectDataTab:(id)sender;
- (IBAction)selectSFXTab:(id)sender;
- (IBAction)selectSamplesTab:(id)sender;
- (IBAction)selectCreditsTab:(id)sender;
@end
@implementation MainTabView
- (IBAction)selectDataTab:(id)sender
{
[self selectTabViewItemAtIndex:0];
}
- (IBAction)selectSFXTab:(id)sender
{
[self selectTabViewItemAtIndex:1];
}
- (IBAction)selectSamplesTab:(id)sender
{
[self selectTabViewItemAtIndex:2];
}
- (IBAction)selectCreditsTab:(id)sender
{
[self selectTabViewItemAtIndex:3];
}
@end
@implementation SamplesTableController
- (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView
{
return presenter->m_sampleTableData.size();
}
- (NSView*)tableView:(NSTableView *)tableView viewForTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row
{
if (presenter->m_sampleTableData.size() <= row)
return nil;
NSTableCellView* view = [tableView makeViewWithIdentifier:@"SampleIDColumn" owner:self];
AudioGroupSampleToken* sampToken = presenter->m_sampleTableData[row];
if ([tableColumn.identifier isEqualToString:@"SampleIDColumn"])
view.textField.attributedStringValue = sampToken->m_name;
else if ([tableColumn.identifier isEqualToString:@"SampleDetailsColumn"])
view.textField.stringValue = @"";
else
view.textField.attributedStringValue = sampToken->m_name;
return view;
}
- (BOOL)tableView:(NSTableView *)tableView isGroupRow:(NSInteger)row
{
if (presenter->m_sampleTableData.size() <= row)
return NO;
AudioGroupSampleToken* sampToken = presenter->m_sampleTableData[row];
if (!sampToken->m_sample)
return YES;
return NO;
}
- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)row
{
if (presenter->m_sampleTableData.size() <= row)
return NO;
AudioGroupSampleToken* sampToken = presenter->m_sampleTableData[row];
if (!sampToken->m_sample)
return NO;
return YES;
}
- (id)initWithAudioGroupPresenter:(AudioGroupFilePresenter*)present
{
self = [super init];
presenter = present;
return self;
}
@end
@implementation SFXTableController
- (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView
{
return presenter->m_sfxTableData.size();
}
- (NSView*)tableView:(NSTableView *)tableView viewForTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row
{
if (presenter->m_sfxTableData.size() <= row)
return nil;
NSTableCellView* view = [tableView makeViewWithIdentifier:@"SFXIDColumn" owner:self];
AudioGroupSFXToken* sfxToken = presenter->m_sfxTableData[row];
if ([tableColumn.identifier isEqualToString:@"SFXIDColumn"])
view.textField.attributedStringValue = sfxToken->m_name;
else if ([tableColumn.identifier isEqualToString:@"SFXDetailsColumn"])
view.textField.stringValue = @"";
else
view.textField.attributedStringValue = sfxToken->m_name;
return view;
}
- (BOOL)tableView:(NSTableView *)tableView isGroupRow:(NSInteger)row
{
if (presenter->m_sfxTableData.size() <= row)
return NO;
AudioGroupSFXToken* sfxToken = presenter->m_sfxTableData[row];
if (!sfxToken->m_sfx)
return YES;
return NO;
}
- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)row
{
if (presenter->m_sfxTableData.size() <= row)
return NO;
AudioGroupSFXToken* sfxToken = presenter->m_sfxTableData[row];
if (!sfxToken->m_sfx)
return NO;
return YES;
}
- (void)tableViewSelectionDidChange:(NSNotification *)notification
{
NSTableView* table = notification.object;
NSInteger row = table.selectedRow;
if (presenter->m_sfxTableData.size() <= row)
return;
AudioGroupSFXToken* sfxToken = presenter->m_sfxTableData[row];
AppDelegate* delegate = (AppDelegate*)NSApp.delegate;
[delegate startSFX:sfxToken->m_loadId];
}
- (id)initWithAudioGroupPresenter:(AudioGroupFilePresenter*)present
{
self = [super init];
presenter = present;
return self;
}
@end
@implementation AppDelegate
- (void)applicationWillFinishLaunching:(NSNotification*)notification
{
booEngine = boo::NewAudioVoiceEngine();
amuseAllocator.emplace(*booEngine);
amuseEngine.emplace(*amuseAllocator);
[mainWindow.toolbar setSelectedItemIdentifier:@"DataTab"];
groupFilePresenter = [[AudioGroupFilePresenter alloc] initWithAudioGroupClient:self];
dataOutline.dataSource = groupFilePresenter;
dataOutline.delegate = groupFilePresenter;
[dataOutline reloadItem:nil reloadChildren:YES];
samplesController = [[SamplesTableController alloc] initWithAudioGroupPresenter:groupFilePresenter];
samplesTable.dataSource = samplesController;
samplesTable.delegate = samplesController;
[samplesTable reloadData];
sfxController = [[SFXTableController alloc] initWithAudioGroupPresenter:groupFilePresenter];
sfxTable.dataSource = sfxController;
sfxTable.delegate = sfxController;
[sfxTable reloadData];
[NSTimer scheduledTimerWithTimeInterval:1.0 / 60.0 target:self selector:@selector(pumpTimer:) userInfo:nil repeats:YES];
}
- (void)pumpTimer:(NSTimer*)timer
{
booEngine->pumpAndMixVoices();
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
{
return YES;
}
- (BOOL)importURL:(NSURL*)url
{
amuse::ContainerRegistry::Type containerType;
std::vector<std::pair<std::string, amuse::IntrusiveAudioGroupData>> data =
amuse::ContainerRegistry::LoadContainer(url.path.UTF8String, containerType);
if (data.empty())
{
NSString* err = [NSString stringWithFormat:@"Unable to load Audio Groups from %s", url.path.UTF8String];
NSAlert* alert = [[NSAlert alloc] init];
alert.informativeText = err;
alert.messageText = @"Invalid Data File";
[alert runModal];
return false;
}
std::string name(amuse::ContainerRegistry::TypeToName(containerType));
if (containerType == amuse::ContainerRegistry::Type::Raw4)
name = url.URLByDeletingPathExtension.lastPathComponent.UTF8String;
return [groupFilePresenter addCollectionName:std::move(name) items:std::move(data)];
}
- (IBAction)importFile:(id)sender
{
__block NSOpenPanel* panel = [NSOpenPanel openPanel];
[panel beginSheetModalForWindow:mainWindow completionHandler:^(NSInteger result) {
if (result == NSModalResponseOK)
{
[self importURL:panel.URL];
}
}];
}
- (void)startSFX:(int)sfxId
{
if (activeSFXVox)
activeSFXVox->keyOff();
activeSFXVox = amuseEngine->fxStart(sfxId, 1.f, 0.f);
}
- (void)startSample:(int)sampleId
{
}
- (void)reloadTables
{
[sfxTable reloadData];
[samplesTable reloadData];
}
- (IBAction)filterDataOutline:(id)sender
{
[groupFilePresenter setSearchFilter:[sender stringValue]];
}
- (IBAction)removeDataItem:(id)sender
{
[groupFilePresenter removeSelectedItem];
}
- (void)outlineView:(DataOutlineView *)ov selectionChanged:(id)item
{
if ([item isKindOfClass:[AudioGroupCollectionToken class]])
{
removeDataButton.enabled = TRUE;
removeDataMenu.enabled = TRUE;
}
else
{
removeDataButton.enabled = FALSE;
removeDataMenu.enabled = FALSE;
}
}
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename
{
NSURL* url = [NSURL fileURLWithPath:filename isDirectory:NO];
return [self importURL:url];
}
- (amuse::Engine&)getAmuseEngine
{
return *amuseEngine;
}
@end
int main(int argc, const char * argv[])
{
return NSApplicationMain(argc, argv);
}