mirror of
https://github.com/id-Software/DOOM-iOS.git
synced 2025-06-04 19:11:03 +00:00
514 lines
14 KiB
Text
Executable file
514 lines
14 KiB
Text
Executable file
/*
|
|
|
|
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
#import <Foundation/Foundation.h>
|
|
#import <UIKit/UIKit.h>
|
|
#import "Carousel.h"
|
|
#include <algorithm>
|
|
@implementation idCarouselItem
|
|
|
|
@synthesize image;
|
|
@synthesize title;
|
|
@synthesize hash;
|
|
|
|
@end
|
|
|
|
@implementation idCarousel
|
|
|
|
// Move full turn at this percentage
|
|
const static float CAROUSEL_CHANGE_DRAG = 0.2f;
|
|
const static float CAROUSEL_BACKITEMS_ALPHA = 0.5f;
|
|
const static float CAROUSEL_FRONTITEM_ALPHA = 1.0f;
|
|
|
|
enum idCarouselDrag_t {
|
|
CAROUSEL_DRAG_MOVE_NONE = 0,
|
|
CAROUSEL_DRAG_MOVE_FORWARD,
|
|
CAROUSEL_DRAG_MOVE_BACKWARD
|
|
};
|
|
|
|
/*
|
|
========================
|
|
Lerp
|
|
========================
|
|
*/
|
|
static CGFloat Lerp(CGFloat from, CGFloat to, CGFloat f )
|
|
{
|
|
return from + ( ( to - from ) * f );
|
|
}
|
|
|
|
/*
|
|
========================
|
|
LerpPoint
|
|
========================
|
|
*/
|
|
static CGPoint LerpPoint(CGPoint a, CGPoint b, CGFloat t)
|
|
{
|
|
CGPoint p;
|
|
p.x = Lerp(a.x, b.x, t);
|
|
p.y = Lerp(a.y, b.y, t);
|
|
return p;
|
|
}
|
|
|
|
/*
|
|
========================
|
|
LerpSize
|
|
========================
|
|
*/
|
|
static CGSize LerpSize(CGSize a, CGSize b, CGFloat t)
|
|
{
|
|
CGSize s;
|
|
s.width = Lerp(a.width, b.width, t);
|
|
s.height = Lerp(a.height, b.height, t);
|
|
return s;
|
|
}
|
|
|
|
/*
|
|
========================
|
|
LerpRect
|
|
========================
|
|
*/
|
|
static CGRect LerpRect( CGRect a, CGRect b, CGFloat t ) {
|
|
|
|
CGRect r;
|
|
r.origin = LerpPoint( a.origin, b.origin, t );
|
|
r.size = LerpSize( a.size, b.size, t );
|
|
return r;
|
|
|
|
}
|
|
|
|
/*
|
|
========================
|
|
awakeFromNib
|
|
========================
|
|
*/
|
|
- (void) awakeFromNib {
|
|
|
|
mainRect = mainSelection.frame;
|
|
prevRect = prevSelection.frame;
|
|
nextRect = nextSelection.frame;
|
|
|
|
// Allocate our Items Array
|
|
carouselItems = [[ NSMutableArray alloc ] init ];
|
|
|
|
[super awakeFromNib];
|
|
}
|
|
|
|
/*
|
|
========================
|
|
touchesBegan
|
|
========================
|
|
*/
|
|
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
|
|
(void)(event);
|
|
hasDragged = 0;
|
|
startDragPoint = [[touches anyObject] locationInView:self];
|
|
}
|
|
|
|
/*
|
|
========================
|
|
touchesMoved
|
|
========================
|
|
*/
|
|
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
|
|
(void)(event);
|
|
if( prevSelection == nil || nextSelection == nil ) {
|
|
// Nothing to transition to... dont swip transition
|
|
return;
|
|
}
|
|
|
|
CGPoint movedPoint = [[touches anyObject] locationInView:self];
|
|
CGFloat offsetX = movedPoint.x - startDragPoint.x;
|
|
|
|
// Find out where im at relative to the side of the screen
|
|
CGFloat percentage = offsetX / self.frame.size.width;
|
|
percentage = (float)fmin( percentage, 1.0f );
|
|
percentage = (float)fmax( percentage, -1.0f );
|
|
|
|
if( percentage > CAROUSEL_CHANGE_DRAG ) {
|
|
hasDragged = CAROUSEL_DRAG_MOVE_FORWARD;
|
|
} else if( percentage < -CAROUSEL_CHANGE_DRAG ) {
|
|
hasDragged = CAROUSEL_DRAG_MOVE_BACKWARD;
|
|
}
|
|
|
|
if( percentage > 0 ) { // Going to the right of the screen..
|
|
|
|
CGRect newMainRect = LerpRect( mainRect, nextRect , percentage );
|
|
CGRect newNextRect = LerpRect( nextRect, prevRect , percentage );
|
|
CGRect newPrevRect = LerpRect( prevRect, mainRect , percentage );
|
|
|
|
mainSelection.frame = newMainRect;
|
|
prevSelection.frame = newPrevRect;
|
|
nextSelection.frame = newNextRect;
|
|
|
|
mainSelection.alpha = Lerp( CAROUSEL_FRONTITEM_ALPHA, CAROUSEL_BACKITEMS_ALPHA, percentage );
|
|
prevSelection.alpha = Lerp( CAROUSEL_BACKITEMS_ALPHA, CAROUSEL_FRONTITEM_ALPHA, percentage );
|
|
|
|
} else { // Going the left.
|
|
|
|
percentage = CGFloat(fabs( percentage ));
|
|
|
|
CGRect newMainRect = LerpRect( mainRect, prevRect , percentage );
|
|
CGRect newNextRect = LerpRect( nextRect, mainRect , percentage );
|
|
CGRect newPrevRect = LerpRect( prevRect, nextRect , percentage );
|
|
|
|
mainSelection.frame = newMainRect;
|
|
prevSelection.frame = newPrevRect;
|
|
nextSelection.frame = newNextRect;
|
|
|
|
mainSelection.alpha = Lerp( CAROUSEL_FRONTITEM_ALPHA, CAROUSEL_BACKITEMS_ALPHA, percentage );
|
|
nextSelection.alpha = Lerp( CAROUSEL_BACKITEMS_ALPHA, CAROUSEL_FRONTITEM_ALPHA, percentage );
|
|
}
|
|
}
|
|
|
|
/*
|
|
========================
|
|
touchesEnded
|
|
========================
|
|
*/
|
|
- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
|
|
(void)(event);
|
|
(void)(touches);
|
|
|
|
if( hasDragged == CAROUSEL_DRAG_MOVE_FORWARD ) {
|
|
[ self RotateForward ];
|
|
} else if( hasDragged == CAROUSEL_DRAG_MOVE_BACKWARD ) {
|
|
[ self RotateBackward ];
|
|
} else {
|
|
[ self RotateToOrigin ];
|
|
}
|
|
}
|
|
|
|
/*
|
|
========================
|
|
Init
|
|
========================
|
|
*/
|
|
- (void) Init {
|
|
|
|
// Get the items At the new layout.
|
|
idCarouselItem * cItem = [ carouselItems objectAtIndex: (NSUInteger)currentItem ];
|
|
idCarouselItem * nItem = [ carouselItems objectAtIndex: (NSUInteger)nextItem ];
|
|
idCarouselItem * pItem = [ carouselItems objectAtIndex: (NSUInteger)prevItem ];
|
|
|
|
// Set the Main Selection Text.
|
|
[ selectionLabel setText: cItem.title ];
|
|
|
|
// Set the prev selection UIImage
|
|
mainSelection.image = cItem.image;
|
|
prevSelection.image = nItem.image;
|
|
nextSelection.image = pItem.image;
|
|
}
|
|
|
|
/*
|
|
========================
|
|
AddCarouselItem
|
|
========================
|
|
*/
|
|
- (void) AddCarouselItem:( NSString* )Image
|
|
:( NSString* )Title
|
|
:( int ) ItemHash {
|
|
|
|
idCarouselItem * Item = [ idCarouselItem alloc ];
|
|
|
|
// Initialize the Item with the data passed in.
|
|
Item.image = [UIImage imageNamed: Image ];
|
|
Item.title = Title;
|
|
Item.hash = ItemHash;
|
|
|
|
// Add the Item to our object array.
|
|
[ carouselItems addObject: Item ];
|
|
|
|
// Set the Cur Item as the one just added.
|
|
currentItem = 0;
|
|
nextItem = 1;
|
|
prevItem = (NSInteger)[ carouselItems count ] - 1;
|
|
|
|
}
|
|
|
|
/*
|
|
========================
|
|
GetSelectedItem_Index
|
|
========================
|
|
*/
|
|
- (NSInteger) GetSelectedItem_Index {
|
|
return currentItem;
|
|
}
|
|
|
|
/*
|
|
========================
|
|
GetSelectedItem_Hash
|
|
========================
|
|
*/
|
|
- (int) GetSelectedItem_Hash {
|
|
idCarouselItem * item = [ carouselItems objectAtIndex: (NSUInteger)currentItem ];
|
|
|
|
return item.hash;
|
|
}
|
|
|
|
/*
|
|
========================
|
|
MoveForward
|
|
|
|
Interface Builder Direct Access to moving the Carousel
|
|
========================
|
|
*/
|
|
- (IBAction) MoveForward {
|
|
[ self RotateForward ];
|
|
}
|
|
|
|
/*
|
|
========================
|
|
MoveBackward -
|
|
|
|
Interface Builder Direct Access to moving the Carousel
|
|
========================
|
|
*/
|
|
- (IBAction) MoveBackward {
|
|
[ self RotateBackward ];
|
|
}
|
|
|
|
/*
|
|
========================
|
|
RotateToOrigin
|
|
========================
|
|
*/
|
|
- (void) RotateToOrigin {
|
|
|
|
// Animate back to the correct position.
|
|
// Move the Current Selection to Next Selection
|
|
[UIView beginAnimations:nil context:nil];
|
|
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
|
|
[UIView setAnimationBeginsFromCurrentState:YES];
|
|
|
|
// Move them into Place.
|
|
mainSelection.frame = mainRect;
|
|
prevSelection.frame = prevRect;
|
|
nextSelection.frame = nextRect;
|
|
|
|
mainSelection.alpha = 1.0f;
|
|
nextSelection.alpha = CAROUSEL_BACKITEMS_ALPHA;
|
|
prevSelection.alpha = CAROUSEL_BACKITEMS_ALPHA;
|
|
|
|
[UIView commitAnimations];
|
|
}
|
|
|
|
/*
|
|
========================
|
|
RotateForward
|
|
========================
|
|
*/
|
|
- (void) RotateForward {
|
|
|
|
if( prevSelection == nil || nextSelection == nil ) {
|
|
|
|
// Flip book to the next selection.
|
|
// increment the item indicies.
|
|
currentItem++;
|
|
nextItem++;
|
|
prevItem++;
|
|
|
|
// Check the Extents.
|
|
if( currentItem >= (NSInteger)[ carouselItems count ] ) {
|
|
currentItem = 0;
|
|
}
|
|
if( nextItem >= (NSInteger)[ carouselItems count ] ) {
|
|
nextItem = 0;
|
|
}
|
|
if( prevItem >= (NSInteger)[ carouselItems count ] ) {
|
|
prevItem = 0;
|
|
}
|
|
|
|
idCarouselItem * cItem = [ carouselItems objectAtIndex: (NSUInteger)currentItem ];
|
|
|
|
// Set the Main Selection Text.
|
|
[ selectionLabel setText: cItem.title ];
|
|
|
|
// Set the prev selection UIImage
|
|
mainSelection.image = cItem.image;
|
|
|
|
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
UIImageView * tempMain = mainSelection;
|
|
UIImageView * tempPrev = prevSelection;
|
|
UIImageView * tempNext = nextSelection;
|
|
|
|
// Move the Current Selection to Next Selection
|
|
[UIView beginAnimations:nil context:nil];
|
|
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
|
|
[UIView setAnimationBeginsFromCurrentState:YES];
|
|
|
|
// Move them into Place.
|
|
mainSelection.frame = nextRect;
|
|
prevSelection.frame = mainRect;
|
|
nextSelection.frame = prevRect;
|
|
|
|
// Darken the prev/next
|
|
mainSelection.alpha = CAROUSEL_BACKITEMS_ALPHA;
|
|
prevSelection.alpha = CAROUSEL_FRONTITEM_ALPHA;
|
|
nextSelection.alpha = CAROUSEL_BACKITEMS_ALPHA;
|
|
|
|
[UIView commitAnimations];
|
|
|
|
|
|
// Swap out the ImageViews so that they are in the correct order.
|
|
nextSelection = tempMain;
|
|
mainSelection = tempPrev;
|
|
prevSelection = tempNext;
|
|
|
|
// Make sure they are in back of the main selection.
|
|
[ self sendSubviewToBack: nextSelection ];
|
|
[ self sendSubviewToBack: prevSelection ];
|
|
|
|
// increment the item indicies.
|
|
currentItem++;
|
|
nextItem++;
|
|
prevItem++;
|
|
|
|
// Check the Extents.
|
|
if( currentItem >= (NSInteger)[ carouselItems count ] ) {
|
|
currentItem = 0;
|
|
}
|
|
if( nextItem >= (NSInteger)[ carouselItems count ] ) {
|
|
nextItem = 0;
|
|
}
|
|
if( prevItem >= (NSInteger)[ carouselItems count ] ) {
|
|
prevItem = 0;
|
|
}
|
|
|
|
// Get the items At the new layout.
|
|
idCarouselItem * cItem = [ carouselItems objectAtIndex: (NSUInteger)currentItem ];
|
|
idCarouselItem * nItem = [ carouselItems objectAtIndex: (NSUInteger)nextItem ];
|
|
idCarouselItem * pItem = [ carouselItems objectAtIndex: (NSUInteger)prevItem ];
|
|
|
|
// Set the Main Selection Text.
|
|
[ selectionLabel setText: cItem.title ];
|
|
|
|
// Set the prev selection UIImage
|
|
mainSelection.image = cItem.image;
|
|
prevSelection.image = nItem.image;
|
|
nextSelection.image = pItem.image;
|
|
|
|
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
|
}
|
|
|
|
/*
|
|
========================
|
|
RotateBackward
|
|
========================
|
|
*/
|
|
- (void) RotateBackward {
|
|
|
|
if( nextSelection == nil || prevSelection == nil ) {
|
|
|
|
// increment the item indicies.
|
|
currentItem--;
|
|
nextItem--;
|
|
prevItem--;
|
|
|
|
// Check the Extents.
|
|
if( currentItem < 0 ) {
|
|
currentItem = (NSInteger)[ carouselItems count ] - 1;
|
|
}
|
|
if( nextItem < 0 ) {
|
|
nextItem = (NSInteger)[ carouselItems count ] - 1;;
|
|
}
|
|
if( prevItem < 0 ) {
|
|
prevItem = (NSInteger)[ carouselItems count ] - 1;;
|
|
}
|
|
|
|
idCarouselItem * cItem = [ carouselItems objectAtIndex: (NSUInteger)currentItem ];
|
|
|
|
// Set the Main Selection Text.
|
|
[ selectionLabel setText: cItem.title ];
|
|
|
|
// Set the prev selection UIImage
|
|
mainSelection.image = cItem.image;
|
|
|
|
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
|
|
|
return;
|
|
}
|
|
|
|
UIImageView * tempMain = mainSelection;
|
|
UIImageView * tempPrev = prevSelection;
|
|
UIImageView * tempNext = nextSelection;
|
|
|
|
// Move the Current Selection to Next Selection
|
|
[UIView beginAnimations:nil context:nil];
|
|
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
|
|
[UIView setAnimationBeginsFromCurrentState:YES];
|
|
|
|
// Move them into Place.
|
|
mainSelection.frame = prevRect;
|
|
prevSelection.frame = nextRect;
|
|
nextSelection.frame = mainRect;
|
|
|
|
// Darken the prev/next
|
|
mainSelection.alpha = CAROUSEL_BACKITEMS_ALPHA;
|
|
prevSelection.alpha = CAROUSEL_BACKITEMS_ALPHA;
|
|
nextSelection.alpha = CAROUSEL_FRONTITEM_ALPHA;
|
|
|
|
[UIView commitAnimations];
|
|
|
|
// Swap out the ImageViews so that they are in the correct order.
|
|
nextSelection = tempPrev;
|
|
mainSelection = tempNext;
|
|
prevSelection = tempMain;
|
|
|
|
// Make sure they are in back of the main selection.
|
|
[ self sendSubviewToBack: nextSelection ];
|
|
[ self sendSubviewToBack: prevSelection ];
|
|
|
|
// increment the item indicies.
|
|
currentItem--;
|
|
nextItem--;
|
|
prevItem--;
|
|
|
|
// Check the Extents.
|
|
if( currentItem < 0 ) {
|
|
currentItem = (NSInteger)[ carouselItems count ] - 1;
|
|
}
|
|
if( nextItem < 0 ) {
|
|
nextItem = (NSInteger)[ carouselItems count ] - 1;;
|
|
}
|
|
if( prevItem < 0 ) {
|
|
prevItem = (NSInteger)[ carouselItems count ] - 1;;
|
|
}
|
|
|
|
// Get the items At the new layout.
|
|
idCarouselItem * cItem = [ carouselItems objectAtIndex: (NSUInteger) currentItem ];
|
|
idCarouselItem * nItem = [ carouselItems objectAtIndex: (NSUInteger)nextItem ];
|
|
idCarouselItem * pItem = [ carouselItems objectAtIndex: (NSUInteger)prevItem ];
|
|
|
|
// Set the Main Selection Text.
|
|
[ selectionLabel setText: cItem.title ];
|
|
|
|
// Set the prev selection UIImage
|
|
mainSelection.image = cItem.image;
|
|
prevSelection.image = nItem.image;
|
|
nextSelection.image = pItem.image;
|
|
|
|
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
|
}
|
|
|
|
@end
|