Implement ticks for level indicator. Code by Christopher Elsmore

<elsmorian@gmail.com>.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@25378 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
fredkiefer 2007-08-03 17:19:26 +00:00
parent 8b5ef317f7
commit c463685ee7
4 changed files with 283 additions and 168 deletions

View file

@ -1,3 +1,11 @@
2007-08-03 Fred Kiefer <FredKiefer@gmx.de>
* Source/NSView.m (-displayIfNeededInRectIgnoringOpacity:):
Correct spelling in comment.
* Headers/AppKit/NSLevelIndicatorCell.h: Add ivar for cell frame.
* Source/NSLevelIndicator.m (-rectOfTickMarkAtIndex:, -cellSize): Implement.
Patch by Christopher Elsmore <elsmorian@gmail.com>.
2007-08-03 Fred Kiefer <FredKiefer@gmx.de> 2007-08-03 Fred Kiefer <FredKiefer@gmx.de>
* Headers/AppKit/NSDocumentController.h, * Headers/AppKit/NSDocumentController.h,

View file

@ -53,6 +53,7 @@ typedef enum _NSLevelIndicatorStyle
int _numberOfTickMarks; int _numberOfTickMarks;
NSLevelIndicatorStyle _style; NSLevelIndicatorStyle _style;
NSTickMarkPosition _tickMarkPosition; NSTickMarkPosition _tickMarkPosition;
NSRect _cellFrame;
} }
- (id)initWithLevelIndicatorStyle:(NSLevelIndicatorStyle)style; - (id)initWithLevelIndicatorStyle:(NSLevelIndicatorStyle)style;

View file

