API  0.9.7
 All Classes Files Functions Variables Macros Groups Pages
CPSliderColorPicker.j
Go to the documentation of this file.
1 /*
2  * CPApplication.j
3  * AppKit
4  *
5  * Created by Ross Boucher.
6  * Copyright 2008, 280 North, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 
24 @global CPColorPickerViewWidth
25 @global CPColorPickerViewHeight
26 @global CPSliderColorPickerMode
27 
28 
29 /*
30  @ignore
31 */
32 @implementation CPSliderColorPicker : CPColorPicker
33 {
34  CPView _contentView;
35 
36  CPSlider _redSlider;
37  CPSlider _greenSlider;
38  CPSlider _blueSlider;
39  CPSlider _hueSlider;
40  CPSlider _saturationSlider;
41  CPSlider _brightnessSlider;
42 
43  CPTextField _rgbLabel;
44  CPTextField _hsbLabel;
45  CPTextField _redLabel;
46  CPTextField _greenLabel;
47  CPTextField _blueLabel;
48  CPTextField _hueLabel;
49  CPTextField _saturationLabel;
50  CPTextField _brightnessLabel;
51  CPTextField _hexLabel;
52  CPTextField _hexValue;
53 
54  CPTextField _redValue;
55  CPTextField _greenValue;
56  CPTextField _blueValue;
57  CPTextField _hueValue;
58  CPTextField _saturationValue;
59  CPTextField _brightnessValue;
60 }
61 
62 - (id)initWithPickerMask:(int)mask colorPanel:(CPColorPanel)owningColorPanel
63 {
64  return [super initWithPickerMask:mask colorPanel:owningColorPanel];
65 }
66 
67 - (id)initView
68 {
69  var aFrame = CGRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
70 
71  _contentView = [[CPView alloc] initWithFrame:aFrame];
72  [_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
73 
74  _rgbLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 10, 100, 20)];
75  [_rgbLabel setStringValue:"Red, Green, Blue"];
76  [_rgbLabel setTextColor:[CPColor blackColor]];
77 
78  _redLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 37, 15, 20)];
79  [_redLabel setStringValue:"R"];
80  [_redLabel setTextColor:[CPColor blackColor]];
81 
82  _redSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 35, aFrame.size.width - 70, 20)];
83  [_redSlider setMaxValue:1.0];
84  [_redSlider setMinValue:0.0];
85  [_redSlider setTarget:self];
86  [_redSlider setAction:@selector(sliderChanged:)];
87  [_redSlider setAutoresizingMask:CPViewWidthSizable];
88 
89  // red value input box
90  _redValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 30, 45, 28)];
91  [_redValue setAutoresizingMask:CPViewMinXMargin];
92  [_redValue setEditable:YES];
93  [_redValue setBezeled:YES];
94  [_redValue setDelegate:self];
95  [_contentView addSubview:_redValue];
96 
97  _greenLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 63, 15, 20)];
98  [_greenLabel setStringValue:"G"];
99  [_greenLabel setTextColor:[CPColor blackColor]];
100 
101  _greenSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 61, aFrame.size.width - 70, 20)];
102  [_greenSlider setMaxValue:1.0];
103  [_greenSlider setMinValue:0.0];
104  [_greenSlider setTarget:self];
105  [_greenSlider setAction:@selector(sliderChanged:)];
106  [_greenSlider setAutoresizingMask:CPViewWidthSizable];
107 
108  // green value input box
109  _greenValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 56, 45, 28)];
110  [_greenValue setAutoresizingMask:CPViewMinXMargin];
111  [_greenValue setEditable:YES];
112  [_greenValue setBezeled:YES];
113  [_greenValue setDelegate:self];
114  [_contentView addSubview:_greenValue];
115 
116  _blueLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 90, 15, 20)];
117  [_blueLabel setStringValue:"B"];
118  [_blueLabel setTextColor:[CPColor blackColor]];
119 
120  _blueSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 87, aFrame.size.width - 70, 20)];
121  [_blueSlider setMaxValue:1.0];
122  [_blueSlider setMinValue:0.0];
123  [_blueSlider setTarget:self];
124  [_blueSlider setAction:@selector(sliderChanged:)];
125  [_blueSlider setAutoresizingMask:CPViewWidthSizable];
126 
127  // blue value input box
128  _blueValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 82, 45, 28)];
129  [_blueValue setAutoresizingMask:CPViewMinXMargin];
130  [_blueValue setEditable:YES];
131  [_blueValue setBezeled:YES];
132  [_blueValue setDelegate:self];
133  [_contentView addSubview:_blueValue];
134 
135  _hsbLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 120, 190, 20)];
136  [_hsbLabel setStringValue:"Hue, Saturation, Brightness"];
137  [_hsbLabel setTextColor:[CPColor blackColor]];
138 
139  _hueLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 145, 15, 20)];
140  [_hueLabel setStringValue:"H"];
141  [_hueLabel setTextColor:[CPColor blackColor]];
142 
143  _hueSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 143, aFrame.size.width - 70, 20)];
144  [_hueSlider setMaxValue:0.999];
145  [_hueSlider setMinValue:0.0];
146  [_hueSlider setTarget:self];
147  [_hueSlider setAction:@selector(sliderChanged:)];
148  [_hueSlider setAutoresizingMask:CPViewWidthSizable];
149 
150  // hue value input box
151  _hueValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 138, 45, 28)];
152  [_hueValue setAutoresizingMask:CPViewMinXMargin];
153  [_hueValue setEditable:YES];
154  [_hueValue setBezeled:YES];
155  [_hueValue setDelegate:self];
156  [_contentView addSubview:_hueValue];
157 
158  _saturationLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 170, 15, 20)];
159  [_saturationLabel setStringValue:"S"];
160  [_saturationLabel setTextColor:[CPColor blackColor]];
161 
162  _saturationSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 168, aFrame.size.width - 70, 20)];
163  [_saturationSlider setMaxValue:1.0];
164  [_saturationSlider setMinValue:0.0];
165  [_saturationSlider setTarget:self];
166  [_saturationSlider setAction:@selector(sliderChanged:)];
167  [_saturationSlider setAutoresizingMask:CPViewWidthSizable];
168 
169  // saturation value input box
170  _saturationValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 164, 45, 28)];
171  [_saturationValue setAutoresizingMask:CPViewMinXMargin];
172  [_saturationValue setEditable:YES];
173  [_saturationValue setBezeled:YES];
174  [_saturationValue setDelegate:self];
175  [_contentView addSubview:_saturationValue];
176 
177  _brightnessLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 196, 15, 20)];
178  [_brightnessLabel setStringValue:"B"];
179  [_brightnessLabel setTextColor:[CPColor blackColor]];
180 
181  _brightnessSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 194, aFrame.size.width - 70, 20)];
182  [_brightnessSlider setMaxValue:1.0];
183  [_brightnessSlider setMinValue:0.0];
184  [_brightnessSlider setTarget:self];
185  [_brightnessSlider setAction:@selector(sliderChanged:)];
186  [_brightnessSlider setAutoresizingMask:CPViewWidthSizable];
187 
188  // brightness value input box
189  _brightnessValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 190, 45, 28)];
190  [_brightnessValue setAutoresizingMask:CPViewMinXMargin];
191  [_brightnessValue setEditable:YES];
192  [_brightnessValue setBezeled:YES];
193  [_brightnessValue setDelegate:self];
194  [_contentView addSubview:_brightnessValue];
195 
196  _hexLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 230, 30, 20)];
197  [_hexLabel setStringValue:"Hex"];
198  [_hexLabel setTextColor:[CPColor blackColor]];
199 
200  //hex input box
201  _hexValue = [[CPTextField alloc] initWithFrame:CGRectMake(32, 225, 80, 28)];
202  [_hexValue setEditable:YES];
203  [_hexValue setBezeled:YES];
204  [_hexValue setDelegate:self];
205  [_contentView addSubview:_hexValue];
206 
207  [_contentView addSubview:_rgbLabel];
208  [_contentView addSubview:_redLabel];
209  [_contentView addSubview:_greenLabel];
210  [_contentView addSubview:_blueLabel];
211  [_contentView addSubview:_redSlider];
212  [_contentView addSubview:_greenSlider];
213  [_contentView addSubview:_blueSlider];
214 
215  [_contentView addSubview:_hsbLabel];
216  [_contentView addSubview:_hueLabel];
217  [_contentView addSubview:_saturationLabel];
218  [_contentView addSubview:_brightnessLabel];
219  [_contentView addSubview:_hueSlider];
220  [_contentView addSubview:_saturationSlider];
221  [_contentView addSubview:_brightnessSlider];
222 
223  [_contentView addSubview:_hexLabel];
224 }
225 
226 - (CPView)provideNewView:(BOOL)initialRequest
227 {
228  if (initialRequest)
229  [self initView];
230 
231  return _contentView;
232 }
233 
234 - (int)currentMode
235 {
236  return CPSliderColorPickerMode;
237 }
238 
239 - (BOOL)supportsMode:(int)mode
240 {
241  return (mode == CPSliderColorPickerMode) ? YES : NO;
242 }
243 
244 - (void)sliderChanged:(id)sender
245 {
246  var newColor,
247  colorPanel = [self colorPanel],
248  alpha = [colorPanel opacity];
249 
250  switch (sender)
251  {
252  case _hueSlider:
253  case _saturationSlider:
254  case _brightnessSlider: newColor = [CPColor colorWithHue:[_hueSlider floatValue]
255  saturation:[_saturationSlider floatValue]
256  brightness:[_brightnessSlider floatValue]
257  alpha:alpha];
258 
259  [self updateRGBSliders:newColor];
260  break;
261 
262  case _redSlider:
263  case _greenSlider:
264  case _blueSlider: newColor = [CPColor colorWithCalibratedRed:[_redSlider floatValue]
265  green:[_greenSlider floatValue]
266  blue:[_blueSlider floatValue]
267  alpha:alpha];
268 
269  [self updateHSBSliders:newColor];
270  break;
271  }
272 
273  [self updateLabels];
274  [self updateHex:newColor];
275  [colorPanel setColor:newColor];
276 }
277 
278 - (void)setColor:(CPColor)aColor
279 {
280  if (!aColor)
281  [CPException raise:CPInvalidArgumentException reason:"aColor can't be nil"];
282 
283  [self updateRGBSliders:aColor];
284  [self updateHSBSliders:aColor];
285  [self updateHex:aColor];
286  [self updateLabels];
287 }
288 
289 - (void)updateHSBSliders:(CPColor)aColor
290 {
291  var hsb = [aColor hsbComponents];
292 
293  [_hueSlider setFloatValue:hsb[0]];
294  [_saturationSlider setFloatValue:hsb[1]];
295  [_brightnessSlider setFloatValue:hsb[2]];
296 }
297 
298 - (void)updateHex:(CPColor)aColor
299 {
300  [_hexValue setStringValue:[aColor hexString]];
301 }
302 
303 - (void)updateRGBSliders:(CPColor)aColor
304 {
305  var rgb = [aColor components];
306 
307  [_redSlider setFloatValue:rgb[0]];
308  [_greenSlider setFloatValue:rgb[1]];
309  [_blueSlider setFloatValue:rgb[2]];
310 }
311 
312 - (void)updateLabels
313 {
314  [_hueValue setStringValue:ROUND([_hueSlider floatValue] * 360.0)];
315  [_saturationValue setStringValue:ROUND([_saturationSlider floatValue] * 100.0)];
316  [_brightnessValue setStringValue:ROUND([_brightnessSlider floatValue] * 100.0)];
317 
318  [_redValue setStringValue:ROUND([_redSlider floatValue] * 255)];
319  [_greenValue setStringValue:ROUND([_greenSlider floatValue] * 255)];
320  [_blueValue setStringValue:ROUND([_blueSlider floatValue] * 255)];
321 }
322 
323 - (CPImage)provideNewButtonImage
324 {
325  return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:CPColorPicker] pathForResource:"slider_button.png"] size:CGSizeMake(32, 32)];
326 }
327 
328 - (CPImage)provideNewAlternateButtonImage
329 {
330  return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:CPColorPicker] pathForResource:"slider_button_h.png"] size:CGSizeMake(32, 32)];
331 }
332 
333 - (void)controlTextDidEndEditing:(CPNotification)aNotification
334 {
335  var field = [aNotification object],
336  value = [[field stringValue] stringByTrimmingWhitespace];
337 
338  if (field === _hexValue)
339  {
340  var newColor = [CPColor colorWithHexString:value];
341 
342  if (newColor)
343  {
344  [self setColor:newColor];
345  [[self colorPanel] setColor:newColor];
346  }
347  }
348  else
349  {
350  switch (field)
351  {
352  case _redValue: [_redSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
353  [self sliderChanged:_redSlider];
354  break;
355 
356  case _greenValue: [_greenSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
357  [self sliderChanged:_greenSlider];
358  break;
359 
360  case _blueValue: [_blueSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
361  [self sliderChanged:_blueSlider];
362  break;
363 
364  case _hueValue: [_hueSlider setFloatValue:MAX(MIN(ROUND(value), 360) / 360.0, 0)];
365  [self sliderChanged:_hueSlider];
366  break;
367 
368  case _saturationValue: [_saturationSlider setFloatValue:MAX(MIN(ROUND(value), 100) / 100.0, 0)];
369  [self sliderChanged:_saturationSlider];
370  break;
371 
372  case _brightnessValue: [_brightnessSlider setFloatValue:MAX(MIN(ROUND(value), 100) / 100.0, 0)];
373  [self sliderChanged:_brightnessSlider];
374  break;
375  }
376  }
377 }
378 
379 @end