Question

I want to create a custom class for my NSLevelIndicator which just rounds up the edges. (i.e. like the rounded rect button) I created a custom class and I know I have to implement this in the

-(void)drawRect:(NSRect)dirtyRect;

method but I have absolutely no idea how to realise this and I hope someone has an idea for this.

No correct solution

OTHER TIPS

Output

@interface DILevelIndicatorCell : NSLevelIndicatorCell

@property ( readwrite, assign ) BOOL drawBezel;

@property ( readwrite, assign ) BOOL verticalCenter;

@end

- ( void )drawWithFrame:( NSRect ) rcCellFrame inView:( NSView* ) pControlView
{

    NSRect rcInterior = rcCellFrame;

    if( _drawBezel )
    {
        [ self _drawBezelWithFrame:rcCellFrame ];

        rcInterior = NSInsetRect( rcCellFrame, 3, 3 );
    }

    if( _verticalCenter )
    {
        CGFloat i = ( NSHeight( rcInterior ) - [ self cellSize ].height ) / 2;
        rcInterior.origin.y    += i;
        rcInterior.size.height -= i;
    }    

    [ super drawWithFrame:rcInterior inView:pControlView ];
}

- ( void )_drawBezelWithFrame:( NSRect ) dirtyRect
{

    CGFloat fRoundedRadius = 10.0f;

    NSGraphicsContext* ctx = [ NSGraphicsContext currentContext ];
    [ ctx saveGraphicsState ];
    {
        NSBezierPath* pPath    = [ NSBezierPath bezierPathWithRoundedRect:dirtyRect
                                                                  xRadius:fRoundedRadius
                                                                  yRadius:fRoundedRadius ];
        [ pPath setClip ];

        [ [ NSColor colorWithCalibratedRed:0.9 green:0.9 blue:0.95 alpha:1.0 ] setFill ];
        NSRectFillUsingOperation ( dirtyRect, NSCompositeSourceOver );

         [ [ NSColor colorWithCalibratedRed:0.7 green:0.7 blue:0.85 alpha:1.0 ] setFill ];
        [ pPath setLineWidth:1 ];
        [ pPath stroke ];
    }
    [ ctx restoreGraphicsState ];
}

Subclass NSLevelIndicatorCell and overwrite drawWithFrame:inView:

#import "CustomLevelIndicatorCell.h"

@implementation CustomLevelIndicatorCell

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {

    double level = (self.floatValue - self.minValue)/(self.maxValue- self.minValue);
    if (level > 1.0){level = 1.0;}
    NSLog(@"Level: %a", level);

    NSColor *fillColor;
    if(self.value < self.criticalValue)
        fillColor = [NSColor redColor];
    else if(self.value < self.warningValue)
        fillColor = [NSColor yellowColor];
    else
        fillColor = [NSColor greenColor];


    NSRect levelRect = NSInsetRect(cellFrame, 2, 1);
    levelRect.size.width = levelRect.size.width * level;
    NSBezierPath * levelPath = [NSBezierPath bezierPathWithRoundedRect:levelRect xRadius:3 yRadius:3];
    [fillColor setFill];
    [levelPath fill];
    NSBezierPath * indicatorPath = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(cellFrame, 2, 1) xRadius:3 yRadius:3];
    [indicatorPath setLineWidth:1];
    [[NSColor grayColor] setStroke];
    [indicatorPath stroke];

}

@end

You can then just set the cell of your NSLevelIndicator to your CustomLevelIndicatorCell, either in InterfaceBuilder or in code by setCell:

Hope this helps!

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