00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 @import "CPButton.j"
00024 @import "CPCookie.j"
00025 @import "CPPanel.j"
00026 @import "CPView.j"
00027
00028 CPColorPanelColorDidChangeNotification = @"CPColorPanelColorDidChangeNotification";
00029
00030 var PREVIEW_HEIGHT = 20.0,
00031 TOOLBAR_HEIGHT = 32.0,
00032 SWATCH_HEIGHT = 14.0,
00033 ICON_WIDTH = 32.0,
00034 ICON_PADDING = 12.0;
00035
00036 var SharedColorPanel = nil,
00037 ColorPickerClasses = [];
00038
00039
00040
00041
00042
00043
00044 CPWheelColorPickerMode = 1;
00045
00046
00047
00048
00049
00050 CPSliderColorPickerMode = 2;
00051
00052 CPColorPickerViewWidth = 265,
00053 CPColorPickerViewHeight = 370;
00054
00063 @implementation CPColorPanel : CPPanel
00064 {
00065 _CPColorPanelToolbar _toolbar;
00066 _CPColorPanelSwatches _swatchView;
00067 _CPColorPanelPreview _previewView;
00068
00069 CPSlider _opacitySlider;
00070
00071 CPArray _colorPickers;
00072 CPView _currentView;
00073 id _activePicker;
00074
00075 CPColor _color;
00076
00077 id _target;
00078 SEL _action;
00079
00080 int _mode;
00081 }
00082
00087 + (void)provideColorPickerClass:(Class)aColorPickerSubclass
00088 {
00089 ColorPickerClasses.push(aColorPickerSubclass);
00090 }
00091
00095 + (CPColorPanel)sharedColorPanel
00096 {
00097 if (!SharedColorPanel)
00098 SharedColorPanel = [[CPColorPanel alloc] init];
00099
00100 return SharedColorPanel;
00101 }
00102
00107 + (void)setPickerMode:(CPColorPanelMode)mode
00108 {
00109 var panel = [CPColorPanel sharedColorPanel];
00110 [panel setMode: mode];
00111 }
00112
00113
00114
00115
00116
00117 - (id)init
00118 {
00119 self = [super initWithContentRect:CGRectMake(500.0, 50.0, 219.0, 370.0)
00120 styleMask:(CPTitledWindowMask | CPClosableWindowMask | CPResizableWindowMask)];
00121
00122 if (self)
00123 {
00124 [[self contentView] setBackgroundColor:[CPColor colorWithWhite:0.95 alpha:1.0]];
00125
00126 [self setTitle:@"Color Panel"];
00127 [self setLevel:CPFloatingWindowLevel];
00128
00129 [self setFloatingPanel:YES];
00130 [self setBecomesKeyOnlyIfNeeded:YES];
00131
00132 [self setMinSize:CGSizeMake(219.0, 342.0)];
00133 [self setMaxSize:CGSizeMake(323.0, 537.0)];
00134 }
00135
00136 return self;
00137 }
00138
00142 - (void)setColor:(CPColor)aColor
00143 {
00144 _color = aColor;
00145 [_previewView setBackgroundColor: _color];
00146
00147 [CPApp sendAction:@selector(changeColor:) to:nil from:self];
00148
00149 if (_target && _action)
00150 [CPApp sendAction:_action to:_target from:self];
00151
00152 [[CPNotificationCenter defaultCenter]
00153 postNotificationName:CPColorPanelColorDidChangeNotification
00154 object:self];
00155
00156 [_activePicker setColor:_color];
00157 [_opacitySlider setFloatValue:[_color alphaComponent]];
00158 }
00159
00165 - (void)setColor:(CPColor)aColor updatePicker:(BOOL)bool
00166 {
00167 [self setColor:aColor];
00168
00169 if (bool)
00170 [_activePicker setColor:_color];
00171 }
00172
00176 - (CPColor)color
00177 {
00178 return _color;
00179 }
00180
00181 - (float)opacity
00182 {
00183 return [_opacitySlider floatValue];
00184 }
00185
00190 - (void)setTarget:(id)aTarget
00191 {
00192 _target = aTarget;
00193 }
00194
00199 - (id)target
00200 {
00201 return _target;
00202 }
00203
00209 - (void)setAction:(selector)anAction
00210 {
00211 _action = anAction;
00212 }
00213
00217 - (selector)action
00218 {
00219 return _action;
00220 }
00221
00226 - (void)setMode:(CPColorPanelMode)mode
00227 {
00228 _mode = mode;
00229 }
00230
00231 - (void)_setPicker:(id)sender
00232 {
00233 var picker = _colorPickers[[sender tag]],
00234 view = [picker provideNewView:NO];
00235
00236 if (!view)
00237 view = [picker provideNewView:YES];
00238
00239 if (view == _currentView)
00240 return;
00241
00242 if (_currentView)
00243 [view setFrame:[_currentView frame]];
00244 else
00245 {
00246 var height = (TOOLBAR_HEIGHT+10+PREVIEW_HEIGHT+5+SWATCH_HEIGHT+32),
00247 bounds = [[self contentView] bounds];
00248
00249 [view setFrameSize: CPSizeMake(bounds.size.width - 10, bounds.size.height - height)];
00250 [view setFrameOrigin: CPPointMake(5, height)];
00251 }
00252
00253 [_currentView removeFromSuperview];
00254 [[self contentView] addSubview:view];
00255
00256 _currentView = view;
00257 _activePicker = picker;
00258
00259 [picker setColor:[self color]];
00260 }
00261
00265 - (CPColorPanelMode)mode
00266 {
00267 return _mode;
00268 }
00269
00270 - (void)orderFront:(id)aSender
00271 {
00272 [self _loadContentsIfNecessary];
00273 [super orderFront:aSender];
00274 }
00275
00276
00277 - (void)_loadContentsIfNecessary
00278 {
00279 if (_toolbar)
00280 return;
00281
00282 if (!_color)
00283 _color = [CPColor whiteColor];
00284
00285 _colorPickers = [];
00286
00287 var count = [ColorPickerClasses count];
00288 for (var i=0; i<count; i++)
00289 {
00290 var currentPickerClass = ColorPickerClasses[i],
00291 currentPicker = [[currentPickerClass alloc] initWithPickerMask:0 colorPanel:self];
00292
00293 _colorPickers.push(currentPicker);
00294 }
00295
00296 var contentView = [self contentView],
00297 bounds = [contentView bounds];
00298
00299 _toolbar = [[CPView alloc] initWithFrame:CGRectMake(0, 6, CGRectGetWidth(bounds), TOOLBAR_HEIGHT)];
00300 [_toolbar setAutoresizingMask: CPViewWidthSizable];
00301
00302 var totalToolbarWidth = count * ICON_WIDTH + (count - 1) * ICON_PADDING,
00303 leftOffset = (CGRectGetWidth(bounds) - totalToolbarWidth) / 2.0,
00304 buttonForLater = nil;
00305
00306 for (var i=0; i<count; i++)
00307 {
00308 var image = [_colorPickers[i] provideNewButtonImage],
00309 highlightImage = [_colorPickers[i] provideNewAlternateButtonImage],
00310 button = [[CPButton alloc] initWithFrame:CGRectMake(leftOffset + i*(ICON_WIDTH+ICON_PADDING), 0, ICON_WIDTH, ICON_WIDTH)];
00311
00312 [button setTag:i];
00313 [button setTarget:self];
00314 [button setAction:@selector(_setPicker:)];
00315 [button setBordered:NO];
00316 [button setAutoresizingMask:CPViewMinXMargin|CPViewMaxXMargin];
00317
00318 [button setImage:image];
00319 [button setAlternateImage:highlightImage];
00320
00321 [_toolbar addSubview:button];
00322
00323 if (!buttonForLater)
00324 buttonForLater = button;
00325 }
00326
00327
00328 var previewBox = [[CPView alloc] initWithFrame:CGRectMake(76, TOOLBAR_HEIGHT + 10, CGRectGetWidth(bounds) - 86, PREVIEW_HEIGHT)];
00329
00330 _previewView = [[_CPColorPanelPreview alloc] initWithFrame:CGRectInset([previewBox bounds], 2.0, 2.0)];
00331
00332 [_previewView setColorPanel:self];
00333 [_previewView setAutoresizingMask:CPViewWidthSizable];
00334
00335 [previewBox setBackgroundColor:[CPColor colorWithWhite:0.8 alpha:1.0]];
00336 [previewBox setAutoresizingMask:CPViewWidthSizable];
00337
00338 [previewBox addSubview:_previewView];
00339
00340 var _previewLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + 10, 60, 15)];
00341 [_previewLabel setStringValue: "Preview:"];
00342 [_previewLabel setTextColor:[CPColor blackColor]];
00343 [_previewLabel setAlignment:CPRightTextAlignment];
00344
00345
00346 var swatchBox = [[CPView alloc] initWithFrame:CGRectMake(76, TOOLBAR_HEIGHT + 10 + PREVIEW_HEIGHT + 5, CGRectGetWidth(bounds) - 86, SWATCH_HEIGHT + 2.0)];
00347
00348 [swatchBox setBackgroundColor:[CPColor colorWithWhite:0.8 alpha:1.0]];
00349 [swatchBox setAutoresizingMask:CPViewWidthSizable];
00350
00351 _swatchView = [[_CPColorPanelSwatches alloc] initWithFrame:CGRectInset([swatchBox bounds], 1.0, 1.0)];
00352
00353 [_swatchView setColorPanel: self];
00354 [_swatchView setAutoresizingMask: CPViewWidthSizable];
00355
00356 [swatchBox addSubview:_swatchView];
00357
00358 var _swatchLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + 8 + PREVIEW_HEIGHT + 6, 60, 15)];
00359 [_swatchLabel setStringValue: "Swatches:"];
00360 [_swatchLabel setTextColor:[CPColor blackColor]];
00361 [_swatchLabel setAlignment:CPRightTextAlignment];
00362
00363
00364 var opacityLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + PREVIEW_HEIGHT + 35, 60, 20)];
00365 [opacityLabel setStringValue: "Opacity:"];
00366 [opacityLabel setTextColor:[CPColor blackColor]];
00367 [opacityLabel setAlignment:CPRightTextAlignment];
00368
00369 _opacitySlider = [[CPSlider alloc] initWithFrame:CGRectMake(76, TOOLBAR_HEIGHT + PREVIEW_HEIGHT + 34, CGRectGetWidth(bounds) - 86, 20.0)];
00370
00371 [_opacitySlider setMinValue:0.0];
00372 [_opacitySlider setMaxValue:1.0];
00373
00374 [_opacitySlider setTarget:self];
00375 [_opacitySlider setAction:@selector(setOpacity:)];
00376
00377 [contentView addSubview:_toolbar];
00378 [contentView addSubview:previewBox];
00379 [contentView addSubview:_previewLabel];
00380 [contentView addSubview:swatchBox];
00381 [contentView addSubview:_swatchLabel];
00382 [contentView addSubview:opacityLabel];
00383 [contentView addSubview:_opacitySlider];
00384
00385 _target = nil;
00386 _action = nil;
00387 _activePicker = nil;
00388
00389 [_previewView setBackgroundColor: _color];
00390
00391 if (buttonForLater)
00392 [self _setPicker:buttonForLater];
00393 }
00394
00395 - (void)setOpacity:(id)sender
00396 {
00397 var components = [[self color] components],
00398 alpha = [sender floatValue];
00399
00400 [self setColor:[_color colorWithAlphaComponent:alpha] updatePicker:YES];
00401 }
00402
00403 @end
00404
00405
00406 CPColorDragType = "CPColorDragType";
00407 var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
00408
00409
00410 @implementation _CPColorPanelSwatches : CPView
00411 {
00412 CPView[] _swatches;
00413 CPColor _dragColor;
00414 CPColorPanel _colorPanel;
00415 CPCookie _swatchCookie;
00416 }
00417
00418 -(id)initWithFrame:(CPRect)aFrame
00419 {
00420 self = [super initWithFrame:aFrame];
00421
00422 [self setBackgroundColor: [CPColor grayColor]];
00423
00424 [self registerForDraggedTypes:[CPArray arrayWithObjects:CPColorDragType]];
00425
00426 var whiteColor = [CPColor whiteColor];
00427
00428 _swatchCookie = [[CPCookie alloc] initWithName: CPColorPanelSwatchesCookie];
00429 var colorList = [self startingColorList];
00430
00431 _swatches = [];
00432
00433 for(var i=0; i < 50; i++)
00434 {
00435
00436 var view = [[CPView alloc] initWithFrame: CPRectMake(13*i+1, 1, 12, 12)],
00437 fillView = [[CPView alloc] initWithFrame:CGRectInset([view bounds], 1.0, 1.0)];
00438
00439 [view setBackgroundColor:whiteColor];
00440 [fillView setBackgroundColor: (i < colorList.length) ? colorList[i] : whiteColor];
00441
00442 [view addSubview:fillView];
00443
00444 [self addSubview: view];
00445
00446 _swatches.push(view);
00447 }
00448
00449 return self;
00450 }
00451
00452 - (BOOL)isOpaque
00453 {
00454 return YES;
00455 }
00456
00457 - (CPArray)startingColorList
00458 {
00459 var cookieValue = [_swatchCookie value];
00460 if(cookieValue == "")
00461 {
00462 return [
00463 [CPColor blackColor],
00464 [CPColor darkGrayColor],
00465 [CPColor grayColor],
00466 [CPColor lightGrayColor],
00467 [CPColor whiteColor],
00468 [CPColor redColor],
00469 [CPColor greenColor],
00470 [CPColor blueColor],
00471 [CPColor yellowColor]
00472 ];
00473 }
00474
00475 var cookieValue = eval(cookieValue);
00476 var result = [];
00477
00478 for(var i=0; i<cookieValue.length; i++)
00479 result.push([CPColor colorWithHexString: cookieValue[i]]);
00480
00481 return result;
00482 }
00483
00484 - (CPArray)saveColorList
00485 {
00486 var result = [];
00487
00488 for(var i=0; i<_swatches.length; i++)
00489 result.push([[[_swatches[i] subviews][0] backgroundColor] hexString]);
00490
00491 var future = new Date();
00492 future.setYear(2019);
00493
00494 [_swatchCookie setValue: CPJSObjectCreateJSON(result) expires:future domain: nil];
00495 }
00496
00497 - (void)setColorPanel:(CPColorPanel)panel
00498 {
00499 _colorPanel = panel;
00500 }
00501
00502 - (CPColorPanel)colorPanel
00503 {
00504 return _colorPanel;
00505 }
00506
00507 - (CPColor)colorAtIndex:(int)index
00508 {
00509 return [[_swatches[index] subviews][0] backgroundColor];
00510 }
00511
00512 - (void)setColor:(CPColor)aColor atIndex:(int)index
00513 {
00514
00515 [[_swatches[index] subviews][0] setBackgroundColor:aColor];
00516 [self saveColorList];
00517 }
00518
00519 - (void)mouseUp:(CPEvent)anEvent
00520 {
00521 var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
00522
00523 if(point.x > [self bounds].size.width - 1 || point.x < 1)
00524 return NO;
00525
00526 [_colorPanel setColor: [self colorAtIndex:FLOOR(point.x / 13)] updatePicker: YES];
00527 }
00528
00529 - (void)mouseDragged:(CPEvent)anEvent
00530 {
00531 var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
00532
00533 if(point.x > [self bounds].size.width - 1 || point.x < 1)
00534 return NO;
00535
00536 [[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:[CPArray arrayWithObject:CPColorDragType] owner:self];
00537
00538 var swatch = _swatches[FLOOR(point.x / 13)];
00539
00540
00541 _dragColor = [[swatch subviews][0] backgroundColor];
00542
00543 var bounds = CPRectCreateCopy([swatch bounds]);
00544
00545
00546 var dragView = [[CPView alloc] initWithFrame: bounds];
00547 dragFillView = [[CPView alloc] initWithFrame:CGRectInset(bounds, 1.0, 1.0)];
00548
00549 [dragView setBackgroundColor:[CPColor blackColor]];
00550 [dragFillView setBackgroundColor:_dragColor];
00551
00552 [dragView addSubview:dragFillView];
00553
00554 [self dragView: dragView
00555 at: CPPointMake(point.x - bounds.size.width / 2.0, point.y - bounds.size.height / 2.0)
00556 offset: CPPointMake(0.0, 0.0)
00557 event: anEvent
00558 pasteboard: nil
00559 source: self
00560 slideBack: YES];
00561 }
00562
00563 - (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
00564 {
00565 if(aType == CPColorDragType)
00566 [aPasteboard setData:_dragColor forType:aType];
00567 }
00568
00569 - (void)performDragOperation:(id <CPDraggingInfo>)aSender
00570 {
00571 var location = [self convertPoint:[aSender draggingLocation] fromView:nil],
00572 pasteboard = [aSender draggingPasteboard],
00573 swatch = nil;
00574
00575 if(![pasteboard availableTypeFromArray:[CPColorDragType]] || location.x > [self bounds].size.width - 1 || location.x < 1)
00576 return NO;
00577
00578 [self setColor:[pasteboard dataForType:CPColorDragType] atIndex: FLOOR(location.x / 13)];
00579 }
00580
00581 @end
00582
00583
00584 @implementation _CPColorPanelPreview : CPView
00585 {
00586 CPColorPanel _colorPanel;
00587 }
00588
00589 - (id)initWithFrame:(CPRect)aFrame
00590 {
00591 self = [super initWithFrame:aFrame];
00592
00593 [self registerForDraggedTypes:[CPArray arrayWithObjects:CPColorDragType]];
00594
00595 return self;
00596 }
00597
00598 - (void)setColorPanel:(CPColorPanel)aPanel
00599 {
00600 _colorPanel = aPanel;
00601 }
00602
00603 - (CPColorPanel)colorPanel
00604 {
00605 return _colorPanel;
00606 }
00607
00608 - (void)performDragOperation:(id <CPDraggingInfo>)aSender
00609 {
00610 var pasteboard = [aSender draggingPasteboard];
00611
00612 if(![pasteboard availableTypeFromArray:[CPColorDragType]])
00613 return NO;
00614
00615 var color = [pasteboard dataForType:CPColorDragType];
00616 [_colorPanel setColor: color updatePicker: YES];
00617 }
00618
00619 - (BOOL)isOpaque
00620 {
00621 return YES;
00622 }
00623
00624 - (void)mouseDragged:(CPEvent)anEvent
00625 {
00626 var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
00627
00628 [[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:[CPArray arrayWithObject:CPColorDragType] owner:self];
00629
00630 var bounds = CPRectMake(0, 0, 15, 15);
00631
00632
00633 var dragView = [[CPView alloc] initWithFrame: bounds];
00634 dragFillView = [[CPView alloc] initWithFrame:CGRectInset(bounds, 1.0, 1.0)];
00635
00636 [dragView setBackgroundColor:[CPColor blackColor]];
00637 [dragFillView setBackgroundColor:[self backgroundColor]];
00638
00639 [dragView addSubview:dragFillView];
00640
00641 [self dragView: dragView
00642 at: CPPointMake(point.x - bounds.size.width / 2.0, point.y - bounds.size.height / 2.0)
00643 offset: CPPointMake(0.0, 0.0)
00644 event: anEvent
00645 pasteboard: nil
00646 source: self
00647 slideBack: YES];
00648 }
00649
00650 - (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
00651 {
00652 if(aType == CPColorDragType)
00653 [aPasteboard setData:[self backgroundColor] forType:aType];
00654 }
00655
00656 @end
00657
00658 @import "CPColorPicker.j"
00659 @import "CPSliderColorPicker.j"
00660
00661 [CPColorPanel provideColorPickerClass:CPColorWheelColorPicker];
00662 [CPColorPanel provideColorPickerClass:CPSliderColorPicker];