File: NSSlider.m

package info (click to toggle)
gnustep-gui 0.25.0-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 13,088 kB
  • ctags: 3,417
  • sloc: objc: 153,800; ansic: 18,239; cpp: 579; yacc: 462; makefile: 143; sh: 5
file content (408 lines) | stat: -rw-r--r-- 9,902 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
/** <title>NSSlider</title>

   Copyright (C) 1996 Free Software Foundation, Inc.

   Author: Ovidiu Predescu <ovidiu@net-community.com>
   Date: September 1997
   Author: Felipe A. Rodriguez <far@ix.netcom.com>
   Date: August 1998

   This file is part of the GNUstep GUI Library.

   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 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; see the file COPYING.LIB.
   If not, see <http://www.gnu.org/licenses/> or write to the 
   Free Software Foundation, 51 Franklin Street, Fifth Floor, 
   Boston, MA 02110-1301, USA.
*/

#include "math.h" // fabs
#import <Foundation/NSString.h>

#import "AppKit/NSEvent.h"
#import "AppKit/NSSlider.h"
#import "AppKit/NSSliderCell.h"

/**
  <unit>
  <heading>Class Description</heading>
  
  <p>An NSSlider displays, and allows control of, some value in the
  application.  It represents a continuous stream of values of type
  <code>float</code>, which can be retrieved by the method
  <code>floatValue</code> and set by the method
  <code>setFloatValue:</code>.</p>

  <p>This control is a continuous control.  It sends its action
  message as long as the user is manipulating it.  This can be changed
  by passing <code>NO</code> to the <code>setContinuous:</code>
  message of a given NSSlider.</p>

  <p>Although methods for adding and managing a title are provided,
  the slider's knob can cover this title, so it is recommended that a
  label be added near the slider, for identification.</p>

  <p>As with many controls, NSSlider relies on its cell counterpart,
  NSSliderCell.  For more information, please see the specification
  for NSSliderCell.</p>

  <p>Use of an NSSlider to do the role of an NSScroller is not
  recommended.  A scroller is intended to represent the visible
  portion of a view, whereas a slider is intended to represent some
  value.</p>

  </unit>
*/
@implementation NSSlider

static Class cellClass;

+ (void) initialize
{
  if (self == [NSSlider class])
    {
      // Initial version
      [self setVersion: 1];

      // Set our cell class to NSSliderCell
      [self setCellClass: [NSSliderCell class]];
    }
}

+ (void) setCellClass: (Class)class
{
  cellClass = class;
}

+ (Class) cellClass
{
  return cellClass;
}

- (id) initWithFrame: (NSRect)frameRect
{
  self = [super initWithFrame: frameRect];
  if (self == nil)
    return nil;

  [_cell setState: 1];
  [_cell setContinuous: YES];
  return self;
}

- (BOOL) isFlipped
{
  return YES;
}

/**<p>Returns the value by which the slider will be incremented if the
  user holds down the ALT key.</p><p>See Also: -setAltIncrementValue:</p> */
- (double) altIncrementValue
{
  return [_cell altIncrementValue];
}

/**<p>  Returns the image drawn in the slider's track.  Returns
  <code>nil</code> if this has not been set. </p><p>See Also: -setImage:</p> */
- (NSImage *) image
{
  return [_cell image];
}

/**
  Returns whether or not the slider is vertical.  If, for some reason,
  this cannot be determined, for such reasons as the slider is not yet
  displayed, this method returns -1.  Generally, a slider is
  considered vertical if its height is greater than its width.  */
- (NSInteger) isVertical
{
  return [_cell isVertical];
}

/**
  Returns the thickness of the slider's knob.  This value is in
  pixels, and is the size of the knob along the slider's track.  */
- (CGFloat) knobThickness
{
  return [_cell knobThickness];
}

/**<p> Sets the value by which the slider will be incremented, when the
  ALT key is held down, to <var>increment</var>.</p>
  <p>See Also: -altIncrementValue</p>
*/
- (void) setAltIncrementValue: (double)increment
{
  [_cell setAltIncrementValue: increment];
}

/** <p>Sets the image to be displayed in the slider's track
    to <var>barImage</var>.</p><p>See Also: -image</p>
 */
- (void) setImage: (NSImage *)backgroundImage
{
  [_cell setImage: backgroundImage];
}

/**<p>Sets the thickness of the knob to <var>aFloat</var>, in pixels.
  This value sets the amount of space which the knob takes up in the
  slider's track.</p><p>See Also: -knobThickness</p> 
 */
- (void) setKnobThickness: (CGFloat)aFloat
{
  [_cell setKnobThickness: aFloat];
}

/** <p>Sets the title of the slider to <var>aString</var>.  
    This title is displayed  on the slider's track, behind the knob.</p>
    <p>See Also: -title</p>
*/
- (void) setTitle: (NSString *)aString
{
  [_cell setTitle: aString];
}

/** <p>Sets the cell used to draw the title to <var>aCell</var>.</p>
 <p>See Also: -titleCell</p>*/
- (void) setTitleCell: (NSCell *)aCell
{
  [_cell setTitleCell: aCell];
}

/** <p>Sets the colour with which the title will be drawn to
    <var>aColor</var>.</p><p>See Also -titleColor</p>
*/
- (void) setTitleColor: (NSColor *)aColor
{
  [_cell setTitleColor: aColor];
}

/** <p>Sets the font with which the title will be drawm to 
    <var>fontObject</var>.</p>
 <p>See Also: -titleFont</p>*/
