mirror of https://github.com/AxioDL/amuse.git
Container loading bug fixes, drag-n-drop support
This commit is contained in:
parent
62ece61cb2
commit
168c4d3cfd
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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[])
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -537,6 +537,8 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadMP2(FILE
|
|||
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);
|
||||
|
||||
|
@ -555,6 +557,7 @@ static std::vector<std::pair<std::string, IntrusiveAudioGroupData>> LoadMP2(FILE
|
|||
samp.release(), sampSz, GCNDataTag{}});
|
||||
}
|
||||
}
|
||||
}
|
||||
FSeek(fp, origPos, SEEK_SET);
|
||||
}
|
||||
}
|
||||
|
@ -1287,11 +1290,14 @@ 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);
|
||||
|
||||
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,11 +1463,14 @@ 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue