Showing preview only (209K chars total). Download the full file or copy to clipboard to get everything.
Repository: RSully/RSColorPicker
Branch: master
Commit: 5e19c03ec062
Files: 67
Total size: 190.4 KB
Directory structure:
gitextract_9nhdc9e5/
├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── RSColorPicker/
│ ├── ColorPickerClasses/
│ │ ├── ANImageBitmapRep/
│ │ │ ├── ANImageBitmapRep.h
│ │ │ ├── ANImageBitmapRep.m
│ │ │ ├── BitmapContextRep.h
│ │ │ ├── BitmapContextRep.m
│ │ │ ├── Compatibility/
│ │ │ │ ├── NSImage+ANImageBitmapRep.h
│ │ │ │ ├── NSImage+ANImageBitmapRep.m
│ │ │ │ ├── OSCommonImage.h
│ │ │ │ ├── OSCommonImage.m
│ │ │ │ ├── UIImage+ANImageBitmapRep.h
│ │ │ │ └── UIImage+ANImageBitmapRep.m
│ │ │ ├── CoreGraphics/
│ │ │ │ ├── CGContextCreator.h
│ │ │ │ ├── CGContextCreator.m
│ │ │ │ ├── CGImageContainer.h
│ │ │ │ └── CGImageContainer.m
│ │ │ └── Manipulators/
│ │ │ ├── BitmapContextManipulator.h
│ │ │ ├── BitmapContextManipulator.m
│ │ │ ├── BitmapCropManipulator.h
│ │ │ ├── BitmapCropManipulator.m
│ │ │ ├── BitmapDrawManipulator.h
│ │ │ ├── BitmapDrawManipulator.m
│ │ │ ├── BitmapRotationManipulator.h
│ │ │ ├── BitmapRotationManipulator.m
│ │ │ ├── BitmapScaleManipulator.h
│ │ │ └── BitmapScaleManipulator.m
│ │ ├── BGRSLoupeLayer.h
│ │ ├── BGRSLoupeLayer.m
│ │ ├── RSColorFunctions.h
│ │ ├── RSColorFunctions.m
│ │ ├── RSColorPickerState.h
│ │ ├── RSColorPickerState.m
│ │ ├── RSColorPickerView.h
│ │ ├── RSColorPickerView.m
│ │ ├── RSGenerateOperation.h
│ │ ├── RSGenerateOperation.m
│ │ ├── RSSelectionLayer.h
│ │ └── RSSelectionLayer.m
│ ├── RSBrightnessSlider.h
│ ├── RSBrightnessSlider.m
│ ├── RSColorPicker-Info.plist
│ ├── RSColorPicker-Prefix.pch
│ ├── RSColorPickerAppDelegate.h
│ ├── RSColorPickerAppDelegate.m
│ ├── RSOpacitySlider.h
│ ├── RSOpacitySlider.m
│ ├── TestColorViewController.h
│ ├── TestColorViewController.m
│ ├── en.lproj/
│ │ └── InfoPlist.strings
│ └── main.m
├── RSColorPicker.podspec
├── RSColorPicker.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── xcshareddata/
│ └── xcschemes/
│ └── RSColorPicker.xcscheme
└── RSColorPickerTests/
├── CPTestCase.h
├── CPTestCase.m
├── CPTestCaseTests.m
├── RSColorFunctionsTests.m
├── RSColorPickerStateTests.m
├── RSColorPickerTests-Info.plist
├── RSColorPickerTests-Prefix.pch
├── RSColorPickerViewDelegateTests.m
├── RSColorPickerViewTests.m
└── en.lproj/
└── InfoPlist.strings
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# OS X
.DS_Store
# Xcode
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
profile
*.moved-aside
DerivedData
*.hmap
*.ipa
# CocoaPods
Pods
================================================
FILE: .travis.yml
================================================
language: objective-c
xcode_project: RSColorPicker.xcodeproj
xcode_scheme: RSColorPicker
xcode_sdk: iphonesimulator
notifications:
email: false
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
Pull requests are welcome for bug fixes or feature additions. If you contribute code, make sure you stick to the following syntax guidelines:
- Indentation should be done with 4 spaces, not `\t`.
- For Objective-C method implementations, the opening curly brace `{` should appear on the same line as the method name: `- (void)foobar {`.
- For Objective-C methods, there should be a space after the `-` or `+`, as in the example above.
- For C function implementations, the `{` should appear immediately on the next line after the function name & arguments.
- For pointers, declare variables such as `NSArray *myVar`, with the `*` touching the variable name. For Objective-C arguments, put a space before the `*`: `- (NSArray *)myMethod`.
- For C functions that return a pointer, put a space before *and* after the `*`: `void * getBuffer()`.
================================================
FILE: LICENSE.md
================================================
[RSColorPicker](https://github.com/RSully/RSColorPicker) - Copyright (c) 2011, Ryan (RSully)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: README.md
================================================
# Project:
[](https://travis-ci.org/RSully/RSColorPicker)
iOS color picker that is resolution independent.
Inspired by [ANColorPicker](https://github.com/unixpickle/ANColorPicker).
Also uses [ANImageBitmapRep](https://github.com/unixpickle/ANImageBitmapRep) for easy pixel-level manipulation.
And of course, thanks to [Wikipedia](http://en.wikipedia.org/wiki/HSL_and_HSV).
## Class Files:
### `RSColorPickerView`
Square (circle) color-picker that handles touch events, allows for brightness control, and allows for opacity control. Uses delegation to report color selection as-changed
## Usage:
See included example project (`TestColorViewController`).
### Requirements:
* Accelerate.framework
* QuartzCore.framework
* CoreGraphics.framework
* UIKit.framework
* Foundation.framework
* ANImageBitmapRep (included)
## License
See [LICENSE.md](LICENSE.md). You know the drill, use at your own risk, this code is given without support, etc. And for good karma link back to this github.com page, [github.com/rsully/rscolorpicker](https://github.com/RSully/RSColorPicker)
***
<img alt="Color Picker - Default" src="./Example01.png" width="320">
<img alt="Color Picker - Loupe" src="./Example02.png" width="320">
<img alt="Color Picker - Opacity" src="./Example03.png" width="320">
<img alt="Color Picker - Circle" src="./Example04.png" width="320">
<img alt="Color Picker - Resize" src="./Example05.png" width="320">
## Contributing
Pull requests are welcome for bug fixes or feature additions. If you contribute code, make sure you stick to the [contibution guidelines](CONTRIBUTING.md).
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/ANImageBitmapRep.h
================================================
//
// ANImageBitmapRep.h
// ImageManip
//
// Created by Alex Nichol on 7/12/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "OSCommonImage.h"
#import "BitmapScaleManipulator.h"
#import "BitmapCropManipulator.h"
#import "BitmapRotationManipulator.h"
#import "BitmapDrawManipulator.h"
#import "UIImage+ANImageBitmapRep.h"
typedef struct {
CGFloat red;
CGFloat green;
CGFloat blue;
CGFloat alpha;
} BMPixel;
BMPixel BMPixelMake (CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha);
#if TARGET_OS_IPHONE
UIColor * UIColorFromBMPixel (BMPixel pixel);
#elif TARGET_OS_MAC
NSColor * NSColorFromBMPixel (BMPixel pixel);
#endif
@interface ANImageBitmapRep : BitmapContextRep <BitmapScaleManipulator, BitmapCropManipulator, BitmapRotationManipulator, BitmapDrawManipulator, NSCopying> {
#if __has_feature(objc_arc) == 1
__strong NSArray * baseClasses;
#else
NSArray * baseClasses;
#endif
}
#if __has_feature(objc_arc) == 1
+ (ANImageBitmapRep *)imageBitmapRepWithCGSize:(CGSize)avgSize __attribute__((ns_returns_autoreleased));
+ (ANImageBitmapRep *)imageBitmapRepWithImage:(ANImageObj *)anImage __attribute__((ns_returns_autoreleased));
#else
+ (ANImageBitmapRep *)imageBitmapRepWithCGSize:(CGSize)avgSize;
+ (ANImageBitmapRep *)imageBitmapRepWithImage:(ANImageObj *)anImage;
#endif
/**
* Reverses the RGB values of all pixels in the bitmap. This causes
* an "inverted" effect.
*/
- (void)invertColors;
/**
* Scales the image down, then back up again. Use this to blur an image.
* @param quality A percentage from 0 to 1, 0 being horrible quality, 1 being
* perfect quality.
*/
- (void)setQuality:(CGFloat)quality;
/**
* Darken or brighten the image.
* @param brightness A percentage from 0 to 2. In this case, 0 is the darkest
* and 2 is the brightest. If this is 1, no change will be made.
*/
- (void)setBrightness:(CGFloat)brightness;
/**
* Returns a pixel at a given location.
* @param point The point from which a pixel will be taken. For all points
* in a BitmapContextRep, the x and y values start at 0 and end at
* width - 1 and height - 1 respectively.
* @return The pixel with values taken from the specified point.
*/
- (BMPixel)getPixelAtPoint:(BMPoint)point;
/**
* Sets a pixel at a specific location.
* @param pixel An RGBA pixel represented by an array of four floats.
* Each component is one float long, and goes from 0 to 1.
* In this case, 0 is black and 1 is white.
* @param point The location of the pixel to change. For all points
* in a BitmapContextRep, the x and y values start at 0 and end at
* width - 1 and height - 1 respectively.
*/
- (void)setPixel:(BMPixel)pixel atPoint:(BMPoint)point;
/**
* Creates a new UIImage or NSImage from the bitmap context.
*/
#if __has_feature(objc_arc) == 1
- (ANImageObj *)image __attribute__((ns_returns_autoreleased));
#else
- (ANImageObj *)image;
#endif
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/ANImageBitmapRep.m
================================================
//
// ANImageBitmapRep.m
// ImageManip
//
// Created by Alex Nichol on 7/12/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "ANImageBitmapRep.h"
BMPixel BMPixelMake (CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha) {
BMPixel pixel;
pixel.red = red;
pixel.green = green;
pixel.blue = blue;
pixel.alpha = alpha;
return pixel;
}
#if TARGET_OS_IPHONE
UIColor * UIColorFromBMPixel (BMPixel pixel) {
return [UIColor colorWithRed:pixel.red green:pixel.green blue:pixel.blue alpha:pixel.alpha];
}
#elif TARGET_OS_MAC
NSColor * NSColorFromBMPixel (BMPixel pixel) {
return [NSColor colorWithCalibratedRed:pixel.red green:pixel.green blue:pixel.blue alpha:pixel.alpha];
}
#endif
@interface ANImageBitmapRep (BaseClasses)
- (void)generateBaseClasses;
@end
@implementation ANImageBitmapRep
- (void)forwardInvocation:(NSInvocation *)anInvocation {
if (!baseClasses) [self generateBaseClasses];
for (int i = 0; i < [baseClasses count]; i++) {
BitmapContextManipulator * manip = [baseClasses objectAtIndex:i];
if ([manip respondsToSelector:[anInvocation selector]]) {
[anInvocation invokeWithTarget:manip];
return;
}
}
[self doesNotRecognizeSelector:[anInvocation selector]];
}
#if __has_feature(objc_arc) == 1
+ (ANImageBitmapRep *)imageBitmapRepWithCGSize:(CGSize)avgSize {
return [[ANImageBitmapRep alloc] initWithSize:BMPointMake(round(avgSize.width), round(avgSize.height))];
}
+ (ANImageBitmapRep *)imageBitmapRepWithImage:(ANImageObj *)anImage {
return [[ANImageBitmapRep alloc] initWithImage:anImage];
}
#else
+ (ANImageBitmapRep *)imageBitmapRepWithCGSize:(CGSize)avgSize {
return [[[ANImageBitmapRep alloc] initWithSize:BMPointMake(round(avgSize.width), round(avgSize.height))] autorelease];
}
+ (ANImageBitmapRep *)imageBitmapRepWithImage:(ANImageObj *)anImage {
return [[[ANImageBitmapRep alloc] initWithImage:anImage] autorelease];
}
#endif
- (void)invertColors {
UInt8 pixel[4];
BMPoint size = [self bitmapSize];
for (long y = 0; y < size.y; y++) {
for (long x = 0; x < size.x; x++) {
[self getRawPixel:pixel atPoint:BMPointMake(x, y)];
pixel[0] = 255 - pixel[0];
pixel[1] = 255 - pixel[1];
pixel[2] = 255 - pixel[2];
[self setRawPixel:pixel atPoint:BMPointMake(x, y)];
}
}
}
- (void)setQuality:(CGFloat)quality {
NSAssert(quality >= 0 && quality <= 1, @"Quality must be between 0 and 1.");
if (quality == 1.0) return;
CGSize cSize = CGSizeMake((CGFloat)([self bitmapSize].x) * quality, (CGFloat)([self bitmapSize].y) * quality);
BMPoint oldSize = [self bitmapSize];
[self setSize:BMPointMake(round(cSize.width), round(cSize.height))];
[self setSize:oldSize];
}
- (void)setBrightness:(CGFloat)brightness {
NSAssert(brightness >= 0 && brightness <= 2, @"Brightness must be between 0 and 2.");
BMPoint size = [self bitmapSize];
for (long y = 0; y < size.y; y++) {
for (long x = 0; x < size.x; x++) {
BMPoint point = BMPointMake(x, y);
BMPixel pixel = [self getPixelAtPoint:point];
pixel.red *= brightness;
pixel.green *= brightness;
pixel.blue *= brightness;
if (pixel.red > 1) pixel.red = 1;
if (pixel.green > 1) pixel.green = 1;
if (pixel.blue > 1) pixel.blue = 1;
[self setPixel:pixel atPoint:point];
}
}
}
- (BMPixel)getPixelAtPoint:(BMPoint)point {
UInt8 rawPixel[4];
[self getRawPixel:rawPixel atPoint:point];
BMPixel pixel;
pixel.alpha = (CGFloat)(rawPixel[3]) / 255.0;
pixel.red = ((CGFloat)(rawPixel[0]) / 255.0) / pixel.alpha;
pixel.green = ((CGFloat)(rawPixel[1]) / 255.0) / pixel.alpha;
pixel.blue = ((CGFloat)(rawPixel[2]) / 255.0) / pixel.alpha;
return pixel;
}
- (void)setPixel:(BMPixel)pixel atPoint:(BMPoint)point {
NSAssert(pixel.red >= 0 && pixel.red <= 1, @"Pixel color must range from 0 to 1.");
NSAssert(pixel.green >= 0 && pixel.green <= 1, @"Pixel color must range from 0 to 1.");
NSAssert(pixel.blue >= 0 && pixel.blue <= 1, @"Pixel color must range from 0 to 1.");
NSAssert(pixel.alpha >= 0 && pixel.alpha <= 1, @"Pixel color must range from 0 to 1.");
UInt8 rawPixel[4];
rawPixel[0] = round(pixel.red * 255.0 * pixel.alpha);
rawPixel[1] = round(pixel.green * 255.0 * pixel.alpha);
rawPixel[2] = round(pixel.blue * 255.0 * pixel.alpha);
rawPixel[3] = round(pixel.alpha * 255.0);
[self setRawPixel:rawPixel atPoint:point];
}
- (ANImageObj *)image {
return ANImageFromCGImage([self CGImage]);
}
#if __has_feature(objc_arc) != 1
- (void)dealloc {
[baseClasses release];
[super dealloc];
}
#endif
#pragma mark Base Classes
- (void)generateBaseClasses {
BitmapCropManipulator * croppable = [[BitmapCropManipulator alloc] initWithContext:self];
BitmapScaleManipulator * scalable = [[BitmapScaleManipulator alloc] initWithContext:self];
BitmapRotationManipulator * rotatable = [[BitmapRotationManipulator alloc] initWithContext:self];
BitmapDrawManipulator * drawable = [[BitmapDrawManipulator alloc] initWithContext:self];
baseClasses = [[NSArray alloc] initWithObjects:croppable, scalable, rotatable, drawable, nil];
#if __has_feature(objc_arc) != 1
[rotatable release];
[scalable release];
[croppable release];
[drawable release];
#endif
}
#pragma mark NSCopying
- (id)copyWithZone:(NSZone *)zone {
BMPoint size = [self bitmapSize];
ANImageBitmapRep * rep = [[ANImageBitmapRep allocWithZone:zone] initWithSize:size];
CGContextRef newContext = [rep context];
CGContextDrawImage(newContext, CGRectMake(0, 0, size.x, size.y), [self CGImage]);
[rep setNeedsUpdate:YES];
return rep;
}
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/BitmapContextRep.h
================================================
//
// BitmapContextRep.h
// ImageManip
//
// Created by Alex Nichol on 7/12/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "OSCommonImage.h"
#import "CGImageContainer.h"
#import "CGContextCreator.h"
/**
* A structure that defines a point in bitmap space.
* This is similar to the CGPoint structure, but it
* does not use floating points, making it more accurate.
*/
typedef struct {
long x;
long y;
} BMPoint;
BMPoint BMPointMake (long x, long y);
BMPoint BMPointFromSize (CGSize size);
BMPoint BMPointFromPoint (CGPoint point);
/**
* BitmapContextRep is a concrete subclass of NSObject that provides a basic
* class for mutating image's bitmaps. This class is very barebones,
* and generally will not be enough for most image manipulation.
*/
@interface BitmapContextRep : NSObject {
CGContextRef context;
CGImageRef lastImage;
unsigned char * bitmapData;
BOOL needsUpdate;
}
/**
* Creates a bitmap context with pixels and dimensions from an image.
* @param image The image to wrap in a bitmap context.
*/
- (id)initWithImage:(ANImageObj *)image;
/**
* Creates a bitmap context with the information from a CGImageRef.
* @param image The image to use for initialization. The reference will
* not be consumed, so you will still need to CGImageRelease() this as expected.
*/
- (id)initWithCGImage:(CGImageRef)img;
/**
* Creates a blank bitmap context with specified dimensions.
* @param sizePoint The size to use for the new bitmap. The x value
* of this is used for the width, and the y value is used for height.
*/
- (id)initWithSize:(BMPoint)sizePoint;
/**
* Returns the bitmap context underlying the image.
*/
- (CGContextRef)context;
/**
* Replaces the current context with a new one.
* @param aContext The new bitmap context for the image which will be retained
* and released automatically by the BitmapContextRep.
*/
- (void)setContext:(CGContextRef)aContext;
/**
* Returns the current size of the bitmap.
*/
- (BMPoint)bitmapSize;
/**
* Tells the BitmapContext that a new image should be generated when
* one is requested because the internal context has been externally
* modified.
* @param needsUpdate This should almost always be YES. If this is no,
* a new CGImageRef will not be generated when one is requested.
*/
- (void)setNeedsUpdate:(BOOL)flag;
/**
* Returns by reference a 4-byte RGBA pixel at a certain point.
* @param rgba A pointer to a 4-byte or more pixel buffer.
* @param point The point from which a pixel will be read. For all
* points in a BitmapContextRep, the x and y values start at 0 and end
* at width - 1 and height - 1 respectively.
*/
- (void)getRawPixel:(UInt8 *)rgba atPoint:(BMPoint)point;
/**
* Sets a 4-byte ARGB pixel at a specified point.
* @param rgba The pixel buffer containing at least 4 bytes.
* @param point The point at which the pixel will be set. For all
* points in a BitmapContextRep, the x and y values start at 0 and end
* at width - 1 and height - 1 respectively.
* @discussion Since alpha is premultiplied, it is important to remember to multiply
* the alpha as a percentage by the RGB values. This means that a white pixel
* with 50% alpha would become rgba(128, 128, 128, 128).
*/
- (void)setRawPixel:(const UInt8 *)rgba atPoint:(BMPoint)point;
/**
* Returns an autoreleased CGImageRef of the current BitmapContext.
*/
- (CGImageRef)CGImage;
/**
* Returns a mutable RGBA data array. If you modify this, you should call
* [context setNeedsUpdate:YES] before calling [context CGImage] or similar.
*/
- (unsigned char *)bitmapData;
@end
@protocol BitmapContextRep
@optional
- (CGContextRef)context;
- (void)setContext:(CGContextRef)aContext;
- (BMPoint)bitmapSize;
- (void)setNeedsUpdate:(BOOL)flag;
- (void)getRawPixel:(UInt8 *)rgba atPoint:(BMPoint)point;
- (void)setRawPixel:(const UInt8 *)rgba atPoint:(BMPoint)point;
- (CGImageRef)CGImage;
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/BitmapContextRep.m
================================================
//
// BitmapContextRep.m
// ImageManip
//
// Created by Alex Nichol on 7/12/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "BitmapContextRep.h"
BMPoint BMPointMake (long x, long y) {
BMPoint p;
p.x = x;
p.y = y;
return p;
}
BMPoint BMPointFromSize (CGSize size) {
return BMPointMake(round(size.width), round(size.height));
}
BMPoint BMPointFromPoint (CGPoint point) {
return BMPointMake(round(point.x), round(point.y));
}
@implementation BitmapContextRep
- (id)initWithImage:(ANImageObj *)image {
if ((self = [super init])) {
CGImageRef img = CGImageFromANImage(image);
context = [CGContextCreator newARGBBitmapContextWithImage:img];
bitmapData = CGBitmapContextGetData(context);
lastImage = CGImageRetain(img);
}
return self;
}
- (id)initWithCGImage:(CGImageRef)img {
if ((self = [super init])) {
context = [CGContextCreator newARGBBitmapContextWithImage:img];
bitmapData = CGBitmapContextGetData(context);
lastImage = CGImageRetain(img);
}
return self;
}
- (id)initWithSize:(BMPoint)sizePoint {
if ((self = [super init])) {
if (sizePoint.x == 0 || sizePoint.y == 0) {
#if __has_feature(objc_arc)
return nil;
#else
[super dealloc];
return nil;
#endif
}
context = [CGContextCreator newARGBBitmapContextWithSize:CGSizeMake(sizePoint.x, sizePoint.y)];
bitmapData = CGBitmapContextGetData(context);
lastImage = CGBitmapContextCreateImage(context);
}
return self;
}
- (CGContextRef)context {
return context;
}
- (void)setContext:(CGContextRef)aContext {
if (context == aContext) return;
// free previous.
CGContextRelease(context);
free(bitmapData);
// create new.
context = CGContextRetain(aContext);
bitmapData = CGBitmapContextGetData(aContext);
[self setNeedsUpdate:YES];
}
- (BMPoint)bitmapSize {
BMPoint point;
point.x = (long)CGBitmapContextGetWidth(context);
point.y = (long)CGBitmapContextGetHeight(context);
return point;
}
- (void)setNeedsUpdate:(BOOL)flag {
needsUpdate = flag;
}
- (void)getRawPixel:(UInt8 *)rgba atPoint:(BMPoint)point {
size_t width = CGBitmapContextGetWidth(context);
NSAssert(point.x >= 0 && point.x < width, @"Point must be within bitmap.");
NSAssert(point.y >= 0 && point.y < CGBitmapContextGetHeight(context), @"Point must be within bitmap.");
unsigned char * argbData = &bitmapData[((point.y * width) + point.x) * 4];
rgba[0] = argbData[1]; // red
rgba[1] = argbData[2]; // green
rgba[2] = argbData[3]; // blue
rgba[3] = argbData[0]; // alpha
[self setNeedsUpdate:YES];
}
- (void)setRawPixel:(const UInt8 *)rgba atPoint:(BMPoint)point {
size_t width = CGBitmapContextGetWidth(context);
NSAssert(point.x >= 0 && point.x < width, @"Point must be within bitmap.");
NSAssert(point.y >= 0 && point.y < CGBitmapContextGetHeight(context), @"Point must be within bitmap.");
unsigned char * argbData = &bitmapData[((point.y * width) + point.x) * 4];
argbData[1] = rgba[0]; // red
argbData[2] = rgba[1]; // green
argbData[3] = rgba[2]; // blue
argbData[0] = rgba[3]; // alpha
[self setNeedsUpdate:YES];
}
- (CGImageRef)CGImage {
if (needsUpdate) {
CGImageRelease(lastImage);
lastImage = CGBitmapContextCreateImage(context);
needsUpdate = NO;
}
#if __has_feature(objc_arc) == 1
return (__bridge CGImageRef)CGImageReturnAutoreleased(lastImage);
#else
return (CGImageRef)[[CGImageContainer imageContainerWithImage:lastImage] image];
#endif
}
- (unsigned char *)bitmapData {
return bitmapData;
}
- (void)dealloc {
CGContextRelease(context);
free(bitmapData);
if (lastImage != NULL) {
CGImageRelease(lastImage);
}
#if __has_feature(objc_arc) != 1
[super dealloc];
#endif
}
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Compatibility/NSImage+ANImageBitmapRep.h
================================================
//
// NSImage+ANImageBitmapRep.h
// ImageBitmapRep
//
// Created by Alex Nichol on 10/23/11.
// Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//
#import "TargetConditionals.h"
#if TARGET_OS_IPHONE != 1
#import <Cocoa/Cocoa.h>
@class ANImageBitmapRep;
@interface NSImage (ANImageBitmapRep)
#if __has_feature(objc_arc) == 1
+ (NSImage *)imageFromImageBitmapRep:(ANImageBitmapRep *)ibr __attribute__((ns_returns_autoreleased));
- (ANImageBitmapRep *)imageBitmapRep __attribute__((ns_returns_autoreleased));
- (NSImage *)imageByScalingToSize:(CGSize)sz __attribute__((ns_returns_autoreleased));
- (NSImage *)imageFittingFrame:(CGSize)sz __attribute__((ns_returns_autoreleased));
- (NSImage *)imageFillingFrame:(CGSize)sz __attribute__((ns_returns_autoreleased));
#else
+ (NSImage *)imageFromImageBitmapRep:(ANImageBitmapRep *)ibr;
- (ANImageBitmapRep *)imageBitmapRep;
- (NSImage *)imageByScalingToSize:(CGSize)sz;
- (NSImage *)imageFittingFrame:(CGSize)sz;
- (NSImage *)imageFillingFrame:(CGSize)sz;
#endif
@end
#endif
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Compatibility/NSImage+ANImageBitmapRep.m
================================================
//
// NSImage+ANImageBitmapRep.m
// ImageBitmapRep
//
// Created by Alex Nichol on 10/23/11.
// Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//
#import "TargetConditionals.h"
#if TARGET_OS_IPHONE != 1
#import "NSImage+ANImageBitmapRep.h"
#import "ANImageBitmapRep.h"
@implementation NSImage (ANImageBitmapRep)
+ (NSImage *)imageFromImageBitmapRep:(ANImageBitmapRep *)ibr {
return [ibr image];
}
- (ANImageBitmapRep *)imageBitmapRep {
#if __has_feature(objc_arc) == 1
return [[ANImageBitmapRep alloc] initWithImage:self];
#else
return [[[ANImageBitmapRep alloc] initWithImage:self] autorelease];
#endif
}
- (NSImage *)imageByScalingToSize:(CGSize)sz {
ANImageBitmapRep * imageBitmap = [[ANImageBitmapRep alloc] initWithImage:self];
[imageBitmap setSize:BMPointMake(round(sz.width), round(sz.height))];
NSImage * scaled = [imageBitmap image];
#if __has_feature(objc_arc) != 1
[imageBitmap release];
#endif
return scaled;
}
- (NSImage *)imageFittingFrame:(CGSize)sz {
ANImageBitmapRep * imageBitmap = [[ANImageBitmapRep alloc] initWithImage:self];
[imageBitmap setSizeFittingFrame:BMPointMake(round(sz.width), round(sz.height))];
NSImage * scaled = [imageBitmap image];
#if __has_feature(objc_arc) != 1
[imageBitmap release];
#endif
return scaled;
}
- (NSImage *)imageFillingFrame:(CGSize)sz {
ANImageBitmapRep * imageBitmap = [[ANImageBitmapRep alloc] initWithImage:self];
[imageBitmap setSizeFillingFrame:BMPointMake(round(sz.width), round(sz.height))];
NSImage * scaled = [imageBitmap image];
#if __has_feature(objc_arc) != 1
[imageBitmap release];
#endif
return scaled;
}
@end
#endif
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Compatibility/OSCommonImage.h
================================================
//
// OSCommonImage.h
// ImageBitmapRep
//
// Created by Alex Nichol on 10/23/11.
// Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//
#ifndef ImageBitmapRep_OSCommonImage_h
#define ImageBitmapRep_OSCommonImage_h
#import "TargetConditionals.h"
#import "CGImageContainer.h"
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
typedef UIImage ANImageObj;
#elif TARGET_OS_MAC
#import <Cocoa/Cocoa.h>
typedef NSImage ANImageObj;
#endif
CGImageRef CGImageFromANImage (ANImageObj * anImageObj);
ANImageObj * ANImageFromCGImage (CGImageRef imageRef);
#endif
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Compatibility/OSCommonImage.m
================================================
//
// OSCommonImage.c
// ImageBitmapRep
//
// Created by Alex Nichol on 10/23/11.
// Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//
#include "OSCommonImage.h"
CGImageRef CGImageFromANImage (ANImageObj * anImageObj) {
#if TARGET_OS_IPHONE
return [anImageObj CGImage];
#elif TARGET_OS_MAC
CGImageSourceRef source;
#if __has_feature(objc_arc) == 1
source = CGImageSourceCreateWithData((__bridge CFDataRef)[anImageObj TIFFRepresentation], NULL);
#else
source = CGImageSourceCreateWithData((CFDataRef)[anImageObj TIFFRepresentation], NULL);
#endif
CGImageRef maskRef = CGImageSourceCreateImageAtIndex(source, 0, NULL);
CFRelease(source);
#if __has_feature(objc_arc) == 1
CGImageRef autoreleased = (__bridge CGImageRef)CGImageReturnAutoreleased(maskRef);
CGImageRelease(maskRef);
return autoreleased;
#else
CGImageContainer * container = [CGImageContainer imageContainerWithImage:maskRef];
CGImageRelease(maskRef);
return [container image];
#endif
#endif
}
ANImageObj * ANImageFromCGImage (CGImageRef imageRef) {
#if TARGET_OS_IPHONE
return [UIImage imageWithCGImage:imageRef];
#elif TARGET_OS_MAC
NSImage * image = [[NSImage alloc] initWithCGImage:imageRef size:NSZeroSize];
#if __has_feature(objc_arc) == 1
return image;
#else
return [image autorelease];
#endif
#endif
}
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Compatibility/UIImage+ANImageBitmapRep.h
================================================
//
// UIImage+ANImageBitmapRep.h
// ImageBitmapRep
//
// Created by Alex Nichol on 8/11/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "TargetConditionals.h"
#if TARGET_OS_IPHONE
@class ANImageBitmapRep;
#import <UIKit/UIKit.h>
@interface UIImage (ANImageBitmapRep)
#if __has_feature(objc_arc) == 1
+ (UIImage *)imageFromImageBitmapRep:(ANImageBitmapRep *)ibr __attribute__((ns_returns_autoreleased));
- (ANImageBitmapRep *)imageBitmapRep __attribute__((ns_returns_autoreleased));
- (UIImage *)imageByScalingToSize:(CGSize)sz __attribute__((ns_returns_autoreleased));
- (UIImage *)imageFittingFrame:(CGSize)sz __attribute__((ns_returns_autoreleased));
- (UIImage *)imageFillingFrame:(CGSize)sz __attribute__((ns_returns_autoreleased));
#else
+ (UIImage *)imageFromImageBitmapRep:(ANImageBitmapRep *)ibr;
- (ANImageBitmapRep *)imageBitmapRep;
- (UIImage *)imageByScalingToSize:(CGSize)sz;
- (UIImage *)imageFittingFrame:(CGSize)sz;
- (UIImage *)imageFillingFrame:(CGSize)sz;
#endif
@end
#endif
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Compatibility/UIImage+ANImageBitmapRep.m
================================================
//
// UIImage+ANImageBitmapRep.m
// ImageBitmapRep
//
// Created by Alex Nichol on 8/11/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "TargetConditionals.h"
#if TARGET_OS_IPHONE
#import "UIImage+ANImageBitmapRep.h"
#import "ANImageBitmapRep.h"
@implementation UIImage (ANImageBitmapRep)
+ (UIImage *)imageFromImageBitmapRep:(ANImageBitmapRep *)ibr {
return [ibr image];
}
- (ANImageBitmapRep *)imageBitmapRep {
#if __has_feature(objc_arc) == 1
return [[ANImageBitmapRep alloc] initWithImage:self];
#else
return [[[ANImageBitmapRep alloc] initWithImage:self] autorelease];
#endif
}
- (UIImage *)imageByScalingToSize:(CGSize)sz {
ANImageBitmapRep * imageBitmap = [[ANImageBitmapRep alloc] initWithImage:self];
[imageBitmap setSize:BMPointMake(round(sz.width), round(sz.height))];
UIImage * scaled = [imageBitmap image];
#if __has_feature(objc_arc) != 1
[imageBitmap release];
#endif
return scaled;
}
- (UIImage *)imageFittingFrame:(CGSize)sz {
ANImageBitmapRep * imageBitmap = [[ANImageBitmapRep alloc] initWithImage:self];
[imageBitmap setSizeFittingFrame:BMPointMake(round(sz.width), round(sz.height))];
UIImage * scaled = [imageBitmap image];
#if __has_feature(objc_arc) != 1
[imageBitmap release];
#endif
return scaled;
}
- (UIImage *)imageFillingFrame:(CGSize)sz {
ANImageBitmapRep * imageBitmap = [[ANImageBitmapRep alloc] initWithImage:self];
[imageBitmap setSizeFillingFrame:BMPointMake(round(sz.width), round(sz.height))];
UIImage * scaled = [imageBitmap image];
#if __has_feature(objc_arc) != 1
[imageBitmap release];
#endif
return scaled;
}
@end
#endif
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/CoreGraphics/CGContextCreator.h
================================================
//
// CGContextCreator.h
// ImageBitmapRep
//
// Created by Alex Nichol on 7/4/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "TargetConditionals.h"
#if TARGET_OS_IPHONE
#import <CoreGraphics/CoreGraphics.h>
#elif TARGET_OS_MAC
#import <Quartz/Quartz.h>
#endif
/**
* This class has several static methods for creating bitmap contexts.
* These methods are pretty much only called when creating a new
* ANImageBitmapRep.
*/
@interface CGContextCreator : NSObject {
}
+ (CGContextRef)newARGBBitmapContextWithSize:(CGSize)size;
+ (CGContextRef)newARGBBitmapContextWithImage:(CGImageRef)image;
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/CoreGraphics/CGContextCreator.m
================================================
//
// CGContextCreator.m
// ImageBitmapRep
//
// Created by Alex Nichol on 7/4/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "CGContextCreator.h"
@implementation CGContextCreator
- (id)init {
if ((self = [super init])) {
// Initialization code here.
}
return self;
}
+ (CGContextRef)newARGBBitmapContextWithSize:(CGSize)size {
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
void * bitmapData;
int bitmapByteCount;
int bitmapBytesPerRow;
// Get image width, height. We'll use the entire image.
size_t pixelsWide = round(size.width);
size_t pixelsHigh = round(size.height);
bitmapBytesPerRow = (int)(pixelsWide * 4);
bitmapByteCount = (int)(bitmapBytesPerRow * pixelsHigh);
// Use the generic RGB color space.
colorSpace = CGColorSpaceCreateDeviceRGB();
if (colorSpace == NULL) {
fprintf(stderr, "Error allocating color space\n");
return NULL;
}
// allocate
bitmapData = malloc(bitmapByteCount);
if (bitmapData == NULL) {
NSLog(@"Malloc failed which is too bad. I was hoping to use this memory.");
CGColorSpaceRelease(colorSpace);
// even though CGContextRef technically is not a pointer,
// it's typedef probably is and it is a scalar anyway.
return NULL;
}
// Create the bitmap context. We are
// setting up the image as an ARGB (0-255 per component)
// 4-byte per/pixel.
context = CGBitmapContextCreate (bitmapData,
pixelsWide,
pixelsHigh,
8,
bitmapBytesPerRow,
colorSpace,
(CGBitmapInfo)kCGImageAlphaPremultipliedFirst);
if (context == NULL) {
free (bitmapData);
NSLog(@"Failed to create bitmap!");
}
CGContextClearRect(context, CGRectMake(0, 0, size.width, size.height));
CGColorSpaceRelease(colorSpace);
return context;
}
+ (CGContextRef)newARGBBitmapContextWithImage:(CGImageRef)image {
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
void * bitmapData;
int bitmapByteCount;
int bitmapBytesPerRow;
// Get image width, height. We'll use the entire image.
size_t pixelsWide = CGImageGetWidth(image);
size_t pixelsHigh = CGImageGetHeight(image);
bitmapBytesPerRow = (int)(pixelsWide * 4);
bitmapByteCount = (int)(bitmapBytesPerRow * pixelsHigh);
// Use the generic RGB color space.
colorSpace = CGColorSpaceCreateDeviceRGB();
if (colorSpace == NULL) {
fprintf(stderr, "Error allocating color space\n");
return NULL;
}
// allocate
bitmapData = malloc(bitmapByteCount);
if (bitmapData == NULL) {
NSLog(@"Malloc failed which is too bad. I was hoping to use this memory.");
CGColorSpaceRelease(colorSpace);
// even though CGContextRef technically is not a pointer,
// it's typedef probably is and it is a scalar anyway.
return NULL;
}
// Create the bitmap context. We are
// setting up the image as an ARGB (0-255 per component)
// 4-byte per/pixel.
context = CGBitmapContextCreate (bitmapData,
pixelsWide,
pixelsHigh,
8, // bits per component
bitmapBytesPerRow,
colorSpace,
(CGBitmapInfo)kCGImageAlphaPremultipliedFirst);
if (context == NULL) {
free (bitmapData);
NSLog(@"Failed to create bitmap!");
}
// draw the image on the context.
// CGContextTranslateCTM(context, 0, CGImageGetHeight(image));
// CGContextScaleCTM(context, 1.0, -1.0);
CGContextClearRect(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)));
CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
CGColorSpaceRelease(colorSpace);
return context;
}
#if __has_feature(objc_arc) != 1
- (void)dealloc {
[super dealloc];
}
#endif
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/CoreGraphics/CGImageContainer.h
================================================
//
// CGImageContainer.h
// ImageBitmapRep
//
// Created by Alex Nichol on 5/3/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "TargetConditionals.h"
#if TARGET_OS_IPHONE
#import <CoreGraphics/CoreGraphics.h>
#elif TARGET_OS_MAC
#import <Quartz/Quartz.h>
#endif
#if __has_feature(objc_arc) != 1
@interface CGImageContainer : NSObject {
CGImageRef image;
}
/**
* The image that this container encloses.
*/
@property (readonly) CGImageRef image;
/**
* Create a new image container with an image.
* @param anImage Will be retained and enclosed in this class.
* This object will be released when the CGImageContainer is
* deallocated. This can be nil.
* @return The new image container, or nil if anImage is nil.
*/
- (id)initWithImage:(CGImageRef)anImage;
/**
* Create a new image container with an image.
* @param anImage Will be retained and enclosed in this class.
* This object will be released when the CGImageContainer is
* deallocated. This can be nil.
* @return The new image container, or nil if anImage is nil.
* The image container returned will be autoreleased.
*/
+ (CGImageContainer *)imageContainerWithImage:(CGImageRef)anImage;
@end
#else
id CGImageReturnAutoreleased (CGImageRef original) __attribute__((ns_returns_autoreleased));
#endif
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/CoreGraphics/CGImageContainer.m
================================================
//
// CGImageContainer.m
// ImageBitmapRep
//
// Created by Alex Nichol on 5/3/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "CGImageContainer.h"
#if __has_feature(objc_arc) != 1
@implementation CGImageContainer
@synthesize image;
- (id)initWithImage:(CGImageRef)anImage {
if ((self = [super init])) {
image = CGImageRetain(anImage);
}
return self;
}
+ (CGImageContainer *)imageContainerWithImage:(CGImageRef)anImage {
CGImageContainer * container = [(CGImageContainer *)[CGImageContainer alloc] initWithImage:anImage];
return [container autorelease];
}
- (void)dealloc {
CGImageRelease(image);
[super dealloc];
}
@end
#else
__attribute__((ns_returns_autoreleased))
id CGImageReturnAutoreleased (CGImageRef original) {
// CGImageRetain(original);
return (__bridge id)original;
}
#endif
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapContextManipulator.h
================================================
//
// BitmapContextManip.h
// ImageBitmapRep
//
// Created by Alex Nichol on 10/14/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "BitmapContextRep.h"
@interface BitmapContextManipulator : NSObject <BitmapContextRep> {
#if __has_feature(objc_arc) == 1
__unsafe_unretained BitmapContextRep * bitmapContext;
#else
BitmapContextRep * bitmapContext;
#endif
}
#if __has_feature(objc_arc) == 1
@property (nonatomic, assign) BitmapContextRep * bitmapContext;
#else
@property (nonatomic, assign) BitmapContextRep * bitmapContext;
#endif
- (id)initWithContext:(BitmapContextRep *)aContext;
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapContextManipulator.m
================================================
//
// BitmapContextManip.m
// ImageBitmapRep
//
// Created by Alex Nichol on 10/14/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "BitmapContextManipulator.h"
@implementation BitmapContextManipulator
@synthesize bitmapContext;
- (id)initWithContext:(BitmapContextRep *)aContext {
if ((self = [super init])) {
self.bitmapContext = aContext;
}
return self;
}
- (void)forwardInvocation:(NSInvocation *)anInvocation {
[anInvocation invokeWithTarget:bitmapContext];
}
#if __has_feature(objc_arc) != 1
- (void)dealloc {
self.bitmapContext = nil;
[super dealloc];
}
#endif
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapCropManipulator.h
================================================
//
// CroppableBitmapRep.h
// ImageManip
//
// Created by Alex Nichol on 7/12/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "BitmapContextManipulator.h"
@protocol BitmapCropManipulator
@optional
- (void)cropFrame:(CGRect)frame;
- (void)cropTopFrame:(CGRect)frame;
- (void)cropTopEllipse:(CGRect)frame;
- (CGImageRef)croppedImageWithFrame:(CGRect)frame;
@end
@interface BitmapCropManipulator : BitmapContextManipulator {
}
/**
* Cuts a part of the bitmap out for a new bitmap.
* @param frame The rectangle from which a portion of the image will
* be cut.
* The coordinates for this start at (0,0).
* @discussion The coordinates for this method begin in the bottom
* left corner. For a coordinate system starting from the top
* left corner, use cropTopFrame: instead.
*/
- (void)cropFrame:(CGRect)frame;
/**
* Cuts a part of the bitmap out for a new bitmap.
* @param frame The rectangle from which a portion of the image will
* be cut.
* The coordinates for this start at (0,0).
* @discussion The coordinates for this method begin in the top
* left corner. For a coordinate system starting from the bottom
* left corner, use cropFrame: instead.
*/
- (void)cropTopFrame:(CGRect)frame;
/**
* Cuts an ellipse of the bitmap out for a new bitmap.
* @param frame The rectangle around the ellipse to be cut. The
* coordinates for this start at (0,0).
* @discussion The coordinates for this method begin in the top
* left corner. There is no alternative.
*/
- (void)cropTopEllipse:(CGRect)frame;
/**
* Creates a new CGImageRef by cutting out a portion of this one.
* This takes its behavoir from cropFrame.
* @return An autoreleased CGImageRef that has been cropped from this
* image.
*/
- (CGImageRef)croppedImageWithFrame:(CGRect)frame;
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapCropManipulator.m
================================================
//
// CroppableBitmapRep.m
// ImageManip
//
// Created by Alex Nichol on 7/12/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "BitmapCropManipulator.h"
@implementation BitmapCropManipulator
- (void)cropFrame:(CGRect)frame {
BMPoint size = [bitmapContext bitmapSize];
// It's kind of rude to prevent them from doing something kind of cool, so let's not.
// NSAssert(frame.origin.x >= 0 && frame.origin.x + frame.size.width <= size.x, @"Cropping frame must be within the bitmap.");
// NSAssert(frame.origin.y >= 0 && frame.origin.y + frame.size.height <= size.y, @"Cropping frame must be within the bitmap.");
CGContextRef newBitmap = [CGContextCreator newARGBBitmapContextWithSize:frame.size];
CGPoint offset = CGPointMake(-frame.origin.x, -frame.origin.y);
CGContextDrawImage(newBitmap, CGRectMake(offset.x, offset.y, size.x, size.y), [bitmapContext CGImage]);
[bitmapContext setContext:newBitmap];
CGContextRelease(newBitmap);
}
- (void)cropTopFrame:(CGRect)frame {
BMPoint size = [bitmapContext bitmapSize];
// It's kind of rude to prevent them from doing something kind of cool, so let's not.
// NSAssert(frame.origin.x >= 0 && frame.origin.x + frame.size.width <= size.x, @"Cropping frame must be within the bitmap.");
// NSAssert(frame.origin.y >= 0 && frame.origin.y + frame.size.height <= size.y, @"Cropping frame must be within the bitmap.");
CGContextRef newBitmap = [CGContextCreator newARGBBitmapContextWithSize:frame.size];
CGPoint offset = CGPointMake(-frame.origin.x, -(size.y - (frame.origin.y + frame.size.height)));
CGContextDrawImage(newBitmap, CGRectMake(offset.x, offset.y, size.x, size.y), [bitmapContext CGImage]);
[bitmapContext setContext:newBitmap];
CGContextRelease(newBitmap);
}
- (void)cropTopEllipse:(CGRect)frame {
frame.origin.x = round(frame.origin.x);
frame.origin.y = round(frame.origin.y);
frame.size.width = round(frame.size.width);
frame.size.height = round(frame.size.height);
BMPoint size = [bitmapContext bitmapSize];
// It's kind of rude to prevent them from doing something kind of cool, so let's not.
// NSAssert(frame.origin.x >= 0 && frame.origin.x + frame.size.width <= size.x, @"Cropping frame must be within the bitmap.");
// NSAssert(frame.origin.y >= 0 && frame.origin.y + frame.size.height <= size.y, @"Cropping frame must be within the bitmap.");
CGContextRef newBitmap = [CGContextCreator newARGBBitmapContextWithSize:frame.size];
CGPoint offset = CGPointMake(-frame.origin.x, -(size.y - (frame.origin.y + frame.size.height)));
CGContextSaveGState(newBitmap);
CGContextBeginPath(newBitmap);
CGContextAddEllipseInRect(newBitmap, CGRectMake(0, 0, frame.size.width, frame.size.height));
CGContextClip(newBitmap);
CGContextDrawImage(newBitmap, CGRectMake(offset.x, offset.y, size.x, size.y), [bitmapContext CGImage]);
CGContextRestoreGState(newBitmap);
[bitmapContext setContext:newBitmap];
CGContextRelease(newBitmap);
}
- (CGImageRef)croppedImageWithFrame:(CGRect)frame {
BMPoint size = [bitmapContext bitmapSize];
// It's kind of rude to prevent them from doing something kind of cool, so let's not.
// NSAssert(frame.origin.x >= 0 && frame.origin.x + frame.size.width <= size.x, @"Cropping frame must be within the bitmap.");
// NSAssert(frame.origin.y >= 0 && frame.origin.y + frame.size.height <= size.y, @"Cropping frame must be within the bitmap.");
CGContextRef newBitmap = [CGContextCreator newARGBBitmapContextWithSize:frame.size];
CGPoint offset = CGPointMake(-frame.origin.x, -frame.origin.y);
CGContextDrawImage(newBitmap, CGRectMake(offset.x, offset.y, size.x, size.y), [bitmapContext CGImage]);
CGImageRef image = CGBitmapContextCreateImage(newBitmap);
CGContextRelease(newBitmap);
#if __has_feature(objc_arc) == 1
CGImageRef retainedAutorelease = (__bridge CGImageRef)CGImageReturnAutoreleased(image);
CGImageRelease(image);
return retainedAutorelease;
#else
CGImageContainer * container = [CGImageContainer imageContainerWithImage:image];
CGImageRelease(image);
return [container image];
#endif
}
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapDrawManipulator.h
================================================
//
// BitmapDrawManipulator.h
// FaceBlur
//
// Created by Alex Nichol on 7/1/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "BitmapContextManipulator.h"
@protocol BitmapDrawManipulator
@optional
- (void)drawImage:(CGImageRef)image inRect:(CGRect)rect;
- (void)drawEllipseInFrame:(CGRect)frame color:(CGColorRef)color;
@end
@interface BitmapDrawManipulator : BitmapContextManipulator
/**
* Overlays an image on the existing bitmap.
* @param image The image to be overlayed.
* @param rect The frame in which the image will be drawn.
* The coordinates for this begin at the top-left hand
* corner of the view.
*/
- (void)drawImage:(CGImageRef)image inRect:(CGRect)rect;
/**
* Draws a colored ellipse in a given rectangle.
* @param frame The rectangle in which to draw the ellipse
* @param color The fill color for the ellipse. The coordinates
* for this begin at the top-left hand corner of the view.
*/
- (void)drawEllipseInFrame:(CGRect)frame color:(CGColorRef)color;
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapDrawManipulator.m
================================================
//
// BitmapDrawManipulator.m
// FaceBlur
//
// Created by Alex Nichol on 7/1/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "BitmapDrawManipulator.h"
@implementation BitmapDrawManipulator
- (void)drawImage:(CGImageRef)image inRect:(CGRect)rect {
BMPoint size = [bitmapContext bitmapSize];
// It's kind of rude to prevent them from doing something kind of cool, so let's not.
// NSAssert(frame.origin.x >= 0 && frame.origin.x + frame.size.width <= size.x, @"Cropping frame must be within the bitmap.");
// NSAssert(frame.origin.y >= 0 && frame.origin.y + frame.size.height <= size.y, @"Cropping frame must be within the bitmap.");
CGPoint offset = CGPointMake(rect.origin.x, (size.y - (rect.origin.y + rect.size.height)));
CGContextRef context = [[self bitmapContext] context];
CGContextSaveGState(context);
CGContextDrawImage(context, CGRectMake(offset.x, offset.y, rect.size.width, rect.size.height), image);
CGContextRestoreGState(context);
[self.bitmapContext setNeedsUpdate:YES];
}
- (void)drawEllipseInFrame:(CGRect)frame color:(CGColorRef)color {
CGContextRef context = [[self bitmapContext] context];
CGContextSaveGState(context);
CGContextScaleCTM(context, 1, -1);
CGContextTranslateCTM(context, 0, -[bitmapContext bitmapSize].y);
CGContextSetFillColorWithColor(context, color);
CGContextFillEllipseInRect(context, frame);
CGContextRestoreGState(context);
[self.bitmapContext setNeedsUpdate:YES];
}
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapRotationManipulator.h
================================================
//
// RotatableBitmapRep.h
// ImageManip
//
// Created by Alex Nichol on 7/12/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "BitmapContextManipulator.h"
@protocol BitmapRotationManipulator
@optional
- (void)rotate:(CGFloat)degrees;
- (CGImageRef)imageByRotating:(CGFloat)degrees;
@end
@interface BitmapRotationManipulator : BitmapContextManipulator {
}
/**
* Rotate the image bitmap around its center by a certain number of degrees.
* @param degrees The degrees from 0 to 360. This is not measured in radians.
* @discussion This will resize the image if needed.
*/
- (void)rotate:(CGFloat)degrees;
/**
* Create a new image by rotating this image bitmap around its center by a specified
* number of degrees.
* @param degrees The degrees (not in radians) by which the image should be rotated.
* @discussion This will resize the image if needed.
*/
- (CGImageRef)imageByRotating:(CGFloat)degrees;
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapRotationManipulator.m
================================================
//
// RotatableBitmapRep.m
// ImageManip
//
// Created by Alex Nichol on 7/12/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "BitmapRotationManipulator.h"
#define DEGTORAD(x) (x * (M_PI / 180.0f))
static CGPoint locationForAngle (CGFloat angle, CGFloat hypotenuse) {
CGPoint p;
p.x = (CGFloat)cos((double)DEGTORAD(angle)) * hypotenuse;
p.y = (CGFloat)sin((double)DEGTORAD(angle)) * hypotenuse;
return p;
}
@implementation BitmapRotationManipulator
- (void)rotate:(CGFloat)degrees {
if (degrees == 0) return;
CGSize size = CGSizeMake([bitmapContext bitmapSize].x, [bitmapContext bitmapSize].y);
CGSize newSize = CGSizeZero;
/* Since the corners go off to the sides, we have to use the existing hypotenuse to calculate the new size
for the image. This is done using some basic trigonometry.
*/
CGFloat hypotenuse;
hypotenuse = (CGFloat)sqrt(pow((double)size.width / 2.0, 2.0) + pow((double)size.height / 2.0, 2.0));
CGPoint minP = CGPointMake(CGFLOAT_MAX, CGFLOAT_MAX);
CGPoint maxP = CGPointMake(CGFLOAT_MIN, CGFLOAT_MIN);
/* Find the angle for the corners. */
float firstAngle = (float)atan2((double)size.height / 2.0, (double)size.width / 2.0);
float secondAngle = (float)atan2((double)size.height / 2.0, (double)size.width / -2.0);
float thirdAngle = (float)atan2((double)size.height / -2.0, (double)size.width / -2.0);
float fourthAngle = (float)atan2((double)size.height / -2.0, (double)size.width / 2.0);
float angles[4] = {firstAngle, secondAngle, thirdAngle, fourthAngle};
/* Rotate the corners by the new degrees, finding out how outgoing
the corners will be. This will allow us to easily calculate
the new size of the image.
*/
for (int i = 0; i < 4; i++) {
// conver the angle to radians.
float deg = angles[i] * (float)(180.0f / M_PI);
CGPoint p1 = locationForAngle(deg + degrees, hypotenuse);
if (p1.x < minP.x) minP.x = p1.x;
if (p1.x > maxP.x) maxP.x = p1.x;
if (p1.y < minP.y) minP.y = p1.y;
if (p1.y > maxP.y) maxP.y = p1.y;
}
newSize.width = maxP.x - minP.x;
newSize.height = maxP.y - minP.y;
/* Figure out where the thing is going to go when rotated by the bottom left
corner. Use that information to translate it so that it rotates from the center.
*/
hypotenuse = (CGFloat)sqrt((pow(newSize.width / 2.0, 2) + pow(newSize.height / 2.0, 2)));
CGPoint newCenter;
float addAngle = (float)atan2((double)newSize.height / 2, (double)newSize.width / 2) * (float)(180.0f / M_PI);
newCenter.x = cos((float)DEGTORAD((degrees + addAngle))) * hypotenuse;
newCenter.y = sin((float)DEGTORAD((degrees + addAngle))) * hypotenuse;
CGPoint offsetCenter;
offsetCenter.x = (float)((float)newSize.width / 2.0f) - (float)newCenter.x;
offsetCenter.y = (float)((float)newSize.height / 2.0f) - (float)newCenter.y;
CGContextRef newContext = [CGContextCreator newARGBBitmapContextWithSize:newSize];
CGContextSaveGState(newContext);
CGContextTranslateCTM(newContext, (float)round((float)offsetCenter.x), (float)round((float)offsetCenter.y));
CGContextRotateCTM(newContext, (CGFloat)DEGTORAD(degrees));
CGRect drawRect;
drawRect.size = size;
drawRect.origin.x = (CGFloat)round((newSize.width / 2) - (size.width / 2));
drawRect.origin.y = (CGFloat)round((newSize.height / 2) - (size.height / 2));
CGContextDrawImage(newContext, drawRect, [bitmapContext CGImage]);
CGContextRestoreGState(newContext);
[bitmapContext setContext:newContext];
CGContextRelease(newContext);
}
- (CGImageRef)imageByRotating:(CGFloat)degrees {
if (degrees == 0) return [bitmapContext CGImage];
CGSize size = CGSizeMake([bitmapContext bitmapSize].x, [bitmapContext bitmapSize].y);
CGSize newSize = CGSizeZero;
/* Since the corners go off to the sides, we have to use the existing hypotenuse to calculate the new size
for the image. This is done using some basic trigonometry.
*/
CGFloat hypotenuse;
hypotenuse = (CGFloat)sqrt(pow((double)size.width / 2.0, 2.0) + pow((double)size.height / 2.0, 2.0));
CGPoint minP = CGPointMake(CGFLOAT_MAX, CGFLOAT_MAX);
CGPoint maxP = CGPointMake(CGFLOAT_MIN, CGFLOAT_MIN);
/* Find the angle for the corners. */
float firstAngle = (float)atan2((double)size.height / 2.0, (double)size.width / 2.0);
float secondAngle = (float)atan2((double)size.height / 2.0, (double)size.width / -2.0);
float thirdAngle = (float)atan2((double)size.height / -2.0, (double)size.width / -2.0);
float fourthAngle = (float)atan2((double)size.height / -2.0, (double)size.width / 2.0);
float angles[4] = {firstAngle, secondAngle, thirdAngle, fourthAngle};
/* Rotate the corners by the new degrees, finding out how outgoing
the corners will be. This will allow us to easily calculate
the new size of the image.
*/
for (int i = 0; i < 4; i++) {
// conver the angle to radians.
float deg = angles[i] * (float)(180.0f / M_PI);
CGPoint p1 = locationForAngle(deg + degrees, hypotenuse);
if (p1.x < minP.x) minP.x = p1.x;
if (p1.x > maxP.x) maxP.x = p1.x;
if (p1.y < minP.y) minP.y = p1.y;
if (p1.y > maxP.y) maxP.y = p1.y;
}
newSize.width = ceil(maxP.x - minP.x);
newSize.height = ceil(maxP.y - minP.y);
/* Figure out where the thing is going to go when rotated by the bottom left
corner. Use that information to translate it so that it rotates from the center.
*/
hypotenuse = (CGFloat)sqrt((pow(newSize.width / 2.0, 2) + pow(newSize.height / 2.0, 2)));
CGPoint newCenter;
float addAngle = (float)atan2((double)newSize.height / 2, (double)newSize.width / 2) * (float)(180.0f / M_PI);
newCenter.x = cos((float)DEGTORAD((degrees + addAngle))) * hypotenuse;
newCenter.y = sin((float)DEGTORAD((degrees + addAngle))) * hypotenuse;
CGPoint offsetCenter;
offsetCenter.x = (float)((float)newSize.width / 2.0f) - (float)newCenter.x;
offsetCenter.y = (float)((float)newSize.height / 2.0f) - (float)newCenter.y;
CGContextRef newContext = [CGContextCreator newARGBBitmapContextWithSize:newSize];
CGContextSaveGState(newContext);
CGContextTranslateCTM(newContext, (float)round((float)offsetCenter.x), (float)round((float)offsetCenter.y));
CGContextRotateCTM(newContext, (CGFloat)DEGTORAD(degrees));
CGRect drawRect;
drawRect.size = size;
drawRect.origin.x = (CGFloat)round((newSize.width / 2) - (size.width / 2));
drawRect.origin.y = (CGFloat)round((newSize.height / 2) - (size.height / 2));
CGContextDrawImage(newContext, drawRect, [bitmapContext CGImage]);
CGContextRestoreGState(newContext);
CGImageRef image = CGBitmapContextCreateImage(newContext);
void * buff = CGBitmapContextGetData(newContext);
CGContextRelease(newContext);
free(buff);
#if __has_feature(objc_arc) == 1
id retainedImage = CGImageReturnAutoreleased(image);
CGImageRelease(image);
return (__bridge CGImageRef)retainedImage;
#else
CGImageContainer * container = [CGImageContainer imageContainerWithImage:image];
CGImageRelease(image);
return [container image];
#endif
}
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapScaleManipulator.h
================================================
//
// ScalableBitmapRep.h
// ImageManip
//
// Created by Alex Nichol on 7/12/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "BitmapContextManipulator.h"
@protocol BitmapScaleManipulator <NSObject>
@optional
- (void)setSize:(BMPoint)aSize;
- (void)setSizeFittingFrame:(BMPoint)aSize;
- (void)setSizeFillingFrame:(BMPoint)aSize;
@end
@interface BitmapScaleManipulator : BitmapContextManipulator {
}
/**
* Stretches the bitmap context to a specified size.
* @param aSize The new size to make the bitmap.
* If this is the same as the current size, the bitmap
* will not be changed.
*/
- (void)setSize:(BMPoint)aSize;
/**
* Scales the image to fit a particular frame without stretching (bringing out of scale).
* @param aSize The size to which the image scaled.
* @discussion The actual image itself will most likely be smaller than the specified
* size, leaving transparent edges to make the image fit the exact size.
*/
- (void)setSizeFittingFrame:(BMPoint)aSize;
/**
* Scales the image to fill a particular frame without stretching.
* This will most likely cause the left and right or top and bottom
* edges of the image to be cut off.
* @param aSize The size that the image will be forced to fill.
*/
- (void)setSizeFillingFrame:(BMPoint)aSize;
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapScaleManipulator.m
================================================
//
// ScalableBitmapRep.m
// ImageManip
//
// Created by Alex Nichol on 7/12/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "BitmapScaleManipulator.h"
@implementation BitmapScaleManipulator
- (void)setSize:(BMPoint)aSize {
CGContextRef newContext = [CGContextCreator newARGBBitmapContextWithSize:CGSizeMake(aSize.x, aSize.y)];
CGImageRef image = [bitmapContext CGImage];
CGContextDrawImage(newContext, CGRectMake(0, 0, aSize.x, aSize.y), image);
[bitmapContext setContext:newContext];
CGContextRelease(newContext);
}
- (void)setSizeFittingFrame:(BMPoint)aSize {
CGSize oldSize = CGSizeMake([bitmapContext bitmapSize].x, [bitmapContext bitmapSize].y);
CGSize newSize = CGSizeMake(aSize.x, aSize.y);
float wratio = newSize.width / oldSize.width;
float hratio = newSize.height / oldSize.height;
float scaleRatio;
if (wratio < hratio) {
scaleRatio = wratio;
} else {
scaleRatio = hratio;
}
scaleRatio = scaleRatio;
CGSize newContentSize = CGSizeMake(oldSize.width * scaleRatio, oldSize.height * scaleRatio);
CGImageRef image = [bitmapContext CGImage];
CGContextRef newContext = [CGContextCreator newARGBBitmapContextWithSize:CGSizeMake(aSize.x, aSize.y)];
CGContextDrawImage(newContext, CGRectMake(newSize.width / 2 - (newContentSize.width / 2),
newSize.height / 2 - (newContentSize.height / 2),
newContentSize.width, newContentSize.height), image);
[bitmapContext setContext:newContext];
CGContextRelease(newContext);
}
- (void)setSizeFillingFrame:(BMPoint)aSize {
CGSize oldSize = CGSizeMake([bitmapContext bitmapSize].x, [bitmapContext bitmapSize].y);
CGSize newSize = CGSizeMake(aSize.x, aSize.y);
float wratio = newSize.width / oldSize.width;
float hratio = newSize.height / oldSize.height;
float scaleRatio;
if (wratio > hratio) { // only difference from -setSizeFittingFrame:
scaleRatio = wratio;
} else {
scaleRatio = hratio;
}
scaleRatio = scaleRatio;
CGSize newContentSize = CGSizeMake(oldSize.width * scaleRatio, oldSize.height * scaleRatio);
CGImageRef image = [bitmapContext CGImage];
CGContextRef newContext = [CGContextCreator newARGBBitmapContextWithSize:CGSizeMake(aSize.x, aSize.y)];
CGContextDrawImage(newContext, CGRectMake(newSize.width / 2 - (newContentSize.width / 2),
newSize.height / 2 - (newContentSize.height / 2),
newContentSize.width, newContentSize.height), image);
[bitmapContext setContext:newContext];
CGContextRelease(newContext);
}
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/BGRSLoupeLayer.h
================================================
/**
* BGRSLoupeLayer.h
* Copyright (c) 2011, Benjamin Guest.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* -Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* -Neither the name of Benjamin Guest nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
@class RSColorPickerView;
@interface BGRSLoupeLayer : CALayer {
BOOL isReadyToDismiss;
BOOL isRunningInitialAnimation;
}
@property (nonatomic) CGPoint loupeCenter;
@property (nonatomic, weak) RSColorPickerView *colorPicker;
#pragma mark - Drawing
- (void)drawGridInContext:(CGContextRef)ctx;
#pragma mark - Animation
- (void)appearInColorPicker:(RSColorPickerView *)aColorPicker;
- (void)disappear;
- (void)disappearAnimated:(BOOL)anim;
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/BGRSLoupeLayer.m
================================================
/**
* BGRSLoupeLayer.m
* Copyright (c) 2011, Benjamin Guest.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* -Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* -Neither the name of Benjamin Guest nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#import "BGRSLoupeLayer.h"
#import "RSColorPickerView.h"
@interface BGRSLoupeLayer ()
@property (nonatomic) struct CGPath *gridCirclePath;
- (void)drawGlintInContext:(CGContextRef)ctx;
- (UIImage *)loupeImage;
@end
@implementation BGRSLoupeLayer
@synthesize loupeCenter, colorPicker;
const CGFloat LOUPE_SIZE = 85, SHADOW_SIZE = 6, RIM_THICKNESS = 3.0;
const int NUM_PIXELS = 5, NUM_SKIP = 15;
- (id)init {
self = [super init];
if (self) {
CGFloat size = LOUPE_SIZE+2*SHADOW_SIZE;
self.bounds = CGRectMake(-size/2,-size/2,size,size);
self.anchorPoint = CGPointMake(0.5, 1);
UIImage *loupeImage = [self loupeImage];
CALayer *loupeLayer = [CALayer layer];
loupeLayer.bounds = self.bounds;
loupeLayer.position = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
loupeLayer.contents = (id)loupeImage.CGImage;
[self addSublayer:loupeLayer];
}
return self;
}
- (void)dealloc {
self.colorPicker = nil;
if (_gridCirclePath) CGPathRelease(_gridCirclePath);
}
- (struct CGPath *)gridCirclePath {
if (_gridCirclePath == NULL) {
CGMutablePathRef circlePath = CGPathCreateMutable();
const CGFloat radius = LOUPE_SIZE/2;
CGPathAddArc(circlePath, nil, 0, 0, radius-RIM_THICKNESS/2, 0, 2*M_PI, YES);
_gridCirclePath = circlePath;
}
return _gridCirclePath;
}
- (UIImage *)loupeImage {
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGFloat size = LOUPE_SIZE+2*SHADOW_SIZE;
CGContextTranslateCTM(ctx, size/2, size/2);
// Draw Shadow
CGContextSaveGState(ctx); // Save before shadow
UIBezierPath *inner = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(self.bounds, SHADOW_SIZE + 1, SHADOW_SIZE + 1)];
UIBezierPath *outer = [UIBezierPath bezierPathWithRect:self.bounds];
[outer appendPath:inner];
outer.usesEvenOddFillRule = YES;
[outer addClip];
CGSize shadowOffset = CGSizeMake(0,SHADOW_SIZE/2);
CGContextSetShadowWithColor(ctx, shadowOffset, SHADOW_SIZE/2, [UIColor blackColor].CGColor);
CGContextAddEllipseInRect(ctx, CGRectMake(-LOUPE_SIZE/2, -LOUPE_SIZE/2, LOUPE_SIZE, LOUPE_SIZE));
CGContextSetFillColorWithColor(ctx, [colorPicker selectionColor].CGColor);
CGContextFillPath(ctx);
CGContextRestoreGState(ctx); // Restore context after shadow
// Create Cliping Area
CGContextSaveGState(ctx); // Save context for cliping
CGContextAddPath(ctx, self.gridCirclePath); // Clip gird drawing to inside of loupe
CGContextClip(ctx);
[self drawGlintInContext:ctx];
CGContextRestoreGState(ctx); // Restor from clip drawing
// Stroke Rim of Loupe
CGContextSetLineWidth(ctx, RIM_THICKNESS);
CGContextSetStrokeColorWithColor(ctx, [UIColor blackColor].CGColor);
CGContextAddPath(ctx, self.gridCirclePath);
CGContextStrokePath(ctx);
// Draw center of rim loupe
CGContextSetLineWidth(ctx, RIM_THICKNESS-1);
CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);
CGContextAddPath(ctx, self.gridCirclePath);
CGContextStrokePath(ctx);
const CGFloat w = ceilf(LOUPE_SIZE/NUM_PIXELS);
// Draw Selection Square
CGFloat xyOffset = -(w+1)/2;
CGRect selectedRect = CGRectMake(xyOffset, xyOffset, w, w);
CGContextAddRect(ctx, selectedRect);
CGContextSetStrokeColorWithColor(ctx, [UIColor blackColor].CGColor);
CGContextSetLineWidth(ctx, 1.0);
CGContextStrokePath(ctx);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
- (void)drawInContext:(CGContextRef)ctx {
CGContextAddPath(ctx, self.gridCirclePath); // Clip gird drawing to inside of loupe
CGContextClip(ctx);
// Draw Opacity Background
NSInteger numCols = 6;
CGFloat loupeLength = LOUPE_SIZE;
CGFloat pixelLength = loupeLength / numCols;
UIColor *colorWhite = [UIColor whiteColor];
UIColor *colorGray = [UIColor grayColor];
UIColor *color1;
UIColor *color2;
UIColor *pixelColor;
for (int j = 0; j < numCols; j++){
color1 = (j % 2) ? colorWhite : colorGray;
color2 = (j % 2) ? colorGray : colorWhite;
for (int i = 0; i < numCols; i++){
CGRect pixelRect = CGRectMake((pixelLength * i) - (loupeLength / 2),
(pixelLength * j) - (loupeLength / 2),
pixelLength,
pixelLength);
pixelColor = (i % 2) ? color1 : color2;
CGContextSetFillColorWithColor(ctx, pixelColor.CGColor);
CGContextFillRect(ctx, pixelRect);
}
}
[self drawGridInContext:ctx];
}
- (void)drawGridInContext:(CGContextRef)ctx {
const CGFloat w = ceilf(LOUPE_SIZE/NUM_PIXELS);
CGPoint currentPoint = [colorPicker selection];
currentPoint.x -= NUM_PIXELS*NUM_SKIP/2;
currentPoint.y -= NUM_PIXELS*NUM_SKIP/2;
int i,j;
// Draw Pixelated Loupe
for (j=0; j<NUM_PIXELS; j++){
for (i=0; i<NUM_PIXELS; i++){
CGRect pixelRect = CGRectMake(w*i-LOUPE_SIZE/2, w*j-LOUPE_SIZE/2, w, w);
UIColor *pixelColor = [self.colorPicker colorAtPoint:currentPoint];
CGContextSetFillColorWithColor(ctx, pixelColor.CGColor);
CGContextFillRect(ctx, pixelRect);
currentPoint.x += NUM_SKIP;
}
currentPoint.x -= NUM_PIXELS*NUM_SKIP;
currentPoint.y += NUM_SKIP;
}
}
- (void)drawGlintInContext:(CGContextRef)ctx{
// Draw Top Glint
CGFloat radius = LOUPE_SIZE/2;
CGFloat glintRadius = 1.50*LOUPE_SIZE;
CGFloat drop = 0.25*LOUPE_SIZE;
CGFloat yOff = drop + glintRadius - radius;
// Calculations
CGFloat glintAngle1 = acosf((yOff*yOff + glintRadius*glintRadius - radius*radius)
/(2*yOff*glintRadius));
CGFloat glintAngle2 = asinf(glintRadius/radius * sinf(glintAngle1));
CGFloat glintEdgeHeight = -radius*sinf(glintAngle2-M_PI_2);
// Add bottom arc
CGContextAddArc(ctx, 0, yOff, glintRadius, -M_PI_2+glintAngle1, -M_PI_2-glintAngle1, YES);
// Add top arc
CGContextAddArc(ctx, 0, 0, radius, -M_PI_2-glintAngle2, -M_PI_2+glintAngle2, NO);
CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);
//CGContextStrokePath(ctx);
//return;
CGContextClosePath(ctx);
CGContextSaveGState(ctx); // Save context for cliping
CGContextClip(ctx);
CGColorSpaceRef space = CGColorSpaceCreateDeviceGray();
NSArray *colors = @[(id)[UIColor colorWithWhite:1.0 alpha:0.65].CGColor,
(id)[UIColor colorWithWhite:1.0 alpha:0.15].CGColor];
CGGradientRef myGradient = CGGradientCreateWithColors(space, (__bridge CFArrayRef)colors, NULL);
CGContextDrawLinearGradient(ctx, myGradient ,CGPointMake(0,-radius), CGPointMake(0,-glintEdgeHeight), 0);
CGGradientRelease(myGradient);
CGContextRestoreGState(ctx);
// Draw bottom glint
yOff = 0.40*LOUPE_SIZE;
radius = 0.40*LOUPE_SIZE;
CGPoint glintCenter = CGPointMake(0, yOff);
CGContextAddArc(ctx, 0, yOff, radius, 0, M_2_PI, YES);
CGContextSaveGState(ctx); // Save context for cliping
CGContextClip(ctx);
colors = @[(id)[UIColor colorWithWhite:1.0 alpha:0.5].CGColor,
(id)[UIColor colorWithWhite:1.0 alpha:0.0].CGColor];
myGradient = CGGradientCreateWithColors(space, (__bridge CFArrayRef)colors, NULL);
CGContextDrawRadialGradient(ctx, myGradient, glintCenter, 0.0, glintCenter, radius, 0.0);
CGGradientRelease(myGradient);
CGContextRestoreGState(ctx);
// Release objects
CGColorSpaceRelease(space);
}
#pragma mark - Animation -
static NSString *const kAppearKey = @"cp_l_appear";
- (void)appearInColorPicker:(RSColorPickerView*)aColorPicker{
if (self.colorPicker != aColorPicker) {
self.colorPicker = aColorPicker;
}
[self removeAllAnimations];
self.transform = CATransform3DIdentity;
isReadyToDismiss = NO;
// Add Layer to color picker
[CATransaction setDisableActions:YES];
[self.colorPicker.layer addSublayer:self];
// Animate Arival
isRunningInitialAnimation = YES;
CAKeyframeAnimation *springEffect = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
springEffect.values = @[@(0.1), @(1.4), @(0.95), @(1)];
springEffect.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
springEffect.removedOnCompletion = NO;
springEffect.duration = 0.35f;
springEffect.delegate = self;
// Animate
[self addAnimation:springEffect forKey:kAppearKey];
}
/**
* Disapear removes the loupe view from the color picker by shrinking it down to zero
*/
static NSString *const kDisappearKey = @"cp_l_disappear";
- (void)disappear {
[self disappearAnimated:YES];
}
- (void)disappearAnimated:(BOOL)anim {
isReadyToDismiss = YES;
if (isRunningInitialAnimation) return;
if (!anim) {
[self removeFromSuperlayer];
return;
}
self.transform = CATransform3DMakeScale(0.01, 0.01, 1);
CABasicAnimation *disapear = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
disapear.fromValue = @(1);
disapear.duration = 0.1f;
disapear.delegate = self;
disapear.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
disapear.removedOnCompletion = NO;
[self addAnimation:disapear forKey:kDisappearKey];
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
if (anim == [self animationForKey:kDisappearKey]){
if (!flag) return;
[self removeFromSuperlayer];
self.transform = CATransform3DIdentity;
} else if (anim == [self animationForKey:kAppearKey]) {
isRunningInitialAnimation = NO;
if (isReadyToDismiss) {
[self disappear];
}
}
}
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/RSColorFunctions.h
================================================
//
// RSColorFunctions.h
// RSColorPicker
//
// Created by Ryan Sullivan on 3/12/13.
//
#import <UIKit/UIKit.h>
#import "ANImageBitmapRep.h"
BMPixel RSPixelFromHSV(CGFloat H, CGFloat S, CGFloat V);
void RSHSVFromPixel(BMPixel pixel, CGFloat *h, CGFloat *s, CGFloat *v);
// four floats will be placed into `components`
void RSGetComponentsForColor(CGFloat *components, UIColor *color);
UIImage * RSUIImageWithScale(UIImage *img, CGFloat scale);
UIImage * RSOpacityBackgroundImage(CGFloat length, CGFloat scale, UIColor *color);
UIColor * RSRandomColorOpaque(BOOL isOpaque);
================================================
FILE: RSColorPicker/ColorPickerClasses/RSColorFunctions.m
================================================
//
// RSColorFunctions.m
// RSColorPicker
//
// Created by Ryan Sullivan on 3/12/13.
//
#import "RSColorFunctions.h"
BMPixel RSPixelFromHSV(CGFloat H, CGFloat S, CGFloat V)
{
if (S == 0) {
return BMPixelMake(V, V, V, 1.0);
}
if (H == 1) {
H = 0;
}
CGFloat var_h = H * 6.0;
// Verified `H` is never <0 so (int) is OK:
int var_i = (int)var_h;
CGFloat var_1 = V * (1.0 - S);
if (var_i == 0) {
CGFloat var_3 = V * (1.0 - S * (1.0 - (var_h - var_i)));
return BMPixelMake(V, var_3, var_1, 1.0);
} else if (var_i == 1) {
CGFloat var_2 = V * (1.0 - S * (var_h - var_i));
return BMPixelMake(var_2, V, var_1, 1.0);
} else if (var_i == 2) {
CGFloat var_3 = V * (1.0 - S * (1.0 - (var_h - var_i)));
return BMPixelMake(var_1, V, var_3, 1.0);
} else if (var_i == 3) {
CGFloat var_2 = V * (1.0 - S * (var_h - var_i));
return BMPixelMake(var_1, var_2, V, 1.0);
} else if (var_i == 4) {
CGFloat var_3 = V * (1.0 - S * (1.0 - (var_h - var_i)));
return BMPixelMake(var_3, var_1, V, 1.0);
}
CGFloat var_2 = V * (1.0 - S * (var_h - var_i));
return BMPixelMake(V, var_1, var_2, 1.0);
}
void RSHSVFromPixel(BMPixel pixel, CGFloat *h, CGFloat *s, CGFloat *v)
{
UIColor *color = [UIColor colorWithRed:pixel.red green:pixel.green blue:pixel.blue alpha:1];
[color getHue:h saturation:s brightness:v alpha:NULL];
}
void RSGetComponentsForColor(CGFloat *components, UIColor *color)
{
// First try to get the components the right way
if ([color getRed:&components[0] green:&components[1] blue:&components[2] alpha:&components[3]]) {
return;
} else if ([color getWhite:&components[0] alpha:&components[3]]) {
components[1] = components[0];
components[2] = components[0];
return;
}
// *Then* resort to this good old hack.
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char resultingPixel[4] = {0};
CGContextRef context = CGBitmapContextCreate(&resultingPixel, 1, 1, 8, 4, rgbColorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedLast);
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, CGRectMake(0, 0, 1, 1));
CGContextRelease(context);
CGColorSpaceRelease(rgbColorSpace);
for (int component = 0; component < 4; component++) {
components[component] = resultingPixel[component] / 255.0;
}
if (components[3] > 0)
{
components[0] /= components[3];
components[1] /= components[3];
components[2] /= components[3];
}
}
UIImage * RSUIImageWithScale(UIImage *img, CGFloat scale)
{
return [UIImage imageWithCGImage:img.CGImage scale:scale orientation:UIImageOrientationUp];
}
/**
* Returns image that looks like a checkered background.
*/
UIImage * RSOpacityBackgroundImage(CGFloat length, CGFloat scale, UIColor *color) {
NSCAssert(scale > 0, @"Tried to create opacity background image with scale 0");
NSCAssert(length > 0, @"Tried to create opacity background image with length 0");
UIBezierPath *rectanglePath = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, length*0.5, length*0.5)];
UIBezierPath *rectangle2Path = [UIBezierPath bezierPathWithRect:CGRectMake(length*0.5, length*0.5, length*0.5, length*0.5)];
UIBezierPath *rectangle3Path = [UIBezierPath bezierPathWithRect:CGRectMake(0, length*0.5, length*0.5, length*0.5)];
UIBezierPath *rectangle4Path = [UIBezierPath bezierPathWithRect:CGRectMake(length*0.5, 0, length*0.5, length*0.5)];
UIGraphicsBeginImageContextWithOptions(CGSizeMake(length, length), NO, scale);
[color setFill];
[rectanglePath fill];
[rectangle2Path fill];
[[UIColor whiteColor] setFill];
[rectangle3Path fill];
[rectangle4Path fill];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return RSUIImageWithScale(image, scale);
}
UIColor * RSRandomColorOpaque(BOOL isOpaque) {
/*
From https://gist.github.com/kylefox/1689973
***
Distributed under The MIT License:
http://opensource.org/licenses/mit-license.php
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Alpha modifications for RSColorPicker test project
*/
CGFloat hue = ( arc4random() % 256 / 256.0 ); // 0.0 to 1.0
CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from white
CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from black
CGFloat alpha = 1;
if (!isOpaque) {
alpha = ( arc4random() % 128 / 256.0 ) + 0.5;
}
return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha];
}
================================================
FILE: RSColorPicker/ColorPickerClasses/RSColorPickerState.h
================================================
//
// RSColorPickerState.h
// RSColorPicker
//
// Created by Alex Nichol on 12/16/13.
//
#import <Foundation/Foundation.h>
#import "RSColorFunctions.h"
/**
* Represents the state of a color picker. This includes
* the position on the color picker (for a square picker) that
* is selected.
*
* Terms used:
* "size" - the diameter of the color picker
* "padding" - the amount of pixels on each side of the color picker
* reserved for padding
*/
@interface RSColorPickerState : NSObject {
CGPoint scaledRelativePoint; // H & S
CGFloat brightness; // V
CGFloat alpha; // A
}
@property (readonly) CGFloat hue, saturation, brightness, alpha;
/**
* Creates a state with a 1.0 alpha and 1.0 brightness that would arise
* by selecting `point` on a color picker of diameter `size` and padding `padding`.
*/
+ (RSColorPickerState *)stateForPoint:(CGPoint)point size:(CGFloat)size padding:(CGFloat)padding;
/**
* Create a state with a given color.
*/
- (id)initWithColor:(UIColor *)selectionColor;
/**
* Create a state given a point on the unit circle and brightness+alpha
*/
- (id)initWithScaledRelativePoint:(CGPoint)p brightness:(CGFloat)V alpha:(CGFloat)A;
/**
* Create a state given HSVA components.
*/
- (id)initWithHue:(CGFloat)H saturation:(CGFloat)S brightness:(CGFloat)V alpha:(CGFloat)A;
- (UIColor *)color;
/**
* Returns the position of this state on a color picker of size `size` and padding `padding`.
* Note: this point may be outside of the unit circle if a point outside the unit circle
* was picked to generate this state.
*/
- (CGPoint)selectionLocationWithSize:(CGFloat)size padding:(CGFloat)padding;
// This class is immutable, so these are helpful!
- (RSColorPickerState *)stateBySettingBrightness:(CGFloat)newBright;
- (RSColorPickerState *)stateBySettingAlpha:(CGFloat)newAlpha;
- (RSColorPickerState *)stateBySettingHue:(CGFloat)newHue;
- (RSColorPickerState *)stateBySettingSaturation:(CGFloat)newSaturation;
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/RSColorPickerState.m
================================================
//
// RSColorPickerState.m
// RSColorPicker
//
// Created by Alex Nichol on 12/16/13.
//
#import "RSColorPickerState.h"
static CGFloat _calculateHue(CGPoint point);
static CGFloat _calculateSaturation(CGPoint point);
static CGPoint _calculatePoint(CGFloat hue, CGFloat saturation);
@implementation RSColorPickerState
@synthesize brightness, alpha;
- (CGFloat)hue {
return _calculateHue(scaledRelativePoint);
}
- (CGFloat)saturation {
return _calculateSaturation(scaledRelativePoint);
}
- (UIColor *)color {
return [UIColor colorWithHue:self.hue saturation:self.saturation brightness:brightness alpha:alpha];
}
+ (RSColorPickerState *)stateForPoint:(CGPoint)point size:(CGFloat)size padding:(CGFloat)padding {
// calculate everything we need to know
CGPoint relativePoint = CGPointMake(point.x - (size / 2.0), (size / 2.0) - point.y);
CGPoint scaledRelativePoint = relativePoint;
scaledRelativePoint.x /= (size / 2.0) - padding;
scaledRelativePoint.y /= (size / 2.0) - padding;
return [[RSColorPickerState alloc] initWithScaledRelativePoint:scaledRelativePoint
brightness:1 alpha:1];
}
- (id)initWithColor:(UIColor *)_selectionColor {
if ((self = [super init])) {
CGFloat rgba[4];
RSGetComponentsForColor(rgba, _selectionColor);
UIColor * selectionColor = [UIColor colorWithRed:rgba[0] green:rgba[1] blue:rgba[2] alpha:rgba[3]];
CGFloat hue, saturation;
[selectionColor getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha];
scaledRelativePoint = _calculatePoint(hue, saturation);
}
return self;
}
- (id)initWithScaledRelativePoint:(CGPoint)p brightness:(CGFloat)V alpha:(CGFloat)A {
if ((self = [super init])) {
scaledRelativePoint = p;
brightness = V;
alpha = A;
}
return self;
}
- (id)initWithHue:(CGFloat)H saturation:(CGFloat)S brightness:(CGFloat)V alpha:(CGFloat)A {
if ((self = [super init])) {
scaledRelativePoint = _calculatePoint(H, S);
brightness = V;
alpha = A;
}
return self;
}
- (CGPoint)selectionLocationWithSize:(CGFloat)size padding:(CGFloat)padding {
CGPoint unscaled = scaledRelativePoint;
unscaled.x *= (size / 2.0) - padding;
unscaled.y *= (size / 2.0) - padding;
return CGPointMake(unscaled.x + (size / 2.0), (size / 2.0) - unscaled.y);
}
#pragma mark - Modification
- (RSColorPickerState *)stateBySettingBrightness:(CGFloat)newBright {
return [[RSColorPickerState alloc] initWithScaledRelativePoint:scaledRelativePoint brightness:newBright alpha:alpha];
}
- (RSColorPickerState *)stateBySettingAlpha:(CGFloat)newAlpha {
return [[RSColorPickerState alloc] initWithScaledRelativePoint:scaledRelativePoint brightness:brightness alpha:newAlpha];
}
- (RSColorPickerState *)stateBySettingHue:(CGFloat)newHue {
CGPoint newPoint = _calculatePoint(newHue, self.saturation);
return [[RSColorPickerState alloc] initWithScaledRelativePoint:newPoint brightness:brightness alpha:alpha];
}
- (RSColorPickerState *)stateBySettingSaturation:(CGFloat)newSaturation {
CGPoint newPoint = _calculatePoint(self.hue, newSaturation);
return [[RSColorPickerState alloc] initWithScaledRelativePoint:newPoint brightness:brightness alpha:alpha];
}
#pragma mark - Debugging
- (NSString *)description {
NSMutableString *description = [NSMutableString stringWithFormat:@"<%@: %p { ", NSStringFromClass([self class]), self];
[description appendFormat:@"scaledPoint:%@ ", NSStringFromCGPoint(scaledRelativePoint)];
[description appendFormat:@"brightness:%f ", brightness];
[description appendFormat:@"alpha:%f", alpha];
[description appendString:@"} >"];
return description;
}
@end
#pragma mark - Helper Functions
static CGFloat _calculateHue(CGPoint point) {
double angle = atan2(point.y, point.x);
if (angle < 0) angle += M_PI * 2;
return angle / (M_PI * 2);
}
static CGFloat _calculateSaturation(CGPoint point) {
CGFloat radius = sqrt(pow(point.x, 2) + pow(point.y, 2));
if (radius > 1) {
radius = 1;
}
return radius;
}
static CGPoint _calculatePoint(CGFloat hue, CGFloat saturation) {
// convert to HSV
CGFloat angle = hue * (2.0 * M_PI);
CGFloat pointX = cos(angle) * saturation;
CGFloat pointY = sin(angle) * saturation;
return CGPointMake(pointX, pointY);
}
================================================
FILE: RSColorPicker/ColorPickerClasses/RSColorPickerView.h
================================================
//
// RSColorPickerView.h
// RSColorPicker
//
// Created by Ryan Sullivan on 8/12/11.
//
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import <Accelerate/Accelerate.h>
@class RSColorPickerView, BGRSLoupeLayer;
@protocol RSColorPickerViewDelegate <NSObject>
/**
* Called everytime the color picker's selection/color is changed.
* Don't do expensive operations here as it will slow down your app.
*/
- (void)colorPickerDidChangeSelection:(RSColorPickerView *)colorPicker;
@optional
- (void)colorPicker:(RSColorPickerView *)colorPicker touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)colorPicker:(RSColorPickerView *)colorPicker touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
@end
IB_DESIGNABLE
@interface RSColorPickerView : UIView
/**
* Specifies if the color picker should be drawn as a circle, or as a square.
*/
@property (nonatomic) IBInspectable BOOL cropToCircle;
/**
* The brightness of the current selection
*/
@property (nonatomic) CGFloat brightness;
/**
* The opacity of the current selection.
*/
@property (nonatomic) CGFloat opacity;
/**
* The selection color.
* This setter may modify `brightness` and `opacity` as necessary.
*/
@property (nonatomic) UIColor * selectionColor;
/**
* The delegate
*/
@property (nonatomic, weak) id <RSColorPickerViewDelegate> delegate;
/**
* The current point (in the color picker's bounds) of the selected color.
*/
@property (readwrite) CGPoint selection;
/**
* The distance around the edges of the color picker that is drawn for padding.
* Colors are cut-off before this distance so that the user can pick all colors.
*/
@property (readonly) CGFloat paddingDistance;
/**
* Specifies if the loupe should be drawn or not.
* Default: YES (show).
*/
@property (nonatomic) BOOL showLoupe;
/**
* The color at a given point in the color picker's bounds.
*/
- (UIColor *)colorAtPoint:(CGPoint)point;
/**
* Methods that create/cache data needed to create a color picker.
* These run async (except where noted) and can help the overall UX.
*/
+ (void)prepareForDiameter:(CGFloat)diameter;
+ (void)prepareForDiameter:(CGFloat)diameter padding:(CGFloat)padding;
+ (void)prepareForDiameter:(CGFloat)diameter scale:(CGFloat)scale;
+ (void)prepareForDiameter:(CGFloat)diameter scale:(CGFloat)scale padding:(CGFloat)padding;
+ (void)prepareForDiameter:(CGFloat)diameter scale:(CGFloat)scale padding:(CGFloat)padding inBackground:(BOOL)bg;
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/RSColorPickerView.m
================================================
//
// RSColorPickerView.m
// RSColorPicker
//
// Created by Ryan Sullivan on 8/12/11.
//
#import "ANImageBitmapRep.h"
#import "BGRSLoupeLayer.h"
#import "RSColorFunctions.h"
#import "RSColorPickerState.h"
#import "RSColorPickerView.h"
#import "RSGenerateOperation.h"
#import "RSSelectionLayer.h"
#define kSelectionViewSize 22
@interface RSColorPickerView () {
struct {
unsigned int bitmapNeedsUpdate:1;
} _colorPickerViewFlags;
RSColorPickerState * state;
}
@property (nonatomic) ANImageBitmapRep *rep;
/**
* A path which represents the shape of the color picker palette,
* padded by 1/2 the selectionViews's size.
*/
@property (nonatomic) UIBezierPath *activeAreaShape;
/**
* The layer which contains just the currently selected color
* within the -selectionLayer.
*/
@property (nonatomic) CALayer *selectionColorLayer;
/**
* Layer which shows the circular selection "target".
*/
@property (nonatomic) RSSelectionLayer *selectionLayer;
/**
* The layer which will ultimately contain the generated
* palette image.
*/
@property (nonatomic) CALayer *gradientLayer;
/**
* A black layer. As the brightness is lowered, the opacity
* of brightnessLayer is increased and thus this view becomes more
* visible.
*/
@property (nonatomic) CALayer *brightnessLayer;
/**
* A checkerboard pattern indicating opacity.
* As opacity is lowered, the alpha of this view becomes
* closer to 1.
*/
@property (nonatomic) CALayer *opacityLayer;
/**
* Layer that will contain the gradientLayer, brightnessLayer,
* opacityLayer.
*/
@property (nonatomic) CALayer *contentsLayer;
@property (nonatomic) BGRSLoupeLayer *loupeLayer;
/**
* Gets updated to the scale of the current UIWindow.
*/
@property (nonatomic) CGFloat scale;
- (void)initRoutine;
- (void)resizeOrRescale;
// Called to generate the _rep ivar and set it.
- (void)genBitmap;
// Called to generate the bezier paths
- (void)generateBezierPaths;
// Called to update the UI for the current state.
- (void)handleStateChanged;
// Called to handle a state change (optionally disabling CA Actions for loupe).
- (void)handleStateChangedDisableActions:(BOOL)disable;
// touch handling
- (CGPoint)validPointForTouch:(CGPoint)touchPoint;
- (RSColorPickerState *)stateForPoint:(CGPoint)point;
- (void)updateStateForTouchPoint:(CGPoint)point;
// metrics
- (CGFloat)paletteDiameter;
@end
@implementation RSColorPickerView
#pragma mark - Object Lifecycle -
- (id)initWithFrame:(CGRect)frame {
CGFloat square = fmin(frame.size.height, frame.size.width);
frame.size = CGSizeMake(square, square);
self = [super initWithFrame:frame];
if (self) {
[self initRoutine];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self initRoutine];
}
return self;
}
- (void)initRoutine {
// Show or hide the loupe. Default: show.
self.showLoupe = YES;
self.opaque = YES;
self.backgroundColor = [UIColor clearColor];
_colorPickerViewFlags.bitmapNeedsUpdate = NO;
// the view used to select the colour
self.selectionLayer = [RSSelectionLayer layer];
self.selectionLayer.frame = CGRectMake(0.0, 0.0, kSelectionViewSize, kSelectionViewSize);
[self.selectionLayer setNeedsDisplay];
self.selectionColorLayer = [CALayer layer];
self.selectionColorLayer.cornerRadius = kSelectionViewSize / 2;
self.selectionColorLayer.frame = CGRectMake(0.0, 0.0, kSelectionViewSize, kSelectionViewSize);
self.brightnessLayer = [CALayer layer];
self.brightnessLayer.frame = self.bounds;
self.brightnessLayer.backgroundColor = [UIColor blackColor].CGColor;
self.gradientLayer = [CALayer layer];
self.gradientLayer.frame = self.bounds;
self.opacityLayer = [CALayer layer];
self.contentsLayer = [CALayer layer];
self.contentsLayer.frame = self.bounds;
[self.contentsLayer addSublayer:self.gradientLayer];
[self.contentsLayer addSublayer:self.brightnessLayer];
[self.contentsLayer addSublayer:self.selectionColorLayer];
[self.contentsLayer addSublayer:self.opacityLayer];
[self.contentsLayer addSublayer:self.selectionLayer];
[self.layer addSublayer:self.contentsLayer];
[self handleStateChangedDisableActions:NO];
self.contentsLayer.masksToBounds = YES;
self.cropToCircle = NO;
self.selectionColor = [UIColor whiteColor];
}
- (void)resizeOrRescale {
if (!self.window || self.frame.size.width == 0 || self.frame.size.height == 0) {
self.scale = 0;
[self.loupeLayer disappearAnimated:NO];
return;
}
self.scale = self.window.screen.scale;
[CATransaction begin];
[CATransaction setDisableActions:YES];
self.layer.contentsScale = self.scale;
self.selectionLayer.contentsScale = self.scale;
self.selectionColorLayer.contentsScale = self.scale;
self.brightnessLayer.contentsScale = self.scale;
self.gradientLayer.contentsScale = self.scale;
self.opacityLayer.contentsScale = 1.0;//self.scale;
self.loupeLayer.contentsScale = self.scale;
self.contentsLayer.contentsScale = self.scale;
_colorPickerViewFlags.bitmapNeedsUpdate = YES;
self.contentsLayer.frame = self.bounds;
self.gradientLayer.frame = self.bounds;
self.brightnessLayer.frame = self.bounds;
self.opacityLayer.frame = self.bounds;
self.opacityLayer.backgroundColor = [[UIColor colorWithPatternImage:RSOpacityBackgroundImage(20, self.scale, [UIColor colorWithWhite:0.5 alpha:1.0])] CGColor];
[self genBitmap];
[self generateBezierPaths];
[self handleStateChanged];
[CATransaction commit];
}
- (void)didMoveToWindow {
[self resizeOrRescale];
}
- (void)setFrame:(CGRect)frame {
NSAssert(frame.size.width == frame.size.height, @"RSColorPickerView must be square.");
[super setFrame:frame];
[self resizeOrRescale];
}
#pragma mark - Business -
- (void)genBitmap {
if (!_colorPickerViewFlags.bitmapNeedsUpdate) return;
self.rep = [self.class bitmapForDiameter:self.gradientLayer.bounds.size.width scale:self.scale padding:self.paddingDistance shouldCache:YES];
_colorPickerViewFlags.bitmapNeedsUpdate = NO;
self.gradientLayer.contents = (id)[RSUIImageWithScale(self.rep.image, self.scale) CGImage];
}
- (void)generateBezierPaths {
[CATransaction begin];
[CATransaction setDisableActions:YES];
CGRect activeAreaFrame = CGRectInset(self.bounds, self.paddingDistance, self.paddingDistance);
if (self.cropToCircle) {
self.contentsLayer.cornerRadius = self.paletteDiameter / 2.0;
self.activeAreaShape = [UIBezierPath bezierPathWithOvalInRect:activeAreaFrame];
} else {
self.contentsLayer.cornerRadius = 0.0;
self.activeAreaShape = [UIBezierPath bezierPathWithRect:activeAreaFrame];
}
[CATransaction commit];
}
#pragma mark - Getters -
- (UIColor *)colorAtPoint:(CGPoint)point {
return [self stateForPoint:point].color;
}
- (CGFloat)brightness {
return state.brightness;
}
- (CGFloat)opacity {
return state.alpha;
}
- (UIColor *)selectionColor {
return state.color;
}
- (CGPoint)selection {
return [state selectionLocationWithSize:self.paletteDiameter padding:self.paddingDistance];
}
#pragma mark - Setters -
- (void)setSelection:(CGPoint)selection {
[self updateStateForTouchPoint:selection];
}
- (void)setBrightness:(CGFloat)bright {
state = [state stateBySettingBrightness:bright];
[self handleStateChanged];
}
- (void)setOpacity:(CGFloat)opacity {
state = [state stateBySettingAlpha:opacity];
[self handleStateChanged];
}
- (void)setCropToCircle:(BOOL)circle {
_cropToCircle = circle;
[self generateBezierPaths];
if (circle) {
// there's a chance the selection was outside the bounds
CGPoint point = [self validPointForTouch:[state selectionLocationWithSize:self.paletteDiameter
padding:self.paddingDistance]];
[self updateStateForTouchPoint:point];
} else {
[self handleStateChanged];
}
}
- (void)setSelectionColor:(UIColor *)selectionColor {
state = [[RSColorPickerState alloc] initWithColor:selectionColor];
[self handleStateChanged];
}
#pragma mark - Selection Updates -
- (void)handleStateChanged {
[self handleStateChangedDisableActions:YES];
}
- (void)handleStateChangedDisableActions:(BOOL)disable {
[CATransaction begin];
[CATransaction setDisableActions: disable];
// update positions
CGPoint selectionLocation = [state selectionLocationWithSize:self.paletteDiameter padding:self.paddingDistance];
self.selectionLayer.position = selectionLocation;
self.selectionColorLayer.position = selectionLocation;
self.loupeLayer.position = selectionLocation;
// Make loupeLayer sharp on screen
CGRect loupeFrame = self.loupeLayer.frame;
loupeFrame.origin = CGPointMake(round(loupeFrame.origin.x), round(loupeFrame.origin.y));
self.loupeLayer.frame = loupeFrame;
[self.loupeLayer setNeedsDisplay];
// set colors and opacities
self.selectionColorLayer.backgroundColor = [[self selectionColor] CGColor];
self.opacityLayer.opacity = 1 - self.opacity;
self.brightnessLayer.opacity = 1 - self.brightness;
[CATransaction commit];
// notify delegate
if ([self.delegate respondsToSelector:@selector(colorPickerDidChangeSelection:)]) {
[self.delegate colorPickerDidChangeSelection:self];
}
}
- (void)updateStateForTouchPoint:(CGPoint)point {
state = [self stateForPoint:[self validPointForTouch:point]];
[self handleStateChanged];
}
#pragma mark - Metrics -
- (CGFloat)paddingDistance {
return kSelectionViewSize / 2.0;
}
- (CGFloat)paletteDiameter {
return self.bounds.size.width;
}
#pragma mark - Touch Events -
- (CGPoint)validPointForTouch:(CGPoint)touchPoint {
if ([self.activeAreaShape containsPoint:touchPoint]) {
return touchPoint;
}
if (self.cropToCircle) {
// We compute the right point on the gradient border
CGPoint returnedPoint;
// TouchCircle is the circle which pass by the point 'touchPoint', of radius 'r'
// 'X' is the x coordinate of the touch in TouchCircle
CGFloat X = touchPoint.x - CGRectGetMidX(self.bounds);
// 'Y' is the y coordinate of the touch in TouchCircle
CGFloat Y = touchPoint.y - CGRectGetMidY(self.bounds);
CGFloat r = sqrt(pow(X, 2) + pow(Y, 2));
// alpha is the angle in radian of the touch on the unit circle
CGFloat alpha = acos( X / r );
if (touchPoint.y > CGRectGetMidX(self.bounds)) alpha = (2 * M_PI) - alpha;
// 'actual radius' is the distance between the center and the border of the gradient
CGFloat actualRadius = (self.paletteDiameter / 2.0) - self.paddingDistance;
returnedPoint.x = fabs(actualRadius) * cos(alpha);
returnedPoint.y = fabs(actualRadius) * sin(alpha);
// we offset the center of the circle, to get the coordinate from the right top left origin
returnedPoint.x = returnedPoint.x + CGRectGetMidX(self.bounds);
returnedPoint.y = CGRectGetMidY(self.bounds) - returnedPoint.y;
return returnedPoint;
} else {
CGPoint point = touchPoint;
if (point.x < self.paddingDistance) point.x = self.paddingDistance;
if (point.x > self.paletteDiameter - self.paddingDistance) {
point.x = self.paletteDiameter - self.paddingDistance;
}
if (point.y < self.paddingDistance) point.y = self.paddingDistance;
if (point.y > self.paletteDiameter - self.paddingDistance) {
point.y = self.paletteDiameter - self.paddingDistance;
}
return point;
}
}
- (RSColorPickerState *)stateForPoint:(CGPoint)point {
RSColorPickerState * newState = [RSColorPickerState stateForPoint:point
size:self.paletteDiameter
padding:self.paddingDistance];
newState = [[newState stateBySettingAlpha:self.opacity] stateBySettingBrightness:self.brightness];
return newState;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (self.showLoupe) {
// Lazily load loupeLayer, if user wants to display it.
if (!self.loupeLayer) {
self.loupeLayer = [BGRSLoupeLayer layer];
self.loupeLayer.contentsScale = self.scale;
}
[self.loupeLayer appearInColorPicker:self];
} else {
// Otherwise, byebye
[self.loupeLayer disappear];
}
CGPoint point = [touches.anyObject locationInView:self];
[self updateStateForTouchPoint:point];
if ([self.delegate respondsToSelector:@selector(colorPicker:touchesBegan:withEvent:)]) {
[self.delegate colorPicker:self touchesBegan:touches withEvent:event];
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint point = [[touches anyObject] locationInView:self];
[self updateStateForTouchPoint:point];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint point = [[touches anyObject] locationInView:self];
[self updateStateForTouchPoint:point];
[self.loupeLayer disappear];
if ([self.delegate respondsToSelector:@selector(colorPicker:touchesEnded:withEvent:)]) {
[self.delegate colorPicker:self touchesEnded:touches withEvent:event];
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[self.loupeLayer disappear];
}
#pragma mark - Class Methods -
static NSCache *generatedBitmaps;
static NSOperationQueue *generateQueue;
static dispatch_queue_t backgroundQueue;
+ (void)initialize {
generatedBitmaps = [NSCache new];
generateQueue = [NSOperationQueue new];
generateQueue.maxConcurrentOperationCount = NSOperationQueueDefaultMaxConcurrentOperationCount;
backgroundQueue = dispatch_queue_create("com.github.rsully.rscolorpicker.background", DISPATCH_QUEUE_SERIAL);
}
#pragma mark Background Methods
+ (void)prepareForDiameter:(CGFloat)diameter {
[self prepareForDiameter:diameter padding:kSelectionViewSize/2.0];
}
+ (void)prepareForDiameter:(CGFloat)diameter padding:(CGFloat)padding {
[self prepareForDiameter:diameter scale:1.0 padding:padding];
}
+ (void)prepareForDiameter:(CGFloat)diameter scale:(CGFloat)scale {
[self prepareForDiameter:diameter scale:scale padding:kSelectionViewSize / 2.0];
}
+ (void)prepareForDiameter:(CGFloat)diameter scale:(CGFloat)scale padding:(CGFloat)padding {
[self prepareForDiameter:diameter scale:scale padding:padding inBackground:YES];
}
#pragma mark Prep Method
+ (void)prepareForDiameter:(CGFloat)diameter scale:(CGFloat)scale padding:(CGFloat)padding inBackground:(BOOL)bg {
void (*function)(dispatch_queue_t, dispatch_block_t) = bg ? dispatch_async : dispatch_sync;
function(backgroundQueue, ^{
[self bitmapForDiameter:diameter scale:scale padding:padding shouldCache:YES];
});
}
#pragma mark Generate Helper Method
+ (ANImageBitmapRep *)bitmapForDiameter:(CGFloat)diameter scale:(CGFloat)scale padding:(CGFloat)paddingDistance shouldCache:(BOOL)cache {
RSGenerateOperation *repOp = nil;
// Handle the scale here so the operation can just work with pixels directly
paddingDistance *= scale;
diameter *= scale;
if (diameter <= 0) return nil;
// Unique key for this size combo
NSString *dictionaryCacheKey = [NSString stringWithFormat:@"%.1f-%.1f", diameter, paddingDistance];
// Check cache
repOp = [generatedBitmaps objectForKey:dictionaryCacheKey];
if (repOp) {
if (!repOp.isFinished) {
[repOp waitUntilFinished];
}
return repOp.bitmap;
}
repOp = [[RSGenerateOperation alloc] initWithDiameter:diameter andPadding:paddingDistance];
if (cache) {
[generatedBitmaps setObject:repOp forKey:dictionaryCacheKey cost:diameter];
}
[generateQueue addOperation:repOp];
[repOp waitUntilFinished];
return repOp.bitmap;
}
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/RSGenerateOperation.h
================================================
//
// GenerateOperation.h
// RSColorPicker
//
// Created by Ryan on 7/22/13.
//
#import <Foundation/Foundation.h>
#import <Accelerate/Accelerate.h>
@class ANImageBitmapRep;
@interface RSGenerateOperation : NSOperation
-(id)initWithDiameter:(CGFloat)diameter andPadding:(CGFloat)padding;
@property (readonly) CGFloat diameter;
@property (readonly) CGFloat padding;
@property ANImageBitmapRep *bitmap;
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/RSGenerateOperation.m
================================================
//
// GenerateOperation.m
// RSColorPicker
//
// Created by Ryan on 7/22/13.
//
#import "RSGenerateOperation.h"
#import "ANImageBitmapRep.h"
#import "RSColorFunctions.h"
@implementation RSGenerateOperation
- (id)initWithDiameter:(CGFloat)diameter andPadding:(CGFloat)padding {
if ((self = [self init])) {
_diameter = diameter;
_padding = padding;
}
return self;
}
- (void)main {
BMPoint repSize = BMPointMake(_diameter, _diameter);
// Create fresh
ANImageBitmapRep *rep = [[ANImageBitmapRep alloc] initWithSize:repSize];
CGFloat radius = _diameter / 2.0;
CGFloat relRadius = radius - _padding;
CGFloat relX, relY;
int i, x, y;
int arrSize = powf(_diameter, 2);
size_t arrDataSize = sizeof(float) * arrSize;
// data
float *preComputeX = (float *)malloc(arrDataSize);
float *preComputeY = (float *)malloc(arrDataSize);
// output
float *atan2Vals = (float *)malloc(arrDataSize);
float *distVals = (float *)malloc(arrDataSize);
i = 0;
for (x = 0; x < _diameter; x++) {
relX = x - radius;
for (y = 0; y < _diameter; y++) {
relY = radius - y;
preComputeY[i] = relY;
preComputeX[i] = relX;
i++;
}
}
// Use Accelerate.framework to compute the distance and angle of every
// pixel from the center of the bitmap.
vvatan2f(atan2Vals, preComputeY, preComputeX, &arrSize);
vDSP_vdist(preComputeX, 1, preComputeY, 1, distVals, 1, arrSize);
// Compution done, free these
free(preComputeX);
free(preComputeY);
i = 0;
for (x = 0; x < _diameter; x++) {
for (y = 0; y < _diameter; y++) {
CGFloat r_distance = fmin(distVals[i], relRadius);
CGFloat angle = atan2Vals[i];
if (angle < 0.0) angle = (2.0 * M_PI) + angle;
CGFloat perc_angle = angle / (2.0 * M_PI);
BMPixel thisPixel = RSPixelFromHSV(perc_angle, r_distance/relRadius, 1); // full brightness
[rep setPixel:thisPixel atPoint:BMPointMake(x, y)];
i++;
}
}
// Bitmap generated, free these
free(atan2Vals);
free(distVals);
self.bitmap = rep;
}
- (BOOL)isConcurrent {
return YES;
}
- (BOOL)isExecuting {
return self.bitmap == nil;
}
- (BOOL)isFinished {
return !self.isExecuting;
}
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/RSSelectionLayer.h
================================================
//
// RSSelectionView.h
// RSColorPicker
//
// Created by Ryan Sullivan on 3/12/13.
//
#import <UIKit/UIKit.h>
@interface RSSelectionLayer : CALayer
@end
================================================
FILE: RSColorPicker/ColorPickerClasses/RSSelectionLayer.m
================================================
//
// RSSelectionView.m
// RSColorPicker
//
// Created by Ryan Sullivan on 3/12/13.
//
#import "RSSelectionLayer.h"
@interface RSSelectionLayer ()
@property (nonatomic, strong) CGColorRef outerRingColor __attribute__((NSObject));
@property (nonatomic, strong) CGColorRef innerRingColor __attribute__((NSObject));
@end
@implementation RSSelectionLayer
- (void)drawInContext:(CGContextRef)ctx {
if (!self.outerRingColor || !self.innerRingColor) {
self.outerRingColor = [[UIColor colorWithWhite:1 alpha:0.4] CGColor];
self.innerRingColor = [[UIColor colorWithWhite:0 alpha:1] CGColor];
}
CGRect rect = self.bounds;
CGContextSetLineWidth(ctx, 3);
CGContextSetStrokeColorWithColor(ctx, self.outerRingColor);
CGContextStrokeEllipseInRect(ctx, CGRectInset(rect, 1.5, 1.5));
CGContextSetLineWidth(ctx, 2);
CGContextSetStrokeColorWithColor(ctx, self.innerRingColor);
CGContextStrokeEllipseInRect(ctx, CGRectInset(rect, 3, 3));
}
@end
================================================
FILE: RSColorPicker/RSBrightnessSlider.h
================================================
//
// RSBrightnessSlider.h
// RSColorPicker
//
// Created by Ryan Sullivan on 8/12/11.
//
#import <Foundation/Foundation.h>
#import "RSColorPickerView.h"
@interface RSBrightnessSlider : UISlider
@property (nonatomic) RSColorPickerView *colorPicker;
@end
================================================
FILE: RSColorPicker/RSBrightnessSlider.m
================================================
//
// RSBrightnessSlider.m
// RSColorPicker
//
// Created by Ryan Sullivan on 8/12/11.
//
#import "RSBrightnessSlider.h"
#import "CGContextCreator.h"
/**
* Returns Image with hourglass looking slider that looks something like:
*
* 6 ______ 5
* \ /
* 7 \ / 4
* ->||<--- cWidth (Center Width)
* ||
* 8 / \ 3
* / \
* 1 ------ 2
*/
UIImage * RSHourGlassThumbImage(CGSize size, CGFloat cWidth){
//Set Size
CGFloat width = size.width;
CGFloat height = size.height;
//Setup Context
CGContextRef ctx = [CGContextCreator newARGBBitmapContextWithSize:size];
//Set Colors
CGContextSetFillColorWithColor(ctx, [UIColor blackColor].CGColor);
CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);
//Draw Slider, See Diagram above for point numbers
CGFloat yDist83 = sqrtf(3)/2*width;
CGFloat yDist74 = height - yDist83;
CGPoint addLines[] = {
CGPointMake(0, -1), //Point 1
CGPointMake(width, -1), //Point 2
CGPointMake(width/2+cWidth/2, yDist83), //Point 3
CGPointMake(width/2+cWidth/2, yDist74), //Point 4
CGPointMake(width, height+1), //Point 5
CGPointMake(0, height+1), //Point 6
CGPointMake(width/2-cWidth/2, yDist74), //Point 7
CGPointMake(width/2-cWidth/2, yDist83) //Point 8
};
//Fill Path
CGContextAddLines(ctx, addLines, sizeof(addLines)/sizeof(addLines[0]));
CGContextFillPath(ctx);
//Stroke Path
CGContextAddLines(ctx, addLines, sizeof(addLines)/sizeof(addLines[0]));
CGContextClosePath(ctx);
CGContextStrokePath(ctx);
CGImageRef cgImage = CGBitmapContextCreateImage(ctx);
CGContextRelease(ctx);
UIImage *image = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return image;
}
/**
* Returns image that looks like a square arrow loop, something like:
*
* +-----+
* | +-+ | ------------------------
* | | | | |
* ->| |<--- loopSize.width loopSize.height
* | | | | |
* | +-+ | ------------------------
* +-----+
*/
UIImage * RSArrowLoopThumbImage(CGSize size, CGSize loopSize){
//Setup Rects
CGRect outsideRect = CGRectMake(0, 0, size.width, size.height);
CGRect insideRect;
insideRect.size = loopSize;
insideRect.origin.x = (size.width - loopSize.width)/2;
insideRect.origin.y = (size.height - loopSize.height)/2;
//Setup Context
CGContextRef ctx = [CGContextCreator newARGBBitmapContextWithSize:size];
//Set Colors
CGContextSetFillColorWithColor(ctx, [UIColor blackColor].CGColor);
CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);
CGMutablePathRef loopPath = CGPathCreateMutable();
CGPathAddRect(loopPath, nil, outsideRect);
CGPathAddRect(loopPath, nil, insideRect);
//Fill Path
CGContextAddPath(ctx, loopPath);
CGContextEOFillPath(ctx);
//Stroke Path
CGContextAddRect(ctx, insideRect);
CGContextStrokePath(ctx);
CGImageRef cgImage = CGBitmapContextCreateImage(ctx);
//Memory
CGPathRelease(loopPath);
CGContextRelease(ctx);
UIImage *image = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return image;
}
@implementation RSBrightnessSlider
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self initRoutine];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self initRoutine];
}
return self;
}
- (void)initRoutine {
self.minimumValue = 0.0;
self.maximumValue = 1.0;
self.continuous = YES;
self.enabled = YES;
self.userInteractionEnabled = YES;
[self addTarget:self action:@selector(myValueChanged:) forControlEvents:UIControlEventValueChanged];
}
- (void)myValueChanged:(id)notif {
[_colorPicker setBrightness:self.value];
}
- (void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGColorSpaceRef space = CGColorSpaceCreateDeviceGray();
NSArray *colors = @[(id)[UIColor colorWithWhite:0 alpha:1].CGColor,
(id)[UIColor colorWithWhite:1 alpha:1].CGColor];
CGGradientRef myGradient = CGGradientCreateWithColors(space, (__bridge CFArrayRef)colors, NULL);
CGContextDrawLinearGradient(ctx, myGradient, CGPointZero, CGPointMake(rect.size.width, 0), 0);
CGGradientRelease(myGradient);
CGColorSpaceRelease(space);
}
- (void)setColorPicker:(RSColorPickerView*)cp {
_colorPicker = cp;
if (!_colorPicker) { return; }
self.value = [_colorPicker brightness];
}
@end
================================================
FILE: RSColorPicker/RSColorPicker-Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>me.rsullivan.apps.rscolorpicker.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
</dict>
</plist>
================================================
FILE: RSColorPicker/RSColorPicker-Prefix.pch
================================================
//
// Prefix header for all source files of the 'RSColorPicker' target in the 'RSColorPicker' project
//
#import <Availability.h>
#ifndef __IPHONE_3_0
#warning "This project uses features only available in iPhone SDK 3.0 and later."
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif
================================================
FILE: RSColorPicker/RSColorPickerAppDelegate.h
================================================
//
// RSColorPickerAppDelegate.h
// RSColorPicker
//
// Created by Ryan Sullivan on 8/12/11.
//
#import <UIKit/UIKit.h>
#import "TestColorViewController.h"
@interface RSColorPickerAppDelegate : NSObject <UIApplicationDelegate>
@property (nonatomic, strong) UIWindow *window;
@end
================================================
FILE: RSColorPicker/RSColorPickerAppDelegate.m
================================================
//
// RSColorPickerAppDelegate.m
// RSColorPicker
//
// Created by Ryan Sullivan on 8/12/11.
//
#import "RSColorPickerAppDelegate.h"
#import "RSColorPickerView.h"
@implementation RSColorPickerAppDelegate
@synthesize window=_window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Setup root controller as color
TestColorViewController *rootController = [[TestColorViewController alloc] initWithNibName:nil bundle:nil];
// Then add it to a nav controller so we can experiment with pushing
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:rootController];
// Add navigation to our window
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.rootViewController = navController;
// Show the window
[self.window makeKeyAndVisible];
return YES;
}
@end
================================================
FILE: RSColorPicker/RSOpacitySlider.h
================================================
//
// RSOpacitySlider.h
// RSColorPicker
//
// Created by Jared Allen on 5/16/13.
// Copyright (c) 2013 Red Cactus LLC. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "RSColorPickerView.h"
@interface RSOpacitySlider : UISlider
@property (nonatomic) RSColorPickerView *colorPicker;
@end
================================================
FILE: RSColorPicker/RSOpacitySlider.m
================================================
//
// RSOpacitySlider.m
// RSColorPicker
//
// Created by Jared Allen on 5/16/13.
// Copyright (c) 2013 Red Cactus LLC. All rights reserved.
//
#import "RSOpacitySlider.h"
#import "RSColorFunctions.h"
@implementation RSOpacitySlider
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self initRoutine];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self initRoutine];
}
return self;
}
- (void)initRoutine {
self.minimumValue = 0.0;
self.maximumValue = 1.0;
self.continuous = YES;
self.enabled = YES;
self.userInteractionEnabled = YES;
[self addTarget:self action:@selector(myValueChanged:) forControlEvents:UIControlEventValueChanged];
}
- (void)didMoveToWindow {
if (!self.window) return;
UIImage *backgroundImage = RSOpacityBackgroundImage(16.f, self.window.screen.scale, [UIColor colorWithWhite:0.5 alpha:1.0]);
self.backgroundColor = [UIColor colorWithPatternImage:backgroundImage];
}
- (void)myValueChanged:(id)notif {
_colorPicker.opacity = self.value;
}
- (void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGColorSpaceRef space = CGColorSpaceCreateDeviceGray();
NSArray *colors = [[NSArray alloc] initWithObjects:
(id)[UIColor colorWithWhite:0 alpha:0].CGColor,
(id)[UIColor colorWithWhite:1 alpha:1].CGColor,nil];
CGGradientRef myGradient = CGGradientCreateWithColors(space, (__bridge CFArrayRef)colors, NULL);
CGContextDrawLinearGradient(ctx, myGradient, CGPointZero, CGPointMake(rect.size.width, 0), 0);
CGGradientRelease(myGradient);
CGColorSpaceRelease(space);
}
- (void)setColorPicker:(RSColorPickerView *)cp {
_colorPicker = cp;
if (!_colorPicker) { return; }
self.value = [_colorPicker brightness];
}
@end
================================================
FILE: RSColorPicker/TestColorViewController.h
================================================
//
// TestColorViewController.h
// RSColorPicker
//
// Created by Ryan Sullivan on 7/14/13.
//
#import <UIKit/UIKit.h>
#import "ColorPickerClasses/RSColorPickerView.h"
#import "ColorPickerClasses/RSColorFunctions.h"
@class RSBrightnessSlider;
@class RSOpacitySlider;
@interface TestColorViewController : UIViewController <RSColorPickerViewDelegate> {
BOOL isSmallSize;
}
@property (nonatomic) RSColorPickerView *colorPicker;
@property (nonatomic) RSBrightnessSlider *brightnessSlider;
@property (nonatomic) RSOpacitySlider *opacitySlider;
@property (nonatomic) UIView *colorPatch;
@property UILabel *rgbLabel;
@end
================================================
FILE: RSColorPicker/TestColorViewController.m
================================================
//
// TestColorViewController.m
// RSColorPicker
//
// Created by Ryan Sullivan on 7/14/13.
//
#import "TestColorViewController.h"
#import "RSBrightnessSlider.h"
#import "RSOpacitySlider.h"
@implementation TestColorViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = RSRandomColorOpaque(YES);
self.navigationController.navigationBar.translucent = NO;
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Push" style:UIBarButtonItemStyleBordered
target:self action:@selector(pushNext:)];
// View that displays color picker (needs to be square)
_colorPicker = [[RSColorPickerView alloc] initWithFrame:CGRectMake(20.0, 10.0, 280.0, 280.0)];
// Optionally set and force the picker to only draw a circle
// [_colorPicker setCropToCircle:YES]; // Defaults to NO (you can set BG color)
// Set the selection color - useful to present when the user had picked a color previously
[_colorPicker setSelectionColor:RSRandomColorOpaque(YES)];
// [_colorPicker setSelectionColor:[UIColor colorWithRed:1 green:0 blue:0.752941 alpha:1.000000]];
// [_colorPicker setSelection:CGPointMake(269, 269)];
// Set the delegate to receive events
[_colorPicker setDelegate:self];
[self.view addSubview:_colorPicker];
// On/off circle or square
UISwitch *circleSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(10, 340, 0, 0)];
[circleSwitch setOn:_colorPicker.cropToCircle];
[circleSwitch addTarget:self action:@selector(circleSwitchAction:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:circleSwitch];
// View that controls brightness
_brightnessSlider = [[RSBrightnessSlider alloc] initWithFrame:CGRectMake(CGRectGetMaxX(circleSwitch.frame) + 4, 300.0, 320 - (20 + CGRectGetWidth(circleSwitch.frame)), 30.0)];
[_brightnessSlider setColorPicker:_colorPicker];
[self.view addSubview:_brightnessSlider];
// View that controls opacity
_opacitySlider = [[RSOpacitySlider alloc] initWithFrame:CGRectMake(CGRectGetMaxX(circleSwitch.frame) + 4, 340.0, 320 - (20 + CGRectGetWidth(circleSwitch.frame)), 30.0)];
[_opacitySlider setColorPicker:_colorPicker];
[self.view addSubview:_opacitySlider];
// View that shows selected color
_colorPatch = [[UIView alloc] initWithFrame:CGRectMake(160, 380.0, 150, 30.0)];
[self.view addSubview:_colorPatch];
// Buttons for testing
UIButton *selectRed = [UIButton buttonWithType:UIButtonTypeRoundedRect];
selectRed.frame = CGRectMake(10.0, 380.0, 30.0, 30.0);
[selectRed setTitle:@"R" forState:UIControlStateNormal];
[selectRed addTarget:self action:@selector(selectRed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:selectRed];
UIButton *selectGreen = [UIButton buttonWithType:UIButtonTypeRoundedRect];
selectGreen.frame = CGRectMake(50.0, 380.0, 30.0, 30.0);
[selectGreen setTitle:@"G" forState:UIControlStateNormal];
[selectGreen addTarget:self action:@selector(selectGreen:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:selectGreen];
UIButton *selectBlue = [UIButton buttonWithType:UIButtonTypeRoundedRect];
selectBlue.frame = CGRectMake(90.0, 380.0, 30.0, 30.0);
[selectBlue setTitle:@"B" forState:UIControlStateNormal];
[selectBlue addTarget:self action:@selector(selectBlue:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:selectBlue];
UIButton *selectBlack = [UIButton buttonWithType:UIButtonTypeRoundedRect];
selectBlack.frame = CGRectMake(10, 420.0, 50.0, 30.0);
[selectBlack setTitle:@"Black" forState:UIControlStateNormal];
[selectBlack addTarget:self action:@selector(selectBlack:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:selectBlack];
UIButton *selectWhite = [UIButton buttonWithType:UIButtonTypeRoundedRect];
selectWhite.frame = CGRectMake(CGRectGetMaxX(selectBlack.frame) + 10, 420.0, 50.0, 30.0);
[selectWhite setTitle:@"White" forState:UIControlStateNormal];
[selectWhite addTarget:self action:@selector(selectWhite:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:selectWhite];
UIButton *selectPurple = [UIButton buttonWithType:UIButtonTypeRoundedRect];
selectPurple.frame = CGRectMake(CGRectGetMaxX(selectWhite.frame) + 10, 420.0, 50.0, 30.0);
[selectPurple setTitle:@"Purple" forState:UIControlStateNormal];
[selectPurple addTarget:self action:@selector(selectPurple:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:selectPurple];
UIButton *selectCyan = [UIButton buttonWithType:UIButtonTypeRoundedRect];
selectCyan.frame = CGRectMake(CGRectGetMaxX(selectPurple.frame) + 10, 420.0, 50.0, 30.0);
[selectCyan setTitle:@"Cyan" forState:UIControlStateNormal];
[selectCyan addTarget:self action:@selector(selectCyan:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:selectCyan];
UIButton *resizeButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
resizeButton.frame = CGRectMake(10, CGRectGetMaxY(selectCyan.frame) + 5, 50, 30);
[resizeButton setTitle:@"Resize" forState:UIControlStateNormal];
[resizeButton addTarget:self action:@selector(testResize:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:resizeButton];
UIButton *loupButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
loupButton.frame = CGRectMake(CGRectGetMaxX(resizeButton.frame) + 10, CGRectGetMinY(resizeButton.frame), 50, 30);
[loupButton setTitle:@"Loup" forState:UIControlStateNormal];
[loupButton addTarget:self action:@selector(testLoup:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:loupButton];
_rgbLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(loupButton.frame) + 10, CGRectGetMinY(loupButton.frame), 180, 30)];
_rgbLabel.text = @"RGB";
_rgbLabel.font = [UIFont systemFontOfSize:[UIFont systemFontSize]];
[self.view addSubview:_rgbLabel];
}
#pragma mark - RSColorPickerView delegate methods
- (void)colorPickerDidChangeSelection:(RSColorPickerView *)cp {
// Get color data
UIColor *color = [cp selectionColor];
CGFloat r, g, b, a;
[[cp selectionColor] getRed:&r green:&g blue:&b alpha:&a];
// Update important UI
_colorPatch.backgroundColor = color;
_brightnessSlider.value = [cp brightness];
_opacitySlider.value = [cp opacity];
// Debug
NSString *colorDesc = [NSString stringWithFormat:@"rgba: %f, %f, %f, %f", r, g, b, a];
NSLog(@"%@", colorDesc);
int ir = r * 255;
int ig = g * 255;
int ib = b * 255;
int ia = a * 255;
colorDesc = [NSString stringWithFormat:@"rgba: %d, %d, %d, %d", ir, ig, ib, ia];
NSLog(@"%@", colorDesc);
_rgbLabel.text = colorDesc;
NSLog(@"%@", NSStringFromCGPoint(cp.selection));
}
#pragma mark - User action
- (void)testResize:(id)sender {
if (isSmallSize) {
_colorPicker.frame = CGRectMake(20.0, 10.0, 280.0, 280.0);
isSmallSize = NO;
} else {
_colorPicker.frame = CGRectMake(40.0, 10.0, 240.0, 240.0);
isSmallSize = YES;
}
}
- (void)testLoup:(id)sender {
if (_colorPicker.showLoupe) {
_colorPicker.showLoupe = NO;
} else {
_colorPicker.showLoupe = YES;
}
}
- (void)selectRed:(id)sender {
[_colorPicker setSelectionColor:[UIColor redColor]];
}
- (void)selectGreen:(id)sender {
[_colorPicker setSelectionColor:[UIColor greenColor]];
}
- (void)selectBlue:(id)sender {
[_colorPicker setSelectionColor:[UIColor blueColor]];
}
- (void)selectBlack:(id)sender {
[_colorPicker setSelectionColor:[UIColor blackColor]];
}
- (void)selectWhite:(id)sender {
[_colorPicker setSelectionColor:[UIColor whiteColor]];
}
- (void)selectPurple:(id)sender {
[_colorPicker setSelectionColor:[UIColor purpleColor]];
}
- (void)selectCyan:(id)sender {
[_colorPicker setSelectionColor:[UIColor cyanColor]];
}
- (void)circleSwitchAction:(UISwitch *)s {
_colorPicker.cropToCircle = s.isOn;
}
#pragma mark - Push the stack
- (void)pushNext:(id)sender {
TestColorViewController *colorController = [[TestColorViewController alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:colorController animated:YES];
}
#pragma mark - Generated methods
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
================================================
FILE: RSColorPicker/en.lproj/InfoPlist.strings
================================================
/* Localized versions of Info.plist keys */
================================================
FILE: RSColorPicker/main.m
================================================
//
// main.m
// RSColorPicker
//
// Created by Ryan Sullivan on 8/12/11.
//
#import <UIKit/UIKit.h>
#import "RSColorPickerAppDelegate.h"
int main(int argc, char *argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass(RSColorPickerAppDelegate.class));
}
}
================================================
FILE: RSColorPicker.podspec
================================================
Pod::Spec.new do |s|
s.name = "RSColorPicker"
s.version = "0.9.2"
s.summary = "iOS color picker view"
s.description = "iOS color picker view with brightness control, opacity control, and delegation support."
s.homepage = "https://github.com/RSully/RSColorPicker"
s.screenshots = "https://raw.github.com/RSully/RSColorPicker/v0.9.2/Example01.png", "https://raw.github.com/RSully/RSColorPicker/v0.9.2/Example02.png", "https://raw.github.com/RSully/RSColorPicker/v0.9.2/Example03.png", "https://raw.github.com/RSully/RSColorPicker/v0.9.2/Example04.png", "https://raw.github.com/RSully/RSColorPicker/v0.9.2/Example05.png"
s.license = { :type => 'BSD', :file => "LICENSE.md" }
s.author = { "Ryan" => "rsul.dev@me.com" }
s.source = { :git => "https://github.com/RSully/RSColorPicker.git", :tag => "v0.9.2" }
s.platform = :ios, '6.0'
s.source_files = 'RSColorPicker/ColorPickerClasses/**/*.{h,m}'
s.frameworks = 'QuartzCore', 'CoreGraphics', 'UIKit', 'Accelerate'
s.requires_arc = true
s.public_header_files = "RSColorPicker/ColorPickerClasses/RSColorPickerView.h"
end
================================================
FILE: RSColorPicker.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
1FA35E6013F57B2700A6B347 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FA35E5F13F57B2700A6B347 /* UIKit.framework */; };
1FA35E6213F57B2700A6B347 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FA35E6113F57B2700A6B347 /* Foundation.framework */; };
1FA35E6413F57B2700A6B347 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FA35E6313F57B2700A6B347 /* CoreGraphics.framework */; };
1FA35E6A13F57B2800A6B347 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 1FA35E6813F57B2800A6B347 /* InfoPlist.strings */; };
1FA35E6D13F57B2800A6B347 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FA35E6C13F57B2800A6B347 /* main.m */; };
1FA35E7013F57B2800A6B347 /* RSColorPickerAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FA35E6F13F57B2800A6B347 /* RSColorPickerAppDelegate.m */; };
1FA35E9913F5A17E00A6B347 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FA35E9813F5A17E00A6B347 /* QuartzCore.framework */; };
2B12A0DF1792FF46007F2A0A /* TestColorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B12A0DE1792FF46007F2A0A /* TestColorViewController.m */; };
2B78462718D290340002F859 /* CPTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B78462618D290340002F859 /* CPTestCase.m */; };
2B78462918D298570002F859 /* CPTestCaseTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B78462818D298570002F859 /* CPTestCaseTests.m */; };
2B85423116EFC8970047FFBE /* ANImageBitmapRep.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B85420D16EFC8970047FFBE /* ANImageBitmapRep.m */; };
2B85423216EFC8970047FFBE /* BitmapContextRep.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B85420F16EFC8970047FFBE /* BitmapContextRep.m */; };
2B85423316EFC8970047FFBE /* NSImage+ANImageBitmapRep.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B85421216EFC8970047FFBE /* NSImage+ANImageBitmapRep.m */; };
2B85423416EFC8970047FFBE /* OSCommonImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B85421416EFC8970047FFBE /* OSCommonImage.m */; };
2B85423516EFC8970047FFBE /* UIImage+ANImageBitmapRep.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B85421616EFC8970047FFBE /* UIImage+ANImageBitmapRep.m */; };
2B85423616EFC8970047FFBE /* CGContextCreator.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B85421916EFC8970047FFBE /* CGContextCreator.m */; };
2B85423716EFC8970047FFBE /* CGImageContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B85421B16EFC8970047FFBE /* CGImageContainer.m */; };
2B85423816EFC8970047FFBE /* BitmapContextManipulator.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B85421E16EFC8970047FFBE /* BitmapContextManipulator.m */; };
2B85423916EFC8970047FFBE /* BitmapCropManipulator.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B85422016EFC8970047FFBE /* BitmapCropManipulator.m */; };
2B85423A16EFC8970047FFBE /* BitmapDrawManipulator.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B85422216EFC8970047FFBE /* BitmapDrawManipulator.m */; };
2B85423B16EFC8970047FFBE /* BitmapRotationManipulator.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B85422416EFC8970047FFBE /* BitmapRotationManipulator.m */; };
2B85423C16EFC8970047FFBE /* BitmapScaleManipulator.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B85422616EFC8970047FFBE /* BitmapScaleManipulator.m */; };
2B85423D16EFC8970047FFBE /* BGRSLoupeLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B85422816EFC8970047FFBE /* BGRSLoupeLayer.m */; };
2B85423F16EFC8970047FFBE /* RSColorFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B85422C16EFC8970047FFBE /* RSColorFunctions.m */; };
2B85424016EFC8970047FFBE /* RSColorPickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B85422E16EFC8970047FFBE /* RSColorPickerView.m */; };
2B85424116EFC8970047FFBE /* RSSelectionLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B85423016EFC8970047FFBE /* RSSelectionLayer.m */; };
2B989DF318D61F760049D521 /* RSColorFunctionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B989DF218D61F760049D521 /* RSColorFunctionsTests.m */; };
2BF47AD318D4D44600C12FA5 /* RSColorPickerViewDelegateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BF47AD218D4D44600C12FA5 /* RSColorPickerViewDelegateTests.m */; };
2BF8BFF818E9B67600E7C5BF /* RSColorPickerStateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BF8BFF718E9B67600E7C5BF /* RSColorPickerStateTests.m */; };
2BFBDBDA18D2574400DFC1E5 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2BFBDBD918D2574400DFC1E5 /* XCTest.framework */; };
2BFBDBDB18D2574400DFC1E5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FA35E6113F57B2700A6B347 /* Foundation.framework */; };
2BFBDBDC18D2574400DFC1E5 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FA35E5F13F57B2700A6B347 /* UIKit.framework */; };
2BFBDBE218D2574400DFC1E5 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2BFBDBE018D2574400DFC1E5 /* InfoPlist.strings */; };
2BFBDBE418D2574400DFC1E5 /* RSColorPickerViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BFBDBE318D2574400DFC1E5 /* RSColorPickerViewTests.m */; };
930D5A8016DE4D36006C38D4 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 930D5A7F16DE4D36006C38D4 /* Default-568h@2x.png */; };
94A10AFB1799B6A900F0BD7E /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94A10AFA1799B6A900F0BD7E /* Accelerate.framework */; };
94A10AFF179DB67C00F0BD7E /* RSGenerateOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 94A10AFE179DB67C00F0BD7E /* RSGenerateOperation.m */; };
FA5AA0EA185F6477000355FE /* RSBrightnessSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = FA5AA0E7185F6477000355FE /* RSBrightnessSlider.m */; };
FA5AA0EB185F6477000355FE /* RSOpacitySlider.m in Sources */ = {isa = PBXBuildFile; fileRef = FA5AA0E9185F6477000355FE /* RSOpacitySlider.m */; };
FAFF6E4C185F84BD00412D58 /* RSColorPickerState.m in Sources */ = {isa = PBXBuildFile; fileRef = FAFF6E4B185F84BD00412D58 /* RSColorPickerState.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
2BFBDBE618D2574400DFC1E5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 1FA35E5213F57B2700A6B347 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 1FA35E5A13F57B2700A6B347;
remoteInfo = RSColorPicker;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
1FA35E5B13F57B2700A6B347 /* RSColorPicker.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RSColorPicker.app; sourceTree = BUILT_PRODUCTS_DIR; };
1FA35E5F13F57B2700A6B347 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
1FA35E6113F57B2700A6B347 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
1FA35E6313F57B2700A6B347 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
1FA35E6713F57B2700A6B347 /* RSColorPicker-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RSColorPicker-Info.plist"; sourceTree = "<group>"; };
1FA35E6913F57B2800A6B347 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
1FA35E6B13F57B2800A6B347 /* RSColorPicker-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RSColorPicker-Prefix.pch"; sourceTree = "<group>"; };
1FA35E6C13F57B2800A6B347 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
1FA35E6E13F57B2800A6B347 /* RSColorPickerAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RSColorPickerAppDelegate.h; sourceTree = "<group>"; };
1FA35E6F13F57B2800A6B347 /* RSColorPickerAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RSColorPickerAppDelegate.m; sourceTree = "<group>"; };
1FA35E9813F5A17E00A6B347 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
2B12A0DD1792FF46007F2A0A /* TestColorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestColorViewController.h; sourceTree = "<group>"; };
2B12A0DE1792FF46007F2A0A /* TestColorViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestColorViewController.m; sourceTree = "<group>"; };
2B78462518D290340002F859 /* CPTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPTestCase.h; sourceTree = "<group>"; };
2B78462618D290340002F859 /* CPTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPTestCase.m; sourceTree = "<group>"; };
2B78462818D298570002F859 /* CPTestCaseTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPTestCaseTests.m; sourceTree = "<group>"; };
2B85420C16EFC8970047FFBE /* ANImageBitmapRep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANImageBitmapRep.h; sourceTree = "<group>"; };
2B85420D16EFC8970047FFBE /* ANImageBitmapRep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANImageBitmapRep.m; sourceTree = "<group>"; };
2B85420E16EFC8970047FFBE /* BitmapContextRep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapContextRep.h; sourceTree = "<group>"; };
2B85420F16EFC8970047FFBE /* BitmapContextRep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BitmapContextRep.m; sourceTree = "<group>"; };
2B85421116EFC8970047FFBE /* NSImage+ANImageBitmapRep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSImage+ANImageBitmapRep.h"; sourceTree = "<group>"; };
2B85421216EFC8970047FFBE /* NSImage+ANImageBitmapRep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSImage+ANImageBitmapRep.m"; sourceTree = "<group>"; };
2B85421316EFC8970047FFBE /* OSCommonImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSCommonImage.h; sourceTree = "<group>"; };
2B85421416EFC8970047FFBE /* OSCommonImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSCommonImage.m; sourceTree = "<group>"; };
2B85421516EFC8970047FFBE /* UIImage+ANImageBitmapRep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+ANImageBitmapRep.h"; sourceTree = "<group>"; };
2B85421616EFC8970047FFBE /* UIImage+ANImageBitmapRep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+ANImageBitmapRep.m"; sourceTree = "<group>"; };
2B85421816EFC8970047FFBE /* CGContextCreator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGContextCreator.h; sourceTree = "<group>"; };
2B85421916EFC8970047FFBE /* CGContextCreator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CGContextCreator.m; sourceTree = "<group>"; };
2B85421A16EFC8970047FFBE /* CGImageContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGImageContainer.h; sourceTree = "<group>"; };
2B85421B16EFC8970047FFBE /* CGImageContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CGImageContainer.m; sourceTree = "<group>"; };
2B85421D16EFC8970047FFBE /* BitmapContextManipulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapContextManipulator.h; sourceTree = "<group>"; };
2B85421E16EFC8970047FFBE /* BitmapContextManipulator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BitmapContextManipulator.m; sourceTree = "<group>"; };
2B85421F16EFC8970047FFBE /* BitmapCropManipulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapCropManipulator.h; sourceTree = "<group>"; };
2B85422016EFC8970047FFBE /* BitmapCropManipulator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BitmapCropManipulator.m; sourceTree = "<group>"; };
2B85422116EFC8970047FFBE /* BitmapDrawManipulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapDrawManipulator.h; sourceTree = "<group>"; };
2B85422216EFC8970047FFBE /* BitmapDrawManipulator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BitmapDrawManipulator.m; sourceTree = "<group>"; };
2B85422316EFC8970047FFBE /* BitmapRotationManipulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapRotationManipulator.h; sourceTree = "<group>"; };
2B85422416EFC8970047FFBE /* BitmapRotationManipulator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BitmapRotationManipulator.m; sourceTree = "<group>"; };
2B85422516EFC8970047FFBE /* BitmapScaleManipulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapScaleManipulator.h; sourceTree = "<group>"; };
2B85422616EFC8970047FFBE /* BitmapScaleManipulator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BitmapScaleManipulator.m; sourceTree = "<group>"; };
2B85422716EFC8970047FFBE /* BGRSLoupeLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BGRSLoupeLayer.h; sourceTree = "<group>"; };
2B85422816EFC8970047FFBE /* BGRSLoupeLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BGRSLoupeLayer.m; sourceTree = "<group>"; };
2B85422B16EFC8970047FFBE /* RSColorFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSColorFunctions.h; sourceTree = "<group>"; };
2B85422C16EFC8970047FFBE /* RSColorFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSColorFunctions.m; sourceTree = "<group>"; };
2B85422D16EFC8970047FFBE /* RSColorPickerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSColorPickerView.h; sourceTree = "<group>"; };
2B85422E16EFC8970047FFBE /* RSColorPickerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSColorPickerView.m; sourceTree = "<group>"; };
2B85422F16EFC8970047FFBE /* RSSelectionLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSSelectionLayer.h; sourceTree = "<group>"; };
2B85423016EFC8970047FFBE /* RSSelectionLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSSelectionLayer.m; sourceTree = "<group>"; };
2B989DF218D61F760049D521 /* RSColorFunctionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSColorFunctionsTests.m; sourceTree = "<group>"; };
2BF47AD218D4D44600C12FA5 /* RSColorPickerViewDelegateTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSColorPickerViewDelegateTests.m; sourceTree = "<group>"; };
2BF8BFF718E9B67600E7C5BF /* RSColorPickerStateTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSColorPickerStateTests.m; sourceTree = "<group>"; };
2BFBDBD818D2574400DFC1E5 /* RSColorPickerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RSColorPickerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
2BFBDBD918D2574400DFC1E5 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
2BFBDBDF18D2574400DFC1E5 /* RSColorPickerTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RSColorPickerTests-Info.plist"; sourceTree = "<group>"; };
2BFBDBE118D2574400DFC1E5 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
2BFBDBE318D2574400DFC1E5 /* RSColorPickerViewTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RSColorPickerViewTests.m; sourceTree = "<group>"; };
2BFBDBE518D2574400DFC1E5 /* RSColorPickerTests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RSColorPickerTests-Prefix.pch"; sourceTree = "<group>"; };
930D5A7F16DE4D36006C38D4 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
94A10AFA1799B6A900F0BD7E /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
94A10AFD179DB67C00F0BD7E /* RSGenerateOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSGenerateOperation.h; sourceTree = "<group>"; };
94A10AFE179DB67C00F0BD7E /* RSGenerateOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSGenerateOperation.m; sourceTree = "<group>"; };
FA5AA0E6185F6477000355FE /* RSBrightnessSlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSBrightnessSlider.h; sourceTree = "<group>"; };
FA5AA0E7185F6477000355FE /* RSBrightnessSlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSBrightnessSlider.m; sourceTree = "<group>"; };
FA5AA0E8185F6477000355FE /* RSOpacitySlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSOpacitySlider.h; sourceTree = "<group>"; };
FA5AA0E9185F6477000355FE /* RSOpacitySlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSOpacitySlider.m; sourceTree = "<group>"; };
FAFF6E4A185F84BD00412D58 /* RSColorPickerState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSColorPickerState.h; sourceTree = "<group>"; };
FAFF6E4B185F84BD00412D58 /* RSColorPickerState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSColorPickerState.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
1FA35E5813F57B2700A6B347 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
94A10AFB1799B6A900F0BD7E /* Accelerate.framework in Frameworks */,
1FA35E9913F5A17E00A6B347 /* QuartzCore.framework in Frameworks */,
1FA35E6013F57B2700A6B347 /* UIKit.framework in Frameworks */,
1FA35E6213F57B2700A6B347 /* Foundation.framework in Frameworks */,
1FA35E6413F57B2700A6B347 /* CoreGraphics.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
2BFBDBD518D2574400DFC1E5 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
2BFBDBDA18D2574400DFC1E5 /* XCTest.framework in Frameworks */,
2BFBDBDC18D2574400DFC1E5 /* UIKit.framework in Frameworks */,
2BFBDBDB18D2574400DFC1E5 /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
1FA35E5013F57B2700A6B347 = {
isa = PBXGroup;
children = (
930D5A7F16DE4D36006C38D4 /* Default-568h@2x.png */,
1FA35E6513F57B2700A6B347 /* RSColorPicker */,
2BFBDBDD18D2574400DFC1E5 /* RSColorPickerTests */,
1FA35E5E13F57B2700A6B347 /* Frameworks */,
1FA35E5C13F57B2700A6B347 /* Products */,
);
sourceTree = "<group>";
};
1FA35E5C13F57B2700A6B347 /* Products */ = {
isa = PBXGroup;
children = (
1FA35E5B13F57B2700A6B347 /* RSColorPicker.app */,
2BFBDBD818D2574400DFC1E5 /* RSColorPickerTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
1FA35E5E13F57B2700A6B347 /* Frameworks */ = {
isa = PBXGroup;
children = (
94A10AFA1799B6A900F0BD7E /* Accelerate.framework */,
1FA35E9813F5A17E00A6B347 /* QuartzCore.framework */,
1FA35E5F13F57B2700A6B347 /* UIKit.framework */,
1FA35E6113F57B2700A6B347 /* Foundation.framework */,
1FA35E6313F57B2700A6B347 /* CoreGraphics.framework */,
2BFBDBD918D2574400DFC1E5 /* XCTest.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
1FA35E6513F57B2700A6B347 /* RSColorPicker */ = {
isa = PBXGroup;
children = (
1FA35E6E13F57B2800A6B347 /* RSColorPickerAppDelegate.h */,
1FA35E6F13F57B2800A6B347 /* RSColorPickerAppDelegate.m */,
2B12A0DD1792FF46007F2A0A /* TestColorViewController.h */,
2B12A0DE1792FF46007F2A0A /* TestColorViewController.m */,
FA5AA0E6185F6477000355FE /* RSBrightnessSlider.h */,
FA5AA0E7185F6477000355FE /* RSBrightnessSlider.m */,
FA5AA0E8185F6477000355FE /* RSOpacitySlider.h */,
FA5AA0E9185F6477000355FE /* RSOpacitySlider.m */,
2B85420A16EFC8970047FFBE /* ColorPickerClasses */,
1FA35E6613F57B2700A6B347 /* Supporting Files */,
);
path = RSColorPicker;
sourceTree = "<group>";
};
1FA35E6613F57B2700A6B347 /* Supporting Files */ = {
isa = PBXGroup;
children = (
1FA35E6713F57B2700A6B347 /* RSColorPicker-Info.plist */,
1FA35E6813F57B2800A6B347 /* InfoPlist.strings */,
1FA35E6B13F57B2800A6B347 /* RSColorPicker-Prefix.pch */,
1FA35E6C13F57B2800A6B347 /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
2B85420A16EFC8970047FFBE /* ColorPickerClasses */ = {
isa = PBXGroup;
children = (
2B85420B16EFC8970047FFBE /* ANImageBitmapRep */,
2B85422716EFC8970047FFBE /* BGRSLoupeLayer.h */,
2B85422816EFC8970047FFBE /* BGRSLoupeLayer.m */,
2B85422D16EFC8970047FFBE /* RSColorPickerView.h */,
2B85422E16EFC8970047FFBE /* RSColorPickerView.m */,
94A10AFC179DB66400F0BD7E /* Generation */,
2B85422F16EFC8970047FFBE /* RSSelectionLayer.h */,
2B85423016EFC8970047FFBE /* RSSelectionLayer.m */,
2B85422B16EFC8970047FFBE /* RSColorFunctions.h */,
2B85422C16EFC8970047FFBE /* RSColorFunctions.m */,
FAFF6E4A185F84BD00412D58 /* RSColorPickerState.h */,
FAFF6E4B185F84BD00412D58 /* RSColorPickerState.m */,
);
path = ColorPickerClasses;
sourceTree = "<group>";
};
2B85420B16EFC8970047FFBE /* ANImageBitmapRep */ = {
isa = PBXGroup;
children = (
2B85420C16EFC8970047FFBE /* ANImageBitmapRep.h */,
2B85420D16EFC8970047FFBE /* ANImageBitmapRep.m */,
2B85420E16EFC8970047FFBE /* BitmapContextRep.h */,
2B85420F16EFC8970047FFBE /* BitmapContextRep.m */,
2B85421016EFC8970047FFBE /* Compatibility */,
2B85421716EFC8970047FFBE /* CoreGraphics */,
2B85421C16EFC8970047FFBE /* Manipulators */,
);
path = ANImageBitmapRep;
sourceTree = "<group>";
};
2B85421016EFC8970047FFBE /* Compatibility */ = {
isa = PBXGroup;
children = (
2B85421116EFC8970047FFBE /* NSImage+ANImageBitmapRep.h */,
2B85421216EFC8970047FFBE /* NSImage+ANImageBitmapRep.m */,
2B85421316EFC8970047FFBE /* OSCommonImage.h */,
2B85421416EFC8970047FFBE /* OSCommonImage.m */,
2B85421516EFC8970047FFBE /* UIImage+ANImageBitmapRep.h */,
2B85421616EFC8970047FFBE /* UIImage+ANImageBitmapRep.m */,
);
path = Compatibility;
sourceTree = "<group>";
};
2B85421716EFC8970047FFBE /* CoreGraphics */ = {
isa = PBXGroup;
children = (
2B85421816EFC8970047FFBE /* CGContextCreator.h */,
2B85421916EFC8970047FFBE /* CGContextCreator.m */,
2B85421A16EFC8970047FFBE /* CGImageContainer.h */,
2B85421B16EFC8970047FFBE /* CGImageContainer.m */,
);
path = CoreGraphics;
sourceTree = "<group>";
};
2B85421C16EFC8970047FFBE /* Manipulators */ = {
isa = PBXGroup;
children = (
2B85421D16EFC8970047FFBE /* BitmapContextManipulator.h */,
2B85421E16EFC8970047FFBE /* BitmapContextManipulator.m */,
2B85421F16EFC8970047FFBE /* BitmapCropManipulator.h */,
2B85422016EFC8970047FFBE /* BitmapCropManipulator.m */,
2B85422116EFC8970047FFBE /* BitmapDrawManipulator.h */,
2B85422216EFC8970047FFBE /* BitmapDrawManipulator.m */,
2B85422316EFC8970047FFBE /* BitmapRotationManipulator.h */,
2B85422416EFC8970047FFBE /* BitmapRotationManipulator.m */,
2B85422516EFC8970047FFBE /* BitmapScaleManipulator.h */,
2B85422616EFC8970047FFBE /* BitmapScaleManipulator.m */,
);
path = Manipulators;
sourceTree = "<group>";
};
2BFBDBDD18D2574400DFC1E5 /* RSColorPickerTests */ = {
isa = PBXGroup;
children = (
2BF8BFF718E9B67600E7C5BF /* RSColorPickerStateTests.m */,
2B989DF218D61F760049D521 /* RSColorFunctionsTests.m */,
2BF47AD218D4D44600C12FA5 /* RSColorPickerViewDelegateTests.m */,
2B78462818D298570002F859 /* CPTestCaseTests.m */,
2BFBDBE318D2574400DFC1E5 /* RSColorPickerViewTests.m */,
2BFBDBDE18D2574400DFC1E5 /* Supporting Files */,
2B78462518D290340002F859 /* CPTestCase.h */,
2B78462618D290340002F859 /* CPTestCase.m */,
);
path = RSColorPickerTests;
sourceTree = "<group>";
};
2BFBDBDE18D2574400DFC1E5 /* Supporting Files */ = {
isa = PBXGroup;
children = (
2BFBDBDF18D2574400DFC1E5 /* RSColorPickerTests-Info.plist */,
2BFBDBE018D2574400DFC1E5 /* InfoPlist.strings */,
2BFBDBE518D2574400DFC1E5 /* RSColorPickerTests-Prefix.pch */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
94A10AFC179DB66400F0BD7E /* Generation */ = {
isa = PBXGroup;
children = (
94A10AFD179DB67C00F0BD7E /* RSGenerateOperation.h */,
94A10AFE179DB67C00F0BD7E /* RSGenerateOperation.m */,
);
name = Generation;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
1FA35E5A13F57B2700A6B347 /* RSColorPicker */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1FA35E7613F57B2800A6B347 /* Build configuration list for PBXNativeTarget "RSColorPicker" */;
buildPhases = (
1FA35E5713F57B2700A6B347 /* Sources */,
1FA35E5813F57B2700A6B347 /* Frameworks */,
1FA35E5913F57B2700A6B347 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = RSColorPicker;
productName = RSColorPicker;
productReference = 1FA35E5B13F57B2700A6B347 /* RSColorPicker.app */;
productType = "com.apple.product-type.application";
};
2BFBDBD718D2574400DFC1E5 /* RSColorPickerTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 2BFBDBEA18D2574400DFC1E5 /* Build configuration list for PBXNativeTarget "RSColorPickerTests" */;
buildPhases = (
2BFBDBD418D2574400DFC1E5 /* Sources */,
2BFBDBD518D2574400DFC1E5 /* Frameworks */,
2BFBDBD618D2574400DFC1E5 /* Resources */,
);
buildRules = (
);
dependencies = (
2BFBDBE718D2574400DFC1E5 /* PBXTargetDependency */,
);
name = RSColorPickerTests;
productName = RSColorPickerTests;
productReference = 2BFBDBD818D2574400DFC1E5 /* RSColorPickerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
1FA35E5213F57B2700A6B347 /* Project object */ = {
isa = PBXProject;
attributes = {
CLASSPREFIX = RSCP;
LastUpgradeCheck = 0500;
ORGANIZATIONNAME = "";
TargetAttributes = {
1FA35E5A13F57B2700A6B347 = {
DevelopmentTeam = A5KAV3AMGE;
};
2BFBDBD718D2574400DFC1E5 = {
TestTargetID = 1FA35E5A13F57B2700A6B347;
};
};
};
buildConfigurationList = 1FA35E5513F57B2700A6B347 /* Build configuration list for PBXProject "RSColorPicker" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 1FA35E5013F57B2700A6B347;
productRefGroup = 1FA35E5C13F57B2700A6B347 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
1FA35E5A13F57B2700A6B347 /* RSColorPicker */,
2BFBDBD718D2574400DFC1E5 /* RSColorPickerTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
1FA35E5913F57B2700A6B347 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1FA35E6A13F57B2800A6B347 /* InfoPlist.strings in Resources */,
930D5A8016DE4D36006C38D4 /* Default-568h@2x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
2BFBDBD618D2574400DFC1E5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2BFBDBE218D2574400DFC1E5 /* InfoPlist.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
1FA35E5713F57B2700A6B347 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1FA35E6D13F57B2800A6B347 /* main.m in Sources */,
1FA35E7013F57B2800A6B347 /* RSColorPickerAppDelegate.m in Sources */,
2B85423116EFC8970047FFBE /* ANImageBitmapRep.m in Sources */,
2B85423216EFC8970047FFBE /* BitmapContextRep.m in Sources */,
2B85423316EFC8970047FFBE /* NSImage+ANImageBitmapRep.m in Sources */,
FA5AA0EA185F6477000355FE /* RSBrightnessSlider.m in Sources */,
2B85423416EFC8970047FFBE /* OSCommonImage.m in Sources */,
2B85423516EFC8970047FFBE /* UIImage+ANImageBitmapRep.m in Sources */,
2B85423616EFC8970047FFBE /* CGContextCreator.m in Sources */,
2B85423716EFC8970047FFBE /* CGImageContainer.m in Sources */,
2B85423816EFC8970047FFBE /* BitmapContextManipulator.m in Sources */,
FA5AA0EB185F6477000355FE /* RSOpacitySlider.m in Sources */,
2B85423916EFC8970047FFBE /* BitmapCropManipulator.m in Sources */,
2B85423A16EFC8970047FFBE /* BitmapDrawManipulator.m in Sources */,
2B85423B16EFC8970047FFBE /* BitmapRotationManipulator.m in Sources */,
FAFF6E4C185F84BD00412D58 /* RSColorPickerState.m in Sources */,
2B85423C16EFC8970047FFBE /* BitmapScaleManipulator.m in Sources */,
2B85423D16EFC8970047FFBE /* BGRSLoupeLayer.m in Sources */,
2B85423F16EFC8970047FFBE /* RSColorFunctions.m in Sources */,
2B85424016EFC8970047FFBE /* RSColorPickerView.m in Sources */,
2B85424116EFC8970047FFBE /* RSSelectionLayer.m in Sources */,
2B12A0DF1792FF46007F2A0A /* TestColorViewController.m in Sources */,
94A10AFF179DB67C00F0BD7E /* RSGenerateOperation.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
2BFBDBD418D2574400DFC1E5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2BF47AD318D4D44600C12FA5 /* RSColorPickerViewDelegateTests.m in Sources */,
2B78462718D290340002F859 /* CPTestCase.m in Sources */,
2BF8BFF818E9B67600E7C5BF /* RSColorPickerStateTests.m in Sources */,
2BFBDBE418D2574400DFC1E5 /* RSColorPickerViewTests.m in Sources */,
2B989DF318D61F760049D521 /* RSColorFunctionsTests.m in Sources */,
2B78462918D298570002F859 /* CPTestCaseTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
2BFBDBE718D2574400DFC1E5 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 1FA35E5A13F57B2700A6B347 /* RSColorPicker */;
targetProxy = 2BFBDBE618D2574400DFC1E5 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
1FA35E6813F57B2800A6B347 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
1FA35E6913F57B2800A6B347 /* en */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
2BFBDBE018D2574400DFC1E5 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
2BFBDBE118D2574400DFC1E5 /* en */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
1FA35E7413F57B2800A6B347 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_VERSION = com.apple.compilers.llvmgcc42;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 4.3;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
1FA35E7513F57B2800A6B347 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_VERSION = com.apple.compilers.llvmgcc42;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 4.3;
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
SDKROOT = iphoneos;
};
name = Release;
};
1FA35E7713F57B2800A6B347 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(DEVELOPER_FRAMEWORKS_DIR)",
);
GCC_DYNAMIC_NO_PIC = NO;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "RSColorPicker/RSColorPicker-Prefix.pch";
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
INFOPLIST_FILE = "RSColorPicker/RSColorPicker-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
WRAPPER_EXTENSION = app;
};
name = Debug;
};
1FA35E7813F57B2800A6B347 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(DEVELOPER_FRAMEWORKS_DIR)",
);
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "RSColorPicker/RSColorPicker-Prefix.pch";
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
INFOPLIST_FILE = "RSColorPicker/RSColorPicker-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
VALIDATE_PRODUCT = YES;
WRAPPER_EXTENSION = app;
};
name = Release;
};
2BFBDBE818D2574400DFC1E5 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/RSColorPicker.app/RSColorPicker";
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
"$(DEVELOPER_FRAMEWORKS_DIR)",
);
GCC_DYNAMIC_NO_PIC = NO;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "RSColorPickerTests/RSColorPickerTests-Prefix.pch";
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
INFOPLIST_FILE = "RSColorPickerTests/RSColorPickerTests-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 7.1;
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUNDLE_LOADER)";
WRAPPER_EXTENSION = xctest;
};
name = Debug;
};
2BFBDBE918D2574400DFC1E5 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/RSColorPicker.app/RSColorPicker";
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
"$(DEVELOPER_FRAMEWORKS_DIR)",
);
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "RSColorPickerTests/RSColorPickerTests-Prefix.pch";
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
INFOPLIST_FILE = "RSColorPickerTests/RSColorPickerTests-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 7.1;
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUNDLE_LOADER)";
VALIDATE_PRODUCT = YES;
WRAPPER_EXTENSION = xctest;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1FA35E5513F57B2700A6B347 /* Build configuration list for PBXProject "RSColorPicker" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1FA35E7413F57B2800A6B347 /* Debug */,
1FA35E7513F57B2800A6B347 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1FA35E7613F57B2800A6B347 /* Build configuration list for PBXNativeTarget "RSColorPicker" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1FA35E7713F57B2800A6B347 /* Debug */,
1FA35E7813F57B2800A6B347 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
2BFBDBEA18D2574400DFC1E5 /* Build configuration list for PBXNativeTarget "RSColorPickerTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2BFBDBE818D2574400DFC1E5 /* Debug */,
2BFBDBE918D2574400DFC1E5 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 1FA35E5213F57B2700A6B347 /* Project object */;
}
================================================
FILE: RSColorPicker.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:RSColorPicker.xcodeproj">
</FileRef>
</Workspace>
================================================
FILE: RSColorPicker.xcodeproj/xcshareddata/xcschemes/RSColorPicker.xcscheme
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0500"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1FA35E5A13F57B2700A6B347"
BuildableName = "RSColorPicker.app"
BlueprintName = "RSColorPicker"
ReferencedContainer = "container:RSColorPicker.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "2BFBDBD718D2574400DFC1E5"
BuildableName = "RSColorPickerTests.xctest"
BlueprintName = "RSColorPickerTests"
ReferencedContainer = "container:RSColorPicker.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1FA35E5A13F57B2700A6B347"
BuildableName = "RSColorPicker.app"
BlueprintName = "RSColorPicker"
ReferencedContainer = "container:RSColorPicker.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1FA35E5A13F57B2700A6B347"
BuildableName = "RSColorPicker.app"
BlueprintName = "RSColorPicker"
ReferencedContainer = "container:RSColorPicker.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1FA35E5A13F57B2700A6B347"
BuildableName = "RSColorPicker.app"
BlueprintName = "RSColorPicker"
ReferencedContainer = "container:RSColorPicker.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
================================================
FILE: RSColorPickerTests/CPTestCase.h
================================================
//
// CPTestCase.h
// RSColorPicker
//
// Created by Ryan Sullivan on 3/13/14.
//
//
#import <XCTest/XCTest.h>
#define kColorComponentAccuracy (1.0/255.0)
@interface CPTestCase : XCTestCase
- (void)assertColor:(UIColor *)colorA equalsColor:(UIColor *)colorB;
- (void)assertColor:(UIColor *)colorA notEqualsColor:(UIColor *)colorB;
@end
================================================
FILE: RSColorPickerTests/CPTestCase.m
================================================
//
// CPTestCase.m
// RSColorPicker
//
// Created by Ryan Sullivan on 3/13/14.
//
//
#import "CPTestCase.h"
#import "RSColorFunctions.h"
@implementation CPTestCase
#pragma mark - Component helpers
- (void)assertColor:(UIColor *)colorA equalsColor:(UIColor *)colorB
{
CGFloat rgbaA[4];
CGFloat rgbaB[4];
RSGetComponentsForColor(rgbaA, colorA);
RSGetComponentsForColor(rgbaB, colorB);
XCTAssertEqualWithAccuracy(rgbaA[0], rgbaB[0], kColorComponentAccuracy);
XCTAssertEqualWithAccuracy(rgbaA[1], rgbaB[1], kColorComponentAccuracy);
XCTAssertEqualWithAccuracy(rgbaA[2], rgbaB[2], kColorComponentAccuracy);
XCTAssertEqualWithAccuracy(rgbaA[3], rgbaB[3], kColorComponentAccuracy);
// Check it manually too
// Might as well keep this code around if we're maintaining the one below
XCTAssert(
(fabs(rgbaA[0] - rgbaB[0]) < kColorComponentAccuracy) &&
(fabs(rgbaA[1] - rgbaB[1]) < kColorComponentAccuracy) &&
(fabs(rgbaA[2] - rgbaB[2]) < kColorComponentAccuracy) &&
(fabs(rgbaA[3] - rgbaB[3]) < kColorComponentAccuracy),
@"Color %@ does not equal color %@, but they should be equal", colorA, colorB
);
}
- (void)assertColor:(UIColor *)colorA notEqualsColor:(UIColor *)colorB
{
CGFloat rgbaA[4];
CGFloat rgbaB[4];
RSGetComponentsForColor(rgbaA, colorA);
RSGetComponentsForColor(rgbaB, colorB);
XCTAssert(
(fabs(rgbaA[0] - rgbaB[0]) > kColorComponentAccuracy) ||
(fabs(rgbaA[1] - rgbaB[1]) > kColorComponentAccuracy) ||
(fabs(rgbaA[2] - rgbaB[2]) > kColorComponentAccuracy) ||
(fabs(rgbaA[3] - rgbaB[3]) > kColorComponentAccuracy),
@"Color %@ is too similar to %@, but they should not be equal", colorA, colorB
);
}
@end
================================================
FILE: RSColorPickerTests/CPTestCaseTests.m
================================================
//
// CPTestCaseTests.m
// RSColorPicker
//
// Created by Ryan Sullivan on 3/13/14.
//
//
#import <XCTest/XCTest.h>
@interface CPTestCaseTests : CPTestCase
@end
@implementation CPTestCaseTests
- (void)testAssertColorEqualsColor
{
UIColor *redA = [UIColor redColor];
UIColor *redB = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0];
[self assertColor:redA equalsColor:redB];
}
- (void)testAssertColorNotEqualsColor
{
UIColor *red = [UIColor redColor];
UIColor *green = [UIColor greenColor];
[self assertColor:red notEqualsColor:green];
}
@end
================================================
FILE: RSColorPickerTests/RSColorFunctionsTests.m
================================================
//
// RSColorFunctionsTests.m
// RSColorPicker
//
// Created by Ryan Sullivan on 3/16/14.
//
//
#import <XCTest/XCTest.h>
#import "RSColorFunctions.h"
@interface RSColorFunctionsTests : CPTestCase
@end
@implementation RSColorFunctionsTests
- (void)setUp
{
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown
{
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testPixelFromHSV {
UIColor *actual, *expected;
// Inefficient, but should be OK:
for (CGFloat h = 0; h < 1; h += 0.05)
{
for (CGFloat s = 0; s < 1; s += 0.05)
{
for (CGFloat v = 0; v < 0; v += 0.05)
{
actual = UIColorFromBMPixel(RSPixelFromHSV(h, s, v));
expected = [UIColor colorWithHue:h saturation:s brightness:v alpha:1.0];
[self assertColor:actual equalsColor:expected];
}
}
}
}
- (void)testHSVFromPixel {
// Not really needed yet, since we're using Apple's implementation
BMPixel pixel = BMPixelMake(0, 0, 0, 1.0);
CGFloat h, s, v;
RSHSVFromPixel(pixel, &h, &s, &v);
UIColor *color1 = [UIColor colorWithRed:0 green:0 blue:0 alpha:1.0];
UIColor *color2 = [UIColor colorWithHue:h saturation:s brightness:v alpha:1.0];
[self assertColor:color1 equalsColor:color2];
}
- (void)testComponentsForColor_rgb {
UIColor *color = [UIColor colorWithRed:0.1 green:0.2 blue:0.3 alpha:0.4];
UIColor *testColor;
CGFloat components[4];
RSGetComponentsForColor(components, color);
testColor = [UIColor colorWithRed:components[0] green:components[1] blue:components[2] alpha:components[3]];
[self assertColor:color equalsColor:testColor];
}
- (void)testComponentsForColor_gray {
UIColor *color = [UIColor colorWithWhite:0.1 alpha:0.2];
UIColor *testColor;
CGFloat components[4];
RSGetComponentsForColor(components, color);
testColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:0.2];
[self assertColor:color equalsColor:testColor];
testColor = [UIColor colorWithRed:components[0] green:components[1] blue:components[2] alpha:components[3]];
[self assertColor:color equalsColor:testColor];
}
- (void)testComponentsForColor_hsv {
UIColor *color = [UIColor colorWithHue:0 saturation:1.0 brightness:1.0 alpha:0.4];
UIColor *testColor;
CGFloat components[4];
RSGetComponentsForColor(components, color);
testColor = [UIColor colorWithRed:1.0 green:0 blue:0 alpha:0.4];
[self assertColor:color equalsColor:testColor];
testColor = [UIColor colorWithRed:components[0] green:components[1] blue:components[2] alpha:components[3]];
[self assertColor:color equalsColor:testColor];
}
- (void)testComponentsForColor_cmyk {
// All of this just to get a CMYK color
UIColor * (^colorFromCMYK)(CGFloat C, CGFloat M, CGFloat Y, CGFloat K, CGFloat A) = ^UIColor*(CGFloat C, CGFloat M, CGFloat Y, CGFloat K, CGFloat A){
CGColorSpaceRef cmykColorSpace = CGColorSpaceCreateDeviceCMYK();
CGFloat colors[5] = {C, M, Y, K, A}; // CMYK+Alpha
CGColorRef cgColor = CGColorCreate(cmykColorSpace, colors);
UIColor *color = [UIColor colorWithCGColor:cgColor];
CGColorRelease(cgColor);
CGColorSpaceRelease(cmykColorSpace);
return color;
};
UIColor *color;
UIColor *testColor;
CGFloat components[4];
// Test all 1 (black + black)
color = colorFromCMYK(1, 1, 1, 1, 0.5);
RSGetComponentsForColor(components, color);
testColor = [UIColor colorWithWhite:0 alpha:0.5];
[self assertColor:color equalsColor:testColor];
testColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
[self assertColor:color equalsColor:testColor];
// Test all 0 with 1 (black)
color = colorFromCMYK(0, 0, 0, 1, 0.5);
RSGetComponentsForColor(components, color);
testColor = [UIColor colorWithWhite:0 alpha:0.5];
[self assertColor:color equalsColor:testColor];
testColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
[self assertColor:color equalsColor:testColor];
// Test all 0 (white)
color = colorFromCMYK(0, 0, 0, 0, 0.5);
RSGetComponentsForColor(components, color);
testColor = [UIColor colorWithWhite:1 alpha:0.5];
[self assertColor:color equalsColor:testColor];
testColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.5];
[self assertColor:color equalsColor:testColor];
}
- (void)testImageWithScale {
}
- (void)testOpacityBackgroundImage {
}
- (void)testRandomColor {
CGFloat components[4];
UIColor *color = RSRandomColorOpaque(YES);
RSGetComponentsForColor(components, color);
XCTAssertEqualWithAccuracy(components[3], 1.0, kColorComponentAccuracy);
}
@end
================================================
FILE: RSColorPickerTests/RSColorPickerStateTests.m
================================================
//
// RSColorPickerStateTests.m
// RSColorPicker
//
// Created by Ryan Sullivan on 3/31/14.
//
//
#import <XCTest/XCTest.h>
#import "RSColorPickerState.h"
#import "RSColorFunctions.h"
@interface RSColorPickerStateTests : CPTestCase
@end
@implementation RSColorPickerStateTests
- (void)setUp
{
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown
{
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testHue_initWithColor {
for (int i = 0; i < 5; i++)
{
UIColor *expectedColor = RSRandomColorOpaque(i % 2 == 0);
RSColorPickerState *state = [[RSColorPickerState alloc] initWithColor:expectedColor];
CGFloat h, s, v, a;
[expectedColor getHue:NULL saturation:&s brightness:&v alpha:&a];
h = state.hue;
UIColor *actualColor = [UIColor colorWithHue:h saturation:s brightness:v alpha:a];
[self assertColor:actualColor equalsColor:expectedColor];
}
}
- (void)testSaturation_initWithColor {
for (int i = 0; i < 5; i++)
{
UIColor *expectedColor = RSRandomColorOpaque(i % 2 == 0);
RSColorPickerState *state = [[RSColorPickerState alloc] initWithColor:expectedColor];
CGFloat h, s, v, a;
[expectedColor getHue:&h saturation:NULL brightness:&v alpha:&a];
s = state.saturation;
UIColor *actualColor = [UIColor colorWithHue:h saturation:s brightness:v alpha:a];
[self assertColor:actualColor equalsColor:expectedColor];
}
}
- (void)testColor_initWithColor {
for (int i = 0; i < 5; i++)
{
UIColor *expectedColor = RSRandomColorOpaque(i % 2 == 0);
RSColorPickerState *state = [[RSColorPickerState alloc] initWithColor:expectedColor];
[self assertColor:state.color equalsColor:expectedColor];
}
}
- (void)testColor_initWithScaledRelativePoint {
// Scaled relative point is *relative*, so 0,0 is the center, which should be white
RSColorPickerState *state = [[RSColorPickerState alloc] initWithScaledRelativePoint:CGPointMake(0, 0)
brightness:1.0 alpha:1.0];
UIColor *expectedColor = [UIColor whiteColor];
[self assertColor:expectedColor equalsColor:state.color];
}
- (void)testColor_stateForPointSizePadding {
// Regardless of padding, 100,100 is the center point of a 200px circle, which is white
// Assumed that default is 100% brightness and 100% alpha
RSColorPickerState *state = [RSColorPickerState stateForPoint:CGPointMake(100, 100) size:200 padding:0];
UIColor *expectedColor = [UIColor whiteColor];
[self assertColor:expectedColor equalsColor:state.color];
}
- (void)testColor_initWithHueSaturationBrightnessAlpha {
RSColorPickerState *state = [[RSColorPickerState alloc] initWithHue:0 saturation:0 brightness:1.0 alpha:1.0];
UIColor *expectedColor = [UIColor whiteColor];
[self assertColor:expectedColor equalsColor:state.color];
}
- (void)testSelectionLocationWithSizePadding {
UIColor *expectedColor;
RSColorPickerState *state;
CGPoint expectedPoint, actualPoint;
NSArray *centerTests = @[[UIColor blackColor], [UIColor whiteColor], [UIColor colorWithWhite:0.5 alpha:1.0]];
for (expectedColor in centerTests)
{
state = [[RSColorPickerState alloc] initWithColor:expectedColor];
expectedPoint = CGPointMake(100, 100);
actualPoint = [state selectionLocationWithSize:200.0 padding:20.0];
XCTAssertEqual(expectedPoint.x, actualPoint.x);
XCTAssertEqual(expectedPoint.y, actualPoint.y);
}
}
@end
================================================
FILE: RSColorPickerTests/RSColorPickerTests-Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>me.rsullivan.tests.rscolorpicker.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
================================================
FILE: RSColorPickerTests/RSColorPickerTests-Prefix.pch
================================================
//
// Prefix header
//
// The contents of this file are implicitly included at the beginning of every source file.
//
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <XCTest/XCTest.h>
#import "CPTestCase.h"
#endif
================================================
FILE: RSColorPickerTests/RSColorPickerViewDelegateTests.m
================================================
//
// RSColorPickerViewDelegateTests.m
// RSColorPicker
//
// Created by Ryan Sullivan on 3/15/14.
//
//
#import <XCTest/XCTest.h>
#import "RSColorPickerView.h"
#import "RSColorFunctions.h"
@interface RSColorPickerViewDelegateTests : CPTestCase <RSColorPickerViewDelegate>
@property (nonatomic) RSColorPickerView * colorPicker;
@property (nonatomic) int delegateDidChangeSelectionCalledCount;
@end
@implementation RSColorPickerViewDelegateTests
- (void)setUp
{
[super setUp];
// Reset counter
self.delegateDidChangeSelectionCalledCount = 0;
self.colorPicker = [[RSColorPickerView alloc] initWithFrame:CGRectMake(0.0, 0.0, 200.0, 200.0)];
self.colorPicker.selectionColor = RSRandomColorOpaque(NO);
// Make sure we set delegate last so counters don't get messed up by init
self.colorPicker.delegate = self;
}
- (void)tearDown
{
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testDelegateDidChangeSelection_selectionColor
{
self.colorPicker.selectionColor = RSRandomColorOpaque(NO);
XCTAssertEqual(self.delegateDidChangeSelectionCalledCount, 1);
}
- (void)testDelegateDidChangeSelection_selection
{
self.colorPicker.selection = CGPointMake(100.0, 100.0);
XCTAssertEqual(self.delegateDidChangeSelectionCalledCount, 1);
}
#pragma mark - RSColorPickerView Delegates
- (void)colorPickerDidChangeSelection:(RSColorPickerView *)cp
{
self.delegateDidChangeSelectionCalledCount++;
NSLog(@"Got RSColorPickerViewDelegate selection change callback");
}
- (void)colorPicker:(RSColorPickerView *)colorPicker touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
XCTFail(@"Got -touchesBegan from running tests");
}
- (void)colorPicker:(RSColorPickerView *)colorPicker touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
XCTFail(@"Got -touchesEnded from running tests");
}
@end
================================================
FILE: RSColorPickerTests/RSColorPickerViewTests.m
================================================
//
// RSColorPickerTests.m
// RSColorPickerTests
//
// Created by Ryan Sullivan on 3/13/14.
//
//
#import <XCTest/XCTest.h>
#import "RSColorPickerView.h"
#import "RSColorFunctions.h"
#import "RSColorPickerState.h"
@interface RSColorPickerViewTests : CPTestCase <RSColorPickerViewDelegate>
@property (nonatomic) RSColorPickerView * colorPicker;
@end
@implementation RSColorPickerViewTests
- (void)setUp
{
[super setUp];
self.colorPicker = [[RSColorPickerView alloc] initWithFrame:CGRectMake(0.0, 0.0, 200.0, 200.0)];
self.colorPicker.selectionColor = RSRandomColorOpaque(NO);
self.colorPicker.delegate = self;
}
- (void)tearDown
{
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testSetSelectionColor_multiple
{
UIColor *newSelection = RSRandomColorOpaque(NO);
self.colorPicker.selectionColor = newSelection;
UIColor *setA = self.colorPicker.selectionColor;
self.colorPicker.selectionColor = newSelection;
UIColor *setB = self.colorPicker.selectionColor;
[self assertColor:newSelection equalsColor:setA];
[self assertColor:newSelection equalsColor:setB];
XCTAssertEqualObjects(setA, setB);
}
- (void)testSetSelectionColor_random
{
UIColor *newSelection = RSRandomColorOpaque(NO);
UIColor *oldSelection = self.colorPicker.selectionColor;
self.colorPicker.selectionColor = newSelection;
UIColor *currentSelection = self.colorPicker.selectionColor;
[self assertColor:currentSelection notEqualsColor:oldSelection];
[self assertColor:currentSelection equalsColor:newSelection];
}
- (void)testSetSelectionColor_self
{
UIColor *currentColor = self.colorPicker.selectionColor;
// Re-set it
self.colorPicker.selectionColor = currentColor;
UIColor *newCurrentColor = self.colorPicker.selectionColor;
[self assertColor:currentColor equalsColor:newCurrentColor];
XCTAssertEqualObjects(currentColor, newCurrentColor);
}
- (void)testSetCropToCircle
{
self.colorPicker.cropToCircle = YES;
XCTAssertTrue(self.colorPicker.cropToCircle);
self.colorPicker.cropToCircle = NO;
XCTAssertFalse(self.colorPicker.cropToCircle);
}
- (void)testSetSelection_pointByColor
{
// Requirements
CGFloat size = self.colorPicker.bounds.size.height;
CGFloat padding = self.colorPicker.paddingDistance;
// Fetch current state/selection
CGPoint oldSelec
gitextract_9nhdc9e5/
├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── RSColorPicker/
│ ├── ColorPickerClasses/
│ │ ├── ANImageBitmapRep/
│ │ │ ├── ANImageBitmapRep.h
│ │ │ ├── ANImageBitmapRep.m
│ │ │ ├── BitmapContextRep.h
│ │ │ ├── BitmapContextRep.m
│ │ │ ├── Compatibility/
│ │ │ │ ├── NSImage+ANImageBitmapRep.h
│ │ │ │ ├── NSImage+ANImageBitmapRep.m
│ │ │ │ ├── OSCommonImage.h
│ │ │ │ ├── OSCommonImage.m
│ │ │ │ ├── UIImage+ANImageBitmapRep.h
│ │ │ │ └── UIImage+ANImageBitmapRep.m
│ │ │ ├── CoreGraphics/
│ │ │ │ ├── CGContextCreator.h
│ │ │ │ ├── CGContextCreator.m
│ │ │ │ ├── CGImageContainer.h
│ │ │ │ └── CGImageContainer.m
│ │ │ └── Manipulators/
│ │ │ ├── BitmapContextManipulator.h
│ │ │ ├── BitmapContextManipulator.m
│ │ │ ├── BitmapCropManipulator.h
│ │ │ ├── BitmapCropManipulator.m
│ │ │ ├── BitmapDrawManipulator.h
│ │ │ ├── BitmapDrawManipulator.m
│ │ │ ├── BitmapRotationManipulator.h
│ │ │ ├── BitmapRotationManipulator.m
│ │ │ ├── BitmapScaleManipulator.h
│ │ │ └── BitmapScaleManipulator.m
│ │ ├── BGRSLoupeLayer.h
│ │ ├── BGRSLoupeLayer.m
│ │ ├── RSColorFunctions.h
│ │ ├── RSColorFunctions.m
│ │ ├── RSColorPickerState.h
│ │ ├── RSColorPickerState.m
│ │ ├── RSColorPickerView.h
│ │ ├── RSColorPickerView.m
│ │ ├── RSGenerateOperation.h
│ │ ├── RSGenerateOperation.m
│ │ ├── RSSelectionLayer.h
│ │ └── RSSelectionLayer.m
│ ├── RSBrightnessSlider.h
│ ├── RSBrightnessSlider.m
│ ├── RSColorPicker-Info.plist
│ ├── RSColorPicker-Prefix.pch
│ ├── RSColorPickerAppDelegate.h
│ ├── RSColorPickerAppDelegate.m
│ ├── RSOpacitySlider.h
│ ├── RSOpacitySlider.m
│ ├── TestColorViewController.h
│ ├── TestColorViewController.m
│ ├── en.lproj/
│ │ └── InfoPlist.strings
│ └── main.m
├── RSColorPicker.podspec
├── RSColorPicker.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── xcshareddata/
│ └── xcschemes/
│ └── RSColorPicker.xcscheme
└── RSColorPickerTests/
├── CPTestCase.h
├── CPTestCase.m
├── CPTestCaseTests.m
├── RSColorFunctionsTests.m
├── RSColorPickerStateTests.m
├── RSColorPickerTests-Info.plist
├── RSColorPickerTests-Prefix.pch
├── RSColorPickerViewDelegateTests.m
├── RSColorPickerViewTests.m
└── en.lproj/
└── InfoPlist.strings
SYMBOL INDEX (11 symbols across 9 files)
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/ANImageBitmapRep.h
type BMPixel (line 16) | typedef struct {
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/BitmapContextRep.h
type BMPoint (line 18) | typedef struct {
function interface (line 32) | interface BitmapContextRep : NSObject {
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Compatibility/OSCommonImage.h
type UIImage (line 17) | typedef UIImage ANImageObj;
type NSImage (line 20) | typedef NSImage ANImageObj;
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/CoreGraphics/CGContextCreator.h
function interface (line 23) | interface CGContextCreator : NSObject {
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/CoreGraphics/CGImageContainer.h
function interface (line 20) | interface CGImageContainer : NSObject {
FILE: RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapContextManipulator.h
function interface (line 12) | interface BitmapContextManipulator : NSObject <BitmapContextRep> {
FILE: RSColorPicker/ColorPickerClasses/BGRSLoupeLayer.h
function interface (line 36) | interface BGRSLoupeLayer : CALayer {
FILE: RSColorPicker/ColorPickerClasses/RSColorPickerState.h
function interface (line 21) | interface RSColorPickerState : NSObject {
FILE: RSColorPicker/TestColorViewController.h
function interface (line 15) | interface TestColorViewController : UIViewController <RSColorPickerViewD...
Condensed preview — 67 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (209K chars).
[
{
"path": ".gitignore",
"chars": 242,
"preview": "# OS X\n.DS_Store\n\n# Xcode\nbuild/\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.pers"
},
{
"path": ".travis.yml",
"chars": 147,
"preview": "language: objective-c\nxcode_project: RSColorPicker.xcodeproj\nxcode_scheme: RSColorPicker\nxcode_sdk: iphonesimulator\nnoti"
},
{
"path": "CONTRIBUTING.md",
"chars": 859,
"preview": "\n# Contributing\n\nPull requests are welcome for bug fixes or feature additions. If you contribute code, make sure you sti"
},
{
"path": "LICENSE.md",
"chars": 1343,
"preview": "[RSColorPicker](https://github.com/RSully/RSColorPicker) - Copyright (c) 2011, Ryan (RSully)\nAll rights reserved.\n\nRedis"
},
{
"path": "README.md",
"chars": 1678,
"preview": "\n# Project:\n\n[](https://travis-ci.org/RSull"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/ANImageBitmapRep.h",
"chars": 2919,
"preview": "//\n// ANImageBitmapRep.h\n// ImageManip\n//\n// Created by Alex Nichol on 7/12/11.\n// Copyright 2011 __MyCompanyName__."
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/ANImageBitmapRep.m",
"chars": 5875,
"preview": "//\n// ANImageBitmapRep.m\n// ImageManip\n//\n// Created by Alex Nichol on 7/12/11.\n// Copyright 2011 __MyCompanyName__."
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/BitmapContextRep.h",
"chars": 3939,
"preview": "//\n// BitmapContextRep.h\n// ImageManip\n//\n// Created by Alex Nichol on 7/12/11.\n// Copyright 2011 __MyCompanyName__."
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/BitmapContextRep.m",
"chars": 3936,
"preview": "//\n// BitmapContextRep.m\n// ImageManip\n//\n// Created by Alex Nichol on 7/12/11.\n// Copyright 2011 __MyCompanyName__."
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Compatibility/NSImage+ANImageBitmapRep.h",
"chars": 1041,
"preview": "//\n// NSImage+ANImageBitmapRep.h\n// ImageBitmapRep\n//\n// Created by Alex Nichol on 10/23/11.\n// Copyright (c) 2011 _"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Compatibility/NSImage+ANImageBitmapRep.m",
"chars": 1687,
"preview": "//\n// NSImage+ANImageBitmapRep.m\n// ImageBitmapRep\n//\n// Created by Alex Nichol on 10/23/11.\n// Copyright (c) 2011 _"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Compatibility/OSCommonImage.h",
"chars": 565,
"preview": "//\n// OSCommonImage.h\n// ImageBitmapRep\n//\n// Created by Alex Nichol on 10/23/11.\n// Copyright (c) 2011 __MyCompanyN"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Compatibility/OSCommonImage.m",
"chars": 1353,
"preview": "//\n// OSCommonImage.c\n// ImageBitmapRep\n//\n// Created by Alex Nichol on 10/23/11.\n// Copyright (c) 2011 __MyCompanyN"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Compatibility/UIImage+ANImageBitmapRep.h",
"chars": 1031,
"preview": "//\n// UIImage+ANImageBitmapRep.h\n// ImageBitmapRep\n//\n// Created by Alex Nichol on 8/11/11.\n// Copyright 2011 __MyCo"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Compatibility/UIImage+ANImageBitmapRep.m",
"chars": 1677,
"preview": "//\n// UIImage+ANImageBitmapRep.m\n// ImageBitmapRep\n//\n// Created by Alex Nichol on 8/11/11.\n// Copyright 2011 __MyCo"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/CoreGraphics/CGContextCreator.h",
"chars": 672,
"preview": "//\n// CGContextCreator.h\n// ImageBitmapRep\n//\n// Created by Alex Nichol on 7/4/11.\n// Copyright 2011 __MyCompanyName"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/CoreGraphics/CGContextCreator.m",
"chars": 4369,
"preview": "//\n// CGContextCreator.m\n// ImageBitmapRep\n//\n// Created by Alex Nichol on 7/4/11.\n// Copyright 2011 __MyCompanyName"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/CoreGraphics/CGImageContainer.h",
"chars": 1347,
"preview": "//\n// CGImageContainer.h\n// ImageBitmapRep\n//\n// Created by Alex Nichol on 5/3/11.\n// Copyright 2011 __MyCompanyName"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/CoreGraphics/CGImageContainer.m",
"chars": 872,
"preview": "//\n// CGImageContainer.m\n// ImageBitmapRep\n//\n// Created by Alex Nichol on 5/3/11.\n// Copyright 2011 __MyCompanyName"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapContextManipulator.h",
"chars": 663,
"preview": "//\n// BitmapContextManip.h\n// ImageBitmapRep\n//\n// Created by Alex Nichol on 10/14/11.\n// Copyright 2011 __MyCompany"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapContextManipulator.m",
"chars": 642,
"preview": "//\n// BitmapContextManip.m\n// ImageBitmapRep\n//\n// Created by Alex Nichol on 10/14/11.\n// Copyright 2011 __MyCompany"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapCropManipulator.h",
"chars": 1844,
"preview": "//\n// CroppableBitmapRep.h\n// ImageManip\n//\n// Created by Alex Nichol on 7/12/11.\n// Copyright 2011 __MyCompanyName_"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapCropManipulator.m",
"chars": 4245,
"preview": "//\n// CroppableBitmapRep.m\n// ImageManip\n//\n// Created by Alex Nichol on 7/12/11.\n// Copyright 2011 __MyCompanyName_"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapDrawManipulator.h",
"chars": 1061,
"preview": "//\n// BitmapDrawManipulator.h\n// FaceBlur\n//\n// Created by Alex Nichol on 7/1/12.\n// Copyright (c) 2012 __MyCompanyN"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapDrawManipulator.m",
"chars": 1534,
"preview": "//\n// BitmapDrawManipulator.m\n// FaceBlur\n//\n// Created by Alex Nichol on 7/1/12.\n// Copyright (c) 2012 __MyCompanyN"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapRotationManipulator.h",
"chars": 987,
"preview": "//\n// RotatableBitmapRep.h\n// ImageManip\n//\n// Created by Alex Nichol on 7/12/11.\n// Copyright 2011 __MyCompanyName_"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapRotationManipulator.m",
"chars": 7436,
"preview": "//\n// RotatableBitmapRep.m\n// ImageManip\n//\n// Created by Alex Nichol on 7/12/11.\n// Copyright 2011 __MyCompanyName_"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapScaleManipulator.h",
"chars": 1342,
"preview": "//\n// ScalableBitmapRep.h\n// ImageManip\n//\n// Created by Alex Nichol on 7/12/11.\n// Copyright 2011 __MyCompanyName__"
},
{
"path": "RSColorPicker/ColorPickerClasses/ANImageBitmapRep/Manipulators/BitmapScaleManipulator.m",
"chars": 2781,
"preview": "//\n// ScalableBitmapRep.m\n// ImageManip\n//\n// Created by Alex Nichol on 7/12/11.\n// Copyright 2011 __MyCompanyName__"
},
{
"path": "RSColorPicker/ColorPickerClasses/BGRSLoupeLayer.h",
"chars": 2111,
"preview": "/** \n * BGRSLoupeLayer.h\n * Copyright (c) 2011, Benjamin Guest.\n * All rights reserved.\n *\n * Redistribution and use in"
},
{
"path": "RSColorPicker/ColorPickerClasses/BGRSLoupeLayer.m",
"chars": 11684,
"preview": "/**\n * BGRSLoupeLayer.m\n * Copyright (c) 2011, Benjamin Guest.\n * All rights reserved.\n *\n * Redistribution and use in s"
},
{
"path": "RSColorPicker/ColorPickerClasses/RSColorFunctions.h",
"chars": 582,
"preview": "//\n// RSColorFunctions.h\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 3/12/13.\n//\n\n#import <UIKit/UIKit.h>\n#imp"
},
{
"path": "RSColorPicker/ColorPickerClasses/RSColorFunctions.m",
"chars": 5857,
"preview": "//\n// RSColorFunctions.m\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 3/12/13.\n//\n\n#import \"RSColorFunctions.h\""
},
{
"path": "RSColorPicker/ColorPickerClasses/RSColorPickerState.h",
"chars": 1988,
"preview": "//\n// RSColorPickerState.h\n// RSColorPicker\n//\n// Created by Alex Nichol on 12/16/13.\n//\n\n#import <Foundation/Foundat"
},
{
"path": "RSColorPicker/ColorPickerClasses/RSColorPickerState.m",
"chars": 4446,
"preview": "//\n// RSColorPickerState.m\n// RSColorPicker\n//\n// Created by Alex Nichol on 12/16/13.\n//\n\n#import \"RSColorPickerState"
},
{
"path": "RSColorPicker/ColorPickerClasses/RSColorPickerView.h",
"chars": 2463,
"preview": "//\n// RSColorPickerView.h\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 8/12/11.\n//\n\n#import <UIKit/UIKit.h>\n#im"
},
{
"path": "RSColorPicker/ColorPickerClasses/RSColorPickerView.m",
"chars": 16210,
"preview": "//\n// RSColorPickerView.m\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 8/12/11.\n//\n\n\n#import \"ANImageBitmapRep."
},
{
"path": "RSColorPicker/ColorPickerClasses/RSGenerateOperation.h",
"chars": 415,
"preview": "//\n// GenerateOperation.h\n// RSColorPicker\n//\n// Created by Ryan on 7/22/13.\n//\n\n#import <Foundation/Foundation.h>\n#i"
},
{
"path": "RSColorPicker/ColorPickerClasses/RSGenerateOperation.m",
"chars": 2402,
"preview": "//\n// GenerateOperation.m\n// RSColorPicker\n//\n// Created by Ryan on 7/22/13.\n//\n\n#import \"RSGenerateOperation.h\"\n#imp"
},
{
"path": "RSColorPicker/ColorPickerClasses/RSSelectionLayer.h",
"chars": 159,
"preview": "//\n// RSSelectionView.h\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 3/12/13.\n//\n\n#import <UIKit/UIKit.h>\n\n@int"
},
{
"path": "RSColorPicker/ColorPickerClasses/RSSelectionLayer.m",
"chars": 999,
"preview": "//\n// RSSelectionView.m\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 3/12/13.\n//\n\n#import \"RSSelectionLayer.h\"\n"
},
{
"path": "RSColorPicker/RSBrightnessSlider.h",
"chars": 261,
"preview": "//\n// RSBrightnessSlider.h\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 8/12/11.\n//\n\n#import <Foundation/Founda"
},
{
"path": "RSColorPicker/RSBrightnessSlider.m",
"chars": 4781,
"preview": "//\n// RSBrightnessSlider.m\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 8/12/11.\n//\n\n#import \"RSBrightnessSlide"
},
{
"path": "RSColorPicker/RSColorPicker-Info.plist",
"chars": 1040,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "RSColorPicker/RSColorPicker-Prefix.pch",
"chars": 332,
"preview": "//\n// Prefix header for all source files of the 'RSColorPicker' target in the 'RSColorPicker' project\n//\n\n#import <Avail"
},
{
"path": "RSColorPicker/RSColorPickerAppDelegate.h",
"chars": 287,
"preview": "//\n// RSColorPickerAppDelegate.h\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 8/12/11.\n//\n\n#import <UIKit/UIKit"
},
{
"path": "RSColorPicker/RSColorPickerAppDelegate.m",
"chars": 949,
"preview": "//\n// RSColorPickerAppDelegate.m\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 8/12/11.\n//\n\n#import \"RSColorPick"
},
{
"path": "RSColorPicker/RSOpacitySlider.h",
"chars": 313,
"preview": "//\n// RSOpacitySlider.h\n// RSColorPicker\n//\n// Created by Jared Allen on 5/16/13.\n// Copyright (c) 2013 Red Cactus L"
},
{
"path": "RSColorPicker/RSOpacitySlider.m",
"chars": 1946,
"preview": "//\n// RSOpacitySlider.m\n// RSColorPicker\n//\n// Created by Jared Allen on 5/16/13.\n// Copyright (c) 2013 Red Cactus L"
},
{
"path": "RSColorPicker/TestColorViewController.h",
"chars": 628,
"preview": "//\n// TestColorViewController.h\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 7/14/13.\n//\n\n#import <UIKit/UIKit."
},
{
"path": "RSColorPicker/TestColorViewController.m",
"chars": 8896,
"preview": "//\n// TestColorViewController.m\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 7/14/13.\n//\n\n#import \"TestColorVie"
},
{
"path": "RSColorPicker/en.lproj/InfoPlist.strings",
"chars": 45,
"preview": "/* Localized versions of Info.plist keys */\n\n"
},
{
"path": "RSColorPicker/main.m",
"chars": 310,
"preview": "//\n// main.m\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 8/12/11.\n//\n\n#import <UIKit/UIKit.h>\n#import \"RSColor"
},
{
"path": "RSColorPicker.podspec",
"chars": 1138,
"preview": "Pod::Spec.new do |s|\n s.name = \"RSColorPicker\"\n s.version = \"0.9.2\"\n s.summary = \"iOS color picker "
},
{
"path": "RSColorPicker.xcodeproj/project.pbxproj",
"chars": 40354,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "RSColorPicker.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 158,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:RSColorPicker.x"
},
{
"path": "RSColorPicker.xcodeproj/xcshareddata/xcschemes/RSColorPicker.xcscheme",
"chars": 3655,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0500\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "RSColorPickerTests/CPTestCase.h",
"chars": 344,
"preview": "//\n// CPTestCase.h\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 3/13/14.\n//\n//\n\n#import <XCTest/XCTest.h>\n\n#def"
},
{
"path": "RSColorPickerTests/CPTestCase.m",
"chars": 1775,
"preview": "//\n// CPTestCase.m\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 3/13/14.\n//\n//\n\n#import \"CPTestCase.h\"\n#import "
},
{
"path": "RSColorPickerTests/CPTestCaseTests.m",
"chars": 585,
"preview": "//\n// CPTestCaseTests.m\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 3/13/14.\n//\n//\n\n#import <XCTest/XCTest.h>\n"
},
{
"path": "RSColorPickerTests/RSColorFunctionsTests.m",
"chars": 4921,
"preview": "//\n// RSColorFunctionsTests.m\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 3/16/14.\n//\n//\n\n#import <XCTest/XCTe"
},
{
"path": "RSColorPickerTests/RSColorPickerStateTests.m",
"chars": 3764,
"preview": "//\n// RSColorPickerStateTests.m\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 3/31/14.\n//\n//\n\n#import <XCTest/XC"
},
{
"path": "RSColorPickerTests/RSColorPickerTests-Info.plist",
"chars": 712,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "RSColorPickerTests/RSColorPickerTests-Prefix.pch",
"chars": 267,
"preview": "//\n// Prefix header\n//\n// The contents of this file are implicitly included at the beginning of every source file.\n//\n"
},
{
"path": "RSColorPickerTests/RSColorPickerViewDelegateTests.m",
"chars": 1945,
"preview": "//\n// RSColorPickerViewDelegateTests.m\n// RSColorPicker\n//\n// Created by Ryan Sullivan on 3/15/14.\n//\n//\n\n#import <XC"
},
{
"path": "RSColorPickerTests/RSColorPickerViewTests.m",
"chars": 8114,
"preview": "//\n// RSColorPickerTests.m\n// RSColorPickerTests\n//\n// Created by Ryan Sullivan on 3/13/14.\n//\n//\n\n#import <XCTest/XC"
},
{
"path": "RSColorPickerTests/en.lproj/InfoPlist.strings",
"chars": 45,
"preview": "/* Localized versions of Info.plist keys */\n\n"
}
]
About this extraction
This page contains the full source code of the RSully/RSColorPicker GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 67 files (190.4 KB), approximately 55.6k tokens, and a symbol index with 11 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.