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でもこればかりは無理な模様.
|
|
