ページ

ラベル ドラッグ&ドロップ の投稿を表示しています。 すべての投稿を表示
ラベル ドラッグ&ドロップ の投稿を表示しています。 すべての投稿を表示

2009年2月22日日曜日

ドラッグ&ドロップ(6)ウィンドウの移動

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

以前ウィンドウの移動を抑止したが、画像以外の余白部分のドラッグであればウィンドウ移動にしたい。NSView#mouseDownCanMoveWindowが使えそうに見えたがどうもうまくいかず、結局余白部分のヒットテスト&自前ウィンドウ移動で対応した。

(参考)Cocoabuilder - Re: Conditional mouseDownCanMoveWindow for NSView?


擬似コードはこんな感じ。

- (void)mouseDown:(NSEvent *)theEvent
{
if (画像ヒットテスト) {
 // ドラッグ処理

} else {
// ウィンドウ移動処理
NSWindow *window = [self window];
NSPoint origin = [window frame].origin;
NSPoint old_p = [window convertBaseToScreen:[theEvent locationInWindow]];
while ((theEvent = [window nextEventMatchingMask:NSLeftMouseDraggedMask|NSLeftMouseUpMask]) && ([theEvent type] != NSLeftMouseUp)) {
NSPoint new_p = [window convertBaseToScreen:[theEvent locationInWindow]];
origin.x += new_p.x - old_p.x;
origin.y += new_p.y - old_p.y;
[window setFrameOrigin:origin];
old_p = new_p;
}
}
}



例えば下の図の場合、中心の画像上でマウスを押せば画像のドラッグ&ドロップになり、その周りの黒い余白をドラッグすればウィンドウの移動となる。

2009年2月20日金曜日

ドラッグ&ドロップ(5)ドロップ先を増やす

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

ファインダだけでなく他のアプリへもドラッグ&ドロップできるようにしよう。

ペーストボード(NSPasteboard)へ他のデータタイプも登録する。

NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];

[pboard declareTypes:[NSArray arrayWithObjects:NSFilesPromisePboardType, NSFilenamesPboardType, NSTIFFPboardType, nil] owner:self];

[pboard setPropertyList:[NSArray arrayWithObject:[filename pathExtension]]
forType:NSFilesPromisePboardType];

[pboard setData:[image TIFFRepresentation] forType:NSTIFFPboardType];
[pboard setPropertyList:[NSArray arrayWithObject:filename]
forType:NSFilenamesPboardType];


これで大抵のアプリへドラッグ&ドロップできるようになった。

なお Mail.app はファインダと同じくNSFilesPromisePboardTypeを使っていて添付ファイル用のフォルダへコピーすることを期待しているようだ。ドロップ時に呼出される namesOfPromisedFilesDroppedAtDestination: の引数を見ると、コピー先のURL指定はこんな感じだった。
 file://localhost/private/var/folders/0d/0dNdrhYNHnqjC2KaQLPHu++++TI/-Tmp-/com.apple.mail.drag-T0x710f70.tmp.4L3Dui/


ファインダ向けのコードそのまま(ファイルを指定フォルダへコピーする)でうまく動いた。

2009年2月19日木曜日

ドラッグ&ドロップ(4)マウスカーソルにプラスマークを

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

ファインダへのドロップ時にマウスカーソルにプラスマーク(+)をつけたい。これは draggingSourceOperationMaskForLocal: を使うと簡単にできる。

- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal
{
return NSDragOperationCopy;
}


このメソッドはドラッグ&ドロップ開始で使った dragImage:at:offset:event:pasteboard:source:slideBack: を呼出したビューに対してコールバックされる。ドラッグ中、ドラッグ先が変化するたびに呼出される。戻り値は NSDragOperation で定義されていて、今回は NSDragOperationCopy を返すようにした。

さて実行してみよう。以前はマウスカーソルにプラスマークが付いていなかった。


それがこうなる。

2009年2月18日水曜日

ドラッグ&ドロップ(3)ファインダへドロップ

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

基本的な部分ができたのでファインダへのドロップ処理を実装する。
これは随分前に検証していたので簡単にできた。

詳細は下記を参照の事。
スクラップブックその10 - 画像をファインダへドラッグ&ドロップする


SimpleViewerで画像をつかんでデスクトップ(ファインダ)へドロップすると


ファイルがコピーされる。

2009年2月17日火曜日

ドラッグ&ドロップ(2)ドラッグ画像の加工

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

ドラッグ画像を加工する。前回は画像の透明度と大きさは現物のままだった。


まずドラッグ画像を半透明にする。これは #dragImage:at:offset:event:pasteboard:source:slideBack: へ渡すNSImageを半透明に加工すれば良い。

 NSImage *dragged_image = [[[NSImage alloc] initWithSize:_image.size] autorelease];
[dragged_image lockFocus];
[_image compositeToPoint:NSZeroPoint
operation:NSCompositeSourceOver
fraction:0.5f];
[dragged_image unlockFocus];

こうなる。




次は大きさの調整。原寸大のままなのでこれを表示倍率に合わせた大きさに修正する。


前回は compositeToPoint:operation:fraction: を使っていた。
 [_image compositeToPoint:NSZeroPoint
operation:NSCompositeSourceOver
fraction:0.8f];


これを drawInRect:fromRect:operation:fraction: に変える。
 [_image drawInRect:NSMakeRect(0, 0, size.width, size.height)
fromRect:NSMakeRect(0, 0, _image.size.width, _image.size.height)
operation:NSCompositeSourceOver
fraction:0.5f];


描画先範囲 と描画元範囲を指定することで縮小された画像を描画することができる。
するとこうなる。

2009年2月16日月曜日

ドラッグ&ドロップ(1)ドラッグ開始

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

β版前最後の機能としてSimpleViewerにドラッグ&ドロップを実装する。SimpleViewer上の画像をつかんでファインダなどの他のアプリへ渡せるようにしよう。

まずはドラッグ開始から。これは NSViewのメソッド NSView#dragImage:at:offset:event:pasteboard:source:slideBack: を使うと簡単にできる。このメソッドを mouseDwon: に実装すればマウスボタンを押した時にドラッグが開始される。

- (void)mouseDown:(NSEvent *)theEvent
{
[self dragImage:dragged_image
at:NSMakePoint(0, 0)
offset:NSZeroSize
event:theEvent
pasteboard:pboard
source:self
slideBack:YES];
}


dragged_image にはとりあえず表示中の画像をそのまま渡しておく。

こんな感じ。


なお SimpleViewer(NSPanel)はデフォルトでウィンドウのドラッグ移動が有効になっているので、今回のドラッグと動作がバッティングしてうまくいかない。画像のドラッグが始まると同時にウィンドウの移動が行われてしまる。そこでNSWindow#setMovableByWindowBackground:を使いドラッグ時ウィンドウ移動の動作を切っておく。

SimpleViewerPanel.m
[self setMovableByWindowBackground:NO];


ただこれはこれで不便だ。もう一工夫必要だな。