Files
cappuccino/AppKit/CPSliderColorPicker.j
T

384 lines
14 KiB
Plaintext

/*
* CPApplication.j
* AppKit
*
* Created by Ross Boucher.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPColorPicker.j"
@import "CPSlider.j"
@import "CPTextField.j"
@import "CPView.j"
@global CPColorPickerViewWidth
@global CPColorPickerViewHeight
@global CPSliderColorPickerMode
/*
@ignore
*/
@implementation CPSliderColorPicker : CPColorPicker
{
CPView _contentView;
CPSlider _redSlider;
CPSlider _greenSlider;
CPSlider _blueSlider;
CPSlider _hueSlider;
CPSlider _saturationSlider;
CPSlider _brightnessSlider;
CPTextField _rgbLabel;
CPTextField _hsbLabel;
CPTextField _redLabel;
CPTextField _greenLabel;
CPTextField _blueLabel;
CPTextField _hueLabel;
CPTextField _saturationLabel;
CPTextField _brightnessLabel;
CPTextField _hexLabel;
CPTextField _hexValue;
CPTextField _redValue;
CPTextField _greenValue;
CPTextField _blueValue;
CPTextField _hueValue;
CPTextField _saturationValue;
CPTextField _brightnessValue;
}
- (id)initWithPickerMask:(int)mask colorPanel:(CPColorPanel)owningColorPanel
{
return [super initWithPickerMask:mask colorPanel:owningColorPanel];
}
- (id)initView
{
var aFrame = CGRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
_contentView = [[CPView alloc] initWithFrame:aFrame];
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
_rgbLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 10, 100, 20)];
[_rgbLabel setStringValue:"Red, Green, Blue"];
[_rgbLabel setTextColor:[CPColor blackColor]];
_redLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 37, 15, 20)];
[_redLabel setStringValue:"R"];
[_redLabel setTextColor:[CPColor blackColor]];
_redSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 35, aFrame.size.width - 70, 20)];
[_redSlider setMaxValue:1.0];
[_redSlider setMinValue:0.0];
[_redSlider setTarget:self];
[_redSlider setAction:@selector(sliderChanged:)];
[_redSlider setAutoresizingMask:CPViewWidthSizable];
// red value input box
_redValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 30, 45, 28)];
[_redValue setAutoresizingMask:CPViewMinXMargin];
[_redValue setEditable:YES];
[_redValue setBezeled:YES];
[_redValue setDelegate:self];
[_contentView addSubview:_redValue];
_greenLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 63, 15, 20)];
[_greenLabel setStringValue:"G"];
[_greenLabel setTextColor:[CPColor blackColor]];
_greenSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 61, aFrame.size.width - 70, 20)];
[_greenSlider setMaxValue:1.0];
[_greenSlider setMinValue:0.0];
[_greenSlider setTarget:self];
[_greenSlider setAction:@selector(sliderChanged:)];
[_greenSlider setAutoresizingMask:CPViewWidthSizable];
// green value input box
_greenValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 56, 45, 28)];
[_greenValue setAutoresizingMask:CPViewMinXMargin];
[_greenValue setEditable:YES];
[_greenValue setBezeled:YES];
[_greenValue setDelegate:self];
[_contentView addSubview:_greenValue];
_blueLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 90, 15, 20)];
[_blueLabel setStringValue:"B"];
[_blueLabel setTextColor:[CPColor blackColor]];
_blueSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 87, aFrame.size.width - 70, 20)];
[_blueSlider setMaxValue:1.0];
[_blueSlider setMinValue:0.0];
[_blueSlider setTarget:self];
[_blueSlider setAction:@selector(sliderChanged:)];
[_blueSlider setAutoresizingMask:CPViewWidthSizable];
// blue value input box
_blueValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 82, 45, 28)];
[_blueValue setAutoresizingMask:CPViewMinXMargin];
[_blueValue setEditable:YES];
[_blueValue setBezeled:YES];
[_blueValue setDelegate:self];
[_contentView addSubview:_blueValue];
_hsbLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 120, 190, 20)];
[_hsbLabel setStringValue:"Hue, Saturation, Brightness"];
[_hsbLabel setTextColor:[CPColor blackColor]];
_hueLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 145, 15, 20)];
[_hueLabel setStringValue:"H"];
[_hueLabel setTextColor:[CPColor blackColor]];
_hueSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 143, aFrame.size.width - 70, 20)];
[_hueSlider setMaxValue:0.999];
[_hueSlider setMinValue:0.0];
[_hueSlider setTarget:self];
[_hueSlider setAction:@selector(sliderChanged:)];
[_hueSlider setAutoresizingMask:CPViewWidthSizable];
// hue value input box
_hueValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 138, 45, 28)];
[_hueValue setAutoresizingMask:CPViewMinXMargin];
[_hueValue setEditable:YES];
[_hueValue setBezeled:YES];
[_hueValue setDelegate:self];
[_contentView addSubview:_hueValue];
_saturationLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 170, 15, 20)];
[_saturationLabel setStringValue:"S"];
[_saturationLabel setTextColor:[CPColor blackColor]];
_saturationSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 168, aFrame.size.width - 70, 20)];
[_saturationSlider setMaxValue:1.0];
[_saturationSlider setMinValue:0.0];
[_saturationSlider setTarget:self];
[_saturationSlider setAction:@selector(sliderChanged:)];
[_saturationSlider setAutoresizingMask:CPViewWidthSizable];
// saturation value input box
_saturationValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 164, 45, 28)];
[_saturationValue setAutoresizingMask:CPViewMinXMargin];
[_saturationValue setEditable:YES];
[_saturationValue setBezeled:YES];
[_saturationValue setDelegate:self];
[_contentView addSubview:_saturationValue];
_brightnessLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 196, 15, 20)];
[_brightnessLabel setStringValue:"B"];
[_brightnessLabel setTextColor:[CPColor blackColor]];
_brightnessSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 194, aFrame.size.width - 70, 20)];
[_brightnessSlider setMaxValue:1.0];
[_brightnessSlider setMinValue:0.0];
[_brightnessSlider setTarget:self];
[_brightnessSlider setAction:@selector(sliderChanged:)];
[_brightnessSlider setAutoresizingMask:CPViewWidthSizable];
// brightness value input box
_brightnessValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 190, 45, 28)];
[_brightnessValue setAutoresizingMask:CPViewMinXMargin];
[_brightnessValue setEditable:YES];
[_brightnessValue setBezeled:YES];
[_brightnessValue setDelegate:self];
[_contentView addSubview:_brightnessValue];
_hexLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 230, 30, 20)];
[_hexLabel setStringValue:"Hex"];
[_hexLabel setTextColor:[CPColor blackColor]];
//hex input box
_hexValue = [[CPTextField alloc] initWithFrame:CGRectMake(32, 225, 80, 28)];
[_hexValue setEditable:YES];
[_hexValue setBezeled:YES];
[_hexValue setDelegate:self];
[_contentView addSubview:_hexValue];
[_contentView addSubview:_rgbLabel];
[_contentView addSubview:_redLabel];
[_contentView addSubview:_greenLabel];
[_contentView addSubview:_blueLabel];
[_contentView addSubview:_redSlider];
[_contentView addSubview:_greenSlider];
[_contentView addSubview:_blueSlider];
[_contentView addSubview:_hsbLabel];
[_contentView addSubview:_hueLabel];
[_contentView addSubview:_saturationLabel];
[_contentView addSubview:_brightnessLabel];
[_contentView addSubview:_hueSlider];
[_contentView addSubview:_saturationSlider];
[_contentView addSubview:_brightnessSlider];
[_contentView addSubview:_hexLabel];
}
- (CPView)provideNewView:(BOOL)initialRequest
{
if (initialRequest)
[self initView];
return _contentView;
}
- (int)currentMode
{
return CPSliderColorPickerMode;
}
- (BOOL)supportsMode:(int)mode
{
return (mode == CPSliderColorPickerMode) ? YES : NO;
}
- (void)sliderChanged:(id)sender
{
var newColor,
colorPanel = [self colorPanel],
alpha = [colorPanel opacity];
switch (sender)
{
case _hueSlider:
case _saturationSlider:
case _brightnessSlider: newColor = [CPColor colorWithHue:[_hueSlider floatValue]
saturation:[_saturationSlider floatValue]
brightness:[_brightnessSlider floatValue]
alpha:alpha];
[self updateRGBSliders:newColor];
break;
case _redSlider:
case _greenSlider:
case _blueSlider: newColor = [CPColor colorWithCalibratedRed:[_redSlider floatValue]
green:[_greenSlider floatValue]
blue:[_blueSlider floatValue]
alpha:alpha];
[self updateHSBSliders:newColor];
break;
}
[self updateLabels];
[self updateHex:newColor];
[colorPanel setColor:newColor];
}
- (void)setColor:(CPColor)aColor
{
if (!aColor)
[CPException raise:CPInvalidArgumentException reason:"aColor can't be nil"];
[self updateRGBSliders:aColor];
[self updateHSBSliders:aColor];
[self updateHex:aColor];
[self updateLabels];
}
- (void)updateHSBSliders:(CPColor)aColor
{
var hsb = [aColor hsbComponents];
[_hueSlider setFloatValue:hsb[0]];
[_saturationSlider setFloatValue:hsb[1]];
[_brightnessSlider setFloatValue:hsb[2]];
}
- (void)updateHex:(CPColor)aColor
{
[_hexValue setStringValue:[aColor hexString]];
}
- (void)updateRGBSliders:(CPColor)aColor
{
var rgb = [aColor components];
[_redSlider setFloatValue:rgb[0]];
[_greenSlider setFloatValue:rgb[1]];
[_blueSlider setFloatValue:rgb[2]];
}
- (void)updateLabels
{
[_hueValue setStringValue:ROUND([_hueSlider floatValue] * 360.0)];
[_saturationValue setStringValue:ROUND([_saturationSlider floatValue] * 100.0)];
[_brightnessValue setStringValue:ROUND([_brightnessSlider floatValue] * 100.0)];
[_redValue setStringValue:ROUND([_redSlider floatValue] * 255)];
[_greenValue setStringValue:ROUND([_greenSlider floatValue] * 255)];
[_blueValue setStringValue:ROUND([_blueSlider floatValue] * 255)];
}
- (CPImage)provideNewButtonImage
{
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:CPColorPicker] pathForResource:"slider_button.png"] size:CGSizeMake(32, 32)];
}
- (CPImage)provideNewAlternateButtonImage
{
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:CPColorPicker] pathForResource:"slider_button_h.png"] size:CGSizeMake(32, 32)];
}
- (void)controlTextDidEndEditing:(CPNotification)aNotification
{
var field = [aNotification object],
value = [[field stringValue] stringByTrimmingWhitespace];
if (field === _hexValue)
{
var newColor = [CPColor colorWithHexString:value];
if (newColor)
{
[self setColor:newColor];
[[self colorPanel] setColor:newColor];
}
}
else
{
switch (field)
{
case _redValue: [_redSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
[self sliderChanged:_redSlider];
break;
case _greenValue: [_greenSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
[self sliderChanged:_greenSlider];
break;
case _blueValue: [_blueSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
[self sliderChanged:_blueSlider];
break;
case _hueValue: [_hueSlider setFloatValue:MAX(MIN(ROUND(value), 360) / 360.0, 0)];
[self sliderChanged:_hueSlider];
break;
case _saturationValue: [_saturationSlider setFloatValue:MAX(MIN(ROUND(value), 100) / 100.0, 0)];
[self sliderChanged:_saturationSlider];
break;
case _brightnessValue: [_brightnessSlider setFloatValue:MAX(MIN(ROUND(value), 100) / 100.0, 0)];
[self sliderChanged:_brightnessSlider];
break;
}
}
}
@end