mirror of
https://github.com/microtherion/VocalEasel.git
synced 2024-12-22 19:23:59 +00:00
Display lyrics
This commit is contained in:
parent
c832f4cca3
commit
d32906f0bb
|
@ -1113,16 +1113,14 @@ void VLSong::LilypondStanza(std::string & lyrics, size_t stanza) const
|
|||
}
|
||||
}
|
||||
|
||||
bool VLSong::FindWord(size_t & measure, VLFraction & at)
|
||||
bool VLSong::FindWord(size_t stanza, size_t & measure, VLFraction & at)
|
||||
{
|
||||
at += VLFraction(1,64);
|
||||
|
||||
return PrevWord(measure, at);
|
||||
return PrevWord(stanza, measure, at);
|
||||
}
|
||||
|
||||
bool VLSong::PrevWord(size_t & measure, VLFraction & at)
|
||||
bool VLSong::PrevWord(size_t stanza, size_t & measure, VLFraction & at)
|
||||
{
|
||||
#if 0
|
||||
do {
|
||||
VLMeasure & meas = fMeasures[measure];
|
||||
VLNoteList::iterator note = fMeasures[measure].fMelody.begin();
|
||||
|
@ -1131,17 +1129,16 @@ bool VLSong::PrevWord(size_t & measure, VLFraction & at)
|
|||
VLFraction word(0);
|
||||
VLFraction now(0);
|
||||
|
||||
for (VLNoteList::iterator note = meas.fMelody.begin();
|
||||
note != meas.fMelody.end() && now < at;
|
||||
++note
|
||||
) {
|
||||
if (!(note->fTied & VLNote::kTiedWithPrev)
|
||||
&& !(note->fHyphen & VLNote::kHyphenToPrev)
|
||||
) {
|
||||
word = now;
|
||||
hasWord = true;
|
||||
}
|
||||
while (note != meas.fMelody.end() && now < at) {
|
||||
if (note->fPitch != VLNote::kNoPitch)
|
||||
if (note->fLyrics.size() < stanza
|
||||
|| !(note->fLyrics[stanza-1].fKind & VLSyllable::kHasPrev)
|
||||
) {
|
||||
word = now;
|
||||
hasWord = true;
|
||||
}
|
||||
now += note->fDuration;
|
||||
++note;
|
||||
}
|
||||
if (hasWord) {
|
||||
at = word;
|
||||
|
@ -1151,14 +1148,12 @@ bool VLSong::PrevWord(size_t & measure, VLFraction & at)
|
|||
at = meas.fProperties->fTime;
|
||||
}
|
||||
} while (measure-- > 0);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VLSong::NextWord(size_t & measure, VLFraction & at)
|
||||
bool VLSong::NextWord(size_t stanza, size_t & measure, VLFraction & at)
|
||||
{
|
||||
#if 0
|
||||
bool firstMeasure = true;
|
||||
do {
|
||||
VLMeasure & meas = fMeasures[measure];
|
||||
|
@ -1168,18 +1163,16 @@ bool VLSong::NextWord(size_t & measure, VLFraction & at)
|
|||
VLFraction word(0);
|
||||
VLFraction now(0);
|
||||
|
||||
for (VLNoteList::iterator note = meas.fMelody.begin();
|
||||
note != meas.fMelody.end();
|
||||
++note
|
||||
) {
|
||||
if (!(note->fTied & VLNote::kTiedWithPrev)
|
||||
&& !(note->fHyphen & VLNote::kHyphenToPrev)
|
||||
&& (!firstMeasure || now > at)
|
||||
) {
|
||||
word = now;
|
||||
hasWord = true;
|
||||
}
|
||||
while (note != meas.fMelody.end()) {
|
||||
if (note->fPitch != VLNote::kNoPitch && (!firstMeasure || now>at))
|
||||
if (note->fLyrics.size() < stanza
|
||||
|| !(note->fLyrics[stanza-1].fKind & VLSyllable::kHasPrev)
|
||||
) {
|
||||
word = now;
|
||||
hasWord = true;
|
||||
}
|
||||
now += note->fDuration;
|
||||
++note;
|
||||
}
|
||||
if (hasWord) {
|
||||
at = word;
|
||||
|
@ -1189,7 +1182,6 @@ bool VLSong::NextWord(size_t & measure, VLFraction & at)
|
|||
firstMeasure = false;
|
||||
}
|
||||
} while (++measure < fMeasures.size());
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -255,9 +255,9 @@ struct VLSong {
|
|||
void DelNote(size_t measure, VLFraction at);
|
||||
void Transpose(int semitones);
|
||||
|
||||
bool FindWord(size_t & measure, VLFraction & at);
|
||||
bool PrevWord(size_t & measure, VLFraction & at);
|
||||
bool NextWord(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 NextWord(size_t stanza, size_t & measure, VLFraction & at);
|
||||
|
||||
size_t CountMeasures() const { return fMeasures.size(); }
|
||||
size_t CountStanzas() const;
|
||||
|
|
|
@ -388,6 +388,7 @@ VLMusicElement sSemi2Accidental[12][12] = {
|
|||
if (fNeedsRecalc)
|
||||
[self recalculateDimensions];
|
||||
|
||||
size_t stanzas = [self song]->CountStanzas();
|
||||
const float kLineW = fClefKeyW + fMeasPerSystem*fMeasureW;
|
||||
for (int system = 0; system<fNumSystems; ++system) {
|
||||
const float kSystemY = [self systemY:system];
|
||||
|
@ -399,6 +400,8 @@ VLMusicElement sSemi2Accidental[12][12] = {
|
|||
[self drawGridForSystem:system];
|
||||
[self drawNotesForSystem:system];
|
||||
[self drawChordsForSystem:system];
|
||||
for (size_t stanza=0; stanza++<stanzas;)
|
||||
[self drawLyricsForSystem:system stanza:stanza];
|
||||
}
|
||||
[[self editTarget] highlightCursor];
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
const float kLineX = 5.0;
|
||||
const float kLineH = 10.0;
|
||||
const float kSystemH = 15.0f*kLineH;
|
||||
const float kSystemY = 3.0f*kLineH;
|
||||
const float kSystemY = 5.0f*kLineH;
|
||||
const float kClefX = 20.5f;
|
||||
const float kClefY =-15.0f;
|
||||
const float kClefW = 30.0f;
|
||||
|
@ -29,6 +29,7 @@ const float kChordY = 7.0f*kLineH;
|
|||
const float kChordW = 40.0f;
|
||||
const float kChordH = 25.0f;
|
||||
const float kLyricsY = -3.0*kLineH;
|
||||
const float kLyricsH = 1.5*kLineH;
|
||||
const float kNoteX = 7.0f;
|
||||
const float kNoteY = 5.0f;
|
||||
const float kStemX = 0.0f;
|
||||
|
|
41
Sources/VLSheetViewLyrics.h
Normal file
41
Sources/VLSheetViewLyrics.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// VLSheetViewLyrics.h
|
||||
// Vocalese
|
||||
//
|
||||
// Created by Matthias Neeracher on 1/4/06.
|
||||
// Copyright 2006 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import "VLSheetWindow.h"
|
||||
|
||||
@interface VLLyricsEditable : VLEditable {
|
||||
VLSheetView * fView;
|
||||
VLSong * fSong;
|
||||
int fMeasure;
|
||||
VLFract fAt;
|
||||
}
|
||||
|
||||
- (VLLyricsEditable *)initWithView:(VLSheetView *)view
|
||||
song:(VLSong *)song
|
||||
measure:(int)measure
|
||||
at:(VLFract)at;
|
||||
- (NSString *) stringValue;
|
||||
- (void) setStringValue:(NSString*)val;
|
||||
- (BOOL) validValue:(NSString*)val;
|
||||
- (void) moveToNext;
|
||||
- (void) moveToPrev;
|
||||
- (void) highlightCursor;
|
||||
|
||||
@end
|
||||
|
||||
@interface VLSheetView (Lyrics)
|
||||
|
||||
- (void) editLyrics;
|
||||
- (void) drawLyricsForSystem:(int)system stanza:(size_t)stanza;
|
||||
- (void) highlightLyricsInMeasure:(int)measure at:(VLFraction)at stanza:(size_t)stanza;
|
||||
|
||||
@end
|
||||
|
||||
// Local Variables:
|
||||
// mode:ObjC
|
||||
// End:
|
137
Sources/VLSheetViewLyrics.mm
Normal file
137
Sources/VLSheetViewLyrics.mm
Normal file
|
@ -0,0 +1,137 @@
|
|||
//
|
||||
// VLSheetViewLyrics.mm
|
||||
// Vocalese
|
||||
//
|
||||
// Created by Matthias Neeracher on 1/4/06.
|
||||
// Copyright 2006 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import "VLSheetView.h"
|
||||
#import "VLSheetViewLyrics.h"
|
||||
#import "VLSheetViewInternal.h"
|
||||
|
||||
#import "VLModel.h"
|
||||
#import "VLSoundOut.h"
|
||||
|
||||
@implementation VLLyricsEditable
|
||||
|
||||
- (VLLyricsEditable *)initWithView:(VLSheetView *)view
|
||||
song:(VLSong *)song
|
||||
measure:(int)measure
|
||||
at:(VLFract)at
|
||||
{
|
||||
self = [super init];
|
||||
fView = view;
|
||||
fSong = song;
|
||||
fMeasure= measure;
|
||||
fAt = at;
|
||||
|
||||
[fView setNeedsDisplay: YES];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *) stringValue
|
||||
{
|
||||
}
|
||||
|
||||
- (void) setStringValue:(NSString *)val
|
||||
{
|
||||
}
|
||||
|
||||
- (BOOL) validValue:(NSString *)val
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) moveToNext
|
||||
{
|
||||
}
|
||||
|
||||
- (void) moveToPrev
|
||||
{
|
||||
}
|
||||
|
||||
- (void) highlightCursor
|
||||
{
|
||||
[fView highlightLyricsInMeasure:fMeasure at:fAt];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation VLSheetView (Lyrics)
|
||||
|
||||
- (void) drawLyricsForSystem:(int)system stanza:(size_t)stanza
|
||||
{
|
||||
static NSDictionary * sLyricsFont = nil;
|
||||
if (!sLyricsFont)
|
||||
sLyricsFont =
|
||||
[[NSDictionary alloc] initWithObjectsAndKeys:
|
||||
[NSFont fontWithName: @"Helvetica" size: 12],
|
||||
NSFontAttributeName,
|
||||
nil];
|
||||
|
||||
const VLSong * song = [self song];
|
||||
const float kSystemY = [self systemY:system];
|
||||
|
||||
//
|
||||
// Build new list
|
||||
//
|
||||
for (int m = 0; m<fMeasPerSystem; ++m) {
|
||||
int measIdx = m+system*fMeasPerSystem;
|
||||
if (measIdx >= song->CountMeasures())
|
||||
break;
|
||||
const VLMeasure measure = song->fMeasures[measIdx];
|
||||
const VLNoteList & notes = measure.fMelody;
|
||||
VLFraction at(0);
|
||||
for (VLNoteList::const_iterator note = notes.begin();
|
||||
note != notes.end();
|
||||
++note
|
||||
) {
|
||||
if (note->fLyrics.size() < stanza
|
||||
|| !note->fLyrics[stanza-1].fText.size()
|
||||
) {
|
||||
;
|
||||
} else {
|
||||
NSString * syll =
|
||||
[NSString stringWithUTF8String:
|
||||
note->fLyrics[stanza-1].fText.c_str()];
|
||||
NSSize sz =
|
||||
[syll sizeWithAttributes:sLyricsFont];
|
||||
NSPoint syllLoc =
|
||||
NSMakePoint(fClefKeyW+(m+at)*fMeasureW
|
||||
+ 0.5f*(kNoteW-sz.width),
|
||||
kSystemY+kLyricsY-stanza*kLyricsH);
|
||||
if (note->fLyrics[stanza-1].fKind & VLSyllable::kHasNext)
|
||||
syll = [syll stringByAppendingString:@" -"];
|
||||
[syll drawAtPoint:syllLoc withAttributes:sLyricsFont];
|
||||
}
|
||||
at += note->fDuration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) editLyrics
|
||||
{
|
||||
VLEditable * e =
|
||||
[[VLLyricsEditable alloc]
|
||||
initWithView:self
|
||||
song:[self song]
|
||||
measure:fCursorMeasure
|
||||
at:fCursorAt];
|
||||
[self setEditTarget:e];
|
||||
[fFieldEditor selectText:self];
|
||||
}
|
||||
|
||||
- (void) highlightLyricsInMeasure:(int)measure at:(VLFraction)at stanza:(size_t)stanza
|
||||
{
|
||||
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
|
|
@ -67,6 +67,8 @@
|
|||
95E04DAB0AEB4886006F30A0 /* VLXMLDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95F5F50E0ADCC433003980B2 /* VLXMLDocument.mm */; };
|
||||
95E04DC70AEB4B57006F30A0 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */; };
|
||||
95E04DCE0AEB4D9B006F30A0 /* Templates in Resources */ = {isa = PBXBuildFile; fileRef = 95E04DCA0AEB4D9B006F30A0 /* Templates */; };
|
||||
95E299BF0B2006F5001977D2 /* VLSheetViewLyrics.h in Copy MMA Library */ = {isa = PBXBuildFile; fileRef = 95E299BD0B2006F5001977D2 /* VLSheetViewLyrics.h */; };
|
||||
95E299C00B2006F5001977D2 /* VLSheetViewLyrics.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95E299BE0B2006F5001977D2 /* VLSheetViewLyrics.mm */; };
|
||||
95EDA5AA0B06DE46004D8D6E /* VLMIDIDocument.h in Copy MMA Library */ = {isa = PBXBuildFile; fileRef = 95EDA5A80B06DE46004D8D6E /* VLMIDIDocument.h */; };
|
||||
95EDA5AB0B06DE47004D8D6E /* VLMIDIDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95EDA5A90B06DE46004D8D6E /* VLMIDIDocument.mm */; };
|
||||
95F5F50F0ADCC433003980B2 /* VLXMLDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95F5F50E0ADCC433003980B2 /* VLXMLDocument.mm */; };
|
||||
|
@ -103,6 +105,7 @@
|
|||
95009B510B0ED0BB00EB33A4 /* CADebugMacros.h in Copy MMA Library */,
|
||||
95009B640B0ED18700EB33A4 /* CAConditionalMacros.h in Copy MMA Library */,
|
||||
95009B650B0ED18700EB33A4 /* CAMath.h in Copy MMA Library */,
|
||||
95E299BF0B2006F5001977D2 /* VLSheetViewLyrics.h in Copy MMA Library */,
|
||||
);
|
||||
name = "Copy MMA Library";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -190,6 +193,8 @@
|
|||
95E04DA00AEB4837006F30A0 /* TVLLilypond */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = TVLLilypond; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
95E04DA60AEB486E006F30A0 /* TVLLilypond.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = TVLLilypond.mm; path = Tests/TVLLilypond.mm; sourceTree = "<group>"; };
|
||||
95E04DCA0AEB4D9B006F30A0 /* Templates */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Templates; path = Resources/Templates; sourceTree = "<group>"; };
|
||||
95E299BD0B2006F5001977D2 /* VLSheetViewLyrics.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = VLSheetViewLyrics.h; path = Sources/VLSheetViewLyrics.h; sourceTree = "<group>"; };
|
||||
95E299BE0B2006F5001977D2 /* VLSheetViewLyrics.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = VLSheetViewLyrics.mm; path = Sources/VLSheetViewLyrics.mm; sourceTree = "<group>"; };
|
||||
95EDA5A80B06DE46004D8D6E /* VLMIDIDocument.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = VLMIDIDocument.h; path = Sources/VLMIDIDocument.h; sourceTree = "<group>"; };
|
||||
95EDA5A90B06DE46004D8D6E /* VLMIDIDocument.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = VLMIDIDocument.mm; path = Sources/VLMIDIDocument.mm; sourceTree = "<group>"; };
|
||||
95F5F50D0ADCC433003980B2 /* VLXMLDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLXMLDocument.h; path = Sources/VLXMLDocument.h; sourceTree = "<group>"; };
|
||||
|
@ -341,6 +346,8 @@
|
|||
952DCD77096BBB11001C2316 /* VLSheetViewChords.mm */,
|
||||
95B66656096BCA1F00FE18C9 /* VLSheetViewNotes.h */,
|
||||
95B66657096BCA1F00FE18C9 /* VLSheetViewNotes.mm */,
|
||||
95E299BD0B2006F5001977D2 /* VLSheetViewLyrics.h */,
|
||||
95E299BE0B2006F5001977D2 /* VLSheetViewLyrics.mm */,
|
||||
95F5F50D0ADCC433003980B2 /* VLXMLDocument.h */,
|
||||
95F5F50E0ADCC433003980B2 /* VLXMLDocument.mm */,
|
||||
953722650AE9F0E100B6E483 /* VLLilypondDocument.h */,
|
||||
|
@ -626,6 +633,7 @@
|
|||
95009B2A0B0ECF9000EB33A4 /* CAAudioFileFormats.cpp in Sources */,
|
||||
95009B2C0B0ECF9000EB33A4 /* CAStreamBasicDescription.cpp in Sources */,
|
||||
95009B500B0ED0BB00EB33A4 /* CADebugMacros.cpp in Sources */,
|
||||
95E299C00B2006F5001977D2 /* VLSheetViewLyrics.mm in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user