mirror of
https://github.com/id-Software/DOOM-IOS2.git
synced 2026-03-20 08:59:35 +01:00
Initial Commit
This commit is contained in:
512
common/idmobilelib/ios/Carousel.mm
Executable file
512
common/idmobilelib/ios/Carousel.mm
Executable file
@@ -0,0 +1,512 @@
|
||||
/*
|
||||
|
||||
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 ];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
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 = fabsf( 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
|
||||
Reference in New Issue
Block a user