Extendable text selection

This commit is contained in:
Matthias Neeracher 2011-09-11 01:15:21 +02:00
parent b831adb136
commit 7dc46ea1de
6 changed files with 104 additions and 31 deletions

View File

@ -100,7 +100,6 @@ enum VLCursorVisual {
int fHighlightEndMeasure;
VLFract fHighlightEndAt;
size_t fHighlightStanza;
bool fHighlightNow;
VLKeyValueUndo * fUndo;
IBOutlet id fFieldEditor;
@ -153,6 +152,7 @@ enum VLCursorVisual {
- (VLEditable *) editTarget;
- (void) setEditTarget:(VLEditable *)editable;
- (void) updateEditTarget;
- (VLRegion) findRegionForEvent:(NSEvent *) event;
- (void) setGroove:(NSString *)groove;

View File

@ -148,6 +148,11 @@ static float sFlatPos[] = {
[[[self window] windowController] setEditTarget:editable];
}
- (void) updateEditTarget
{
[fFieldEditor takeStringValueFrom:[self editTarget]];
}
- (VLSong *) song
{
return [[self document] song];
@ -837,21 +842,26 @@ const float kSemiFloor = -1.0f*kLineH;
- (void) mouseDown:(NSEvent *)event
{
BOOL extend = ([event modifierFlags] & NSShiftKeyMask) != 0;
switch ([self findRegionForEvent:event]) {
case kRegionNote:
fSelEnd = -1;
[self addNoteAtCursor];
[self addNoteAtCursor];
break;
case kRegionChord:
fSelEnd = -1;
[self editChord];
break;
case kRegionLyrics:
fSelEnd = -1;
[self editLyrics];
if (extend && [[self editTarget] canExtendSelection:kRegionLyrics]) {
[[self editTarget] extendSelection:fCursorMeasure at:fCursorAt];
} else {
fSelEnd = -1;
[self editLyrics];
}
break;
case kRegionMeasure:
[self editSelection:([event modifierFlags] & NSShiftKeyMask) != 0];
[self editSelection:extend];
break;
default:
fSelEnd = -1;
@ -861,13 +871,14 @@ const float kSemiFloor = -1.0f*kLineH;
- (void) mouseDragged:(NSEvent *)event
{
bool inMeasureSelection = fCursorRegion == kRegionMeasure;
if (!inMeasureSelection)
[super mouseDragged:event];
VLRegion prevRegion = fCursorRegion;
[super mouseDragged:event];
[self autoscroll:event];
if (inMeasureSelection)
if (prevRegion == kRegionMeasure)
[self adjustSelection:event];
else if ([[self editTarget] canExtendSelection:[self findRegionForEvent:event]])
[[self editTarget] extendSelection:fCursorMeasure at:fCursorAt];
}
- (void) keyDown:(NSEvent *)event
@ -919,11 +930,9 @@ const float kSemiFloor = -1.0f*kLineH;
[editable moveToPrev];
break;
default:
[editable autorelease];
fHighlightStanza = 0xFFFFFFFF;
editable = nil;
editable = nil;
}
[self setEditTarget:editable];
if (editable)
[fFieldEditor selectText:self];
else

View File

@ -16,8 +16,11 @@
size_t fStanza;
size_t fMeasure;
VLFract fAt;
size_t fAnchorMeas;
VLFract fAnchorAt;
size_t fNextMeas;
VLFract fNextAt;
NSString * fText;
}
- (VLLyricsEditable *)initWithView:(VLSheetView *)view

View File

@ -22,8 +22,11 @@
{
size_t endMeas = fMeasure;
VLFraction endAt = fAt;
fSong->NextWord(fStanza, endMeas, endAt);
if (!fSong->NextWord(fStanza, endMeas, endAt))
endMeas = 1000;
[fView highlightTextInStanza:fStanza startMeasure:fMeasure at:fAt endMeasure:endMeas at:endAt];
std::string word = fSong->GetWord(fStanza, fMeasure, fAt);
fText = [[NSString alloc] initWithUTF8String:word.c_str()];
}
- (VLLyricsEditable *)initWithView:(VLSheetView *)view
@ -38,6 +41,8 @@
fStanza = stanza;
fMeasure = measure;
fAt = at;
fAnchorMeas = measure;
fAnchorAt = at;
fNextMeas = fMeasure;
fNextAt = fAt;
@ -49,10 +54,14 @@
return self;
}
- (void)dealloc
{
[fText release];
}
- (NSString *) stringValue
{
std::string word = fSong->GetWord(fStanza, fMeasure, fAt);
return [NSString stringWithUTF8String:word.c_str()];
return fText;
}
- (void) setStringValue:(NSString *)val
@ -111,6 +120,51 @@
[fView highlightLyricsInStanza:fStanza measure:fMeasure at:fAt];
}
- (BOOL)canExtendSelection:(VLRegion)region
{
return region == kRegionLyrics;
}
- (void)extendSelection:(size_t)measure at:(VLFract)At
{
VLFraction at = At;
if (!fSong->FindWord(fStanza, measure, at))
return;
if (measure < fAnchorMeas || (measure==fAnchorMeas && at < fAnchorAt)) {
//
// Backward from anchor
//
fMeasure = measure;
fAt = at;
measure = fAnchorMeas;
at = fAnchorAt;
} else {
//
// Forward from anchor
//
fMeasure = fAnchorMeas;
at = fAnchorAt;
fSong->FindWord(fStanza, fMeasure, at);
fAt = at;
at = At;
}
if (!fSong->NextWord(fStanza, measure, at))
measure = 1000;
[fView highlightTextInStanza:fStanza startMeasure:fMeasure at:fAt endMeasure:measure at:at];
std::string text;
size_t textMeas = fMeasure;
VLFraction textAt = fAt;
while (textMeas < measure || (textMeas == measure && textAt < at)) {
if (text.size())
text += ' ';
text += fSong->GetWord(fStanza, textMeas, textAt);
fSong->NextWord(fStanza, textMeas, textAt);
}
[fText release];
fText = [[NSString alloc] initWithUTF8String:text.c_str()];
[fView updateEditTarget];
}
@end
class VLCocoaFontHandler : public VLFontHandler {
@ -192,23 +246,17 @@ float VLCocoaFontHandler::Width(const char * utf8Text)
) {
;
} else {
if (!fHighlightNow) {
fHighlightNow = stanza == fHighlightStanza
&& measIdx == fHighlightStartMeasure
&& at == fHighlightStartAt;
if (fHighlightNow && !sHighlightColor)
sHighlightColor =
[[self textBackgroundColorForSystem:system]
shadowWithLevel:0.2];
} else {
fHighlightNow = fHighlightNow && stanza == fHighlightStanza
&& (measIdx < fHighlightEndMeasure
||(measIdx == fHighlightEndMeasure && at < fHighlightEndAt));
}
bool highlight = stanza == fHighlightStanza
&& (measIdx > fHighlightStartMeasure
|| (measIdx == fHighlightStartMeasure && at >= fHighlightStartAt))
&& (measIdx < fHighlightEndMeasure
|| (measIdx == fHighlightEndMeasure && at < fHighlightEndAt));
if (highlight && !sHighlightColor)
sHighlightColor = [[self textBackgroundColorForSystem:system] shadowWithLevel:0.2];
text.AddSyllable(note->fLyrics[stanza-1],
[self noteXInMeasure:measIdx at:at],
fHighlightNow);
highlight);
}
at += note->fDuration;
}
@ -249,7 +297,7 @@ float VLCocoaFontHandler::Width(const char * utf8Text)
fHighlightStartAt = startAt;
fHighlightEndMeasure = endMeasure;
fHighlightEndAt = endAt;
fHighlightNow = false;
[self setNeedsDisplay:YES];
}
@end

View File

@ -10,6 +10,7 @@
#import <Cocoa/Cocoa.h>
#import <AudioToolbox/AudioToolbox.h>
#import "VLSheetView.h"
@interface VLEditable : NSObject
{
@ -21,6 +22,8 @@
- (void) moveToNext;
- (void) moveToPrev;
- (void) highlightCursor;
- (BOOL) canExtendSelection:(VLRegion)region;
- (void) extendSelection:(size_t)measure at:(VLFract)at;
@end

View File

@ -44,6 +44,15 @@
{
}
- (BOOL)canExtendSelection:(VLRegion)region
{
return NO;
}
- (void)extendSelection:(size_t)measure at:(VLFract)at
{
}
@end
@implementation VLSheetWindow
@ -82,6 +91,7 @@
- (void)setEditTarget:(VLEditable *)editable
{
[editTarget autorelease];
editTarget = editable;
}