Sei sulla pagina 1di 27

//

// TextureAtlasViewController.m
// Game Landscaper
//
// Created by Saro Bear on 6/4/14.
// Copyright (c) 2015 Bear Love Studio LLP. All rights reserved.
//

#import <Photos/PhotosTypes.h>
#import <Photos/PHImageManager.h>
#import <Photos/Photos.h>

#import "TextureAtlasController.h"
#import "TextureAtlasHeaderController.h"
#import "TextureAtlasCanvasController.h"
#import "AtlasExportViewController.h"
#import "AtlasPropertyController.h"
#import "AtlasAssetsController.h"
#import "AtlasUtilityController.h"
#import "TextureAtlasDelegate.h"
#import "LaerExternalController.h"
#import "Utilities.h"
#import "Global.h"
#import "BrowserAsset.h"
#import "BearActivityIndicator.h"

#import "LaerDataManager.h"
#import "LaerAssetCD+CoreDataClass.h"
#import "AssetEntityCD+CoreDataClass.h"
#import "LaerProductCD+CoreDataClass.h"
#import "ScaleVariantsCD+CoreDataClass.h"

#import "MemoryLoadingView.h"
#import "UIImage+Resize.h"

#import "MagickWand.h"
#import "AtlasCreator.h"

#define SEGUE_ID_ATLAS_HEADER @"atlas_header_controller"


#define SEGUE_ID_ATLAS_SETTINGS @"atlas_settings_controller"
#define SEGUE_ID_ATLAS_ASSETS @"atlas_assets_controller"
#define SEGUE_ID_ATLAS_UTILITIES @"atlas_utilities_controller"

#define STORYBOARD_ID_CANVAS_CONTROLLER
@"texture_canvas_controller"
#define STORYBOARD_ID_EXPORT_CONTROLLER
@"atlas_export_controller"

#define STORYBOARD_ID_CAMERA_CONTROLLER @"camera_controller"


#define STORYBOARD_ID_ALBUM_CONTROLLER @"album_controller"
#define STORYBOARD_ID_BROWSE_CONTROLLER @"browse_controller"
#define STORYBOARD_ID_DROPBOX_CONTROLLER @"dropbox_controller"
#define SEGUE_ID_LANDSCAPER_HEADER @"landscaper_header"
#define SEGUE_ID_LANDSCAPER_ASSETS @"landscaper_assets"
#define SEGUE_ID_LANDSCAPER_PROPERTIES @"landscaper_properties"
#define SEGUE_ID_LANDSCAPER_COMPONENTS
@"landscaper_components"

#define SETTINGS_WINDOW_HIDDEN 250.0f


#define SETTINGS_WINDOW_SHOW 7.0f

#define ASSETS_WINDOW_HIDDEN 250.0f


#define ASSETS_WINDOW_SHOW 7.0f

#define UTILITY_WINDOW_HIDDEN 80.0f

@interface TextureAtlasController () <TextureAtlasDelegate,


UIGestureRecognizerDelegate, AtlasExportDelegate>

@property (nonatomic, weak) TextureAtlasHeaderController


*headerController;
@property (nonatomic, weak) AtlasPropertyController *settingsController;
@property (nonatomic, weak) AtlasAssetsController *assetsController;
@property (nonatomic, weak) AtlasUtilityController *utilitiesController;

@property (nonatomic, strong) LaerExternalController *externalController;


@property (nonatomic, strong) TextureAtlasCanvasController
*canvasController;
@property (nonatomic, strong) TextureAtlasCD *atlasCD;
@property (nonatomic, strong) MemoryLoadingView
*memoryLoadingView;

@property (nonatomic, weak) IBOutlet UIView *settingsContainer;


@property (nonatomic, weak) IBOutlet UIView *assetsContainer;
@property (nonatomic, weak) IBOutlet UIImageView *bgImageView;
@property (nonatomic, weak) IBOutlet NSLayoutConstraint
*settingsTrailCons;
@property (nonatomic, weak) IBOutlet NSLayoutConstraint *assetsTrailCons;
@property (nonatomic, weak) IBOutlet NSLayoutConstraint *utilityTrailCons;
@property (nonatomic, weak) IBOutlet BearActivityIndicator *bearActInd;

@property (nonatomic, strong) NSMutableArray *importAssets;


@property (nonatomic, assign) NSInteger totalImportCount;

@property (nonatomic, assign) CGFloat binWidth;


@property (nonatomic, assign) CGFloat binHeight;
@property (nonatomic, assign) NSInteger curScreen;
@property (nonatomic, assign) BOOL didQuit;
@property (nonatomic, assign) BOOL isMemoryUp;

@end

typedef void (^saveImage)(BOOL success);


@implementation TextureAtlasController

#pragma mark - private methods


-(void)showError:(NSString*)msg
{
UIAlertController *alertView = [UIAlertController
alertControllerWithTitle:@"Alert" message:msg
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"Ok"
style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {}];
[alertView addAction:alertAction];
[self presentViewController:alertView animated:YES completion:nil];
}

