タイトル鶴薗賢吾のCocoaはやっぱり!出張版》補足-#5-Mac OS X 10.1の新機能 2(その1)カテゴリーCocoa, Mac OS X, 鶴薗賢吾のCocoaはやっぱり!出張版
作成日2001/10/21 23:57:57作成者新居雅行
■ 今回のテーマ
今回は、第4回の「 Mac OS X 10.1の新機能 」で書いていなかった機能について説明を行っていきます。Mac OS X 10.1の新機能や変更点の詳細は、Appleからのリリースノートに記述されていますので、必要に応じて参照してください。

◇Appleサイト
 http://developer.apple.com/techpubs/macosx/ReleaseNotes/index.html
◇ハードディスク上 ( Developer Toolsをインストールした場合 )
 /Developer/Documentation/ReleaseNotes/

また、10.0.4から10.1での詳細な変更点が書かれたテクニカルノートもAppleのサイトにアップされましたので、こちらも参考にされるとよいと思います。

◇Technical Note TN2029: Mac OS X v10.1
 http://developer.apple.com/technotes/tn/tn2029.html

■ ライブリサイズ
NSViewには、「 ユーザーが現在ウィンドウのリサイズしているかどうか 」を知るためのメソッドが追加されました。inLiveResizeというメソッドです。ウィンドウがリサイズされている最中には、ウィンドウのサイズが変わるたびに、NSView内を描画するメソッドであるdrawRect : が繰り返し呼ばれます。

しかしながら、描画処理が重たい場合は、リサイズも重くなり操作性に影響します。そのため、「 ウィンドウのサイズが確定したときのみ描画したい 」とか、「 ライブリサイズ中はラフな描画に切り替えたい 」ということがあると思います。そういうときには、drawRect : の中でinLiveResizeを呼んで判定すればよいのです。

また、ライブリサイズ開始直前と終了直後には、NSViewのviewWillStartLiveResizeとviewDidEndLiveResizeが呼ばれるようになりました。ライブリサイズ時に別の描画を行う場合、初期化処理や終了処理が必要であればここに記述します。さらに、viewDidEndLiveResizeから、[ self setNeedsDisplay : YES ] を実行して、通常の描画を行わせるようにしておきます。

では、ライブリサイズ中には画像を描画しないNSImageViewを作ってみましょう。NSImageViewのサブクラスとして、NSQuickImageViewを作ったとします。このクラスに以下の2つのメソッドを実装することで、実現できます。

// NSQuickImageView.m

// 描画が必要なときに呼ばれる

- (void) drawRect : (NSRect) rect {

if ( [ self inLiveResize ] ) { // ライブリサイズ中か判定
[ [ NSColor grayColor ] set ]; // グレーで
[ NSBezierPath fillRect : rect ]; // 矩形の塗りつぶし
}
else
[ super drawRect : rect ]; // NSImageViewにおまかせ

}

// ライブリサイズ終了直後に呼ばれる

- (void) viewDidEndLiveResize {
[ self setNeedsDisplay : YES ]; // 通常の再描画を行わせる
}

このようにすると、リサイズ中は、グレーに塗りつぶすだけになり、ウィンドウのサイズが確定したところで、通常の画像描画が行われます。実行結果は以下のようになります。

図. ライブリサイズ中の描画を軽くしたときの実行結果
 

 ★ ライブリサイズ中かを取得
  [書式] - (BOOL) inLiveResize
  [出力] 返り値 : ライブリサイズ中なら - YES、そうでないなら - NO

 ★ ライブリサイズ開始直前の処理を行う
  [書式] - (void) viewWillStartLiveResize

 ★ ライブリサイズ終了直後の処理を行う
  [書式] - (void) viewDidEndLiveResize

■ 3つ以上のボタンがあるデバイスのサポート
最近のマウスは、色々な種類があり、ボタンが3つ以上付いているものも多くなりましたが、これらのサポートも簡単に行えるようになりました。

3つ目以降のボタンのイベントを受け付けるために、NSResponderクラス ( イベントを受け付けるクラス ) に、otherMouseDown : 、otherMouseUp : 、otherMouseDragged : というメソッドが追加されました。これらのメソッドは、3つ目以降のボタンの操作が行われたときに呼び出されます。通常は、NSViewのサブクラスにこれらのメソッドを書いてイベント処理を行うことになります。

 ★ 3つ目以降のボタンが押された
  [書式] - (void) otherMouseDown : (NSEvent *) theEvent
  [入力] theEvent : イベント情報

 ★ 3つ目以降のボタンが放された
  [書式] - (void) otherMouseUp : (NSEvent *) theEvent
  [入力] theEvent : イベント情報

 ★ 3つ目以降のボタンでドラッグされた
  [書式] - (void) otherMouseDragged : (NSEvent *) theEvent
  [入力] theEvent : イベント情報

3つ目以降のどのボタンの操作なのかは、パラメータで受け取ったNSEventのbuttonNumberというメソッドを使うことで判別できます。左のボタンが0で、右のボタンが1、3番目のボタンが2というように値が増えていきます。

マウスの種類に依存するかもしれませんが、最近よくあるホイールがクリックできるマウスの場合は、これが3つ目のボタンになるようです。

 ★ どのボタンのイベントかを取得
  [書式] - (int) buttonNumber
  [出力] int : ボタンの番号 ( 左ボタン - 0、右ボタン - 1、3つ目のボタン - 2、... )

これにともなって、イベントの種類を表す定数や、イベントのマスクを行うための定数も増えています。

// イベントの種類を表す定数
typedef enum _NSEventType {
NSLeftMouseDown = 1,
NSLeftMouseUp = 2,
: 省略
NSScrollWheel = 22,
NSOtherMouseDown = 25,
NSOtherMouseUp = 26,
NSOtherMouseDragged = 27
} NSEventType;

// 受け付けるイベントを制限するための定数
enum {
NSLeftMouseDownMask = 1 << NSLeftMouseDown,
NSLeftMouseUpMask = 1 << NSLeftMouseUp,
: 省略
NSScrollWheelMask = 1 << NSScrollWheel,
NSOtherMouseDownMask = 1 << NSOtherMouseDown,
NSOtherMouseUpMask = 1 << NSOtherMouseUp,
NSOtherMouseDraggedMask = 1 << NSOtherMouseDragged,
NSAnyEventMask = 0xffffffffU
};


■ 直前のイベントからのマウスの移動量
NSEventのdeltaXとdeltaYでは、マウス移動やマウスドラッグのイベントで直前のイベントからの移動量が取得できるようになりました。NSViewのサブクラスに以下のようなコードを書くことで移動量を得ることが出来ます。

// 直前のイベント処理からのドラッグ量を取得するサンプル
- (void) mouseDragged : (NSEvent *) theEvent {

NSLog( @"deltaX = %f", [ theEvent deltaX ] );
NSLog( @"deltaY = %f", [ theEvent deltaY ] );

}

[鶴薗賢吾]
関連リンクCocoaはやっぱり!