Кастом круговой NSSlider - PullRequest
       2

Кастом круговой NSSlider

0 голосов
/ 04 января 2012

Я пытаюсь реализовать собственный круговой слайдер, который использует изображения для рисования циферблата и ручки.Для этого я подклассифицировал NSSliderCell и переопределял методы drawBarInside и drawKnob.Теперь, если я оставлю тип ползунка по умолчанию (горизонтальный), будут вызваны мои функции рисования, и изображения будут нарисованы вместо панели и ручки по умолчанию (конечно, все выглядит неправильно, поскольку изображения сделаны для кругового ползунка, но онитам).Но как только я меняю тип ползунка на круговой (либо в IB, либо установив self.sliderType = NSCircularSlider; в моей ячейке ползунка), эти два метода никогда не вызываются, и мои изображения не рисуются (создается только стандартный циферблат).Я что-то здесь забыл или круговые ползунки вообще не могут быть настроены?

Вот мой код: DialSliderCell является подклассом NSSliderCell и инициируется и устанавливается в классе под названием DialSlider, которыйявляется подклассом NSSlider (этот класс больше ничего не делает в то время).

@implementation DialSliderCell

- (id)init {
    self = [super init];
    if (self) {
        dialImage = [NSImage imageNamed:@"dial"];
        knobImage = [NSImage imageNamed:@"dialKnob"];
        self.sliderType = NSCircularSlider;
    }
    NSLog(@"init");
    return self;
}

- (void)drawKnob:(NSRect)knobRect {
    knobRect.size = knobImage.size;
    [knobImage drawInRect:knobRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
    NSLog(@"drawKnob");
}

- (void)drawBarInside:(NSRect)aRect flipped:(BOOL)flipped {
    [dialImage drawInRect:aRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
    NSLog(@"drawBarInside");
}

@end

Ответы [ 2 ]

2 голосов
/ 13 января 2012

Я решил эту проблему, переопределив метод drawInteriorWithFrame.Решение основано на оригинальном методе.Я просто удалил все, что не связано с круговыми ползунками, удалил оригинальную графику и добавил свою собственную.Геометрия почти полностью оригинальная.

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

    NSPoint knobCenter;
    NSPoint point;
    float fraction, angle, radius;

    knobCenter = NSMakePoint(NSMidX(cellFrame), NSMidY(cellFrame));

    [dialImage drawInRect:cellFrame fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];

    int knobDiameter = knobImage.size.width;
    int knobRadius = knobDiameter / 2;
    fraction = ([self floatValue] - [self minValue]) / ([self maxValue] - [self minValue]);
    angle = (fraction * (2.0 * M_PI)) - (M_PI / 2.0);
    radius = (cellFrame.size.height / 2) - knobDiameter;
    point = NSMakePoint((radius * cos(angle)) + knobCenter.x,
                    (radius * sin(angle)) + knobCenter.y);

    NSRect dotRect;
    dotRect.origin.x = point.x - knobRadius;
    dotRect.origin.y = point.y - knobRadius;
    dotRect.size = knobImage.size;
    [knobImage drawInRect:dotRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
}

Размер прямоугольника cellFrame устанавливается равным размеру dialImage изображения.

Обратите внимание, что описанный выше метод некажется, вызывается автоматически, поэтому мне также пришлось переопределить метод drawWithFrame и заставить его вызывать drawInteriorWithFrame:

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
    [self drawInteriorWithFrame:cellFrame inView:controlView];
}
0 голосов
/ 04 января 2012

Все, что я могу думать, это то, что вы не переопределяете все назначенные инициализаторы

из документов ...

Назначенные инициализаторы. При создании подкласса NSCell вы должны реализовать все из назначенных инициализаторов. Эти методы: init, initWithCoder :, initTextCell: и initImageCell:.

Вероятно, один из трех других называется круговым ползунком.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...