Implemen loading, update management

This commit is contained in:
Matthias Neeracher 2006-10-14 10:10:19 +00:00
parent 1b61bcd41e
commit fe55af3f7c
8 changed files with 125 additions and 29 deletions

View File

@ -1,8 +1,8 @@
{ {
IBClasses = ( IBClasses = (
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{CLASS = MyDocument; LANGUAGE = ObjC; SUPERCLASS = NSDocument; },
{CLASS = VLDocument; LANGUAGE = ObjC; SUPERCLASS = NSDocument; }, {CLASS = VLDocument; LANGUAGE = ObjC; SUPERCLASS = NSDocument; },
{CLASS = VLEditable; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{ {
ACTIONS = {hideFieldEditor = id; setDivisions = id; setKey = id; setTime = id; }; ACTIONS = {hideFieldEditor = id; setDivisions = id; setKey = id; setTime = id; };
CLASS = VLSheetView; CLASS = VLSheetView;

View File

@ -11,6 +11,6 @@
<integer>5</integer> <integer>5</integer>
</array> </array>
<key>IBSystem Version</key> <key>IBSystem Version</key>
<string>9A274</string> <string>9A283</string>
</dict> </dict>
</plist> </plist>

Binary file not shown.

View File

@ -12,7 +12,7 @@
<string>vlsong</string> <string>vlsong</string>
</array> </array>
<key>CFBundleTypeIconFile</key> <key>CFBundleTypeIconFile</key>
<string></string> <string>vlsong.icns</string>
<key>CFBundleTypeName</key> <key>CFBundleTypeName</key>
<string>Song</string> <string>Song</string>
<key>CFBundleTypeOSTypes</key> <key>CFBundleTypeOSTypes</key>
@ -32,7 +32,7 @@
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>Vocalese</string> <string>Vocalese</string>
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string></string> <string>vocalese</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>com.aereperennius.Vocalese</string> <string>com.aereperennius.Vocalese</string>
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>

View File

@ -76,8 +76,13 @@
{ {
VLProperties & prop = song->fProperties.front(); VLProperties & prop = song->fProperties.front();
if (transpose)
song->Transpose((7*((key>>8)-prop.fKey) % 12));
prop.fKey = key >> 8; prop.fKey = key >> 8;
prop.fMode= key & 0xFF; prop.fMode= key & 0xFF;
[self updateChangeCount:NSChangeDone];
} }
- (NSNumber *) songTime - (NSNumber *) songTime
@ -92,6 +97,8 @@
VLProperties & prop = song->fProperties.front(); VLProperties & prop = song->fProperties.front();
prop.fTime = VLFraction(num, denom); prop.fTime = VLFraction(num, denom);
[self updateChangeCount:NSChangeDone];
} }
- (NSNumber *) songDivisions - (NSNumber *) songDivisions
@ -106,37 +113,19 @@
VLProperties & prop = song->fProperties.front(); VLProperties & prop = song->fProperties.front();
prop.fDivisions = divisions; prop.fDivisions = divisions;
[self updateChangeCount:NSChangeDone];
} }
- (NSString *)windowNibName - (NSString *)windowNibName
{ {
// Override returning the nib file name of the document
// If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
return @"VLDocument"; return @"VLDocument";
} }
- (void)windowControllerDidLoadNib:(NSWindowController *) aController - (void)windowControllerDidLoadNib:(NSWindowController *) controller
{ {
[super windowControllerDidLoadNib:aController]; [super windowControllerDidLoadNib:controller];
// Add any code here that needs to be executed once the windowController has loaded the document's window. [controller setShouldCloseDocument:YES];
}
- (NSData *)dataRepresentationOfType:(NSString *)aType
{
// Insert code here to write your document from the given data. You can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead.
// For applications targeted for Tiger or later systems, you should use the new Tiger API -dataOfType:error:. In this case you can also choose to override -writeToURL:ofType:error:, -fileWrapperOfType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead.
return nil;
}
- (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType
{
// Insert code here to read your document from the given data. You can also choose to override -loadFileWrapperRepresentation:ofType: or -readFromFile:ofType: instead.
// For applications targeted for Tiger or later systems, you should use the new Tiger API readFromData:ofType:error:. In this case you can also choose to override -readFromURL:ofType:error: or -readFromFileWrapper:ofType:error: instead.
return YES;
} }
@end @end

View File

@ -119,6 +119,7 @@ std::string NormalizeName(NSString* rawName)
fSong->AddChord(chord, fMeasure, fAt); fSong->AddChord(chord, fMeasure, fAt);
[fView setNeedsDisplay:YES]; [fView setNeedsDisplay:YES];
} }
[[fView document] updateChangeCount:NSChangeDone];
} }
- (BOOL) validValue:(NSString *)val - (BOOL) validValue:(NSString *)val

View File

