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:As shown in the code I posted NSSlider's drawWithFrame sets
>
>> Override -drawWithFrame:inView.
>
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