-(void)memoryAlert
{
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:@"Warning" message:@"Device resources are becomig
expensive which may cause the app to crash! Do you still want to continue ?"
preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *yesAction = [UIAlertAction actionWithTitle:@"Yes!"


style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action)
{
_didQuit = NO;
_isMemoryUp = NO;
[self startImportAssets];
}];

UIAlertAction *cacelAction = [UIAlertAction actionWithTitle:@"No"


style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action)
{
[_bearActInd stopAnimation];
_isMemoryUp = NO;
_didQuit = YES;
}];

[alertController addAction:yesAction];
[alertController addAction:cacelAction];
[self presentViewController:alertController animated:YES completion:^ {

}];
}

-(void)layoutChildrens
{
if(!_canvasController) return;

[[_canvasController view] setCenter:CGPointMake(self.view.bounds.size.width


* 0.5f, self.view.bounds.size.height * 0.5f)];
[self.view insertSubview:_canvasController.view
aboveSubview:_bgImageView];

[self updateTexture];
}

-(void)addGestures
{
if(!_canvasController) {
return;
}

UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc]


initWithTarget:self action:@selector(pinchGestureHandler:)];
[pinchGesture setDelegate:self];
[self.view addGestureRecognizer:pinchGesture];

UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc]


initWithTarget:self action:@selector(panGestureHandler:)];
[panGesture setDelegate:self];
[self.view addGestureRecognizer:panGesture];
}

-(void)cleanup
{
NSArray *gestures = [self.view gestureRecognizers];

for (UIGestureRecognizer *gesture in gestures) {


[self.view removeGestureRecognizer:gesture];
}

if(_canvasController)
{
[_canvasController removeFromParentViewController];
[_canvasController didMoveToParentViewController:nil];
[_canvasController.view removeFromSuperview];
}
_canvasController = nil;
}

-(void)initialize
{
_canvasController = (TextureAtlasCanvasController*)[Utilities
getController:STORYBOARD_ID_CANVAS_CONTROLLER];
[_canvasController setDelegate:self];
[_canvasController.view setFrame:CGRectMake(0.0f, 0.0f, [_atlasCD.width
floatValue], [_atlasCD.height floatValue])];
[self addChildViewController:_canvasController];

[self addGestures];
}

-(NSUInteger)getMaxIndexId
{
LaerDataManager *dataManager = [LaerDataManager sharedInstance];
return [dataManager fetchMaxValue:NSStringFromClass([AssetEntityCD class])
predicate:[NSPredicate predicateWithFormat:@"product.productName = %@",
[self currentProductName]] property:@"indexId"];
}

-(void)addAsset:(NSString*)asset
{
LaerDataManager *dataManager = [LaerDataManager sharedInstance];

//get the asset id


NSUInteger indexId = [self getMaxIndexId] + 1;

CGFloat width = 0.0f;


CGFloat height = 0.0f;

ssize_t trimX = 0;
ssize_t trimY = 0;
size_t trimW = 0;
size_t trimH = 0;

MagickWandGenesis();
MagickWand *wand = NewMagickWand();

double trimValue = MIN([[_atlasCD trimOpacity] doubleValue], 90);


NSString *imagePath = [Utilities getImageLocation:[self currentProductName]
assetName:asset];

MagickBooleanType status = MagickReadImage(wand, [imagePath


UTF8String]);
if(status == MagickTrue)
{
width = MagickGetImageWidth(wand); //original width
height = MagickGetImageHeight(wand); //original height

PixelWand *color = NewPixelWand();


status = PixelSetColor(color, "none");
if(status)
{
status = MagickSetImageBorderColor(wand, color);
if(status)
{
status = MagickBorderImage(wand, color, 10, 10);
if(status)
{
status = MagickTrimImage(wand, trimValue);
if(status)
{
MagickGetImagePage(wand, &trimW, &trimH, &trimX, &trimY);

trimW = MagickGetImageWidth(wand); //trim width


trimH = MagickGetImageHeight(wand); //trim height
trimX = MAX(0, (trimX - 10));
trimY = MAX(0, (trimY - 10));
}
}
}
}

DestroyPixelWand(color);
}

wand = DestroyMagickWand(wand);
MagickWandTerminus();

//update into the CD


LaerProductCD *productCD = [dataManager
fetchEntity:NSStringFromClass([LaerProductCD class]) property:@"productName"
andValue:[self currentProductName]
andResultType:NSManagedObjectResultType];

NSPredicate *predicate = [NSPredicate


predicateWithFormat:@"product.productName = %@ AND fileName = %@", [self
currentProductName], asset];

LaerAssetCD *assetCD = [dataManager


fetchEntity:NSStringFromClass([LaerAssetCD class]) withPredicate:predicate
andResultType:NSManagedObjectResultType];

if(!assetCD)
{
assetCD = [NSEntityDescription
insertNewObjectForEntityForName:NSStringFromClass([LaerAssetCD class])
inManagedObjectContext:[dataManager getObjectContext]];
[assetCD setFileName:[asset lastPathComponent]];
[assetCD setWidth:[NSNumber numberWithFloat:width]];
[assetCD setHeight:[NSNumber numberWithFloat:height]];
[assetCD setTrimX:[NSNumber numberWithFloat:trimX]];
[assetCD setTrimY:[NSNumber numberWithFloat:trimY]];
[assetCD setTrimHeight:[NSNumber numberWithFloat:trimH]];
[assetCD setTrimWidth:[NSNumber numberWithFloat:trimW]];

[assetCD setProduct:productCD];
}

AssetEntityCD *assetEntity = [NSEntityDescription


insertNewObjectForEntityForName:NSStringFromClass([AssetEntityCD class])
inManagedObjectContext:[dataManager getObjectContext]];
[assetEntity setIndexId:[NSNumber numberWithInteger:indexId]];
[assetEntity setEntityId:[[asset lastPathComponent]
stringByDeletingPathExtension]];
[assetEntity setX:[NSNumber numberWithFloat:0]];
[assetEntity setY:[NSNumber numberWithFloat:0]];

[assetEntity setAsset:assetCD];
[assetEntity setProduct:productCD];

BOOL isSuccess = [dataManager save];


if(!isSuccess) {
[self showError:@"File system error!"];
}
}

