home link download back number special issue

HMDT - Special Issue / Sketch BP / ポリゴンツールのドローオブジェクトの編集の実装


- 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: を使えば消える。これでオッケー。


- ソースコードのダウンロード -

HMDT - Download / Sketch BP


Home | Link | Download | Back Number | Speciall Issue

Sketch BP

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

HMDT