![]() |
API 0.9.5
|
00001 /* 00002 * CPColorWell.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 00026 var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiveNotification"; 00027 00036 @implementation CPColorWell : CPControl 00037 { 00038 BOOL _active; 00039 BOOL _bordered; 00040 00041 CPColor _color; 00042 CPView _wellView; 00043 } 00044 00045 - (id)initWithFrame:(CGRect)aFrame 00046 { 00047 self = [super initWithFrame:aFrame]; 00048 00049 if (self) 00050 { 00051 _active = NO; 00052 _bordered = YES; 00053 _color = [CPColor whiteColor]; 00054 00055 [self drawBezelWithHighlight:NO]; 00056 [self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)]; 00057 00058 [self _registerForNotifications]; 00059 } 00060 00061 return self; 00062 } 00063 00064 - (void)_registerForNotifications 00065 { 00066 var defaultCenter = [CPNotificationCenter defaultCenter]; 00067 00068 [defaultCenter 00069 addObserver:self 00070 selector:@selector(colorWellDidBecomeExclusive:) 00071 name:_CPColorWellDidBecomeExclusiveNotification 00072 object:nil]; 00073 00074 [defaultCenter 00075 addObserver:self 00076 selector:@selector(colorPanelWillClose:) 00077 name:CPWindowWillCloseNotification 00078 object:[CPColorPanel sharedColorPanel]]; 00079 } 00080 00084 - (BOOL)isBordered 00085 { 00086 return _bordered; 00087 } 00088 00092 - (void)setBordered:(BOOL)bordered 00093 { 00094 if (_bordered == bordered) 00095 return; 00096 00097 _bordered = bordered; 00098 00099 [self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)]; 00100 } 00101 00102 // Managing Color From Color Wells 00103 00107 - (CPColor)color 00108 { 00109 return _color; 00110 } 00111 00115 - (void)setColor:(CPColor)aColor 00116 { 00117 if (_color == aColor) 00118 return; 00119 00120 _color = aColor; 00121 00122 [self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)]; 00123 } 00124 00129 - (void)takeColorFrom:(id)aSender 00130 { 00131 [self setColor:[aSender color]]; 00132 } 00133 00134 // Activating and Deactivating Color Wells 00140 - (void)activate:(BOOL)shouldBeExclusive 00141 { 00142 if (shouldBeExclusive) 00143 // FIXME: make this queue! 00144 [[CPNotificationCenter defaultCenter] 00145 postNotificationName:_CPColorWellDidBecomeExclusiveNotification 00146 object:self]; 00147 00148 00149 if ([self isActive]) 00150 return; 00151 00152 _active = YES; 00153 00154 [[CPNotificationCenter defaultCenter] 00155 addObserver:self 00156 selector:@selector(colorPanelDidChangeColor:) 00157 name:CPColorPanelColorDidChangeNotification 00158 object:[CPColorPanel sharedColorPanel]]; 00159 } 00160 00164 - (void)deactivate 00165 { 00166 if (![self isActive]) 00167 return; 00168 00169 _active = NO; 00170 00171 [[CPNotificationCenter defaultCenter] 00172 removeObserver:self 00173 name:CPColorPanelColorDidChangeNotification 00174 object:[CPColorPanel sharedColorPanel]]; 00175 } 00176 00180 - (BOOL)isActive 00181 { 00182 return _active; 00183 } 00184 00185 // Drawing a Color Well 00186 00187 - (void)drawBezelWithHighlight:(BOOL)shouldHighlight 00188 { 00189 } 00190 00195 - (void)drawWellInside:(CGRect)aRect 00196 { 00197 if (!_wellView) 00198 { 00199 _wellView = [[CPView alloc] initWithFrame:aRect]; 00200 [_wellView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; 00201 00202 [self addSubview:_wellView]; 00203 } 00204 else 00205 [_wellView setFrame:aRect]; 00206 00207 [_wellView setBackgroundColor:_color]; 00208 } 00209 00210 - (void)colorPanelDidChangeColor:(CPNotification)aNotification 00211 { 00212 [self takeColorFrom:[aNotification object]]; 00213 00214 [self sendAction:[self action] to:[self target]]; 00215 } 00216 00217 - (void)colorWellDidBecomeExclusive:(CPNotification)aNotification 00218 { 00219 if (self != [aNotification object]) 00220 [self deactivate]; 00221 } 00222 00223 - (void)colorPanelWillClose:(CPNotification)aNotification 00224 { 00225 [self deactivate]; 00226 } 00227 00228 - (void)mouseDown:(CPEvent)anEvent 00229 { 00230 if (![self isEnabled]) 00231 return; 00232 00233 [self drawBezelWithHighlight:YES]; 00234 } 00235 00236 - (void)mouseDragged:(CPEvent)anEvent 00237 { 00238 if (![self isEnabled]) 00239 return; 00240 00241 [self drawBezelWithHighlight:CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil])]; 00242 } 00243 00244 - (void)mouseUp:(CPEvent)anEvent 00245 { 00246 [self drawBezelWithHighlight:NO]; 00247 00248 if (!CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil]) || ![self isEnabled]) 00249 return; 00250 00251 [self activate:YES]; 00252 00253 var colorPanel = [CPColorPanel sharedColorPanel]; 00254 00255 [colorPanel setColor:_color]; 00256 [colorPanel orderFront:self]; 00257 } 00258 00259 @end 00260 00261 var CPColorWellColorKey = "CPColorWellColorKey", 00262 CPColorWellBorderedKey = "CPColorWellBorderedKey"; 00263 00264 @implementation CPColorWell (CPCoding) 00265 00270 - (id)initWithCoder:(CPCoder)aCoder 00271 { 00272 self = [super initWithCoder:aCoder]; 00273 00274 if (self) 00275 { 00276 _active = NO; 00277 _bordered = [aCoder decodeBoolForKey:CPColorWellBorderedKey]; 00278 _color = [aCoder decodeObjectForKey:CPColorWellColorKey]; 00279 00280 [self drawBezelWithHighlight:NO]; 00281 [self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)]; 00282 00283 [self _registerForNotifications]; 00284 } 00285 00286 return self; 00287 } 00288 00293 - (void)encodeWithCoder:(CPCoder)aCoder 00294 { 00295 // We do this in order to avoid encoding the _wellView, which 00296 // should just automatically be created programmatically as needed. 00297 var actualSubviews = _subviews; 00298 00299 _subviews = [_subviews copy]; 00300 [_subviews removeObjectIdenticalTo:_wellView]; 00301 00302 [super encodeWithCoder:aCoder]; 00303 00304 _subviews = actualSubviews; 00305 00306 [aCoder encodeObject:_color forKey:CPColorWellColorKey]; 00307 [aCoder encodeObject:_bordered forKey:CPColorWellBorderedKey]; 00308 } 00309 00310 @end