How can I remove the "blur" effect that Cocoa adds to transparent sheets? - objective-c

By default, Cocoa adds a background blur effect to transparent and semitransparent modal sheets when they are applied to a window. I would like to disable the blur effect. How would I go about doing it?
I have created a custom sheet (a subclass of NSWindow with a transparent background and some controls in it). I am able to display it using the standard beginSheet method as follows:
[NSApp beginSheet:myCustomSheet
modalForWindow:mainWindow
modalDelegate:self
didEndSelector:...];
The sheet displays fine, but everything behind it is blurred.
Note 1: I am writing a completely customized user interface for a touch screen / kiosk type app, so none of the usual Apple user interface guidelines apply.
Note 2: I do want to see what is underneath the sheet. As SirRatty pointed out, it is possible to block out the blurred portion by filling in the background. In my case, I want to have the background show through, just without appearing blurred.

There's a private API call that can be used to set a CI filter on the background of a window:
http://www.mail-archive.com/cocoa-dev#lists.apple.com/msg16280.html
There's also a CGSRemoveWindowFilter:
extern CGError CGSRemoveWindowFilter(CGSConnectionID cid, CGSWindowID wid, CGSWindowFilterRef filter);
Just be aware that the usual private API caveats apply (might go away or change in the future, etc.).

What I've done:
In IB, add a window-sized custom NSView to the window, at the bottom of the content view hierarchy. Set the object's class to MySolidView (or whatever.)
In Xcode, the MySolidView class does just one thing: on -drawRect it will fill the view with a solid color. (e.g. light grey).

You could write your own sheet animation routines that display your own NSWindow and fill the background of the window with a semitransparent colour. I'm not sure whether setAlphaValue: for NSWindow will also affect the child elements' opacity. If it does affect them, you could use setBackgroundColor: and provide the default window background colour but with an alpha component, this should not affect the child elements.
I suppose one of the problems of developing/designing your own user interface is when you have to reimplement the wheel just for a minor customisation. At least, if you write it yourself, you'll have more control over its customisation in the future.

Related

What Cocoa Views and Controls Will Create Something like Part of the Network Prefs Display (Mac OS)? [duplicate]

