2011-01-26 8 views
4

Я создаю пользовательский NSSlider с пользовательским NSSliderCell. Все работает красиво, кроме ручки. Когда я перетаскиваю его до максимального значения, ручка обрезается, я могу видеть только 50% изображения ручки.NSSlider NSSliderCell clipping custom knob

При назначении моего пользовательского NSSliderCell я устанавливаю значение knobThickness для ширины изображения, которое я использую в качестве регулятора. Я предположил (я думаю, ошибочно), что это учитывает это и останавливает его от отсечения?

Любые идеи, что я делаю неправильно? Ползунок попадает в maxValue только тогда, когда ручка обрезается на 50%, поэтому он не перемещается без добавления какого-либо значения.

- (void)drawKnob:(NSRect)knobRect { 
NSImage * knob = _knobOff; 
knobRectVar = knobRect; 

[[self controlView] lockFocus]; 
[knob 
    compositeToPoint: 
    NSMakePoint(knobRect.origin.x+4,knobRect.origin.y+knobRect.size.height+20) 
    operation:NSCompositeSourceOver]; 
[[self controlView] unlockFocus]; 
} 

- (void)drawBarInside:(NSRect)rect flipped:(BOOL)flipped { 
rect.size.height = 8; 

[[self controlView] lockFocus]; 
NSImage *leftCurve = [NSImage imageNamed:@"customSliderLeft"]; 
[leftCurve drawInRect:NSMakeRect(5, 25, 8, 8) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1]; 

    NSRect leftRect = rect; 
    leftRect.origin.x=13; 
    leftRect.origin.y=25; 
    leftRect.size.width = knobRectVar.origin.x + (knobRectVar.size.width/2); 
    [leftBarImage setSize:leftRect.size]; 
    [leftBarImage drawInRect:leftRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction:1]; 
[[self controlView] unlockFocus]; 

} 

ответ

-2

Вам не нужно блокировать и разблокировать фокус на controlView из методов рисования внутри ячейки. Эти методы вызывают только ваш метод -drawRect: controlView, который вызывается с блокировкой фокуса вида.

Почему вы добавляете 20 пунктов к координате Y, изображение ручки составлено в -drawKnob?

+0

рисует ручку с 50% обрезаются и не по центру панели без +20.0 – mootymoots

+0

BTW - это был ответ на эту проблему? Я удалил код, который вы упомянули, и это не имело никакого значения. – mootymoots

+1

Я предлагаю вам попробовать переопределить -knobRectFlipped: и вычислить ручку rect на основе текущего значения ползунка, а затем не выполнять никаких других настроек в -drawKnob :.Моя причина в том, чтобы предположить, что, возможно, контекст чертежа привязывается к knobRect прямо перед вызовом -drawKnob:. Можно ли увидеть скриншоты слайдера при средних и максимальных значениях? –

0

Знайте, что прошло некоторое время, но я столкнулся с этим вопросом и обнаружил быстрое и грязное обходное решение.

Я не мог обойти первоначальную причину этого, но кажется, что NSSlider ожидает квадратичного изображения ручки. Самый простой способ найти диапазон вашего слайдера - от 0.0f до 110.0f, например.

Затем вы назначаете метод valueChanged target, если значение> 100.0f и возвращает его этому значению, если оно есть. Я создал фоновое изображение с некоторыми пикселями только альфа-пикселей с правой стороны, поэтому ваш фон не шире, чем фактический диапазон фейдера.

Быстро и грязно, но не требует много кода и работает очень хорошо. Надеюсь, что это поможет другим парням споткнуться на ту же проблему.

2

NSSLider ожидает специальных размеров от ручки на изображениях для каждого размера управления:

NSRegularControlSize: 21x21 
NSSmallControlSize:  15x15 
NSMiniControlSize:  12x12 

К сожалению, высота вашего регулятора изображения не должен превышать один из этих параметров. Но ширина может быть длиннее. Если вы можете посчитать й позицию для ручки, как это:

CGFloat newOriginX = knobRect.origin.x * 
     (_barRect.size.width - (_knobImage.size.width - knobRect.size.width))/_barRect.size.width; 

Где _barRect является cellFrame вашего бара фона из:

- (void)drawBarInside:(NSRect)cellFrame flipped:(BOOL)flipped; 

Я создал простое решение для обычая NSSlider. Следуйте по этой ссылке https://github.com/Doshipak/LADSlider

1

Вы можете переопределить [NSSliderCell knobRectFlipped:] в дополнение к [NSSliderCell drawKnob:]. Вот мое решение:

- (void)drawKnob:(NSRect)rect 
{ 
    NSImage *drawImage = [self knobImage]; 

    NSRect drawRect = [self knobRectFlipped:[self.controlView isFlipped]]; 

    CGFloat fraction = 1.0; 

    [drawImage drawInRect:drawRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:fraction respectFlipped:YES hints:nil]; 
} 

- (NSRect)knobRectFlipped:(BOOL)flipped 
{ 
    NSImage *drawImage = [self knobImage]; 

    NSRect drawRect = [super knobRectFlipped:flipped]; 

    drawRect.size = drawImage.size; 

    NSRect bounds = self.controlView.bounds; 
    bounds = NSInsetRect(bounds, ceil(drawRect.size.width/2), 0); 
    CGFloat val = MIN(self.maxValue, MAX(self.minValue, self.doubleValue)); 
    val = (val - self.minValue)/(self.maxValue - self.minValue); 
    CGFloat x = val * NSWidth(bounds) + NSMinX(bounds); 

    drawRect = NSOffsetRect(drawRect, x - NSMidX(drawRect) + 1, 0); 
    return drawRect; 
}