Edit lyrics

This commit is contained in:
Matthias Neeracher 2006-12-02 09:02:44 +00:00
parent d32906f0bb
commit afe4f8078d
6 changed files with 115 additions and 25 deletions

View File

@ -1160,7 +1160,6 @@ bool VLSong::NextWord(size_t stanza, size_t & measure, VLFraction & at)
VLNoteList::iterator note = fMeasures[measure].fMelody.begin(); VLNoteList::iterator note = fMeasures[measure].fMelody.begin();
VLNoteList::iterator end = fMeasures[measure].fMelody.end(); VLNoteList::iterator end = fMeasures[measure].fMelody.end();
bool hasWord = false; bool hasWord = false;
VLFraction word(0);
VLFraction now(0); VLFraction now(0);
while (note != meas.fMelody.end()) { while (note != meas.fMelody.end()) {
@ -1168,20 +1167,92 @@ bool VLSong::NextWord(size_t stanza, size_t & measure, VLFraction & at)
if (note->fLyrics.size() < stanza if (note->fLyrics.size() < stanza
|| !(note->fLyrics[stanza-1].fKind & VLSyllable::kHasPrev) || !(note->fLyrics[stanza-1].fKind & VLSyllable::kHasPrev)
) { ) {
word = now; at = now;
hasWord = true;
return true;
} }
now += note->fDuration; now += note->fDuration;
++note; ++note;
} }
if (hasWord) {
at = word;
return true;
} else {
firstMeasure = false; firstMeasure = false;
}
} while (++measure < fMeasures.size()); } while (++measure < fMeasures.size());
return false; return false;
} }
std::string VLSong::GetWord(size_t stanza, size_t measure, VLFraction at)
{
std::string word;
do {
VLMeasure & meas = fMeasures[measure];
VLNoteList::iterator note = fMeasures[measure].fMelody.begin();
VLNoteList::iterator end = fMeasures[measure].fMelody.end();
VLFraction now(0);
while (note != meas.fMelody.end()) {
if (now >= at && note->fPitch != VLNote::kNoPitch) {
if (word.size())
word += '-';
if (stanza <= note->fLyrics.size()) {
word += note->fLyrics[stanza-1].fText;
if (!(note->fLyrics[stanza-1].fKind & VLSyllable::kHasNext))
return word;
}
}
now += note->fDuration;
++note;
}
at = 0;
} while (++measure < fMeasures.size());
return word;
}
void VLSong::SetWord(size_t stanza, size_t measure, VLFraction at, std::string word)
{
uint8_t kind = 0;
bool cleanup = false;
do {
VLMeasure & meas = fMeasures[measure];
VLNoteList::iterator note = fMeasures[measure].fMelody.begin();
VLNoteList::iterator end = fMeasures[measure].fMelody.end();
VLFraction now(0);
while (note != meas.fMelody.end()) {
if (now >= at && note->fPitch != VLNote::kNoPitch) {
if (cleanup) {
//
// Make sure that following syllable doesn't have
// kHasPrev set
//
if (note->fLyrics.size() >= stanza)
note->fLyrics[stanza-1].fKind &= ~VLSyllable::kHasPrev;
return;
}
if (note->fLyrics.size()<stanza)
note->fLyrics.resize(stanza);
size_t root = word.find('-');
std::string syll;
if (root == std::string::npos) {
syll = word;
kind &= ~VLSyllable::kHasNext;
cleanup = true;
} else {
syll = word.substr(0, root);
word.erase(0, root+1);
kind |= VLSyllable::kHasNext;
}
note->fLyrics[stanza-1].fText = syll;
note->fLyrics[stanza-1].fKind = kind;
kind |= VLSyllable::kHasPrev;
}
now += note->fDuration;
++note;
}
at = 0;
} while (++measure < fMeasures.size());
}

View File

@ -258,6 +258,8 @@ struct VLSong {
bool FindWord(size_t stanza, size_t & measure, VLFraction & at); bool FindWord(size_t stanza, size_t & measure, VLFraction & at);
bool PrevWord(size_t stanza, size_t & measure, VLFraction & at); bool PrevWord(size_t stanza, size_t & measure, VLFraction & at);
bool NextWord(size_t stanza, size_t & measure, VLFraction & at); bool NextWord(size_t stanza, size_t & measure, VLFraction & at);
std::string GetWord(size_t stanza, size_t measure, VLFraction at);
void SetWord(size_t stanza, size_t measure, VLFraction at, std::string word);
size_t CountMeasures() const { return fMeasures.size(); } size_t CountMeasures() const { return fMeasures.size(); }
size_t CountStanzas() const; size_t CountStanzas() const;

View File

@ -73,6 +73,7 @@ enum VLRecalc {
int fCursorPitch; int fCursorPitch;
int fCursorActualPitch; int fCursorActualPitch;
VLMusicElement fCursorAccidental; VLMusicElement fCursorAccidental;
size_t fCursorStanza;
IBOutlet id fFieldEditor; IBOutlet id fFieldEditor;
} }

View File

