bzr branch
/browse/iphone/tappity
| Line | Revision | Contents |
| 1 | 9 | // |
| 2 | // JigsAppDelegate.m |
|
| 3 | // Jigs |
|
| 4 | // |
|
| 5 | // Created by döme on 12.07.2009. |
|
| 6 | // Copyright __MyCompanyName__ 2009. All rights reserved. |
|
| 7 | // |
|
| 8 | ||
| 9 | 42 | |
| 10 | 9 | #import "JigsAppDelegate.h" |
| 11 | 13 | #import "JigView.h" |
| 12 | #import "JigsawViewController.h" |
|
| 13 | 25 | #import "NewGameViewController.h" |
| 14 | 38 | #import "GriddedImageWell.h" |
| 15 | 30 | #import "ElAnimation.h" |
| 16 | 38 | #import "geometry.h" |
| 17 | 46 | #import "TappityServer.h" |
| 18 | 30 | |
| 19 | #import <QuartzCore/QuartzCore.h> |
|
| 20 | ||
| 21 | @interface JigsAppDelegate (Private) |
|
| 22 | - (void) setupNewGameView; |
|
| 23 | - (void) updateNewGameInterface; |
|
| 24 | - (void) startAnimation; |
|
| 25 | 31 | - (void) stopInfoBlinkAnimation; |
| 26 | - (void) infoBlinkAnimationCallback: (id) info; |
|
| 27 | ||
| 28 | 30 | @end |
| 29 | 9 | |
| 30 | @implementation JigsAppDelegate |
|
| 31 | ||
| 32 | 37 | - (void) saveGame |
| 33 | { |
|
| 34 | NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; |
|
| 35 | ||
| 36 | [defaults setDouble: timeInPuzzle forKey: @"timeInCurrentPuzzle"]; |
|
| 37 | ||
| 38 | [jigView saveJigsawState]; |
|
| 39 | } |
|
| 40 | ||
| 41 | - (void) restoreGame |
|
| 42 | { |
|
| 43 | NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; |
|
| 44 | ||
| 45 | timeInPuzzle = [defaults doubleForKey: @"timeInCurrentPuzzle"]; |
|
| 46 | [jigView restoreJigsawState]; |
|
| 47 | } |
|
| 48 | ||
| 49 | 9 | |
| 50 | 27 | - (void) newGameAction: (id) sender |
| 51 | { |
|
| 52 | [self presentNewGameDialog: self]; |
|
| 53 | } |
|
| 54 | ||
| 55 | 30 | - (void) generateJigsaw |
| 56 | { |
|
| 57 | [jigView generateJigsaw]; |
|
| 58 | } |
|
| 59 | ||
| 60 | 34 | |
| 61 | - (void) viewFadeInFinished: (id) info |
|
| 62 | { |
|
| 63 | UIView* oldView = [info objectForKey: AnimationUserInfoKey]; |
|
| 64 | if (oldView != currentView) |
|
| 65 | [oldView removeFromSuperview]; |
|
| 66 | } |
|
| 67 | ||
| 68 | - (void) fadeInView: (UIView*) newView |
|
| 69 | { |
|
| 70 | [newView.layer setOpacity: 0.0f]; |
|
| 71 | [self.view addSubview: newView]; |
|
| 72 | |
|
| 73 | if (newView == currentView) |
|
| 74 | return; |
|
| 75 | ||
| 76 | // NSLog(@"animating view in"); |
|
| 77 | ||
| 78 | 30 | id anim = nil; |
| 79 | ||
| 80 | 34 | if (currentView) |
| 81 | 30 | { |
| 82 | 37 | // NSLog(@"fading out %p", currentView); |
| 83 | 30 | anim = [[[ElFloatAnimation alloc] init] autorelease]; |
| 84 | 34 | [anim setTarget: [currentView layer]]; |
| 85 | 30 | [anim setProperty: @"opacity"]; |
| 86 | 34 | [anim setStartValue: [currentView layer].opacity]; |
| 87 | 30 | [anim setEndValue: 0.0f]; |
| 88 | [anim setDuration: 0.5f]; |
|
| 89 | [anim queueForKey: @"viewFading" atBeginning: NO cancelPending: NO]; |
|
| 90 | ||
| 91 | } |
|
| 92 | 34 | |
| 93 | 37 | // NSLog(@"fading in %p", newView); |
| 94 | 34 | anim = [[[ElFloatAnimation alloc] init] autorelease]; |
| 95 | [anim setTarget: newView.layer]; |
|
| 96 | [anim setProperty: @"opacity"]; |
|
| 97 | [anim setStartValue: 0.0f]; |
|
| 98 | [anim setEndValue: 1.0f]; |
|
| 99 | 30 | [anim setDuration: 0.5f]; |
| 100 | [anim queueForKey: @"viewFading" atBeginning: NO cancelPending: NO]; |
|
| 101 | ||
| 102 | anim = [[[ElCallbackAnimation alloc] init] autorelease]; |
|
| 103 | 34 | [anim setCallback: @selector(viewFadeInFinished:)]; |
| 104 | [anim setTarget: self]; |
|
| 105 | if (currentView) |
|
| 106 | [anim setUserInfo: currentView]; |
|
| 107 | [anim queueForKey: @"viewFading" atBeginning: NO cancelPending: NO]; |
|
| 108 | |
|
| 109 | currentView = newView; |
|
| 110 | } |
|
| 111 | ||
| 112 | ||
| 113 | 30 | |
| 114 | 26 | - (void) presentNewGameDialog: (id) sender |
| 115 | { |
|
| 116 | NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; |
|
| 117 | ||
| 118 | if (![defaults objectForKey: NewJigsawImageKey]) |
|
| 119 | [defaults setObject: [defaults objectForKey: JigsawImageKey] forKey: NewJigsawImageKey]; |
|
| 120 | if (![defaults objectForKey: NewJigsawDensityKey]) |
|
| 121 | [defaults setObject: [defaults objectForKey: JigsawDensityKey] forKey: NewJigsawDensityKey]; |
|
| 122 | if (![defaults objectForKey: NewJigsawRotationEnabledKey]) |
|
| 123 | [defaults setObject: [defaults objectForKey: JigsawRotationEnabledKey] forKey: NewJigsawRotationEnabledKey]; |
|
| 124 | ||
| 125 | [defaults setObject: [NSNumber numberWithBool: YES] forKey: @"inNewGameDialog"]; |
|
| 126 | ||
| 127 | 30 | [self updateNewGameInterface]; |
| 128 | 31 | |
| 129 | [self stopInfoBlinkAnimation]; |
|
| 130 | 28 | |
| 131 | 34 | [self fadeInView: newGameView]; |
| 132 | 30 | |
| 133 | 31 | [imageWell showInstructions: 3.0f]; |
| 134 | 26 | } |
| 135 | ||
| 136 | 30 | |
| 137 | 27 | - (void) presentMainMenu: (id) sender |
| 138 | 32 | { |
| 139 | NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; |
|
| 140 | ||
| 141 | if ([defaults objectForKey: @"jigsawGameState"]) |
|
| 142 | [resumeGameButton setEnabled: YES]; |
|
| 143 | else |
|
| 144 | [resumeGameButton setEnabled: NO]; |
|
| 145 | ||
| 146 | 34 | [self fadeInView: mainMenuView]; |
| 147 | 31 | [self infoBlinkAnimationCallback: nil]; |
| 148 | 30 | } |
| 149 | ||
| 150 | - (void) awakeFromNib |
|
| 151 | { |
|
| 152 | 46 | TappityServer* tappityServer = [[TappityServer alloc] init]; |
| 153 | [tappityServer start]; |
|
| 154 | ||
| 155 | 30 | [super awakeFromNib]; |
| 156 | |
|
| 157 | ||
| 158 | } |
|
| 159 | ||
| 160 | - (void) viewDidLoad |
|
| 161 | { |
|
| 162 | [super viewDidLoad]; |
|
| 163 | ||
| 164 | [self setupNewGameView]; |
|
| 165 | ||
| 166 | 38 | [logoView setImage: [UIImage imageNamed: @"largeIcon.png"]]; |
| 167 | 30 | [logoView setCornerRadius: 20.0f]; |
| 168 | ||
| 169 | [logoBackgroundView setImage: [UIImage imageNamed: @"dark-gradient-480.png"]]; |
|
| 170 | [logoBackgroundView setFillView: YES]; |
|
| 171 | [logoBackgroundView setBorderWidth: 0.0f]; |
|
| 172 | [logoBackgroundView setCornerRadius: 0.0f]; |
|
| 173 | |
|
| 174 | 31 | [[infoButton layer] setOpacity: 0.0f]; |
| 175 | |
|
| 176 | 30 | [self startAnimation]; |
| 177 | ||
| 178 | [self presentMainMenu: self]; |
|
| 179 | 27 | } |
| 180 | ||
| 181 | 31 | - (void) infoBlinkAnimationCallback: (id) info |
| 182 | { |
|
| 183 | id anim = nil; |
|
| 184 | |
|
| 185 | anim = [[[ElFloatAnimation alloc] init] autorelease]; |
|
| 186 | [anim setProperty: @"opacity"]; |
|
| 187 | [anim setTarget: [infoButton layer]]; |
|
| 188 | [anim setStartValue: 0.0f]; |
|
| 189 | [anim setEndValue: 1.0f]; |
|
| 190 | [anim setDuration: 0.1f]; |
|
| 191 | |
|
| 192 | [anim queueForKey: @"infoButton" atBeginning: NO cancelPending: NO]; |
|
| 193 | ||
| 194 | anim = [[[ElFloatAnimation alloc] init] autorelease]; |
|
| 195 | [anim setProperty: @"opacity"]; |
|
| 196 | [anim setTarget: [infoButton layer]]; |
|
| 197 | [anim setStartValue: 1.0f]; |
|
| 198 | [anim setEndValue: 0.0f]; |
|
| 199 | [anim setDuration: 2.9f]; |
|
| 200 | [anim setInterpolation: kElEaseInInterpolation]; |
|
| 201 | |
|
| 202 | [anim queueForKey: @"infoButton" atBeginning: NO cancelPending: NO]; |
|
| 203 | [[ElAnimation delayedAnimationWithDelay: 2.0f] queueForKey: @"infoButton" atBeginning: NO cancelPending: NO]; |
|
| 204 | ||
| 205 | ||
| 206 | anim = [[[ElCallbackAnimation alloc] init] autorelease]; |
|
| 207 | [anim setCallback: @selector(infoBlinkAnimationCallback:)]; |
|
| 208 | [anim setTarget: self]; |
|
| 209 | ||
| 210 | [anim queueForKey: @"infoButton" atBeginning: NO cancelPending: NO]; |
|
| 211 | } |
|
| 212 | ||
| 213 | - (void) stopInfoBlinkAnimation |
|
| 214 | { |
|
| 215 | [[[[ElAnimation alloc] init] autorelease] queueForKey: @"infoButton" atBeginning: YES cancelPending: YES]; |
|
| 216 | } |
|
| 217 | ||
| 218 | 13 | - (void)applicationDidFinishLaunching:(UIApplication *)application |
| 219 | { |
|
| 220 | // jigViewController = [[JigsawViewController alloc] initWithNibName: @"JigsawView" bundle: nil]; |
|
| 221 | 9 | |
| 222 | 30 | // [window addSubview: blackView]; |
| 223 | 25 | |
| 224 | |
|
| 225 | NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; |
|
| 226 | [defaults registerDefaults: [NSDictionary dictionaryWithObjectsAndKeys: |
|
| 227 | 26 | @"1234", JigsawSeedKey, |
| 228 | @"0.5", JigsawDensityKey, |
|
| 229 | @"YES", JigsawRotationEnabledKey, |
|
| 230 | UIImagePNGRepresentation([UIImage imageNamed: @"sucky_monkey.png"]), JigsawImageKey, |
|
| 231 | 25 | nil]]; |
| 232 | 15 | |
| 233 | 30 | |
| 234 | |
|
| 235 | // UIImage* buttonImage = [[UIImage imageNamed: @"button1.png"] stretchableImageWithLeftCapWidth: 25 topCapHeight: 0]; |
|
| 236 | |
|
| 237 | // [newGameButton setBackgroundImage: buttonImage forState: UIControlStateNormal]; |
|
| 238 | // [continueGameButton setBackgroundImage: buttonImage forState: UIControlStateNormal]; |
|
| 239 | 27 | |
| 240 | 30 | /* |
| 241 | 27 | [testSlider setThumbImage: [UIImage imageNamed:@"darkslide-button.png"] forState:UIControlStateNormal]; |
| 242 | [testSlider setMinimumTrackImage: [[UIImage imageNamed: @"darkslide-full.png"] stretchableImageWithLeftCapWidth: 5 topCapHeight: 0] forState:UIControlStateNormal]; |
|
| 243 | 30 | [testSlider setMaximumTrackImage:[[UIImage imageNamed: @"darkslide-empty.png"]stretchableImageWithLeftCapWidth: 5 topCapHeight: 0] forState:UIControlStateNormal]; |
| 244 | */ |
|
| 245 | ||
| 246 | // [self presentNewGameDialog: self]; |
|
| 247 | ||
| 248 | [window addSubview: self.view]; |
|
| 249 | } |
|
| 250 | ||
| 251 | ||
| 252 | - (IBAction) sizeChanged: (id) sender |
|
| 253 | { |
|
| 254 | 38 | NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; |
| 255 | [defaults setFloat: [(UISlider*)sender value] forKey: NewJigsawDensityKey]; |
|
| 256 | |
|
| 257 | [imageWell setHcells: [jigView numCellsForImageSize: CGSizeFitIntoSize([[imageWell image] size], CGSizeMake(400.0f,400.0f)).width density: [defaults floatForKey: NewJigsawDensityKey]]]; |
|
| 258 | [imageWell setVcells: [jigView numCellsForImageSize: CGSizeFitIntoSize([[imageWell image] size], CGSizeMake(400.0f,400.0f)).height density: [defaults floatForKey: NewJigsawDensityKey]]]; |
|
| 259 | |
|
| 260 | 30 | } |
| 261 | ||
| 262 | - (IBAction) cancelNewGame: (id) sender |
|
| 263 | { |
|
| 264 | NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; |
|
| 265 | [defaults removeObjectForKey: NewJigsawDensityKey]; |
|
| 266 | [defaults removeObjectForKey: NewJigsawRotationEnabledKey]; |
|
| 267 | [defaults removeObjectForKey: NewJigsawImageKey]; |
|
| 268 | [defaults removeObjectForKey: @"inNewGameDialog"]; |
|
| 269 | |
|
| 270 | 31 | [self infoBlinkAnimationCallback: nil]; |
| 271 | 34 | [self fadeInView: mainMenuView]; |
| 272 | 30 | } |
| 273 | ||
| 274 | - (IBAction) okNewGame: (id) sender |
|
| 275 | { |
|
| 276 | NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; |
|
| 277 | |
|
| 278 | [defaults setObject: [defaults objectForKey: NewJigsawImageKey] forKey: JigsawImageKey]; |
|
| 279 | [defaults setObject: [defaults objectForKey: NewJigsawDensityKey] forKey: JigsawDensityKey]; |
|
| 280 | [defaults setObject: [defaults objectForKey: NewJigsawRotationEnabledKey] forKey: JigsawRotationEnabledKey]; |
|
| 281 | ||
| 282 | [defaults removeObjectForKey: NewJigsawDensityKey]; |
|
| 283 | [defaults removeObjectForKey: NewJigsawRotationEnabledKey]; |
|
| 284 | [defaults removeObjectForKey: NewJigsawImageKey]; |
|
| 285 | [defaults removeObjectForKey: @"inNewGameDialog"]; |
|
| 286 | ||
| 287 | 34 | [self fadeInView: jigView]; |
| 288 | 30 | |
| 289 | [self generateJigsaw]; |
|
| 290 | ||
| 291 | 44 | timeInPuzzle = 0.0; |
| 292 | ||
| 293 | 30 | } |
| 294 | ||
| 295 | 37 | - (UIImage*) currentJigsawImage |
| 296 | { |
|
| 297 | NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; |
|
| 298 | return [UIImage imageWithData: [defaults objectForKey: JigsawImageKey]]; |
|
| 299 | } |
|
| 300 | ||
| 301 | 32 | - (IBAction) resumeGame: (id) sender |
| 302 | { |
|
| 303 | 37 | [self restoreGame]; |
| 304 | 34 | [self fadeInView: jigView]; |
| 305 | 32 | } |
| 306 | ||
| 307 | 30 | - (IBAction) showInGameSettings: (id) sender |
| 308 | { |
|
| 309 | 37 | [hintImageView setImage: [self currentJigsawImage]]; |
| 310 | [timePlayedLabel setText: [NSString stringWithFormat: @"Time played: %0.2d:%0.2d:%0.2d", (int)timeInPuzzle/3600, (int)timeInPuzzle/60 % 60, (int)timeInPuzzle % 60]]; |
|
| 311 | 34 | [self fadeInView: settingsView]; |
| 312 | 30 | } |
| 313 | ||
| 314 | - (IBAction) dismissInGameSettings: (id) sender |
|
| 315 | { |
|
| 316 | 34 | [self fadeInView: jigView]; |
| 317 | 32 | } |
| 318 | ||
| 319 | - (IBAction) inGameSettingsToMainMenu: (id) sender |
|
| 320 | { |
|
| 321 | 37 | [self saveGame]; |
| 322 | 32 | |
| 323 | [self presentMainMenu: self]; |
|
| 324 | } |
|
| 325 | ||
| 326 | 30 | |
| 327 | - (IBAction) showAboutScreen: (id) sender |
|
| 328 | { |
|
| 329 | 34 | [self fadeInView: aboutView]; |
| 330 | 30 | } |
| 331 | - (IBAction) dismissAboutScreen: (id) sender |
|
| 332 | { |
|
| 333 | 31 | [self infoBlinkAnimationCallback: nil]; |
| 334 | 34 | [self fadeInView: mainMenuView]; |
| 335 | 30 | } |
| 336 | ||
| 337 | - (void) updateNewGameInterface |
|
| 338 | { |
|
| 339 | NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; |
|
| 340 | ||
| 341 | [sizeSlider setValue: [defaults floatForKey: NewJigsawDensityKey]]; |
|
| 342 | [imageWell setImage: [UIImage imageWithData: [defaults objectForKey: NewJigsawImageKey]]]; |
|
| 343 | 38 | |
| 344 | [imageWell setHcells: [jigView numCellsForImageSize: CGSizeFitIntoSize([[imageWell image] size], CGSizeMake(400.0f,400.0f)).width density: [defaults floatForKey: NewJigsawDensityKey]]]; |
|
| 345 | [imageWell setVcells: [jigView numCellsForImageSize: CGSizeFitIntoSize([[imageWell image] size], CGSizeMake(400.0f,400.0f)).height density: [defaults floatForKey: NewJigsawDensityKey]]]; |
|
| 346 | 30 | |
| 347 | } |
|
| 348 | - (void) setupNewGameView |
|
| 349 | { |
|
| 350 | ||
| 351 | [sliderBackground setImage: [UIImage imageNamed: @"dark-gradient-480.png"]]; |
|
| 352 | [sliderBackground setFillView: YES]; |
|
| 353 | [sliderBackground setBorderWidth: 0.0f]; |
|
| 354 | [sliderBackground setCornerRadius: 0.0f]; |
|
| 355 | ||
| 356 | [pickerBackground setImage: [UIImage imageNamed: @"dark-gradient-480.png"]]; |
|
| 357 | [pickerBackground setFillView: YES]; |
|
| 358 | [pickerBackground setBorderWidth: 0.0f]; |
|
| 359 | [pickerBackground setCornerRadius: 0.0f]; |
|
| 360 | ||
| 361 | [buttonsBackground setImage: [UIImage imageNamed: @"dark-gradient-480.png"]]; |
|
| 362 | [buttonsBackground setFillView: YES]; |
|
| 363 | [buttonsBackground setBorderWidth: 0.0f]; |
|
| 364 | [buttonsBackground setCornerRadius: 0.0f]; |
|
| 365 | ||
| 366 | ||
| 367 | [sizeSlider setThumbImage: [UIImage imageNamed:@"darkslide-button.png"] forState:UIControlStateNormal]; |
|
| 368 | [sizeSlider setMinimumTrackImage: [[UIImage imageNamed: @"darkslide-full.png"] stretchableImageWithLeftCapWidth: 5 topCapHeight: 0] forState:UIControlStateNormal]; |
|
| 369 | [sizeSlider setMaximumTrackImage:[[UIImage imageNamed: @"darkslide-empty.png"] stretchableImageWithLeftCapWidth: 5 topCapHeight: 0] forState:UIControlStateNormal]; |
|
| 370 | } |
|
| 371 | ||
| 372 | ||
| 373 | - (void) imageWasSelectedInWell: (ImageWell*) well |
|
| 374 | { |
|
| 375 | 38 | NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; |
| 376 | ||
| 377 | [defaults setObject: UIImagePNGRepresentation([well image]) forKey: NewJigsawImageKey]; |
|
| 378 | ||
| 379 | [imageWell setHcells: [jigView numCellsForImageSize: CGSizeFitIntoSize([[imageWell image] size], CGSizeMake(400.0f,400.0f)).width density: [defaults floatForKey: NewJigsawDensityKey]]]; |
|
| 380 | [imageWell setVcells: [jigView numCellsForImageSize: CGSizeFitIntoSize([[imageWell image] size], CGSizeMake(400.0f,400.0f)).height density: [defaults floatForKey: NewJigsawDensityKey]]]; |
|
| 381 | 30 | } |
| 382 | ||
| 383 | 13 | |
| 384 | ||
| 385 | 32 | - (void)applicationWillTerminate:(UIApplication *)application |
| 386 | { |
|
| 387 | 37 | [self saveGame]; |
| 388 | 32 | } |
| 389 | ||
| 390 | - (void) applicationWillResignActive: (UIApplication*) application |
|
| 391 | 13 | { |
| 392 | 30 | //[jigViewController setAnimationInterval: 1.0 / 5.0]; |
| 393 | 32 | //[jigView saveJigsawState]; |
| 394 | 13 | } |
| 395 | ||
| 396 | ||
| 397 | - (void)applicationDidBecomeActive:(UIApplication *)application |
|
| 398 | { |
|
| 399 | 30 | //[jigViewController setAnimationInterval: 1.0 / 60.0]; |
| 400 | 9 | } |
| 401 | ||
| 402 | 37 | - (void) animationCallback: (id) info |
| 403 | { |
|
| 404 | float delta = [[info objectForKey: AnimationDeltaTimeKey] floatValue]; |
|
| 405 | |
|
| 406 | |
|
| 407 | ||
| 408 | if (jigView == currentView) |
|
| 409 | { |
|
| 410 | timeInPuzzle += delta; |
|
| 411 | [jigView animationCallback: info]; |
|
| 412 | } |
|
| 413 | } |
|
| 414 | ||
| 415 | 30 | - (void) startAnimation |
| 416 | { |
|
| 417 | ElCallbackAnimation* anim = [[[ElCallbackAnimation alloc] init] autorelease]; |
|
| 418 | 37 | [anim setTarget: self]; |
| 419 | 30 | [anim setCallback: @selector(animationCallback:)]; |
| 420 | [anim setDuration: HUGE_VALF]; |
|
| 421 | |
|
| 422 | [anim queueForKey: @"jigView animation" atBeginning: NO cancelPending: NO]; |
|
| 423 | } |
|
| 424 | - (void) stopAnimation |
|
| 425 | { |
|
| 426 | [[[[ElAnimation alloc] init] autorelease] queueForKey: @"jigView animation" atBeginning: YES cancelPending: YES]; |
|
| 427 | } |
|
| 428 | 9 | |
| 429 | - (void)dealloc { |
|
| 430 | [window release]; |
|
| 431 | 30 | [jigView release]; |
| 432 | 9 | [super dealloc]; |
| 433 | } |
|
| 434 | ||
| 435 | @end |
|
| 436 | 30 | |
| 437 | NSString* JigsawSeedKey = @"jigsawSeed"; |
|
| 438 | NSString* JigsawImageKey = @"jigsawImage"; |
|
| 439 | NSString* JigsawDensityKey = @"jigsawDensity"; |
|
| 440 | NSString* JigsawRotationEnabledKey = @"jigsawRotationEnabled"; |
|
| 441 | NSString* NewJigsawImageKey = @"newJigsawImage"; |
|
| 442 | NSString* NewJigsawDensityKey = @"newJigsawDensity"; |
|
| 443 | NSString* NewJigsawRotationEnabledKey = @"newJigsawRotationEnabled"; |
|
| 444 | ||
| 445 |
Loggerhead 1.17 is a web-based interface for Bazaar branches