Modal child windows - like sheets but not a sheet - objective-c

I'm trying to replicate the modal behavior of a sheet in Cocoa without actually using a sheet. That is, attaching a borderless child window to the main window and have the child window be the only responder. The parent window should remain key, support resizing, but cannot be navigated/responded to via keyboard or mouse.
So far I've added a borderless NSPanel subclass to the main window, which returns YES from -acceptsFirstResponder, and run the child window modally of the parent. The parent window remains the key window (as the NSPanel subclass returns NO from -canBecomeKeyWindow) but the parent window still has focus. I can use the keyboard to selected a button, which does nothing because of the modal child window. I need the child window to become first responder and calling -makeFirstResponder and setting the -initialFirstResponder view for the window has not effect.

NSWindow has had an - (void)addChildWindow:(NSWindow *)childWindow ordered:(NSWindowOrderingMode)orderingMode method since Mac OS X 10.2. Using the NSWindowAbove ordering mode should be pretty close to what you're looking for. If you create the child window to cover the parent (make the child window borderless), but leave the parent's titlebar exposed – that should do what you're looking for. You may still need to disable interaction with the controls on the parent window while the child is shown if that's the behaviour you want.

Related

NSOutlineView select with the first click

I have an NSPanel with a NSOutlineView to display my data. I want to select a row with a first click inside the NSOutlineView even if the panel is not in focus (i.e. not the key window) I have a delegate that allows selection and I have overridden the NSOutlineView class to override the acceptsFirstMouse: method, but I could not get the first click selection.
I checked the mouseDown event and it fired without any problems (in my class that overrides) when the panel was and wasn't the key window. But when the panel is not key, NSOutlineViewDelegate method shouldSelectItem: is not called.
What am I missing/doing wrong?
You just need to subclass your NSTableOutlineView and override:
- (BOOL)needsPanelToBecomeKey
to return NO.
NSView class reference states:
Overridden by subclasses to determine if the receiver requires its
panel, which might otherwise avoid becoming key, to become the key
window so that it can handle keyboard input and navigation.
Discussion
Such a subclass should also override acceptsFirstResponder
to return YES.
This method is also used in keyboard navigation. It determines if a
mouse click should give focus to a view (make it first responder).
Some views will want to get keyboard focus when you click in them, for
example text fields. Other views should only get focus if you tab to
them, for example, buttons. You wouldn't want focus to shift from a
textfield that has editing in progress simply because you clicked on a
check box.
Source: Apple documentation

NSWindow child window close on parent click

I need to implement a custom popover (cannot use NSPopover). Its all working fine, but I also need to implement that the popover closes itself when the user clicks somewhere in the parent window.
What's the best way to implement this, resp. how could this be implemented without subclassing the parent window?
Make the popover key window when showing it, and use NSWindowDidResignKeyNotification (or the delegate method) to close when it resigns that status (which happens when user makes some other window active). Closing whenever the parent window is closed is also a good idea (NSWindowWillCloseNotification).

How do I force keyboard focus for a Modal Window without Title Bar

I want to run a simple dialog similar to Finder Go To Folder.
I have used a NSPanel made this Document Modal and run with runModal.
This works, but displays a title.
If I turn off the Title Bar (in IB) the buttons work, but the NSTextField does not get keyboard focus.
I have tried lots of techniques to make it firstResponder or set as key, setBecomesKeyOnlyIfNeeded:NO but to no avail.
You need to subclass NSWindow, override - (BOOL)canBecomeKeyWindow and return YES.
By default, borderless windows cannot become the key window.

NSView outside of NSWindow

I have an NSWindow and basically, what I am trying to pop up an NSWindow outside of the bounds of the NSWindow it's in every time a user hovers over the NSWindow.
But every time I try to do that, since the NSView is outside of the bounds of NSWindow it gets cut off.
Here's a picture of what I am trying to achieve:
You need to create a borderless NSWindow, large enough to contain your view, and make the window a child window of the main window it's attached to. To make a window a child of another window, you use the addChildWindow:ordered: method of NSWindow.
Child windows are attached to the parent window and will move with their parent window when the parent window moves. If you just open a new window without making it a child window, it will be "left behind" if the other window is moved.
To make a borderless window, pass NSBorderlessWindowMask as the styleMask to the initWithContentRect:styleMask:backing:defer: method of NSWindow.
The easiest approach is to create another NSWindow with no border and put the button in that.

Document.xib contains two windows, one window needs to be a preference panel

I have created a Document-Based Application using Core Data. I replaced the automatically created window in Document.xib with two windows: a "Panel" window and a "Window" window.
The "Panel" window contains a table view with bindings to an NSArrayController. The table view is used to add data to the array using the document class's entities and attributes. I would like to make this window act as a Preferences window. This window should appear when a button in the main "Window" is clicked.
The "Window" is my main window where I display data from the same NSArrayController using bindings. This window contains a button that I would like to use to make the "Panel" window appear.
I can hide the "Panel" window upon launch and only show the main "Window", but I can't figure out how to set the action of the button to show the "Panel" window.
Any thoughts on how to accomplish this??
I tried using two separate XIB files, but then I have a problem where I can't get the NSArrayController data into the other window.
Try connecting your button's action selector to your panel's makeKeyAndOrderFront: action.