1

In my project an NSSlider controls the volume of a AVPlayer. I'd like to colorize the portion of the NSSlider left of the knob. How can this be achieved?

murze
  • 4,015
  • 8
  • 43
  • 70
  • From what I remember this is kind of a pain, but you have to subclass nsslider and override drawRect: but you have to send the proper messages to the sliders knob cell to draw in the correct place... There may be an easier way, I will look at some examples tomorrow. – Grady Player Nov 20 '12 at 04:48

2 Answers2

1

You should use NSProgressIndicator for that.

As alternative, you can use a custom NSSliderCell and override - (BOOL)_usesCustomTrackImage to return YES and override - (void)drawBarInside:(NSRect)cellFrame flipped:(BOOL)flipped to draw your custom bar. There, you can use [NSCell doubleValue] to get the current position of the slider.

Yoav
  • 5,962
  • 5
  • 39
  • 61
0

You should subclass NSSliderCell and write something like this:

@interface CustomSliderCell : NSSliderCell {
    NSRect _barRect;
    NSRect _currentKnobRect;
}
//    You should set image for the barFill
//    (or not if you want to use the default background)
//    And image for the bar before the knob image
    @property (strong, nonatomic) NSImage *barFillImage;
    @property (strong, nonatomic) NSImage *barFillBeforeKnobImage;


//    Slider also has the ages so you should set
//    the different images for the left and the right one:
    @property (strong, nonatomic) NSImage *barLeftAgeImage;
    @property (strong, nonatomic) NSImage *barRightAgeImage;
@end

And implementation:

- (void)drawKnob:(NSRect)knobRect {
    [super drawKnob:knobRect];
    _currentKnobRect = knobRect;
}

-(void)drawBarInside:(NSRect)cellFrame flipped:(BOOL)flipped {
    _barRect = cellFrame; 
    NSRect beforeKnobRect = [self createBeforeKnobRect];
    NSRect afterKnobRect = [self createAfterKnobRect];

//    Draw bar before the knob
    NSDrawThreePartImage(beforeKnobRect, _barLeftAgeImage, _barFillBeforeKnobImage, _barFillBeforeKnobImage,
            NO, NSCompositeSourceOver, 1.0, flipped);

//    If you want to draw the default background 
//    add the following line at the at the beginning of the method:
//    [super drawBarInside:cellFrame flipped:flipped];
//    And comment the next line:
    NSDrawThreePartImage(afterKnobRect, _barFillImage, _barFillImage, _barRightAgeImage,
            NO, NSCompositeSourceOver, 1.0, flipped);
}

- (NSRect)createBeforeKnobRect {
    NSRect beforeKnobRect = _barRect;

    beforeKnobRect.size.width = _currentKnobRect.origin.x + _knobImage.size.width / 2;
    beforeKnobRect.size.height = _barFillBeforeKnobImage.size.height;
    beforeKnobRect.origin.y = beforeKnobRect.size.height / 2;

    return beforeKnobRect;
}

- (NSRect)createAfterKnobRect {
    NSRect afterKnobRect = _currentKnobRect;

    afterKnobRect.origin.x += _knobImage.size.width / 2;
    afterKnobRect.size.width = _barRect.size.width - afterKnobRect.origin.x;
    afterKnobRect.size.height = _barFillImage.size.height;
    afterKnobRect.origin.y = afterKnobRect.size.height / 2;

    return afterKnobRect;
}

I've created LADSLider which will help you to create what you want really simple and fast.

Doshipak
  • 211
  • 1
  • 2
  • 9