Preventing NSSlider bar from drawing

  • Thanks to all who helped me solve my IB/-initWithCoder: problem
    solved previously.

    So my custom NSSlider/NSSliderCell is drawing as I expect, except for
    one small quirk: I can't seem to prevent the original Aqua bar from
    drawing. Currently, I'm overriding -[NSSliderCell drawKnob:] and -
    [NSSliderCell drawBarInside:flipped:], and those correctly invoke my
    drawing commands. I'm still left with the original Aqua bar benath
    what I've drawn, however.

    If I override -[NSCell -drawWithFrame:inView:], I can prevent the bar
    from drawing, but the position at which the knob draws doesn't
    reflect the current doubleValue until I click the slider and begin
    using it. (It draws at 0,0 initially and doesn't get erased until I
    drag the knob over it.)

    My current thinking is that I need to override the -
    drawWithFrame:inView: method, lock focus on the control view, call -
    drawBarInside:flipped:, call -drawKnob: (not -drawKnob), and then
    unlock focus. If this is the case, is there a good way to determine
    what rect to pass into -drawKnob:?

    --
    mikey
  • Am 16.01.2007 um 17:24 Uhr schrieb Michael Watson:

    > I can't seem to prevent the original Aqua bar from drawing.

    Same here. I couldn't find a way that wouldn't require to essentially
    replace the entire control.

    Andreas
  • I hacked the apple slider using a category:

    - (void) drawWithFrame: (NSRect)cellFrame inView: (NSView*)controlView {
    cellFrame = [self drawingRectForBounds: cellFrame];

    [super setTrackRect: cellFrame]; //need to access private member

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

    ---

    /*
    Hack to set private member via category -> bad but only thing I can
    think of from keeping the sliderCell draw a bar behind ours which
    then shines through.
    */
    @interface NSSliderCell (SetTrackRect)
    @end

    @implementation NSSliderCell (SetTrackRect)

    - (void) setTrackRect: (NSRect)theRect {
    _trackRect = theRect;
    }

    @end
  • Andreas & Michael,

    In your NSSliderCell subclass, you have to override the private
    method  _usesCustomTrackImage to suppress the drawing of the slider's
    track.

    - (BOOL)_usesCustomTrackImage {
    return YES;
    }

    --Karl <karl...>

    On 16-Jan-07, at 3:01 PM, <cocoa-dev-request...> wrote:

    > Date: Tue, 16 Jan 2007 20:24:01 +0100
    > From: Andreas Mayer <andreas...>
    > Subject: Re: Preventing NSSlider bar from drawing
    > To: <cocoa-dev...>
    > Message-ID: <7CDB3B56-D249-4DB1-9940-58B7A9A2BE71...>
    > Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed
    >
    >
    > Am 16.01.2007 um 17:24 Uhr schrieb Michael Watson:
    >
    >> I can't seem to prevent the original Aqua bar from drawing.
    >
    > Same here. I couldn't find a way that wouldn't require to essentially
    > replace the entire control.
    >
    >
    > Andreas
  • Overriding private methods is unsound design. Ditto accessing private
    variables.

    Override -drawWithFrame:inView:, calculate where to draw the knob in
    the control, invoke -drawBarInside:flipped:, and then invoke -drawKnob:.

    That's what I've decided to do, and it looks like it should work.

    --
    mikey

    On 16 Jan, 2007, at 16:22, Karl Moskowski wrote:

    > Andreas & Michael,
    >
    > In your NSSliderCell subclass, you have to override the private
    > method  _usesCustomTrackImage to suppress the drawing of the
    > slider's track.
    >
    > - (BOOL)_usesCustomTrackImage {
    > return YES;
    > }
    >
    > --Karl <karl...>
    >
    >
    > On 16-Jan-07, at 3:01 PM, <cocoa-dev-request...> wrote:
    >
    >> Date: Tue, 16 Jan 2007 20:24:01 +0100
    >> From: Andreas Mayer <andreas...>
    >> Subject: Re: Preventing NSSlider bar from drawing
    >> To: <cocoa-dev...>
    >> Message-ID: <7CDB3B56-D249-4DB1-9940-58B7A9A2BE71...>
    >> Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed
    >>
    >>
    >> Am 16.01.2007 um 17:24 Uhr schrieb Michael Watson:
    >>
    >>> I can't seem to prevent the original Aqua bar from drawing.
    >>
    >> Same here. I couldn't find a way that wouldn't require to essentially
    >> replace the entire control.
    >>
    >>
    >> Andreas

  • Am 16.01.2007 um 22:22 Uhr schrieb Karl Moskowski:

    > In your NSSliderCell subclass, you have to override the private
    > method  _usesCustomTrackImage to suppress the drawing of the
    > slider's track.

    I'll try that, thanks!

    Am 16.01.2007 um 22:53 Uhr schrieb Michael Watson:

    > Overriding private methods is unsound design. Ditto accessing
    > private variables.

    Well, it seems that the slider is not using  -drawBarInside:flipped:,
    since overwriting it does not work as expected. So this is a bug and
    I have no problem working around it by using "unsound design". I'll
    just make sure that _usesCustomTrackImage is actually implemented
    before replacing it. And should it go away in the future, I would
    hope that NSSlider had been fixed ...

    Andreas
  • >> Overriding private methods is unsound design. Ditto accessing
    >> private variables.
    >
    > Well, it seems that the slider is not using  -
    > drawBarInside:flipped:, since overwriting it does not work as
    > expected. So this is a bug and I have no problem working around it
    > by using "unsound design". I'll just make sure that
    > _usesCustomTrackImage is actually implemented before replacing it.
    > And should it go away in the future, I would hope that NSSlider had
    > been fixed ...
    >

    There's nothing broken about NSSlider. -drawBarInside:flipped: is
    most certainly used, because I'm doing it in one of my control
    subclasses. I'm not sure what you're doing, but as I said in a
    previous e-mail, this works for me:

    - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
    {
    // calculate knob frame
    cellFrame = [self drawingRectForBounds:cellFrame];
    [self drawBarInside:cellFrame isFlipped:[controlView isFlipped]];
    [self drawKnob:yourKnobFrame];
    }

    - (void)drawKnob:(NSRect)knobRect
    {
    // draw your knob
    }

    - (void)drawBarInside:(NSRect)rect flipped:(BOOL)flipped
    {
    // draw your bar
    }

    Note that you may need to lock focus on your destination control view
    before drawing.

    --
    m-s
  • Am 17.01.2007 um 16:17 Uhr schrieb Michael Watson:

    > -drawBarInside:flipped: is most certainly used,

    It's used as in 'called'. But obviously the actual slider track is
    drawn some place else since overwriting -drawBarInside:flipped: does
    not prevent it (the default track) from being drawn. maybe I'm not
    understanding something, but that seems like a bug to me.

    Andreas
  • On 17 Jan, 2007, at 11:23, Andreas Mayer wrote:

    >
    > Am 17.01.2007 um 16:17 Uhr schrieb Michael Watson:
    >
    >> -drawBarInside:flipped: is most certainly used,
    >
    > It's used as in 'called'. But obviously the actual slider track is
    > drawn some place else since overwriting -drawBarInside:flipped:
    > does not prevent it (the default track) from being drawn. maybe I'm
    > not understanding something, but that seems like a bug to me.
    >

    No offense, but did you skip over the pseudoexample?

    Override -drawWithFrame:inView. Call -drawBarInside:isFlipped: and -
    drawKnob: manually. Reread the example. It works because Apple's
    private bar drawing isn't called if you don't call it yourself in -
    drawWithFrame:inView.

    --
    m-s
  • Am 17.01.2007 um 17:29 Uhr schrieb Michael Watson:

    > Override -drawWithFrame:inView.

    I don't want to. And I don't think I should need to either.

    > It works because Apple's private bar drawing isn't called if you
    > don't call it yourself in -drawWithFrame:inView.

    Yes, I know. But why isn't that call located inside -
    drawBarInside:isFlipped:, as I think it should?

    Andreas
  • On 17 Jan, 2007, at 12:12, Andreas Mayer wrote:

    > I don't want to. And I don't think I should need to either.

    Overriding private methods and accessing private variables is somehow
    better?

    --
    m-s
  • Am 17.01.2007 um 18:28 Uhr schrieb Michael Watson:

    > Overriding private methods and accessing private variables is
    > somehow better?

    Yes. YMMV.
  • > Am 17.01.2007 um 17:29 Uhr schrieb Michael Watson:
    >
    >> Override -drawWithFrame:inView.
    >
    As shown in the code I posted NSSlider's drawWithFrame sets
    trackRectangle. If that doesn't get updated with access private var,
    you get some issues with resizing..... at least I did get those.

    Regards,
    Dominik
previous month january 2007 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Go to today