Attached sheet implementation

This commit is contained in:
cacaodev authored and Ross Boucher committed 2009-10-08 12:58:22 -07:00
1 parent 1d76ac1b91
commit c6b934a035
5 files changed
+229 -36

No files matched your search

+31
View File
@@ -719,9 +719,40 @@ CPRunContinuesResponse = -1002;
*/
- (void)beginSheet:(CPWindow)aSheet modalForWindow:(CPWindow)aWindow modalDelegate:(id)aModalDelegate didEndSelector:(SEL)aDidEndSelector contextInfo:(id)aContextInfo
{
var styleMask = [aSheet styleMask];
if (!(styleMask & CPDocModalWindowMask))
{
[CPException raise:CPInternalInconsistencyException reason:@"Currently only CPDocModalWindowMask style mask is supported for attached sheets"];
return;
}
[aWindow _attachSheet:aSheet modalDelegate:aModalDelegate didEndSelector:aDidEndSelector contextInfo:aContextInfo];
}
- (void)endSheet:(CPWindow)sheet returnCode:(int)returnCode
{
var count = [_windows count];
while (--count >= 0)
{
var aWindow = [_windows objectAtIndex:count];
var context = aWindow._sheetContext;
if (context != nil && context["sheet"] === sheet)
{
context["returnCode"] = returnCode;
[aWindow _detachSheetWindow];
return;
}
}
}
- (void)endSheet:(CPWindow)sheet
{
[self endSheet:sheet returnCode:0];
}
- (CPArray)arguments
{
if(_fullArgsString != window.location.hash)
+7
View File
@@ -46,6 +46,13 @@ CPCancelButton = 0;
<li>A panel can be made to work even when there's an attention panel on-screen. This permits actions within the panel to affect the attention panel.</li>
</ul>
*/
/*
@global
@class CPWindow
*/
CPDocModalWindowMask = 1 << 6;
@implementation CPPanel : CPWindow
{
BOOL _becomesKeyOnlyIfNeeded;
+133 -35
View File
@@ -309,6 +309,8 @@ var CPWindowSaveImage = nil,
BOOL _isFullPlatformWindow;
_CPWindowFullPlatformWindowSession _fullPlatformWindowSession;
CPDictionary _sheetContext;
}
/*
@@ -439,7 +441,10 @@ CPTexturedBackgroundWindowMask
else if (aStyleMask === CPBorderlessWindowMask)
return _CPBorderlessWindowView;
else if (aStyleMask & CPDocModalWindowMask)
return _CPDocModalWindowView;
return _CPStandardWindowView;
}
@@ -1722,57 +1727,146 @@ CPTexturedBackgroundWindowMask
*/
}
- (void)_setFrame:(CGRect)aFrame delegate:(id)delegate duration:(int)duration curve:(CPAnimationCurve)curve
{
var animation = [[_CPWindowFrameAnimation alloc] initWithWindow:self targetFrame:aFrame];
[animation setDelegate:delegate];
[animation setAnimationCurve:curve];
[animation setDuration:duration];
[animation startAnimation];
}
/* @ignore */
- (void)_setAttachedSheetFrameOrigin
{
// Position the sheet above the contentRect.
var attachedSheet = [self attachedSheet];
var contentRect = [[self contentView] frame],
sheetFrame = CGRectMakeCopy([_attachedSheet frame]);
sheetFrame = CGRectMakeCopy([attachedSheet frame]);
sheetFrame.origin.y = CGRectGetMinY(_frame) + CGRectGetMinY(contentRect);
sheetFrame.origin.x = CGRectGetMinX(_frame) + FLOOR((CGRectGetWidth(_frame) - CGRectGetWidth(sheetFrame)) / 2.0);
[_attachedSheet setFrameOrigin:sheetFrame.origin];
}
/* @ignore */
- (void)_animateAttachedSheet
{
/* NSWindow *sheet = [sheetContext sheet];
NSRect sheetFrame;
[_sheetContext autorelease];
_sheetContext=[sheetContext retain];
[self _setSheetOrigin];
sheetFrame = [sheet frame];
[(NSWindowBackgroundView *)[sheet _backgroundView] setBorderType:NSButtonBorder];
[[sheet contentView] setAutoresizesSubviews:NO];
[[sheet contentView] setAutoresizingMask:NSViewNotSizable];
// [(NSWindowBackgroundView *)[sheet _backgroundView] cacheImageForAnimation];
[_attachedSheet setFrame:CPRectMake(CGRectGetMinX(sheetFrame), CGRectGetMinY(sheetFrame), CGRectGetWidth(sheetFrame), 0.0) display:YES];
[sheet setFrame:NSMakeRect(sheetFrame.origin.x, NSMaxY([self frame]), sheetFrame.size.width, 0) display:YES];
[self _setSheetOriginAndFront];
[sheet setFrame:sheetFrame display:YES animate:YES];*/
[attachedSheet setFrameOrigin:sheetFrame.origin];
}
/* @ignore */
- (void)_attachSheet:(CPWindow)aSheet modalDelegate:(id)aModalDelegate didEndSelector:(SEL)aDidEndSelector contextInfo:(id)aContextInfo
{
// Set this as our attached sheet.
_attachedSheet = aSheet;
var sheetFrame = [aSheet frame];
// setup contexts
_sheetContext = {"sheet":aSheet, "modalDelegate":aModalDelegate, "endSelector":aDidEndSelector, "contextInfo":aContextInfo, "frame":CGRectMakeCopy(sheetFrame), "returnCode":-1, "opened": NO};
[self _attachSheetWindow:aSheet];
}
/* @ignore */
- (void)_attachSheetWindow:(CPWindow)aSheet
{
var sheetFrame = [aSheet frame],
frame = [self frame],
sheetContent = [aSheet contentView];
// If a window is ever run as a sheet, then it's sheet bit is set to YES.
// Configure sheet.
// if ([aSheet styleMask] & CPHUDBackgroundWindowMask)
// [aSheet setMovableByWindowBackground:NO];
_sheetContext["autoresizingMask"] = [sheetContent autoresizingMask];
[sheetContent setAutoresizingMask:CPViewMinYMargin];
[sheetContent setAutoresizesSubviews:NO];
aSheet._isSheet = YES;
aSheet._parentView = self;
[self _setAttachedSheetFrameOrigin];
// calculate start/end frames
var originx = frame.origin.x + FLOOR((frame.size.width - sheetFrame.size.width)/2);
var originy = frame.origin.y + [[self contentView] frame].origin.y;
var startFrame = CGRectMake(originx, originy , sheetFrame.size.width, 0);
var endFrame = CGRectMake(originx, originy ,sheetFrame.size.width,sheetFrame.size.height);
// Notify the world we will open the sheet
[[CPNotificationCenter defaultCenter] postNotificationName:@"CPWindowWillBeginSheetNotification" object:self];
// Start modal
[CPApp runModalForWindow:aSheet];
// Order front and animate the sheet
// aSheet._isAnimating = YES;
[aSheet orderFront:self];
[aSheet setFrame:startFrame];
_sheetContext["opened"] = YES;
[aSheet _setFrame:endFrame delegate:self duration:0.3 curve:CPAnimationEaseOut];
// Should run the main loop here until _isAnimating = FALSE
[aSheet becomeKeyWindow];
}
/* @ignore */
- (void)_detachSheetWindow
{
var sheet = [self attachedSheet];
// Place this window above ourselves.
[_platformWindow order:CPWindowAbove window:aSheet relativeTo:self];
// End frame for animation
var startFrame = [sheet frame];
var endFrame = CGRectMakeCopy(startFrame);
endFrame.size.height = 0;
// Set the new frame in case the sheet have been resized
_sheetContext["frame"] = startFrame;
// Autoresizing
var sheetContent = [sheet contentView];
[sheetContent setAutoresizingMask:CPViewMinYMargin];
[sheetContent setAutoresizesSubviews:NO];
// Start animation with delegate
_sheetContext["opened"] = NO;
[sheet _setFrame:endFrame delegate:self duration:0.2 curve:CPAnimationLinear];
}
/* @ignore */
- (void)animationDidEnd:(id)anim
{
var sheet = _sheetContext["sheet"];
if (anim._window != sheet)
return;
// Retore autoresizing
var sheetContent = [sheet contentView];
[sheetContent setAutoresizingMask:_sheetContext["autoresizingMask"]];
[sheetContent setAutoresizesSubviews:YES];
// If we are opened return now
if (_sheetContext["opened"] == YES)
return;
// Stop modal
[CPApp stopModal];
// Notify the world we closed the sheet
[[CPNotificationCenter defaultCenter] postNotificationName:@"CPWindowDidEndSheetNotification" object:self];
// check first if front ?
[sheet orderOut:self];
// Set the sheet frame to its last open state.
var lastFrame = _sheetContext["frame"];
[sheet setFrame:lastFrame];
// Send didEndSelector
var delegate = _sheetContext["modalDelegate"];
var endSelector = _sheetContext["endSelector"];
if(delegate != nil && endSelector != nil)
objj_msgSend(_sheetContext["modalDelegate"],
_sheetContext["endSelector"],
sheet,
_sheetContext["returnCode"],
_sheetContext["contextInfo"]);
// reset contexts
_sheetContext = nil;
sheet._parentView = nil;
}
/*!
@@ -1780,7 +1874,10 @@ CPTexturedBackgroundWindowMask
*/
- (CPWindow)attachedSheet
{
return _attachedSheet;
if (_sheetContext == nil)
return nil;
return _sheetContext["sheet"];
}
/*!
@@ -2225,6 +2322,7 @@ function _CPWindowFullPlatformWindowSessionMake(aWindowView, aContentRect, hasSh
@import "_CPWindowView.j"
@import "_CPStandardWindowView.j"
@import "_CPDocModalWindowView.j"
@import "_CPHUDWindowView.j"
@import "_CPBorderlessWindowView.j"
@import "_CPBorderlessBridgeWindowView.j"
+50
View File
@@ -0,0 +1,50 @@
@import "_CPWindowView.j"
var _CPStandardWindowViewBodyBackgroundColor = nil;
@implementation _CPDocModalWindowView : _CPWindowView
{
CPView _bodyView;
}
+ (CPColor)bodyBackgroundColor
{
if (!_CPStandardWindowViewBodyBackgroundColor)
_CPStandardWindowViewBodyBackgroundColor = [CPColor colorWithWhite:0.96 alpha:1.0];
return _CPStandardWindowViewBodyBackgroundColor;
}
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
{
self = [super initWithFrame:aFrame styleMask:aStyleMask];
if (self)
{
var theClass = [self class],
bounds = [self bounds];
_bodyView = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds), CGRectGetHeight(bounds))];
[_bodyView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[_bodyView setBackgroundColor:[theClass bodyBackgroundColor]];
[_bodyView setHitTests:NO];
[self addSubview:_bodyView];
}
return self;
}
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
return aFrameRect;
}
- (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
return aContentRect;
}
@end
+8 -1
View File
@@ -135,7 +135,14 @@ var _CPWindowViewResizeIndicatorImage = nil;
}
else if (type === CPLeftMouseDragged)
[theWindow setFrameSize:CGSizeMake(CGRectGetWidth(_resizeFrame) + location.x - CGRectGetMinX(_resizeFrame), CGRectGetHeight(_resizeFrame) + location.y - CGRectGetMinY(_resizeFrame))];
{
var newSize = CGSizeMake(CGRectGetWidth(_resizeFrame) + location.x - CGRectGetMinX(_resizeFrame), CGRectGetHeight(_resizeFrame) + location.y - CGRectGetMinY(_resizeFrame));
if (theWindow._isSheet && theWindow._parentView && (theWindow._frame.size.width !== newSize.width))
[theWindow._parentView _setAttachedSheetFrameOrigin];
[theWindow setFrameSize:newSize];
}
[CPApp setTarget:self selector:@selector(trackResizeWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
}