跟踪时,自定义NSSliderCell旋钮不跟随鼠标

时间:2011-08-26 16:43:21

标签: cocoa macos

我实现了一个自定义NSSliderCell,它使用了一个非常不同的旋钮,大小比默认旋钮(这是一个交互式展览 - 我不能使用任何默认的Mac OS X控件)。

当滑块出现并且行为正确时(旋钮从一端到另一端等),当你仔细观察时会看到一种奇怪的行为:移动鼠标说,20像素,将导致旋钮移动30像素。这意味着在鼠标到达终点之前,旋钮可能会到达滑块的末端(并且滑块将具有最大值)。

这看起来非常奇怪,违背了所有期望。我想知道我需要改变什么以确保旋钮跟随鼠标并且不会移动得更快。

2 个答案:

答案 0 :(得分:3)

好的,一如既往,解决方案是最简单的。

以下是获得非常自定义滑块所需的最简单代码:

#import "CSSSliderCell.h"
#define KNOB_WIDTH 20
#define KNOB_HEIGHT 126
#define SLIDER_WIDTH 13

@implementation CSSSliderCell

- (void)drawKnob:(NSRect)rect
{
    // knobImage is an NSImage 
    [knobImage drawInRect:rect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];

}

- (void)drawBarInside:(NSRect)cellFrame flipped:(BOOL)flipped
{   
    NSRect slideRect = cellFrame;
    NSColor *backColor = [NSColor redColor];
    if ([(NSSlider*) [self controlView] isVertical] == YES)
    {
        slideRect.size.width = SLIDER_WIDTH;
        slideRect.origin.x += (cellFrame.size.width - SLIDER_WIDTH) * 0.5;
    } else {
        slideRect.size.height = SLIDER_WIDTH;
        slideRect.origin.y += (cellFrame.size.height - SLIDER_WIDTH) * 0.5;
    }

    NSBezierPath *bezierPath = [NSBezierPath bezierPathWithRoundedRect:slideRect xRadius:SLIDER_WIDTH * 0.5 yRadius:SLIDER_WIDTH * 0.5];  
    [backColor setFill];
    [bezierPath fill];

}


- (NSRect)knobRectFlipped:(BOOL)flipped{

    CGFloat value = ([self doubleValue]  - [self minValue])/ ([self maxValue] - [self minValue]);
    NSRect defaultRect = [super knobRectFlipped:flipped];
    NSRect myRect = NSMakeRect(0, 0, 0, 0);
    if ([(NSSlider*) [self controlView] isVertical] == YES)
    {
        myRect.size.width = KNOB_WIDTH;
        myRect.size.height = KNOB_HEIGHT;
        if (!flipped) {
            myRect.origin.y = value * ([[self controlView] frame].size.height - KNOB_HEIGHT);
        } else {
            myRect.origin.y = (1.0 - value) * ([[self controlView] frame].size.height - KNOB_HEIGHT);
        }
        myRect.origin.x = defaultRect.origin.x;

    } else {
        myRect.size.width = KNOB_HEIGHT;
        myRect.size.height = KNOB_WIDTH;
        myRect.origin.x = value * ([[self controlView] frame].size.width - KNOB_HEIGHT);
        myRect.origin.y = defaultRect.origin.y;

    }
    return myRect;
}
- (BOOL)_usesCustomTrackImage
{
    return YES;
}


@end

这可能有问题,但到目前为止,无论是水平还是垂直方向,它都能很好地运作。

答案 1 :(得分:1)

orestis,你的代码对我很有帮助。谢谢!

但是,旋钮的位置(myRect.origin)不正确。我修改了代码(并删除了硬编码的宏)。

- (NSRect)knobRectFlipped:(BOOL)flipped {
    float KNOB_WIDTH = [knobImage size].width;
    float KNOB_HEIGHT = [knobImage size].height;
    CGFloat value = ([self doubleValue]  - [self minValue])/ ([self maxValue] - [self minValue]);
    NSRect defaultRect = [super knobRectFlipped:flipped];
    NSRect myRect = NSMakeRect(0, 0, 0, 0);
    if ([(NSSlider*) [self controlView] isVertical] == YES)
    {
        //...   
    } else {
        myRect.size.width = KNOB_WIDTH;
        myRect.size.height = KNOB_HEIGHT;
        myRect.origin.x = value * ([[self controlView] frame].size.width - KNOB_WIDTH);
        myRect.origin.y = defaultRect.origin.y + defaultRect.size.height/2.0 - myRect.size.height/2.0; // Fixed the position

    }
    return myRect;
};