Customizing NSSliderCell

857 Views Asked by At

I want to customize NSSliderCell, but I'm getting strange glitch.

Here is what it should looks like (zoomed):

enter image description here

It draws ok, but when I'm drugging the knob, left bar starts look weird (looks like part of knob's shadow is left from previous frame):

enter image description here

Once I stop drugging the knob, slider becomes normal again.

Here is the code:

@implementation VolumeSliderCell

NSImage *knobImage = nil;
NSImage *leftBarLeftCapImage = nil;
NSImage *leftBarFillImage = nil;
NSImage *rightBarFillImage = nil;
NSImage *rightBarRightCapImage = nil;

- (id)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
    knobImage = [NSImage imageNamed:@"volume_knob.png"];
    leftBarLeftCapImage = [NSImage imageNamed:@"volume_leftbar_leftcap.png"];
    leftBarFillImage = [NSImage imageNamed:@"volume_leftbar_fill.png"];
    rightBarFillImage = [NSImage imageNamed:@"volume_rightbar_fill.png"];
    rightBarRightCapImage = [NSImage imageNamed:@"volume_rightbar_rightcap.png"];
}

return self;
}

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
//NSRect cellFrame = [self controlView].bounds;
//[[self controlView] setNeedsDisplayInRect:cellFrame];

[self drawBarInside:cellFrame flipped:[controlView isFlipped]];
[self drawKnob:cellFrame];
}

- (void)drawKnob:(NSRect)knobRect
{
[NSGraphicsContext saveGraphicsState];

CGRect bounds = [self controlView].bounds;
CGFloat value = ([self doubleValue]  - [self minValue])/ ([self maxValue] - [self minValue]);
CGRect rect = CGRectMake(value * (bounds.size.width - [knobImage size].width), (bounds.size.height - [knobImage size].height) / 2, [knobImage size].width, [knobImage size].height);

[knobImage drawInRect:CGRectIntegral(rect)];

[NSGraphicsContext restoreGraphicsState];
}

- (void)drawBarInside:(NSRect)aRect flipped:(BOOL)flipped
{
[NSGraphicsContext saveGraphicsState];

CGRect bounds = [self controlView].bounds;
CGFloat value = ([self doubleValue]  - [self minValue])/ ([self maxValue] - [self minValue]);
CGRect leftRect = CGRectMake([knobImage size].width / 2, (bounds.size.height - [leftBarFillImage size].height) / 2, value * (bounds.size.width - [knobImage size].width), [leftBarFillImage size].height);
CGRect rightRect = CGRectMake(leftRect.origin.x + leftRect.size.width, (bounds.size.height - [leftBarFillImage size].height) / 2, bounds.size.width - (leftRect.origin.x + leftRect.size.width + [knobImage size].width / 2), [leftBarFillImage size].height);

if (rightRect.size.width < 0)
{
    rightRect.size.width = 0;
}

NSDrawThreePartImage(CGRectIntegral(leftRect), leftBarLeftCapImage, leftBarFillImage, nil, NO, NSCompositeSourceOver, 1.0, YES);
NSDrawThreePartImage(CGRectIntegral(rightRect), nil, rightBarFillImage, rightBarRightCapImage, NO, NSCompositeSourceOver, 1.0, YES);

[NSGraphicsContext restoreGraphicsState];
}

What's wrong?

0

There are 0 best solutions below