janeh
janeh

Reputation: 3804

Customize NSToolbar - Disable "Use small size"

How do I disable the "Use small size" option in the toolbar? I am using Xcode 4.

(That's the option that appears when users go to customize the Toolbar.)

Upvotes: 2

Views: 2255

Answers (4)

ctietze
ctietze

Reputation: 2932

Here's a Swift 2.2 version of @MacGreg's solution. You can keep your NSWindowDelegate wherever you like, just ensure at least the following is called:

var toolbar: UniformToolbar!

func window(window: NSWindow, willPositionSheet sheet: NSWindow, usingRect rect: NSRect) -> NSRect {

    toolbar.removeSizeToggle(window: sheet)

    return rect
}

Toolbar Subclass without the Checkbox

class UniformToolbar: NSToolbar {

    override var sizeMode: NSToolbarSizeMode {
        get {
            return NSToolbarSizeMode.Regular
        }
        set { /* no op */ }
    }

    func removeSizeToggle(window window: NSWindow) {

        guard let views = window.contentView?.subviews else { return }

        let toggle: NSButton? = views.lazy
            .flatMap({ (view: NSView) -> NSButton? in view as? NSButton })
            .filter({ (button: NSButton) -> Bool in

                guard let buttonTypeValue = button.cell?.valueForKey("buttonType")?.unsignedIntegerValue,
                    buttonType = NSButtonType(rawValue: buttonTypeValue)
                    else { return false }

                return buttonType == .SwitchButton
            })
            .first

        toggle?.hidden = true
        window.contentView?.display()
    }
}

Upvotes: 0

Wevah
Wevah

Reputation: 28242

If you're not distributing on the Mac App Store, and don't mind subclassing private methods, you can create an NSToolbarSubclass and override _allowsSizeMode: to return NO:

- (BOOL)_allowsSizeMode:(NSToolbarSizeMode)mode {
    return mode != NSToolbarSizeModeSmall;
}

This has the added benefit of removing the checkbox from the customization sheet, as well.

Upvotes: 5

MacGreg
MacGreg

Reputation: 66

Thanks to Rob Keniger for the excellent start. If you can have your custom toolbar as a delegate of your window, you can avoid having "Use small size" visible by getting at the sheet before it is displayed on screen. Do this by implementing [NSToolbar window:willPositionSheet:usingRect:] in the custom toolbar class. Elsewhere in your code, you'll need to do:

[myWindowWithToolbar setDelegate:myInstanceOfXXToolbar];

Here's the updated custom toolbar class:

@implementation XXToolbar

- (void)setSizeMode:(NSToolbarSizeMode)aSizeMode
{
    [super setSizeMode:NSToolbarSizeModeRegular];
}

- (NSRect)window:(NSWindow *)window willPositionSheet:(NSWindow *)sheet usingRect:(NSRect)rect {
    NSView *buttonView = nil;

    for(NSView* view in [[sheet contentView] subviews])
    {
        if([view isKindOfClass:[NSButton class]])
        {
            if([[[(NSButton*)view cell] valueForKey:@"buttonType"] integerValue] == NSSwitchButton)
            {
                buttonView = view;
                break;
            }
        }
    }

    if (buttonView) {
        [buttonView setHidden:YES];

        // This is important as it causes the sheet to redraw without the button off screen
        [[sheet contentView] display];
    }

    return rect;
}

@end

Hope you find this useful.

Upvotes: 2

Rob Keniger
Rob Keniger

Reputation: 46020

You could subclass NSToolbar, override -setSizeMode: and in your implementation call [super setSizeMode: NSToolbarSizeModeRegular];.

If you're instantiating the toolbar in Interface Builder then make sure you assign your subclass to the toolbar in the nib.

@implementation RKToolbar
- (void)setSizeMode:(NSToolbarSizeMode)aSizeMode
{
    [super setSizeMode:NSToolbarSizeModeRegular];
}
@end

This won't remove the checkbox from the customize panel but it will prevent it from doing anything.

There's not really a supported way to remove the checkbox. This does work but it's pretty hacky:

//in your NSToolbar subclass
- (void)runCustomizationPalette:(id)sender
{
    [super runCustomizationPalette:sender];

    NSWindow* toolbarWindow = [NSApp mainWindow];

    NSWindow* sheet = [toolbarWindow attachedSheet];

    for(NSView* view in [[sheet contentView] subviews])
    {
        if([view isKindOfClass:[NSButton class]])
        {
            if([[[(NSButton*)view cell] valueForKey:@"buttonType"] integerValue] == NSSwitchButton)
            {
                [view setHidden:YES];
            }
        }
    }
}

Upvotes: 2

Related Questions