-
Notifications
You must be signed in to change notification settings - Fork 9
/
ErrorBannerView.m
167 lines (121 loc) · 3.87 KB
/
ErrorBannerView.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
//
// ErrorPresentationView.m
// Pinna
//
// Created by Kevin MacWhinnie on 10/12/12.
//
//
#import "ErrorBannerView.h"
#import "RKAnimator.h"
#import "RKChromeView.h"
#import "NS(Attributed)String+Geometrics.h"
@interface ErrorPresentationViewController : NSViewController <RKChromeViewDelegate>
{
}
#pragma mark Outlets
@property (nonatomic, assign) IBOutlet NSImageView *iconView;
@property (nonatomic, assign) IBOutlet NSTextField *titleLabel;
@property (nonatomic, assign) IBOutlet NSButton *button;
#pragma mark - Properties
@property (nonatomic, assign) ErrorBannerView *parentView;
@end
@implementation ErrorPresentationViewController
- (id)init
{
if((self = [super initWithNibName:@"ErrorPresentationView" bundle:nil]))
{
}
return self;
}
- (void)sizeToFit
{
NSRect titleLabelFrame = [self.titleLabel frame];
CGFloat properHeight = [self.titleLabel.attributedStringValue heightForWidth:NSWidth(self.titleLabel.frame)];
CGFloat heightDelta = NSHeight(titleLabelFrame) - properHeight;
titleLabelFrame.origin.y -= heightDelta;
titleLabelFrame.size.height += heightDelta;
[self.titleLabel setFrame:titleLabelFrame];
NSRect frame = [self.view frame];
frame.size.height += heightDelta;
[self.view setFrame:frame];
}
#pragma mark - RKChromeViewDelegate
- (void)windowChromeViewWasClicked:(RKChromeView *)windowChromeView
{
[self.parentView close];
}
@end
#pragma mark -
@implementation ErrorBannerView
- (id)init
{
if((self = [super init]))
{
mErrorPresentationViewController = [ErrorPresentationViewController new];
mErrorPresentationViewController.parentView = self;
self.title = @"Unknown Error";
self.buttonTitle = @"Dismiss";
__block ErrorBannerView *me = self;
self.buttonAction = ^{ [me close]; };
}
return self;
}
#pragma mark - Properties
@synthesize title = mTitle;
@synthesize buttonTitle = mButtonTitle;
@synthesize buttonAction = mButtonAction;
#pragma mark -
- (BOOL)isVisible
{
return ([self superview] != nil);
}
#pragma mark - Presentation
- (void)showInView:(NSView *)parentView
{
NSParameterAssert(parentView);
NSAssert(!self.isVisible, @"Cannot show an error presentation view more than once.");
NSRect frame = { .origin = NSZeroPoint, .size = [parentView frame].size };
[self setFrame:frame];
[parentView addSubview:self];
NSView *errorPresentationView = mErrorPresentationViewController.view;
mErrorPresentationViewController.titleLabel.stringValue = self.title ?: @"";
mErrorPresentationViewController.button.title = self.buttonTitle ?: @"";
mErrorPresentationViewController.button.target = self;
mErrorPresentationViewController.button.action = @selector(invokeAction:);
//[mErrorPresentationViewController sizeToFit];
NSRect initialRect = NSMakeRect(0.0, NSMaxY([self frame]),
NSWidth([self frame]), NSHeight([errorPresentationView frame]));
[errorPresentationView setFrame:initialRect];
[self addSubview:errorPresentationView];
NSRect finalRect = initialRect;
finalRect.origin.y = NSMaxY([self frame]) - NSHeight(initialRect);
[[RKAnimator animator] transaction:^(RKAnimatorTransaction *transaction) {
[transaction setFrame:finalRect forTarget:errorPresentationView];
} completionHandler:^(BOOL didFinish) {
mCloseTimer = [NSTimer scheduledTimerWithTimeInterval:3.5
target:self
selector:@selector(close)
userInfo:nil
repeats:NO];
}];
}
- (void)close
{
if(!self.isVisible)
return;
[mCloseTimer invalidate];
mCloseTimer = nil;
[[RKAnimator animator] transaction:^(RKAnimatorTransaction *transaction) {
[transaction fadeOutTarget:self];
} completionHandler:^(BOOL didFinish) {
[mErrorPresentationViewController.view removeFromSuperviewWithoutNeedingDisplay];
[self removeFromSuperview];
}];
}
#pragma mark - Glue
- (IBAction)invokeAction:(id)sender
{
if(self.buttonAction)
self.buttonAction();
}
@end