BezierPathViewの初期化方法を変更する
ツールチップに設定した文字列で設定を変えるという方法はトリッキーな感じがして元々あまり気に入らなかったのですが、それに加えて動作確認中にツールチップがちらついたり、下のウィンドウに配置されたビューのツールチップが表示されてしまったりといった問題も発生してしまいました。そこで初期設定を別の方法で行なう事にしました。
これまでは自分の初期化は自分で行なう方針でしたが、これをやめてEnclosureViewに設定してもらう事にします。そこでバインディングに使うキーパスと、X軸用のビューであるかどうかを設定するメソッドsetKeyPath:isXView:を用意します。
インターフェイスファイルにメソッドの宣言を追加します。
//
// BezierPathView.h
// RepeatingMotifGenerator
//
// Copyright NovemberKou 2008. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface BezierPathView : NSView
{
IBOutlet NSArrayController *controller;
BOOL isXView, multipleSelection, noSelection;
NSBezierPath *dataPath, *displayPath;
}
- (NSBezierPath *)dataPath;
- (void)setDataPath:(NSBezierPath *)newPath;
- (void)setKeyPath:(NSString *)keyPath isXView:(BOOL)isX;
@end
setKeyPath:isXView:メソッドを実装します。実施している内容は、isXViewフラグの設定と、dataPathのバインディングの設定だけです。".bezierPath"は必ず末尾につくとわかっているので、引数には含めずこのメソッドで付け足す事にしました。
//
// BezierPathView.m
//
- (void)setKeyPath:(NSString *)keyPath isXView:(BOOL)isX
{
isXView = isX;
[self bind:@"dataPath"
toObject:controller
withKeyPath:[keyPath stringByAppendingString:@".bezierPath"]
options:nil];
}
以前はawakeFromNibでdataPathのバインディングを設定していましたが、setKeyPath:isXView:メソッドで設定する様に変更したので、その部分を削除します。
//
// BezierPathView.m
//
- (void)awakeFromNib
{
[self bind:@"dataPath"
toObject:controller
withKeyPath:[self keyPath]
options:nil];
[self bind:@"selectionIndexes"
toObject:controller
withKeyPath:@"selectionIndexes"
options:nil];
}
EnclosureViewでBezierPathViewを初期化する
EnclosureViewでBezierPathViewを初期化する為にアウトレットを追加、変更します。OscillatorViewは数が二個から六個に増えたので、名称を変更します。そしてlissajousViewを削除して、代わりに原図とミキサーのビューを追加します。viewMasterが原図のビュー、viewXとviewYがそれぞれX軸とY軸のミキサー用のビューです。
//
// EnclosureView.h
// RepeatingMotifGenerator
//
// Copyright NovemberKou 2008. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@class OscillatorView, BezierPathView;
@interface EnclosureView : NSView
{
IBOutlet OscillatorView *x1View,*x2View,*x3View;
IBOutlet OscillatorView *y1View,*y2View,*y3View;
IBOutlet BezierPathView *viewX,*viewY,*viewMaster;
IBOutlet OscillatorView *xView, *yView;
IBOutlet NSView *lissajousView;
IBOutlet NSArrayController *controller;
IBOutlet NSTextField *frequencyTextField, *phaseLagTextField;
IBOutlet NSSlider *frequencySlider, *phaseLagSlider;
IBOutlet NSStepper *phaseLagStepper;
int whiteSpace,viewMargin;
OscillatorView *selectedView;
}
- (void)selectOscillator:(OscillatorView *)sender;
@end
awakeFromNibに初期化コードを追加します。ついでにOscillatorViewの選択を明示的に行なう様に変更しました。
//
// EnclosureView.m
//
- (void)awakeFromNib
{
selectedView = nil;
[self selectOscillator:x1View];
[self frameDidChange:nil];
[viewMaster setKeyPath:@"selection" isXView:NO];
[viewX setKeyPath:@"selection.x" isXView:YES];
[viewY setKeyPath:@"selection.y" isXView:NO];
[x1View setKeyPath:@"selection.x.osc1" isXView:YES];
[x2View setKeyPath:@"selection.x.osc2" isXView:YES];
[x3View setKeyPath:@"selection.x.osc3" isXView:YES];
[y1View setKeyPath:@"selection.y.osc1" isXView:NO];
[y2View setKeyPath:@"selection.y.osc2" isXView:NO];
[y3View setKeyPath:@"selection.y.osc3" isXView:NO];
}
OscillatorViewの変更点
例えばキーパスが"selection.x.osc1.bezierPath"の場合、"selection.x.osc1"がsetKeyPath:isXView:の引数として渡されるので、これを保持します。実際の切替えはEnclosureViewが行ないますので、oscillatorKeyPathメソッドで参照できる様にします。
//
// OscillatorView.h
// RepeatingMotifGenerator
//
// Copyright NovemberKou 2008. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "BezierPathView.h"
@interface OscillatorView : BezierPathView
{
BOOL selected;
NSString *oscillatorKeyPath;
}
- (NSString *)oscillatorKeyPath;
- (BOOL)selected;
- (void)setSelected:(BOOL)isSelected;
@end
keyPathメソッドは不要になったので削除します。
初期化メソッドとdeallocメソッドを追加します。初期化メソッドではインスタンス変数oscillatorKeyPathの初期値をセットしていますが、何もセットしないと起動時にスライダーやテキストフィールドのバインディングを設定するコードでエラーが発生するので、その対策としてセットしています。deallocメソッドでは保持していたキーパスを解放します。
setKeyPath:isXView:メソッドをオーバーライドして、キーパスを保持するコードを追加しています。
//
// OscillatorView.m
//
- (NSString *)keyPath
{
NSString *viewName;
viewName = [[self toolTip] substringWithRange:NSMakeRange(0,1)];
isXView = [viewName isEqualToString:@"x"];
selected = isXView;
return [NSString stringWithFormat:@"selection.%@.bezierPath",viewName];
}
#pragma mark -
#pragma mark Initializer and Deallocator
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if(self)
{
selected = NO;
oscillatorKeyPath = @"selection.x.osc1";
}
return self;
}
- (void)dealloc
{
[oscillatorKeyPath release];
[super dealloc];
}
#pragma mark -
#pragma mark Accessor methods
- (NSString *)oscillatorKeyPath {return oscillatorKeyPath;}
- (void)setKeyPath:(NSString *)keyPath isXView:(BOOL)isX
{
[super setKeyPath:keyPath isXView:isX];
[keyPath retain];
[oscillatorKeyPath release];
oscillatorKeyPath = keyPath;
}

ホーム
前へ