2013-12-20 3 views
1

Я хочу создать собственный класс для моего NSLevelIndicator, который просто округляет края. (Т.е. как кнопка округлой Rect) Я создал пользовательский класс, и я знаю, что я должен реализовать это в методеСделать NSLevelIndicator нарисовать округлые края

-(void)drawRect:(NSRect)dirtyRect; 

но у меня нет абсолютно никакой идеи, как реализовать это, и я надеюсь, что кто-то имеет идею это.

+1

«... Я знаю, что я должен реализовать это в методе [' drawRect: '] ...« Там есть морщина: NSLevelIndicator - это элемент управления, а не обычный вид, поэтому вам нужно работать хотя бы частично на уровне ячейки , Хорошая новость заключается в том, что вам может не потребоваться подкласс NSLevelIndicator; плохая новость, вам придется подклассифицировать NSLevelIndicatorCell вместо этого (если не дополнительно). –

ответ

1

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 ]; 
} 
+0

Спасибо, но не тот стиль, который я ищу. Похоже, что вокруг LevelIndicator нарисована только линия. Я пытаюсь изменить зеленый индикатор уровня – user3124229

0

Подкласс NSLevelIndicatorCell и перезаписать 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 

Вы можете просто установить клетки вашего NSLevelIndicator к вашему CustomLevelIndicatorCell, либо в InterfaceBuilder или в коде по setCell:

Надеюсь, это поможет!

Смежные вопросы