diff --git a/Sources/VLSheetViewInternal.h b/Sources/VLSheetViewInternal.h index b7ff594..be7b5ef 100644 --- a/Sources/VLSheetViewInternal.h +++ b/Sources/VLSheetViewInternal.h @@ -10,6 +10,7 @@ const float kLineX = 5.0; const float kLineH = 10.0; +const float kTripletH = 5.0; #define kSystemBaseline ((fNumBotLedgers+1)*kLineH+fNumStanzas*kLyricsH) #define kSystemAscent ((fNumTopLedgers+7)*kLineH+kChordH) #define kSystemH (kSystemBaseline+kSystemAscent) diff --git a/Sources/VLSheetViewNotes.mm b/Sources/VLSheetViewNotes.mm index 8d78fad..1c96ed1 100644 --- a/Sources/VLSheetViewNotes.mm +++ b/Sources/VLSheetViewNotes.mm @@ -312,14 +312,41 @@ operation: NSCompositeSourceOver]; } +- (void) drawTripletBracketFrom:(int)startX to:(int)endX atY:(int)y +{ + static NSDictionary * sTripletFont = nil; + if (!sTripletFont) + sTripletFont = + [[NSDictionary alloc] initWithObjectsAndKeys: + [NSFont fontWithName: @"Helvetica" size: 12], + NSFontAttributeName, + nil]; + + NSBezierPath * bz = [NSBezierPath bezierPath]; + + [bz moveToPoint: NSMakePoint(startX, y-kTripletH)]; + [bz lineToPoint: NSMakePoint(startX, y)]; + [bz lineToPoint: NSMakePoint(endX, y)]; + [bz lineToPoint: NSMakePoint(endX, y-kTripletH)]; + [bz stroke]; + + [@"3" drawAtPoint: NSMakePoint((startX+endX)*0.5f, y+kTripletH) + withAttributes: sTripletFont]; +} + - (void) drawNotesForSystem:(int)system { const int kFirstMeas = fLayout->FirstMeasure(system); const VLSong * song = [self song]; const VLProperties & kProp = song->Properties(kFirstMeas); const VLSystemLayout & kLayout = (*fLayout)[system]; + const float kSystemY = [self systemY:system]; + + float tripletStartX; + float tripletEndX; + float tripletY; + bool hasTriplets = false; - float kSystemY = [self systemY:system]; for (int m = 0; mfTied & VLNote::kTiedWithPrev; int pitch = note->fPitch; + NSPoint pos; if (pitch != VLNote::kNoPitch) { [self drawLedgerLinesInSection:measure.fPropIdx withPitch:pitch visual:note->fVisual at:NSMakePoint([self noteXInMeasure:measIdx at:at], kSystemY)]; VLMusicElement accidental; - NSPoint pos = - NSMakePoint([self noteXInMeasure:measIdx at:at], - kSystemY+[self noteYInSection:measure.fPropIdx - withPitch:pitch - visual:note->fVisual - accidental:&accidental]); + pos = NSMakePoint([self noteXInMeasure:measIdx at:at], + kSystemY+[self noteYInSection:measure.fPropIdx + withPitch:pitch + visual:note->fVisual + accidental:&accidental]); VLMusicElement acc = accidental; int step= [self stepInSection:measure.fPropIdx withPitch:pitch @@ -367,16 +394,32 @@ accidentals[step] = accidental; } else { VLMusicElement accidental; - NSPoint pos = - NSMakePoint([self noteXInMeasure:measIdx at:at], - kSystemY+[self noteYInSection:measure.fPropIdx - withPitch:65 visual:0 - accidental:&accidental]); + pos = NSMakePoint([self noteXInMeasure:measIdx at:at], + kSystemY+[self noteYInSection:measure.fPropIdx + withPitch:65 visual:0 + accidental:&accidental]); [self drawRest:note->fVisual & VLNote::kNoteHead at: pos]; } + if (note->fVisual & VLNote::kTriplet) { + tripletEndX = pos.x+kNoteW*0.5f; + if (hasTriplets) { + tripletY = std::max(tripletY, pos.y+kLineH); + } else { + tripletY = std::max(kSystemY+5.0f*kLineH, pos.y+kLineH); + tripletStartX = pos.x-kNoteW*0.5f; + hasTriplets = true; + } + } else if (hasTriplets) { + [self drawTripletBracketFrom:tripletStartX to:tripletEndX atY:tripletY]; + hasTriplets = false; + } + at += note->fDuration; } } + if (hasTriplets) { + [self drawTripletBracketFrom:tripletStartX to:tripletEndX atY:tripletY]; + } if (fCursorPitch != VLNote::kNoPitch && fLayout->SystemForMeasure(fCursorMeasure) == system) [self drawNoteCursor]; }