Transparent NSMenu - objective-c

I'm trying to change the opacity of a NSMenu, I made custom NSMenuItems and changed their opacity but there is still the white color of menu behinde them, I'm looking for a way too change the color and opacity of the menu background. I was wondering if it's even possible?
Regards

I don't think there is an elegant way to do that. NSMenu isn't a subclass of NSView. The rendering view is probably a private variable of the menu object.
NSMenuItem has a view property that you can use. Try setting a custom view (if you don't already) and later find the menu's view by calling menuItem.view.superview. Then set that view's alpha property.
Alternatively you could try to find the private view property of NSMenu with a tool like class-dump. Note that using private variables is never a good idea. Especially if you're planning to release the app on the App Store.

Related

How to change NSToolBar background color?

I'm using a NSToolbar and I'm trying to change the color to a white instead of the default gray. How can I accomplish that?
Since the toolbar integrates into the window title bar, you need to draw both the title bar and the toolbar. Which basically means you need to take over drawing for the entire window.
This requires "swizzling" which, while it works well, is not supported by Apple and therefore may get your app rejected from the app store.
Basically you need to inject your own code into the NSWindow class, by using objective-c runtime functions to modify the class definition. Note that this will affect all windows in your app, so you will need to have an if statement checking if this is a window you want to modify.
Subclass NSWindow, and in the +initialize method, find the "frame view" class which is the one that does most of the window drawing, and rename it's "drawRect:" method to "originalDrawRect:". Then you define a new "drawRect:" method on the class, as a duplicate of a method in your NSWindow subclass. This method should first call originalDrawRect and then do custom drawing on top of it.
Note: you will be drawing over the top of the window title text... so'll need to change the the drawing mode to kCGBlendModeColor or something. Or else just draw the title string again. You can ask the window where the title text should be drawn.
Here's a full article with more details: http://parmanoir.com/Custom_NSThemeFrame

NSButton draw alternate image on click

I know this is probably super easy, but I'm having a hard time wading through header files and could use some guidance.
I have an NSPopUpButton defined in a nib with a menu attached to it. I have defined it in the nib to be "Pull Down" type with no arrow (the images given to me by our designer include a special arrow he wants to use). It is a borderless button. The title properly is empty, though I have set the image and alternateImage.
What I'm looking for is a configuration, either in the nib, file's owner implementation, or by subclass NSPopUpButton, that will allow me to display the button's alternate image (or any other image) while the button's menu is being displayed. Instead, it looks like the system is dimming the button's image.
I've tried numerous nib configurations, various properties of NSButton and NSButtonCell, overriding mouseDown and mouseUp. Nothing I do works.
If playing with the "Type" property doesn't help, you may well have to subclass the drawing of NSButtonCell to get what you want.
- (void)drawImage:(NSImage *)image withFrame:(NSRect)frame inView:(NSView *)controlView in NSButtonCell seems promising.
I think it's custom NSButtonCell class time; I don't know of any way to override the theme for this type of button.
Your only alternative would be to use a regular NSButton with the appropriate image and show the menu at the correct position manually, which would probably be a lot easier to implement.

Xcode-style font picker

I'd like to add a font picker in my app. Xcode's Interface Builder has a great implementation which is used in Xcode's own preferences' window too.
It's the one with a little 'T' button (seemingly) inside the font name text field itself.
Is this a standard cocoa implementation?
You'll need to roll your own. See Subclassing NSControl. You'll subclass NSTextField and NSTextFieldCell. Read the entire guide, actually. Once you've got a good understanding, then you can override the drawing/geometry routines to return a rect whose width is slightly smaller (small enough to leave room for the font "button"). Then draw your font button. You'll respond to its mouse events on the font button the same as you would for any NSView.
There's no standard control for the preview text box with the button, but there is the standard NSFontPanel class that you can use to let users select the font once the 'T' button has been clicked.
Best idea is probably to override NSTextFieldCell. I've been able to get the desired appearance by overriding -drawInteriorWithFrame:inView:, and passing a slightly less wide frame when calling through to super, then drawing the button myself. You'd also have to implement the mouse tracking of the button yourself, but you could probably just create your own NSButtonCell instance and call through to it for a few methods with the sub-rect for the button.
For convenience, you may also want to create a NSTextField subclass that uses this cell instead of a straight NSTextFieldCell, but if you're loading stuff from a XIB, you can just change the class of the cell in the XIB and leave it in a regular text field view.

Subclassing an NSDrawer's contentView to implement a completely custom drawer

I want to implement my own custom drawer completely by subclassing NSView and doing all my view drawing in that. I've created a custom NSView class that does hardly anything apart from implement initWithFrame: and drawRect: which I've got logging the frame/bounds of the NSView (which is reporting correctly). I've also instantiated this view and added it to the NSDrawer object in my application using setContentView: so that it uses my custom NSView.
However, this still draws a default drawer layout attached to the edge of my applications NSWindow. How do I override this default style so that I can draw my own drawer (!) in my custom, subclassed NSView without anything default being drawn by the OS? (So that I can control the design and size of the drawer myself, to basically emulate a tab bar that won't act strictly as a traditional drawer.)
I made a custom drawer by subclassing NSWindow rather than NSDrawer. It was a lot of work. There is a private object, NSThemeFrame, that sits between a NSWindow and its contentView. To avoid using private API, you have to make a transparent window and let its contentView act like a NSThemeFrame. Matt Gallagher shows how: http://cocoawithlove.com/2008/12/drawing-custom-window-on-mac-os-x.html
That frame is being drawn by the drawer's frame view. To do this, you need to use some private methods, and the easiest way is probably to use a custom subclass of NSDrawer. I do not know the specific methods used for drawers, but you can get a header for the class including private methods using class-dump.
Edit: This is what NSDrawer actually does.
NSDrawer is an opaque object that manages other objects. It creates a window using the private NSDrawerWindow class. Setting its content view sets the window's content view. The NSDrawerWindow class uses the private NSDrawerFrame class, which is a subclass of the private NSFrameView class, as its background and displays its content view inside that.
To change the frame, you need a way to change the frame view in the window. The easiest thing to do would be to get a header for NSDrawerWindow and add a category that overrides +frameViewClassForStyleMask: to return the class for your custom view. Your custom view should be a subclass of NSFrameView, which means you also need a header for that class.

Set NSScrollView to not editable

I was wondering how to take care that my NSScrollView is not editable by the user, but i didn't find a way, there is no option in IB, nor do I find an appropriate method of the NSSCrollView class.
A previous post suggested to implement a delegate method
- (BOOL)textShouldBeginEditing:(NSText *)aTextObject
to return false, but this didn't work for me yet.
No solution was given on the previous question.
(I also tried selecting the TextView everything it doesn't display an option 'editable' i just downloaded the new Xcode so the version shouldn't be a problem)
You can't make NSScrollView non-editable. You can hide scrollers with setHasVerical/HorizontalScroller: that would prevent user from scrolling.
If you have NSTextView and want to make it non-editable just send setEditable:NO to it, not the scroll view. For that you obviously need a reference to the NSTextView or use NSScrollViews -documentView.
what is inside the scrollView that you want to prevent editing of?
what views have you got embedded in the scrollView? you need to find the view embedded in the scrollView that you want to prevent editing on, and call setEditable:NO on it.