Container loading bug fixes, drag-n-drop support

This commit is contained in:
Jack Andersen 2016-06-04 17:11:24 -10:00
parent 62ece61cb2
commit 168c4d3cfd
7 changed files with 136 additions and 83 deletions

View File

@ -6,6 +6,10 @@
<string>@APPLE_TEAM_ID@.@APPLE_BUNDLE_ID@</string>
<key>com.apple.developer.team-identifier</key>
<string>@APPLE_TEAM_ID@</string>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>group.io.github.axiodl.Amuse.AudioGroups</string>

View File

@ -91,11 +91,6 @@ CA
<action selector="removeDataItem:" target="Y3H-Qy-a7C" id="aAl-Ko-LrT"/>
</connections>
</menuItem>
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
<connections>
<action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
@ -195,9 +190,9 @@ CA
<action selector="removeDataItem:" target="Y3H-Qy-a7C" id="hau-zt-Ozz"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mpK-AK-Otf">
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mpK-AK-Otf" customClass="InactiveButton">
<rect key="frame" x="58" y="-1" width="486" height="32"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="overlaps" alignment="center" lineBreakMode="truncatingTail" refusesFirstResponder="YES" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="JwG-gw-HOj">
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="overlaps" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="JwG-gw-HOj">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
@ -215,7 +210,7 @@ CA
<color key="backgroundColor" name="_sourceListBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn identifier="CollectionColumn" width="193" minWidth="100" maxWidth="1000" id="DlG-iE-h1a">
<tableColumn identifier="CollectionColumn" width="300" minWidth="100" maxWidth="1000" id="DlG-iE-h1a">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Collection">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@ -227,7 +222,7 @@ CA
</buttonCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
</tableColumn>
<tableColumn identifier="DetailsColumn" width="343" minWidth="40" maxWidth="1000" id="alh-ut-BoX">
<tableColumn identifier="DetailsColumn" width="236" minWidth="40" maxWidth="1000" id="alh-ut-BoX">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Details">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@ -258,8 +253,8 @@ CA
<autoresizingMask key="autoresizingMask"/>
</tableHeaderView>
</scrollView>
<searchField wantsLayer="YES" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Huk-pR-ayq">
<rect key="frame" x="65" y="4" width="474" height="22"/>
<searchField wantsLayer="YES" verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Huk-pR-ayq">
<rect key="frame" x="64" y="3" width="476" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="22" id="uJy-eO-Y8o"/>
</constraints>

View File

@ -9,6 +9,13 @@
@class SamplesTableController;
@class SFXTableController;
/* Blocks mousedown events */
@interface InactiveButton : NSButton {}
@end
@implementation InactiveButton
- (void)mouseDown:(NSEvent *)theEvent {}
@end
@interface MainView : NSView
{
AudioUnitViewController* amuseVC;
@ -36,17 +43,18 @@
@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:@[(__bridge NSString*)kUTTypeData]];
[self registerForDraggedTypes:@[NSURLPboardType]];
return self;
}
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
{
return NO;
}
@end
@interface MainTabView : NSTabView
@ -107,7 +115,7 @@
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification*)notification
- (void)applicationWillFinishLaunching:(NSNotification*)notification
{
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints"];
[mainWindow.toolbar setSelectedItemIdentifier:@"DataTab"];
@ -150,6 +158,8 @@
}
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)];
}
@ -188,6 +198,12 @@
}
}
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename
{
NSURL* url = [NSURL fileURLWithPath:filename isDirectory:NO];
return [self importURL:url];
}
@end
int main(int argc, const char * argv[])

View File

