mirror of
https://github.com/microtherion/VocalEasel.git
synced 2024-12-22 19:23:59 +00:00
Implement measure selection
This commit is contained in:
parent
9af760d1dc
commit
52c8f61efd
|
@ -43,7 +43,8 @@ enum VLRegion {
|
||||||
kRegionNowhere,
|
kRegionNowhere,
|
||||||
kRegionNote,
|
kRegionNote,
|
||||||
kRegionChord,
|
kRegionChord,
|
||||||
kRegionLyrics
|
kRegionLyrics,
|
||||||
|
kRegionMeasure
|
||||||
};
|
};
|
||||||
|
|
||||||
enum VLRecalc {
|
enum VLRecalc {
|
||||||
|
@ -75,6 +76,8 @@ enum VLRecalc {
|
||||||
int fCursorActualPitch;
|
int fCursorActualPitch;
|
||||||
VLMusicElement fCursorAccidental;
|
VLMusicElement fCursorAccidental;
|
||||||
size_t fCursorStanza;
|
size_t fCursorStanza;
|
||||||
|
int fSelStart;
|
||||||
|
int fSelEnd;
|
||||||
|
|
||||||
IBOutlet id fFieldEditor;
|
IBOutlet id fFieldEditor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,8 @@ static float sFlatPos[] = {
|
||||||
fClickMode = ' ';
|
fClickMode = ' ';
|
||||||
fDisplayScale = 1.0f;
|
fDisplayScale = 1.0f;
|
||||||
fCursorPitch = VLNote::kNoPitch;
|
fCursorPitch = VLNote::kNoPitch;
|
||||||
|
fSelStart = 0;
|
||||||
|
fSelEnd = -1;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -382,6 +384,25 @@ VLMusicElement sSemi2Accidental[12][12] = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)highlightSelectionForSystem:(int)system
|
||||||
|
{
|
||||||
|
int startMeas = std::max(fSelStart-system*fMeasPerSystem, 0);
|
||||||
|
int endMeas = std::min(fSelEnd-system*fMeasPerSystem, fMeasPerSystem);
|
||||||
|
const float kRawSystemY = [self systemY:system]-kSystemY;
|
||||||
|
|
||||||
|
[NSGraphicsContext saveGraphicsState];
|
||||||
|
[[NSColor selectedTextBackgroundColor] setFill];
|
||||||
|
if (fSelStart == fSelEnd)
|
||||||
|
[NSBezierPath fillRect:
|
||||||
|
NSMakeRect(fClefKeyW+startMeas*fMeasureW-kMeasTol, kRawSystemY,
|
||||||
|
2.0f*kMeasTol, kSystemH)];
|
||||||
|
else
|
||||||
|
[NSBezierPath fillRect:
|
||||||
|
NSMakeRect(fClefKeyW+startMeas*fMeasureW, kRawSystemY,
|
||||||
|
(endMeas-startMeas)*fMeasureW, kSystemH)];
|
||||||
|
[NSGraphicsContext restoreGraphicsState];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)drawRect:(NSRect)rect
|
- (void)drawRect:(NSRect)rect
|
||||||
{
|
{
|
||||||
if (fNeedsRecalc)
|
if (fNeedsRecalc)
|
||||||
|
@ -396,6 +417,15 @@ VLMusicElement sSemi2Accidental[12][12] = {
|
||||||
kLineW, kSystemH-kClefY)
|
kLineW, kSystemH-kClefY)
|
||||||
))
|
))
|
||||||
continue; // This system does not need to be drawn
|
continue; // This system does not need to be drawn
|
||||||
|
//
|
||||||
|
// When highlighting, draw highlight FIRST and then draw our stuff
|
||||||
|
// on top.
|
||||||
|
//
|
||||||
|
if (fSelStart <= fSelEnd
|
||||||
|
&& (system+1)*fMeasPerSystem > fSelStart
|
||||||
|
&& system*fMeasPerSystem < fSelEnd+(fSelStart==fSelEnd)
|
||||||
|
)
|
||||||
|
[self highlightSelectionForSystem:system];
|
||||||
[self drawGridForSystem:system];
|
[self drawGridForSystem:system];
|
||||||
[self drawNotesForSystem:system];
|
[self drawNotesForSystem:system];
|
||||||
[self drawChordsForSystem:system];
|
[self drawChordsForSystem:system];
|
||||||
|
@ -573,6 +603,21 @@ static int8_t sSharpAcc[] = {
|
||||||
loc.y = fmodf(loc.y, kSystemH);
|
loc.y = fmodf(loc.y, kSystemH);
|
||||||
|
|
||||||
loc.x -= fClefKeyW;
|
loc.x -= fClefKeyW;
|
||||||
|
if (loc.y > kSystemY && loc.y < kSystemY+4.0f*kLineH
|
||||||
|
&& fmodf(loc.x+kMeasTol, fMeasureW) < 2*kMeasTol
|
||||||
|
) {
|
||||||
|
int measure = static_cast<int>((loc.x+kMeasTol)/fMeasureW);
|
||||||
|
|
||||||
|
if (measure < 0 || measure > fMeasPerSystem)
|
||||||
|
return fCursorRegion = kRegionNowhere;
|
||||||
|
|
||||||
|
fCursorMeasure = measure+system*fMeasPerSystem;
|
||||||
|
|
||||||
|
if (fCursorMeasure > [self song]->fMeasures.size())
|
||||||
|
return fCursorRegion = kRegionNowhere;
|
||||||
|
else
|
||||||
|
return fCursorRegion = kRegionMeasure;
|
||||||
|
}
|
||||||
if (loc.x < 0.0f || loc.x >= fMeasPerSystem*fMeasureW)
|
if (loc.x < 0.0f || loc.x >= fMeasPerSystem*fMeasureW)
|
||||||
return fCursorRegion = kRegionNowhere;
|
return fCursorRegion = kRegionNowhere;
|
||||||
|
|
||||||
|
@ -644,6 +689,7 @@ static int8_t sSharpAcc[] = {
|
||||||
|
|
||||||
- (void) mouseDown:(NSEvent *)event
|
- (void) mouseDown:(NSEvent *)event
|
||||||
{
|
{
|
||||||
|
fSelEnd = -1;
|
||||||
switch ([self findRegionForEvent:event]) {
|
switch ([self findRegionForEvent:event]) {
|
||||||
case kRegionNote:
|
case kRegionNote:
|
||||||
[self addNoteAtCursor];
|
[self addNoteAtCursor];
|
||||||
|
@ -653,11 +699,53 @@ static int8_t sSharpAcc[] = {
|
||||||
break;
|
break;
|
||||||
case kRegionLyrics:
|
case kRegionLyrics:
|
||||||
[self editLyrics];
|
[self editLyrics];
|
||||||
|
break;
|
||||||
|
case kRegionMeasure:
|
||||||
|
fSelStart = fSelEnd = fCursorMeasure;
|
||||||
|
[self setNeedsDisplay:YES];
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) mouseDragged:(NSEvent *)event
|
||||||
|
{
|
||||||
|
if (fCursorRegion != kRegionMeasure)
|
||||||
|
[super mouseDragged:event];
|
||||||
|
[self autoscroll:event];
|
||||||
|
int prevMeasure = fCursorMeasure;
|
||||||
|
switch ([self findRegionForEvent:event]) {
|
||||||
|
case kRegionNote:
|
||||||
|
case kRegionChord:
|
||||||
|
case kRegionLyrics:
|
||||||
|
if (fCursorAt.fNum)
|
||||||
|
++fCursorMeasure;
|
||||||
|
//
|
||||||
|
// Fall through
|
||||||
|
//
|
||||||
|
case kRegionMeasure:
|
||||||
|
if (fCursorMeasure > fSelEnd) {
|
||||||
|
fSelEnd = fCursorMeasure;
|
||||||
|
[self setNeedsDisplay:YES];
|
||||||
|
} else if (fCursorMeasure < fSelStart) {
|
||||||
|
fSelStart = fCursorMeasure;
|
||||||
|
[self setNeedsDisplay:YES];
|
||||||
|
} else if (prevMeasure == fSelEnd && fCursorMeasure<prevMeasure) {
|
||||||
|
fSelEnd = fCursorMeasure;
|
||||||
|
[self setNeedsDisplay:YES];
|
||||||
|
} else if (prevMeasure == fSelStart && fCursorMeasure>prevMeasure) {
|
||||||
|
fSelStart = fCursorMeasure;
|
||||||
|
[self setNeedsDisplay:YES];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fCursorMeasure = prevMeasure;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fCursorRegion = kRegionMeasure;
|
||||||
|
}
|
||||||
|
|
||||||
- (void) keyDown:(NSEvent *)event
|
- (void) keyDown:(NSEvent *)event
|
||||||
{
|
{
|
||||||
NSString * k = [event charactersIgnoringModifiers];
|
NSString * k = [event charactersIgnoringModifiers];
|
||||||
|
|
|
@ -13,6 +13,7 @@ const float kSystemY = 5.0f*kLineH;
|
||||||
const float kClefX = 20.5f;
|
const float kClefX = 20.5f;
|
||||||
const float kClefY =-15.0f;
|
const float kClefY =-15.0f;
|
||||||
const float kClefW = 30.0f;
|
const float kClefW = 30.0f;
|
||||||
|
const float kMeasTol = 3.5f;
|
||||||
const float kMeasNoX = 10.0f;
|
const float kMeasNoX = 10.0f;
|
||||||
const float kMeasNoY = 4.5f*kLineH;
|
const float kMeasNoY = 4.5f*kLineH;
|
||||||
const float kNoteW = 12.0f;
|
const float kNoteW = 12.0f;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user