root / Classes / NameAndStatusTitleView.m @ 9fee07a6
History | View | Annotate | Download (9.3 kB)
1 |
// |
---|---|
2 |
// NameAndStatusTitleView.m |
3 |
// OpenStack |
4 |
// |
5 |
// Created by Michael Mayo on 3/22/11. |
6 |
// Copyright 2011 __MyCompanyName__. All rights reserved. |
7 |
// |
8 |
|
9 |
#import "NameAndStatusTitleView.h" |
10 |
#import "Server.h" |
11 |
#import "Image.h" |
12 |
#import "DDProgressView.h" |
13 |
#import <QuartzCore/QuartzCore.h> |
14 |
|
15 |
static CGFloat iPadXOffset; |
16 |
static CGFloat logoXOffset; |
17 |
|
18 |
@implementation NameAndStatusTitleView |
19 |
|
20 |
@synthesize entity, statusTint, nameLabel, statusLabel, logoView, logoFilename, progressView; |
21 |
|
22 |
static UIFont *nameFont = nil; |
23 |
static UIFont *statusFont = nil; |
24 |
|
25 |
+ (void)initialize { |
26 |
nameFont = [[UIFont boldSystemFontOfSize:17.0] retain]; |
27 |
statusFont = [[UIFont boldSystemFontOfSize:13.0] retain]; |
28 |
} |
29 |
|
30 |
- (id)initWithEntity:(id)e logoFilename:(NSString *)filename { |
31 |
|
32 |
self = [self initWithFrame:CGRectMake(0, 0, 1320, 64)]; |
33 |
if (self) { |
34 |
self.entity = e; |
35 |
self.logoFilename = filename; |
36 |
|
37 |
logoXOffset = self.logoFilename ? 44 : 0; |
38 |
iPadXOffset = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 29 : 0; |
39 |
|
40 |
if (!([self.entity respondsToSelector:@selector(name)] && [self.entity respondsToSelector:@selector(status)] && [self.entity respondsToSelector:@selector(progress)] && [self.entity respondsToSelector:@selector(shouldBePolled)])) { |
41 |
@throw [NSException exceptionWithName:@"NameAndStatusEntityInvalidException" reason:@"entity for NameAndStatusTitleView should respond to name, status, progress, shouldBePolled" userInfo:nil]; |
42 |
} |
43 |
|
44 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
45 |
self.backgroundColor = [UIColor scrollViewTexturedBackgroundColor]; |
46 |
} else { |
47 |
self.backgroundColor = [UIColor groupTableViewBackgroundColor]; |
48 |
} |
49 |
|
50 |
self.autoresizingMask = UIViewAutoresizingFlexibleWidth; |
51 |
|
52 |
// shadow |
53 |
self.clipsToBounds = NO; |
54 |
[self.layer setShadowColor:[[UIColor blackColor] CGColor]]; |
55 |
[self.layer setShadowRadius:2.0f]; |
56 |
[self.layer setShadowOffset:CGSizeMake(1, 1)]; |
57 |
[self.layer setShadowOpacity:0.8f]; |
58 |
|
59 |
nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(12.0 + logoXOffset + iPadXOffset, 12.0, 654, 22)]; |
60 |
|
61 |
nameLabel.backgroundColor = [UIColor clearColor]; |
62 |
nameLabel.textColor = [UIColor whiteColor]; |
63 |
nameLabel.font = nameFont; |
64 |
nameLabel.text = [self.entity name]; |
65 |
nameLabel.adjustsFontSizeToFitWidth = YES; |
66 |
[nameLabel.layer setShadowColor:[[UIColor blackColor] CGColor]]; |
67 |
[nameLabel.layer setShadowRadius:1.0f]; |
68 |
[nameLabel.layer setShadowOffset:CGSizeMake(1, 1)]; |
69 |
[nameLabel.layer setShadowOpacity:1.0f]; |
70 |
|
71 |
[self addSubview:nameLabel]; |
72 |
|
73 |
CGSize statusSize = [[self.entity status] sizeWithFont:statusFont forWidth:300 lineBreakMode:UILineBreakModeCharacterWrap]; |
74 |
statusLabel = [[UILabel alloc] initWithFrame:CGRectMake(12.0 + logoXOffset + iPadXOffset, 34.0, 200, statusSize.height)]; |
75 |
statusLabel.backgroundColor = [UIColor clearColor]; |
76 |
statusLabel.textColor = [UIColor whiteColor]; |
77 |
statusLabel.font = statusFont; |
78 |
statusLabel.text = [self.entity status]; |
79 |
statusLabel.lineBreakMode = UILineBreakModeCharacterWrap; |
80 |
statusLabel.numberOfLines = 0; |
81 |
// statusLabel.shadowOffset = CGSizeMake(0, 1.0); |
82 |
// statusLabel.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.4]; |
83 |
[statusLabel.layer setShadowColor:[[UIColor blackColor] CGColor]]; |
84 |
[statusLabel.layer setShadowRadius:1.0f]; |
85 |
[statusLabel.layer setShadowOffset:CGSizeMake(1, 1)]; |
86 |
[statusLabel.layer setShadowOpacity:1.0f]; |
87 |
[self addSubview:statusLabel]; |
88 |
|
89 |
self.statusTint = [[[UIView alloc] initWithFrame:self.frame] autorelease]; |
90 |
self.statusTint.autoresizesSubviews = YES; |
91 |
self.statusTint.autoresizingMask = UIViewAutoresizingFlexibleWidth; |
92 |
self.statusTint.alpha = 0.7; |
93 |
|
94 |
if ([@"ACTIVE" isEqualToString:[self.entity status]]) { |
95 |
self.statusTint.backgroundColor = [UIColor colorWithRed:0.314 green:0.588 blue:0.086 alpha:1.0]; |
96 |
} else if ([self.entity shouldBePolled]) { |
97 |
self.statusTint.backgroundColor = [UIColor orangeColor]; |
98 |
} else { |
99 |
self.statusTint.backgroundColor = [UIColor redColor]; |
100 |
} |
101 |
|
102 |
[self addSubview:self.statusTint]; |
103 |
[self sendSubviewToBack:self.statusTint]; |
104 |
|
105 |
if (self.logoFilename) { |
106 |
logoView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:self.logoFilename]]; |
107 |
logoView.frame = CGRectMake(12.0 + iPadXOffset, 14.0, logoView.frame.size.width, logoView.frame.size.height); |
108 |
logoView.clipsToBounds = NO; |
109 |
[logoView.layer setShadowColor:[[UIColor blackColor] CGColor]]; |
110 |
[logoView.layer setShadowRadius:1.0f]; |
111 |
[logoView.layer setShadowOffset:CGSizeMake(1, 1)]; |
112 |
[logoView.layer setShadowOpacity:0.8f]; |
113 |
[self addSubview:logoView]; |
114 |
} |
115 |
|
116 |
self.progressView = [[[DDProgressView alloc] initWithFrame:CGRectMake(70 + logoXOffset + iPadXOffset, 37, 100, 20)] autorelease]; |
117 |
self.progressView.progress = 0.0; |
118 |
[self.progressView.layer setShadowColor:[[UIColor blackColor] CGColor]]; |
119 |
[self.progressView.layer setShadowRadius:1.0f]; |
120 |
[self.progressView.layer setShadowOffset:CGSizeMake(1, 1)]; |
121 |
[self.progressView.layer setShadowOpacity:1.0f]; |
122 |
|
123 |
[self addSubview:progressView]; |
124 |
} |
125 |
return self; |
126 |
} |
127 |
|
128 |
- (id)initWithEntity:(id)e { |
129 |
return [self initWithEntity:e logoFilename:nil]; |
130 |
} |
131 |
|
132 |
- (void)drawRect:(CGRect)rect { |
133 |
|
134 |
self.nameLabel.text = [self.entity name]; |
135 |
|
136 |
if ([[self.entity status] isEqualToString:@"BUILD"]) { |
137 |
self.progressView.alpha = 1; |
138 |
self.statusLabel.text = @"Building"; |
139 |
self.progressView.frame = CGRectMake(70 + logoXOffset + iPadXOffset, 37, 100, 20); |
140 |
} else if ([[self.entity status] isEqualToString:@"QUEUE_RESIZE"]) { |
141 |
self.progressView.alpha = 1; |
142 |
self.statusLabel.text = @"Resizing"; //@"Queueing"; |
143 |
self.progressView.frame = CGRectMake(70 + logoXOffset + iPadXOffset, 37, 100, 20); |
144 |
} else if ([[self.entity status] isEqualToString:@"PREP_RESIZE"]) { |
145 |
self.progressView.alpha = 1; |
146 |
self.statusLabel.text = @"Resizing"; //@"Preparing"; |
147 |
self.progressView.frame = CGRectMake(70 + logoXOffset + iPadXOffset, 37, 100, 20); |
148 |
} else if ([[self.entity status] isEqualToString:@"RESIZE"]) { |
149 |
self.progressView.alpha = 1; |
150 |
self.statusLabel.text = @"Resizing"; |
151 |
self.progressView.frame = CGRectMake(70 + logoXOffset + iPadXOffset, 37, 100, 20); |
152 |
} else if ([[self.entity status] isEqualToString:@"VERIFY_RESIZE"]) { |
153 |
self.progressView.alpha = 0; |
154 |
self.statusLabel.text = @"Resize Complete"; |
155 |
} else if ([[self.entity status] isEqualToString:@"REBUILD"]) { |
156 |
self.progressView.alpha = 1; |
157 |
self.statusLabel.text = @"Rebuilding"; |
158 |
self.progressView.frame = CGRectMake(70 + logoXOffset + iPadXOffset, 37, 100, 20); |
159 |
} else if ([[self.entity status] isEqualToString:@"REBOOT"]) { |
160 |
self.progressView.alpha = 0; |
161 |
self.statusLabel.text = @"Rebooting"; |
162 |
} else if ([[self.entity status] isEqualToString:@"UNKNOWN"]) { |
163 |
self.progressView.alpha = 0; |
164 |
self.statusLabel.text = @"Unknown"; |
165 |
} else if ([[self.entity status] isEqualToString:@"ACTIVE"]) { |
166 |
self.progressView.alpha = 0; |
167 |
self.statusLabel.text = @"Active"; |
168 |
} else { |
169 |
self.progressView.alpha = 0; |
170 |
self.statusLabel.text = [self.entity status]; |
171 |
} |
172 |
|
173 |
[self.progressView setProgress:[(Server *)self.entity progress] / 100.0 animated:YES]; |
174 |
|
175 |
if (![@"ACTIVE" isEqualToString:[self.entity status]]) { |
176 |
|
177 |
if ([self.entity shouldBePolled]) { |
178 |
self.statusTint.backgroundColor = [UIColor orangeColor]; |
179 |
} else { |
180 |
self.statusTint.backgroundColor = [UIColor redColor]; |
181 |
} |
182 |
|
183 |
if (![self.statusTint.layer animationForKey:@"animateOpacity"]) { |
184 |
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; |
185 |
animation.duration = 1.0; |
186 |
animation.repeatCount = HUGE_VALF; // repeat forever |
187 |
animation.autoreverses = YES; |
188 |
animation.fromValue = [NSNumber numberWithFloat:1.0]; |
189 |
animation.toValue = [NSNumber numberWithFloat:0.5]; |
190 |
[self.statusTint.layer addAnimation:animation forKey:@"animateOpacity"]; |
191 |
} |
192 |
} else { |
193 |
[UIView animateWithDuration:1 animations:^{ |
194 |
if ([@"ACTIVE" isEqualToString:[self.entity status]]) { |
195 |
[self.statusTint.layer removeAnimationForKey:@"animateOpacity"]; |
196 |
self.statusTint.backgroundColor = [UIColor colorWithRed:0.314 green:0.588 blue:0.086 alpha:1.0]; |
197 |
} else if ([self.entity shouldBePolled]) { |
198 |
self.statusTint.backgroundColor = [UIColor orangeColor]; |
199 |
} else { |
200 |
self.statusTint.backgroundColor = [UIColor redColor]; |
201 |
} |
202 |
}]; |
203 |
} |
204 |
[super drawRect:rect]; |
205 |
} |
206 |
|
207 |
- (void)dealloc { |
208 |
[entity release]; |
209 |
[statusTint release]; |
210 |
[nameLabel release]; |
211 |
[statusLabel release]; |
212 |
[logoView release]; |
213 |
[logoFilename release]; |
214 |
[progressView release]; |
215 |
[super dealloc]; |
216 |
} |
217 |
|
218 |
@end |