-(void)startImportAssets
{
if(_isMemoryUp)
{
[self memoryAlert];
return;
}

if(_didQuit)
{
[_importAssets removeAllObjects];
_importAssets = nil;

[self updateTexture];

return;
}

//initialise the progress bar on the object downloader


[self saveAsset:^(BOOL success)
{
if(!success) {
//TODO::collect the failed assets
}

id asset = [_importAssets lastObject];


NSString *newAsset = nil;

if([asset isKindOfClass:[BrowserAsset class]])


{
BrowserAsset *browseAsset = (BrowserAsset*)asset;
if(![browseAsset fileName]) {
[browseAsset setFileName:[[browseAsset filePath]
lastPathComponent]];
}

NSString *fileName = [browseAsset fileName];


newAsset = [LANDSCAPER_THUMB_ID
stringByAppendingString:fileName];
}
else {
newAsset = asset;
}

[_importAssets removeLastObject];

[self addAsset:[newAsset
stringByReplacingOccurrencesOfString:LANDSCAPER_THUMB_ID withString:@""]];
[self updateTexture];

if([_importAssets count]) {
[self performSelector:@selector(startImportAssets) withObject:NULL
afterDelay:0.1f];
}
else
{
[_importAssets removeAllObjects];
_importAssets = nil;
}
}];
}

-(void)saveCameraAsset:(saveImage)isSuccess
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,
0), ^
{
NSString *thumbName = [_importAssets lastObject];
NSString *thumbLocation = [Utilities getCameraShotThumbLocation:[self
currentProductName] usingThumbName:thumbName];
NSString *origLocation = [thumbLocation
stringByReplacingOccurrencesOfString:LANDSCAPER_THUMB_ID withString:@""];

UIImage *thumbImage = [UIImage


imageWithContentsOfFile:thumbLocation];
UIImage *thumb = [thumbImage
imageByScalingProportionallyToSize:THUMBNAIL_SIZE([[UIScreen mainScreen]
scale])];
NSData *thumbData = UIImagePNGRepresentation(thumb);

dispatch_sync(dispatch_get_main_queue(), ^
{
if([Utilities moveIntoImagesPath:[self currentProductName]
filePath:origLocation])
{
if([Utilities saveIntoImagesPath:[self currentProductName] fileName:
[NSString stringWithFormat:@"%@%@",LANDSCAPER_THUMB_ID,[origLocation
lastPathComponent]] file:thumbData])
{
[Utilities deleteFromCameraPath:[self currentProductName]
fileName:thumbName];
isSuccess(YES);
}
else {
isSuccess(NO);
}
}
else {
isSuccess(NO);
}
});
});
}

CGImageRef createStandardImage(CGImageRef image)


