diff -r 2dc43ce68721 -r e00762923086 project_files/HedgewarsMobile/ValueTrackingSliderView.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/HedgewarsMobile/ValueTrackingSliderView.m Tue Feb 07 00:34:25 2012 +0100 @@ -0,0 +1,193 @@ +/* + * Hedgewars-iOS, a Hedgewars port for iOS devices + * Copyright (c) 2009-2011 Vittorio Giovara + * + * 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; version 2 of the License + * + * 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. + * + * File created on 06/02/2012. + */ + +// class heavily based on: http://blog.neuwert-media.com/2011/04/customized-uislider-with-visual-value-tracking/ + + +#import "ValueTrackingSliderView.h" + +#pragma mark - +#pragma mark Private UIView subclass rendering the popup showing slider value +@interface SliderValuePopupView : UIView +@property (nonatomic) float value; +@property (nonatomic, retain) UIFont *font; +@property (nonatomic, retain) NSString *text; +@end + +@implementation SliderValuePopupView + +@synthesize value = _value; +@synthesize font = _font; +@synthesize text = _text; + +-(id) initWithFrame:(CGRect) frame { + self = [super initWithFrame:frame]; + if (self) { + self.font = [UIFont boldSystemFontOfSize:18]; + } + return self; +} + +-(void) dealloc { + self.text = nil; + self.font = nil; + [super dealloc]; +} + +-(void) drawRect:(CGRect) rect { + // Create the path for the rounded rectangle + CGRect roundedRect = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, self.bounds.size.width, floorf(self.bounds.size.height * 0.8)); + UIBezierPath *roundedRectPath = [UIBezierPath bezierPathWithRoundedRect:roundedRect cornerRadius:6.0]; + roundedRectPath.lineWidth = 2.0f; + + // Create the arrow path + UIBezierPath *arrowPath = [UIBezierPath bezierPath]; + CGFloat midX = CGRectGetMidX(self.bounds); + CGPoint p0 = CGPointMake(midX, CGRectGetMaxY(self.bounds)); + [arrowPath moveToPoint:p0]; + [arrowPath addLineToPoint:CGPointMake((midX - 10.0), CGRectGetMaxY(roundedRect))]; + [arrowPath addLineToPoint:CGPointMake((midX + 10.0), CGRectGetMaxY(roundedRect))]; + [arrowPath closePath]; + + // Attach the arrow path to the rounded rect + [roundedRectPath appendPath:arrowPath]; + + // Color various sections + [[UIColor blackColor] setFill]; + [roundedRectPath fill]; + [[UIColor whiteColor] setStroke]; + [roundedRectPath stroke]; + [[UIColor whiteColor] setFill]; + [arrowPath fill]; + + // Draw the text + if (self.text) { + [[UIColor lightYellowColor] set]; + CGSize s = [_text sizeWithFont:self.font]; + CGFloat yOffset = (roundedRect.size.height - s.height) / 2; + CGRect textRect = CGRectMake(roundedRect.origin.x, yOffset, roundedRect.size.width, s.height); + + [_text drawInRect:textRect + withFont:self.font + lineBreakMode:UILineBreakModeWordWrap + alignment:UITextAlignmentCenter]; + } +} + +@end + +#pragma mark - +#pragma mark MNEValueTrackingSlider implementations +@implementation ValueTrackingSliderView + +@synthesize thumbRect, textValue; + +#pragma Private methods + +-(void) _constructSlider { + valuePopupView = [[SliderValuePopupView alloc] initWithFrame:CGRectZero]; + valuePopupView.backgroundColor = [UIColor clearColor]; + valuePopupView.alpha = 0.0; + [self addSubview:valuePopupView]; +} + +-(void) _fadePopupViewInAndOut:(BOOL)aFadeIn { + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:0.25]; + if (aFadeIn) { + valuePopupView.alpha = 1.0; + } else { + valuePopupView.alpha = 0.0; + } + [UIView commitAnimations]; +} + +-(void) _positionAndUpdatePopupView { + CGRect _thumbRect = self.thumbRect; + CGRect popupRect = CGRectOffset(_thumbRect, 0, -floorf(_thumbRect.size.height * 1.5)); + valuePopupView.frame = CGRectInset(popupRect, -100, -15); + valuePopupView.text = self.textValue; + [valuePopupView setNeedsDisplay]; +} + +#pragma mark Memory management + +-(id) initWithFrame:(CGRect) frame { + self = [super initWithFrame:frame]; + if (self) { + [self _constructSlider]; + } + return self; +} + +-(id) initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + [self _constructSlider]; + } + return self; +} + +-(void) dealloc { + [valuePopupView release]; + [textValue release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark UIControl touch event tracking +-(BOOL) beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event { + // Fade in and update the popup view + CGPoint touchPoint = [touch locationInView:self]; + // Check if the knob is touched. Only in this case show the popup-view + if(CGRectContainsPoint(CGRectInset(self.thumbRect, -12.0, -12.0), touchPoint)) { + [self _positionAndUpdatePopupView]; + [self _fadePopupViewInAndOut:YES]; + } + return [super beginTrackingWithTouch:touch withEvent:event]; +} + +-(BOOL) continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event { + // Update the popup view as slider knob is being moved + [self _positionAndUpdatePopupView]; + return [super continueTrackingWithTouch:touch withEvent:event]; +} + +-(void) cancelTrackingWithEvent:(UIEvent *)event { + [super cancelTrackingWithEvent:event]; +} + +-(void) endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event { + // Fade out the popoup view + [self _fadePopupViewInAndOut:NO]; + [super endTrackingWithTouch:touch withEvent:event]; +} + +#pragma mark - +#pragma mark Custom property accessors +-(CGRect) thumbRect { + CGRect trackRect = [self trackRectForBounds:self.bounds]; + CGRect thumbR = [self thumbRectForBounds:self.bounds + trackRect:trackRect + value:self.value]; + return thumbR; +} + +@end