0

For a personal project, I'm currently trying to replicate the visual stylings of the toolbar in Automator for OS X. I have tried just about everything to get my NSButtons inside of the NSToolbar to look visually similar, but can't seem to figure out the delicate UI components to figure it out, so I'm turning to the brilliant minds on Stack Overflow.

What I'm trying to do: I'm trying to copy the visual stylings of the Automator toolbar buttons:

enter image description here

The Setup: Currently I have tiff images for active button state, inactive button state, and pressed button state. I want to use these images as the background for the NSButtonCell. Right now, I've subclassed NSButtonCell (code below), and set the NSButtonCell class to be TFToolbarButtonCell in the XIB file in Interface Builder. In the subclass of NSButtonCell, I'm overriding -drawWithFrame:inView to draw the appropriate state image in the frame; I'm also overriding -highlight:withFrame:inView to draw the pressed image when the button is clicked.

Any direction into what I might be doing wrong here would be greatly appreciated!

TFToolbarButtonCell.h

#import <Cocoa/Cocoa.h>

@interface TFToolbarButtonCell : NSButtonCell

    @property (nonatomic, strong) NSImage *onImage;
    @property (nonatomic, strong) NSImage *offImage;
    @property (nonatomic, strong) NSImage *highlightImage;

@end

TFToolbarButtonCell.m

#import "TFToolbarButtonCell.h"

@implementation TFToolbarButtonCell

    - (id)init
    {
        self = [super init];
        if(self) {
            //initialize here
        }
        return self;
    }

    - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
    {
        if([self state]){
            [self.onImage drawInRect:cellFrame fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
        } else {
            [self.offImage drawInRect:cellFrame fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
        }
    }

   - (void)highlight:(BOOL)flag withFrame:(NSRect)cellFrame inView:(NSView *)controlView
    {
        if(flag){
            [self.highlightImage drawInRect:cellFrame fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
        }
    }

@end
coryb
  • 238
  • 3
  • 14

1 Answers1

0

I think you can accomplish what you want by subclassing NSButton and implementing

- (void)mouseDown:(NSEvent *)theEvent
- (void)mouseUp:(NSEvent *)theEvent

and your own method to set the inactive state.

These methods would call

- (void)setImage:(NSImage *)anImage

To change from active to pressed to inactive states using the different images.

You also have to uncheck "Bordered" in Interface Builder on your NSButton to stop the button background from showing.

Also, calling

- (void)setEnabled:(BOOL)enabled

on the NSToolbarItem will change the palette label to active/inactive (grey the text below the button).

SG1
  • 545
  • 3
  • 5
  • Thanks. Only one issue remains: In the initWithFrame in the NSButton subclass, I set the button type to NSMomentaryChangeButton, and then set the image to active (I'm not going to worry about the inactive state). However, when I build and run, and the toolbar initializes, along with the button, the active image doesn't appear unless first clicked. Any ideas on why that might be happening? – coryb Apr 12 '13 at 14:17
  • 1
    You need to to call it in - (void) awakeFromNib instead because it will be called after the nib has finished loading. see: http://stackoverflow.com/questions/6436895/init-and-awakefromnib – SG1 Apr 12 '13 at 17:36