@ -10,6 +10,7 @@
#import "VLSheetViewInternal.h" #import "VLSheetViewInternal.h"
#import "VLSheetViewChords.h" #import "VLSheetViewChords.h"
#import "VLSheetViewNotes.h" #import "VLSheetViewNotes.h"
#import "VLSheetViewLyrics.h"
#import "VLSoundOut.h" #import "VLSoundOut.h"
#import "VLDocument.h" #import "VLDocument.h"
@ -597,6 +598,8 @@ static int8_t sSharpAcc[] = {
fCursorAt = VLFraction(fCursorAt.fNum / scale, 4); fCursorAt = VLFraction(fCursorAt.fNum / scale, 4);
return fCursorRegion = kRegionChord; return fCursorRegion = kRegionChord;
} else if (loc.y < kSystemY+kLyricsY) { } else if (loc.y < kSystemY+kLyricsY) {
fCursorStanza = static_cast<size_t>((kSystemY+kLyricsY-loc.y) / kLyricsH)
+ 1;
return fCursorRegion = kRegionLyrics; return fCursorRegion = kRegionLyrics;
} }

View File

@ -11,12 +11,14 @@
@interface VLLyricsEditable : VLEditable { @interface VLLyricsEditable : VLEditable {
VLSheetView * fView; VLSheetView * fView;
VLSong * fSong; VLSong * fSong;
int fMeasure; size_t fStanza;
VLFract fAt; size_t fMeasure;
VLFraction fAt;
} }
- (VLLyricsEditable *)initWithView:(VLSheetView *)view - (VLLyricsEditable *)initWithView:(VLSheetView *)view
song:(VLSong *)song song:(VLSong *)song
stanza:(int)stanza
measure:(int)measure measure:(int)measure
at:(VLFract)at; at:(VLFract)at;
- (NSString *) stringValue; - (NSString *) stringValue;
@ -32,7 +34,7 @@
- (void) editLyrics; - (void) editLyrics;
- (void) drawLyricsForSystem:(int)system stanza:(size_t)stanza; - (void) drawLyricsForSystem:(int)system stanza:(size_t)stanza;
- (void) highlightLyricsInMeasure:(int)measure at:(VLFraction)at stanza:(size_t)stanza; - (void) highlightLyricsInStanza:(size_t)stanza measure:(int)measure at:(VLFraction)at;
@end @end

View File

@ -17,15 +17,19 @@
- (VLLyricsEditable *)initWithView:(VLSheetView *)view - (VLLyricsEditable *)initWithView:(VLSheetView *)view
song:(VLSong *)song song:(VLSong *)song
stanza:(int)stanza
measure:(int)measure measure:(int)measure
at:(VLFract)at at:(VLFract)at
{ {
self = [super init]; self = [super init];
fView = view; fView = view;
fSong = song; fSong = song;
fStanza = stanza;
fMeasure= measure; fMeasure= measure;
fAt = at; fAt = at;
fSong->FindWord(fStanza, fMeasure, fAt);
[fView setNeedsDisplay: YES]; [fView setNeedsDisplay: YES];
return self; return self;
@ -33,10 +37,13 @@
- (NSString *) stringValue - (NSString *) stringValue
{ {
std::string word = fSong->GetWord(fStanza, fMeasure, fAt);
return [NSString stringWithUTF8String:word.c_str()];
} }
- (void) setStringValue:(NSString *)val - (void) setStringValue:(NSString *)val
{ {
fSong->SetWord(fStanza, fMeasure, fAt, [val UTF8String]);
} }
- (BOOL) validValue:(NSString *)val - (BOOL) validValue:(NSString *)val
@ -46,15 +53,25 @@
- (void) moveToNext - (void) moveToNext
{ {
if (!fSong->NextWord(fStanza, fMeasure, fAt)) {
fMeasure = 0;
fAt = 0;
fSong->FindWord(fStanza, fMeasure, fAt);
}
} }
- (void) moveToPrev - (void) moveToPrev
{ {
if (!fSong->PrevWord(fStanza, fMeasure, fAt)) {
fMeasure = fSong->CountMeasures()-1;
fAt = fSong->fMeasures[fMeasure].fProperties->fTime;
fSong->PrevWord(fStanza, fMeasure, fAt);
}
} }
- (void) highlightCursor - (void) highlightCursor
{ {
[fView highlightLyricsInMeasure:fMeasure at:fAt]; [fView highlightLyricsInStanza:fStanza measure:fMeasure at:fAt];
} }
@end @end
@ -117,21 +134,15 @@
[[VLLyricsEditable alloc] [[VLLyricsEditable alloc]
initWithView:self initWithView:self
song:[self song] song:[self song]
stanza:fCursorStanza
measure:fCursorMeasure measure:fCursorMeasure
at:fCursorAt]; at:fCursorAt];
[self setEditTarget:e]; [self setEditTarget:e];
[fFieldEditor selectText:self]; [fFieldEditor selectText:self];
} }
- (void) highlightLyricsInMeasure:(int)measure at:(VLFraction)at stanza:(size_t)stanza - (void) highlightLyricsInStanza:(size_t)stanza measure:(int)measure at:(VLFraction)at
{ {
const VLProperties & prop = [self song]->fProperties.front();
const float kSystemY = [self systemY:measure / fMeasPerSystem];
NSRect r =
NSMakeRect([self noteXInMeasure:measure at:at]-kNoteW*0.5f,
kSystemY+kChordY, prop.fDivisions*kNoteW, kChordH);
[[NSColor colorWithCalibratedWhite:0.8f alpha:1.0f] setFill];
NSRectFillUsingOperation(r, NSCompositePlusDarker);
} }
@end @end