感じがつかめたので使い回せるように手を入れる。
ソース:ThinButton-3.zip
ボタンを押した時のメッセージ送り先 _target と ボタンを識別するための_tagを追加した。また影を付けたいので shadowも保持することにした。
ThinButton.h
@interface ThinButton : NSView {
NSImage *_image;
NSTrackingArea* _tracking_area;
UInt _state;
NSShadow* shadow;
id _target;
UInt _tag;
}
- (id)initWithImageResource:(NSString*)resource atPoint:(NSPoint)point target:(id)target tag:(UInt)tag
;
- (UInt)tag;
@end
初期化は専用のイニシャライザで行なう。この中で画像をバンドルから取り出した後、NSViewの初期化を行なう。その他、トラッキングエリアの登録と影の準備を行なう。
ThinButton.m
- (id)initWithImageResource:(NSString*)resource atPoint:(NSPoint)point target:(id)target tag:(UInt)tag
{
NSImage *image = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForImageResource:resource]];
NSRect frame;
frame.origin = point;
frame.size = [image size];
frame.size.width += 1.0;
frame.size.height += 1.0;
self = [super initWithFrame:frame];
if (self) {
_image = image;
[_image setFlipped:YES];
NSRect track_rect = frame;
track_rect.origin = NSZeroPoint;
_tracking_area = [[NSTrackingArea alloc] initWithRect:track_rect
options:(NSTrackingMouseEnteredAndExited|NSTrackingActiveInKeyWindow)
owner:self
userInfo:nil];
[self addTrackingArea:_tracking_area];
shadow = [[NSShadow alloc] init];
[shadow setShadowOffset:NSMakeSize(1.0, -1.0)];
[shadow setShadowBlurRadius:2.0];
[shadow setShadowColor:[[NSColor blackColor] colorWithAlphaComponent:0.5]];
_state = 0;
_target = target;
_tag = tag;
}
return self;
}
その他は前回までとほとんど同じ。違うのはマウスを押した時にターゲットへイベントを送る処理を追加したところ。メソッドの存在をチェックした上でメッセージを送る。
- (void)mouseUp:(NSEvent *)theEvent {
[self changeState:1];
if ([_target respondsToSelector:@selector(click:)]) {
[_target performSelector:@selector(click:) withObject:self];
}
}
一方、このボタンを使う側のコードはこんな感じ。
AppController.m
-(void)awakeFromNib
{
ThinButton *button;
button = [[[ThinButton alloc] initWithImageResource:@"icon_cancel"
atPoint:NSMakePoint(100,100)
target:self
tag:TAG_CANCEL] autorelease];
[[_window contentView] addSubview:button];
button = [[[ThinButton alloc] initWithImageResource:@"icon_timer"
atPoint:NSMakePoint(122,100)
target:self
tag:TAG_TIMER] autorelease];
[[_window contentView] addSubview:button];
button = [[[ThinButton alloc] initWithImageResource:@"icon_record"
atPoint:NSMakePoint(144,100)
target:self
tag:TAG_RECORD] autorelease];
[[_window contentView] addSubview:button];
}
initWithImageResource: を使い初期化した後、NSWindowの contentViewのサブビューとして追加していく。
ボタンが押されたら click: が呼ばれる。[sender tag] によりどのボタンが押されたかが判別できる。
-(void)click:(id)sender
{
NSLog(@"%@, %d", sender, [sender tag]);
}
サンプルを実行すると3つのボタンが薄らと表示される。
マウスカーソルを載せたり、押すと、透明度が変化する。
- - - -
簡単にできたがボタン一つ一つが NSViewなのがちょっとひっかかる。1つの NSViewで複数のボタンを処理した方が良い気がしてきた。