Geometry 関数
NSBundle
NSDictionary
NSFileManager
NSMutableAttributedString
NSNumber
NSScanner
NSString
NSTimer
Graphic 関数
NSApplication
NSBezierPath
NSCell
NSColor
NSCursor
NSCustomImageRep
NSDocument
NSDocumentController
NSDragging
NSEvent
NSFontManager
NSGraphicsContext
NSImage
NSMenu
NSOutlineView
NSPanel
NSPopUpButton
NSResponder
NSScrollView
NSString 追加
NSTableColumn
NSTableView
NSTextStorage
NSTextView
NSToolbar
NSView
-View にカーソルを対応付ける
-drawRect 以外で描画する
-コンテキストメニューを動的に変化させる
-フォーカスリングのスタイルを変える
NSWindow
NSWorkspace
その他
.nib ウィンドウ
Views パレット
クラス
インスタンス変数
メソッド
CFXML
Carbon Event
Carbon Graphics
Cocoa で日本語
メソッド
その他

- Application Kit-
NSView

Application Kit - NSView
View にカーソルを対応付ける
Keywords: resetCursorRects, addCursorRect

ある View とカーソルを対応付けられたら、便利だと思わないかい?View にマウスが入ったら、カーソルが変わる、出たら戻る、って感じの動作。

そのための機構が用意されている。Tracking Rect ってやつだ。Tracking Rect として、ある rect をセットしてやると、そこへマウスが入る時と、出る時が監視されるんだ。Tracking Rect の詳しい話は他に譲るとして、NSView にはカーソルと Tracking Rect を結び付けるための便利なメソッドが用意されているんだ。

まず、resetCurosorRects というメソッドだ。

Application Kit/NSView.h
- (void)resetCursorRects;

このメソッドは NSView がカーソル用の Tracking Rect を設定する時に使われるんだ。ユーザがオーバーライドする。カーソル用 Tracking Rect は、View の大きさが変わったり、ウィンドウの大きさが変わったりした時に、リセットされる。その度にこのメソッドが呼び出されるわけ。

resetCursorRects の中では、addCursorRect:cursor: を使おう。

Application Kit/NSView.h
- (void)addCursorRect:(NSRect)aRect 
        cursor:(NSCursor*)aCursor;

addCurosrRect:: で、カーソル用 Tracking Rect を追加できる。aRect の領域に入ったら、aCursor のカーソルに変わるんだ。

CursorView.m (sample)
- (void)resetCursorRects
{
    NSRect rect = [self bounds];
    NSCursor* cursor = [NSCursor IBeamCursor];
    [self addCursorRect:rect cursor:cursor];
}

これで、この View の領域に入った時、カーソルが I ビームカーソルに変わるぞ。


Application Kit - NSView
drawRect 以外で描画する
Keywords: displayIfNeeded

View になにかを描くときは、drawRect: メソッドをオーバーライドして、その中でいろいろやるのが普通だ。でも、それ以外のタイミングでやりたくなるときもあるよね。そんなときは、displayIfNeeded を使う。

Application Kit/NSView.h
- (void)displayIfNeeded;

View に対してなんらかの描画をしたあと、displayIfNeeded を呼べば、システムがよきにはからってくれるわけ。

DisplayView.m (sample)
- (void)initWithFrame:(NSRect)rect
{
    self = [super initWithFrameRect:rect];
    if(self) {
        NSArray* array = 
            [NSArray arrayWithObject:NSFilenamesPboardType];
        [self registerForDraggedTypes:array];
    }
    return self;
}

- (unsigned int)draggingEntered:(id <NSDraggingInfo>)sender
{
    NSFrameRect([self visibleRect]);
    [self dispalyIfNeeded];
    
    return NSDragOperationNone;
}

- (void)draggingExited:(id <NSDraggingInfo>)sender
{
    NSEraseRect([self visibleRect]);
    [self dispalyIfNeeded];
}

上のサンプルは、Finder からファイルをドラッグしてきたときに、View をハイライト表示させる例だ。draggingEntered: の中で、NSFrameRect を使って枠を描いてる。その後に displayIfNeeded を呼んで、システムにアップデートをお願いしているんだ。draggingExited: の方も同様だね。


Application Kit - NSView
コンテキストメニューを動的に変化させる
Keywords: menuForEvent

NSResponder で解説した通り、コンテキストメニューを設定できるんだ。そのメニューを、状況に応じて動的に変化させたい場合には?その場合には NSView のメソッドである menuForEvent: を使うんだ。

Application Kit/NSView.h
- (NSMenu *)menuForEvent:(NSEvent *)event;

ctrl + クリックなど、コンテキストメニューを表示させようとすると、このメソッドが呼び出される。で、好きなメニューを作って、返してやればいいんだ。そうすれば、それが表示される。引数として NSEvent が渡されるので、マウスの位置とか、好きな情報を取り出して使えばいいんだ。

■関連リンク:
コンテキストメニューを設定する (NSResponder)


Application Kit - NSView
フォーカスリングのスタイルを変える
Keywords: NSFocusRingType

Mac OS X 10.3 からは、NSView と NSCell に、フォーカスリングのタイプを設定できるようになった。フォーカスリングっていうのは、テキストビューとかにフォーカスがあたったときに、周りに描かれるあれね。

フォーカスリングのタイプは、NSFocusRingType 定数として定義されている。次の 3 つがあるんだ。

Application Kit/NSGraphics.h
typedef enum _NSFocusRingType {
    NSFocusRingTypeDefault = 0,
    NSFocusRingTypeNone = 1,
    NSFocusRingTypeExterior = 2
} NSFocusRingType;

NSFocusRingTypeDefault は、NSView か NSCell で定義されているデフォルトのタイプを使う。NSFocusRingTypeNone は、フォーカスリング無し。NSFocusRingTypeExterior は、標準のフォーカスリングで、外側に描くやつだ。ま、実質 NSFocusRingTypeExterior しかないようなもんだ。

このフォーカスリングを取得、設定するには、NSView か NSCell の focusRingType、setFocusRingType を使う。

Application Kit/NSView.h
- (NSFocusRingType)focusRingType;
- (void)setFocusRingType:(NSFocusRingType)focusRingType;

ここでフォーカスリングとしてデフォルト(NSFocusRingTypeDefault)が設定されると、NSView か NSCell の defaultFocusRingType が呼ばれる。ここで得られる値がデフォルトとして使われるんだ。

Application Kit/NSView.h
+ (NSFocusRingType)defaultFocusRingType;

だから、これを上書きすれば、デフォルトのフォーカスリングを変更できる。たとえば、こんな感じで。

(sample)
@interface NSView (DefaultFocusRingType)
+ (NSFocusRingType)defaultFocusRingType;
@end

@implementation NSView (DefaultFocusRingType)
+ (NSFocusRingType)defaultFocusRingType
{
    return NSFocusRingTypeNone;
}
@end

これはカテゴリを使って、NSView の defaultFocusRingType を書き換えてみた例だ。NSFocusRingTypeNone を返すようにしてみた。これで、デフォルトの挙動を変更できるぜ。



[Home] [Download] [Archives] [BBS] [Cocoa Programming Tips 1001] [Core Foundation の秘密] [Safari Developer Center] [はじめてのブラウザのつくり方] [Sketch BP] [スクリーンセイバーを作ろう] [Objective-C 最適化] [Authorization API 完全理解] [Mac OS X Programming Books Review] [オブジェクト指向の言語比較論] [panther-dev]

mailto: mkino@xd5.so-net.ne.jp