025. SuperCollider.app Quick Hack(1) Enterじゃなくて⌘ + Returnで実行したい

突如Cocoaがやりたくなったので,Languageを見ていく.

Language.xcodeproj
です.

こっちはSuperColliderのApplicationの実装です.

知りたいのは,テキストを選択してenterを押したときに何が起こっているのか?
である.

まずは,SCはDocument Based Applciationなので
MyDocumentがDocumentの実装である.

で,nibファイルが読み込まれた後

- (void)windowControllerDidLoadNib:(NSWindowController*) aController

が呼ばれるので,こいつを見ていく.

- (void)windowControllerDidLoadNib:(NSWindowController*) aController

{

    [super windowControllerDidLoadNib:aController];

    NSSize contentSize;

    contentSize = [scrollView contentSize];

    if (initTextView) {

        textView = initTextView;

    } else {

        textView = [self makeTextView];

    }

    [scrollView setDocumentView: textView];

…..

ということで,

firstWindow

は,postというタイトルのコンソール用だと予測できる.

bool firstWindow = true;

なので,最初はtrue

initTextViewは最初はnilなので

textView = [self makeTextView];

が呼ばれる.

MyDocument.M: 70

- (SCTextView*)makeTextView

{

    SCTextView* aTextView = [[SCTextView alloc] initWithFrame

                    NSMakeRect(0,0,612,512)];

    [aTextView setAutoresizingMask: 63];

    [[aTextView textContainer] setWidthTracksTextView: YES];

    [aTextView setDelegate: self];

    [aTextView setAllowsUndo: YES];

    [aTextView setRichText: YES];

    [aTextView setSmartInsertDeleteEnabled: NO];

    [aTextView setImportsGraphics: YES];

    [aTextView setFont: [NSFont fontWithName: @"Monaco" size: 9]];

    [aTextView setLangClassToCall:@"CocoaDocument" 

            withKeyDownActionIndex:4 withKeyUpActionIndex:5];

    [aTextView setObjectKeyDownActionIndex:2 setObjectKeyUpActionIndex:1];

    [aTextView setAcceptsFirstResponder:YES];

    isRichText = YES;

    return aTextView;

}

ということで,いつもSinOscとか打ってるのはSCTextViewであることが分かる.

ということは当然,enter押して呼ばれているのは
SCTextView.M: 154

- (void) keyDown: (NSEvent*) event

これ.

で,enterで実行してるのは

    if ([characters isEqual: @"\03"]) {

        [[self delegate] executeSelection: self];

    }

これ.

MyDocument.M: 70

[aTextView setDelegate: self];

なので,delegateはMyDocumentです.

MyDocument.M: 587

- (IBAction) executeSelection: (id) sender

{

    [self sendSelection: "interpretPrintCmdLine" ];

}

MyDocument.M: 922

- (void)sendSelection: (char*) methodName

{        

    if (!compiledOK) {

        return;

    }

    NSRange selectedRange;

    NSString* selection = [textView currentlySelectedTextOrLine: &selectedRange];

    const char *text = [selection UTF8String];

    int textlength = strlen(text);

    [[SCVirtualMachine sharedInstance] setCmdLine: text length: textlength];

    

    NSRange newSelectedRange = NSMakeRange(selectedRange.location + selectedRange.length, 0);

    [textView setSelectedRange: newSelectedRange];

    

    pthread_mutex_lock(&gLangMutex);

    runLibrary(getsym(methodName));

    pthread_mutex_unlock(&gLangMutex); 

}

ということで,SCVirtualMachineにテキストを送って

runLibrary(getsym(methodName));

すると動くらしい.

ということは,SC Editorを作るにはTextViewのDelegateにMyDocumentをセットする必要があるということになる.

しかし,これは設計よくないなー.
SCTextViewが他のClassに依存しまくりじゃーないですか.涙

気を取り直してHack.

Quick Hack

僕は家では,Apple Keyboardを使っているので,enterが遠い.果てしなく遠い.
なので⌘ + returnで実行したい.
しかし,⌘ + returnではTextViewのkeydownが呼ばれない.

- (void) keyDown: (NSEvent*) event

{

NSLog(@”%s”,__PRETTY_FUNCTION__);

とでも書いて,キーを叩いてみるといい.

⌘キーは,ショートカットで使われるので別扱いなわけです.
(⌘はたぶんwindowsで文字化けしますが,気にせず書く)

ということで,ショートカットのときに呼ばれるmethodを上書きしてあげればよい.

NSResponderの

- (BOOL)performKeyEquivalent:(NSEvent *)theEvent;

をオーバーライドしてあげる.

SCTextView.Mに

- (BOOL)performKeyEquivalent:(NSEvent *)theEvent{

    if ([theEvent modifierFlags] & NSCommandKeyMask && [[theEvent characters] isEqualToString:@”\r”]) {

        [self keyDown:theEvent];

        return YES;

    }else{

        return [super performKeyEquivalent:theEvent];

    }

}

を追加して

SCTextView.M: 191

keyDownの

if ([characters isEqual: @"\03"]) {

if ([characters isEqual: @"\03"] || ([characters isEqual: @"\r"] && [event modifierFlags] & NSCommandKeyMask)){

に修正.
Enterか⌘ + Returnのときは実行するように変更したわけです.

これは便利だーあー.

SCCR初,役に立ちそうな記事になった!うほほ.

SCのDocument ClassのkeyDownでもこればかりは無理な模様.

このエントリーをはてなブックマークに追加

Leave a Reply

You must be logged in to post a comment.