@ -37,7 +37,7 @@ struct AudioGroupDataCollection
MetaData(amuse::DataFormat fmtIn, uint32_t absOffsIn, uint32_t activeIn)
: fmt(fmtIn), absOffs(absOffsIn), active(activeIn) {}
MetaData(athena::io::FileReader& r)
: fmt(amuse::DataFormat(r.readUint32Big())), absOffs(r.readUint32Big()), active(r.readUint32Big()) {}
: fmt(amuse::DataFormat(r.readUint32Little())), absOffs(r.readUint32Little()), active(r.readUint32Little()) {}
};
std::experimental::optional<MetaData> m_metaData;
@ -60,34 +60,6 @@ struct AudioGroupDataCollection
void disable(AudioGroupFilePresenter* presenter);
};
template <class T>
class IteratorTracker
{
typename std::map<std::string, T>::const_iterator m_audioGroupOutlineBegin;
typename std::map<std::string, T>::const_iterator m_audioGroupOutlineEnd;
typename std::map<std::string, T>::const_iterator m_audioGroupOutlineIt;
size_t m_audioGroupOutlineIdx = 0;
public:
IteratorTracker(typename std::map<std::string, T>::const_iterator begin,
typename std::map<std::string, T>::const_iterator end)
: m_audioGroupOutlineBegin(begin), m_audioGroupOutlineEnd(end), m_audioGroupOutlineIt(begin) {}
typename std::map<std::string, T>::const_iterator seekToIndex(size_t idx)
{
if (idx == m_audioGroupOutlineIdx)
return m_audioGroupOutlineIt;
if (idx < m_audioGroupOutlineIdx)
{
for (; idx < m_audioGroupOutlineIdx && m_audioGroupOutlineIt != m_audioGroupOutlineBegin ;
--m_audioGroupOutlineIdx, --m_audioGroupOutlineIt) {}
return m_audioGroupOutlineIt;
}
for (; idx > m_audioGroupOutlineIdx && m_audioGroupOutlineIt != m_audioGroupOutlineEnd ;
++m_audioGroupOutlineIdx, ++m_audioGroupOutlineIt) {}
return m_audioGroupOutlineIt;
}
};
struct AudioGroupCollection
{
NSURL* m_url;
@ -95,7 +67,6 @@ struct AudioGroupCollection
AudioGroupCollectionToken* m_token;
std::map<std::string, std::unique_ptr<AudioGroupDataCollection>> m_groups;
std::vector<std::map<std::string, std::unique_ptr<AudioGroupDataCollection>>::iterator> m_filterGroups;
//std::experimental::optional<IteratorTracker<std::unique_ptr<AudioGroupDataCollection>>> m_iteratorTracker;
AudioGroupCollection(NSURL* url);
void addCollection(std::vector<std::pair<std::string, amuse::IntrusiveAudioGroupData>>&& collection);
@ -127,8 +98,6 @@ struct AudioGroupCollection
std::vector<std::map<std::string, std::unique_ptr<AudioGroupCollection>>::iterator> m_filterAudioGroupCollections;
NSOutlineView* lastOutlineView;
NSString* searchStr;
//std::experimental::optional<IteratorTracker<std::unique_ptr<AudioGroupCollection>>> m_iteratorTracker;
}
- (BOOL)addCollectionName:(std::string&&)name items:(std::vector<std::pair<std::string, amuse::IntrusiveAudioGroupData>>&&)collection;
- (void)update;

View File