{
const size_t width = CGImageGetWidth(image);
const size_t height = CGImageGetHeight(image);
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(NULL, width, height, 8, 4*width,
space,
kCGBitmapByteOrder32Big |
kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(space);
CGContextDrawImage(ctx, CGRectMake(0, 0, width, height), image);
CGImageRef dstImage = CGBitmapContextCreateImage(ctx);
CGContextRelease(ctx);

return dstImage;
}

-(void)saveBrowseAsset:(saveImage)isSuccess
{
BrowserAsset *asset = [_importAssets lastObject];
NSString *fileName = [asset fileName];
NSString *thumbPath = [Utilities getImageLocationPlaceHolder:[self
currentProductName] assetName:[NSString stringWithFormat:@"%@
%@",LANDSCAPER_THUMB_ID, fileName]];

if([asset albumType] == EXTERNAL_BROWSER_TYPE_ALBUM_IMPORT)


{
PHAsset *phAsset = [[PHAsset
fetchAssetsWithLocalIdentifiers:@[asset.filePath] options:nil] firstObject];
[[PHImageManager defaultManager] requestImageForAsset:(PHAsset
*)phAsset targetSize:PHImageManagerMaximumSize
contentMode:PHImageContentModeDefault options:nil resultHandler:^(UIImage
*result, NSDictionary *info)
{
NSData *origData = UIImagePNGRepresentation(result);

//dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,
0), ^
//{
MagickWandGenesis();
MagickWand *wand = NewMagickWand();
MagickBooleanType status = MagickReadImageBlob(wand, [origData
bytes], [origData length]);

if(status == MagickTrue)
{
NSString *filePath = [Utilities getImageLocationPlaceHolder:[self
currentProductName] assetName:fileName];
status = MagickWriteImage(wand, [filePath UTF8String]);
if(status == MagickTrue)
{
CGSize targetSize = [Utilities
getAspectSize:CGSizeMake(MagickGetImageWidth(wand),
MagickGetImageHeight(wand)) andSize:CGSizeMake(THUMBNAIL_AREA(0),
THUMBNAIL_AREA(0))];

status = MagickThumbnailImage(wand, targetSize.width,


targetSize.height);

if(status == MagickTrue) {
status = MagickWriteImage(wand, [thumbPath UTF8String]);
}
}
}

wand = DestroyMagickWand(wand);
MagickWandTerminus();

// dispatch_sync(dispatch_get_main_queue(), ^ {
isSuccess(status);
//});
///});
}];
}
else
{
//
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,
0), ^
// {
MagickCoreGenesis("", MagickFalse);

ImageInfo *imageInfo = AcquireImageInfo();


ExceptionInfo *exceptionInfo = AcquireExceptionInfo();

// Get image from bundle.


char *input_image = strdup([[asset filePath] UTF8String]);
char *output_image = strdup([thumbPath UTF8String]);
char *size = strdup([[NSString stringWithFormat:@"%dx",
(int)THUMBNAIL_AREA(0)] UTF8String]);

char *argv[] = {strdup("convert"), strdup("-density"), strdup("1200"),


input_image, output_image, NULL}; //{strdup("convert"), input_image, strdup("-
resize"), size, output_image, NULL};

MagickBooleanType status = ConvertImageCommand(imageInfo, 5, argv,


NULL, exceptionInfo);
if (exceptionInfo->severity != UndefinedException)
{
status = MagickTrue;
CatchException(exceptionInfo);
}
else {
status = MagickTrue;
}

imageInfo = DestroyImageInfo(imageInfo);
exceptionInfo = DestroyExceptionInfo(exceptionInfo);

MagickCoreTerminus();

if(status == MagickTrue)
{
BOOL success = NO;
if([asset albumType] == EXTERNAL_BROWSER_TYPE_ITUNES_IMPORT)
{
NSData *outData = [NSData dataWithContentsOfFile:[asset
filePath]];
success = [Utilities saveIntoImagesPath:[self currentProductName]
fileName:fileName file:outData];
}
else {
success = [Utilities moveIntoImagesPath:[self currentProductName]
filePath:[asset filePath]];
}

// dispatch_sync(dispatch_get_main_queue(), ^ {
isSuccess(success);
// });
}
else
{
// dispatch_sync(dispatch_get_main_queue(), ^ {
isSuccess(status);
//});
}
// });
}
}

-(void)saveAsset:(saveImage)isSuccess
{
id asset = [_importAssets lastObject];

if([asset isKindOfClass:[BrowserAsset class]]) {


[self saveBrowseAsset:isSuccess];
}
else {
[self saveCameraAsset:isSuccess];
}
}

-(CGFloat)getScaleFromTransform:(CGAffineTransform)transform {
return sqrt(transform.a * transform.a + transform.c * transform.c);
}

-(NSString*)getBasicOrder:(int)order
{
NSString *orderStr = @"fileName";

switch (order)
{
case ATLAS_BASIC_ALGORITHM_WIDTH:
orderStr = @"width";
break;
case ATLAS_BASIC_ALGORITHM_HEIGHT:
orderStr = @"height";
break;
case ATLAS_BASIC_ALGORITHM_DEPTH:
orderStr = @"depth";
default:
break;
}

return orderStr;
}

-(void)prepareTexture
{
NSPredicate *predicate = [NSPredicate
predicateWithFormat:@"product.productName = %@ AND isSelected = 1",
self.currentProductName];

ScaleVariantsCD *variant = [[LaerDataManager sharedInstance]


fetchEntity:NSStringFromClass([ScaleVariantsCD class]) withPredicate:predicate
andResultType:NSManagedObjectResultType];

AtlasCreator *creator = [[AtlasCreator alloc] initWithProductName:[self


currentProductName]];
[creator prepareTextureForScale:variant withCompletionHandler:^(NSArray
*data)
{
NSString *fileLocation = data[0];
NSArray *usedAssets = data[1];
NSArray *wastedAssets = data[2];
NSNumber *size = data[3];

if(![fileLocation caseInsensitiveCompare:@"nil"]) {
[_headerController enableExportIcons:NO];
}
else
{
if([usedAssets count]) {
[_headerController enableExportIcons:YES];
}
else {
[_headerController enableExportIcons:NO];
}
}

[_assetsController setAssets:@[usedAssets, wastedAssets]];


[_canvasController drawTexture:fileLocation size:[size CGSizeValue]];
[_canvasController.view setCenter:[self.view center]];
[_settingsController updateCanvasSize:[size CGSizeValue]];

[self textureUpdated:fileLocation];
}];
}

-(void)trimImages
{
LaerDataManager *dataManager = [LaerDataManager sharedInstance];
NSPredicate *assetPredicate = [NSPredicate
predicateWithFormat:@"product.productName = %@ AND atlasEntry = YES",
[self currentProductName]];

NSArray *assets = [dataManager


fetchAllEntities:NSStringFromClass([LaerAssetCD class])
withSortKey:@"fileName" andOrder:YES withPredicate:assetPredicate
andResultType:NSManagedObjectResultType fetch:nil result:NO];

if(![assets count]) {
return;
}

MagickWandGenesis();
MagickWand *wand = NewMagickWand();

for (LaerAssetCD *asset in assets)


{
double trimValue = MIN([[_atlasCD trimOpacity] doubleValue], 90);
NSString *imagePath = [Utilities getImageLocation:[self
currentProductName] assetName:[asset fileName]];

CGFloat width = 0.0f;


CGFloat height = 0.0f;

ssize_t trimX = 0;
ssize_t trimY = 0;
size_t trimW = 0;
size_t trimH = 0;

MagickBooleanType status = MagickReadImage(wand, [imagePath


UTF8String]);
if(status == MagickTrue)
{
width = MagickGetImageWidth(wand); //original width
height = MagickGetImageHeight(wand); //original height

PixelWand *color = NewPixelWand();


status = PixelSetColor(color, "none");
if(status)
{
status = MagickSetImageBorderColor(wand, color);
if(status)
{
status = MagickBorderImage(wand, color, 10, 10);
if(status)
{
status = MagickTrimImage(wand, trimValue);

if(status)
{
MagickGetImagePage(wand, &trimW, &trimH, &trimX, &trimY);

trimW = MagickGetImageWidth(wand); //trim width


trimH = MagickGetImageHeight(wand); //trim height
trimX = MAX(0, (trimX - 10));
trimY = MAX(0, (trimY - 10));

[asset setTrimX:[NSNumber numberWithFloat:trimX]];


[asset setTrimY:[NSNumber numberWithFloat:trimY]];
[asset setTrimWidth:[NSNumber numberWithFloat:trimW]];
[asset setTrimHeight:[NSNumber numberWithFloat:trimH]];
}
}
}
}

DestroyPixelWand(color);
}
}

wand = DestroyMagickWand(wand);
MagickWandTerminus();

[[LaerDataManager sharedInstance] save];

[self updateTexture];
}

#pragma mark - public methods


-(LaerExternalController*)getScreenController:(NSInteger)screen
{
[self hideNavigationPanels];

UIViewController *controller = nil;

switch (screen)
{
case OPTION_ALBUM_SCREEN:
{
controller = [Utilities
getController:STORYBOARD_ID_BROWSE_CONTROLLER];
[(LaerExternalController*)controller
setBrowserType:EXTERNAL_BROWSER_TYPE_ALBUM_IMPORT];
}
break;
case OPTION_CAMERA_SCREEN:
{
controller = [Utilities
getController:STORYBOARD_ID_CAMERA_CONTROLLER];
}
break;
case OPTION_BROWSE_SCREEN:
{
controller = [Utilities
getController:STORYBOARD_ID_BROWSE_CONTROLLER];
[(LaerExternalController*)controller
setBrowserType:EXTERNAL_BROWSER_TYPE_ITUNES_IMPORT];
}
break;
case OPTION_DROPBOX_IMPORT_SCREEN:
{
controller = [Utilities
getController:STORYBOARD_ID_BROWSE_CONTROLLER];
[(LaerExternalController*)controller
setBrowserType:EXTERNAL_BROWSER_TYPE_DROPBOX_IMPORT];
}
break;
case OPTION_DROPBOX_EXPORT_SCREEN:
{
controller = [Utilities
getController:STORYBOARD_ID_BROWSE_CONTROLLER];
[(LaerExternalController*)controller
setBrowserType:EXTERNAL_BROWSER_TYPE_DROPBOX_EXPORT];
}
break;
default:
break;
}

if(controller)
{
[controller setTitle:[self currentProductName]];
[(LaerExternalController*)controller setDelegate:self];
}

return (LaerExternalController*)controller;
}

-(CGFloat)screenDelay:(NSInteger)screen
{
CGFloat delay = 0.0f;

switch (screen)
{
case OPTION_ALBUM_SCREEN:
delay = 0.1f;
break;
case OPTION_CAMERA_SCREEN:
delay = 0.3f;
break;
case OPTION_SHARE_SCREEN:
delay = 0.1f;
break;
case OPTION_BROWSE_SCREEN:
delay = 0.1f;
break;
default:
break;
}

return delay;
}

-(CGFloat)screenDuration:(NSInteger)screen
{
CGFloat duration = 1.0f;
return duration;
}

-(void)hideForNavigationPanels
{
if(_curScreen > 1) {
[self showScreen:_curScreen show:NO];
}
}

-(void)removeOldScreen {
[self showScreen:_curScreen show:NO];
}

-(void)showScreen:(NSInteger)screen show:(BOOL)show
{
if(show)
{
NSInteger prevScreen = _curScreen;
_curScreen = screen;

if(_externalController)
{
[_externalController.view removeFromSuperview];
[_externalController didMoveToParentViewController:nil];
[_externalController removeFromParentViewController];
_externalController = nil;

[_headerController screenDidHide:prevScreen];
}

UIViewController *controller = [self getScreenController:screen];

__block CGRect frame = [[controller view] frame];

CGFloat offsetY = -0.222f;

if(IS_IPHONE)
{
frame.size.height = self.view.bounds.size.height * 1.2f;
// offsetY = -0.1f;
}

frame.size.width = self.view.bounds.size.width * 0.9f;


frame.origin.y = frame.size.height * -1.0f;
frame.origin.x = self.view.bounds.size.width * 0.5f - frame.size.width * 0.5f;

[controller.view setAlpha:0.7f];
[controller.view setFrame:frame];

//[[controller view] setTranslatesAutoresizingMaskIntoConstraints:NO];

[self addChildViewController:controller];
[controller willMoveToParentViewController:self];
[self.view insertSubview:controller.view
aboveSubview:_canvasController.view];

_externalController = (LaerExternalController*)controller;

[UIView animateWithDuration:[self screenDuration:screen] delay:[self


screenDelay:screen] usingSpringWithDamping:0.4f initialSpringVelocity:0.5f
options:UIViewAnimationOptionBeginFromCurrentState animations:^
{
frame.origin.y = frame.size.height * offsetY;
[controller.view setAlpha:1.0f];
[controller.view setFrame:frame];
} completion:^(BOOL finished)
{
frame.origin.y = frame.size.height * offsetY;
[controller.view setAlpha:1.0f];
[controller.view setFrame:frame];

[_headerController screenDidShow:screen];
}];
}
else
{
if(!_externalController) return;

[UIView animateWithDuration:0.1f delay:0.0f


options:UIViewAnimationOptionBeginFromCurrentState animations:^
{
CGRect frame = [[_externalController view] frame];
frame.origin.y = frame.size.height * -0.9f;
[_externalController.view setAlpha:0.7f];
[_externalController.view setFrame:frame];
} completion:^(BOOL finished)
{
[_externalController.view removeFromSuperview];
[_externalController didMoveToParentViewController:nil];
[_externalController removeFromParentViewController];
_externalController = nil;
if(screen == -1) [_headerController screenDidHide:_curScreen];
else [_headerController screenDidHide:screen];
}];
}

[self shouldShowStatusBar:NO];
}

-(void)updateSettingsSize:(CGSize)size {
[(AtlasPropertyController*)_settingsController updateSettingsContentSize:size];
}

#pragma mar - self methods


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle
*)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];

