mirror of
https://github.com/microtherion/VocalEasel.git
synced 2024-12-22 11:14:00 +00:00
Refactor cursor handling from a pitch based approach to a grid based one
This commit is contained in:
parent
c50fc4e885
commit
ed2a79a74e
|
@ -63,6 +63,12 @@ enum VLRecalc {
|
||||||
kFirstRecalc
|
kFirstRecalc
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum VLCursorVisual {
|
||||||
|
kCursorExtend = 1<<15,
|
||||||
|
kCursorFlagsMask= 0x8000,
|
||||||
|
kCursorNoPitch = -128
|
||||||
|
};
|
||||||
|
|
||||||
@class VLEditable;
|
@class VLEditable;
|
||||||
|
|
||||||
@interface VLSheetView : NSView {
|
@interface VLSheetView : NSView {
|
||||||
|
@ -76,9 +82,8 @@ enum VLRecalc {
|
||||||
VLRegion fCursorRegion;
|
VLRegion fCursorRegion;
|
||||||
int fCursorMeasure;
|
int fCursorMeasure;
|
||||||
VLFract fCursorAt;
|
VLFract fCursorAt;
|
||||||
int fCursorPitch;
|
int fCursorVertPos;
|
||||||
int fCursorActualPitch;
|
uint16_t fCursorVisual;
|
||||||
VLMusicElement fCursorAccidental;
|
|
||||||
size_t fCursorStanza;
|
size_t fCursorStanza;
|
||||||
int fSelStart;
|
int fSelStart;
|
||||||
int fSelEnd;
|
int fSelEnd;
|
||||||
|
@ -121,11 +126,11 @@ enum VLRecalc {
|
||||||
|
|
||||||
- (float) systemY:(int)system;
|
- (float) systemY:(int)system;
|
||||||
- (int) gridInSection:(int)section withPitch:(int)pitch visual:(uint16_t)visual;
|
- (int) gridInSection:(int)section withPitch:(int)pitch visual:(uint16_t)visual;
|
||||||
|
- (float) noteYInGrid:(int)vertPos;
|
||||||
- (float) noteYInSection:(int)section withPitch:(int)pitch visual:(uint16_t *)visual;
|
- (float) noteYInSection:(int)section withPitch:(int)pitch visual:(uint16_t *)visual;
|
||||||
- (float) noteYInSection:(int)section withPitch:(int)pitch;
|
- (float) noteYInSection:(int)section withPitch:(int)pitch;
|
||||||
- (VLMusicElement)accidentalForVisual:(uint16_t)visual;
|
- (VLMusicElement)accidentalForVisual:(uint16_t)visual;
|
||||||
- (float) noteYInMeasure:(int)measure withPitch:(int)pitch visual:(uint16_t *)visual;
|
- (float) noteYInMeasure:(int)measure withGrid:(int)vertPos;
|
||||||
- (float) noteYInMeasure:(int)measure withPitch:(int)pitch;
|
|
||||||
- (float) noteXInMeasure:(int)measure at:(VLFraction)at;
|
- (float) noteXInMeasure:(int)measure at:(VLFraction)at;
|
||||||
|
|
||||||
- (void) scrollMeasureToVisible:(int)measure;
|
- (void) scrollMeasureToVisible:(int)measure;
|
||||||
|
|
|
@ -96,7 +96,8 @@ static float sFlatPos[] = {
|
||||||
fNeedsRecalc = kFirstRecalc;
|
fNeedsRecalc = kFirstRecalc;
|
||||||
fClickMode = ' ';
|
fClickMode = ' ';
|
||||||
fDisplayScale = 1.0f;
|
fDisplayScale = 1.0f;
|
||||||
fCursorPitch = VLNote::kNoPitch;
|
fCursorVertPos = 0;
|
||||||
|
fCursorVisual = 0;
|
||||||
fSelStart = 0;
|
fSelStart = 0;
|
||||||
fSelEnd = -1;
|
fSelEnd = -1;
|
||||||
fNumTopLedgers = 0;
|
fNumTopLedgers = 0;
|
||||||
|
@ -152,12 +153,17 @@ static float sFlatPos[] = {
|
||||||
return VLPitchToGrid(pitch, visual, key);
|
return VLPitchToGrid(pitch, visual, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (float) noteYInGrid:(int)vertPos
|
||||||
|
{
|
||||||
|
return (vertPos*0.5f - 1.0) * kLineH;
|
||||||
|
}
|
||||||
|
|
||||||
- (float) noteYInSection:(int)section withPitch:(int)pitch visual:(uint16_t *)visual
|
- (float) noteYInSection:(int)section withPitch:(int)pitch visual:(uint16_t *)visual
|
||||||
{
|
{
|
||||||
int key = [self song]->fProperties[section].fKey;
|
int key = [self song]->fProperties[section].fKey;
|
||||||
int grid = VLPitchToGrid(pitch, *visual, key);
|
int grid = VLPitchToGrid(pitch, *visual, key);
|
||||||
|
|
||||||
return (grid*0.5f - 1.0) * kLineH;
|
return [self noteYInGrid:grid];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (float) noteYInSection:(int)section withPitch:(int)pitch
|
- (float) noteYInSection:(int)section withPitch:(int)pitch
|
||||||
|
@ -166,7 +172,7 @@ static float sFlatPos[] = {
|
||||||
uint16_t visual = 0;
|
uint16_t visual = 0;
|
||||||
int grid = VLPitchToGrid(pitch, visual, key);
|
int grid = VLPitchToGrid(pitch, visual, key);
|
||||||
|
|
||||||
return (grid*0.5f - 1.0) * kLineH;
|
return [self noteYInGrid:grid];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (VLMusicElement)accidentalForVisual:(uint16_t)visual
|
- (VLMusicElement)accidentalForVisual:(uint16_t)visual
|
||||||
|
@ -187,20 +193,10 @@ static float sFlatPos[] = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (float) noteYInMeasure:(int)measure withPitch:(int)pitch visual:(uint16_t *)visual
|
- (float) noteYInMeasure:(int)measure withGrid:(int)vertPos
|
||||||
{
|
{
|
||||||
return [self systemY:fLayout->SystemForMeasure(measure)]
|
return [self systemY:fLayout->SystemForMeasure(measure)]
|
||||||
+ [self noteYInSection:[self song]->fMeasures[measure].fPropIdx
|
+ [self noteYInGrid:vertPos];
|
||||||
withPitch:pitch visual:visual];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (float) noteYInMeasure:(int)measure withPitch:(int)pitch
|
|
||||||
{
|
|
||||||
uint16_t dummyVis = 0;
|
|
||||||
|
|
||||||
return [self systemY:fLayout->SystemForMeasure(measure)]
|
|
||||||
+ [self noteYInSection:[self song]->fMeasures[measure].fPropIdx
|
|
||||||
withPitch:pitch visual:&dummyVis];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (float) noteXInMeasure:(int)measure at:(VLFraction)at
|
- (float) noteXInMeasure:(int)measure at:(VLFraction)at
|
||||||
|
@ -674,109 +670,38 @@ const char * sBreak[3] = {"", "\xE2\xA4\xBE", "\xE2\x8E\x98"};
|
||||||
[fFieldEditor setAction:nil];
|
[fFieldEditor setAction:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
const float kSemiFloor = -5.0f*kLineH;
|
const float kSemiFloor = -1.0f*kLineH;
|
||||||
static int8_t sSemiToPitch[] = {
|
|
||||||
47, // B
|
|
||||||
48, 50, // D
|
|
||||||
52, 53, // F
|
|
||||||
55, 57, // A
|
|
||||||
59, 60, // Middle C
|
|
||||||
62, 64, // E
|
|
||||||
65, 67, // G
|
|
||||||
69, 71, // B
|
|
||||||
72, 74, // D
|
|
||||||
76, 77, // F
|
|
||||||
79, 81, // A
|
|
||||||
83, 84, // C
|
|
||||||
86, 88, // E
|
|
||||||
89, 91, // G
|
|
||||||
93, 95, // B
|
|
||||||
96, 98 // D
|
|
||||||
};
|
|
||||||
|
|
||||||
static int8_t sFlatAcc[] = {
|
|
||||||
6, // Cb
|
|
||||||
11,
|
|
||||||
4, // Db
|
|
||||||
9,
|
|
||||||
2, // Eb
|
|
||||||
7, // Fb
|
|
||||||
12,
|
|
||||||
5, // Gb
|
|
||||||
10,
|
|
||||||
3, // Ab
|
|
||||||
8,
|
|
||||||
1, // Bb
|
|
||||||
};
|
|
||||||
|
|
||||||
static int8_t sSharpAcc[] = {
|
|
||||||
2, // C# is the 2nd sharp
|
|
||||||
9,
|
|
||||||
4, // D#
|
|
||||||
11,
|
|
||||||
6, // E#
|
|
||||||
1, // F#
|
|
||||||
8,
|
|
||||||
3, // G#
|
|
||||||
10,
|
|
||||||
5, // A#
|
|
||||||
12,
|
|
||||||
7, // B#
|
|
||||||
};
|
|
||||||
|
|
||||||
- (void) accidentalFromEvent:(NSEvent *)event
|
- (void) accidentalFromEvent:(NSEvent *)event
|
||||||
{
|
{
|
||||||
fCursorAccidental = (VLMusicElement)0;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Extension
|
|
||||||
//
|
|
||||||
if (([event modifierFlags] & (NSShiftKeyMask|NSAlternateKeyMask|NSCommandKeyMask))==NSShiftKeyMask) {
|
|
||||||
fCursorAccidental = kMusicExtendCursor;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int cursorSection =
|
|
||||||
[self song]->fMeasures[fCursorMeasure].fPropIdx;
|
|
||||||
const VLProperties & prop =
|
|
||||||
[self song]->fProperties[cursorSection];
|
|
||||||
|
|
||||||
switch ([event modifierFlags] & (NSShiftKeyMask|NSAlternateKeyMask|NSCommandKeyMask)) {
|
switch ([event modifierFlags] & (NSShiftKeyMask|NSAlternateKeyMask|NSCommandKeyMask)) {
|
||||||
|
case NSShiftKeyMask:
|
||||||
|
fCursorVisual = kCursorExtend;
|
||||||
|
break;
|
||||||
case NSShiftKeyMask|NSAlternateKeyMask:
|
case NSShiftKeyMask|NSAlternateKeyMask:
|
||||||
fCursorAccidental = kMusic2FlatCursor; // Gbb
|
fCursorVisual = VLNote::kWant2Flat; // Gbb
|
||||||
fCursorActualPitch = fCursorPitch-2;
|
|
||||||
break;
|
break;
|
||||||
case NSAlternateKeyMask:
|
case NSAlternateKeyMask:
|
||||||
fCursorAccidental = kMusicFlatCursor; // Gb
|
fCursorVisual = VLNote::kWantFlat; // Gb
|
||||||
fCursorActualPitch = fCursorPitch-1;
|
|
||||||
break;
|
break;
|
||||||
case NSShiftKeyMask|NSCommandKeyMask:
|
case NSShiftKeyMask|NSCommandKeyMask:
|
||||||
fCursorAccidental = kMusic2SharpCursor; // G##
|
fCursorVisual = VLNote::kWant2Sharp; // G##
|
||||||
fCursorActualPitch = fCursorPitch+2;
|
|
||||||
break;
|
break;
|
||||||
case NSCommandKeyMask:
|
case NSCommandKeyMask:
|
||||||
fCursorAccidental = kMusicSharpCursor; // G#
|
fCursorVisual = VLNote::kWantSharp; // G#
|
||||||
fCursorActualPitch = fCursorPitch+1;
|
|
||||||
break;
|
break;
|
||||||
case NSAlternateKeyMask|NSCommandKeyMask:
|
case NSAlternateKeyMask|NSCommandKeyMask:
|
||||||
fCursorAccidental = kMusicNaturalCursor; // G
|
fCursorVisual = VLNote::kWantNatural; // G
|
||||||
fCursorActualPitch = fCursorPitch;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
switch (VLVisualInKey(fCursorPitch, prop.fKey)) {
|
fCursorVisual = 0;
|
||||||
case VLNote::kWantFlat:
|
|
||||||
fCursorActualPitch = fCursorPitch-1;
|
|
||||||
case VLNote::kWantSharp:
|
|
||||||
fCursorActualPitch = fCursorPitch+1;
|
|
||||||
default:
|
|
||||||
fCursorActualPitch = fCursorPitch;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (VLRegion) findRegionForEvent:(NSEvent *) event
|
- (VLRegion) findRegionForEvent:(NSEvent *) event
|
||||||
{
|
{
|
||||||
fCursorPitch = VLNote::kNoPitch;
|
fCursorVertPos = kCursorNoPitch;
|
||||||
|
|
||||||
NSPoint loc = [event locationInWindow];
|
NSPoint loc = [event locationInWindow];
|
||||||
loc = [self convertPoint:loc fromView:nil];
|
loc = [self convertPoint:loc fromView:nil];
|
||||||
|
@ -841,8 +766,7 @@ static int8_t sSharpAcc[] = {
|
||||||
}
|
}
|
||||||
|
|
||||||
loc.y -= kSystemBaseline+kSemiFloor;
|
loc.y -= kSystemBaseline+kSemiFloor;
|
||||||
int semi = static_cast<int>(roundf(loc.y / (0.5f*kLineH)));
|
fCursorVertPos = static_cast<int>(roundf(loc.y / (0.5f*kLineH)));
|
||||||
fCursorPitch = sSemiToPitch[semi];
|
|
||||||
|
|
||||||
[self accidentalFromEvent:event];
|
[self accidentalFromEvent:event];
|
||||||
|
|
||||||
|
@ -854,16 +778,16 @@ static int8_t sSharpAcc[] = {
|
||||||
if ([event modifierFlags] & NSAlphaShiftKeyMask)
|
if ([event modifierFlags] & NSAlphaShiftKeyMask)
|
||||||
return; // Keyboard mode, ignore mouse
|
return; // Keyboard mode, ignore mouse
|
||||||
|
|
||||||
bool hadCursor = fCursorPitch != VLNote::kNoPitch;
|
bool hadCursor = fCursorRegion == kRegionNote;
|
||||||
[self findRegionForEvent:event];
|
[self findRegionForEvent:event];
|
||||||
bool hasCursor = fCursorPitch != VLNote::kNoPitch;
|
bool hasCursor = fCursorRegion == kRegionNote;
|
||||||
|
|
||||||
[self setNeedsDisplay:(hadCursor || hasCursor)];
|
[self setNeedsDisplay:(hadCursor || hasCursor)];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)flagsChanged:(NSEvent *)event
|
- (void)flagsChanged:(NSEvent *)event
|
||||||
{
|
{
|
||||||
if (fCursorPitch != VLNote::kNoPitch) {
|
if (fCursorRegion == kRegionNote) {
|
||||||
[self accidentalFromEvent:event];
|
[self accidentalFromEvent:event];
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
|
@ -877,7 +801,7 @@ static int8_t sSharpAcc[] = {
|
||||||
|
|
||||||
- (void) mouseExited:(NSEvent *)event
|
- (void) mouseExited:(NSEvent *)event
|
||||||
{
|
{
|
||||||
fCursorPitch = VLNote::kNoPitch;
|
fCursorRegion = kRegionNowhere;
|
||||||
[[self window] setAcceptsMouseMovedEvents:NO];
|
[[self window] setAcceptsMouseMovedEvents:NO];
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
|
@ -919,14 +843,6 @@ static int8_t sSharpAcc[] = {
|
||||||
NSString * k = [event charactersIgnoringModifiers];
|
NSString * k = [event charactersIgnoringModifiers];
|
||||||
|
|
||||||
switch ([k characterAtIndex:0]) {
|
switch ([k characterAtIndex:0]) {
|
||||||
case '\r':
|
|
||||||
[self startKeyboardCursor];
|
|
||||||
[self addNoteAtCursor];
|
|
||||||
break;
|
|
||||||
case ' ':
|
|
||||||
[self startKeyboardCursor];
|
|
||||||
VLSoundOut::Instance()->PlayNote(VLNote(1, fCursorPitch));
|
|
||||||
break;
|
|
||||||
case 'r':
|
case 'r':
|
||||||
if (fClickMode == 'r')
|
if (fClickMode == 'r')
|
||||||
fClickMode = ' ';
|
fClickMode = ' ';
|
||||||
|
|
|
@ -14,8 +14,7 @@
|
||||||
|
|
||||||
- (void) drawNotesForSystem:(int)system;
|
- (void) drawNotesForSystem:(int)system;
|
||||||
- (void) addNoteAtCursor;
|
- (void) addNoteAtCursor;
|
||||||
- (void) startKeyboardCursor;
|
- (void) drawNoteCursor:(int)vertPos inMeasure:(size_t)measure at:(VLFract)at visual:(uint16_t)visual;
|
||||||
- (void) drawNoteCursor:(int)pitch inMeasure:(size_t)measure at:(VLFract)at accidental:(VLMusicElement)accidental;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -21,58 +21,31 @@
|
||||||
|
|
||||||
- (void) addNoteAtCursor
|
- (void) addNoteAtCursor
|
||||||
{
|
{
|
||||||
if (fCursorMeasure > -1 && fCursorActualPitch) {
|
if (fCursorMeasure > -1 && fCursorVertPos != kCursorNoPitch) {
|
||||||
VLNote newNote(1, fClickMode==' ' ? fCursorActualPitch : VLNote::kNoPitch);
|
|
||||||
switch (fCursorAccidental) {
|
|
||||||
case kMusicFlatCursor:
|
|
||||||
newNote.fVisual |= VLNote::kWantFlat;
|
|
||||||
break;
|
|
||||||
case kMusicSharpCursor:
|
|
||||||
newNote.fVisual |= VLNote::kWantSharp;
|
|
||||||
break;
|
|
||||||
case kMusic2FlatCursor:
|
|
||||||
newNote.fVisual |= VLNote::kWant2Flat;
|
|
||||||
break;
|
|
||||||
case kMusic2SharpCursor:
|
|
||||||
newNote.fVisual |= VLNote::kWant2Sharp;
|
|
||||||
break;
|
|
||||||
case kMusicNaturalCursor:
|
|
||||||
newNote.fVisual |= VLNote::kWantNatural;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
[[self document] willChangeSong];
|
[[self document] willChangeSong];
|
||||||
if (fCursorAccidental == kMusicExtendCursor)
|
if (fCursorVisual == kCursorExtend) {
|
||||||
newNote = [self song]->ExtendNote(fCursorMeasure, fCursorAt);
|
VLNote oldNote = [self song]->ExtendNote(fCursorMeasure, fCursorAt);
|
||||||
else if (fClickMode == 'k')
|
VLSoundOut::Instance()->PlayNote(oldNote);
|
||||||
|
} else if (fClickMode == 'k') {
|
||||||
[self song]->DelNote(fCursorMeasure, fCursorAt);
|
[self song]->DelNote(fCursorMeasure, fCursorAt);
|
||||||
else
|
} else {
|
||||||
|
int pitch = VLNote::kNoPitch;
|
||||||
|
if (fClickMode == ' ')
|
||||||
|
pitch = VLGridToPitch(fCursorVertPos, fCursorVisual,
|
||||||
|
[self song]->Properties(fCursorMeasure).fKey);
|
||||||
|
VLNote newNote(1, pitch, fCursorVisual & ~kCursorFlagsMask);
|
||||||
[self song]->AddNote(VLLyricsNote(newNote), fCursorMeasure, fCursorAt);
|
[self song]->AddNote(VLLyricsNote(newNote), fCursorMeasure, fCursorAt);
|
||||||
[[self document] didChangeSong];
|
|
||||||
|
|
||||||
if (fClickMode == ' ')
|
|
||||||
VLSoundOut::Instance()->PlayNote(newNote);
|
VLSoundOut::Instance()->PlayNote(newNote);
|
||||||
else
|
}
|
||||||
fClickMode = ' ';
|
[[self document] didChangeSong];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) startKeyboardCursor
|
- (void) drawLedgerLines:(int)vertPos at:(NSPoint)p
|
||||||
{
|
|
||||||
if (fCursorMeasure < 0) {
|
|
||||||
fCursorMeasure = 0;
|
|
||||||
fCursorPitch = VLNote::kMiddleC;
|
|
||||||
fCursorActualPitch = fCursorPitch;
|
|
||||||
fCursorAt = VLFraction(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) drawLedgerLinesInSection:(int)section withPitch:(int)pitch visual:(uint16_t)visual at:(NSPoint)p
|
|
||||||
{
|
{
|
||||||
p.x += kLedgerX;
|
p.x += kLedgerX;
|
||||||
int step = ([self gridInSection:section withPitch:pitch visual:visual]-2)/2;
|
|
||||||
|
int step = (vertPos-2) / 2;
|
||||||
for (int i=0; i-- > step; ) {
|
for (int i=0; i-- > step; ) {
|
||||||
NSPoint p0 = p;
|
NSPoint p0 = p;
|
||||||
p0.y += i*kLineH;
|
p0.y += i*kLineH;
|
||||||
|
@ -89,36 +62,37 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) drawNoteCursor:(int)pitch inMeasure:(size_t)measure at:(VLFract)at
|
- (void) drawLedgerLinesInSection:(int)section withPitch:(int)pitch visual:(uint16_t)visual at:(NSPoint)p
|
||||||
accidental:(VLMusicElement)accidental
|
{
|
||||||
mode:(char)mode
|
[self drawLedgerLines:[self gridInSection:section withPitch:pitch visual:visual] at:p];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) drawNoteCursor:(int)vertPos inMeasure:(size_t)measure at:(VLFract)at
|
||||||
|
visual:(uint16_t)visual mode:(char)mode
|
||||||
{
|
{
|
||||||
int cursorX;
|
int cursorX;
|
||||||
int cursorY;
|
int cursorY;
|
||||||
int cursorSect;
|
|
||||||
VLMusicElement cursorElt;
|
VLMusicElement cursorElt;
|
||||||
|
VLMusicElement accidental = mode ? [self accidentalForVisual:visual] : kMusicNothing;
|
||||||
|
|
||||||
cursorX = [self noteXInMeasure:measure at:at];
|
cursorX = [self noteXInMeasure:measure at:at];
|
||||||
if (accidental == kMusicExtendCursor) {
|
if (visual == kCursorExtend) {
|
||||||
cursorY = [self noteYInMeasure:measure withPitch:pitch];
|
cursorY = [self noteYInGrid:vertPos];
|
||||||
cursorElt = accidental;
|
cursorElt = kMusicExtendCursor;
|
||||||
} else {
|
} else {
|
||||||
uint16_t visual = 0;
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
default:
|
default:
|
||||||
cursorY = [self noteYInMeasure:measure withPitch:pitch visual:&visual] - kNoteY;
|
cursorY = [self noteYInMeasure:measure withGrid:vertPos] - kNoteY;
|
||||||
cursorSect = [self song]->fMeasures[measure].fPropIdx;
|
[self drawLedgerLines:vertPos at:NSMakePoint(cursorX,
|
||||||
[self drawLedgerLinesInSection:cursorSect withPitch:pitch
|
[self systemY:fLayout->SystemForMeasure(measure)])];
|
||||||
visual:visual at:NSMakePoint(cursorX,
|
|
||||||
[self systemY:fLayout->SystemForMeasure(measure)])];
|
|
||||||
cursorElt = kMusicNoteCursor;
|
cursorElt = kMusicNoteCursor;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
cursorY = [self noteYInMeasure:measure withPitch:65];
|
cursorY = [self noteYInMeasure:measure withGrid:3];
|
||||||
cursorElt = kMusicRestCursor;
|
cursorElt = kMusicRestCursor;
|
||||||
break;
|
break;
|
||||||
case 'k':
|
case 'k':
|
||||||
cursorY = [self noteYInMeasure:measure withPitch:pitch];
|
cursorY = [self noteYInGrid:vertPos];
|
||||||
cursorElt = kMusicKillCursor;
|
cursorElt = kMusicKillCursor;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -128,9 +102,11 @@
|
||||||
[[self musicElement:cursorElt]
|
[[self musicElement:cursorElt]
|
||||||
compositeToPoint:xy
|
compositeToPoint:xy
|
||||||
operation: NSCompositeSourceOver];
|
operation: NSCompositeSourceOver];
|
||||||
if (mode && accidental && accidental != kMusicExtendCursor) {
|
|
||||||
xy.y += kNoteY;
|
if (accidental) {
|
||||||
switch (cursorElt= accidental) {
|
xy.y += kNoteY;
|
||||||
|
(int &)accidental += kMusicFlatCursor-kMusicFlat;
|
||||||
|
switch (accidental) {
|
||||||
case kMusicFlatCursor:
|
case kMusicFlatCursor:
|
||||||
xy.x += kFlatW;
|
xy.x += kFlatW;
|
||||||
xy.y += kFlatY;
|
xy.y += kFlatY;
|
||||||
|
@ -152,22 +128,21 @@
|
||||||
xy.y += kNaturalY;
|
xy.y += kNaturalY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
[[self musicElement:cursorElt]
|
[[self musicElement:accidental]
|
||||||
compositeToPoint:xy
|
compositeToPoint:xy
|
||||||
operation: NSCompositeSourceOver];
|
operation: NSCompositeSourceOver];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) drawNoteCursor:(int)pitch inMeasure:(size_t)measure at:(VLFract)at
|
- (void) drawNoteCursor:(int)vertPos inMeasure:(size_t)measure at:(VLFract)at visual:(uint16_t)visual
|
||||||
accidental:(VLMusicElement)accidental
|
|
||||||
{
|
{
|
||||||
[self drawNoteCursor:pitch inMeasure:measure at:at accidental:accidental mode:0];
|
[self drawNoteCursor:vertPos inMeasure:measure at:at visual:visual mode:0];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) drawNoteCursor
|
- (void) drawNoteCursor
|
||||||
{
|
{
|
||||||
[self drawNoteCursor:fCursorPitch inMeasure:fCursorMeasure at:fCursorAt
|
[self drawNoteCursor:fCursorVertPos inMeasure:fCursorMeasure at:fCursorAt
|
||||||
accidental:fCursorAccidental mode:fClickMode];
|
visual:fCursorVisual mode:fClickMode];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) drawNote:(int)visual at:(NSPoint)p
|
- (void) drawNote:(int)visual at:(NSPoint)p
|
||||||
|
@ -390,7 +365,6 @@
|
||||||
accidental:[self accidentalForVisual:filterVisuals(step, visual)]
|
accidental:[self accidentalForVisual:filterVisuals(step, visual)]
|
||||||
tied:tied];
|
tied:tied];
|
||||||
} else {
|
} else {
|
||||||
VLMusicElement accidental;
|
|
||||||
pos = NSMakePoint([self noteXInMeasure:measIdx at:at],
|
pos = NSMakePoint([self noteXInMeasure:measIdx at:at],
|
||||||
kSystemY+[self noteYInSection:measure.fPropIdx withPitch:65]);
|
kSystemY+[self noteYInSection:measure.fPropIdx withPitch:65]);
|
||||||
[self drawRest:note->fVisual & VLNote::kNoteHeadMask at: pos];
|
[self drawRest:note->fVisual & VLNote::kNoteHeadMask at: pos];
|
||||||
|
@ -415,7 +389,7 @@
|
||||||
if (hasTriplets) {
|
if (hasTriplets) {
|
||||||
[self drawTripletBracketFrom:tripletStartX to:tripletEndX atY:tripletY];
|
[self drawTripletBracketFrom:tripletStartX to:tripletEndX atY:tripletY];
|
||||||
}
|
}
|
||||||
if (fCursorPitch != VLNote::kNoPitch && fLayout->SystemForMeasure(fCursorMeasure) == system)
|
if (fCursorRegion == kRegionNote && fLayout->SystemForMeasure(fCursorMeasure) == system)
|
||||||
[self drawNoteCursor];
|
[self drawNoteCursor];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,15 @@
|
||||||
#import "VLSheetViewLyrics.h"
|
#import "VLSheetViewLyrics.h"
|
||||||
#import "VLSheetWindow.h"
|
#import "VLSheetWindow.h"
|
||||||
#import "VLDocument.h"
|
#import "VLDocument.h"
|
||||||
|
#import "VLPitchGrid.h"
|
||||||
|
|
||||||
@interface VLPlaybackEditable : VLEditable {
|
@interface VLPlaybackEditable : VLEditable {
|
||||||
VLSheetView * fView;
|
VLSheetView * fView;
|
||||||
size_t fStanza;
|
size_t fStanza;
|
||||||
size_t fNoteMeasure;
|
size_t fNoteMeasure;
|
||||||
VLFract fNoteAt;
|
VLFract fNoteAt;
|
||||||
int fNotePitch;
|
int fNoteVert;
|
||||||
VLMusicElement fNoteAccidental;
|
uint16_t fNoteVisual;
|
||||||
size_t fChordMeasure;
|
size_t fChordMeasure;
|
||||||
VLFract fChordAt;
|
VLFract fChordAt;
|
||||||
}
|
}
|
||||||
|
@ -50,29 +51,10 @@
|
||||||
{
|
{
|
||||||
VLMIDIUserEvent * event = (VLMIDIUserEvent *)[ev pointerValue];
|
VLMIDIUserEvent * event = (VLMIDIUserEvent *)[ev pointerValue];
|
||||||
if (event->fPitch) {
|
if (event->fPitch) {
|
||||||
fNotePitch = event->fPitch;
|
|
||||||
fNoteAccidental = kMusicNothing;
|
|
||||||
switch (event->fVisual & VLNote::kAccidentalsMask) {
|
|
||||||
case VLNote::kWantFlat:
|
|
||||||
fNoteAccidental = kMusicFlatCursor;
|
|
||||||
break;
|
|
||||||
case VLNote::kWantSharp:
|
|
||||||
fNoteAccidental = kMusicSharpCursor;
|
|
||||||
break;
|
|
||||||
case VLNote::kWant2Flat:
|
|
||||||
fNoteAccidental = kMusic2FlatCursor;
|
|
||||||
break;
|
|
||||||
case VLNote::kWant2Sharp:
|
|
||||||
fNoteAccidental = kMusic2SharpCursor;
|
|
||||||
break;
|
|
||||||
case VLNote::kWantNatural:
|
|
||||||
fNoteAccidental = kMusicNaturalCursor;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fNoteMeasure = event->fMeasure;
|
fNoteMeasure = event->fMeasure;
|
||||||
fNoteAt = event->fAt;
|
fNoteAt = event->fAt;
|
||||||
|
fNoteVisual = event->fVisual & VLNote::kAccidentalsMask;
|
||||||
|
fNoteVert = VLPitchToGrid(event->fPitch, fNoteVisual, [fView song]->Properties(fNoteMeasure).fKey);
|
||||||
fStanza = event->fStanza;
|
fStanza = event->fStanza;
|
||||||
[fView highlightTextInStanza:fStanza measure:fNoteMeasure at:fNoteAt one:YES];
|
[fView highlightTextInStanza:fStanza measure:fNoteMeasure at:fNoteAt one:YES];
|
||||||
} else {
|
} else {
|
||||||
|
@ -85,8 +67,8 @@
|
||||||
|
|
||||||
- (void) highlightCursor
|
- (void) highlightCursor
|
||||||
{
|
{
|
||||||
if (fNoteMeasure != 0x80000000 && fNotePitch != VLNote::kNoPitch)
|
if (fNoteMeasure != 0x80000000 && fNoteVert != kCursorNoPitch)
|
||||||
[fView drawNoteCursor:fNotePitch inMeasure:fNoteMeasure at:fNoteAt accidental:fNoteAccidental];
|
[fView drawNoteCursor:fNoteVert inMeasure:fNoteMeasure at:fNoteAt visual:fNoteVisual];
|
||||||
if (fChordMeasure != 0x80000000)
|
if (fChordMeasure != 0x80000000)
|
||||||
[fView highlightChordInMeasure:fChordMeasure at:fChordAt];
|
[fView highlightChordInMeasure:fChordMeasure at:fChordAt];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user