NSTextView background not resizing appropriately - macos

I have an NSTextView inside an NSScrollView. The scroll view has the auto resize masks for height and width, so it changes size with the window it's in.
The text view is set up much in the way the apple documentation recommends here.
But no matter what settings I put on the text view, I cannot get the background color to resize along with the scroll view.
Here's a picture of what I'm dealing with:
The width works, but not the height.
Here's my setup code for the textview as it is for this picture:
NSTextView *view = [[NSTextView alloc] initWithFrame:NSMakeRect(0, 0, scrollview.contentSize.width, scrollview.contentSize.height) textContainer:textContainer];
[view setMinSize:NSMakeSize(0.0, scrollview.contentSize.height)];
[view setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
[view setVerticallyResizable:YES];
[view setHorizontallyResizable:NO];
[view setAllowsDocumentBackgroundColorChange:YES];
[view setDrawsBackground:YES];
[view setAutomaticLinkDetectionEnabled:YES];
[view setAutoresizingMask:NSViewWidthSizable];

The white background colour isn’t that of the NSTextView, but rather that of its enclosing NSScrollView.
To change it, either select the NSScrollView in Interface Builder/Xcode 4. Or, to do it programmatically, use -[NSView encosingScrollView]:
NSScrollView *scrollView = [textView enclosingScrollView];
[scrollView setBackgroundColor:[NSColor blackColor]];

Related

Why is my layer shadow clipped to my NSView's rect?

I'm creating a window containing an NSButton (both window content view & button have wantsLayer = YES), and setting the NSButton's shadowColor, shadowRadius, shadowOpacity and shadowOffset. But my shadow gets clipped to the rect of the NSView. How do I fix this?
NSRect wdBox = NSMakeRect(0,0,100,100);
NSWindow * theWindow = [[[NSWindow alloc] initWithContentRect: wdBox styleMask: NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask backing: NSBackingStoreBuffered defer: NO] autorelease];
NSView* cv = [[[NSView alloc] initWithFrame: wdBox] autorelease];
cv.wantsLayer = YES;
[cv setLayerUsesCoreImageFilters: YES];
theWindow.contentView = cv;
[theWindow setCollectionBehavior: NSWindowCollectionBehaviorFullScreenPrimary];
[theWindow setTitle: #"foo"];
NSButton* mView = [[NSButton alloc] initWithFrame: NSMakeRect(10, 10, 100, 80)];
[mView setLayerUsesCoreImageFilters: YES];
[mView setWantsLayer: YES];
mView.layer.masksToBounds = NO;
[mView.layer setShadowColor: [NSColor.redColor CGColor]];
[mView.layer setShadowOffset: CGSizeMake(4, 4)];
[mView.layer setShadowRadius: 8];
[mView.layer setShadowOpacity: 1.0];
[mView setBezelStyle: NSRoundRectBezelStyle];
[mView setTitle: #"bar"];
[theWindow.contentView addSubview: mView];
Here's a picture:
I had similar code before and it used to work until 10.9, but the shadow suddenly got clipped to the view, so I rewrote it to this simple case, but it's still clipped.
There is a bug in Mavericks. If you create an NSButton in XIB and give it a layer and set its shadow it works fine, but if you create one programmatically it clips its shadow.
I suspect the AppKit team did some crazy hacks when they made buttons do fast layer compositing in Mavericks (they won't redraw their backgrounds unless necessary now, for instance), because they tried to make it all happen magically, which is always always a bad idea.
Note that if you make an NSTextField the shadow code works as you'd expect. It's just NSButtons (so far) that I've found have this issue.
Please file a radar.

How to draw on a transparent NSWindow with a transparent NSView?

I want to draw on the screen with a transparent background, so that everything (e.g. open applications are still visible).
In windowDidLoad of my custom NSWindowController i have the follwing:
[self.window setOpaque: NO];
[self.window setHasShadow:NO];
[self.window setBackgroundColor:[NSColor clearColor]];
[self.window setStyleMask:NSBorderlessWindowMask];
My custom NSWindow overrides canBecomeKeyWindow
- (BOOL)canBecomeKeyWindow {
return YES;
}
My View overrides drawRect
- (void)drawRect:(NSRect)rect {
[[NSColor clearColor]set];
NSRectFill(rect);
...
}
Problem: Trying to draw by using mouse events inside of my custom view results in the view/application beneath my Window to receive these events.
It justs works when i do not set the NSWindow styleMask to NSBorderlessWindowMask or by setting the background color of the custom view to semitransparent.
[[NSColor colorWithCalibratedRed:0 green:0 blue:0 alpha:0.05] set]
How can i draw on screen with full transparency and NSBorderlessWindowMask?
Adding
[self.window setIgnoresMouseEvents:NO];
to windowDidLoad of my custom NSWindowController solved it

Layer-Backed view no longer punches hole in transparent NSWindow

I am trying to make a "hole" in an NSWindow using a CAShapeLayer or even just a CALayer.
When using regular NSViews or even layer-backed views, I can override drawRect: using code like this:
[spotImage drawInRect:self.bounds fromRect:NSZeroRect operation:NSCompositeXOR fraction:1.0];
where spotImage is an NSImage with pure white content and some gradations, and the window has a black background with 0.5 alpha. The NSView subclass where this drawRect is defined has a clearColor background.
The end result is a grey window (It is a transparent window with a styleMask of NSBorderlessWindowMask as can be found in many samples.
If I turn the NSView into a layer-backed view, it calls the drawRect methods and works fine.
When I turn this into a layer-hosting view, and again use the same structure (NSWindow > contentView > CustomView) then, the drawInRect method just draws the image. It no longer punches a hole through it.
It is like the layer itself can no longer punch the hole when it is part of a layer-hosting hierarchy.
Here is some sample code:
The custom NSWindow subclass initializer:
- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag {
self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
if (self) {
[self setBackgroundColor: [NSColor lightGrayColor]]; //[NSColor clearColor]];
[self setAlphaValue:0.5];
[self setOpaque:NO];
[self setHasShadow: NO];
[self useOptimizedDrawing:YES];
[self setIgnoresMouseEvents:YES];
}
return self;
}
the code in my applicationDidFinishLaunching method:
PPContentView *thisView = [[PPContentView alloc]
initWithFrame:CGRectInset([self.window.contentView bounds], 50, 50)];
//[thisView setWantsLayer:YES]; enabling this makes things opaque again
[self.window.contentView addSubview:thisView];
thisView.layer.backgroundColor = [NSColor clearColor].CGColor;
//Create custom content
[thisView setNeedsDisplay:YES];
}
and my custom view's drawRect contains:
[[NSImage imageNamed:#"spotFuzzy.png"] drawInRect:self.bounds fromRect:NSZeroRect operation:NSCompositeXOR fraction:1.0];

Create Drop Shadow for NSView - Cocoa

I'm trying to create a drop shadow surrounding the NSView like how NSWindow does it with its shadow, but I'm having some difficulty. I created a class for the NSView I'm creating the drop shadow for and I'm using this code for the overriding method:
-(void)drawRect:(NSRect)dirtyRect {
NSRect rect = NSInsetRect([self bounds], 10.0, 10.0);
NSShadow *dropShadow = [[[NSShadow alloc] init] autorelease];
[dropShadow setShadowColor:[NSColor blackColor]];
[dropShadow setShadowBlurRadius:5];
[dropShadow setShadowOffset:NSMakeSize(0,-3)];
[NSGraphicsContext saveGraphicsState];
[dropShadow set];
NSRectFill(rect);
[NSGraphicsContext restoreGraphicsState];
[super drawRect:dirtyRect];
}
This doesn't really create a drop shadow in which I'm looking.
Here is the shadow I'm trying to aim for...
rather creates a line through the NSView that seems like a border within the bounds of the view. Anyone got any ideas for this?
I have faced similar shadow issues because NSView clips its bounds.
I fixed it when I used a layer backed view. I simply set the superview's wantsLayer property to YES.. i.e [[view superView] setWantsLayer:YES] and set shadow for view [view setShadow:dropShadow].

Custom NSView with NSTextField subview drawing issue

So I am drawing a custom window (transparent) with a custom NSView as the contentview, and wouldlike to add an NSTextField to the window as well, however, when I add the NSTextField, I get a weird resizing or redraw of the custom NSView, and I can't figure out what is causing the problem. Both the window and the contentview of the window are subclasses of NSWindow, and NSView, respectively. Also, I have tried to just layer the custom NSView (not set it as the contentview) with no change. Any ideas?
NSWindow *quickEntryWindow = [[TransparentWindow alloc] initWithContentRect:NSMakeRect([[NSScreen mainScreen] frame].size.width/2 - 250, [[NSScreen mainScreen] frame].size.height/2 + 50, 500, 100)
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO
special:YES];
BorderView *quickEntryBorderView = [[BorderView alloc] initWithFrame:NSMakeRect(0, 0, [[quickEntryWindow contentView] frame].size.width, [[quickEntryWindow contentView] frame].size.height)];
[quickEntryBorderView canDrawConcurrently];
[quickEntryWindow setContentView:quickEntryBorderView];
NSTextField *quickEntryTextField = [[NSTextField alloc] initWithFrame:NSMakeRect(10, 10, [quickEntryBorderView frame].size.width-20, [quickEntryBorderView frame].size.height-20)];
[quickEntryTextField setAutoresizingMask:NSViewNotSizable];
[quickEntryTextField setBordered:NO];
[quickEntryTextField setDrawsBackground:NO];
[quickEntryTextField setFocusRingType:NSFocusRingTypeNone];
[quickEntryTextField setFont:[NSFont fontWithName:#"Helvetica" size:42]];
[quickEntryTextField setTextColor:[NSColor grayColor]];
[quickEntryBorderView addSubview:quickEntryTextField];
What I get is something that looks like this (it is normal when no text is entered into the NSTextField):
Oh yeah, I know I'm not managing my memory...I'm just trying to get this working. Thanks!

Resources