开发者

Cocoa drawing, "lock" mouse on special events

With a little help from the last question regarding drawings开发者_StackOverflow中文版 in Cocoa i've implemented some basic shapes, as well as dragging / resizing.

So, right now i'm trying to figure out, how to create a effect like in Keynote when a shape is resized and it automatically fits the size of another shape next to it and then "locks" the mouse for a bit of time.

The first attempt is to use a delay function, like

NSDate *future = [NSDate dateWithTimeIntervalSinceNow: 0.5 ];
[NSThread sleepUntilDate:future];

reacting on the desired event (e. g. shape width == height). But this results not in the desired effect, since the whole App freezes for the specified amount of time. In addition to that i think, that the user won't recognize it as something saying "you've reached a special size". Showing guidelines only at the event is not a solution, since the guidelines are shown as soon as the shape is selected.


For snap to guides, I don't think you actually want the cursor to stop. Just that the resizing should stop reacting to the cursor movements, within a small range of your target.

The solution in that other question is more or less what you want, I think. Essentially, when you get close enough to the guide, you just change the point's coordinates to those of the guide. So, building on the sample code I posted in your earlier question, this becomes your view's mouseDragged:, and mouseUp:. You can leave the new checks out of mouseDragged: if you want the point to snap only on mouse up, a different but just as valid behavior.

If you're matching the edges of rectangles, you'll probably find the Foundation Rect Functions, like NSMaxX and NSMaxY, useful.

- (void)mouseDragged:(NSEvent *)event {
    if( !currMovingDot ) return;
    NSPoint spot = [self convertPoint:[event locationInWindow] 
                             fromView:nil];
    spot.x = MAX(0, MIN(spot.x, self.bounds.size.width));
    spot.y = MAX(0, MIN(spot.y, self.bounds.size.height));

    // Look for Dots whose centerlines are close to
    // the current mouse position
    for( Dot * dot in dots ){
        if (dot == currMovingDot) {
            // Don't snap to myself! Leaving this out causes
            // "snap to grid" effect.
            continue;
        }
        // Where SNAP_DIST is #define'd somewhere
        // something under 10 seems to be a good value
        if( abs(spot.x - dot.position.x) <= SNAP_DIST ){
            spot.x = dot.position.x;
        }
        if( abs(spot.y - dot.position.y) <= SNAP_DIST ){
            spot.y = dot.position.y;
        }
    } 


    currMovingDot.position = spot;
    [self setNeedsDisplay:YES];
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