Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
805 - 1
//
2
//  InAppSettingsViewController.m
3
//  InAppSettings
4
//
5
//  Created by David Keegan on 11/21/09.
6
//  Copyright 2009 InScopeApps{+}. All rights reserved.
7
//
8
 
9
#import "InAppSettings.h"
10
#import "InAppSettingsConstants.h"
11
#import "InAppSettingsPSMultiValueSpecifierTable.h"
12
 
13
@implementation InAppSettings
14
 
15
+ (void) registerDefaults {
16
  [[[InAppSettingsReaderRegisterDefaults alloc] init] release];
17
}
18
 
19
@end
20
 
21
@implementation InAppSettingsModalViewController
22
 
23
- (id) init {
24
  InAppSettingsViewController * settings = [[InAppSettingsViewController alloc] init];
25
 
26
  self = [[UINavigationController alloc] initWithRootViewController:settings];
27
  [settings addDoneButton];
28
  [settings release];
29
  return self;
30
}
31
 
32
@end
33
 
34
@implementation InAppSettingsViewController
35
 
36
@synthesize file;
37
@synthesize settingsTableView;
38
@synthesize firstResponder;
39
@synthesize settingsReader;
40
@synthesize delegate;
41
@synthesize dataSource;
42
 
43
 
44
#pragma mark modal view
45
 
46
- (void) dismissModalView {
47
  [self.navigationController dismissModalViewControllerAnimated:YES];
48
}
49
 
50
- (void) addDoneButton {
51
  UIBarButtonItem * doneButton = [[UIBarButtonItem alloc]
52
                                  initWithBarButtonSystemItem:UIBarButtonSystemItemDone
53
                                                       target:self
54
                                                       action:@selector(dismissModalView)];
55
 
56
  self.navigationItem.rightBarButtonItem = doneButton;
57
  [doneButton release];
58
}
59
 
60
#pragma mark setup view
61
 
62
- (id) initWithFile:(NSString *)inputFile {
63
  self = [super init];
64
  if (self != nil) {
65
    self.file = inputFile;
66
  }
67
  return self;
68
}
69
 
70
- (void) viewDidLoad {
71
  // setup the table
72
  self.settingsTableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
73
  self.settingsTableView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
74
  self.settingsTableView.delegate = self;
75
  self.settingsTableView.dataSource = self;
76
  [self.view addSubview:self.settingsTableView];
77
 
78
  // if the title is nil set it to Settings
79
  if (!self.title) {
80
    self.title = NSLocalizedString(@"Settings", nil);
81
  }
82
 
83
  // load settigns plist
84
  if (!self.file) {
85
    self.file = InAppSettingsRootFile;
86
  }
87
 
88
  InAppSettingsReader* tmpSettingsReader =  [[InAppSettingsReader alloc] initWithFile:self.file dataSource:dataSource];
89
  self.settingsReader = tmpSettingsReader;
90
  [tmpSettingsReader release];
91
 
92
 
93
  // setup keyboard notification
94
  self.firstResponder = nil;
95
  [self registerForKeyboardNotifications];
96
}
97
 
98
- (void) viewWillAppear:(BOOL)animated {
99
  self.firstResponder = nil;
100
 
101
  self.settingsTableView.contentInset = UIEdgeInsetsZero;
102
  self.settingsTableView.scrollIndicatorInsets = UIEdgeInsetsZero;
103
 
104
  [self.settingsTableView reloadData];
105
  [super viewWillAppear:animated];
106
}
107
 
108
- (void) viewWillDisappear:(BOOL)animated {
109
  self.firstResponder = nil;
110
  [super viewWillDisappear:animated];
111
}
112
 
113
- (void) dealloc {
114
  self.firstResponder = nil;
115
  self.delegate = nil;
116
 
117
  [file release];
118
  [settingsTableView release];
119
  [settingsReader release];
120
  [super dealloc];
121
}
122
 
123
#pragma mark text field cell delegate
124
 
