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 end = fMeasures[measure].fMelody.end();
bool hasWord = false;
VLFraction word(0);
VLFraction now(0);
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
|| !(note->fLyrics[stanza-1].fKind & VLSyllable::kHasPrev)
) {
word = now;
hasWord = true;
at = now;
return true;
}
now += note->fDuration;
++note;
}
if (hasWord) {
at = word;
return true;
} else {
firstMeasure = false;
}
firstMeasure = false;
} while (++measure < fMeasures.size());
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 PrevWord(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 CountStanzas() const;

View File

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

View File

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

View File

@ -9,14 +9,16 @@
#import "VLSheetWindow.h"
@interface VLLyricsEditable : VLEditable {
VLSheetView * fView;
VLSong * fSong;
int fMeasure;
VLFract fAt;
VLSheetView * fView;
VLSong * fSong;
size_t fStanza;
size_t fMeasure;
VLFraction fAt;
}
- (VLLyricsEditable *)initWithView:(VLSheetView *)view
song:(VLSong *)song
stanza:(int)stanza
measure:(int)measure
at:(VLFract)at;
- (NSString *) stringValue;
@ -32,7 +34,7 @@
- (void) editLyrics;
- (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

View File

@ -17,15 +17,19 @@
- (VLLyricsEditable *)initWithView:(VLSheetView *)view
song:(VLSong *)song
stanza:(int)stanza
measure:(int)measure
at:(VLFract)at
{
self = [super init];
fView = view;
fSong = song;
fStanza = stanza;
fMeasure= measure;
fAt = at;
fSong->FindWord(fStanza, fMeasure, fAt);
[fView setNeedsDisplay: YES];
return self;
@ -33,10 +37,13 @@
- (NSString *) stringValue
{
std::string word = fSong->GetWord(fStanza, fMeasure, fAt);
return [NSString stringWithUTF8String:word.c_str()];
}
- (void) setStringValue:(NSString *)val
{
fSong->SetWord(fStanza, fMeasure, fAt, [val UTF8String]);
}
- (BOOL) validValue:(NSString *)val
@ -46,15 +53,25 @@
- (void) moveToNext
{
if (!fSong->NextWord(fStanza, fMeasure, fAt)) {
fMeasure = 0;
fAt = 0;
fSong->FindWord(fStanza, fMeasure, fAt);
}
}
- (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
{
[fView highlightLyricsInMeasure:fMeasure at:fAt];
[fView highlightLyricsInStanza:fStanza measure:fMeasure at:fAt];
}
@end
@ -117,21 +134,15 @@
[[VLLyricsEditable alloc]
initWithView:self
song:[self song]
stanza:fCursorStanza
measure:fCursorMeasure
at:fCursorAt];
[self setEditTarget:e];
[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