libs-gui/Source/NSLevelIndicatorCell.m
Fred Kiefer 8ad4aa86c4 Replace some occurences of int with NSInteger
and unsigned with NSUInteger. This allows to recompile gui on 
64 bit systems after the change to NSNotFound in base.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@34312 72102866-910b-0410-8b05-ffd578937521
2011-12-17 17:16:09 +00:00

573 lines
16 KiB
Objective-C

/*
NSLevelIndicatorCell.m
The level indicator cell class
Copyright (C) 2007 Free Software Foundation, Inc.
Author: H. Nikolaus Schaller
Date: 2006
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.
*/
#import <Foundation/NSException.h>
#import "AppKit/NSBezierPath.h"
#import "AppKit/NSGraphics.h"
#import "AppKit/NSImage.h"
#import "AppKit/NSLevelIndicatorCell.h"
@implementation NSLevelIndicatorCell
- (id) init
{
return [self initWithLevelIndicatorStyle: NSRatingLevelIndicatorStyle];
}
- (id) initWithLevelIndicatorStyle: (NSLevelIndicatorStyle)style
{
self = [super init];
if (self)
{
[self setAlignment: NSCenterTextAlignment];
[self setLevelIndicatorStyle: style];
//_minValue = 0.0;
if ((style == NSContinuousCapacityLevelIndicatorStyle) ||
(style == NSRelevancyLevelIndicatorStyle))
{
_maxValue = 100.0;
}
else
{
_maxValue = 5.0;
}
[self setDoubleValue: 0.0];
}
return self;
}
- (id) copyWithZone:(NSZone *) zone
{
NSLevelIndicatorCell *c = [super copyWithZone: zone];
return c;
}
- (void) dealloc
{
[super dealloc];
}
- (NSLevelIndicatorStyle) style
{
return _style;
}
- (double) maxValue
{
return _maxValue;
}
- (void) setMaxValue: (double)val
{
_maxValue = val;
}
- (double) minValue
{
return _minValue;
}
- (void) setMinValue:(double) val
{
_minValue = val;
}
- (double) criticalValue
{
return _criticalValue;
}
- (void) setCriticalValue: (double)val
{
_criticalValue = val;
}
- (double) warningValue
{
return _warningValue;
}
- (void) setWarningValue: (double)val
{
_warningValue = val;
}
- (void) setLevelIndicatorStyle: (NSLevelIndicatorStyle)style
{
_style = style;
}
- (NSInteger) numberOfMajorTickMarks
{
return _numberOfMajorTickMarks;
}
- (void) setNumberOfMajorTickMarks: (NSInteger)count
{
_numberOfMajorTickMarks = count;
}
- (NSInteger) numberOfTickMarks
{
return _numberOfTickMarks;
}
- (void) setNumberOfTickMarks: (NSInteger)count
{
_numberOfTickMarks = count;
}
- (NSTickMarkPosition) tickMarkPosition
{
return _tickMarkPosition;
}
- (void) setTickMarkPosition: (NSTickMarkPosition)pos
{
_tickMarkPosition = pos;
}
- (double) tickMarkValueAtIndex: (NSInteger)index
{
if ((index < 0) || (index >= _numberOfTickMarks))
{
[NSException raise: NSRangeException
format: @"tick mark index invalid"];
}
return _minValue + index * (_maxValue - _minValue) / _numberOfTickMarks;
}
- (NSRect) rectOfTickMarkAtIndex: (NSInteger)index
{
NSRect cellRect = NSZeroRect;
float frameWidth = _cellFrame.size.width;
if ((index < 0) || (index >= _numberOfTickMarks))
{
[NSException raise: NSRangeException
format: @"tick mark index invalid"];
}
// Create default minor tickmark size in cellRect
cellRect.size.width = 1;
cellRect.size.height = 4;
// If all tick marks are major:
if (_numberOfTickMarks <= _numberOfMajorTickMarks)
{
// Use major tick mark size
cellRect.size.width = 3;
cellRect.size.height = 7;
}
// If major tick marks fit with even spacing
else if ((_numberOfTickMarks -1) % (_numberOfMajorTickMarks - 1) == 0)
{
NSInteger minorTicksPerMajor = (_numberOfTickMarks - 1) / (_numberOfMajorTickMarks - 1);
// If index is a major tick mark
if (index % minorTicksPerMajor == 0)
{
// Use major tick mark size
cellRect.size.width = 3;
cellRect.size.height = 7;
}
}
// FIXME: Extra tick mark code, when all major tick marks don't fit but a lesser amount will
// Last tick mark
if (index == (_numberOfTickMarks - 1))
{
cellRect.origin.x = (frameWidth - cellRect.size.width);
}
// Not the first tick mark. (First tick mark will use 0,0 default values already set)
else if (index != 0)
{
float spacing = (frameWidth / (_numberOfTickMarks - 1)) * index;
cellRect.origin.x = spacing - (cellRect.size.width / 2);
}
// Set origins if tick marks are above the indicator
if (_tickMarkPosition == NSTickMarkAbove)
{
switch (_style)
{
case NSContinuousCapacityLevelIndicatorStyle:
{
cellRect.origin.y = 16;
break;
}
case NSRelevancyLevelIndicatorStyle:
{
cellRect.origin.y = 12;
break;
}
case NSRatingLevelIndicatorStyle:
{
cellRect.origin.y = 13;
break;
}
case NSDiscreteCapacityLevelIndicatorStyle:
{
cellRect.origin.y = 18;
break;
}
}
}
// If tick mark is minor and below indicator, use y origin of 3. If not, default value of 0 is used
else if (cellRect.size.width == 1)
{
cellRect.origin.y = 3;
}
return NSIntegralRect(cellRect);
}
- (NSSize) cellSize
{
// Sizes are the same as those from OSX
NSSize cellSize = NSMakeSize(400000, 25);
// Change cellSize to the correct size:
switch (_style)
{
case NSContinuousCapacityLevelIndicatorStyle:
{
cellSize.height = 23;
break;
}
case NSRelevancyLevelIndicatorStyle:
{
cellSize.height = 19;
break;
}
case NSRatingLevelIndicatorStyle:
{
cellSize.height = 20;
cellSize.width = 13 * _maxValue;
break;
}
case NSDiscreteCapacityLevelIndicatorStyle:
{
cellSize.height = 25;
break;
}
}
return cellSize;
}
- (void) drawInteriorWithFrame: (NSRect)cellFrame inView: (NSView*)controlView
{
NSColor *fillColor;
double value = [self doubleValue];
double val = (value -_minValue) / (_maxValue -_minValue);
BOOL vertical = (cellFrame.size.height > cellFrame.size.width);
_cellFrame = cellFrame;
if (value < _warningValue)
fillColor = [NSColor greenColor];
else if (value < _criticalValue)
fillColor = [NSColor yellowColor];
else
fillColor = [NSColor redColor];
if (_numberOfTickMarks != 0)
{
// FIXME: this code only works for horizontal frames
float x;
float y0, y1;
float step = _numberOfTickMarks > 1 ?
(cellFrame.size.width - 1.0) / (_numberOfTickMarks - 1) :
1.0;
int tick;
if (_tickMarkPosition == NSTickMarkBelow)
{
cellFrame.origin.y += 8.0;
cellFrame.size.height -= 8.0;
y0 = 4.0;
y1 = 8.0;
}
else
{
cellFrame.size.height -= 8.0;
y0 = cellFrame.size.height;
y1 = y0 + 4.0;
}
[[NSColor darkGrayColor] set];
for(x = 0.0, tick = 0; tick <= _numberOfTickMarks; x += step, tick++)
{
[NSBezierPath strokeLineFromPoint: NSMakePoint(x, y0) toPoint: NSMakePoint(x, y1)];
// FIXME: draw _numberOfMajorTickMarks thick ticks (ignore if more than _numberOfTickMarks)
}
}
switch(_style)
{
case NSDiscreteCapacityLevelIndicatorStyle:
{
int segments = (int)(_maxValue - _minValue);
// width of one segment
float step = (segments > 0) ?
((vertical ? cellFrame.size.height : cellFrame.size.width) / segments) :
10.0;
int i;
int ifill = val * segments + 0.5;
for( i = 0; i < segments; i++)
{
// draw segments
NSRect seg = cellFrame;
if (vertical)
{
seg.size.height = step - 1.0;
seg.origin.y += i * step;
}
else
{
seg.size.width = step - 1.0;
seg.origin.x += i * step;
}
if (i < ifill)
[fillColor set];
else
// FIXME: Should not be needed.
[[NSColor controlBackgroundColor] set];
// we could also fill with a scaled horizontal/vertical image
NSRectFill(seg);
// draw border
[[NSColor lightGrayColor] set];
NSFrameRect(seg);
}
break;
}
case NSContinuousCapacityLevelIndicatorStyle:
{
NSRect ind, fill;
if (vertical)
NSDivideRect(cellFrame, &ind, &fill, cellFrame.size.height * val, NSMinYEdge);
else
NSDivideRect(cellFrame, &ind, &fill, cellFrame.size.width * val, NSMinXEdge);
[fillColor set];
// we could also fill with a scaled horizontal/vertical image
NSRectFill(ind);
// FIXME: Not needed
[[NSColor controlBackgroundColor] set];
NSRectFill(fill);
// draw border
[[NSColor lightGrayColor] set];
NSFrameRect(cellFrame);
break;
}
case NSRelevancyLevelIndicatorStyle:
{
// FIXME: Not needed
[[NSColor controlBackgroundColor] set];
NSRectFill(cellFrame);
[[NSColor darkGrayColor] set];
if (vertical)
{
float y;
float yfill = val * cellFrame.size.height + 0.5;
for (y = 0.0; y < yfill; y += 2.0)
{
[NSBezierPath strokeLineFromPoint: NSMakePoint(0.0, y)
toPoint: NSMakePoint(cellFrame.size.width, y)];
}
}
else
{
float x;
float xfill = val * cellFrame.size.width + 0.5;
for (x = 0.0; x < xfill; x += 2.0)
{
[NSBezierPath strokeLineFromPoint: NSMakePoint(x, 0.0)
toPoint: NSMakePoint(x, cellFrame.size.height)];
}
}
break;
}
case NSRatingLevelIndicatorStyle:
{
NSImage *indicator = [self image];
NSSize isize;
if (!indicator)
indicator = [NSImage imageNamed: @"NSRatingLevelIndicator"];
isize = [indicator size];
// FIXME: Not needed
[[NSColor controlBackgroundColor] set];
NSRectFill(cellFrame);
if (vertical)
{
int y;
for (y = 0.0; y < (val + 0.5); y++)
{
NSPoint pos = NSMakePoint(0, y * isize.height + 2.0);
if (pos.y >= cellFrame.size.height)
break;
// here we can strech the image as needed by using drawInRect:
[indicator drawAtPoint: pos
fromRect: (NSRect){NSZeroPoint, isize}
operation: NSCompositeCopy
fraction:1.0];
}
// FIXME: Should draw place holder for the rest of the cell frame
}
else
{
int x;
for (x = 0.0; x < (val + 0.5); x++)
{
NSPoint pos = NSMakePoint(x * isize.width + 2.0, 0.0);
if(pos.x >= cellFrame.size.width)
break;
[indicator drawAtPoint: pos
fromRect: (NSRect){NSZeroPoint, isize}
operation: NSCompositeCopy
fraction: 1.0];
}
// FIXME: Should draw place holder for the rest of the cell frame
}
}
}
}
- (void) encodeWithCoder: (NSCoder *) aCoder
{
[super encodeWithCoder:aCoder];
if ([aCoder allowsKeyedCoding])
{
[aCoder encodeDouble: _minValue forKey: @"NSMinValue"];
[aCoder encodeDouble: _maxValue forKey: @"NSMaxValue"];
[aCoder encodeDouble: _warningValue forKey: @"NSWarningValue"];
[aCoder encodeDouble: _criticalValue forKey: @"NSCriticalValue"];
[aCoder encodeDouble: [self doubleValue] forKey: @"NSValue"];
[aCoder encodeInt: _style forKey: @"NSIndicatorStyle"];
[aCoder encodeInt: _numberOfMajorTickMarks forKey: @"NSNumberOfMajorTickMarks"];
[aCoder encodeInt: _numberOfTickMarks forKey: @"NSNumberOfTickMarks"];
[aCoder encodeInt: _tickMarkPosition forKey: @"NSTickMarkPosition"];
}
else
{
[aCoder encodeValueOfObjCType: @encode(double) at: &_minValue];
[aCoder encodeValueOfObjCType: @encode(double) at: &_maxValue];
[aCoder encodeValueOfObjCType: @encode(double) at: &_warningValue];
[aCoder encodeValueOfObjCType: @encode(double) at: &_criticalValue];
[aCoder encodeValueOfObjCType: @encode(int) at: &_style];
[aCoder encodeValueOfObjCType: @encode(int) at: &_numberOfMajorTickMarks];
[aCoder encodeValueOfObjCType: @encode(int) at: &_numberOfTickMarks];
[aCoder encodeValueOfObjCType: @encode(int) at: &_tickMarkPosition];
}
}
- (id) initWithCoder:(NSCoder *) aDecoder
{
self = [super initWithCoder:aDecoder];
if ([aDecoder allowsKeyedCoding])
{
if ([aDecoder containsValueForKey: @"NSMinValue"])
{
_minValue = [aDecoder decodeDoubleForKey: @"NSMinValue"];
}
if ([aDecoder containsValueForKey: @"NSMaxValue"])
{
_maxValue = [aDecoder decodeDoubleForKey: @"NSMaxValue"];
}
if ([aDecoder containsValueForKey: @"NSWarningValue"])
{
_warningValue = [aDecoder decodeDoubleForKey: @"NSWarningValue"];
}
if ([aDecoder containsValueForKey: @"NSCriticalValue"])
{
_criticalValue = [aDecoder decodeDoubleForKey: @"NSCriticalValue"];
}
if ([aDecoder containsValueForKey: @"NSValue"])
{
[self setDoubleValue: [aDecoder decodeDoubleForKey: @"NSValue"]];
}
if ([aDecoder containsValueForKey: @"NSIndicatorStyle"])
{
_style = [aDecoder decodeIntForKey: @"NSIndicatorStyle"];
}
if ([aDecoder containsValueForKey: @"NSNumberOfMajorTickMarks"])
{
_numberOfMajorTickMarks = [aDecoder decodeIntForKey: @"NSNumberOfMajorTickMarks"];
}
if ([aDecoder containsValueForKey: @"NSNumberOfTickMarks"])
{
_numberOfTickMarks = [aDecoder decodeIntForKey: @"NSNumberOfTickMarks"];
}
if ([aDecoder containsValueForKey: @"NSTickMarkPosition"])
{
_tickMarkPosition = [aDecoder decodeIntForKey: @"NSTickMarkPosition"];
}
}
else
{
[aDecoder decodeValueOfObjCType: @encode(double) at: &_minValue];
[aDecoder decodeValueOfObjCType: @encode(double) at: &_maxValue];
[aDecoder decodeValueOfObjCType: @encode(double) at: &_warningValue];
[aDecoder decodeValueOfObjCType: @encode(double) at: &_criticalValue];
[aDecoder decodeValueOfObjCType: @encode(int) at: &_style];
[aDecoder decodeValueOfObjCType: @encode(int) at: &_numberOfMajorTickMarks];
[aDecoder decodeValueOfObjCType: @encode(int) at: &_numberOfTickMarks];
[aDecoder decodeValueOfObjCType: @encode(int) at: &_tickMarkPosition];
}
return self;
}
@end