2011-01-26 2 views
4

사용자 지정 NSSliderCell을 사용하여 사용자 지정 NSSlider를 만듭니다. 손잡이가 아닌 모든 것이 아름답게 작동합니다. 최대 값으로 끌면 손잡이가 잘립니다. 손잡이 이미지의 50 % 만 볼 수 있습니다.NSSlider NSSliderCell 사용자 지정 노브 자르기

내 사용자 지정 NSSliderCell을 할당 할 때 knob.Hickness를 노브로 사용하고있는 이미지 너비로 설정합니다. 나는 그것을 (잘못된 것으로 생각한다) 그것이 그것을 고려하고 클리핑 (clipping)을 막을 것이라고 생각했다.

내가 잘못하고있는 아이디어가 있습니까? 손잡이가 50 %로 잘릴 때만 슬라이더가 maxValue를 치기 때문에 값을 추가하지 않고 이동하지 않습니다.

- (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 : 메서드에 의해서만 호출되며 뷰의 포커스가 잠겨있을 때 호출됩니다.

왜 손잡이 이미지가 -drawKnob에서 합성되는 Y 좌표에 20 점을 추가합니까?

+0

이 50 % 손잡이가 잘린 및 BTW 20.0 – mootymoots

+0

없이 줄을 중심으로하지립니다 -이 문제에 대한 답이었다 : 여기 내 솔루션입니다? 내가 언급 한 코드를 삭제했는데 아무런 차이가 없었습니다. – mootymoots

+1

-knobRectFlipped :를 재정의하고 슬라이더의 현재 값을 기반으로 노브 rect를 계산 한 다음 -drawKnob :에서 다른 조정을 수행하지 마십시오.내 제안 이유는 아마도 드로잉 컨텍스트가 -drawKnob :이 호출되기 바로 전에 knobRect에 클립되고 있다는 것입니다. 중간 값과 최대 값에서 슬라이더의 일부 스크린 샷을 볼 수 있습니까? –

0

잠시 시간이 흘렀음을 알고 있지만이 문제와 관련하여 신속하고 지저분한 해결 방법을 발견했습니다.

나는이 초기 원인을 해결할 수 없었지만 NSSlider가 2 차 핸들 이미지를 기대하고있는 것 같습니다. 내가 찾은 가장 쉬운 방법은 예를 들어 슬라이더의 범위를 0.0f - 110.0f로 설정하는 것이 었습니다.

그런 다음 값이 100.0f 이상이면 valueChanged target method를 체크 인하 고 그 값을 다시 해당 값으로 설정하십시오. 배경에 알파 - 픽셀 만있는 픽셀이있는 배경 이미지를 만들었으므로 배경이 실제 페이더 범위보다 넓지는 않습니다.

빠르고 지저분하지만 코드가 많이 필요하지 않고 잘 작동합니다. 다른 사람이 같은 문제를 우연히 만나는 데 도움이되기를 바랍니다.

2

NSSLider는 각 컨트롤 크기 노브 이미지 떨어져 특별한 크기를 예상 :

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

는 불행하게도 당신의 손잡이 이미지의 높이가이 매개 변수 중 하나를 초과 할 수 없습니다. 그러나 너비가 더 길 수도 있습니다. 이 경우이 같은 노브에 대한 x 위치를 계산 할 수 있습니다 _barRect가

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

에서 바 배경의 cellFrame : 나는 정의에 대한 간단한 솔루션을 만들었습니다

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

NSSlider. 이 링크를 따르십시오 https://github.com/Doshipak/LADSlider

1

[NSSliderCell drawKnob:] 외에 [NSSliderCell knobRectFlipped:]을 무시할 수 있습니다.

- (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; 
}