@ -50,28 +50,28 @@
[self setLevelIndicatorStyle: style]; [self setLevelIndicatorStyle: style];
//_minValue = 0.0; //_minValue = 0.0;
if ((style == NSContinuousCapacityLevelIndicatorStyle) || if ((style == NSContinuousCapacityLevelIndicatorStyle) ||
(style == NSRelevancyLevelIndicatorStyle)) (style == NSRelevancyLevelIndicatorStyle))
{ {
_maxValue = 100.0; _maxValue = 100.0;
} }
else else
{ {
_maxValue = 5.0; _maxValue = 5.0;
} }
[self setDoubleValue: 0.0]; [self setDoubleValue: 0.0];
} }
return self; return self;
} }
- (id) copyWithZone:(NSZone *) zone; - (id) copyWithZone:(NSZone *) zone
{ {
NSLevelIndicatorCell *c = [super copyWithZone: zone]; NSLevelIndicatorCell *c = [super copyWithZone: zone];
return c; return c;
} }
- (void) dealloc; - (void) dealloc
{ {
[super dealloc]; [super dealloc];
} }
@ -119,7 +119,7 @@
- (void) setWarningValue: (double)val - (void) setWarningValue: (double)val
{ {
_warningValue=val; _warningValue = val;
} }
- (void) setLevelIndicatorStyle: (NSLevelIndicatorStyle)style - (void) setLevelIndicatorStyle: (NSLevelIndicatorStyle)style
@ -159,31 +159,132 @@
- (double) tickMarkValueAtIndex: (int)index - (double) tickMarkValueAtIndex: (int)index
{ {
if ((index < 0) || (index > _numberOfTickMarks)) if ((index < 0) || (index >= _numberOfTickMarks))
{ {
[NSException raise: NSRangeException [NSException raise: NSRangeException
format: @"tick mark index invalid"]; format: @"tick mark index invalid"];
} }
return _minValue + index * (_maxValue - _minValue) / _numberOfTickMarks; return _minValue + index * (_maxValue - _minValue) / _numberOfTickMarks;
} }
- (NSRect) rectOfTickMarkAtIndex: (int)index; - (NSRect) rectOfTickMarkAtIndex: (int)index
{ {
if ((index < 0) || (index > _numberOfTickMarks)) NSRect cellRect = NSZeroRect;
float frameWidth = _cellFrame.size.width;
if ((index < 0) || (index >= _numberOfTickMarks))
{ {
[NSException raise: NSRangeException [NSException raise: NSRangeException
format: @"tick mark index invalid"]; format: @"tick mark index invalid"];
} }
// FIXME: Need to cache the cell frame for this // Create default minor tickmark size in cellRect
return NSZeroRect; 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)
{
int 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; - (NSSize) cellSize
{ {
// FIXME: sum up all widths and use default height for controlSize // Sizes are the same as those from OSX
return [super cellSize]; 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 - (void) drawInteriorWithFrame: (NSRect)cellFrame inView: (NSView*)controlView
@ -192,7 +293,8 @@
double value = [self doubleValue]; double value = [self doubleValue];
double val = (value -_minValue) / (_maxValue -_minValue); double val = (value -_minValue) / (_maxValue -_minValue);
BOOL vertical = (cellFrame.size.height > cellFrame.size.width); BOOL vertical = (cellFrame.size.height > cellFrame.size.width);
_cellFrame = cellFrame;
if (value < _warningValue) if (value < _warningValue)
fillColor = [NSColor greenColor]; fillColor = [NSColor greenColor];
else if (value < _criticalValue) else if (value < _criticalValue)
@ -205,175 +307,179 @@
// FIXME: this code only works for horizontal frames // FIXME: this code only works for horizontal frames
float x; float x;
float y0, y1; float y0, y1;
float step = _numberOfTickMarks > 1 ? (cellFrame.size.width - 1.0) / (_numberOfTickMarks - 1) : 1.0; float step = _numberOfTickMarks > 1 ?
(cellFrame.size.width - 1.0) / (_numberOfTickMarks - 1) :
1.0;
int tick; int tick;
if (_tickMarkPosition == NSTickMarkBelow) if (_tickMarkPosition == NSTickMarkBelow)
{ {
cellFrame.origin.y += 8.0; cellFrame.origin.y += 8.0;
cellFrame.size.height -= 8.0; cellFrame.size.height -= 8.0;
y0 = 4.0; y0 = 4.0;
y1 = 8.0; y1 = 8.0;
} }
else else
{ {
cellFrame.size.height -= 8.0; cellFrame.size.height -= 8.0;
y0 = cellFrame.size.height; y0 = cellFrame.size.height;
y1 = y0 + 4.0; y1 = y0 + 4.0;
} }
[[NSColor darkGrayColor] set]; [[NSColor darkGrayColor] set];
for(x = 0.0, tick = 0; tick <= _numberOfTickMarks; x += step, tick++) for(x = 0.0, tick = 0; tick <= _numberOfTickMarks; x += step, tick++)
{ {
[NSBezierPath strokeLineFromPoint: NSMakePoint(x, y0) toPoint: NSMakePoint(x, y1)]; [NSBezierPath strokeLineFromPoint: NSMakePoint(x, y0) toPoint: NSMakePoint(x, y1)];
// FIXME: draw _numberOfMajorTickMarks thick ticks (ignore if more than _numberOfTickMarks) // FIXME: draw _numberOfMajorTickMarks thick ticks (ignore if more than _numberOfTickMarks)
} }
} }
switch(_style) switch(_style)
{ {
case NSDiscreteCapacityLevelIndicatorStyle: case NSDiscreteCapacityLevelIndicatorStyle:
{ {
int segments = (int)(_maxValue - _minValue); int segments = (int)(_maxValue - _minValue);
// width of one segment // width of one segment
float step = (segments > 0) ? ((vertical ? cellFrame.size.height : cellFrame.size.width) / segments) : 10.0; float step = (segments > 0) ?
int i; ((vertical ? cellFrame.size.height : cellFrame.size.width) / segments) :
int ifill = val * segments + 0.5; 10.0;
int i;
int ifill = val * segments + 0.5;
for( i = 0; i < segments; i++) for( i = 0; i < segments; i++)
{ {
// draw segments // draw segments
NSRect seg = cellFrame; NSRect seg = cellFrame;
if (vertical) if (vertical)
{ {
seg.size.height = step - 1.0; seg.size.height = step - 1.0;
seg.origin.y += i * step; seg.origin.y += i * step;
} }
else else
{ {
seg.size.width = step - 1.0; seg.size.width = step - 1.0;
seg.origin.x += i * step; seg.origin.x += i * step;
} }
if (i < ifill) if (i < ifill)
[fillColor set]; [fillColor set];
else else
// FIXME: Should not be needed. // FIXME: Should not be needed.
[[NSColor controlBackgroundColor] set]; [[NSColor controlBackgroundColor] set];
// we could also fill with a scaled horizontal/vertical image // we could also fill with a scaled horizontal/vertical image
NSRectFill(seg); NSRectFill(seg);
// draw border // draw border
[[NSColor lightGrayColor] set]; [[NSColor lightGrayColor] set];
NSFrameRect(seg); NSFrameRect(seg);
} }
break; break;
} }
case NSContinuousCapacityLevelIndicatorStyle: case NSContinuousCapacityLevelIndicatorStyle:
{ {
NSRect ind, fill; NSRect ind, fill;
if (vertical) if (vertical)
NSDivideRect(cellFrame, &ind, &fill, cellFrame.size.height * val, NSMinYEdge); NSDivideRect(cellFrame, &ind, &fill, cellFrame.size.height * val, NSMinYEdge);
else else
NSDivideRect(cellFrame, &ind, &fill, cellFrame.size.width * val, NSMinXEdge); NSDivideRect(cellFrame, &ind, &fill, cellFrame.size.width * val, NSMinXEdge);
[fillColor set]; [fillColor set];
// we could also fill with a scaled horizontal/vertical image // we could also fill with a scaled horizontal/vertical image
NSRectFill(ind); NSRectFill(ind);
// FIXME: Not needed // FIXME: Not needed
[[NSColor controlBackgroundColor] set]; [[NSColor controlBackgroundColor] set];
NSRectFill(fill); NSRectFill(fill);
// draw border // draw border
[[NSColor lightGrayColor] set]; [[NSColor lightGrayColor] set];
NSFrameRect(cellFrame); NSFrameRect(cellFrame);
break; break;
} }
case NSRelevancyLevelIndicatorStyle: case NSRelevancyLevelIndicatorStyle:
{ {
// FIXME: Not needed // FIXME: Not needed
[[NSColor controlBackgroundColor] set]; [[NSColor controlBackgroundColor] set];
NSRectFill(cellFrame); NSRectFill(cellFrame);
[[NSColor darkGrayColor] set]; [[NSColor darkGrayColor] set];
if (vertical) if (vertical)
{ {
float y; float y;
float yfill = val * cellFrame.size.height + 0.5; float yfill = val * cellFrame.size.height + 0.5;
for (y = 0.0; y < yfill; y += 2.0) for (y = 0.0; y < yfill; y += 2.0)
{ {
[NSBezierPath strokeLineFromPoint: NSMakePoint(0.0, y) [NSBezierPath strokeLineFromPoint: NSMakePoint(0.0, y)
toPoint: NSMakePoint(cellFrame.size.width, y)]; toPoint: NSMakePoint(cellFrame.size.width, y)];
} }
} }
else else
{ {
float x; float x;
float xfill = val * cellFrame.size.width + 0.5; float xfill = val * cellFrame.size.width + 0.5;
for (x = 0.0; x < xfill; x += 2.0) for (x = 0.0; x < xfill; x += 2.0)
{ {
[NSBezierPath strokeLineFromPoint: NSMakePoint(x, 0.0) [NSBezierPath strokeLineFromPoint: NSMakePoint(x, 0.0)
toPoint: NSMakePoint(x, cellFrame.size.height)]; toPoint: NSMakePoint(x, cellFrame.size.height)];
} }
} }
break; break;
} }
case NSRatingLevelIndicatorStyle: case NSRatingLevelIndicatorStyle:
{ {
NSImage *indicator = [self image]; NSImage *indicator = [self image];
NSSize isize; NSSize isize;
if (!indicator) if (!indicator)
indicator = [NSImage imageNamed: @"NSRatingLevelIndicator"]; indicator = [NSImage imageNamed: @"NSRatingLevelIndicator"];
isize = [indicator size]; isize = [indicator size];
// FIXME: Not needed // FIXME: Not needed
[[NSColor controlBackgroundColor] set]; [[NSColor controlBackgroundColor] set];
NSRectFill(cellFrame); NSRectFill(cellFrame);
if (vertical) if (vertical)
{ {
int y; int y;
for (y = 0.0; y < (val + 0.5); y++) for (y = 0.0; y < (val + 0.5); y++)
{ {
NSPoint pos = NSMakePoint(0, y * isize.height + 2.0); NSPoint pos = NSMakePoint(0, y * isize.height + 2.0);
if (pos.y >= cellFrame.size.height) if (pos.y >= cellFrame.size.height)
break; break;
// here we can strech the image as needed by using drawInRect: // here we can strech the image as needed by using drawInRect:
[indicator drawAtPoint: pos [indicator drawAtPoint: pos
fromRect: (NSRect){NSZeroPoint, isize} fromRect: (NSRect){NSZeroPoint, isize}
operation: NSCompositeCopy operation: NSCompositeCopy
fraction:1.0]; fraction:1.0];
} }
// FIXME: Should draw place holder for the rest of the cell frame // FIXME: Should draw place holder for the rest of the cell frame
} }
else else
{ {
int x; int x;
for (x = 0.0; x < (val + 0.5); x++) for (x = 0.0; x < (val + 0.5); x++)
{ {
NSPoint pos = NSMakePoint(x * isize.width + 2.0, 0.0); NSPoint pos = NSMakePoint(x * isize.width + 2.0, 0.0);
if(pos.x >= cellFrame.size.width) if(pos.x >= cellFrame.size.width)
break; break;
[indicator drawAtPoint: pos [indicator drawAtPoint: pos
fromRect: (NSRect){NSZeroPoint, isize} fromRect: (NSRect){NSZeroPoint, isize}
operation: NSCompositeCopy operation: NSCompositeCopy
fraction: 1.0]; fraction: 1.0];
} }
// FIXME: Should draw place holder for the rest of the cell frame // FIXME: Should draw place holder for the rest of the cell frame
} }
} }
} }
} }
@ -414,40 +520,40 @@
{ {
if ([aDecoder containsValueForKey: @"NSMinValue"]) if ([aDecoder containsValueForKey: @"NSMinValue"])
{ {
_minValue = [aDecoder decodeDoubleForKey: @"NSMinValue"]; _minValue = [aDecoder decodeDoubleForKey: @"NSMinValue"];
} }
if ([aDecoder containsValueForKey: @"NSMaxValue"]) if ([aDecoder containsValueForKey: @"NSMaxValue"])
{ {
_maxValue = [aDecoder decodeDoubleForKey: @"NSMaxValue"]; _maxValue = [aDecoder decodeDoubleForKey: @"NSMaxValue"];
} }
if ([aDecoder containsValueForKey: @"NSWarningValue"]) if ([aDecoder containsValueForKey: @"NSWarningValue"])
{ {
_warningValue = [aDecoder decodeDoubleForKey: @"NSWarningValue"]; _warningValue = [aDecoder decodeDoubleForKey: @"NSWarningValue"];
} }
if ([aDecoder containsValueForKey: @"NSCriticalValue"]) if ([aDecoder containsValueForKey: @"NSCriticalValue"])
{ {
_criticalValue = [aDecoder decodeDoubleForKey: @"NSCriticalValue"]; _criticalValue = [aDecoder decodeDoubleForKey: @"NSCriticalValue"];
} }
if ([aDecoder containsValueForKey: @"NSValue"]) if ([aDecoder containsValueForKey: @"NSValue"])
{ {
[self setDoubleValue: [aDecoder decodeDoubleForKey: @"NSValue"]]; [self setDoubleValue: [aDecoder decodeDoubleForKey: @"NSValue"]];
} }
if ([aDecoder containsValueForKey: @"NSIndicatorStyle"]) if ([aDecoder containsValueForKey: @"NSIndicatorStyle"])
{ {
_style = [aDecoder decodeIntForKey: @"NSIndicatorStyle"]; _style = [aDecoder decodeIntForKey: @"NSIndicatorStyle"];
} }
if ([aDecoder containsValueForKey: @"NSNumberOfMajorTickMarks"]) if ([aDecoder containsValueForKey: @"NSNumberOfMajorTickMarks"])
{ {
_numberOfMajorTickMarks = [aDecoder decodeIntForKey: @"NSNumberOfMajorTickMarks"]; _numberOfMajorTickMarks = [aDecoder decodeIntForKey: @"NSNumberOfMajorTickMarks"];
} }
if ([aDecoder containsValueForKey: @"NSNumberOfTickMarks"]) if ([aDecoder containsValueForKey: @"NSNumberOfTickMarks"])
{ {
_numberOfTickMarks = [aDecoder decodeIntForKey: @"NSNumberOfTickMarks"]; _numberOfTickMarks = [aDecoder decodeIntForKey: @"NSNumberOfTickMarks"];
} }
if ([aDecoder containsValueForKey: @"NSTickMarkPosition"]) if ([aDecoder containsValueForKey: @"NSTickMarkPosition"])
{ {
_tickMarkPosition = [aDecoder decodeIntForKey: @"NSTickMarkPosition"]; _tickMarkPosition = [aDecoder decodeIntForKey: @"NSTickMarkPosition"];
} }
} }
else else
{ {

View file

@ -2254,8 +2254,8 @@ convert_rect_using_matrices(NSRect aRect, NSAffineTransform *matrix1,
/* /*
* If we still need display after displaying the invalid rectangle, * If we still need display after displaying the invalid rectangle,
* this means, some subviews still need to display. For opaque subviews * this means that some subviews still need to display. For opaque subviews
* there invalid rectangle may even overlap the original aRect. * their invalid rectangle may even overlap the original aRect.
* Display any subview that need display. * Display any subview that need display.
*/ */
if (_rFlags.needs_display == YES) if (_rFlags.needs_display == YES)