ページ

2008年5月16日金曜日

ThinButton(その3)ボタンの部品化

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

感じがつかめたので使い回せるように手を入れる。

ソース: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で複数のボタンを処理した方が良い気がしてきた。