API  1.0.0
CPAlert.j
Go to the documentation of this file.
1 /*
2  * CPAlert.j
3  * AppKit
4  *
5  * Created by Jake MacMullin.
6  * Copyright 2008, Jake MacMullin.
7  *
8  * 11/10/2008 Ross Boucher
9  * - Make it conform to style guidelines, general cleanup and enhancements
10  * 11/10/2010 Antoine Mercadal
11  * - Enhancements, better compliance with Cocoa API
12  *
13  * This library is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU Lesser General Public
15  * License as published by the Free Software Foundation; either
16  * version 2.1 of the License, or (at your option) any later version.
17  *
18  * This library is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  * Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public
24  * License along with this library; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26  */
27 
28 
29 
30 
31 @global CPApp
32 
35 
36 @typedef CPAlertStyle
37 /*
38  @global
39  @group CPAlertStyle
40 */
42 /*
43  @global
44  @group CPAlertStyle
45 */
47 /*
48  @global
49  @group CPAlertStyle
50 */
52 
53 var bottomHeight = 71;
54 
55 @protocol CPAlertDelegate <CPObject>
56 
57 @optional
58 - (BOOL)alertShowHelp:(CPAlert)alert;
59 - (void)alertDidEnd:(CPAlert)theAlert returnCode:(int)returnCode;
60 
61 @end
62 @implementation _CPAlertThemeView : CPView
63 {
64  id __doxygen__;
65 }
66 
67 + (CPString)defaultThemeClass
68 {
69  return @"alert";
70 }
71 
72 + (CPDictionary)themeAttributes
73 {
74  return @{
75  @"size": CGSizeMake(400.0, 110.0),
76  @"content-inset": CGInsetMake(15, 15, 15, 50),
77  @"informative-offset": 6,
78  @"button-offset": 10,
79  @"message-text-alignment": CPJustifiedTextAlignment,
80  @"message-text-color": [CPColor blackColor],
81  @"message-text-font": [CPFont boldSystemFontOfSize:13.0],
82  @"message-text-shadow-color": [CPNull null],
83  @"message-text-shadow-offset": CGSizeMakeZero(),
84  @"informative-text-alignment": CPJustifiedTextAlignment,
85  @"informative-text-color": [CPColor blackColor],
86  @"informative-text-font": [CPFont systemFontOfSize:12.0],
87  @"informative-text-shadow-color": [CPNull null],
88  @"informative-text-shadow-offset": CGSizeMakeZero(),
89  @"image-offset": CGPointMake(15, 12),
90  @"information-image": [CPNull null],
91  @"warning-image": [CPNull null],
92  @"error-image": [CPNull null],
93  @"help-image": [CPNull null],
94  @"help-image-left-offset": 15,
95  @"help-image-pressed": [CPNull null],
96  @"suppression-button-y-offset": 0.0,
97  @"suppression-button-x-offset": 0.0,
98  @"default-elements-margin": 3.0,
99  @"suppression-button-text-color": [CPColor blackColor],
100  @"suppression-button-text-font": [CPFont systemFontOfSize:12.0],
101  @"suppression-button-text-shadow-color": [CPNull null],
102  @"suppression-button-text-shadow-offset": 0.0,
103  @"modal-window-button-margin-y": 0.0,
104  @"modal-window-button-margin-x": 0.0,
105  @"standard-window-button-margin-y": 0.0,
106  @"standard-window-button-margin-x": 0.0,
107  };
108 }
109 
110 @end
111 
134 @implementation CPAlert : CPObject
135 {
136  BOOL _showHelp;
137  BOOL _showSuppressionButton;
138 
139  CPAlertStyle _alertStyle;
140  CPString _title;
141  CPView _accessoryView;
142  CPImage _icon;
143 
144  CPArray _buttons;
145  CPCheckBox _suppressionButton;
146 
147  id <CPAlertDelegate> _delegate @accessors(property=delegate);
148  id _modalDelegate;
149  SEL _didEndSelector;
150  Function _didEndBlock;
151  unsigned _implementedDelegateMethods;
152 
153  _CPAlertThemeView _themeView;
154  CPWindow _window;
155  int _defaultWindowStyle;
156 
157  CPImageView _alertImageView;
158  CPTextField _informativeLabel;
159  CPTextField _messageLabel;
160  CPButton _alertHelpButton;
161 
162  BOOL _needsLayout;
163 }
164 
165 #pragma mark Creating Alerts
166 
177 + (CPAlert)alertWithMessageText:(CPString)aMessage defaultButton:(CPString)defaultButtonTitle alternateButton:(CPString)alternateButtonTitle otherButton:(CPString)otherButtonTitle informativeTextWithFormat:(CPString)informativeText
178 {
179  var newAlert = [[self alloc] init];
180 
181  [newAlert setMessageText:aMessage];
182  [newAlert addButtonWithTitle:defaultButtonTitle];
183 
184  if (alternateButtonTitle)
185  [newAlert addButtonWithTitle:alternateButtonTitle];
186 
187  if (otherButtonTitle)
188  [newAlert addButtonWithTitle:otherButtonTitle];
189 
190  if (informativeText)
191  [newAlert setInformativeText:informativeText];
192 
193  return newAlert;
194 }
195 
202 + (CPAlert)alertWithError:(CPString)anErrorMessage
203 {
204  var newAlert = [[self alloc] init];
205 
206  [newAlert setMessageText:anErrorMessage];
207  [newAlert setAlertStyle:CPCriticalAlertStyle];
208 
209  return newAlert;
210 }
211 
215 - (id)init
216 {
217  self = [super init];
218 
219  if (self)
220  {
221  _buttons = [];
222  _alertStyle = CPWarningAlertStyle;
223  _showHelp = NO;
224  _needsLayout = YES;
225  _defaultWindowStyle = _CPModalWindowMask;
226  _themeView = [_CPAlertThemeView new];
227 
228  _messageLabel = [CPTextField labelWithTitle:@"Alert"];
229  _alertImageView = [[CPImageView alloc] init];
230  _informativeLabel = [[CPTextField alloc] init];
231  _suppressionButton = [CPCheckBox checkBoxWithTitle:@"Do not show this message again"];
232 
233  _alertHelpButton = [[CPButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 16.0, 16.0)];
234  [_alertHelpButton setTarget:self];
235  [_alertHelpButton setAction:@selector(_showHelp:)];
236  }
237 
238  return self;
239 }
240 
241 
242 #pragma mark -
243 #pragma mark Delegate
244 
249 - (void)setDelegate:(id <CPAlertDelegate>)aDelegate
250 {
251  if (_delegate === aDelegate)
252  return;
253 
254  _delegate = aDelegate;
255  _implementedDelegateMethods = 0;
256 
257  if ([_delegate respondsToSelector:@selector(alertShowHelp:)])
258  _implementedDelegateMethods |= CPAlertDelegate_alertShowHelp_;
259 
260  if ([_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
261  _implementedDelegateMethods |= CPAlertDelegate_alertDidEnd_returnCode_;
262 }
263 
264 
265 #pragma mark Accessors
266 
267 - (CPTheme)theme
268 {
269  return [_themeView theme];
270 }
271 
277 - (void)setTheme:(CPTheme)aTheme
278 {
279  if (aTheme === [self theme])
280  return;
281 
282  if (aTheme === [CPTheme defaultHudTheme])
283  _defaultWindowStyle = CPTitledWindowMask | CPHUDBackgroundWindowMask;
284  else
285  _defaultWindowStyle = CPTitledWindowMask;
286 
287  _window = nil; // will be regenerated at next layout
288  _needsLayout = YES;
289  [_themeView setTheme:aTheme];
290 }
291 
292 - (void)setValue:(id)aValue forThemeAttribute:(CPString)aName
293 {
294  [_themeView setValue:aValue forThemeAttribute:aName];
295 }
296 
297 - (void)setValue:(id)aValue forThemeAttribute:(CPString)aName inState:(ThemeState)aState
298 {
299  [_themeView setValue:aValue forThemeAttribute:aName inState:aState];
300 }
301 
302 
304 - (void)setWindowStyle:(int)style
305 {
306  CPLog.warn("DEPRECATED: setWindowStyle: is deprecated. use setTheme: instead");
307 
308  [self setTheme:(style === CPHUDBackgroundWindowMask) ? [CPTheme defaultHudTheme] : [CPTheme defaultTheme]];
309 }
310 
312 - (int)windowStyle
313 {
314  CPLog.warn("DEPRECATED: windowStyle: is deprecated. use theme instead");
315  return _defaultWindowStyle;
316 }
317 
318 
324 - (void)setMessageText:(CPString)text
325 {
326  [_messageLabel setStringValue:text];
327  _needsLayout = YES;
328 }
329 
335 - (CPString)messageText
336 {
337  return [_messageLabel stringValue];
338 }
339 
345 - (void)setInformativeText:(CPString)text
346 {
347  [_informativeLabel setStringValue:text];
348  _needsLayout = YES;
349 }
350 
356 - (CPString)informativeText
357 {
358  return [_informativeLabel stringValue];
359 }
360 
367 - (void)setTitle:(CPString)aTitle
368 {
369  _title = aTitle;
370  [_window setTitle:aTitle];
371 }
372 
378 - (void)setAccessoryView:(CPView)aView
379 {
380  _accessoryView = aView;
381  _needsLayout = YES;
382 }
383 
389 - (void)setShowsSuppressionButton:(BOOL)shouldShowSuppressionButton
390 {
391  _showSuppressionButton = shouldShowSuppressionButton;
392  _needsLayout = YES;
393 }
394 
395 #pragma mark Accessing Buttons
396 
409 - (void)addButtonWithTitle:(CPString)aTitle
410 {
411  var bounds = [[_window contentView] bounds],
412  count = [_buttons count],
413 
414  button = [[CPButton alloc] initWithFrame:CGRectMakeZero()];
415 
416  [button setTitle:aTitle];
417  [button setTag:count];
418  [button setTarget:self];
419  [button setAction:@selector(_takeReturnCodeFrom:)];
420 
421  [[_window contentView] addSubview:button];
422 
423  if (count == 0)
424  [button setKeyEquivalent:CPCarriageReturnCharacter];
425  else if ([aTitle lowercaseString] === @"cancel")
426  [button setKeyEquivalent:CPEscapeFunctionKey];
427 
428  [_buttons insertObject:button atIndex:0];
429 }
430 
431 #pragma mark Layout
432 
436 - (void)_layoutMessageView
437 {
438  var inset = [_themeView currentValueForThemeAttribute:@"content-inset"],
439  sizeWithFontCorrection = 6.0,
440  messageLabelWidth,
441  messageLabelTextSize;
442 
443  [_messageLabel setTextColor:[_themeView currentValueForThemeAttribute:@"message-text-color"]];
444  [_messageLabel setFont:[_themeView currentValueForThemeAttribute:@"message-text-font"]];
445  [_messageLabel setTextShadowColor:[_themeView currentValueForThemeAttribute:@"message-text-shadow-color"]];
446  [_messageLabel setTextShadowOffset:[_themeView currentValueForThemeAttribute:@"message-text-shadow-offset"]];
447  [_messageLabel setAlignment:[_themeView currentValueForThemeAttribute:@"message-text-alignment"]];
448  [_messageLabel setLineBreakMode:CPLineBreakByWordWrapping];
449 
450  messageLabelWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right;
451  messageLabelTextSize = [[_messageLabel stringValue] sizeWithFont:[_messageLabel font] inWidth:messageLabelWidth];
452 
453  [_messageLabel setFrame:CGRectMake(inset.left, inset.top, messageLabelTextSize.width, messageLabelTextSize.height + sizeWithFontCorrection)];
454 }
455 
459 - (void)_layoutInformativeView
460 {
461  var inset = [_themeView currentValueForThemeAttribute:@"content-inset"],
462  defaultElementsMargin = [_themeView currentValueForThemeAttribute:@"default-elements-margin"],
463  sizeWithFontCorrection = 6.0,
464  informativeLabelWidth,
465  informativeLabelOriginY,
466  informativeLabelTextSize;
467 
468  [_informativeLabel setTextColor:[_themeView currentValueForThemeAttribute:@"informative-text-color"]];
469  [_informativeLabel setFont:[_themeView currentValueForThemeAttribute:@"informative-text-font"]];
470  [_informativeLabel setTextShadowColor:[_themeView currentValueForThemeAttribute:@"informative-text-shadow-color"]];
471  [_informativeLabel setTextShadowOffset:[_themeView currentValueForThemeAttribute:@"informative-text-shadow-offset"]];
472  [_informativeLabel setAlignment:[_themeView currentValueForThemeAttribute:@"informative-text-alignment"]];
473  [_informativeLabel setLineBreakMode:CPLineBreakByWordWrapping];
474 
475  informativeLabelWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right;
476  informativeLabelOriginY = [_messageLabel frameOrigin].y + [_messageLabel frameSize].height + defaultElementsMargin;
477  informativeLabelTextSize = [[_informativeLabel stringValue] sizeWithFont:[_informativeLabel font] inWidth:informativeLabelWidth];
478 
479  [_informativeLabel setFrame:CGRectMake(inset.left, informativeLabelOriginY, informativeLabelTextSize.width, informativeLabelTextSize.height + sizeWithFontCorrection)];
480 }
481 
485 - (void)_layoutAccessoryView
486 {
487  if (!_accessoryView)
488  return;
489 
490  var inset = [_themeView currentValueForThemeAttribute:@"content-inset"],
491  defaultElementsMargin = [_themeView currentValueForThemeAttribute:@"default-elements-margin"],
492  accessoryViewWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right,
493  accessoryViewOriginY = CGRectGetMaxY([_informativeLabel frame]) + defaultElementsMargin;
494 
495  [_accessoryView setFrameOrigin:CGPointMake(inset.left, accessoryViewOriginY)];
496  [[_window contentView] addSubview:_accessoryView];
497 }
498 
502 - (void)_layoutSuppressionButton
503 {
504  if (!_showSuppressionButton)
505  return;
506 
507  var inset = [_themeView currentValueForThemeAttribute:@"content-inset"],
508  suppressionViewXOffset = [_themeView currentValueForThemeAttribute:@"suppression-button-x-offset"],
509  suppressionViewYOffset = [_themeView currentValueForThemeAttribute:@"suppression-button-y-offset"],
510  defaultElementsMargin = [_themeView currentValueForThemeAttribute:@"default-elements-margin"],
511  suppressionButtonViewOriginY = CGRectGetMaxY([(_accessoryView || _informativeLabel) frame]) + defaultElementsMargin + suppressionViewYOffset;
512 
513  [_suppressionButton setTextColor:[_themeView currentValueForThemeAttribute:@"suppression-button-text-color"]];
514  [_suppressionButton setFont:[_themeView currentValueForThemeAttribute:@"suppression-button-text-font"]];
515  [_suppressionButton setTextShadowColor:[_themeView currentValueForThemeAttribute:@"suppression-button-text-shadow-color"]];
516  [_suppressionButton setTextShadowOffset:[_themeView currentValueForThemeAttribute:@"suppression-button-text-shadow-offset"]];
517  [_suppressionButton sizeToFit];
518 
519  [_suppressionButton setFrameOrigin:CGPointMake(inset.left + suppressionViewXOffset, suppressionButtonViewOriginY)];
520  [[_window contentView] addSubview:_suppressionButton];
521 }
522 
526 - (CGSize)_layoutButtonsFromView:(CPView)lastView
527 {
528  var inset = [_themeView currentValueForThemeAttribute:@"content-inset"],
529  minimumSize = [_themeView currentValueForThemeAttribute:@"size"],
530  buttonOffset = [_themeView currentValueForThemeAttribute:@"button-offset"],
531  helpLeftOffset = [_themeView currentValueForThemeAttribute:@"help-image-left-offset"],
532  aRepresentativeButton = [_buttons objectAtIndex:0],
533  defaultElementsMargin = [_themeView currentValueForThemeAttribute:@"default-elements-margin"],
534  panelSize = [[_window contentView] frame].size,
535  buttonsOriginY,
536  buttonMarginY,
537  buttonMarginX,
538  theme = [self theme],
539  offsetX;
540 
541  [aRepresentativeButton setTheme:[self theme]];
542  [aRepresentativeButton sizeToFit];
543 
544  panelSize.height = CGRectGetMaxY([lastView frame]) + defaultElementsMargin + [aRepresentativeButton frameSize].height;
545  if (panelSize.height < minimumSize.height)
546  panelSize.height = minimumSize.height;
547 
548  buttonsOriginY = panelSize.height - [aRepresentativeButton frameSize].height + buttonOffset;
549  offsetX = panelSize.width - inset.right;
550 
551  switch ([_window styleMask])
552  {
553  case _CPModalWindowMask:
554  buttonMarginY = [_themeView currentValueForThemeAttribute:@"modal-window-button-margin-y"];
555  buttonMarginX = [_themeView currentValueForThemeAttribute:@"modal-window-button-margin-x"];
556  break;
557 
558  default:
559  buttonMarginY = [_themeView currentValueForThemeAttribute:@"standard-window-button-margin-y"];
560  buttonMarginX = [_themeView currentValueForThemeAttribute:@"standard-window-button-margin-x"];
561  break;
562  }
563 
564  for (var i = [_buttons count] - 1; i >= 0 ; i--)
565  {
566  var button = _buttons[i];
567  [button setTheme:[self theme]];
568  [button sizeToFit];
569 
570  var buttonFrame = [button frame],
571  width = MAX(80.0, CGRectGetWidth(buttonFrame)),
572  height = CGRectGetHeight(buttonFrame);
573 
574  offsetX -= width;
575  [button setFrame:CGRectMake(offsetX + buttonMarginX, buttonsOriginY + buttonMarginY, width, height)];
576  offsetX -= 10;
577  }
578 
579  if (_showHelp)
580  {
581  var helpImage = [_themeView currentValueForThemeAttribute:@"help-image"],
582  helpImagePressed = [_themeView currentValueForThemeAttribute:@"help-image-pressed"],
583  helpImageSize = helpImage ? [helpImage size] : CGSizeMakeZero(),
584  helpFrame = CGRectMake(helpLeftOffset, buttonsOriginY, helpImageSize.width, helpImageSize.height);
585 
586  [_alertHelpButton setImage:helpImage];
587  [_alertHelpButton setAlternateImage:helpImagePressed];
588  [_alertHelpButton setBordered:NO];
589  [_alertHelpButton setFrame:helpFrame];
590  }
591 
592  panelSize.height += [aRepresentativeButton frameSize].height + inset.bottom + buttonOffset;
593  return panelSize;
594 }
595 
599 - (void)layout
600 {
601  if (!_needsLayout)
602  return;
603 
604  if (!_window)
605  [self _createWindowWithStyle:nil];
606 
607  var iconOffset = [_themeView currentValueForThemeAttribute:@"image-offset"],
608  theImage = _icon,
609  finalSize;
610 
611  if (!theImage)
612  switch (_alertStyle)
613  {
614  case CPWarningAlertStyle:
615  theImage = [_themeView currentValueForThemeAttribute:@"warning-image"];
616  break;
618  theImage = [_themeView currentValueForThemeAttribute:@"information-image"];
619  break;
621  theImage = [_themeView currentValueForThemeAttribute:@"error-image"];
622  break;
623  }
624 
625  [_alertImageView setImage:theImage];
626 
627  var imageSize = theImage ? [theImage size] : CGSizeMakeZero();
628  [_alertImageView setFrame:CGRectMake(iconOffset.x, iconOffset.y, imageSize.width, imageSize.height)];
629 
630  [self _layoutMessageView];
631  [self _layoutInformativeView];
632  [self _layoutAccessoryView];
633  [self _layoutSuppressionButton];
634 
635  var lastView = _informativeLabel;
636  if (_showSuppressionButton)
637  lastView = _suppressionButton;
638  else if (_accessoryView)
639  lastView = _accessoryView;
640 
641  finalSize = [self _layoutButtonsFromView:lastView];
642  if ([_window styleMask] & CPDocModalWindowMask)
643  finalSize.height -= 26; // adjust the absence of title bar
644 
645  [_window setFrameSize:finalSize];
646  [_window center];
647 
648  if ([_window styleMask] & _CPModalWindowMask || [_window styleMask] & CPHUDBackgroundWindowMask)
649  {
650  [_window setMovable:YES];
651  [_window setMovableByWindowBackground:YES];
652  }
653 
654  _needsLayout = NO;
655 }
656 
657 #pragma mark Displaying Alerts
658 
664 - (void)runModal
665 {
666  if (!([_window styleMask] & _defaultWindowStyle))
667  {
668  _needsLayout = YES;
669  [self _createWindowWithStyle:_defaultWindowStyle];
670  }
671 
672  [self layout];
673  [CPApp runModalForWindow:_window];
674 }
675 
680 - (void)runModalWithDidEndBlock:(Function /*(CPAlert alert, int returnCode)*/)block
681 {
682  _didEndBlock = block;
683 
684  [self runModal];
685 }
686 
695 - (void)beginSheetModalForWindow:(CPWindow)aWindow modalDelegate:(id)modalDelegate didEndSelector:(SEL)alertDidEndSelector contextInfo:(id)contextInfo
696 {
697  if (!([_window styleMask] & CPDocModalWindowMask))
698  {
699  _needsLayout = YES;
700  [self _createWindowWithStyle:CPDocModalWindowMask];
701  }
702 
703  [self layout];
704 
705  _modalDelegate = modalDelegate;
706  _didEndSelector = alertDidEndSelector;
707 
708  [CPApp beginSheet:_window modalForWindow:aWindow modalDelegate:self didEndSelector:@selector(_alertDidEnd:returnCode:contextInfo:) contextInfo:contextInfo];
709 }
710 
716 - (void)beginSheetModalForWindow:(CPWindow)aWindow
717 {
719 }
720 
728 - (void)beginSheetModalForWindow:(CPWindow)aWindow didEndBlock:(Function /*(CPAlert alert, int returnCode)*/)block
729 {
730  _didEndBlock = block;
731 
733 }
734 
735 #pragma mark Private
736 
740 - (void)_createWindowWithStyle:(int)forceStyle
741 {
742  var frame = CGRectMakeZero();
743  frame.size = [_themeView currentValueForThemeAttribute:@"size"];
744 
745  _window = [[CPPanel alloc] initWithContentRect:frame styleMask:forceStyle || _defaultWindowStyle];
746  [_window setLevel:CPStatusWindowLevel];
747  [_window setPlatformWindow:[[CPApp keyWindow] platformWindow]];
748 
749  if (_title)
750  [_window setTitle:_title];
751 
752  var contentView = [_window contentView],
753  count = [_buttons count];
754 
755  if (count)
756  while (count--)
757  [contentView addSubview:_buttons[count]];
758  else
759  [self addButtonWithTitle:@"OK"];
760 
761  [contentView addSubview:_messageLabel];
762  [contentView addSubview:_alertImageView];
763  [contentView addSubview:_informativeLabel];
764 
765  if (_showHelp)
766  [contentView addSubview:_alertHelpButton];
767 }
768 
772 - (@action)_showHelp:(id)aSender
773 {
774  [self _sendDelegateAlertShowHelp];
775 }
776 
777 /*
778  @ignore
779 */
780 - (@action)_takeReturnCodeFrom:(id)aSender
781 {
782  if ([_window isSheet])
783  {
784  [_window orderOut:nil];
785  [CPApp endSheet:_window returnCode:[aSender tag]];
786  }
787  else
788  {
789  [CPApp abortModal];
790  [_window close];
791 
792  [self _alertDidEnd:_window returnCode:[aSender tag] contextInfo:nil];
793  }
794 }
795 
799 - (void)_alertDidEnd:(CPWindow)aWindow returnCode:(int)returnCode contextInfo:(id)contextInfo
800 {
801  if (_didEndBlock)
802  {
803  if (typeof(_didEndBlock) === "function")
804  _didEndBlock(self, returnCode);
805  else
806  CPLog.warn("%s: didEnd block is not a function", [self description]);
807 
808  // didEnd blocks are transient
809  _didEndBlock = nil;
810  }
811  else if (_modalDelegate)
812  {
813  if (_didEndSelector)
814  _modalDelegate.isa.objj_msgSend3(_modalDelegate, _didEndSelector, self, returnCode, contextInfo);
815  }
816  else if (_delegate)
817  {
818  if (_didEndSelector)
819  _delegate.isa.objj_msgSend2(_delegate, _didEndSelector, self, returnCode);
820  else
821  [self _sendDelegateAlertDidEndReturnCode:returnCode];
822  }
823 }
824 
825 @end
826 
827 
829 
834 - (void)_sendDelegateAlertDidEndReturnCode:(int)returnCode
835 {
836  if (!(_implementedDelegateMethods & CPAlertDelegate_alertDidEnd_returnCode_))
837  return;
838 
839  [_delegate alertDidEnd:self returnCode:returnCode];
840 }
841 
846 - (BOOL)_sendDelegateAlertShowHelp
847 {
848  if (!(_implementedDelegateMethods & CPAlertDelegate_alertShowHelp_))
849  return YES;
850 
851  return [_delegate alertShowHelp:self];
852 }
853 
854 @end
855 
857 
861 - (BOOL)showsHelp
862 {
863  return _showHelp;
864 }
865 
869 - (void)setShowsHelp:(BOOL)aValue
870 {
871  _showHelp = aValue;
872 }
873 
877 - (BOOL)showsSuppressionButton
878 {
879  return _showSuppressionButton;
880 }
881 
885 - (void)setShowsSuppressionButton:(BOOL)aValue
886 {
887  _showSuppressionButton = aValue;
888 }
889 
893 - (CPAlertStyle)alertStyle
894 {
895  return _alertStyle;
896 }
897 
901 - (void)setAlertStyle:(CPAlertStyle)aValue
902 {
903  _alertStyle = aValue;
904 }
905 
909 - (CPString)title
910 {
911  return _title;
912 }
913 
917 - (void)setTitle:(CPString)aValue
918 {
919  _title = aValue;
920 }
921 
925 - (CPView)accessoryView
926 {
927  return _accessoryView;
928 }
929 
933 - (void)setAccessoryView:(CPView)aValue
934 {
935  _accessoryView = aValue;
936 }
937 
941 - (CPImage)icon
942 {
943  return _icon;
944 }
945 
949 - (void)setIcon:(CPImage)aValue
950 {
951  _icon = aValue;
952 }
953 
957 - (CPArray)buttons
958 {
959  return _buttons;
960 }
961 
965 - (CPCheckBox)suppressionButton
966 {
967  return _suppressionButton;
968 }
969 
973 - (SEL)didEndSelector
974 {
975  return _didEndSelector;
976 }
977 
981 - (void)setDidEndSelector:(SEL)aValue
982 {
983  _didEndSelector = aValue;
984 }
985 
989 - (_CPAlertThemeView)themeView
990 {
991  return _themeView;
992 }
993 
997 - (CPWindow)window
998 {
999  return _window;
1000 }
1001 
1002 @end
Definition: CPFont.h:2
id init()
Definition: CALayer.j:126
CPTheme defaultHudTheme()
Definition: CPTheme.j:63
CGRect frame
CPCriticalAlertStyle
Definition: CPAlert.j:51
An object representation of nil.
Definition: CPNull.h:2
CPFont systemFontOfSize:(CGSize aSize)
Definition: CPFont.j:282
id< CPAlertDelegate > _delegate accessors(property=delegate)
void beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:(CPWindow aWindow, [modalDelegate] id modalDelegate, [didEndSelector] SEL alertDidEndSelector, [contextInfo] id contextInfo)
Definition: CPAlert.j:695
void setTheme:(CPTheme aTheme)
Definition: CPAlert.j:277
id delegate()
Definition: CALayer.j:965
int width
A mutable key-value pair collection.
Definition: CPDictionary.h:2
void runModal()
Definition: CPAlert.j:664
function ThemeState(stateNames)
Definition: CPTheme.j:379
CPInformationalAlertStyle
Definition: CPAlert.j:46
CPTitledWindowMask
CGRect bounds()
Definition: CALayer.j:203
CPColor blackColor()
Definition: CPColor.j:284
id initWithContentRect:styleMask:(CGRect aContentRect, [styleMask] unsigned aStyleMask)
Definition: CPWindow.j:265
An immutable string (collection of characters).
Definition: CPString.h:2
CPNull null()
Definition: CPNull.j:51
Definition: CPImage.h:2
var bottomHeight
Definition: CPAlert.j:53
CPTheme defaultTheme()
Definition: CPTheme.j:44
CPFont boldSystemFontOfSize:(CGSize aSize)
Definition: CPFont.j:294
CPJustifiedTextAlignment
Definition: CPText.j:79
id checkBoxWithTitle:(CPString aTitle)
Definition: CPCheckBox.j:36
CPTextField labelWithTitle:(CPString aTitle)
Definition: CPTextField.j:200
id init()
Definition: CPObject.j:145
global CPApp var CPAlertDelegate_alertDidEnd_returnCode_
Definition: CPAlert.j:34
Definition: CPAlert.h:2
Definition: CPTheme.h:2
CPDocModalWindowMask
Definition: CPPanel.j:29
void layout()
Definition: CPAlert.j:599
Definition: CPPanel.h:2
global CPApp var CPAlertDelegate_alertShowHelp_
Definition: CPAlert.j:33
id alloc()
Definition: CPObject.j:130
Definition: CPView.j:137
CPAlertStyle CPWarningAlertStyle
Definition: CPAlert.j:41
CPHUDBackgroundWindowMask
FrameUpdater prototype description