@ -23,6 +23,7 @@
[self song]->AddNote(newNote, fCursorMeasure, fCursorAt); [self song]->AddNote(newNote, fCursorMeasure, fCursorAt);
[self setNeedsDisplay:YES]; [self setNeedsDisplay:YES];
[[self document] updateChangeCount:NSChangeDone];
VLSoundOut::Instance()->PlayNote(newNote); VLSoundOut::Instance()->PlayNote(newNote);

View File

@ -20,7 +20,8 @@
- (id) nodeForXPath:(NSString *)path error:(NSError **)outError - (id) nodeForXPath:(NSString *)path error:(NSError **)outError
{ {
return [[self nodesForXPath:path error:outError] objectAtIndex:0]; NSArray * nodes = [self nodesForXPath:path error:outError];
return [nodes count] ? [nodes objectAtIndex:0] : nil;
} }
- (NSString *)stringForXPath:(NSString *)path error:(NSError **)outError - (NSString *)stringForXPath:(NSString *)path error:(NSError **)outError
@ -259,6 +260,105 @@ const char * sSteps = "C DbD EbE F GbG AbA BbB ";
return YES; return YES;
} }
int8_t sStepToPitch[] = {
9, 11, 0, 2, 4, 5, 7
};
- (VLNote) readNote:(NSXMLElement*)note withUnit:(VLFraction)unit
{
NSError * outError;
VLNote n;
n.fTied = 0;
if ([[note elementsForName:@"rest"] count]) {
n.fPitch = VLNote::kNoPitch;
} else {
n.fPitch = ([note intForXPath:@"./pitch/octave" error:&outError]+1)*12;
n.fPitch +=
sStepToPitch[[[note stringForXPath:@"./pitch/step" error:&outError]
characterAtIndex:0] - 'A'];
if (NSXMLElement * alter = [note nodeForXPath:@"./pitch/alter" error:&outError])
n.fPitch += [[alter stringValue] intValue];
}
n.fDuration = VLFraction([note intForXPath:@"./duration" error:&outError])*unit;
return n;
}
- (void) readMelody:(NSArray *)measures error:(NSError **)outError
{
NSEnumerator * e = [measures objectEnumerator];
for (NSXMLElement * measure; measure = [e nextObject]; ) {
VLProperties & prop = song->fProperties.front();
VLFraction unit(1, 4*prop.fDivisions);
VLFraction at(0);
int m = [[[measure attributeForName:@"number"]
stringValue] intValue]-1;
if (m >= song->CountMeasures())
song->fMeasures.resize(m);
NSEnumerator * n = [[measure elementsForName:@"note"] objectEnumerator];
for (NSXMLElement * note; note = [n nextObject]; ) {
VLNote n = [self readNote:note withUnit:unit];
if (n.fPitch != VLNote::kNoPitch)
song->AddNote(n, m, at);
at += n.fDuration;
}
}
}
- (void) readChords:(NSArray *)measures error:(NSError **)outError
{
NSEnumerator * e = [measures objectEnumerator];
for (NSXMLElement * measure; measure = [e nextObject]; ) {
VLProperties & prop = song->fProperties.front();
VLFraction unit(1, 4*prop.fDivisions);
VLFraction at(0);
VLFraction dur(0);
int m = [[[measure attributeForName:@"number"]
stringValue] intValue]-1;
VLChord chord;
chord.fSteps = 0;
if (m >= song->CountMeasures())
song->fMeasures.resize(m);
NSEnumerator * n = [[measure elementsForName:@"note"] objectEnumerator];
for (NSXMLElement * note; note = [n nextObject]; ) {
VLNote n = [self readNote:note withUnit:unit];
if (![[note elementsForName:@"chord"] count]) {
//
// Start of new chord
//
if (chord.fSteps)
song->AddChord(chord, m, at);
at += dur;
chord.fPitch = n.fPitch;
chord.fRootPitch= VLNote::kNoPitch;
chord.fDuration = n.fDuration;
chord.fSteps = n.fPitch == VLNote::kNoPitch ? 0 : VLChord::kmUnison;
dur = n.fDuration;
if (n.fPitch < VLNote::kMiddleC) {
chord.fPitch = VLNote::kNoPitch;
chord.fRootPitch= n.fPitch;
}
} else if (chord.fPitch == VLNote::kNoPitch) {
chord.fPitch = n.fPitch;
} else {
chord.fSteps |= 1 << (n.fPitch-chord.fPitch);
}
}
if (chord.fSteps)
song->AddChord(chord, m, at);
}
}
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError - (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
{ {
NSXMLDocument * doc = [[NSXMLDocument alloc] initWithData:data NSXMLDocument * doc = [[NSXMLDocument alloc] initWithData:data
@ -280,7 +380,12 @@ const char * sSteps = "C DbD EbE F GbG AbA BbB ";
error:outError] error:outError]
) )
return NO; return NO;
[self readMelody:[melody nodesForXPath:@"./measure" error:outError]
error:outError];
[self readChords:[chords nodesForXPath:@"./measure" error:outError]
error:outError];
return YES; return YES;
} }