Marek H
Marek H

Reputation: 5576

How to create inner transparent nsview with nonopaque window

I am trying to create opaque border in an non opaque window. Currently I look for subview and create bezierpath to fill outer region. Is there other way how to do this?

Example what I am trying to achieve:

enter image description here

#import "MyView2.h"
#import "MyView.h"

@interface MyView2() {
    NSRect transparentSubviewRect;
}

@end

@implementation MyView2

- (void)awakeFromNib
{
    NSArray *subviews = [self subviews];
    for (NSView *view in subviews) {
        if ([view isKindOfClass:[MyView class]]) {
            transparentSubviewRect = [view frame];
        }
    }
}

- (void)drawRect:(NSRect)dirtyRect {
    NSRect rect = [self frame];
    NSBezierPath *path = [NSBezierPath bezierPath];
    [path moveToPoint:NSMakePoint(NSMaxX(transparentSubviewRect), NSMaxY(transparentSubviewRect))];
    [path lineToPoint:NSMakePoint(NSMinX(transparentSubviewRect), NSMaxY(transparentSubviewRect))];
    [path lineToPoint:NSMakePoint(NSMinX(transparentSubviewRect), NSMinY(transparentSubviewRect))];
    [path lineToPoint:NSMakePoint(NSMaxX(transparentSubviewRect), NSMinY(transparentSubviewRect))];
    [path lineToPoint:NSMakePoint(NSMaxX(transparentSubviewRect), NSMaxY(transparentSubviewRect))];
    [path closePath];
    [path moveToPoint:NSMakePoint(NSMaxX(rect), NSMaxY(rect))];
    [path curveToPoint: NSMakePoint(NSMaxX(rect), NSMinY(rect))
               controlPoint1: NSMakePoint(NSMaxX(transparentSubviewRect), NSMaxY(transparentSubviewRect))
               controlPoint2: NSMakePoint(NSMaxX(rect), NSMinY(transparentSubviewRect))];
    [path lineToPoint:NSMakePoint(NSMinX(rect), NSMinY(rect))];
    [path lineToPoint:NSMakePoint(NSMinX(rect), NSMaxY(rect))];
    [path lineToPoint:NSMakePoint(NSMaxX(rect), NSMaxY(rect))];
    [path lineToPoint:NSMakePoint(NSMaxX(rect), NSMaxY(rect))];
    [path closePath];
    [[NSColor windowBackgroundColor] setFill];
    [path fill];
}

@end

#import "MyWindow.h"

@implementation MyWindow


- (BOOL)isOpaque
{
    return NO;
}

- (NSColor *)backgroundColor
{
    return [NSColor colorWithCalibratedWhite:0.0 alpha:0.3];
}

@end

Upvotes: 0

Views: 237

Answers (1)

Marek H
Marek H

Reputation: 5576

Easier solution was to fill whole view and use NSCompositingOperationClear operation. Mandatory is opaque window + some transparent background color for window.

- (void)drawRect:(NSRect)dirtyRect {
    [[NSColor windowBackgroundColor] setFill];
    NSRectFill([self bounds]);
    NSRectFillUsingOperation(transparentSubviewRect, NSCompositingOperationClear);
}

Upvotes: 1

Related Questions