LaerDataManager *dataManager = [LaerDataManager sharedInstance];


NSPredicate *predicate = [NSPredicate
predicateWithFormat:@"product.productName = %@",[self
currentProductName]];

_atlasCD = [dataManager fetchEntity:NSStringFromClass([TextureAtlasCD


class]) withPredicate:predicate andResultType:NSManagedObjectResultType];

[self initialize];
}

-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}

-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];

if(_canvasController) {
[self layoutChildrens];
}
}

-(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
NSPredicate *predicate = [NSPredicate
predicateWithFormat:@"product.productName = %@", [self
currentProductName]];
NSInteger count = [[LaerDataManager sharedInstance]
fetchCount:NSStringFromClass([LaerAssetCD class]) predicate:predicate];
if(!count)
{
predicate = [NSPredicate predicateWithFormat:@"productName = %@",
[self currentProductName]];
LaerProductCD *product = [[LaerDataManager sharedInstance]
fetchEntity:NSStringFromClass([LaerProductCD class]) withPredicate:predicate
andResultType:NSManagedObjectResultType];
if(product) {
[[LaerDataManager sharedInstance] deleteObject:product];
}
}
else
{
if(_atlasCD && [_atlasCD hasChanges]) {
[[LaerDataManager sharedInstance] save];
}
}

if(_importAssets) {
[_importAssets removeAllObjects];
}

_importAssets = nil;

_didQuit = YES;

[self cleanup];
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];

