Source

BWToolkit / BWTexturedSlider.m

Brandon Walkin b48f0b7 



































Brandon Walkin ca81669 
Brandon Walkin b48f0b7 


























Brandon Walkin 3002b05 
Brandon Walkin b48f0b7 




Brandon Walkin 3002b05 
Brandon Walkin b48f0b7 



Brandon Walkin e677e45 


Brandon Walkin b48f0b7 

Brandon Walkin ca81669 
Brandon Walkin b48f0b7 
Brandon Walkin ca81669 
Brandon Walkin b48f0b7 




























































































Brandon Walkin 563d197 







Brandon Walkin 145ecb8 

Brandon Walkin 8edb347 




















Brandon Walkin 145ecb8 

Brandon Walkin 4ce78c9 













Brandon Walkin dbd181f 






Brandon Walkin b48f0b7 
//
//  BWTexturedSlider.m
//  BWToolkit
//
//  Created by Brandon Walkin (www.brandonwalkin.com)
//  All code is provided under the New BSD license.
//

#import "BWTexturedSlider.h"
#import "BWTexturedSliderCell.h"

static NSImage *quietSpeakerImage, *loudSpeakerImage, *smallPhotoImage, *largePhotoImage;
static float imageInset = 25;

@implementation BWTexturedSlider

@synthesize indicatorIndex;
@synthesize minButton;
@synthesize maxButton;

+ (void)initialize 
{
	NSBundle *bundle = [NSBundle bundleForClass:[BWTexturedSlider class]];
	
	quietSpeakerImage = [[NSImage alloc] initWithContentsOfFile:[bundle pathForImageResource:@"TexturedSliderSpeakerQuiet.png"]];
	loudSpeakerImage = [[NSImage alloc] initWithContentsOfFile:[bundle pathForImageResource:@"TexturedSliderSpeakerLoud.png"]];
	smallPhotoImage = [[NSImage alloc] initWithContentsOfFile:[bundle pathForImageResource:@"TexturedSliderPhotoSmall.tif"]];
	largePhotoImage	= [[NSImage alloc] initWithContentsOfFile:[bundle pathForImageResource:@"TexturedSliderPhotoLarge.tif"]];
}

- (id)initWithCoder:(NSCoder *)decoder
{
	if ((self = [super initWithCoder:decoder]) != nil)
	{
		indicatorIndex = [decoder decodeIntForKey:@"BWTSIndicatorIndex"];
		[self setMinButton:[decoder decodeObjectForKey:@"BWTSMinButton"]];
		[self setMaxButton:[decoder decodeObjectForKey:@"BWTSMaxButton"]];	
	}
	return self;
}

- (void)encodeWithCoder:(NSCoder*)coder
{
    [super encodeWithCoder:coder];
	
	[coder encodeInt:[self indicatorIndex] forKey:@"BWTSIndicatorIndex"];
	[coder encodeObject:[self minButton] forKey:@"BWTSMinButton"];
	[coder encodeObject:[self maxButton] forKey:@"BWTSMaxButton"];
}

- (int)trackHeight
{
	return [[self cell] trackHeight];
}

- (void)setTrackHeight:(int)newTrackHeight
{
	[[self cell] setTrackHeight:newTrackHeight];
	[self setNeedsDisplay:YES];
}

- (void)setSliderToMinimum
{
	[self setDoubleValue:[self minValue]];
	[self sendAction:[self action] to:[self target]];
}

- (void)setSliderToMaximum
{
	[self setDoubleValue:[self maxValue]];
	[self sendAction:[self action] to:[self target]];
}

- (NSView *)hitTest:(NSPoint)aPoint
{
	if ([self indicatorIndex] == 0)
		return [super hitTest:aPoint];
	
	NSPoint convertedPoint = [self convertPoint:aPoint fromView:nil];
	
	if (NSPointInRect(convertedPoint, minButton.frame))
		return minButton;
	else if (NSPointInRect(convertedPoint, maxButton.frame))
		return maxButton;
	else
		return [super hitTest:aPoint];
}

- (void)drawRect:(NSRect)aRect
{
	aRect = self.bounds;
	sliderCellRect = aRect;
	
	if ([self indicatorIndex] == 2)
	{
		[minButton setFrameOrigin:NSMakePoint(imageInset-19, 3)];
		[maxButton setFrameOrigin:NSMakePoint(NSMaxX(self.bounds)-imageInset+4, 3)];
		
		sliderCellRect.size.width -= imageInset * 2;
		sliderCellRect.origin.x += imageInset;
	}
	else if ([self indicatorIndex] == 3)
	{
		[minButton setFrameOrigin:NSMakePoint(imageInset-7, 4)];
		[maxButton setFrameOrigin:NSMakePoint(NSMaxX(self.bounds)-imageInset, 4)];
		
		sliderCellRect.size.width -= imageInset * 2;
		sliderCellRect.origin.x += imageInset;
	}
	
	[[self cell] drawWithFrame:sliderCellRect inView:self];
}

