API 0.9.5
AppKit/CPPopover.j
Go to the documentation of this file.
00001 /*
00002  * CPPopover.j
00003  * AppKit
00004  *
00005  * Created by Antoine Mercadal.
00006  * Copyright 2011 Antoine Mercadal.
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00023 
00024 
00025 
00026 CPPopoverBehaviorApplicationDefined = 0;
00027 CPPopoverBehaviorTransient          = 1;
00028 CPPopoverBehaviorSemitransient      = 2;
00029 
00030 
00031 var CPPopoverDelegate_popover_willShow_     = 1 << 0,
00032     CPPopoverDelegate_popover_didShow_      = 1 << 1,
00033     CPPopoverDelegate_popover_shouldClose_  = 1 << 2,
00034     CPPopoverDelegate_popover_willClose_    = 1 << 3,
00035     CPPopoverDelegate_popover_didClose_     = 1 << 4;
00036 
00037 
00051 @implementation CPPopover : CPResponder
00052 {
00053     @outlet CPViewController    _contentViewController;
00054     @outlet id                  _delegate;
00055 
00056     BOOL                        _animates;
00057     BOOL                        _shown;
00058     int                         _appearance;
00059     int                         _behavior;
00060 
00061     BOOL                        _needsCompute;
00062     _CPAttachedWindow           _attachedWindow;
00063     int                         _implementedDelegateMethods;
00064 }
00065 
00066 
00067 #pragma mark -
00068 #pragma mark Initialization
00069 
00075 - (CPPopover)init
00076 {
00077     if (self = [super init])
00078     {
00079         _animates       = YES;
00080         _appearance     = CPPopoverAppearanceMinimal;
00081         _behavior       = CPPopoverBehaviorApplicationDefined;
00082         _needsCompute   = YES;
00083         _shown          = NO;
00084     }
00085 
00086     return self;
00087 }
00088 
00089 
00090 #pragma mark -
00091 #pragma mark Getters / Setters
00092 
00098 - (CPRect)positioningRect
00099 {
00100     if (!_attachedWindow || ![_attachedWindow isVisible])
00101         return nil;
00102     return [_attachedWindow frame];
00103 }
00104 
00108 - (void)setPositioningRect:(CPRect)aRect
00109 {
00110     if (!_attachedWindow || ![_attachedWindow isVisible])
00111         return;
00112     [_attachedWindow setFrame:aRect];
00113 }
00114 
00120 - (CPRect)contentSize
00121 {
00122     if (!_attachedWindow || ![_attachedWindow isVisible])
00123         return nil;
00124     return [[_contentViewController view] frameSize];
00125 }
00126 
00132 - (void)setContentSize:(CPSize)aSize
00133 {
00134     [[_contentViewController view] setFrameSize:aSize];
00135 }
00136 
00142 - (BOOL)shown
00143 {
00144     if (!_attachedWindow)
00145         return NO;
00146     return [_attachedWindow isVisible];
00147 }
00148 
00156 - (void)setBehaviour:(int)aBehaviour
00157 {
00158     if (_behavior == aBehaviour)
00159         return;
00160 
00161     _behavior = aBehaviour;
00162     _needsCompute = YES;
00163 }
00164 
00165 
00166 - (void)setDelegate:(id)aDelegate
00167 {
00168     if (_delegate === aDelegate)
00169         return;
00170 
00171     _delegate = aDelegate;
00172     _implementedDelegateMethods = 0;
00173 
00174     if ([_delegate respondsToSelector:@selector(popoverWillShow:)])
00175         _implementedDelegateMethods |= CPPopoverDelegate_popover_willShow_;
00176 
00177     if ([_delegate respondsToSelector:@selector(popoverDidShow:)])
00178         _implementedDelegateMethods |= CPPopoverDelegate_popover_didShow_;
00179 
00180     if ([_delegate respondsToSelector:@selector(popoverShouldClose:)])
00181         _implementedDelegateMethods |= CPPopoverDelegate_popover_shouldClose_;
00182 
00183     if ([_delegate respondsToSelector:@selector(popoverWillClose:)])
00184         _implementedDelegateMethods |= CPPopoverDelegate_popover_willClose_;
00185 
00186     if ([_delegate respondsToSelector:@selector(popoverDidClose:)])
00187         _implementedDelegateMethods |= CPPopoverDelegate_popover_didClose_;
00188 }
00189 
00190 #pragma mark -
00191 #pragma mark Positioning
00192 
00200 - (void)showRelativeToRect:(CPRect)positioningRect ofView:(CPView)positioningView preferredEdge:(CPRectEdge)preferredEdge
00201 {
00202     if (_implementedDelegateMethods & CPPopoverDelegate_popover_willShow_)
00203         [_delegate popoverWillShow:self];
00204 
00205     if (!_contentViewController)
00206          [CPException raise:CPInternalInconsistencyException reason:@"contentViewController must not be nil"];
00207 
00208     if (_needsCompute || !_attachedWindow)
00209     {
00210         var styleMask = (_behavior == CPPopoverBehaviorTransient) ? CPClosableOnBlurWindowMask : nil;
00211         _attachedWindow = [[_CPAttachedWindow alloc] initWithContentRect:CPRectMakeZero() styleMask:styleMask];
00212     }
00213 
00214     [_attachedWindow setAppearance:_appearance];
00215     [_attachedWindow setAnimates:_animates];
00216     [_attachedWindow setDelegate:self];
00217     [_attachedWindow setMovableByWindowBackground:NO];
00218     [_attachedWindow setFrame:[_attachedWindow frameRectForContentRect:[[_contentViewController view] frame]]];
00219     [_attachedWindow setContentView:[_contentViewController view]];
00220 
00221     if (positioningRect)
00222         [_attachedWindow positionRelativeToRect:positioningRect preferredEdge:preferredEdge];
00223     else if (positioningView)
00224         [_attachedWindow positionRelativeToView:positioningView preferredEdge:preferredEdge];
00225     else
00226         [CPException raise:CPInvalidArgumentException reason:@"a value must be passed for positioningRect or positioningView"];
00227 
00228     if (_implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
00229         [_delegate popoverDidShow:self];
00230 }
00231 
00235 - (void)close
00236 {
00237     if (_implementedDelegateMethods & CPPopoverDelegate_popover_shouldClose_)
00238         if (![_delegate popoverShouldClose:self])
00239             return;
00240 
00241     if (_implementedDelegateMethods & CPPopoverDelegate_popover_willClose_)
00242         [_delegate popoverWillClose:self];
00243 
00244     [_attachedWindow close];
00245 
00246     if (_implementedDelegateMethods & CPPopoverDelegate_popover_didClose_)
00247         [_delegate popoverDidClose:self];
00248 }
00249 
00250 
00251 #pragma mark -
00252 #pragma mark Action
00253 
00259 - (IBAction)performClose:(id)aSender
00260 {
00261     [self close];
00262 }
00263 
00264 
00265 #pragma mark -
00266 #pragma mark Delegates
00267 
00269 - (BOOL)attachedWindowShouldClose:(_CPAttachedWindow)anAttachedWindow
00270 {
00271     [self close];
00272 
00273     // we return NO, because we want the CPPopover to compute
00274     // if the attached can be close in order to send delegate messages
00275     return NO;
00276 }
00277 
00278 @end
00279 
00280 var CPPopoverNeedsComputeKey = @"CPPopoverNeedsComputeKey",
00281     CPPopoverAppearanceKey = @"CPPopoverAppearanceKey",
00282     CPPopoverAnimatesKey = @"CPPopoverAnimatesKey",
00283     CPPopoverContentViewControllerKey = @"CPPopoverContentViewControllerKey",
00284     CPPopoverDelegateKey = @"CPPopoverDelegateKey",
00285     CPPopoverBehaviorKey = @"CPPopoverBehaviorKey";
00286 
00287 @implementation CPPopover (CPCoding)
00288 
00289 - (id)initWithCoder:(CPCoder)aCoder
00290 {
00291     self = [super initWithCoder:aCoder];
00292 
00293     if (self)
00294     {
00295         _needsCompute = [aCoder decodeIntForKey:CPPopoverNeedsComputeKey];
00296         _appearance = [aCoder decodeIntForKey:CPPopoverAppearanceKey];
00297         _animates = [aCoder decodeBoolForKey:CPPopoverAnimatesKey];
00298         _contentViewController = [aCoder decodeObjectForKey:CPPopoverContentViewControllerKey];
00299         [self setDelegate:[aCoder decodeObjectForKey:CPPopoverDelegateKey]];
00300         [self setBehaviour:[aCoder decodeIntForKey:CPPopoverBehaviorKey]];
00301     }
00302     return self;
00303 }
00304 
00305 - (void)encodeWithCoder:(CPCoder)aCoder
00306 {
00307     [super encodeWithCoder:aCoder];
00308 
00309     [aCoder encodeBool:_needsCompute forKey:CPPopoverNeedsComputeKey];
00310     [aCoder encodeInt:_appearance forKey:CPPopoverAppearanceKey];
00311     [aCoder encodeObject:_animates forKey:CPPopoverAnimatesKey];
00312     [aCoder encodeObject:_contentViewController forKey:CPPopoverContentViewControllerKey];
00313     [aCoder encodeObject:_delegate forKey:CPPopoverDelegateKey];
00314     [aCoder encodeInt:_behavior forKey:CPPopoverBehaviorKey];
00315 }
00316 
00317 @end
00318 
00319 @implementation CPPopover (CPSynthesizedAccessors)
00320 
00324 - (CPViewController)contentViewController
00325 {
00326     return _contentViewController;
00327 }
00328 
00332 - (void)setContentViewController:(CPViewController)aValue
00333 {
00334     _contentViewController = aValue;
00335 }
00336 
00340 - (id)delegate
00341 {
00342     return _delegate;
00343 }
00344 
00348 - (BOOL)animates
00349 {
00350     return _animates;
00351 }
00352 
00356 - (void)setAnimates:(BOOL)aValue
00357 {
00358     _animates = aValue;
00359 }
00360 
00364 - (BOOL)shown
00365 {
00366     return _shown;
00367 }
00368 
00372 - (int)appearance
00373 {
00374     return _appearance;
00375 }
00376 
00380 - (void)setAppearance:(int)aValue
00381 {
00382     _appearance = aValue;
00383 }
00384 
00388 - (int)behavior
00389 {
00390     return _behavior;
00391 }
00392 
00393 @end
 All Classes Files Functions Variables Defines