_isMemoryUp = YES;
}

-(void)dealloc
{
_headerController = nil;
_atlasCD = nil;
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender


{
if([[segue identifier] isEqualToString:SEGUE_ID_ATLAS_HEADER])
{
_headerController =
(TextureAtlasHeaderController*)segue.destinationViewController;
[_headerController setDelegate:self];
}
else if([[segue identifier] isEqualToString:SEGUE_ID_ATLAS_SETTINGS])
{
_settingsController =
(AtlasPropertyController*)segue.destinationViewController;
[_settingsController setDelegate:self];
}
else if([[segue identifier] isEqualToString:SEGUE_ID_ATLAS_ASSETS])
{
_assetsController =
(AtlasAssetsController*)segue.destinationViewController;
[_assetsController setDelegate:self];
}
else if([[segue identifier] isEqualToString:SEGUE_ID_ATLAS_UTILITIES])
{
_utilitiesController =
(AtlasUtilityController*)segue.destinationViewController;
[_utilitiesController setDelegate:self];
}
}

#pragma mark - TextureAtlas delegate methods


-(NSString*)currentProductName {
return self.title;
}

-(BOOL)isExportPossible {
return [_headerController isExportPossible];
}

-(void)importedAssets:(NSArray *)assets
{
if(![assets count])
return;

BOOL isFresh = YES;


_didQuit = NO;

if(!_importAssets) {
_importAssets = [NSMutableArray arrayWithArray:assets];
}
else
{
[_importAssets addObjectsFromArray:assets];
isFresh = NO;
}
assets = nil;

_totalImportCount = [_importAssets count];


if(_assetsTrailCons.constant < (ASSETS_WINDOW_SHOW * -1))
{
[self switchAssetsVisible];
[self switchUtilityVisible];
}

if(isFresh)
{
[_bearActInd startAnimation];
[self performSelector:@selector(startImportAssets) withObject:nil
afterDelay:1.0f];
}
}

-(void)updateTexture
{
[_bearActInd startAnimation];
[self performSelector:@selector(prepareTexture) withObject:nil
afterDelay:0.01f];
}

-(void)textureUpdated:(NSString*)fileLocation
{
[_utilitiesController updateMemoryWithCanvasSize:[[_canvasController view]
bounds].size andUnusedSprites:[_assetsController getUnusedAssetsCount]
fileLocation:fileLocation];

if(!_importAssets) {
[_bearActInd stopAnimation];
}
}

-(void)gotoMainMenu
{
[self.view setUserInteractionEnabled:NO];

UIViewController *controller = [Utilities


getController:STORYBOARD_ID_HOME_CONTROLLER];
[controller setTitle:[self currentProductName]];

CATransition* transition = [CATransition animation];


transition.duration = 0.1f;
transition.timingFunction = [CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionEaseIn];
transition.type = kCATransitionFade;

[self.navigationController.view.layer addAnimation:transition forKey:nil];


[self.navigationController setViewControllers:@[controller] animated:NO];
}

-(BOOL)autoRotation {
return [[_atlasCD rotation] boolValue];
}

-(BOOL)autoSize {
return [[_atlasCD autoSize] boolValue];
}
-(BOOL)trim {
return [[_atlasCD trim] boolValue];
}

-(double)trimOpacity {
return [[_atlasCD trimOpacity] doubleValue];
}

-(void)setAutoSize:(BOOL)enable
{
[_atlasCD setAutoSize:[NSNumber numberWithBool:enable]];
[self updateTexture];
}

-(void)setPowSize:(BOOL)enable
{
[_atlasCD setPow:[NSNumber numberWithBool:enable]];
[self updateTexture];
}

-(void)setAutoRotation:(BOOL)enable
{
[_atlasCD setRotation:[NSNumber numberWithBool:enable]];
[self updateTexture];
}

-(void)setSortOrder:(BOOL)asc
{
[_atlasCD setOrderBy:[NSNumber numberWithBool:asc]];
[self updateTexture];
}

-(void)setTrim:(BOOL)trim
{
[_atlasCD setTrim:[NSNumber numberWithBool:trim]];

[self performSelector:@selector(trimImages) withObject:nil afterDelay:0.01f];


}

-(void)setTrimOpacity:(NSInteger)trimOpacity
{
[_atlasCD setTrimOpacity:[NSNumber numberWithInteger:trimOpacity]];

[self performSelector:@selector(trimImages) withObject:nil afterDelay:0.01f];


}

-(void)switchSettingsVisible
{
if(!_settingsTrailCons) {
return;
}

[self showScreen:_curScreen show:NO];


__block BOOL isVisible = NO;
[UIView animateWithDuration:0.1f delay:0.0f
options:UIViewAnimationOptionBeginFromCurrentState animations:^
{
if(_settingsTrailCons.constant < (SETTINGS_WINDOW_SHOW * -1))
{
_settingsTrailCons.constant = SETTINGS_WINDOW_SHOW * -1;
isVisible = YES;
}
else {
_settingsTrailCons.constant = SETTINGS_WINDOW_HIDDEN * -1;
}
[self.view layoutIfNeeded];

} completion:^(BOOL finished) {
[_headerController highlightSettingsIcon:isVisible];
}];
}

-(void)switchAssetsVisible
{
if(!_assetsTrailCons) {
return;
}

[self showScreen:_curScreen show:NO];

__block BOOL isVisible = NO;


[UIView animateWithDuration:0.1f delay:0.0f
options:UIViewAnimationOptionBeginFromCurrentState animations:^
{
if(_assetsTrailCons.constant < (ASSETS_WINDOW_SHOW * -1))
{
_assetsTrailCons.constant = ASSETS_WINDOW_SHOW * -1;
isVisible = YES;
}
else {
_assetsTrailCons.constant = ASSETS_WINDOW_HIDDEN * -1;
}

[self.view layoutIfNeeded];

} completion:^(BOOL finished) {
[_headerController highlightAssetsIcon:isVisible];
}];
}

-(void)switchUtilityVisible
{
if(!_utilityTrailCons) {
return;
}

[self showScreen:_curScreen show:NO];


__block BOOL isVisible = NO;
[UIView animateWithDuration:0.1f delay:0.0f
options:UIViewAnimationOptionBeginFromCurrentState animations:^
{
if(_utilityTrailCons.constant < (ASSETS_WINDOW_SHOW * -1))
{
_utilityTrailCons.constant = ASSETS_WINDOW_SHOW * -1;
isVisible = YES;
}
else {
_utilityTrailCons.constant = UTILITY_WINDOW_HIDDEN * -1;
}

[self.view layoutIfNeeded];

} completion:^(BOOL finished) {
[_headerController highlightUtilityIcon:isVisible];
}];
}

-(void)hideNavigationPanels
{
[UIView animateWithDuration:0.1f delay:0.0f
options:UIViewAnimationOptionBeginFromCurrentState animations:^
{
_assetsTrailCons.constant = ASSETS_WINDOW_HIDDEN * -1;
_settingsTrailCons.constant = SETTINGS_WINDOW_HIDDEN * -1;
_utilityTrailCons.constant = UTILITY_WINDOW_HIDDEN * -1;

[self.view layoutIfNeeded];

} completion:^(BOOL finished)
{
[_headerController highlightAssetsIcon:NO];
[_headerController highlightSettingsIcon:NO];
[_headerController highlightUtilityIcon:NO];
}];
}

-(void)updateCanvasSize:(CGSize)canvasSize
{
_atlasCD.width = [NSNumber numberWithInt:canvasSize.width];
_atlasCD.height = [NSNumber numberWithInt:canvasSize.height];

[self updateTexture];
}

-(void)algorithm:(int)index {
_atlasCD.algorithm = [NSNumber numberWithInt:index];
}

-(void)heuristics:(int)index
{
_atlasCD.heuristics = [NSNumber numberWithInt:index];
[self updateTexture];
}

-(void)dataFormat:(int)index {
_atlasCD.dataFormat = [NSNumber numberWithInt:index];
}

-(void)textureFormat:(int)index
{
_atlasCD.texFormat = [NSNumber numberWithInt:index];

[self updateTexture];
}

-(void)pixelFormat:(int)index
{
_atlasCD.pixelFormat = [NSNumber numberWithInt:index];

[self updateTexture];
}

-(int)currentAlgorithm {
return [_atlasCD.algorithm intValue];
}

-(int)currentHeuristic {
return [_atlasCD.heuristics intValue];
}

-(int)currentTexFormat {
return [_atlasCD.texFormat intValue];
}

-(int)currentDataFormat {
return [_atlasCD.dataFormat intValue];
}

-(int)currentPixelFormat {
return [_atlasCD.pixelFormat intValue];
}

-(CGSize)canvasSize {
return CGSizeMake([_atlasCD.width floatValue], [_atlasCD.height floatValue]);
}

-(void)exportAssets {
[self exportAtlas:EXPORT_OPTION_ITUNES];
}

-(void)exportAtlas:(NSInteger)option
{
AtlasExportViewController *exportController = (AtlasExportViewController*)
[Utilities getController:STORYBOARD_ID_EXPORT_CONTROLLER];
[exportController setTitle:[self currentProductName]];
[exportController setDelegate:self];
[exportController setExportOption:option];

[self addChildViewController:exportController];
[exportController didMoveToParentViewController:self];
[exportController.view setBounds:[self.view bounds]];
[self.view addSubview:exportController.view];
}

#pragma mark - gesture handlers


- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceiveTouch:(UITouch *)touch
{
CGPoint pointInView = [touch locationInView:gestureRecognizer.view];
if(CGRectContainsPoint(_assetsContainer.frame, pointInView)) {
return NO;
}
else if(CGRectContainsPoint(_settingsContainer.frame, pointInView)) {
return NO;
}

return YES;
}

-(void)panGestureHandler:(UIPanGestureRecognizer*)gesture
{
CGPoint translation = [gesture translationInView:self.view];
_canvasController.view.center = CGPointMake(_canvasController.view.center.x
+ translation.x, _canvasController.view.center.y + translation.y);
[gesture setTranslation:CGPointMake(0, 0) inView:self.view];
}

-(void)pinchGestureHandler:(UIPinchGestureRecognizer*)gesture
{
if(!_canvasController) {
return;
}

UIView *canvasView = _canvasController.view;


if(gesture.state == UIGestureRecognizerStateBegan)
{
CGPoint locationInView = [gesture locationInView:canvasView];
CGPoint locationInSuperview = [gesture locationInView:self.view];

CGFloat scale = [self getScaleFromTransform:canvasView.transform];

locationInView.x *= scale;
locationInView.y *= scale;

canvasView.layer.anchorPoint = CGPointMake(locationInView.x /
canvasView.frame.size.width, locationInView.y / canvasView.frame.size.height);
canvasView.center = locationInSuperview;
}
else
{
CGAffineTransform transform =
CGAffineTransformScale(canvasView.transform, gesture.scale, gesture.scale);
CGFloat scale = [self getScaleFromTransform:transform];

if(scale >= 1.0f) {


canvasView.transform = transform;
}
else
{
canvasView.transform = CGAffineTransformIdentity;
canvasView.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
}
}

gesture.scale = 1.0f;
}

#pragma mark - Atlas data delegate methods


-(NSArray*)getAtlasData {
return [_assetsController getUsedAssets];
}

-(UIImage*)getTextureImage {
return [_canvasController getTextureImage];
}

@end

Potrebbero piacerti anche