125
- (void) textFieldDidBeginEditing:(UITextField *)cellTextField {
126
  self.firstResponder = cellTextField;
127
 
128
  // TODO: find a better way to get the cell from the text view
129
  NSIndexPath * indexPath = [self.settingsTableView indexPathForCell:(UITableViewCell *)[[cellTextField superview] superview]];
130
  [self.settingsTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
131
}
132
 
133
- (BOOL) textFieldShouldReturn:(UITextField *)cellTextField {
134
  self.firstResponder = nil;
135
  [cellTextField resignFirstResponder];
136
  return YES;
137
}
138
 
139
#pragma mark keyboard notification
140
 
141
- (void) registerForKeyboardNotifications {
142
  [[NSNotificationCenter defaultCenter] addObserver:self
143
                                           selector:@selector(keyboardWillShow:)
144
                                               name:UIKeyboardWillShowNotification object:nil];
145
 
146
  [[NSNotificationCenter defaultCenter] addObserver:self
147
                                           selector:@selector(keyboardWillHide:)
148
                                               name:UIKeyboardWillHideNotification object:nil];
149
}
150
 
151
- (void) keyboardWillShow:(NSNotification *)notification {
152
  if (self.firstResponder == nil) {
153
    // get the keybaord rect
154
    CGRect keyboardRect = [[[notification userInfo] objectForKey:UIKeyboardBoundsUserInfoKey] CGRectValue];
155
 
156
    // determin the bottom inset for the table view
157
    UIEdgeInsets settingsTableInset = self.settingsTableView.contentInset;
158
    CGPoint tableViewScreenSpace = [self.settingsTableView.superview convertPoint:self.settingsTableView.frame.origin toView:nil];
159
    CGFloat tableViewBottomOffset = InAppSettingsScreenHeight - (tableViewScreenSpace.y + self.settingsTableView.frame.size.height);
160
    settingsTableInset.bottom = keyboardRect.size.height - tableViewBottomOffset;
161
 
162
    [UIView beginAnimations:nil context:nil];
163
    [UIView setAnimationDuration:InAppSettingsKeyboardAnimation];
164
    [UIView setAnimationBeginsFromCurrentState:YES];
165
    self.settingsTableView.contentInset = settingsTableInset;
166
    self.settingsTableView.scrollIndicatorInsets = settingsTableInset;
167
    [UIView commitAnimations];
168
  }
169
}
170
 
171
- (void) keyboardWillHide:(NSNotification *)notification {
172
  if (self.firstResponder == nil) {
173
    [UIView beginAnimations:nil context:nil];
174
    [UIView setAnimationDuration:InAppSettingsKeyboardAnimation];
175
    [UIView setAnimationBeginsFromCurrentState:YES];
176
    self.settingsTableView.contentInset = UIEdgeInsetsZero;
177
    self.settingsTableView.scrollIndicatorInsets = UIEdgeInsetsZero;
178
    [UIView commitAnimations];
179
  }
180
}
181
 
182
#pragma mark specifier delegate
183
 
184
- (void) settingsSpecifierUpdated:(InAppSettingsSpecifier *)specifier {
185
  if ([self.delegate respondsToSelector:@selector(InAppSettingsValue:forKey:)]) {
186
    [self.delegate InAppSettingsValue:[specifier getValue] forKey:[specifier getKey]];
187
  }
188
}
189
 
190
#pragma mark Table view methods
191
 
192
- (InAppSettingsSpecifier *) settingAtIndexPath:(NSIndexPath *)indexPath {
193
  return [[self.settingsReader.settings objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
194
}
195
 
196
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
197
  return [self.settingsReader.headers count];
198
}
199
 
200
- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
201
  return [self.settingsReader.headers objectAtIndex:section];
202
}
203
 
204
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
205
  return [[self.settingsReader.settings objectAtIndex:section] count];
206
}
207
 
208
- (CGFloat) tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
209
  if (InAppSettingsDisplayPowered && [self.file isEqualToString:InAppSettingsRootFile] && section == (NSInteger)[self.settingsReader.headers count] - 1) {
210
    return InAppSettingsPowerFooterHeight;
211
  }
212
  return 0.0f;
213
}
214
 
215
- (UIView *) tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
216
  if (InAppSettingsDisplayPowered && [self.file isEqualToString:InAppSettingsRootFile] && section == (NSInteger)[self.settingsReader.headers count] - 1) {
217
    UIView * powerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, InAppSettingsScreenWidth, InAppSettingsPowerFooterHeight)];
218
 
219
    // InAppSettings label
