API 0.9.5
AppKit/CPColorPicker.j
Go to the documentation of this file.
00001 /*
00002  * CPColorPicker.j
00003  * AppKit
00004  *
00005  * Created by Ross Boucher.
00006  * Copyright 2008, 280 North, Inc.
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00023 
00024 
00025 
00032 @implementation CPColorPicker : CPObject
00033 {
00034     CPColorPanel    _panel;
00035     int             _mask;
00036 }
00037 
00043 - (id)initWithPickerMask:(int)aMask colorPanel:(CPColorPanel)aPanel
00044 {
00045     self = [super init];
00046 
00047     _panel = aPanel;
00048     _mask  = aMask;
00049 
00050     return self;
00051 }
00052 
00056 - (CPColorPanel)colorPanel
00057 {
00058     return _panel;
00059 }
00060 
00061 /*
00062     FIXME Not implemented.
00063     @return \c nil
00064     @ignore
00065 */
00066 - (CPImage)provideNewButtonImage
00067 {
00068     return nil;
00069 }
00070 
00075 - (void)setMode:(CPColorPanelMode)mode
00076 {
00077     return;
00078 }
00079 
00084 - (void)setColor:(CPColor)aColor
00085 {
00086     return;
00087 }
00088 
00089 @end
00090 
00091 /*
00092     The wheel mode color picker.
00093     @ignore
00094 */
00095 @implementation CPColorWheelColorPicker : CPColorPicker
00096 {
00097     CPView          _pickerView;
00098     CPView          _brightnessSlider;
00099     __CPColorWheel  _hueSaturationView;
00100 
00101     CPColor         _cachedColor;
00102 }
00103 
00104 - (id)initWithPickerMask:(int)mask colorPanel:(CPColorPanel)owningColorPanel
00105 {
00106     return [super initWithPickerMask:mask colorPanel: owningColorPanel];
00107 }
00108 
00109 - (id)initView
00110 {
00111     aFrame = CPRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
00112 
00113     _pickerView = [[CPView alloc] initWithFrame:aFrame];
00114     [_pickerView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
00115 
00116     _brightnessSlider = [[CPSlider alloc] initWithFrame:CGRectMake(0, (aFrame.size.height - 34), aFrame.size.width, 15)];
00117 
00118     [_brightnessSlider setValue:15.0 forThemeAttribute:@"track-width"];
00119     [_brightnessSlider setValue:[CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPColorPicker class]] pathForResource:@"brightness_bar.png"]]] forThemeAttribute:@"track-color"];
00120 
00121     [_brightnessSlider setMinValue:0.0];
00122     [_brightnessSlider setMaxValue:100.0];
00123     [_brightnessSlider setFloatValue:100.0];
00124 
00125     [_brightnessSlider setTarget:self];
00126     [_brightnessSlider setAction:@selector(brightnessSliderDidChange:)];
00127     [_brightnessSlider setAutoresizingMask:CPViewWidthSizable | CPViewMinYMargin];
00128 
00129     _hueSaturationView = [[__CPColorWheel alloc] initWithFrame: CPRectMake(0, 0, aFrame.size.width, aFrame.size.height - 38)];
00130     [_hueSaturationView setDelegate: self];
00131     [_hueSaturationView setAutoresizingMask: (CPViewWidthSizable | CPViewHeightSizable)];
00132 
00133     [_pickerView addSubview:_hueSaturationView];
00134     [_pickerView addSubview:_brightnessSlider];
00135 }
00136 
00137 - (void)brightnessSliderDidChange:(id)sender
00138 {
00139     [self updateColor];
00140 }
00141 
00142 - (void)colorWheelDidChange:(id)sender
00143 {
00144     [self updateColor];
00145 }
00146 
00147 - (void)updateColor
00148 {
00149     var hue        = [_hueSaturationView angle],
00150         saturation = [_hueSaturationView distance],
00151         brightness = [_brightnessSlider floatValue];
00152 
00153     [_hueSaturationView setWheelBrightness:brightness / 100.0];
00154     [_brightnessSlider setBackgroundColor:[CPColor colorWithHue:hue saturation:saturation brightness:100]];
00155 
00156     var colorPanel = [self colorPanel],
00157         opacity = [colorPanel opacity];
00158 
00159     _cachedColor = [CPColor colorWithHue:hue saturation:saturation brightness:brightness alpha:opacity];
00160 
00161     [[self colorPanel] setColor:_cachedColor];
00162 }
00163 
00164 - (BOOL)supportsMode:(int)mode
00165 {
00166     return (mode == CPWheelColorPickerMode) ? YES : NO;
00167 }
00168 
00169 - (int)currentMode
00170 {
00171     return CPWheelColorPickerMode;
00172 }
00173 
00174 - (CPView)provideNewView:(BOOL)initialRequest
00175 {
00176     if (initialRequest)
00177         [self initView];
00178 
00179     return _pickerView;
00180 }
00181 
00182 - (void)setColor:(CPColor)newColor
00183 {
00184     if ([newColor isEqual:_cachedColor])
00185         return;
00186 
00187     var hsb = [newColor hsbComponents];
00188 
00189     [_hueSaturationView setPositionToColor:newColor];
00190     [_brightnessSlider setFloatValue:hsb[2]];
00191     [_hueSaturationView setWheelBrightness:hsb[2] / 100.0];
00192 
00193     [_brightnessSlider setBackgroundColor:[CPColor colorWithHue:hsb[0] saturation:hsb[1] brightness:100]];
00194 }
00195 
00196 - (CPImage)provideNewButtonImage
00197 {
00198     return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:CPColorPicker] pathForResource:"wheel_button.png"] size:CGSizeMake(32, 32)];
00199 }
00200 
00201 - (CPImage)provideNewAlternateButtonImage
00202 {
00203     return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:CPColorPicker] pathForResource:"wheel_button_h.png"] size:CGSizeMake(32, 32)];
00204 }
00205 
00206 @end
00207 
00208 /* @ignore */
00209 @implementation __CPColorWheel : CPView
00210 {
00211     DOMElement  _wheelImage;
00212     DOMElement  _blackWheelImage;
00213 
00214     CPView      _crosshair;
00215 
00216     id          _delegate;
00217 
00218     float       _angle;
00219     float       _distance;
00220 
00221     float       _radius;
00222 }
00223 
00224 - (id)initWithFrame:(CPRect)aFrame
00225 {
00226     self = [super initWithFrame:aFrame];
00227 
00228     var path = [[CPBundle bundleForClass:CPColorPicker] pathForResource:@"wheel.png"];
00229 
00230     _wheelImage = new Image();
00231     _wheelImage.src = path;
00232     _wheelImage.style.position = "absolute";
00233 
00234     path = [[CPBundle bundleForClass:CPColorPicker] pathForResource:@"wheel_black.png"];
00235 
00236     _blackWheelImage = new Image();
00237     _blackWheelImage.src = path;
00238     _blackWheelImage.style.opacity = "0";
00239     _blackWheelImage.style.filter = "alpha(opacity=0)"
00240     _blackWheelImage.style.position = "absolute";
00241 
00242 #if PLATFORM(DOM)
00243     _DOMElement.appendChild(_wheelImage);
00244     _DOMElement.appendChild(_blackWheelImage);
00245 #endif
00246 
00247     [self setWheelSize:aFrame.size];
00248 
00249     _crosshair = [[CPView alloc] initWithFrame:CPRectMake(_radius - 2, _radius - 2, 4, 4)];
00250     [_crosshair setBackgroundColor:[CPColor blackColor]];
00251 
00252     var view = [[CPView alloc] initWithFrame:CGRectInset([_crosshair bounds], 1.0, 1.0)];
00253     [view setBackgroundColor:[CPColor whiteColor]];
00254 
00255     [_crosshair addSubview:view];
00256 
00257     [self addSubview:_crosshair];
00258 
00259     return self;
00260 }
00261 
00262 - (void)setWheelBrightness:(float)brightness
00263 {
00264     _blackWheelImage.style.opacity = 1.0 - brightness;
00265     _blackWheelImage.style.filter = "alpha(opacity=" + (1.0 - brightness) * 100 + ")"
00266 }
00267 
00268 - (void)setFrameSize:(CPSize)aSize
00269 {
00270     [super setFrameSize:aSize];
00271     [self setWheelSize:aSize];
00272 }
00273 
00274 - (void)setWheelSize:(CPSize)aSize
00275 {
00276     var min = MIN(aSize.width, aSize.height);
00277 
00278     _blackWheelImage.style.width = min;
00279     _blackWheelImage.style.height = min;
00280     _blackWheelImage.width = min;
00281     _blackWheelImage.height = min;
00282     _blackWheelImage.style.top = (aSize.height - min) / 2.0 + "px";
00283     _blackWheelImage.style.left = (aSize.width - min) / 2.0 + "px";
00284 
00285     _wheelImage.style.width = min;
00286     _wheelImage.style.height = min;
00287     _wheelImage.width = min;
00288     _wheelImage.height = min;
00289     _wheelImage.style.top = (aSize.height - min) / 2.0 + "px";
00290     _wheelImage.style.left = (aSize.width - min) / 2.0 + "px";
00291 
00292     _radius = min / 2.0;
00293 
00294     [self setAngle:[self degreesToRadians:_angle] distance:(_distance / 100.0) * _radius];
00295 }
00296 
00297 - (void)setDelegate:(id)aDelegate
00298 {
00299     _delegate = aDelegate;
00300 }
00301 
00302 - (id)delegate
00303 {
00304     return _delegate;
00305 }
00306 
00307 - (float)angle
00308 {
00309     return _angle;
00310 }
00311 
00312 - (float)distance
00313 {
00314     return _distance;
00315 }
00316 
00317 - (void)mouseDown:(CPEvent)anEvent
00318 {
00319     [self reposition:anEvent];
00320 }
00321 
00322 - (void)mouseDragged:(CPEvent)anEvent
00323 {
00324     [self reposition:anEvent];
00325 }
00326 
00327 - (void)reposition:(CPEvent)anEvent
00328 {
00329     var bounds   = [self bounds],
00330         location = [self convertPoint:[anEvent locationInWindow] fromView:nil],
00331         midX     = CGRectGetMidX(bounds),
00332         midY     = CGRectGetMidY(bounds),
00333         distance = MIN(SQRT((location.x - midX) * (location.x - midX) + (location.y - midY) * (location.y - midY)), _radius),
00334         angle    = ATAN2(location.y - midY, location.x - midX);
00335 
00336     [self setAngle:angle distance:distance];
00337 
00338     [_delegate colorWheelDidChange:self];
00339 }
00340 
00341 - (void)setAngle:(int)angle distance:(float)distance
00342 {
00343     var bounds = [self bounds],
00344         midX   = CGRectGetMidX(bounds),
00345         midY   = CGRectGetMidY(bounds);
00346 
00347     _angle     = [self radiansToDegrees:angle];
00348     _distance  = (distance / _radius) * 100.0;
00349 
00350     [_crosshair setFrameOrigin:CPPointMake(COS(angle) * distance + midX - 2.0, SIN(angle) * distance + midY - 2.0)];
00351 }
00352 
00353 - (void)setPositionToColor:(CPColor)aColor
00354 {
00355     var hsb    = [aColor hsbComponents],
00356         bounds = [self bounds],
00357         angle    = [self degreesToRadians:hsb[0]],
00358         distance = (hsb[1] / 100.0) * _radius;
00359 
00360     [self setAngle:angle distance:distance];
00361 }
00362 
00363 - (int)radiansToDegrees:(float)radians
00364 {
00365     return ((-radians / PI) * 180 + 360) % 360;
00366 }
00367 
00368 - (float)degreesToRadians:(float)degrees
00369 {
00370     return -(((degrees - 360) / 180) * PI);
00371 }
00372 
00373 @end
00374 
 All Classes Files Functions Variables Defines