![]() |
API 0.9.5
|
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