@ -137,7 +137,7 @@ AudioGroupDataCollection::AudioGroupDataCollection(const std::string& name, NSUR
bool AudioGroupDataCollection::_attemptLoad(AudioGroupFilePresenter* presenter)
{
if (m_metaData && m_loadedProj)
if (m_metaData && m_loadedData && m_loadedProj)
return true;
if (!loadProj(presenter))
return false;
@ -176,7 +176,7 @@ bool AudioGroupDataCollection::_attemptLoad(AudioGroupFilePresenter* presenter)
break;
}
if (m_metaData && m_loadedProj)
if (m_metaData && m_loadedData)
{
m_loadedProj.emplace(amuse::AudioGroupProject::CreateAudioGroupProject(*m_loadedData));
return true;
@ -426,7 +426,9 @@ bool AudioGroupDataCollection::loadMeta(AudioGroupFilePresenter* presenter)
return [NSNumber numberWithInt:NSMixedState];
}
else if ([tableColumn.identifier isEqualToString:@"DetailsColumn"])
return [NSString stringWithFormat:@"%" PRISize " groups", collection.m_groups.size()];
return [NSString stringWithFormat:@"%zu Audio Group%s",
collection.m_groups.size(),
collection.m_groups.size() > 1 ? "s" : ""];
}
else if ([item isKindOfClass:[AudioGroupDataToken class]])
{
@ -437,8 +439,22 @@ bool AudioGroupDataCollection::loadMeta(AudioGroupFilePresenter* presenter)
{
if (!data.m_loadedProj)
return @"";
return [NSString stringWithFormat:@"%zu SongGroups, %zu SFXGroups",
data.m_loadedProj->songGroups().size(), data.m_loadedProj->sfxGroups().size()];
if (data.m_loadedProj->songGroups().size() && data.m_loadedProj->sfxGroups().size())
return [NSString stringWithFormat:@"%zu Song Group%s, %zu SFX Group%s",
data.m_loadedProj->songGroups().size(),
data.m_loadedProj->songGroups().size() > 1 ? "s" : "",
data.m_loadedProj->sfxGroups().size(),
data.m_loadedProj->sfxGroups().size() > 1 ? "s" : ""];
else if (data.m_loadedProj->songGroups().size())
return [NSString stringWithFormat:@"%zu Song Group%s",
data.m_loadedProj->songGroups().size(),
data.m_loadedProj->songGroups().size() > 1 ? "s" : ""];
else if (data.m_loadedProj->sfxGroups().size())
return [NSString stringWithFormat:@"%zu SFX Group%s",
data.m_loadedProj->sfxGroups().size(),
data.m_loadedProj->sfxGroups().size() > 1 ? "s" : ""];
else
return @"";
}
}
@ -505,6 +521,27 @@ bool AudioGroupDataCollection::loadMeta(AudioGroupFilePresenter* presenter)
[(AppDelegate*)NSApp.delegate outlineView:ov selectionChanged:item];
}
- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id<NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(NSInteger)index
{
[outlineView setDropItem:nil dropChildIndex:NSOutlineViewDropOnItemIndex];
NSPasteboard* pboard = [info draggingPasteboard];
if ([[pboard types] containsObject:NSURLPboardType])
return NSDragOperationCopy;
return NSDragOperationNone;
}
- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id<NSDraggingInfo>)info item:(id)item childIndex:(NSInteger)index
{
NSPasteboard* pboard = [info draggingPasteboard];
if ([[pboard types] containsObject:NSURLPboardType])
{
NSURL* url = [NSURL URLFromPasteboard:pboard];
[(AppDelegate*)NSApp.delegate importURL:url];
return YES;
}
return NO;
}
- (BOOL)addCollectionName:(std::string&&)name items:(std::vector<std::pair<std::string, amuse::IntrusiveAudioGroupData>>&&)collection
{
NSFileCoordinator* coord = [[NSFileCoordinator alloc] initWithFilePresenter:self];
@ -560,6 +597,7 @@ bool AudioGroupDataCollection::loadMeta(AudioGroupFilePresenter* presenter)
}
}];
[self resetIterators];
return true;
}
@ -627,7 +665,18 @@ bool AudioGroupDataCollection::loadMeta(AudioGroupFilePresenter* presenter)
- (void)removeSelectedItem
{
id item = [lastOutlineView itemAtRow:lastOutlineView.selectedRow];
if ([item isKindOfClass:[AudioGroupCollectionToken class]])
{
AudioGroupCollection& collection = *((AudioGroupCollectionToken*)item)->m_collection;
NSURL* collectionURL = collection.m_url;
NSString* lastComp = collectionURL.lastPathComponent;
m_audioGroupCollections.erase(lastComp.UTF8String);
[self resetIterators];
[[NSFileManager defaultManager] removeItemAtURL:collectionURL error:nil];
if (m_audioGroupCollections.empty())
[(AppDelegate*)NSApp.delegate outlineView:(DataOutlineView*)lastOutlineView selectionChanged:nil];
}
}
- (id)init

View File

@ -4,6 +4,17 @@
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>public.data</string>
</array>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>amuse-au-container</string>
<key>CFBundleIconFile</key>

View File

