Draw by system, reorganize event handling

This commit is contained in:
Matthias Neeracher 2006-10-02 08:32:25 +00:00
parent 810ff2ee2f
commit 74a6637574
10 changed files with 491 additions and 413 deletions

View File

@ -31,6 +31,11 @@ private:
VLFraction & Normalize(); VLFraction & Normalize();
}; };
inline float operator*(VLFraction f, float sc)
{
return sc*f.fNum/f.fDenom;
}
inline VLFraction operator+(VLFraction one, VLFraction other) inline VLFraction operator+(VLFraction one, VLFraction other)
{ {
return one += other; return one += other;

View File

@ -33,25 +33,29 @@ enum VLMusicElement {
kMusicElements kMusicElements
}; };
enum VLRegion {
kRegionNowhere,
kRegionNote,
kRegionChord,
kRegionLyrics
};
@interface VLSheetView : NSView { @interface VLSheetView : NSView {
BOOL fNeedsRecalc; BOOL fNeedsRecalc;
BOOL fIsRest;
float fClefKeyW; float fClefKeyW;
float fMeasureW; float fMeasureW;
float fLineH;
int fGroups; int fGroups;
int fQuarterBeats; int fQuarterBeats;
int fDivPerGroup; int fDivPerGroup;
int fMeasPerSystem; int fMeasPerSystem;
int fNumSystems; int fNumSystems;
float fDisplayScale; float fDisplayScale;
NSImageRep * fNoteCursorCache;
NSPoint fNoteCursorLocation;
NSPoint fLastNoteCenter; NSPoint fLastNoteCenter;
NSRect fNoteRect; NSTrackingRectTag fCursorTracking;
NSTrackingRectTag fNoteRectTracker; int fCursorMeasure;
int fNoteCursorMeasure; VLFract fCursorAt;
VLFract fNoteCursorAt; int fCursorPitch;
int fNoteCursorPitch;
id fFieldBeingEdited; id fFieldBeingEdited;
BOOL fShowFieldEditor; BOOL fShowFieldEditor;
@ -71,8 +75,14 @@ enum VLMusicElement {
- (float) systemY:(int)system; - (float) systemY:(int)system;
- (float) noteYWithPitch:(int)pitch; - (float) noteYWithPitch:(int)pitch;
- (float) noteYInMeasure:(int)measure withPitch:(int)pitch;
- (float) noteXInMeasure:(int)measure at:(VLFraction)at; - (float) noteXInMeasure:(int)measure at:(VLFraction)at;
- (void) mouseMoved:(NSEvent *)event;
- (void) mouseDown:(NSEvent *)event;
- (void) mouseEntered:(NSEvent *)event;
- (void) mouseExited:(NSEvent *)event;
@end @end
// Local Variables: // Local Variables:

View File

@ -10,6 +10,7 @@
#import "VLSheetViewInternal.h" #import "VLSheetViewInternal.h"
#import "VLSheetViewChords.h" #import "VLSheetViewChords.h"
#import "VLSheetViewNotes.h" #import "VLSheetViewNotes.h"
#import "VLSoundOut.h"
#import "VLDocument.h" #import "VLDocument.h"
@ -79,11 +80,10 @@ static float sFlatPos[] = {
} }
} }
fNeedsRecalc = YES; fNeedsRecalc = YES;
fIsRest = NO;
fShowFieldEditor = NO; fShowFieldEditor = NO;
fDisplayScale = 1.0f; fDisplayScale = 1.0f;
fNoteRectTracker = 0; fCursorPitch = VLNote::kNoPitch;
fNoteCursorCache = nil;
fNoteCursorMeasure = -1;
} }
return self; return self;
} }
@ -148,6 +148,11 @@ static float sFlatPos[] = {
} }
} }
- (float) noteYInMeasure:(int)measure withPitch:(int)pitch
{
return [self systemY:measure/fMeasPerSystem]+[self noteYWithPitch:pitch];
}
- (float) noteXInMeasure:(int)measure at:(VLFraction)at - (float) noteXInMeasure:(int)measure at:(VLFraction)at
{ {
const VLProperties & prop = [self song]->fProperties.front(); const VLProperties & prop = [self song]->fProperties.front();
@ -161,11 +166,12 @@ static float sFlatPos[] = {
- (void) recalculateDimensions - (void) recalculateDimensions
{ {
NSScrollView * scroll = [self enclosingScrollView];
fNeedsRecalc = NO; fNeedsRecalc = NO;
NSSize sz = [[self enclosingScrollView] contentSize]; NSSize sz = [scroll contentSize];
sz.width /= fDisplayScale; sz.width /= fDisplayScale;
sz.height/= fDisplayScale; sz.height /= fDisplayScale;
const VLSong * song = [self song]; const VLSong * song = [self song];
const VLProperties & prop = song->fProperties.front(); const VLProperties & prop = song->fProperties.front();
@ -179,21 +185,16 @@ static float sFlatPos[] = {
fNumSystems = (song->CountMeasures()+fMeasPerSystem-1)/fMeasPerSystem; fNumSystems = (song->CountMeasures()+fMeasPerSystem-1)/fMeasPerSystem;
sz.height = fNumSystems*kSystemH; sz.height = fNumSystems*kSystemH;
#if 0 NSRect r = [scroll bounds];
noteRect = NSMakeRect(clefKeyW, kLineY-kMaxLedgers*kLineH,
visibleMeasures*fMeasureW,
(4.0f+2.0f*kMaxLedgers)*kLineH);
NSPoint mouse = NSPoint mouse =
[self convertPoint:[[self window] mouseLocationOutsideOfEventStream] [scroll convertPoint:[[self window] mouseLocationOutsideOfEventStream]
fromView: nil]; fromView: nil];
BOOL inNoteRect = [self mouse:mouse inRect:noteRect]; BOOL within = [scroll mouse:mouse inRect:r];
[self removeTrackingRect:noteRectTracker];
noteRectTracker = [self addTrackingRect:noteRect owner:self
userData:nil assumeInside:inNoteRect];
[[self window] setAcceptsMouseMovedEvents:inNoteRect];
#endif
[self removeTrackingRect:fCursorTracking];
fCursorTracking = [self addTrackingRect:r owner:self
userData:nil assumeInside:within];
[[self window] setAcceptsMouseMovedEvents:within];
[[self window] makeFirstResponder:self]; [[self window] makeFirstResponder:self];
NSSize frameSz = {sz.width * fDisplayScale, sz.height * fDisplayScale}; NSSize frameSz = {sz.width * fDisplayScale, sz.height * fDisplayScale};
@ -203,7 +204,7 @@ static float sFlatPos[] = {
[self setNeedsDisplay:YES]; [self setNeedsDisplay:YES];
} }
- (void)drawRect:(NSRect)rect - (void)drawGridForSystem:(int)system
{ {
static NSDictionary * sMeasNoFont = nil; static NSDictionary * sMeasNoFont = nil;
if (!sMeasNoFont) if (!sMeasNoFont)
@ -213,6 +214,9 @@ static float sFlatPos[] = {
NSFontAttributeName, NSFontAttributeName,
nil]; nil];
const float kSystemY = [self systemY:system];
const float kLineW = fClefKeyW + fMeasPerSystem*fMeasureW;
const VLSong * song = [self song]; const VLSong * song = [self song];
const VLProperties & prop = song->fProperties.front(); const VLProperties & prop = song->fProperties.front();
@ -222,17 +226,10 @@ static float sFlatPos[] = {
// Draw lines // Draw lines
// //
[bz setLineWidth:0.0]; [bz setLineWidth:0.0];
if (fNeedsRecalc)
[self recalculateDimensions];
for (int system = 0; system<fNumSystems; ++system) {
float kLineY = [self systemY:system];
for (int line = 0; line<5; ++line) { for (int line = 0; line<5; ++line) {
const float x0 = kLineX; const float y = kSystemY+line*kLineH;
const float xx = x0 + fClefKeyW + fMeasPerSystem*fMeasureW; [bz moveToPoint: NSMakePoint(kLineX, y)];
const float y = kLineY+line*kLineH; [bz lineToPoint: NSMakePoint(kLineX+kLineW, y)];
[bz moveToPoint: NSMakePoint(x0, y)];
[bz lineToPoint: NSMakePoint(xx, y)];
}
} }
[bz stroke]; [bz stroke];
[bz removeAllPoints]; [bz removeAllPoints];
@ -240,15 +237,12 @@ static float sFlatPos[] = {
// Draw measure lines // Draw measure lines
// //
[bz setLineWidth:2.0]; [bz setLineWidth:2.0];
for (int system = 0; system<fNumSystems; ++system) {
float kLineY = [self systemY:system];
for (int measure = 0; measure<=fMeasPerSystem; ++measure) { for (int measure = 0; measure<=fMeasPerSystem; ++measure) {
const float x = fClefKeyW+measure*fMeasureW; const float x = fClefKeyW+measure*fMeasureW;
const float yy = kLineY+4.0f*kLineH; const float yy = kSystemY+4.0f*kLineH;
[bz moveToPoint: NSMakePoint(x, kLineY)]; [bz moveToPoint: NSMakePoint(x, kSystemY)];
[bz lineToPoint: NSMakePoint(x, yy)]; [bz lineToPoint: NSMakePoint(x, yy)];
} }
}
[bz stroke]; [bz stroke];
[bz removeAllPoints]; [bz removeAllPoints];
@ -257,12 +251,10 @@ static float sFlatPos[] = {
// //
[bz setLineWidth:0.0]; [bz setLineWidth:0.0];
[[NSColor colorWithDeviceWhite:0.8f alpha:1.0f] set]; [[NSColor colorWithDeviceWhite:0.8f alpha:1.0f] set];
for (int system = 0; system<fNumSystems; ++system) {
float kLineY = [self systemY:system];
for (int measure = 0; measure<fMeasPerSystem; ++measure) { for (int measure = 0; measure<fMeasPerSystem; ++measure) {
const float mx = fClefKeyW+measure*fMeasureW; const float mx = fClefKeyW+measure*fMeasureW;
const float y0 = kLineY-2.0f*kLineH; const float y0 = kSystemY-2.0f*kLineH;
const float yy = kLineY+6.0f*kLineH; const float yy = kSystemY+6.0f*kLineH;
for (int group = 0; group < fGroups; ++group) { for (int group = 0; group < fGroups; ++group) {
for (int div = 0; div < fDivPerGroup; ++div) { for (int div = 0; div < fDivPerGroup; ++div) {
const float x = mx+(group*(fDivPerGroup+1)+div+1)*kNoteW; const float x = mx+(group*(fDivPerGroup+1)+div+1)*kNoteW;
@ -271,22 +263,19 @@ static float sFlatPos[] = {
} }
} }
} }
}
[bz stroke]; [bz stroke];
for (int system = 0; system<fNumSystems; ++system) {
float kLineY = [self systemY:system];
// //
// Draw clef // Draw clef
// //
[[self musicElement:kMusicGClef] [[self musicElement:kMusicGClef]
compositeToPoint: NSMakePoint(kClefX, kLineY+kClefY) compositeToPoint: NSMakePoint(kClefX, kSystemY+kClefY)
operation: NSCompositeSourceOver]; operation: NSCompositeSourceOver];
// //
// Draw measure # // Draw measure #
// //
[[NSString stringWithFormat:@"%d", system*fMeasPerSystem+1] [[NSString stringWithFormat:@"%d", system*fMeasPerSystem+1]
drawAtPoint: NSMakePoint(kMeasNoX, kLineY+kMeasNoY) drawAtPoint: NSMakePoint(kMeasNoX, kSystemY+kMeasNoY)
withAttributes: sMeasNoFont]; withAttributes: sMeasNoFont];
// //
// Draw key (sharps & flats) // Draw key (sharps & flats)
@ -295,7 +284,8 @@ static float sFlatPos[] = {
float x = kClefX+kClefW; float x = kClefX+kClefW;
for (int i=0; i<prop.fKey; ++i) { for (int i=0; i<prop.fKey; ++i) {
[[self musicElement:kMusicSharp] [[self musicElement:kMusicSharp]
compositeToPoint: NSMakePoint(x, kLineY+sSharpPos[i]+kSharpY) compositeToPoint:
NSMakePoint(x, kSystemY+sSharpPos[i]+kSharpY)
operation: NSCompositeSourceOver]; operation: NSCompositeSourceOver];
x += kAccW; x += kAccW;
} }
@ -303,17 +293,31 @@ static float sFlatPos[] = {
float x = kClefX+kClefW; float x = kClefX+kClefW;
for (int i=0; -i>prop.fKey; ++i) { for (int i=0; -i>prop.fKey; ++i) {
[[self musicElement: kMusicFlat] [[self musicElement: kMusicFlat]
compositeToPoint: NSMakePoint(x, kLineY+sFlatPos[i]+kFlatY) compositeToPoint:
NSMakePoint(x, kSystemY+sFlatPos[i]+kFlatY)
operation: NSCompositeSourceOver]; operation: NSCompositeSourceOver];
x += kAccW; x += kAccW;
} }
} }
} }
// - (void)drawRect:(NSRect)rect
// Draw notes {
// if (fNeedsRecalc)
[self drawNotes]; [self recalculateDimensions];
const float kLineW = fClefKeyW + fMeasPerSystem*fMeasureW;
for (int system = 0; system<fNumSystems; ++system) {
const float kSystemY = [self systemY:system];
if (!NSIntersectsRect(rect,
NSMakeRect(kLineX, kSystemY+kClefY,
kLineW, kSystemH-kClefY)
))
continue; // This system does not need to be drawn
[self drawGridForSystem:system];
[self drawNotesForSystem:system];
[self drawChordsForSystem:system];
}
} }
- (IBAction) setKey:(id)sender - (IBAction) setKey:(id)sender
@ -358,4 +362,112 @@ static float sFlatPos[] = {
forKey: @"fShowFieldEditor"]; forKey: @"fShowFieldEditor"];
} }
const float kSemiFloor = -2.5f*kLineH;
static int sSemiToPitch[] = {
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
};
- (VLRegion) findRegionForEvent:(NSEvent *) event
{
fCursorPitch = VLNote::kNoPitch;
const VLProperties & prop = [self song]->fProperties.front();
NSPoint loc = [event locationInWindow];
loc = [self convertPoint:loc fromView:nil];
if (loc.y < 0.0f || loc.y >= fNumSystems*kSystemH)
return kRegionNowhere;
int system = fNumSystems - static_cast<int>(loc.y / kSystemH) - 1;
loc.y = fmodf(loc.y, kSystemH);
loc.x -= fClefKeyW;
if (loc.x < 0.0f || loc.x >= fMeasPerSystem*fMeasureW)
return kRegionNowhere;
int measure = static_cast<int>(loc.x / fMeasureW);
loc.x -= measure*fMeasureW;
int group = static_cast<int>(loc.x / ((fDivPerGroup+1)*kNoteW));
loc.x -= group*(fDivPerGroup+1)*kNoteW;
int div = static_cast<int>(roundf(loc.x / kNoteW))-1;
div = std::min(std::max(div, 0), fDivPerGroup-1);
fCursorAt = VLFraction(div+group*fDivPerGroup, 4*prop.fDivisions);
fCursorMeasure = measure+system*fMeasPerSystem;
if (loc.y >= kSystemY+kChordY)
return kRegionChord;
else if (loc.y < kSystemY+kLyricsY)
return kRegionLyrics;
loc.y -= kSystemY+kSemiFloor;
int semi = static_cast<int>(roundf(loc.y / (0.5f*kLineH)));
fCursorPitch = sSemiToPitch[semi];
return kRegionNote;
}
- (void) mouseMoved:(NSEvent *)event
{
if ([event modifierFlags] & NSAlphaShiftKeyMask)
return; // Keyboard mode, ignore mouse
bool hadCursor = fCursorPitch != VLNote::kNoPitch;
[self findRegionForEvent:event];
bool hasCursor = fCursorPitch != VLNote::kNoPitch;
[self setNeedsDisplay:(hadCursor || hasCursor)];
}
- (void) mouseEntered:(NSEvent *)event
{
[[self window] setAcceptsMouseMovedEvents:YES];
[self mouseMoved:event];
}
- (void) mouseExited:(NSEvent *)event
{
[[self window] setAcceptsMouseMovedEvents:NO];
[self mouseMoved:event];
}
- (void) mouseDown:(NSEvent *)event
{
switch ([self findRegionForEvent:event]) {
case kRegionNote:
[self addNoteAtCursor];
break;
default:
break;
}
}
- (void) keyDown:(NSEvent *)event
{
NSString * k = [event charactersIgnoringModifiers];
switch ([k characterAtIndex:0]) {
case '\r':
[self startKeyboardCursor];
[self addNoteAtCursor];
break;
case ' ':
[self startKeyboardCursor];
VLSoundOut::Instance()->PlayNote(VLNote(1, fCursorPitch));
break;
case 'r':
fIsRest = !fIsRest;
break;
}
}
@end @end

View File

@ -11,6 +11,10 @@
- (IBAction) editChord:(id)sender; - (IBAction) editChord:(id)sender;
- (IBAction) doneEditingChord:(id)sender; - (IBAction) doneEditingChord:(id)sender;
- (void) setupChords; - (void) drawChordsForSystem:(int)system;
@end @end
// Local Variables:
// mode:ObjC
// End:

View File

@ -66,52 +66,31 @@
return s; return s;
} }
- (void) setupChords - (void) drawChordsForSystem:(int)system
{ {
#if 0
const VLSong * song = [self song]; const VLSong * song = [self song];
const VLProperties & prop = song->fProperties.front();
NSView * chordView = [chords contentView];
//
// Delete old list of chord boxes
//
for (NSEnumerator * e = [[chordView subviews] objectEnumerator];
NSView * subview = [e nextObject];
)
[subview removeFromSuperview];
// //
// Build new list // Build new list
// //
NSFont * chordFont = [NSFont controlContentFontOfSize: 14]; for (int m = 0; m<fMeasPerSystem; ++m) {
int beatsPerGroup = quarterBeats / groups; int measIdx = m+system*fMeasPerSystem;
for (int m = 0; m<visibleMeasures; ++m) { if (measIdx >= song->CountMeasures())
const float x0 = clefKeyW+m*measureW; break;
int measure = firstMeasure+m; const VLMeasure measure = song->fMeasures[measIdx];
VLChordList::const_iterator cCur = song->fMeasures[measure].fChords.begin(); const VLChordList & chords = measure.fChords;
VLChordList::const_iterator cEnd = song->fMeasures[measure].fChords.end();
VLFraction at(0); VLFraction at(0);
for (int beat = 0; beat<quarterBeats; ++beat) { for (VLChordList::const_iterator chord = chords.begin();
const float x = x0+kNoteW*(beat*prop.fDivisions+(beat / beatsPerGroup)+0.5f); chord != chords.end();
NSRect f = NSMakeRect(x, 0, kChordW, kChordH); ++chord
NSButton * chord = [[NSButton alloc] initWithFrame: f]; ) {
[chordView addSubview: chord]; NSAttributedString * chordName = [self stringWithChord:*chord];
[chord setBordered: NO]; NSPoint chordLoc =
[chord setTarget: self]; NSMakePoint(kClefX+kClefW+(m+at)*fMeasureW+0.5f*kNoteW,
[chord setAction: @selector(editChord:)]; kSystemY+kChordY);
[chord setTag: (measure << 8) | beat]; [chordName drawAtPoint:chordLoc];
[chord setFont: chordFont];
[chord setTitle: @""];
while (cCur != cEnd && at < VLFraction(beat, 4))
at += (cCur++)->fDuration;
if (cCur != cEnd && at == VLFraction(beat, 4) && cCur->fPitch != VLNote::kNoPitch)
[chord setTitle: [self stringWithChord:*cCur]];
[chord release];
} }
} }
[chords setNeedsDisplay: YES];
#endif
} }
- (IBAction) editChord:(id)sender - (IBAction) editChord:(id)sender

View File

@ -6,8 +6,8 @@
// Copyright 2006 __MyCompanyName__. All rights reserved. // Copyright 2006 __MyCompanyName__. All rights reserved.
// //
const float kLineX = 5; const float kLineX = 5.0;
const float kLineH = 10; const float kLineH = 10.0;
const float kSystemH = 15.0f*kLineH; const float kSystemH = 15.0f*kLineH;
const float kSystemY = 3.0f*kLineH; const float kSystemY = 3.0f*kLineH;
const float kClefX = 20.5f; const float kClefX = 20.5f;
@ -21,8 +21,10 @@ const float kAccW = 10.0f;
const float kSharpY =-15.0f; const float kSharpY =-15.0f;
const float kFlatY = -7.0f; const float kFlatY = -7.0f;
const float kImgScale = 0.04f; const float kImgScale = 0.04f;
const float kChordY = 7.0f*kLineH;
const float kChordW = 40.0f; const float kChordW = 40.0f;
const float kChordH = 25.0f; const float kChordH = 25.0f;
const float kLyricsY = -3.0*kLineH;
const float kNoteX = 7.0f; const float kNoteX = 7.0f;
const float kNoteY = 5.0f; const float kNoteY = 5.0f;
const float kStemX = 0.0f; const float kStemX = 0.0f;

View File

@ -10,14 +10,11 @@
@interface VLSheetView (Notes) @interface VLSheetView (Notes)
- (void) mouseMoved:(NSEvent *)event; - (void) drawNotesForSystem:(int)system;
- (void) mouseDown:(NSEvent *)event; - (void) addNoteAtCursor;
- (void) mouseEntered:(NSEvent *)event;
- (void) mouseExited:(NSEvent *)event;
- (void) drawNotes;
- (void) setNoteCursorMeasure:(int)measure at:(VLFraction)at pitch:(int)pitch;
- (void) hideNoteCursor;
@end @end
// Local Variables:
// mode:ObjC
// End:

View File

@ -15,112 +15,35 @@
@implementation VLSheetView (Notes) @implementation VLSheetView (Notes)
static int sSemiToPitch[] = { - (void) addNoteAtCursor
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
};
- (void) mouseMoved:(NSEvent *)event
{ {
if ([event modifierFlags] & NSAlphaShiftKeyMask) if (fCursorMeasure > -1) {
return; // Keyboard mode, ignore mouse VLNote newNote(1, !fIsRest ? fCursorPitch : VLNote::kNoPitch);
const VLProperties & prop = [self song]->fProperties.front();
NSPoint loc = [event locationInWindow];
loc = [self convertPoint:loc fromView:nil];
loc.x -= fNoteRect.origin.x; [self song]->AddNote(newNote, fCursorMeasure, fCursorAt);
int measure = static_cast<int>(loc.x / fMeasureW);
loc.x -= measure*fMeasureW;
int group = static_cast<int>(loc.x / ((fDivPerGroup+1)*kNoteW));
loc.x -= group*(fDivPerGroup+1)*kNoteW;
int div = static_cast<int>(roundf(loc.x / kNoteW))-1;
div = std::min(std::max(div, 0), fDivPerGroup-1);
VLFraction at(div+group*fDivPerGroup, 4*prop.fDivisions);
loc.y -= fNoteRect.origin.y;
int semi = static_cast<int>(roundf(loc.y / (0.5f*kLineH)));
int pitch = sSemiToPitch[semi];
[self setNoteCursorMeasure:measure at:at pitch:pitch];
}
- (void) addNoteAtCursor:(BOOL)isRest
{
if (fNoteCursorMeasure > -1) {
VLNote newNote(1, !isRest ? fNoteCursorPitch : VLNote::kNoPitch);
[self song]->AddNote(newNote, fNoteCursorMeasure, fNoteCursorAt);
[self setNeedsDisplay:YES]; [self setNeedsDisplay:YES];
VLSoundOut::Instance()->PlayNote(newNote); VLSoundOut::Instance()->PlayNote(newNote);
fIsRest = NO;
} }
} }
- (void) mouseDown:(NSEvent *)event
{
[self mouseMoved:event];
[self addNoteAtCursor: ([event modifierFlags] & NSShiftKeyMask) != 0];
}
- (void) mouseEntered:(NSEvent *)event
{
[[self window] setAcceptsMouseMovedEvents:YES];
[self mouseMoved:event];
}
- (void) mouseExited:(NSEvent *)event
{
[[self window] setAcceptsMouseMovedEvents:NO];
if (!([event modifierFlags] & NSAlphaShiftKeyMask))
[self hideNoteCursor];
}
- (void) startKeyboardCursor - (void) startKeyboardCursor
{ {
if (fNoteCursorMeasure < 0) { if (fCursorMeasure < 0) {
fNoteCursorMeasure = 0; fCursorMeasure = 0;
fNoteCursorPitch = VLNote::kMiddleC; fCursorPitch = VLNote::kMiddleC;
fNoteCursorAt = VLFraction(0); fCursorAt = VLFraction(0);
} }
} }
- (void) keyDown:(NSEvent *)event
{
NSString * k = [event charactersIgnoringModifiers];
switch ([k characterAtIndex:0]) {
case '\r':
[self startKeyboardCursor];
[self addNoteAtCursor];
break;
case ' ':
[self startKeyboardCursor];
VLSoundOut::Instance()->PlayNote(VLNote(1, fNoteCursorPitch));
break;
}
}
- (void) hideNoteCursor
{
fNoteCursorMeasure = -1;
[self setNeedsDisplay:YES];
}
- (void) drawNoteCursor - (void) drawNoteCursor
{ {
NSPoint note = NSPoint note =
NSMakePoint([self noteXInMeasure:fNoteCursorMeasure at:fNoteCursorAt], NSMakePoint([self noteXInMeasure:fCursorMeasure at:fCursorAt],
[self noteYWithPitch:fNoteCursorPitch]); [self noteYInMeasure:fCursorMeasure withPitch:fCursorPitch]);
NSRect noteCursorRect = NSRect noteCursorRect =
NSMakeRect(note.x-kNoteX, note.y-kNoteY, 2.0f*kNoteX, 2.0f*kNoteY); NSMakeRect(note.x-kNoteX, note.y-kNoteY, 2.0f*kNoteX, 2.0f*kNoteY);
[[self musicElement:kMusicNoteCursor] [[self musicElement:kMusicNoteCursor]
@ -245,7 +168,7 @@ static int sSemiToPitch[] = {
operation: NSCompositeSourceOver]; operation: NSCompositeSourceOver];
} }
- (void) drawNotes - (void) drawNotesForSystem:(int)system
{ {
const VLSong * song = [self song]; const VLSong * song = [self song];
const VLProperties & prop = song->fProperties.front(); const VLProperties & prop = song->fProperties.front();
@ -253,8 +176,7 @@ static int sSemiToPitch[] = {
VLFraction swung(3, prop.fDivisions*8, true); // Which notes to swing VLFraction swung(3, prop.fDivisions*8, true); // Which notes to swing
VLFraction swingGrid(2*swung); // Alignment of swing notes VLFraction swingGrid(2*swung); // Alignment of swing notes
for (int system = 0; system<fNumSystems; ++system) { float kSystemY = [self systemY:system];
float kLineY = [self systemY:system];
for (int m = 0; m<fMeasPerSystem; ++m) { for (int m = 0; m<fMeasPerSystem; ++m) {
int measIdx = m+system*fMeasPerSystem; int measIdx = m+system*fMeasPerSystem;
if (measIdx >= song->CountMeasures()) if (measIdx >= song->CountMeasures())
@ -297,35 +219,21 @@ static int sSemiToPitch[] = {
[self drawNote:noteDur [self drawNote:noteDur
at: NSMakePoint( at: NSMakePoint(
[self noteXInMeasure:m at:at], [self noteXInMeasure:m at:at],
kLineY+[self noteYWithPitch:pitch]) kSystemY+[self noteYWithPitch:pitch])
tied:!first]; tied:!first];
else else
[self drawRest:noteDur [self drawRest:noteDur
at: NSMakePoint( at: NSMakePoint(
[self noteXInMeasure:m at:at], [self noteXInMeasure:m at:at],
kLineY+[self noteYWithPitch:65])]; kSystemY+[self noteYWithPitch:65])];
dur -= partialDur; dur -= partialDur;
at += partialDur; at += partialDur;
first = NO; first = NO;
} }
} }
} }
} if (fCursorPitch != VLNote::kNoPitch && fCursorMeasure/fMeasPerSystem == system)
if (fNoteCursorMeasure > -1)
[self drawNoteCursor]; [self drawNoteCursor];
} }
- (void) setNoteCursorMeasure:(int)measure at:(VLFraction)at pitch:(int)pitch
{
if (measure != fNoteCursorMeasure || at != fNoteCursorAt
|| pitch != fNoteCursorPitch
) {
fNoteCursorMeasure = measure;
fNoteCursorAt = at;
fNoteCursorPitch = pitch;
[self setNeedsDisplay:YES];
}
}
@end @end

View File

@ -200,7 +200,47 @@
<key>Content</key> <key>Content</key>
<dict> <dict>
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
<string>95B042FC0ACE431A00236B52</string> <string>95DFE83A0AD105A300375606</string>
<key>PBXProjectModuleLabel</key>
<string>VLSheetView.mm</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict>
<key>Split0</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>95DFE83B0AD105A300375606</string>
<key>PBXProjectModuleLabel</key>
<string>VLSheetView.mm</string>
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
<string>95DFE83E0AD105C900375606</string>
<key>history</key>
<array>
<string>95DFE8370AD1053A00375606</string>
</array>
</dict>
<key>SplitCount</key>
<string>1</string>
</dict>
<key>StatusBarVisibility</key>
<true/>
</dict>
<key>Geometry</key>
<dict>
<key>Frame</key>
<string>{{0, 20}, {763, 552}}</string>
<key>PBXModuleWindowStatusBarHidden2</key>
<false/>
<key>RubberWindowFrame</key>
<string>164 91 763 593 0 0 1024 746 </string>
</dict>
</dict>
<dict>
<key>Content</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>95D1F82E0AB694EC00EE6AC8</string>
<key>PBXProjectModuleLabel</key> <key>PBXProjectModuleLabel</key>
<string>&lt;No Editor&gt;</string> <string>&lt;No Editor&gt;</string>
<key>PBXSplitModuleInNavigatorKey</key> <key>PBXSplitModuleInNavigatorKey</key>
@ -222,7 +262,7 @@
<key>Content</key> <key>Content</key>
<dict> <dict>
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
<string>95B042FB0ACE431A00236B52</string> <string>95D1F7FE0AB68C8C00EE6AC8</string>
<key>PBXProjectModuleLabel</key> <key>PBXProjectModuleLabel</key>
<string>&lt;No Editor&gt;</string> <string>&lt;No Editor&gt;</string>
<key>PBXSplitModuleInNavigatorKey</key> <key>PBXSplitModuleInNavigatorKey</key>
@ -244,7 +284,73 @@
<key>Content</key> <key>Content</key>
<dict> <dict>
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
<string>95B042F70ACE431A00236B52</string> <string>95D1F8130AB6908400EE6AC8</string>
<key>PBXProjectModuleLabel</key>
<string>&lt;No Editor&gt;</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict/>
<key>StatusBarVisibility</key>
<true/>
</dict>
<key>Geometry</key>
<dict>
<key>Frame</key>
<string>{{0, 20}, {763, 552}}</string>
<key>PBXModuleWindowStatusBarHidden2</key>
<false/>
<key>RubberWindowFrame</key>
<string>186 75 763 593 0 0 1024 746 </string>
</dict>
</dict>
<dict>
<key>Content</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>95D1F8850AB69B6700EE6AC8</string>
<key>PBXProjectModuleLabel</key>
<string>&lt;No Editor&gt;</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict/>
<key>StatusBarVisibility</key>
<true/>
</dict>
<key>Geometry</key>
<dict>
<key>Frame</key>
<string>{{0, 20}, {763, 552}}</string>
<key>PBXModuleWindowStatusBarHidden2</key>
<false/>
<key>RubberWindowFrame</key>
<string>168 116 763 593 0 0 1024 746 </string>
</dict>
</dict>
<dict>
<key>Content</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>95D1F8660AB6970400EE6AC8</string>
<key>PBXProjectModuleLabel</key>
<string>&lt;No Editor&gt;</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict/>
<key>StatusBarVisibility</key>
<true/>
</dict>
<key>Geometry</key>
<dict>
<key>Frame</key>
<string>{{0, 20}, {763, 552}}</string>
<key>PBXModuleWindowStatusBarHidden2</key>
<false/>
<key>RubberWindowFrame</key>
<string>15 148 763 593 0 0 1024 746 </string>
</dict>
</dict>
<dict>
<key>Content</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>95D1F8310AB694EC00EE6AC8</string>
<key>PBXProjectModuleLabel</key> <key>PBXProjectModuleLabel</key>
<string>&lt;No Editor&gt;</string> <string>&lt;No Editor&gt;</string>
<key>PBXSplitModuleInNavigatorKey</key> <key>PBXSplitModuleInNavigatorKey</key>
@ -288,7 +394,7 @@
<key>Content</key> <key>Content</key>
<dict> <dict>
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
<string>95D1F8310AB694EC00EE6AC8</string> <string>95B042F70ACE431A00236B52</string>
<key>PBXProjectModuleLabel</key> <key>PBXProjectModuleLabel</key>
<string>&lt;No Editor&gt;</string> <string>&lt;No Editor&gt;</string>
<key>PBXSplitModuleInNavigatorKey</key> <key>PBXSplitModuleInNavigatorKey</key>
@ -310,73 +416,7 @@
<key>Content</key> <key>Content</key>
<dict> <dict>
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
<string>95D1F8660AB6970400EE6AC8</string> <string>95B042FB0ACE431A00236B52</string>
<key>PBXProjectModuleLabel</key>
<string>&lt;No Editor&gt;</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict/>
<key>StatusBarVisibility</key>
<true/>
</dict>
<key>Geometry</key>
<dict>
<key>Frame</key>
<string>{{0, 20}, {763, 552}}</string>
<key>PBXModuleWindowStatusBarHidden2</key>
<false/>
<key>RubberWindowFrame</key>
<string>15 148 763 593 0 0 1024 746 </string>
</dict>
</dict>
<dict>
<key>Content</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>95D1F8850AB69B6700EE6AC8</string>
<key>PBXProjectModuleLabel</key>
<string>&lt;No Editor&gt;</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict/>
<key>StatusBarVisibility</key>
<true/>
</dict>
<key>Geometry</key>
<dict>
<key>Frame</key>
<string>{{0, 20}, {763, 552}}</string>
<key>PBXModuleWindowStatusBarHidden2</key>
<false/>
<key>RubberWindowFrame</key>
<string>168 116 763 593 0 0 1024 746 </string>
</dict>
</dict>
<dict>
<key>Content</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>95D1F8130AB6908400EE6AC8</string>
<key>PBXProjectModuleLabel</key>
<string>&lt;No Editor&gt;</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict/>
<key>StatusBarVisibility</key>
<true/>
</dict>
<key>Geometry</key>
<dict>
<key>Frame</key>
<string>{{0, 20}, {763, 552}}</string>
<key>PBXModuleWindowStatusBarHidden2</key>
<false/>
<key>RubberWindowFrame</key>
<string>186 75 763 593 0 0 1024 746 </string>
</dict>
</dict>
<dict>
<key>Content</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>95D1F7FE0AB68C8C00EE6AC8</string>
<key>PBXProjectModuleLabel</key> <key>PBXProjectModuleLabel</key>
<string>&lt;No Editor&gt;</string> <string>&lt;No Editor&gt;</string>
<key>PBXSplitModuleInNavigatorKey</key> <key>PBXSplitModuleInNavigatorKey</key>
@ -398,7 +438,7 @@
<key>Content</key> <key>Content</key>
<dict> <dict>
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
<string>95D1F82E0AB694EC00EE6AC8</string> <string>95B042FC0ACE431A00236B52</string>
<key>PBXProjectModuleLabel</key> <key>PBXProjectModuleLabel</key>
<string>&lt;No Editor&gt;</string> <string>&lt;No Editor&gt;</string>
<key>PBXSplitModuleInNavigatorKey</key> <key>PBXSplitModuleInNavigatorKey</key>
@ -450,8 +490,6 @@
<key>Layout</key> <key>Layout</key>
<array> <array>
<dict> <dict>
<key>BecomeActive</key>
<true/>
<key>ContentConfiguration</key> <key>ContentConfiguration</key>
<dict> <dict>
<key>PBXBottomSmartGroupGIDs</key> <key>PBXBottomSmartGroupGIDs</key>
@ -497,7 +535,7 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key> <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array> <array>
<array> <array>
<integer>10</integer> <integer>9</integer>
<integer>1</integer> <integer>1</integer>
<integer>0</integer> <integer>0</integer>
</array> </array>
@ -567,6 +605,8 @@
<string>0pt</string> <string>0pt</string>
</dict> </dict>
<dict> <dict>
<key>BecomeActive</key>
<true/>
<key>ContentConfiguration</key> <key>ContentConfiguration</key>
<dict> <dict>
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
@ -603,9 +643,9 @@
</array> </array>
<key>TableOfContents</key> <key>TableOfContents</key>
<array> <array>
<string>9529DCA60AD0E18200C9D67E</string> <string>95DFE81B0AD0F18B00375606</string>
<string>1CE0B1FE06471DED0097A5F4</string> <string>1CE0B1FE06471DED0097A5F4</string>
<string>9529DCA70AD0E18200C9D67E</string> <string>95DFE81C0AD0F18B00375606</string>
<string>1CE0B20306471E060097A5F4</string> <string>1CE0B20306471E060097A5F4</string>
<string>1CE0B20506471E060097A5F4</string> <string>1CE0B20506471E060097A5F4</string>
</array> </array>
@ -739,23 +779,24 @@
<integer>5</integer> <integer>5</integer>
<key>WindowOrderList</key> <key>WindowOrderList</key>
<array> <array>
<string>9529DCB30AD0E40700C9D67E</string> <string>95DFE82C0AD0F29C00375606</string>
<string>9529DCB40AD0E40700C9D67E</string> <string>95DFE82D0AD0F29C00375606</string>
<string>9529DCB50AD0E40700C9D67E</string> <string>95DFE82E0AD0F29C00375606</string>
<string>95D7BFC80AA6C1A500D5E02C</string>
<string>95D1F82E0AB694EC00EE6AC8</string>
<string>95D1F7FE0AB68C8C00EE6AC8</string>
<string>95D1F8130AB6908400EE6AC8</string>
<string>95D1F8850AB69B6700EE6AC8</string>
<string>95D1F8660AB6970400EE6AC8</string>
<string>95D1F8310AB694EC00EE6AC8</string>
<string>95B042FA0ACE431A00236B52</string>
<string>95B042F70ACE431A00236B52</string>
<string>95B042FB0ACE431A00236B52</string>
<string>95B042FC0ACE431A00236B52</string> <string>95B042FC0ACE431A00236B52</string>
<string>95B042FB0ACE431A00236B52</string>
<string>95B042F70ACE431A00236B52</string>
<string>95B042FA0ACE431A00236B52</string>
<string>95D1F8310AB694EC00EE6AC8</string>
<string>95D1F8660AB6970400EE6AC8</string>
<string>95D1F8850AB69B6700EE6AC8</string>
<string>95D1F8130AB6908400EE6AC8</string>
<string>95D1F7FE0AB68C8C00EE6AC8</string>
<string>95D1F82E0AB694EC00EE6AC8</string>
<string>1CD10A99069EF8BA00B06720</string> <string>1CD10A99069EF8BA00B06720</string>
<string>95D7BFC00AA6C1A500D5E02C</string> <string>95D7BFC80AA6C1A500D5E02C</string>
<string>/Development/Vocalese/Vocalese.xcodeproj</string> <string>/Development/Vocalese/Vocalese.xcodeproj</string>
<string>95DFE83A0AD105A300375606</string>
<string>95D7BFC00AA6C1A500D5E02C</string>
</array> </array>
<key>WindowString</key> <key>WindowString</key>
<string>167 326 690 397 0 0 1024 746 </string> <string>167 326 690 397 0 0 1024 746 </string>
@ -774,14 +815,12 @@
<key>Dock</key> <key>Dock</key>
<array> <array>
<dict> <dict>
<key>BecomeActive</key>
<true/>
<key>ContentConfiguration</key> <key>ContentConfiguration</key>
<dict> <dict>
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
<string>1CD0528F0623707200166675</string> <string>1CD0528F0623707200166675</string>
<key>PBXProjectModuleLabel</key> <key>PBXProjectModuleLabel</key>
<string>VLSheetViewNotes.mm</string> <string>VLSheetView.mm</string>
<key>StatusBarVisibility</key> <key>StatusBarVisibility</key>
<true/> <true/>
</dict> </dict>
@ -798,6 +837,8 @@
<string>293pt</string> <string>293pt</string>
</dict> </dict>
<dict> <dict>
<key>BecomeActive</key>
<true/>
<key>ContentConfiguration</key> <key>ContentConfiguration</key>
<dict> <dict>
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
@ -837,7 +878,7 @@
<key>TableOfContents</key> <key>TableOfContents</key>
<array> <array>
<string>95D7BFC00AA6C1A500D5E02C</string> <string>95D7BFC00AA6C1A500D5E02C</string>
<string>9529DCA80AD0E18200C9D67E</string> <string>95DFE81D0AD0F18B00375606</string>
<string>1CD0528F0623707200166675</string> <string>1CD0528F0623707200166675</string>
<string>XCMainBuildResultsModuleGUID</string> <string>XCMainBuildResultsModuleGUID</string>
</array> </array>
@ -957,13 +998,13 @@
<key>TableOfContents</key> <key>TableOfContents</key>
<array> <array>
<string>1CD10A99069EF8BA00B06720</string> <string>1CD10A99069EF8BA00B06720</string>
<string>9529DCA90AD0E18200C9D67E</string> <string>95DFE81E0AD0F18B00375606</string>
<string>1C162984064C10D400B95A72</string> <string>1C162984064C10D400B95A72</string>
<string>9529DCAA0AD0E18200C9D67E</string> <string>95DFE81F0AD0F18B00375606</string>
<string>9529DCAB0AD0E18200C9D67E</string> <string>95DFE8200AD0F18B00375606</string>
<string>9529DCAC0AD0E18200C9D67E</string> <string>95DFE8210AD0F18B00375606</string>
<string>9529DCAD0AD0E18200C9D67E</string> <string>95DFE8220AD0F18B00375606</string>
<string>9529DCAE0AD0E18200C9D67E</string> <string>95DFE8230AD0F18B00375606</string>
</array> </array>
<key>ToolbarConfiguration</key> <key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.debugV3</string> <string>xcode.toolbar.config.debugV3</string>
@ -1090,6 +1131,8 @@
<key>Dock</key> <key>Dock</key>
<array> <array>
<dict> <dict>
<key>BecomeActive</key>
<true/>
<key>ContentConfiguration</key> <key>ContentConfiguration</key>
<dict> <dict>
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
@ -1125,7 +1168,7 @@
<key>TableOfContents</key> <key>TableOfContents</key>
<array> <array>
<string>95D7BFC80AA6C1A500D5E02C</string> <string>95D7BFC80AA6C1A500D5E02C</string>
<string>9529DCB20AD0E40700C9D67E</string> <string>95DFE82B0AD0F29400375606</string>
<string>1C78EAAC065D492600B07095</string> <string>1C78EAAC065D492600B07095</string>
</array> </array>
<key>WindowString</key> <key>WindowString</key>
@ -1133,7 +1176,7 @@
<key>WindowToolGUID</key> <key>WindowToolGUID</key>
<string>95D7BFC80AA6C1A500D5E02C</string> <string>95D7BFC80AA6C1A500D5E02C</string>
<key>WindowToolIsVisible</key> <key>WindowToolIsVisible</key>
<false/> <true/>
</dict> </dict>
<dict> <dict>
<key>Identifier</key> <key>Identifier</key>

View File

@ -62,8 +62,12 @@
PBXFileDataSource_Warnings_ColumnID, PBXFileDataSource_Warnings_ColumnID,
); );
}; };
PBXPerProjectTemplateStateSaveDate = 181460906; PBXPerProjectTemplateStateSaveDate = 181465162;
PBXWorkspaceStateSaveDate = 181460906; PBXWorkspaceStateSaveDate = 181465162;
};
perUserProjectItems = {
95DFE8370AD1053A00375606 /* PBXBookmark */ = 95DFE8370AD1053A00375606 /* PBXBookmark */;
95DFE83E0AD105C900375606 /* PBXTextBookmark */ = 95DFE83E0AD105C900375606 /* PBXTextBookmark */;
}; };
sourceControlManager = 954D7413095406B2007D9571 /* Source Control */; sourceControlManager = 954D7413095406B2007D9571 /* Source Control */;
userBuildSettings = { userBuildSettings = {
@ -155,9 +159,9 @@
}; };
952DCD77096BBB11001C2316 /* VLSheetViewChords.mm */ = { 952DCD77096BBB11001C2316 /* VLSheetViewChords.mm */ = {
uiCtxt = { uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {703, 2114}}"; sepNavIntBoundsRect = "{{0, 0}, {703, 1400}}";
sepNavSelRange = "{4746, 0}"; sepNavSelRange = "{3987, 0}";
sepNavVisRect = "{{0, 1851}, {703, 261}}"; sepNavVisRect = "{{0, 1125}, {703, 261}}";
sepNavWindowFrame = "{{15, 92}, {763, 649}}"; sepNavWindowFrame = "{{15, 92}, {763, 649}}";
}; };
}; };
@ -313,9 +317,9 @@
}; };
95B66657096BCA1F00FE18C9 /* VLSheetViewNotes.mm */ = { 95B66657096BCA1F00FE18C9 /* VLSheetViewNotes.mm */ = {
uiCtxt = { uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {703, 4130}}"; sepNavIntBoundsRect = "{{0, 0}, {703, 2534}}";
sepNavSelRange = "{1225, 0}"; sepNavSelRange = "{5830, 0}";
sepNavVisRect = "{{0, 479}, {703, 261}}"; sepNavVisRect = "{{0, 1499}, {703, 261}}";
sepNavWindowFrame = "{{38, 71}, {763, 649}}"; sepNavWindowFrame = "{{38, 71}, {763, 649}}";
}; };
}; };
@ -332,7 +336,7 @@
hitCount = 0; hitCount = 0;
ignoreCount = 0; ignoreCount = 0;
lineNumber = 21; lineNumber = 21;
modificationTime = 181461973.028078; modificationTime = 181470420.561138;
state = 2; state = 2;
}; };
95BDA15709540BF1009F9D65 /* VLSheetView.h */ = { 95BDA15709540BF1009F9D65 /* VLSheetView.h */ = {
@ -345,10 +349,24 @@
}; };
95BDA15809540BF1009F9D65 /* VLSheetView.mm */ = { 95BDA15809540BF1009F9D65 /* VLSheetView.mm */ = {
uiCtxt = { uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {703, 2814}}"; sepNavIntBoundsRect = "{{0, 0}, {703, 3584}}";
sepNavSelRange = "{8722, 0}"; sepNavSelRange = "{11149, 30}";
sepNavVisRect = "{{0, 2553}, {703, 261}}"; sepNavVisRect = "{{0, 3262}, {703, 261}}";
sepNavWindowFrame = "{{164, 35}, {763, 649}}"; sepNavWindowFrame = "{{164, 35}, {763, 649}}";
}; };
}; };
95DFE8370AD1053A00375606 /* PBXBookmark */ = {
isa = PBXBookmark;
fRef = 95BDA15809540BF1009F9D65 /* VLSheetView.mm */;
};
95DFE83E0AD105C900375606 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 95BDA15809540BF1009F9D65 /* VLSheetView.mm */;
name = "VLSheetView.mm: 394";
rLen = 0;
rLoc = 9493;
rType = 0;
vrLen = 1225;
vrLoc = 9100;
};
} }