NSButtonCell 子类'按钮类型不起作用

发布于 2024-11-16 06:07:47 字数 2202 浏览 5 评论 0原文


我对 NSButtonCell 类进行了子类化,以使按钮具有不同的外观。我的绘图代码工作正常。它是一个充满 CGGradients 的圆形按钮,看起来像 iTunes 播放控件。它们并不完全相同,但对我来说足够相似。

现在我的问题是按钮类型。我在 -[PlayerButtonCell initImageCell:] 中设置了按钮类型,但我无法让它仅在按下按钮时绘制推入的外观。我向您展示我的一段代码:

//
//  PlayerButtonCell.m
//  DownTube
//

#import "PlayerButtonCell.h"

@implementation PlayerButtonCell
/* MARK: Init */
- (id)initImageCell:(NSImage *)image {
    self = [super initImageCell:image];
    if(self != nil) {
        [self setImage:image];
        [self setButtonType:NSMomentaryPushInButton];
    }
    return self;
}

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
    NSImage *myImage;
    NSBezierPath *myPath;
    NSRect myFrame;
    NSInteger myState;

    myFrame = NSInsetRect(cellFrame , STROKE_WIDTH / 2.0 , STROKE_WIDTH / 2.0);
    myImage = [self image];
    myState = [self state];

    NSLog(@"%d", [self buttonType]);

    /* Create bezier path */
    {
        myPath = [NSBezierPath bezierPathWithOvalInRect:myFrame];
    }

    /* Fill with background color */
    {
        /* Fill code here */
    }


    /* Draw gradient if on */
    if(myState == NSOffState) {
        /* Code to draw the button when it's not pushed in */

    } else {
        /* Code to draw the button when it IS pressed */
    }

    /* Stroke */
    {
        /* Code to stroke the bezier path's edge. */
    }
}
@end

如您所见,我通过 [NSButtonCell state] 方法检查推送的状态。但按钮单元的作用就像一个复选框,如NSSwitchButton中所示。这,我不愿意。我想让它瞬间发光。

希望有人能帮助我,
ief2

编辑: 我用这个代码创建了一个按钮,它有任何用处:

- (NSButton *)makeRefreshButton {
    NSButton *myButton;
    NSRect myFrame;
    NSImage *myIcon;
    PlayerButtonCell *myCell;

    myIcon = [NSImage imageNamed:kPlayerViewRefreshIconName];
    myCell = [[PlayerButtonCell alloc] initImageCell:myIcon];

    myFrame.origin = NSMakePoint(CONTENT_PADDING , CONTENT_PADDING);
    myFrame.size = CONTROL_PLAYBACK_SIZE;

    myButton = [[NSButton alloc] initWithFrame:myFrame];
    [myButton setCell:myCell];
    [myButton setButtonType:NSMomentaryPushInButton];

    [myCell release];

    return [myButton autorelease];
}

I subclassed the NSButtonCell class to give a different look to my button. I have the drawing code working fine. It's a rounded button filled with CGGradients to look like the iTunes playback controls. They are not completely the same, but they resemble enough to me.

Now my problem is the button type. I set the button type in the -[PlayerButtonCell initImageCell:] but I'm not getting it working to only draw the pushed in look when the button is pressed. I present you a piece of my code:

//
//  PlayerButtonCell.m
//  DownTube
//

#import "PlayerButtonCell.h"

@implementation PlayerButtonCell
/* MARK: Init */
- (id)initImageCell:(NSImage *)image {
    self = [super initImageCell:image];
    if(self != nil) {
        [self setImage:image];
        [self setButtonType:NSMomentaryPushInButton];
    }
    return self;
}

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
    NSImage *myImage;
    NSBezierPath *myPath;
    NSRect myFrame;
    NSInteger myState;

    myFrame = NSInsetRect(cellFrame , STROKE_WIDTH / 2.0 , STROKE_WIDTH / 2.0);
    myImage = [self image];
    myState = [self state];

    NSLog(@"%d", [self buttonType]);

    /* Create bezier path */
    {
        myPath = [NSBezierPath bezierPathWithOvalInRect:myFrame];
    }

    /* Fill with background color */
    {
        /* Fill code here */
    }


    /* Draw gradient if on */
    if(myState == NSOffState) {
        /* Code to draw the button when it's not pushed in */

    } else {
        /* Code to draw the button when it IS pressed */
    }

    /* Stroke */
    {
        /* Code to stroke the bezier path's edge. */
    }
}
@end

As you can see, I check the pushed in status by the [NSButtonCell state] method. But the button cell acts like a check box, as in NSSwitchButton. This, I do not want. I want it to momentary light.

Hope someone can help me,
ief2

EDIT:
I create a button with this code of it is of any use:

- (NSButton *)makeRefreshButton {
    NSButton *myButton;
    NSRect myFrame;
    NSImage *myIcon;
    PlayerButtonCell *myCell;

    myIcon = [NSImage imageNamed:kPlayerViewRefreshIconName];
    myCell = [[PlayerButtonCell alloc] initImageCell:myIcon];

    myFrame.origin = NSMakePoint(CONTENT_PADDING , CONTENT_PADDING);
    myFrame.size = CONTROL_PLAYBACK_SIZE;

    myButton = [[NSButton alloc] initWithFrame:myFrame];
    [myButton setCell:myCell];
    [myButton setButtonType:NSMomentaryPushInButton];

    [myCell release];

    return [myButton autorelease];
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

权谋诡计 2024-11-23 06:07:47

您正在寻找错误的财产。 -state 是按钮是否被选中。您需要查看 isHighlighted,它会告诉您按钮是否被按下。

查看复选框:

Checkbox states

当您单击并按住它时,该复选框仍处于未选中状态,但会稍微变暗 (702)。然后当您释放鼠标时,它会进行检查(704)。然后,当您再次单击并按住时,选中的复选框会变暗,但仍然处于选中状态(705),并且只有当您在内部释放时,它实际上才会取消选中(701)。

因此,有两个不同的方面,即突出显示和状态,它们结合起来提供 4 种外观之一。每个 NSButtonCell 每当单击它时都会将其状态提升到 -nextState 返回的值。但某些按钮类型显示状态,而其他按钮类型则不显示。查看任何按钮(例如对话框窗口中的“确定”按钮),您会发现在幕后其状态在打开和关闭之间变化,即使它总是以相同的方式绘制。

您的绘图代码会查看 -showsStateBy 属性,并且仅在表明应该显示状态时才显示状态。

You're looking at the wrong property. -state is whether a button is checked or not. You want to look at isHighlighted, which tells you whether your button is pressed or not.

Look at a checkbox:

Checkbox states

When you click and hold on it, the checkbox is still unchecked, but darkens slightly (702). Then when you release the mouse, it checks (704). Then when you click and hold again, the checked checkbox darkens, but is still checked (705), and only when you release inside, it actually unchecks (701).

So there are two different aspects, highlight and state, which combine to provide one of 4 appearances. Every NSButtonCell advances its state to whatever -nextState returns whenever it is clicked. But some button types show the state, while others don't. Look at any pushbutton (e.g. the "OK" button in a dialog window) and you'll find that behind the scenes its state is changed between on and off, even though it always draws the same way.

It is your drawing code that looks at the -showsStateBy property and only shows the state if that indicates it should.

旧城空念 2024-11-23 06:07:47

您在 init 中尝试过 [self setButtonType:NSMomentaryLightButton]; 吗?

have you tried [self setButtonType:NSMomentaryLightButton]; in the init?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文