220
    CGSize InAppSettingsSize = [InAppSettingsProjectName sizeWithFont:InAppSettingsFooterFont];
221
    CGPoint InAppSettingsPos = CGPointMake((CGFloat)round((InAppSettingsScreenWidth * 0.5f) - (InAppSettingsSize.width * 0.5f)),
222
                                           (CGFloat)round((InAppSettingsPowerFooterHeight * 0.5f) - (InAppSettingsSize.height * 0.5f)) - 1);
223
    UILabel * InAppLabel = [[UILabel alloc] initWithFrame:CGRectMake(InAppSettingsPos.x, InAppSettingsPos.y, InAppSettingsSize.width, InAppSettingsSize.height)];
224
    InAppLabel.text = InAppSettingsProjectName;
225
    InAppLabel.font = InAppSettingsFooterFont;
226
    InAppLabel.backgroundColor = [UIColor clearColor];
227
    InAppLabel.textColor = InAppSettingsFooterBlue;
228
    InAppLabel.shadowColor = [UIColor whiteColor];
229
    InAppLabel.shadowOffset = CGSizeMake(0.0f, 1.0f);
230
    [powerView addSubview:InAppLabel];
231
    [InAppLabel release];
232
 
233
    // lighting bolts
234
    CGPoint leftLightningBoltPos = CGPointMake(InAppSettingsPos.x - InAppSettingsLightingBoltSize,
235
                                               (CGFloat)round((InAppSettingsPowerFooterHeight * 0.5f) - (InAppSettingsLightingBoltSize * 0.5f)));
236
    InAppSettingsLightningBolt * leftLightningBolt = [[InAppSettingsLightningBolt alloc]
237
                                                      initWithFrame:CGRectMake(leftLightningBoltPos.x, leftLightningBoltPos.y,
238
                                                                               InAppSettingsLightingBoltSize, InAppSettingsLightingBoltSize)];
239
    [powerView addSubview:leftLightningBolt];
240
    [leftLightningBolt release];
241
 
242
    CGPoint rightLightningBoltPos = CGPointMake((CGFloat)round(InAppSettingsPos.x + InAppSettingsSize.width), leftLightningBoltPos.y);
243
    InAppSettingsLightningBolt * rightLightningBolt = [[InAppSettingsLightningBolt alloc]
244
                                                       initWithFrame:CGRectMake(rightLightningBoltPos.x, rightLightningBoltPos.y,
245
                                                                                InAppSettingsLightingBoltSize, InAppSettingsLightingBoltSize)];
246
    rightLightningBolt.flip = YES;
247
    [powerView addSubview:rightLightningBolt];
248
    [rightLightningBolt release];
249
 
250
    return [powerView autorelease];
251
  }
252
  return nil;
253
}
254
 
255
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
256
  InAppSettingsSpecifier * setting = [self settingAtIndexPath:indexPath];
257
 
258
  setting.delegate = self;
259
 
260
  // get the NSClass for a specifier, if there is none use the base class InAppSettingsTableCell
261
  NSString * cellType = [setting cellName];
262
  Class nsclass = NSClassFromString(cellType);
263
  if (!nsclass) {
264
    cellType = @"InAppSettingsTableCell";
265
    nsclass = NSClassFromString(cellType);
266
  }
267
 
268
  InAppSettingsTableCell * cell = ((InAppSettingsTableCell *)[tableView dequeueReusableCellWithIdentifier:cellType]);
269
  if (cell == nil) {
270
    cell = [[[nsclass alloc] initWithReuseIdentifier:cellType] autorelease];
271
    // setup the cells controlls
272
    [cell setupCell];
273
  }
274
 
275
  // set the values of the cell, this is separated from setupCell for reloading the table
276
  cell.setting = setting;
277
  [cell setValueDelegate:self];
278
  [cell setUIValues];
279
 
280
  return cell;
281
}
282
 
283
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
284
  InAppSettingsSpecifier * setting = [self settingAtIndexPath:indexPath];
285
 