- (void)setIndicatorIndex:(int)anIndex
{
	[minButton removeFromSuperview];
	[maxButton removeFromSuperview];

	if (indicatorIndex == 0 && (anIndex == 2 || anIndex == 3))
	{
		NSRect newFrame = self.frame;
		newFrame.size.width += imageInset * 2;
		newFrame.origin.x -= imageInset;
		[self setFrame:newFrame];
	}
	
	if ((indicatorIndex == 2 || indicatorIndex == 3) && anIndex == 0)
	{
		NSRect newFrame = self.frame;
		newFrame.size.width -= imageInset * 2;
		newFrame.origin.x += imageInset;
		[self setFrame:newFrame];
	}
	
	if (anIndex == 2)
	{
		minButton = [[NSButton alloc] initWithFrame:NSMakeRect(0,0,smallPhotoImage.size.width,smallPhotoImage.size.height)];
		[minButton setBordered:NO];
		[minButton setImage:smallPhotoImage];	
		[minButton setTarget:self];
		[minButton setAction:@selector(setSliderToMinimum)];
		[[minButton cell] setHighlightsBy:2]; 
		
		maxButton = [[NSButton alloc] initWithFrame:NSMakeRect(NSMaxX(self.bounds) - imageInset,0,largePhotoImage.size.width,largePhotoImage.size.height)];
		[maxButton setBordered:NO];
		[maxButton setImage:largePhotoImage];
		[maxButton setTarget:self];
		[maxButton setAction:@selector(setSliderToMaximum)];
		[[maxButton cell] setHighlightsBy:2]; 
		
		[self addSubview:minButton];
		[self addSubview:maxButton];
	}
	else if (anIndex == 3)
	{
		minButton = [[NSButton alloc] initWithFrame:NSMakeRect(0,0,quietSpeakerImage.size.width,quietSpeakerImage.size.height)];
		[minButton setBordered:NO];
		[minButton setImage:quietSpeakerImage];	
		[minButton setTarget:self];
		[minButton setAction:@selector(setSliderToMinimum)];
		[[minButton cell] setHighlightsBy:2]; 
		
		maxButton = [[NSButton alloc] initWithFrame:NSMakeRect(NSMaxX(self.bounds) - imageInset,0,loudSpeakerImage.size.width,loudSpeakerImage.size.height)];
		[maxButton setBordered:NO];
		[maxButton setImage:loudSpeakerImage];
		[maxButton setTarget:self];
		[maxButton setAction:@selector(setSliderToMaximum)];
		[[maxButton cell] setHighlightsBy:2]; 
		
		[self addSubview:minButton];
		[self addSubview:maxButton];
	}
	
	indicatorIndex = anIndex;
}

- (void)setEnabled:(BOOL)flag
{
	[super setEnabled:flag];
	
	[minButton setEnabled:flag];
	[maxButton setEnabled:flag];
}

- (void)scrollWheel:(NSEvent*)event
{
	/* Scroll wheel movement appears to be specified in terms of pixels, and 
	   definitely not in terms of the values that the slider contains.  Because 
	   of this, we'll have to map our current value to pixel space, adjust the 
	   pixel space value, and then map back to value space again. */
	
	CGFloat valueRange = [self maxValue] - [self minValue];
	CGFloat valueOffset = [self doubleValue] - [self minValue];
	CGFloat pixelRange = [self isVertical] ? NSHeight([self frame]) : NSWidth([self frame]);
	 
	CGFloat valueInPixelSpace = ((valueOffset / valueRange) * pixelRange);
	 
	/* deltaX and deltaY are 'flipped' from what you'd expect. Scrolling down 
	   produces + Y values, and scrolling left produces + X values. Because we
	   want left/down scrolling to decrease the value, we adjust accordingly. */
	valueInPixelSpace += [event deltaY];
	valueInPixelSpace -= [event deltaX];
	 
	double newValue = [self minValue] + ((valueInPixelSpace / pixelRange) * valueRange);
	
	[self setFloatValue:newValue];
 	[self sendAction:[self action] to:[self target]];
}

- (BOOL)becomeFirstResponder
{
	[[self cell] setShowsFirstResponder:YES];
	
	return [super becomeFirstResponder];
}

- (BOOL)resignFirstResponder
{
	[[self cell] setShowsFirstResponder:NO];
	
	return [super resignFirstResponder];
}

- (void)dealloc
{
	[minButton release];
	[maxButton release];
	[super dealloc];
}

@end