This question already has an answer here:
NSTableView with +/- buttons like in System Preferences using only Interface Builder
(1 answer)
Closed 7 years ago.
I'm building an OSX app and want to create a set of controls similar to what's found at bottom of the standard Network Preferences configuration panel. I'm running into some layout problems that I wouldn't have expected.
These are my specific questions:
What contains the 3 buttons so there's similar shading all they way across the row where the buttons are positioned? In particular, what's causing the area without buttons to have shading?
How do you do this without getting a double border where the row of buttons meets up with the table?
I want to do this with an xib file. This may be incredibly simple, but I'm missing something I guess.
I find that if you make a button with style "Gradient" and type "Momentary Change", then it looks like the other buttons but does not respond to clicks, so you can use that as the area after the last button. (The NSMomentaryChangeButton is documented as changing the image and title when clicked, so if you don't use an image or title, nothing should change.)
If you check Refuses First Responder in the attributes inspector, then it will not be possible to highlight this blank button using Full Keyboard Access.
Ken Thomases also brings up the issue of the blank button being shown as a button to Accessibility. One can fix that by using a subclass of NSButtonCell that has just one method:
- (BOOL)accessibilityIsIgnored
{
return YES;
}
I think that's easier than writing a custom view.
As d00dle says, avoid double borders by slightly overlapping things.
Since you want the slack space to have the same background as the buttons, and since the buttons can change appearance from release to release of the OS, the best thing to do is to get the frameworks to draw it like it would the buttons.
Rather than using an actual button as JWWalker suggests, I have used a custom view that leverages NSButtonCell to draw the background. The advantage is that you can be sure there's no chance of getting undesirable behavior. For example, a button could get focus (for users who have All Controls selected in System Preferences > Keyboard > Shortcuts > Full Keyboard Access) so that the user could Tab to it. Accessibility will report the presence of the button through VoiceOver. Etc.
Configure the button cell just like the buttons (set buttonType and bezelStyle). In the view's -drawRect: call [buttonCell drawWithFrame:rect inView:self];, where rect is similar to the frames of the buttons. Since one way to avoid double borders is to make the buttons larger than the view's bounds, you may need to do the same for rect. For example, you might want to use NSInsetRect(self.bounds, -1, -1).
The buttons are buttons... This can be accomplished with a custom view drawing border and the background "shading".
To avoid the double border where the table and the custom view meet you simply align it so they overlap by 1 point (pixel) or avoid drawing the top border in your custom view.
I don't know of any standard object capable of doing this.

Enable just small portion of NSWindow?

I must achievement somenthing tricky in my application for MAC OS, and because it's not easy to explain I will put an image: custom window
I created the NSWindow from image but the problema is how can create the NSView (the blue one) which is over and which have the purpose to block other action from user and just left small portion to be active. Any suggestion?
You can create a Custom NSView and draw clear color for enbaled rect area and disabled color for rest of the area. Capture the mouseDown event for the custom view and discard all the mouse events outside enabled rect area and if the mouse down in enabled area then call the mouse down event to the control behind the enabled area.
Wouldn't it be better to put up a sheet with a dialog to ask the user for the required information (and prevent interaction with the rest of the window) instead of mimicking a very un-Mac-like UI?
For example, consider the UI when creating a new project or adding a file to a project in Xcode.
If you really must attempt this, don't use a view to cover the window. Use another window. Make it borderless. Set its backgroundColor to [NSColor clearColor] and its opaque property to NO. Set its hasShadow property to NO. Set its frame to match the content rect of the window you want to block (or maybe its frame if you need to prevent interaction with its title bar).
Attach your overlay window to the main window as a child, using -addChildWindow:ordered:.
For the contentView of the overlay window, create a view that will draw the semi-transparent color everywhere except for over the control you want to leave accessible. To get that rect in the main window's coordinate system, you would use something like [specialView convertRect:specialView.bounds toView:nil].

What secret things are happening to my NSButtonCell?

I'm writing an OS X app (target 10.10, Xcode 6.1) and I'm really confused by my custom NSButtonCell subclass. It seems like there are things going on here that shouldn't. I'm new to OS X programming, so I'm asking if anyone has insight into the inner workings of NSButtonCell.
First, what seems to be working?
I can set the button's image and title. The image appears normally.
The storyboard sets up the button to be Style: Textured and Type: Momentary Change. It's not Bordered, not Transparent, and doesn't allow Mixed State.
List of complaints:
I override -drawTitle:withFrame:inView: to draw the title in a custom color depending on the cell's highlighted. This color should be #cccccc when the cell is not highlighted, but it's actually #d6d6d6.
The button has both image and alternate image. The image that's drawn is never the alternate image, so I override -drawImage:withFrame:inView: to pick the correct image for cell's highlighted. This appears to work, but what the heck, NSButtonCell? How is on/off state different from highlighted? I've tried many of the Type options and none seem to change the fact that pressing the button will momentarily change highlighted, and toggle state.
Speaking of momentarily changing highlighted, it appears that its duration is about as short as possible, so I had to implement a sort of "debouncer" to prevent -drawWithFrame:inView: from being called more frequently than a specified threshold.
My button cell also has properties myBackgroundColor and myAlternateBackgroundColor. I'm not using backgroundColor because I need to be able to draw a custom background shape (filled rect, filled circle, etc). The alternate background color is used when highlighted. The problem here is that the alternate background color should be #93edbf but appears to be #a1eecb! In order to get it to look like #93edbf, I need to set the color to #84ecb2.
So far this has all been about one particular instance of this button cell. But in another instance, the alternate background isn't drawing at all! I've read through the storyboard code and the buttons are as identical as they can be. My view controller code likewise updates both button cells' properties at the same time. Why would one button behave differently from another?
I want the button to highlight on mouse down instead of "momentarily" after mouse up. I haven't yet implemented this in my custom cell. Man, NSButtonCell is really lacking some things. How does something like that happen? Don't the OS X and iOS teams ever talk to each other?
What could it be?
I've already verified that the cell's controlTint is set to NSClearControlTint. I've checked for background filters, compositing filters and content filters on the off chance they had anything to do with this.
I know Apple really wants us to use their native look and feel for UI elements, but I never thought they'd go so far as to force the use of some highlight tint.

Add / Remove buttons in NSOutlineView

I have a Source-View (NSOutlineView) with two Buttons at the bottom. I added an NSBox so that the items don't "shine through" when they're behind the buttons.
This works fine when the window is active:
But as soon as I deactivate the window the NSBox still has that active color, rather than a dimmed version to match the NSOutlineView's background color:
How can I make sure that those two colors always match. Also using a specific color is a bit of a hack since the color NSOutline uses might change at some point.
Update: Apple's Mail.app as well as Things seem to have a solution for that problem. :-/
#Neha put me on the right way to find a solution.
I write it in Ruby because I work with Rubymotion but it's easy to translate :)
Assuming you have a box outlet for the NSBox, you can set it to transparent when the window loses the focus and do the opposite when it becomes the key window, using the appropriate delegate methods:
def windowDidBecomeKey(notification)
box.setTransparent(false)
end
def windowDidResignKey(notification)
box.setTransparent(true)
end
And the result looks fine with the focus:
And without it:
The solution is to keep a reference to the NSOutlineView's backgroundColor property as it is a special NSColor that dynamically changes depending on the key status of the parent window. Set the color of your custom view to that that reference. When the window loses/gains key status, call setNeedsDisplay: on your custom view to redraw it using the new color. Use KVO to observe NSWindowDidBecomeKeyNotification and NSWindowDidResignKeyNotification. Note that pointer to the color stays the same, but the actual color represented by the reference changes. The solution is explained here.
In the attributes inspector of NSBox,
set display to transparent

Cocoa / Interface Builder: What do I need to subclass to replicate this window?

I'm guessing it is using a custom NSWindow, NSTextField, NSSecureTextField, NSButton? I don't necessarily want to replicate it, I would just like to know what would be involved in customizing my app's UI to this level.
The window itself could be a HUD-style panel, which you can get in IB without subclassing anything. It looks like there's a bit of custom background to it, unless it's just faintly showing something behind it; if it is a custom background, a custom view as the content view could do that job.
The separator could be an image view or a custom view.
The static text fields can be done without subclassing. Just change the text color.
The editable text fields, both the regular one and the secure one, you would need to subclass. I have no idea how you would do that.
The follow-link button is a mix of custom drawing and a standard image. Start with the NSImageNameFollowLinkFreestandingTemplate image; draw that, then fill an empty path with white using the source-in blend mode.
The other two buttons are customized, probably using custom cells in order to override the background without overriding the text drawing.