286
  if ([setting isType:InAppSettingsPSMultiValueSpecifier]) {
287
    InAppSettingsPSMultiValueSpecifierTable * multiValueSpecifier = [[InAppSettingsPSMultiValueSpecifierTable alloc] initWithSetting:setting];
288
    [self.navigationController pushViewController:multiValueSpecifier animated:YES];
289
    [multiValueSpecifier release];
290
  } else if ([setting isType:InAppSettingsPSChildPaneSpecifier]) {
291
 
292
    if ( [setting valueForKey:InAppSettingsSpecifierInAppChildPaneClass] ) {
293
 
294
      UIViewController * childPane;
295
 
296
      Class childPaneClass = NSClassFromString([setting valueForKey:InAppSettingsSpecifierInAppChildPaneClass]);
297
      if ( [childPaneClass conformsToProtocol:@protocol(InAppSettingsChildPane)] ) {
298
        childPane = [[childPaneClass alloc] initWithSetting:setting];
299
      } else {
300
        childPane = [[childPaneClass alloc] init];
301
      }
302
 
303
      childPane.title = [setting localizedTitle];
304
      [self.navigationController pushViewController:childPane animated:YES];
305
      [childPane release];
306
    } else {
307
 
308
      InAppSettingsViewController * childPane = [[InAppSettingsViewController alloc] initWithFile:[setting valueForKey:InAppSettingsSpecifierFile]];
309
      childPane.title = [setting localizedTitle];
310
      childPane.dataSource = self.dataSource;
311
      [self.navigationController pushViewController:childPane animated:YES];
312
      [childPane release];
313
    }
314
  } else if ([setting isType:InAppSettingsPSTitleValueSpecifier]) {
315
    InAppSettingsOpenUrl([NSURL URLWithString:[setting valueForKey:InAppSettingsSpecifierInAppURL]]);
316
  }
317
}
318
 
319
- (NSIndexPath *) tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
320
  InAppSettingsTableCell * cell = ((InAppSettingsTableCell *)[tableView cellForRowAtIndexPath:indexPath]);
321
 
322
  if ([cell.setting isType:@"PSTextFieldSpecifier"]) {
323
    [cell.valueInput becomeFirstResponder];
324
  } else if (cell.canSelectCell) {
325
    [self.firstResponder resignFirstResponder];
326
    return indexPath;
327
  }
328
  return nil;
329
}
330
 
331
@end
332
 
333
@implementation InAppSettingsLightningBolt
334
 
335
@synthesize flip;
336
 
337
- (id) initWithFrame:(CGRect)frame {
338
  self = [super initWithFrame:frame];
339
  if (self != nil) {
340
    self.flip = NO;
341
    self.backgroundColor = [UIColor clearColor];
342
  }
343
  return self;
344
}
345
 
346
- (void) drawRect:(CGRect)rect {
347
  CGContextRef context = UIGraphicsGetCurrentContext();
348
 
349
  CGContextSetFillColorWithColor(context, [InAppSettingsFooterBlue CGColor]);
350
    #if __IPHONE_3_2
351
  CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 1.0f), 0.0f, [[UIColor whiteColor] CGColor]);
352
    #else
353
  CGContextSetShadowWithColor(context, CGSizeMake(0.0f, -1.0f), 0.0f, [[UIColor whiteColor] CGColor]);
354
    #endif
355
  if (self.flip) {
356
    CGContextMoveToPoint(context, 4.0f, 1.0f);
357
    CGContextAddLineToPoint(context, 13.0f, 1.0f);
358
    CGContextAddLineToPoint(context, 10.0f, 5.0f);
359
    CGContextAddLineToPoint(context, 12.0f, 7.0f);
360
    CGContextAddLineToPoint(context, 2.0f, 15.0f);
361
    CGContextAddLineToPoint(context, 5.0f, 7.0f);
362
    CGContextAddLineToPoint(context, 3.0f, 5.0f);
363
  } else {
364
    CGContextMoveToPoint(context, 3.0f, 1.0f);
365
    CGContextAddLineToPoint(context, 12.0f, 1.0f);
366
    CGContextAddLineToPoint(context, 13.0f, 5.0f);
367
    CGContextAddLineToPoint(context, 11.0f, 7.0f);
368
    CGContextAddLineToPoint(context, 14.0f, 15.0f);
369
    CGContextAddLineToPoint(context, 4.0f, 7.0f);
370
    CGContextAddLineToPoint(context, 6.0f, 5.0f);
371
  }
372
  CGContextFillPath(context);
373
}
374
 
375
@end