/* NSPopover.h Application Kit Copyright (c) 2010-2012, Apple Inc. All rights reserved. */ #import #import #import #import #import @class NSView, NSViewController, NSWindow, NSNotification, NSString; #pragma mark - #pragma mark Popovers /* A popover is a unit of content that is positioned relative to some other content on the screen. An anchor is used to express the relation between these two units of content. Each popover has an appearance that specifies its visual characteristics, as well as a behavior that determines which user interactions will cause the popover to close. A transient popover is closed in response to most user interactions, whereas a semi-transient popovers is closed when the user interacts with the window containing the popover's positioning view. Popovers with application-defined behavior are not usually closed on the developer's behalf. AppKit automatically positions each popover relative to its positioning view and moves the popover whenever its positioning view moves. A positioning rectangle within the positioning view can be specified for additional granularity. Popovers can be detached to become a separate window when they are dragged by implementing the appropriate delegate method. */ #pragma mark - #pragma mark Enumerated Types /* Popovers may have one of several predefined appearances. You may specify the appearance of a popover using the constants listed below. The default appearance is NSPopoverAppearanceMinimal. */ enum { /* The popover will use a minimal appearance, currently a solid color border and a solid color fill (although this may change in the future). */ NSPopoverAppearanceMinimal = 0, /* The popover will draw with a HUD appearance. */ NSPopoverAppearanceHUD = 1 }; typedef NSInteger NSPopoverAppearance; /* AppKit supports transient, semi-transient, and application-defined behaviors. Please see the class description above for more information. The default popover behavior is NSPopoverBehaviorApplicationDefined. */ enum { /* Your application assumes responsibility for closing the popover. AppKit will still close the popover in a limited number of circumstances. For instance, AppKit will attempt to close the popover when the window of its positioningView is closed. The exact interactions in which AppKit will close the popover are not guaranteed. You may consider implementing -cancel: to close the popover when the escape key is pressed. */ NSPopoverBehaviorApplicationDefined = 0, /* AppKit will close the popover when the user interacts with a user interface element outside the popover. Note that interacting with menus or panels that become key only when needed will not cause a transient popover to close. The exact interactions that will cause transient popovers to close are not specified. */ NSPopoverBehaviorTransient = 1, /* AppKit will close the popover when the user interacts with user interface elements in the window containing the popover's positioning view. Semi-transient popovers cannot be shown relative to views in other popovers, nor can they be shown relative to views in child windows. The exact interactions that cause semi-transient popovers to close are not specified. */ NSPopoverBehaviorSemitransient = 2 }; typedef NSInteger NSPopoverBehavior; @protocol NSPopoverDelegate; NS_CLASS_AVAILABLE(10_7, NA) @interface NSPopover : NSResponder { @private id _bindingAdaptor; id _delegate; id _visualRepresentation; NSView *_positioningView; NSViewController *_contentViewController; NSWindow *_positioningWindow; NSPopoverAppearance _appearance; NSPopoverBehavior _behavior; NSRectEdge _unused; NSRectEdge _preferredEdge; NSPoint _unused2; NSSize _contentSize; NSRect _positioningRect; #if !__OBJC2__ id _reserved[3]; #endif struct { unsigned int animates:1; unsigned int positioningRectIsBounds:1; unsigned int registeredAsTransient:1; unsigned int registeredAsSemitransient:1; unsigned int shown:1; unsigned int toolbarHidesAnchor:1; unsigned int closing:1; unsigned int reserved:25; } _flags; } /* -init is the designated initializer. */ #pragma mark - #pragma mark Bindings /* NSPopover exposes the following bindings: contentWidth (CGFloat, readonly) contentHeight (CGFloat, readonly) positioningRect (NSRect, readonly) */ #pragma mark - #pragma mark Properties /* All properties of NSPopover are KVO compliant. */ /* The delegate of the popover. The delegate is not retained. */ @property(assign) IBOutlet id delegate; /* The appearance of the popover. The default appearance is NSPopoverAppearanceMinimal. See the declaration of NSPopoverAppearance above for more information about appearances. */ @property NSPopoverAppearance appearance; /* The behavior of the popover. The default behavior is NSPopoverBehaviorApplicationDefined. See the declaration of NSPopoverBehavior above for more information about popover behaviors. */ @property NSPopoverBehavior behavior; /* Should the popover be animated when it shows, closes, or appears to transition to a detachable window. This property also controls whether the popover animates when the content view or content size changes. AppKit does not guarantee which behaviors will be animated or that this property will be respected; it is regarded as a hint. The default value is YES. */ @property BOOL animates; /* The view controller that manages the content of the popover. The default value is nil. You must set the content view controller of the popover to a non-nil value before the popover is shown. Changes to the popover's content view controller while the popover is shown will animate (provided animates is YES). */ @property(retain) IBOutlet NSViewController *contentViewController; /* The content size of the popover. The popover's content size is set to match the size of the content view when the content view controller is set. Changes to the content size of the popover will animate while the popover is shown (provided animates is YES). */ @property NSSize contentSize; /* YES if the popover is being shown, NO otherwise. The popover is considered to be shown from the point when -showRelativeToRect:ofView:preferredEdge: is invoked until the popover is closed in response to an invocation of either -close or -performClose:. */ @property(readonly, getter=isShown) BOOL shown; /* Popovers are positioned relative to a positioning view and are automatically moved when the location or size of the positioning view changes. Sometimes it is desirable to position popovers relative to a rectangle within the positioning view. In this case, you must update the positioningRect binding whenever this rectangle changes, or use the positioningRect binding so AppKit can re-position the popover when appropriate. */ @property NSRect positioningRect; #pragma mark - #pragma mark Show and Close /* Shows the popover positioned relative to positioningRect of positioningView (see the description of positioningRect above). The common case is to pass [positioningView bounds] for positioningRect, in which case the popover will be placed adjacent to the positioningView and there is no need to update positioningRect (AppKit will detect the the bounds of the positioning view was specified and automatically update the positioningView). preferredEdge is a hint to AppKit about the desired placement of the anchor of the popover towards the positioningRect, and is with respect to the -isFlipped state of the positioningView. Also, if positioningRect is an empty rect, the [view bounds] will automatically be used. The current (but not guaranteed) behavior is that AppKit will place the anchor towards the preferredEdge of the positioningRect unless such a placement would cause the popover not to fit on the screen of positioningView. If the anchor cannot be placed towards the preferredEdge, AppKit will (in the current implementation) attempt to place the anchor on the opposite side of the positioningRect. If that cannot be done, AppKit will attempt to place the anchor on a remaining sides of the popover, and failing that will center the popover on the screen, causing it to (at least temporarily) lose its anchor. The popover will animate onscreen and eventually animate offscreen when it is closed (unless the property animates is set to NO). This method will throw a NSInvalidArgumentException if view is nil or if view is not in a window, or if the popover's behavior is NSPopoverBehaviorSemitransient and the popover's positioningView is in a popover or child window. It will throw a NSInternalInconsistencyException if the popover's content view controller (or the view controller's view) is nil. If the popover is already being shown, this method will update to be associated with the new view and positioningRect passed. If the positioning view is not visible, this method does nothing. */ - (void)showRelativeToRect:(NSRect)positioningRect ofView:(NSView *)positioningView preferredEdge:(NSRectEdge)preferredEdge; /* Attempts to close the popover. The popover will not be closed if it has a delegate and the delegate returns NO to -popoverShouldClose: (or if the popover's class implements -popoverShouldClose: to return NO). The operation will fail if it is displaying a nested popover, or if it has a child window. A window will attempt to close its popovers when it receives a -performClose: message. The popover will animate out when closed (unless the animates property is set to NO). */ - (IBAction)performClose:(id)sender; /* Forces the popover to close without consulting its delegate. Any popovers nested within the popovers will also receive a close message. When a window is closed in response to the -close message being sent, all of its popovers will be closed. The popover will animate out when closed (unless the animates property is set to NO). */ - (void)close; @end #pragma mark - #pragma mark Notifications /* Specifies the close reason. Currently used only as the userInfo key for the NSPopoverWillCloseNotification. */ APPKIT_EXTERN NSString * const NSPopoverCloseReasonKey NS_AVAILABLE_MAC(10_7); /* Specifies that the popover is being closed in a standard way; a possible value for NSPopoverCloseReasonKey. */ APPKIT_EXTERN NSString * const NSPopoverCloseReasonStandard NS_AVAILABLE_MAC(10_7); /* Specifies that the popover has been closed because it is being detached to a window; a possible value for NSPopoverCloseReasonKey. */ APPKIT_EXTERN NSString * const NSPopoverCloseReasonDetachToWindow NS_AVAILABLE_MAC(10_7); /* Sent before the popover is shown. */ APPKIT_EXTERN NSString * const NSPopoverWillShowNotification NS_AVAILABLE_MAC(10_7); /* Sent after the popover has finished animating onscreen. */ APPKIT_EXTERN NSString * const NSPopoverDidShowNotification NS_AVAILABLE_MAC(10_7); /* Sent before the popover is closed. The userInfo key NSPopoverCloseReasonKey specifies the reason for closing. It can currently be either NSPopoverCloseReasonStandard or NSPopoverCloseReasonDetachToWindow, although more reasons for closing may be added in the future. */ APPKIT_EXTERN NSString * const NSPopoverWillCloseNotification NS_AVAILABLE_MAC(10_7); /* Sent after the popover has finished animating offscreen. This notification has the same user info keys as NSPopoverWillCloseNotification. */ APPKIT_EXTERN NSString * const NSPopoverDidCloseNotification NS_AVAILABLE_MAC(10_7); #pragma mark - #pragma mark Delegate Methods @protocol NSPopoverDelegate @optional /* Returns YES if the popover should close, NO otherwise. The popover invokes this method on its delegate whenever it is about to close to give the delegate a chance to veto the close. If the delegate returns YES, -popoverShouldClose: will also be invoked on the popover to allow the popover to veto the close. */ - (BOOL)popoverShouldClose:(NSPopover *)popover; /* Return a window to which the popover should be detached. You should not remove the popover's content view as part of your implementation of this method. The popover and the detachable window may be shown at the same time and therefore cannot share a content view (or a content view controller). If the popover and the detachable window should have the same content, you should define the content in a separate nib file and use a view controller to instantiate separate copies of the content for the popover and the detachable window. The popover will animate to appear as though it morphs into the detachable window (unless the animates property is set to NO. The exact animation used is not guaranteed). Subclasses of NSPopover may also implement this method, in which case the subclass method will be invoked only if the delegate does not implement the method. */ - (NSWindow *)detachableWindowForPopover:(NSPopover *)popover; /* Invoked on the delegate when the NSPopoverWillShowNotification notification is sent. This method will also be invoked on the popover. */ - (void)popoverWillShow:(NSNotification *)notification; /* Invoked on the delegate when the NSPopoverDidShowNotification notification is sent. This method will also be invoked on the popover. */ - (void)popoverDidShow:(NSNotification *)notification; /* Invoked on the delegate when the NSPopoverWillCloseNotification notification is sent. This method will also be invoked on the popover. */ - (void)popoverWillClose:(NSNotification *)notification; /* Invoked on the delegate when the NSPopoverDidCloseNotification notification is sent. This method will also be invoked on the popover. */ - (void)popoverDidClose:(NSNotification *)notification; @end