CPAlert: Attached alerts. Added a new method -beginSheetModalForWindow: that calls -alertDidEnd:returnCode: on ending. CPAlertTest update testing it.

Fixed a bug in CPWindow where the didEndSelector was reset too early. This bug was visible only when trying to chain sheet alerts.
         Fixed a local/instance variable conflict in AttachedSheet/AppController.j
This commit is contained in:
cacaodev
2010-08-24 11:50:44 -04:00
committed by Alexander Ljungberg
parent 50b7f02470
commit ee4802e513
4 changed files with 105 additions and 39 deletions
+58 -10
View File
@@ -51,7 +51,6 @@ CPInformationalAlertStyle = 1;
*/
CPCriticalAlertStyle = 2;
/*!
@ingroup appkit
@@ -88,6 +87,8 @@ CPCriticalAlertStyle = 2;
CPArray _buttons;
id _delegate;
SEL _didEndSelector;
id _modalDelegate;
}
+ (CPString)themeClass
@@ -126,6 +127,7 @@ CPCriticalAlertStyle = 2;
_alertStyle = CPWarningAlertStyle;
_alertPanel = nil;
_windowStyle = nil;
_alertDidEndSelector = nil;
_messageLabel = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
_alertImageView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
@@ -145,7 +147,7 @@ CPCriticalAlertStyle = 2;
{
_windowStyle = styleMask;
[self setTheme:(_windowStyle === CPHUDBackgroundWindowMask) ? [CPTheme defaultHudTheme] : [CPTheme defaultTheme]];
[self setTheme:(_windowStyle & CPHUDBackgroundWindowMask) ? [CPTheme defaultHudTheme] : [CPTheme defaultTheme]];
// We'll need to recreate the panel to get the new window style.
_alertPanel = nil;
@@ -281,7 +283,7 @@ CPCriticalAlertStyle = 2;
[button setTitle:title];
[button setTarget:self];
[button setTag:_buttonCount];
[button setAction:@selector(_notifyDelegate:)];
[button setAction:@selector(_dismissAlert:)];
[[_alertPanel contentView] addSubview:button];
@@ -397,14 +399,60 @@ CPCriticalAlertStyle = 2;
[CPApp runModalForWindow:_alertPanel];
}
/* @ignore */
- (void)_notifyDelegate:(id)button
{
[CPApp abortModal];
[_alertPanel close];
/*
Runs the receiver modally as an alert sheet attached to a specified window.
if (_delegate && [_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
[_delegate alertDidEnd:self returnCode:[button tag]];
@param window The parent window for the sheet.
@param modalDelegate The delegate for the modal-dialog session.
@param alertDidEndSelector Message the alert sends to modalDelegate after the sheet is dismissed.
@param contextInfo Contextual data passed to modalDelegate in didEndSelector message.
*/
- (void)beginSheetModalForWindow:(CPWindow)window modalDelegate:(id)modalDelegate didEndSelector:(SEL)alertDidEndSelector contextInfo:(void)contextInfo
{
[self layoutPanel];
_didEndSelector = alertDidEndSelector;
_modalDelegate = modalDelegate;
[CPApp beginSheet:_alertPanel modalForWindow:window modalDelegate:self didEndSelector:@selector(_alertDidEnd:returnCode:contextInfo:) contextInfo:contextInfo];
}
/*
Runs the receiver modally as an alert sheet attached to a specified window.
@param window The parent window for the sheet.
*/
- (void)beginSheetModalForWindow:(CPWindow)window
{
[self layoutPanel];
[CPApp beginSheet:_alertPanel modalForWindow:window modalDelegate:self didEndSelector:@selector(_alertDidEnd:returnCode:contextInfo:) contextInfo:nil];
}
- (void)_alertDidEnd:(CPWindow)aSheet returnCode:(CPInteger)returnCode contextInfo:(id)contextInfo
{
if ([_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
[_delegate alertDidEnd:self returnCode:returnCode];
if (_didEndSelector)
objj_msgSend(_modalDelegate, _didEndSelector, self, returnCode, contextInfo);
_didEndSelector = nil;
_modalDelegate = nil;
}
/* @ignore */
- (void)_dismissAlert:(CPButton)button
{
if ([_alertPanel isSheet])
[CPApp endSheet:_alertPanel returnCode:[button tag]];
else
{
[CPApp abortModal];
[_alertPanel close];
[self _alertDidEnd:nil returnCode:[button tag] contextInfo:nil];
}
}
@end
+16 -7
View File
@@ -199,6 +199,8 @@ var SHADOW_MARGIN_LEFT = 20.0,
var CPWindowSaveImage = nil,
CPWindowSavingImage = nil;
var CPWindowResizeTime = 0.2;
/*!
@ingroup appkit
@@ -2098,6 +2100,11 @@ CPTexturedBackgroundWindowMask
[_frameAnimation startAnimation];
}
- (CPTimeInterval)animationResizeTime:(CGRect)newWindowFrame
{
return CPWindowResizeTime;
}
/* @ignore */
- (void)_setAttachedSheetFrameOrigin
{
@@ -2146,7 +2153,7 @@ CPTexturedBackgroundWindowMask
[aSheet setFrame:startFrame display:YES animate:NO];
_sheetContext["opened"] = YES;
[aSheet _setFrame:endFrame delegate:self duration:0.2 curve:CPAnimationEaseOut];
[aSheet _setFrame:endFrame delegate:self duration:[self animationResizeTime:endFrame] curve:CPAnimationEaseOut];
// Should run the main loop here until _isAnimating = FALSE
[aSheet becomeKeyWindow];
@@ -2167,7 +2174,7 @@ CPTexturedBackgroundWindowMask
[self _setUpMasksForView:sheetContent];
_sheetContext["opened"] = NO;
[sheet _setFrame:endFrame delegate:self duration:0.2 curve:CPAnimationEaseIn];
[sheet _setFrame:endFrame delegate:self duration:[self animationResizeTime:endFrame] curve:CPAnimationEaseIn];
}
/* @ignore */
@@ -2196,13 +2203,15 @@ CPTexturedBackgroundWindowMask
[self _restoreMasksForView:sheetContent];
var delegate = _sheetContext["modalDelegate"],
endSelector = _sheetContext["endSelector"];
if (delegate != nil && endSelector != nil)
objj_msgSend(delegate, endSelector, sheet, _sheetContext["returnCode"], _sheetContext["contextInfo"]);
endSelector = _sheetContext["endSelector"],
returnCode = _sheetContext["returnCode"],
contextInfo = _sheetContext["contextInfo"];
_sheetContext = nil;
sheet._parentView = nil;
if (delegate != nil && endSelector != nil)
objj_msgSend(delegate, endSelector, sheet, returnCode, contextInfo);
}
- (void)_setUpMasksForView:(CPView)aView
@@ -2673,7 +2682,7 @@ var interpolate = function(fromValue, toValue, progress)
- (id)initWithWindow:(CPWindow)aWindow targetFrame:(CGRect)aTargetFrame
{
self = [super initWithDuration:0.2 animationCurve:CPAnimationLinear];
self = [super initWithDuration:[aWindow animationResizeTime:aTargetFrame] animationCurve:CPAnimationLinear];
if (self)
{
+11 -16
View File
@@ -22,28 +22,28 @@
[window setMinSize:CGSizeMake(300, 200)];
sheet = [[CPWindow alloc] initWithContentRect:CGRectMake(0,0,300,100) styleMask:CPDocModalWindowMask|CPResizableWindowMask];
[sheet setMinSize:CGSizeMake(300,100)];
var sheetContent = [sheet contentView];
textField = [[CPTextField alloc] initWithFrame:CGRectMake(10,30,280,30)];
[textField setEditable:YES];
[textField setBezeled:YES];
[textField setAutoresizingMask:CPViewWidthSizable];
var okButton = [[CPButton alloc] initWithFrame:CGRectMake(230,70,50,24)];
[okButton setTitle:"OK"];
[okButton setTarget:self];
[okButton setTag:1];
[okButton setAction:@selector(closeSheet:)];
[okButton setAutoresizingMask:CPViewMinXMargin|CPViewMinYMargin];
[okButton setAutoresizingMask:CPViewMinXMargin|CPViewMinYMargin];
var cancelButton = [[CPButton alloc] initWithFrame:CGRectMake(120,70,100,24)];
[cancelButton setTitle:"Cancel"];
[cancelButton setTarget:self];
[cancelButton setTag:0];
[cancelButton setAction:@selector(closeSheet:)];
[cancelButton setAutoresizingMask:CPViewMinXMargin|CPViewMinYMargin];
[cancelButton setAction:@selector(closeSheet:)];
[cancelButton setAutoresizingMask:CPViewMinXMargin|CPViewMinYMargin];
[sheetContent addSubview:textField];
[sheetContent addSubview:okButton];
[sheetContent addSubview:cancelButton];
@@ -51,9 +51,9 @@
var displayButton = [[CPButton alloc] initWithFrame:CGRectMake(200,150,100,24)];
[displayButton setTitle:"Display Sheet"];
[displayButton setTarget:self];
[displayButton setAction:@selector(displaySheet:)];
[displayButton setAction:@selector(displaySheet:)];
[contentView addSubview:displayButton];
[window orderFront:self]
}
@@ -65,20 +65,15 @@
[CPApp beginSheet:sheet modalForWindow:window modalDelegate:self didEndSelector:@selector(didEndSheet:returnCode:contextInfo:) contextInfo:nil];
}
- (void)alertDidEnd:(CPWindow)sheet returnCode:(int)returnCode contextInfo:(id)contextInfo
{
CPLogConsole(_cmd+" returnCode " + returnCode);
}
- (void)closeSheet:(id)sender
{
[CPApp endSheet:sheet returnCode:[sender tag]];
}
- (void)didEndSheet:(CPWindow)sheet returnCode:(int)returnCode contextInfo:(id)contextInfo
- (void)didEndSheet:(CPWindow)aSheet returnCode:(int)returnCode contextInfo:(id)contextInfo
{
var str = [textField stringValue];
[sheet orderOut:self];
if (returnCode == CPOKButton && [str length] > 0)
{
+20 -6
View File
@@ -11,6 +11,7 @@
@implementation AppController : CPObject
{
CPWindow theWindow;
CPTextField label;
CPArray variations;
CPArray messages;
@@ -21,7 +22,7 @@
{
messages = [
[@"Are you sure you want to theorise before you have data?",
@"Invariably, you end up twisting facts to suit theories, instead of theories to suit facts.",
@"Invariably, you end up twisting facts to suit theories, instead of theories to suit facts. lkjhdlkfjhlekjhglkjrshlkjfhsglksrjhfsmlgkjfskljhgkljflkjmlgkhjùlrkjhlmkjmrlekjghmlkjermlgkhjmlfekjghmlkjremlkjghmlkerjmlghkjmlerkjgmlhkjmerlkjgmhlkjmelrkjhmlkjrgmlkjhmlkrjgmlhkjrmelkgjhmlkrejhmlkjrgmlhkjmrlkgjhlmkrzj",
"Theorise", "Cancel"],
[@"Snakes. Why did it have to be snakes?",
nil,
@@ -39,10 +40,13 @@
[CPHUDBackgroundWindowMask, CPWarningAlertStyle],
[CPHUDBackgroundWindowMask, CPInformationalAlertStyle],
[CPHUDBackgroundWindowMask, CPCriticalAlertStyle],
[CPDocModalWindowMask, CPWarningAlertStyle],
[CPDocModalWindowMask, CPInformationalAlertStyle],
[CPDocModalWindowMask, CPCriticalAlertStyle]
];
var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
contentView = [theWindow contentView];
theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(100,100,500,500) styleMask:CPTitledWindowMask];
var contentView = [theWindow contentView];
label = [[CPTextField alloc] initWithFrame:CGRectMake(15, 15, 400, 24)];
@@ -57,8 +61,9 @@
//[CPMenu setMenuBarVisible:YES];
}
- (void)alertDidEnd:(CPAlert)anAlert returnCode:(id)returnCode
- (void)alertDidEnd:(CPAlert)anAlert returnCode:(CPInteger)returnCode
{
CPLogConsole(_cmd);
if (returnCode === 0)
[label setStringValue:"You chose the default action."];
else
@@ -67,6 +72,11 @@
[self showNextAlertVariation];
}
- (void)customDidEnd:(CPAlert)anAlert code:(id)code context:(id)context
{
CPLogConsole(_cmd + anAlert + code + context);
}
- (void)showNextAlertVariation
{
if (![variations count])
@@ -79,15 +89,19 @@
messageIndex = (messageIndex + 1) % messages.length;
[variations removeObjectAtIndex:0];
var windowStyle = variation[0];
[alert setDelegate:self];
[alert setMessageText:message[0]];
[alert setInformativeText:message[1]];
[alert addButtonWithTitle:message[2]];
[alert addButtonWithTitle:message[3]];
[alert setWindowStyle:variation[0]];
[alert setWindowStyle:windowStyle];
[alert setAlertStyle:variation[1]];
[alert runModal];
if (windowStyle & CPDocModalWindowMask)
[alert beginSheetModalForWindow:theWindow modalDelegate:self didEndSelector:@selector(customDidEnd:code:context:) contextInfo:@"here is some context"];
else
[alert runModal];
}
@end