- (void) setTitleFont: (NSFont *)fontObject
{
  [_cell setTitleFont: fontObject];
}

/** <p>Returns the title of the slider as an <code>NSString</code>.</p>
 <p>See Also: -setTitle:</p>*/
- (NSString *) title
{
  return [_cell title];
}

/** <p>Returns the cell used to draw the title.</p>
    <p>See Also: -setTitleCell:</p> 
*/
- (id) titleCell
{
  return [_cell titleCell];
}

/** <p>Returns the colour used to draw the title.</p>
 <p>See Also: -setTitleColor:</p>*/
- (NSColor *) titleColor
{
  return [_cell titleColor];
}

/**<p> Returns the font used to draw the title.</p>
   <p>See Also: -setTitleFont:</p> */
- (NSFont *) titleFont
{
  return [_cell titleFont];
}

/** <p>Returns the maximum value that the slider represents.</p>
 <p>See Also: -setMaxValue:</p>*/
- (double) maxValue
{
  return [_cell maxValue];
}

/** <p>Returns the minimum value that the slider represents.</p>
 <p>See Also: -setMinValue:</p>
*/
- (double) minValue
{
  return [_cell minValue];
}

/**<p> Sets the maximum value that the sliders represents to
   <var>aDouble</var>.</p><p>See Also: -maxValue</p>
*/
- (void) setMaxValue: (double)aDouble
{
  [_cell setMaxValue: aDouble];
}

/**<p> Sets the minimum value that the slider represents to
   <var>aDouble</var>. </p> <p>See Also: -minValue</p>*/
- (void) setMinValue: (double)aDouble
{
  [_cell setMinValue: aDouble];
}

/** 
  Returns <code>YES</code> by default.  This will allow the first
  click sent to the slider, when in an inactive window, to both bring
  the window into focus and manipulate the slider. */
- (BOOL) acceptsFirstMouse: (NSEvent *)theEvent
{
  return YES;
}

- (void) keyDown: (NSEvent *)ev
{
  NSString *characters = [ev characters];
  int i, length = [characters length];
  double value = [self doubleValue];
  double min = [_cell minValue];
  double max = [_cell maxValue];
  double altValue = [_cell altIncrementValue];
  NSUInteger alt_down = ([ev modifierFlags] & NSAlternateKeyMask);
  BOOL only_ticks = [_cell allowsTickMarkValuesOnly];
  BOOL valueChanged = NO;
  double diff;
  
  
  if (alt_down && altValue != -1)
    {
      diff = altValue;
    }
  else if (only_ticks)
    {
      if ([_cell numberOfTickMarks])
        {
  	  double tick0 = [_cell tickMarkValueAtIndex: 0];
	  double tick1 = [_cell tickMarkValueAtIndex: 1];
          diff = tick1 - tick0;
	}
      else
        {
	  diff = 0.0;
        }
    }
  else
    {
      diff = fabs(min - max) / 20;
    }
  
  for (i = 0; i < length; i++)
    {
      switch ([characters characterAtIndex: i])
        {
	   case NSLeftArrowFunctionKey:
	   case NSDownArrowFunctionKey:
		value -= diff;
		valueChanged = YES;
	     break;
	   case NSUpArrowFunctionKey:
	   case NSRightArrowFunctionKey:
	        value += diff;
		valueChanged = YES;
	     break;
	   case NSPageDownFunctionKey:
		value -= diff * 2;
		valueChanged = YES;
	     break;
	   case NSPageUpFunctionKey:
		value += diff * 2;
		valueChanged = YES;
	     break;
	   case NSHomeFunctionKey:
		value = min;
		valueChanged = YES;
	     break;
	   case NSEndFunctionKey:
		value = max;
		valueChanged = YES;
	     break;
        }
    }
  
  if (valueChanged)
    {
      if (only_ticks)
        value = [_cell closestTickMarkValueToValue: value];
      
      if (value < min)
	{ 
	  value = min;
	}
      else if (value > max)
	{
	  value = max;
	}
      
      [self setDoubleValue: value];
      [self sendAction: [self action] to: [self target]];
      return;
    }

  [super keyDown: ev];
}

// ticks
- (BOOL) allowsTickMarkValuesOnly
{
  return [_cell allowsTickMarkValuesOnly];
}

- (double) closestTickMarkValueToValue: (double)aValue
{
  return [_cell closestTickMarkValueToValue: aValue];
}

- (NSInteger) indexOfTickMarkAtPoint: (NSPoint)point
{
  return [_cell indexOfTickMarkAtPoint: point];
}

- (NSInteger) numberOfTickMarks
{
  return [_cell numberOfTickMarks];
}

- (NSRect) rectOfTickMarkAtIndex: (NSInteger)index
{
  return [_cell rectOfTickMarkAtIndex: index];
}

- (void) setAllowsTickMarkValuesOnly: (BOOL)flag
{
  [_cell setAllowsTickMarkValuesOnly: flag];
}

- (void) setNumberOfTickMarks: (NSInteger)numberOfTickMarks
{
 [_cell setNumberOfTickMarks: numberOfTickMarks];
}

- (void) setTickMarkPosition: (NSTickMarkPosition)position
{
 [_cell setTickMarkPosition: position];
}

- (NSTickMarkPosition) tickMarkPosition
{
  return [_cell tickMarkPosition];
}

- (double) tickMarkValueAtIndex: (NSInteger)index
{
  return [_cell tickMarkValueAtIndex: index];
}

@end