FreeRDP
BlockBackground.m
1 //
2 // BlockBackground.m
3 // arrived
4 //
5 // Created by Gustavo Ambrozio on 29/11/11.
6 // Copyright (c) 2011 N/A. All rights reserved.
7 //
8 
9 #import "BlockBackground.h"
10 
11 @implementation BlockBackground
12 
13 @synthesize backgroundImage = _backgroundImage;
14 @synthesize vignetteBackground = _vignetteBackground;
15 
16 static BlockBackground *_sharedInstance = nil;
17 
18 + (BlockBackground *)sharedInstance
19 {
20  if (_sharedInstance != nil)
21  {
22  return _sharedInstance;
23  }
24 
25  @synchronized(self)
26  {
27  if (_sharedInstance == nil)
28  {
29  [[[self alloc] init] autorelease];
30  }
31  }
32 
33  return _sharedInstance;
34 }
35 
36 + (id)allocWithZone:(NSZone *)zone
37 {
38  @synchronized(self)
39  {
40  if (_sharedInstance == nil)
41  {
42  _sharedInstance = [super allocWithZone:zone];
43  return _sharedInstance;
44  }
45  }
46  NSAssert(NO, @ "[BlockBackground alloc] explicitly called on singleton class.");
47  return nil;
48 }
49 
50 - (id)copyWithZone:(NSZone *)zone
51 {
52  return self;
53 }
54 
55 - (id)retain
56 {
57  return self;
58 }
59 
60 - (unsigned)retainCount
61 {
62  return UINT_MAX;
63 }
64 
65 - (oneway void)release
66 {
67 }
68 
69 - (id)autorelease
70 {
71  return self;
72 }
73 
74 - (void)setRotation:(NSNotification *)notification
75 {
76  UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
77 
78  CGRect orientationFrame = [UIScreen mainScreen].bounds;
79 
80  if ((UIInterfaceOrientationIsLandscape(orientation) &&
81  orientationFrame.size.height > orientationFrame.size.width) ||
82  (UIInterfaceOrientationIsPortrait(orientation) &&
83  orientationFrame.size.width > orientationFrame.size.height))
84  {
85  float temp = orientationFrame.size.width;
86  orientationFrame.size.width = orientationFrame.size.height;
87  orientationFrame.size.height = temp;
88  }
89 
90  self.transform = CGAffineTransformIdentity;
91  self.frame = orientationFrame;
92 
93  CGFloat posY = orientationFrame.size.height / 2;
94  CGFloat posX = orientationFrame.size.width / 2;
95 
96  CGPoint newCenter;
97  CGFloat rotateAngle;
98 
99  switch (orientation)
100  {
101  case UIInterfaceOrientationPortraitUpsideDown:
102  rotateAngle = M_PI;
103  newCenter = CGPointMake(posX, orientationFrame.size.height - posY);
104  break;
105  case UIInterfaceOrientationLandscapeLeft:
106  rotateAngle = -M_PI / 2.0f;
107  newCenter = CGPointMake(posY, posX);
108  break;
109  case UIInterfaceOrientationLandscapeRight:
110  rotateAngle = M_PI / 2.0f;
111  newCenter = CGPointMake(orientationFrame.size.height - posY, posX);
112  break;
113  default: // UIInterfaceOrientationPortrait
114  rotateAngle = 0.0;
115  newCenter = CGPointMake(posX, posY);
116  break;
117  }
118 
119  self.transform = CGAffineTransformMakeRotation(rotateAngle);
120  self.center = newCenter;
121 
122  [self setNeedsLayout];
123  [self layoutSubviews];
124 }
125 
126 - (id)init
127 {
128  self = [super initWithFrame:[[UIScreen mainScreen] bounds]];
129  if (self)
130  {
131  self.windowLevel = UIWindowLevelStatusBar;
132  self.hidden = YES;
133  self.userInteractionEnabled = NO;
134  self.backgroundColor = [UIColor colorWithWhite:0.4 alpha:0.5f];
135  self.vignetteBackground = NO;
136 
137  [[NSNotificationCenter defaultCenter]
138  addObserver:self
139  selector:@selector(setRotation:)
140  name:UIApplicationDidChangeStatusBarOrientationNotification
141  object:nil];
142  [self setRotation:nil];
143  }
144  return self;
145 }
146 
147 - (void)addToMainWindow:(UIView *)view
148 {
149  [self setRotation:nil];
150 
151  if ([self.subviews containsObject:view])
152  return;
153 
154  if (self.hidden)
155  {
156  _previousKeyWindow = [[[UIApplication sharedApplication] keyWindow] retain];
157  self.alpha = 0.0f;
158  self.hidden = NO;
159  self.userInteractionEnabled = YES;
160  [self makeKeyWindow];
161  }
162 
163  if (self.subviews.count > 0)
164  {
165  ((UIView *)[self.subviews lastObject]).userInteractionEnabled = NO;
166  }
167 
168  if (_backgroundImage)
169  {
170  UIImageView *backgroundView = [[UIImageView alloc] initWithImage:_backgroundImage];
171  backgroundView.frame = self.bounds;
172  backgroundView.contentMode = UIViewContentModeScaleToFill;
173  [self addSubview:backgroundView];
174  [backgroundView release];
175  [_backgroundImage release];
176  _backgroundImage = nil;
177  }
178 
179  [self addSubview:view];
180 }
181 
182 - (void)reduceAlphaIfEmpty
183 {
184  if (self.subviews.count == 1 ||
185  (self.subviews.count == 2 &&
186  [[self.subviews objectAtIndex:0] isKindOfClass:[UIImageView class]]))
187  {
188  self.alpha = 0.0f;
189  self.userInteractionEnabled = NO;
190  }
191 }
192 
193 - (void)removeView:(UIView *)view
194 {
195  [view removeFromSuperview];
196 
197  UIView *topView = [self.subviews lastObject];
198  if ([topView isKindOfClass:[UIImageView class]])
199  {
200  // It's a background. Remove it too
201  [topView removeFromSuperview];
202  }
203 
204  if (self.subviews.count == 0)
205  {
206  self.hidden = YES;
207  [_previousKeyWindow makeKeyWindow];
208  [_previousKeyWindow release];
209  _previousKeyWindow = nil;
210  }
211  else
212  {
213  ((UIView *)[self.subviews lastObject]).userInteractionEnabled = YES;
214  }
215 }
216 
217 - (void)drawRect:(CGRect)rect
218 {
219  if (_backgroundImage || !_vignetteBackground)
220  return;
221  CGContextRef context = UIGraphicsGetCurrentContext();
222 
223  size_t locationsCount = 2;
224  CGFloat locations[2] = { 0.0f, 1.0f };
225  CGFloat colors[8] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.75f };
226  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
227  CGGradientRef gradient =
228  CGGradientCreateWithColorComponents(colorSpace, colors, locations, locationsCount);
229  CGColorSpaceRelease(colorSpace);
230 
231  CGPoint center = CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2);
232  float radius = MIN(self.bounds.size.width, self.bounds.size.height);
233  CGContextDrawRadialGradient(context, gradient, center, 0, center, radius,
234  kCGGradientDrawsAfterEndLocation);
235  CGGradientRelease(gradient);
236 }
237 
238 @end