Question

I tried searching the internet for good tips to draw a custom Image with a different size for the knob of a NSSlider.

I hope we can gather the ideas this time in one place.

The problem most people get is that they want a different size knob, sometimes a bigger one which is not working unless you override sizetofit as far I could read.

I dont have a solution myself and searched for the same thing.

My problem (and the whole problem) is, I have a image for my knob which is 22x30px.

I have a subclassed NSSliderCell in which drawKnob: method is:

- (void)drawKnob:(NSRect)knobRect {

NSImage *image = [NSImage imageNamed:@"sliderImage"];

[[NSColor colorWithPatternImage:image] set];
NSRectFill(knobRect);
}

which is filling the old knob with my image. Then changed the RectFill to:

NSRectFill(NSMakeRect(knobRect.origin.x,knobRect.origin.y,25,35));

25/35 just to get some bigger values.

But the size isnt going to change the width (in my case its a vertical slider) and the image is not starting in a real corner. Its placed in the middle of the knob, a part of the left side is cut off, on the right side it gets doubeled.

When initializing the NSSlider the frame is big enough to fit the image in, but doesnt get displayed proberly.

I tried a sublass of NSSlider in which I used -(void)sizeToFit {} but I did not really know what to set in there.

I hope we can post here one sample Code of a NSSlider with custom knob image everyone can use and doesnt have to google for 2-3 hours.

I'm shure someone has done a Slider with a custom image

Thanks

Was it helpful?

Solution

In your NSSliderCell subclass, you also need to override knobRectFlipped:. Here's some code of mine, where mNormalKnob is an NSImage loaded into a member variable in initWithCoder:.

- (NSRect)knobRectFlipped:(BOOL)flipped
{
    NSSlider* theSlider = (NSSlider*) [self controlView];
    NSRect myBounds = [theSlider bounds];
    NSSize knobSize = [mNormalKnob size];
    float travelLength = myBounds.size.width - knobSize.width;
    double valueFrac = ([theSlider doubleValue] - [theSlider minValue]) /
        ([theSlider maxValue] - [theSlider minValue]);
    float knobLeft = roundf( valueFrac * travelLength );
    float knobMinY = roundf( myBounds.origin.y +
        0.5f * (myBounds.size.height - knobSize.height) );
    NSRect knobRect = NSMakeRect( knobLeft, knobMinY,
        knobSize.width, knobSize.height );
    return knobRect;
}

I guess I'm assuming that the height of the knob image is no more than the height of the view frame.

Here's another approach that ought to work without regard to the view frame height, though I haven't tried it. Designate the slider and its superview as having Core Animation layers. Make a CALayer as a member variable of your subclass, and set its content to your knob image. Then when it's time to draw the knob, just adjust the position of the knob layer.

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