Question

I've sort of accomplised implementing a custom slider cell that can draw over using images for the scroll bar and knob. The only obstacle that is in the way now is this, when I drag the knob quickly, the images get messed up. I've posted a screen shot.

Screenshot

Here is the code:

#import "customSliderCell.h"
@implementation customSliderCell
- (void)drawKnob:(NSRect)knobRect {

    NSImage * knob = knobImage;
 [[self controlView] lockFocus];
 [knob
 compositeToPoint:NSMakePoint(knobRect.origin.x,knobRect.origin.y+knobRect.size.height)
 operation:NSCompositeSourceOver];

[[self controlView] unlockFocus];
}
- (void)drawBarInside:(NSRect)rect flipped:(BOOL)flipped {
rect.size.height = 8;

    NSRect leftRect = rect;
    leftRect.origin.x=0;
    leftRect.origin.y=2;
    leftRect.size.width = knobrect.origin.x + (knobrect.size.width);
    [leftBarImage setSize:leftRect.size];
    [leftBarImage drawInRect:leftRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction:1];

    NSRect rightRect = rect;
    rightRect.origin.x=0;
    rightRect.origin.y=2;
    rightRect.origin.x = knobrect.origin.x;
    [rightBarImage setSize:rightRect.size];
    [rightBarImage drawInRect:rightRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction:1];
}

ah i'm so close. any help regarding as to why this happens and how to solve it will be greatly appreciated, thanks!

Was it helpful?

Solution

Ok, so it's figured out. apparently the slider was trying to be smart and draw only where the knob has been. so apparently I have to invalidate the rect all the time by overriding setNeedsDisplayInRect in the slider class.

#import "customSlider.h"

@implementation customSlider
-(void)setNeedsDisplayInRect:(NSRect)invalidRect{
    [super setNeedsDisplayInRect:[self bounds]];
}
@end

OTHER TIPS

I am a beginner in Objective-c. I also ran into this problem! Here is the solution to find that I spent two days))) Save and restore GraphicsState:

[NSGraphicsContext restoreGraphicsState];
//...
[leftBarImage drawInRect:leftRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction:1];
//...
[rightBarImage drawInRect:rightRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction:1];
[NSGraphicsContext saveGraphicsState];

Sorry for bad English.

Remove all the -lockFocus and -unlockFocus messages. The framework will take care of setting up the drawing context for you before -drawBarInside:flipped: or -drawKnob: are ever sent.

Also, you shouldn't be creating any objects within a draw method.

Ha, it's another story. No, NSResponder is right and you should remove all 'lockFocus' stuff, however, this issue is a result of the default slider bar drawn by the NSSliderCell somewhere outside of the drawBarInside:flipped:flipped. I have faced this issue not so far ago as well.

Here is discussion and solution: http://www.cocoabuilder.com/archive/cocoa/177288-preventing-nsslider-bar-from-drawing.html , in short, you can override whole drawCell:inView: or use a "dirty hack trick" with overriding a private method. I personally don't like hacks, but in this case I did

- (BOOL)_usesCustomTrackImage {
return YES;
}

And it solved the problem for me

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top