- Modification -
ポリゴンツールのドローオブジェクトの編集の実装

■ ポリゴンツールのドローオブジェクトの編集に必要なもの
続いては、ポリゴンの編集のお話。編集モードでは、ポリゴンのアンカーポイントを動かせるようにしよう。これで、一度作ったポリゴンを変形することができるんだ。
編集のためには、SKTGraphic の編集モードの追加で追加された、editWithEvent:inView: を使う。こいつの中で編集のためのトラッキングループを回すんだ。
あと、もう一つ、編集モードではアンカーポイントを削除できるようにしよう。これは、編集モードで、アンカーポイントを選択してデリートキーを押すと、削除されるんだ。これも追加されたメソッドである、deleteForEditingInView: を使う。
■ ポリゴンツールのドローオブジェクトの編集の実装
まずは、editWithEvent:inView: での編集の実装から。基本的に createWithEvent:inView: を参考にしてるんだ。
|
Sketch/DocumentModel.subproj/SKTPolygon.m (created by mkino)
|
- (BOOL)editWithEvent:(NSEvent*)event inView:(SKTGraphicView*)view {
NSPoint point = [view convertPoint:[event locationInWindow] fromView:nil];
int pointIndex = [self anchorPointUnderPoint:point];
BOOL snapsToGrid = [view snapsToGrid];
float spacing = [view gridSpacing];
BOOL echoToRulers = [[view enclosingScrollView] rulersVisible];
if (pointIndex >=0) {
_selectedPointIndex = pointIndex;
while (1) {
event = [[view window] nextEventMatchingMask:
(NSLeftMouseDraggedMask | NSLeftMouseUpMask)];
if ([event type] == NSLeftMouseDragged) {
point = [view convertPoint:
[event locationInWindow] fromView:nil];
if (snapsToGrid) {
point.x = floor((point.x / spacing) + 0.5) * spacing;
point.y = floor((point.y / spacing) + 0.5) * spacing;
}
[self movePointAtIndex:pointIndex toPoint:point];
}
[self setBounds:[[self origBezierPath] bounds]];
[view setNeedsDisplayInRect:[self drawingBounds]];
if (echoToRulers) {
[view continueEchoingMoveToRulers:[self bounds]];
}
if ([event type] == NSLeftMouseUp) {
break;
}
}
}
else {
return NO;
}
return YES;
}
|
まず、マウスの位置を求めて、その下にアンカーポイントがあるかどうかを anchorPointUnderPoint: を使って調べるんだ。アンカーポイントがあるならば、_selectedPointIndex にそのポイントを入れておく。これで、アンカーポイントが選択されたことになる。そして、トラッキングループに入るんだ。
もしマウスがドラッグされたら、それに合わせてアンカーポイントを動かす。movePointAtIndex: を使うんだ。再描画させておしまい。マウスが離されたらループを抜ける。
■ アンカーポイントの削除の実装
続いて、アンカーポイントの削除を。deleteForEditingInView: で行う。
|
Sketch/DocumentModel.subproj/SKTPolygon.m (created by mkino)
|
- (void)deleteForEditingInView:(SKTGraphicView*)view {
NSRect drawingBounds;
if (_selectedPointIndex != -1) {
// If the points is last one
if ([_anchorPoints count] == 1) {
[[self document] removeGraphic:self];
return;
}
drawingBounds = [self drawingBounds];
[self removePointAtIndex:_selectedPointIndex];
_selectedPointIndex = -1;
[self setBounds:[[self origBezierPath] bounds]];
drawingBounds = NSUnionRect(drawingBounds, [self drawingBounds]);
[view setNeedsDisplayInRect:drawingBounds];
}
}
|
まず、アンカーポイントが選択されているかどうかを調べる。_selectedPointIndex が -1 かどうかで分かるんだ。
そして、現在のアンカーポイントの数を調べる。最後の 1 つだったら、このドローオブジェクト自体を消してやる。SKTDrawDocument の removeGraphic: を呼んでやるんだ。そうじゃないときは、アンカーポイントを削除する。removePointAtIndex: を使えば消える。これでオッケー。
|