@ -49,17 +49,17 @@ const char* ContainerRegistry::TypeToName(Type tp)
case Type::MetroidPrime2:
return "Metroid Prime 2 (GCN)";
case Type::RogueSquadronPC:
return "Star Wars: Rogue Squadron (PC)";
return "Star Wars - Rogue Squadron (PC)";
case Type::RogueSquadronN64:
return "Star Wars: Rogue Squadron (N64)";
return "Star Wars - Rogue Squadron (N64)";
case Type::BattleForNabooPC:
return "Star Wars Episode I: Battle for Naboo (PC)";
return "Star Wars Episode I - Battle for Naboo (PC)";
case Type::BattleForNabooN64:
return "Star Wars Episode I: Battle for Naboo (N64)";
return "Star Wars Episode I - Battle for Naboo (N64)";
case Type::RogueSquadron2:
return "Star Wars: Rogue Squadron 2 (GCN)";
return "Star Wars - Rogue Squadron 2 (GCN)";
case Type::RogueSquadron3:
return "Star Wars: Rogue Squadron 3 (GCN)";
return "Star Wars - Rogue Squadron 3 (GCN)";
}
}
@ -536,23 +536,26 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadMP2(FILE
uint32_t sampSz;
fread(&sampSz, 1, 4, fp);
sampSz = SBig(sampSz);
if (projSz && poolSz && sdirSz && sampSz)
{
std::unique_ptr<uint8_t[]> pool(new uint8_t[poolSz]);
fread(pool.get(), 1, poolSz, fp);
std::unique_ptr<uint8_t[]> pool(new uint8_t[poolSz]);
fread(pool.get(), 1, poolSz, fp);
std::unique_ptr<uint8_t[]> proj(new uint8_t[projSz]);
fread(proj.get(), 1, projSz, fp);
std::unique_ptr<uint8_t[]> proj(new uint8_t[projSz]);
fread(proj.get(), 1, projSz, fp);
std::unique_ptr<uint8_t[]> sdir(new uint8_t[sdirSz]);
fread(sdir.get(), 1, sdirSz, fp);
std::unique_ptr<uint8_t[]> sdir(new uint8_t[sdirSz]);
fread(sdir.get(), 1, sdirSz, fp);
std::unique_ptr<uint8_t[]> samp(new uint8_t[sampSz]);
fread(samp.get(), 1, sampSz, fp);
std::unique_ptr<uint8_t[]> samp(new uint8_t[sampSz]);
fread(samp.get(), 1, sampSz, fp);
ret.emplace_back(std::move(name), IntrusiveAudioGroupData{proj.release(), projSz,
pool.release(), poolSz,
sdir.release(), sdirSz,
samp.release(), sampSz, GCNDataTag{}});
ret.emplace_back(std::move(name), IntrusiveAudioGroupData{proj.release(), projSz,
pool.release(), poolSz,
sdir.release(), sdirSz,
samp.release(), sampSz, GCNDataTag{}});
}
}
}
FSeek(fp, origPos, SEEK_SET);
@ -1287,10 +1290,13 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS2(FILE
std::unique_ptr<uint8_t[]> samp(new uint8_t[head.sampLen]);
memcpy(samp.get(), audData.get() + head.sampOff, head.sampLen);
char name[128];
snprintf(name, 128, "GroupFile%u", j);
ret.emplace_back(name, IntrusiveAudioGroupData{proj.release(), head.projLen, pool.release(), head.poolLen,
sdir.release(), head.sdirLen, samp.release(), head.sampLen, GCNDataTag{}});
if (head.projLen && head.poolLen && head.sdirLen && head.sampLen)
{
char name[128];
snprintf(name, 128, "GroupFile%u", j);
ret.emplace_back(name, IntrusiveAudioGroupData{proj.release(), head.projLen, pool.release(), head.poolLen,
sdir.release(), head.sdirLen, samp.release(), head.sampLen, GCNDataTag{}});
}
}
break;
@ -1457,10 +1463,13 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadRS3(FILE
std::unique_ptr<uint8_t[]> samp(new uint8_t[head.sampLen]);
memcpy(samp.get(), audData.get() + head.sampOff, head.sampLen);
char name[128];
snprintf(name, 128, "GroupFile%u", j);
ret.emplace_back(name, IntrusiveAudioGroupData{proj.release(), head.projLen, pool.release(), head.poolLen,
sdir.release(), head.sdirLen, samp.release(), head.sampLen, GCNDataTag{}});
if (head.projLen && head.poolLen && head.sdirLen && head.sampLen)
{
char name[128];
snprintf(name, 128, "GroupFile%u", j);
ret.emplace_back(name, IntrusiveAudioGroupData{proj.release(), head.projLen, pool.release(), head.poolLen,
sdir.release(), head.sdirLen, samp.release(), head.sampLen, GCNDataTag{}});
}
}
break;