ページ

2009年3月8日日曜日

範囲選択の初期位置(マルチスクリーン対応)

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

引き続きマルチスクリーンの話題。

マルチスクリーンで最初に範囲選択した時にメイン画面ではなくサブ画面の中央に範囲選択枠(ラバーバンド)が表示される。これは現在の実装が単純にマルチスクリーンを考慮していないから。

初期位置を決める現在のコードはこんな感じ。

- (void)resetRect
{
NSScreen* screen = [NSScreen mainScreen]; // multi screen ok
NSSize screen_size = [screen frame].size;
_rect = NSMakeRect((screen_size.width - START_WIDTH)/2,
(screen_size.height - START_HEIGHT)/2,
START_WIDTH, START_HEIGHT);
}



単純にローカル座標系の(0,0)を基点としてメイン画面の中央に配置するようにしている。これでは画面の配置状況によっては意図した(メイン画面中央)位置に範囲選択枠がこない。これを直すにはスクリーン座標系上でメイン画面の左上の座標を求め、これをローカル座標系へ変換した上で描画位置の基点とすれば良いと思われる。スクリーン座標系からカスタムViewのローカル座標系への変換には NSWindow#convertScreenToBase:NSView#convertPoint:fromView:が使える。

変換コードを追加するとこんな感じ。
- (void)resetRect
{
NSScreen* screen = [NSScreen mainScreen]; // multi screen ok
NSSize screen_size = [screen frame].size;
_rect = NSMakeRect((screen_size.width - START_WIDTH)/2,
(screen_size.height - START_HEIGHT)/2,
START_WIDTH, START_HEIGHT);
NSPoint bp = NSZeroPoint;
bp = [[_capture_controller view] convertPoint:[[_capture_controller window] convertScreenToBase:NSMakePoint(0, screen_size.height)] fromView:nil];
_rect.origin.x += bp.x;
_rect.origin.y += bp.y;
}

後半 #convertPoint:fromView: と #convertScreenToBase: を使って基点を生成している。

実行してみたところ単一スクリーンでは問題なさそうだ。
ただマルチスクリーンは今は試せる環境が無い。明日以降試してみよう。