Setting the background of NSBox to a gradient programmatically without subclassing - objective-c

I want to set the background of an NSBox to be a gradient. In Interface Builder it is possible to set the background color of an NSBox to selectedMenuColor which is a gradient.
NSBox only has a setFillColor method so how is Interface Builder filling it with a gradient?
How do I programmatically fill an NSBox without subclassing it? It would be trivial to subclass NSBox but the workings of Interface Builder suggest there may be better solution.

selectedMenuColor is a "magic" color that is not displayed as a solid color. Many of these "magic" colors exist in the system.
I have used colorWithPatternImage: for this before. But note that the image you use as the pattern will get tiled, so you will probably have to resize the image to the size of the box.

Probably the closest you could come would be to use an NSColor created with colorWithPatternImage:, then create the gradient you want as an image and load that in. Ugly, but should work. I think subclassing is your best bet.

The selectedMenuColor color is actually a pre-rendered image of a gradient, and not a gradient drawn on the fly, so there is not any way to specify an arbitrary gradient as a background color. Like Ben said, subclassing is probably the way to go.

In xib, select NSBox, then goto effect inspector, check NSBox for Core Animation Layer.
Now
IBOutlet NSBox *box;
[box.setWantsLayer:YES];
[box.layer setBackgroundColor:[[NSColor whiteColor] CGColor]];
or
[box.setWantsLayer:YES];
[box.layer setBackgroundColor:[[NSColor colorWithPatternImage:[NSImage imageNamed:#"white.gif"]] CGColor]];

Related

Change Fill Color of CALayer

Is it possible to set the fill color of a CALayer that has already been drawn on screen?
I am using SVGKit to load a SVG image into a UIView and everything is working very well but I need to change the fill color. I have read up on CAShapeLayer.fillColor and think that it can be done easily but I don't seem to see an easy way to do it with a CALayer? I really do hope it can be done.
May be someone might even be able to suggest if a CALayer can be converted to a CAShapeLayer?
Look at the docs for CALayer and you'll see
#property CGColorRef backgroundColor

Transparent NSWindow but with standard border and shadow [duplicate]

This question already has an answer here:
Holes in NSView or NSWindow
(1 answer)
Closed 6 years ago.
I want to have a more or less standard NSWindow with a toolbar and all that, but I want the content view to be transparent so that I can see through it. At the same time I want to keep the light gray outline of the window and also it's shadow. BUT I want to avoid the "inner" shadow I get from the toolbar inside the content view area.
What I have tried so far is just to set the window background color to a semi transparent color and also set opaque to NO. The problem is that the window border fades away with the alpha of the background itself, and the more transparency I have on the background, the more the shadow of the toolbar shows up within the content view.
Generally, the window shadow and border changes depending on the transparency of the content view, which I totally understand. But I want a behavior where it keeps the border and shadow just as if it was a completely opaque window, and then I want the content view area to be transparent.
I am not sure what I need to do conceptually to make it work. Maybe I have to draw the window border myself, maybe not. Maybe I need to draw the shadow myself, or maybe not.
Is there anyone that know how to build this? I don't need exact code details, but rather what parts I need to do custom..
I appreciate any input!
I dont't know if this is of any value for you after all this time but try:
[aWindow setOpaque:NO];
[aWindow setBackgroundColor:[NSColor clearColor]];
Subclass the NSView class, override the drawRect:(NSRect)dirtyRect method and set the color of the view as clearcolor, now set the class of your content view as the Subclass of NSView.

Semi-transparent mesh background with opaque buttons

I have read time and again that if you make a UIView transparent, it affects all its subviews, including buttons, etc. I want the background of my UIView to be semi-transparent (alpha=.5 perhaps) and to be made of a specific image pattern that repeats itself, but I want the buttons in that view to be completely opaque. I could separate the buttons into separate views, but that doesn't seem efficient. What is the best approach here? Regarding a mesh background, if I make a pattern I like, is this all that is required:
self.view.backgroundColor= [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"yourimage.jpg"]];
Why not open your image in an image editor and save it as a 50% transparent image?

Howto draw a rect on screen. NSOpenGLContext vs transparent NSWindow + custom NSView

I'm reading pixels from an area of the main screen via NSOpenGLContext. Now I would like to draw a rect around that area to indicate where it actually is.
How would I do this?
My first thought was the "Cocoa way": create a transparent fullscreen NSWindow and a custom NSView to draw the rectangle path. But that feels a bit too complicated. Isn't it possible to draw directly on the NSOpenGLContext?
If you want to draw over elements not inside your application the floating window is the only correct way. There’s really no complication except mapping positions properly, which is easy to do with the coordinate-space conversions available on NSView and NSWindow.

setOpaque:NO vs setBackgroundColor:[NSColor clearColor]

I'm going through a tutorial on drawing a custom [shaped] window with cocoa by subclassing NSWindow.
The tutorial states that in initializer developer should do the following:
[self setOpaque:NO];
[self setBackgroundColor:[NSColor clearColor]];
So i'm wondering what is the differnce between these two messages and why are they needed both since their result is the same.
References: tutorial can be found here.
I guess that the first message is required because the drawing system needs to know whether it should bother updating views that lie behind yours. For example, if a window in another application (behind your window) updates (say text appears etc) the windowing system would not normally need to redraw it, but since your window is transparent it does in this case.
So i'm wondering what is the differnce between these two messages and why are they needed both since their result is the same.
They're not the same.
Look at the documentation for the opaque property: It's how you tell NSView that you're going to draw in your entire bounds, completely covering anything below your view.
If you don't cover the entire bounds, or you don't always draw at 100% opacity, then your view is not opaque, and you should leave that property set to NO.
If you set your view's background color to clearColor (which is simply a color with 0% opacity), and don't draw at 100% opacity over the entire background, then your view is not opaque.
On the other hand, it is possible to have clearColor as your background and then completely draw over it, in which case your view is opaque and should set itself as such.