setPatternPhase 的问题:在 NSColor 的 NSSplitView 中使用 colorWithPatternImage:

发布于 2024-12-11 03:19:50 字数 1479 浏览 0 评论 0原文

我四处搜寻,没有发现任何关于这个特定问题的信息。我有一个带有垂直 NSSplitView 的窗口。在 splitview 的右视图中,我设置了一个 NSBox 对象来填充视图的内容。我使用 setContentView: 加载自定义笔尖,将视图交换到 splitview 右侧的 NSBox。在我的自定义视图中,我使用 NSColor 对象填充视图,该对象使用 NSImage 来图案化背景。所有这一切都按预期进行。我正在使用基于本文的代码: http ://www.mere-mortal-software.com/blog/details.php?d=2007-01-08 将图案的相位设置到左上角:

[[NSGraphicsContext currentContext] saveGraphicsState];
[[NSGraphicsContext currentContext] setPatternPhase: NSMakePoint( [self bounds].origin.x, 
                                                                 [self bounds].size.height )];
[[self leatherColor] set];
NSRectFill( [self bounds] );

[[NSGraphicsContext currentContext] restoreGraphicsState];

目的是使图案出现当视图按照预期行为调整大小时(通过 splitview 移动或窗口本身调整大小),在 NSBox 的左上角保持不变。我已经在一个精简的测试应用程序中实现了这一点,只有一个窗口和一个自定义视图,它的行为符合预期。

然而,在我使用 splitview 的项目中,它的行为就像将 patternPhase 设置在整个窗口的左上角,而不是 splitview 右半部分的左上角(即它应该随着 splitview 大小的调整而移动)它的行为就像“显示更大的图像而不是随之移动。我很确定这是多个坐标空间的问题,我误解了 NSSplitView 的坐标如何工作,或者与视图有关从 NSGraphicsContext 的文档中,在 setPatternPhase: 方法中,它说:“例如,将图案相位设置为 (2,3) 具有将图案单元平铺的开始移动到点 (2,3) 的效果。默认用户空间。”默认用户空间是否与我的自定义视图的边界相对应,或者我是否基于右侧视图坐标集创建点,并且 setPatternPhase 将其实现为整个宽度spitview(包括左半部分)?

您可以提供的任何建议/建议/帮助将不胜感激。

编辑:我已经上传了该项目的副本,以便您可以看到行为: http:// dl.dropbox.com/u/6679821/ViewSwitcher.zip

I have searched around and haven't found anything regarding this particular problem. I have a window with a vertical NSSplitView. Within the right view of the splitview, I have an NSBox object set to fill the contents of the view. I am loading in custom nibs using setContentView: to swap in views to the NSBox on the righthand side of the splitview. In my custom views I'm tying to fill the views with an NSColor object that uses a NSImage to pattern the background. All of this is working as expected. I am using the code based on this article: http://www.mere-mortal-software.com/blog/details.php?d=2007-01-08 to set the phase of the pattern to the top-left corner:

[[NSGraphicsContext currentContext] saveGraphicsState];
[[NSGraphicsContext currentContext] setPatternPhase: NSMakePoint( [self bounds].origin.x, 
                                                                 [self bounds].size.height )];
[[self leatherColor] set];
NSRectFill( [self bounds] );

[[NSGraphicsContext currentContext] restoreGraphicsState];

with the intention that the pattern appears to remain constant in the upper lefthand corner of the NSBox when the views are re-sized as would be the expected behavior (via the splitview moving or the window itself being resized). I have implemented this in a stripped-down test app with just a window and a custom view and it behaves as expected.

In my project with the splitview however, it is behaving like the patternPhase is being set on the upper lefthand corner of the entire window instead of the upper lefthand corner of the right-half of the splitview (i.e. it should shift with resizing the splitview) It behaves like it's "revealing a larger image instead of shifting with it. I'm pretty certain this is an issue with multiple coordinate spaces, me misunderstanding how the coordinates of an NSSplitView work, or something to do with the view hierarchy. From the documentation on NSGraphicsContext, in the setPatternPhase: method it says: "For example, setting the pattern phase to (2,3) has the effect of moving the start of pattern cell tiling to the point (2,3) in default user space." Will the default user space correspond with the bounds of my custom view, or could it be that I am creating the point based on the right side view set of coordinates and the setPatternPhase implements it for the full width of the spitview (including the left-half)?

Any suggestions/advice/help you could provide would be greatly appreciated.

Edit: I have uploaded a copy of the project so you can see the behavior: http://dl.dropbox.com/u/6679821/ViewSwitcher.zip

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

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

发布评论

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

评论(1

唠甜嗑 2024-12-18 03:19:50

您需要根据视图在窗口中的位置来调整相位。我在 NSView 上使用此类别:

@implementation NSView (RKAdditions)
- (void)rk_drawPatternImage:(NSColor*)patternColor inRect:(NSRect)rect
{
    [self rk_drawPatternImage:patternColor inBezierPath:[NSBezierPath bezierPathWithRect:rect]];
}


- (void)rk_drawPatternImage:(NSColor*)patternColor inBezierPath:(NSBezierPath*)path
{
    [NSGraphicsContext saveGraphicsState];

    CGFloat yOffset = NSMaxY([self convertRect:self.bounds toView:nil]);
    CGFloat xOffset = NSMinX([self convertRect:self.bounds toView:nil]);
    [[NSGraphicsContext currentContext] setPatternPhase:NSMakePoint(xOffset, yOffset)];

    [patternColor set];
    [path fill];
    [NSGraphicsContext restoreGraphicsState];
}

@end

在您的情况下,您需要将 -drawRect: 修改为如下所示:

-(void) drawRect: (NSRect)dirtyRect
{
    [self rk_drawPatternImage:[self leatherColor] inRect:self.bounds];
}

You need to adjust the phase depending on where the view sits in the window. I use this category on NSView:

@implementation NSView (RKAdditions)
- (void)rk_drawPatternImage:(NSColor*)patternColor inRect:(NSRect)rect
{
    [self rk_drawPatternImage:patternColor inBezierPath:[NSBezierPath bezierPathWithRect:rect]];
}


- (void)rk_drawPatternImage:(NSColor*)patternColor inBezierPath:(NSBezierPath*)path
{
    [NSGraphicsContext saveGraphicsState];

    CGFloat yOffset = NSMaxY([self convertRect:self.bounds toView:nil]);
    CGFloat xOffset = NSMinX([self convertRect:self.bounds toView:nil]);
    [[NSGraphicsContext currentContext] setPatternPhase:NSMakePoint(xOffset, yOffset)];

    [patternColor set];
    [path fill];
    [NSGraphicsContext restoreGraphicsState];
}

@end

In your case you'd modify -drawRect: to look like this:

-(void) drawRect: (NSRect)dirtyRect
{
    [self rk_drawPatternImage:[self leatherColor] inRect:self.bounds];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文