可可拉丝、“锁”鼠标放在特殊事件上

发布于 2024-11-04 15:32:46 字数 405 浏览 1 评论 0原文

在关于 Cocoa 绘图的最后一个问题的一点帮助下,我实现了一些基本形状,以及拖动/调整大小。

所以,现在我正在尝试弄清楚,如何在调整形状大小时创建像 Keynote 中那样的效果,并且它会自动适应旁边另一个形状的大小,然后“锁定”鼠标一段时间。

第一次尝试是使用延迟函数,例如

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

对所需事件做出反应(例如形状宽度==高度)。但这不会达到预期的效果,因为整个应用程序会冻结指定的时间。除此之外,我认为用户不会将其识别为“您已达到特殊尺寸”。仅在活动中显示指南并不是解决方案,因为一旦选择形状,指南就会显示。

With a little help from the last question regarding drawings 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

痴意少年 2024-11-11 15:32:46

对于捕捉到参考线,我认为您实际上并不希望光标停止。只是调整大小应该停止对目标的小范围内的光标移动做出反应。

其他问题中的解决方案或多或少我想你想要什么。本质上,当您距离参考线足够近时,只需将该点的坐标更改为参考线的坐标即可。因此,基于我在您之前的问题中发布的示例代码,这将成为您视图的 mouseDragged:mouseUp:。如果您希望该点仅在鼠标松开时捕捉,则可以将新检查保留在 mouseDragged: 之外,这是一种不同但同样有效的行为。

如果您要匹配矩形的边缘,您可能会找到 基础矩形函数,例如 NSMaxXNSMaxY,很有用。

- (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];
}

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];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文