1

I put several controls (button,textfield,...) in a NSBox. is it possible to disable NSBox that user can't access controls (means can't click on button or write in textfield)?

how about nsview ?

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370

3 Answers3

5

An NSBox is basically just a view with a border, there's no way to "disable" it. If you want to disable all the controls in a box, you could loop through all its subviews and disable them , or another way I've done this is to put an overlay view over the whole box and override mouseDown in that overlay (to capture any mouseDown events so they aren't queued in the event loop). You can also give the overlay a semi-transparent white color so the box has a disabled appearance.

rdelmar
  • 103,982
  • 12
  • 207
  • 218
3

Or, if you have a custom NSBox, you can override NSView's -hitTest: (conditionally)

- (NSView *)hitTest:(NSPoint)aPoint {
    if (!enabled) return nil;
    else return [super hitTest:aPoint];
}

To stop the window from sending events to all your subviews.

To provide visual feedback, conditionally drawing some sort of overlay in the custom NSBox's -drawRect method would work.

Vervious
  • 5,559
  • 3
  • 38
  • 57
  • This doesn't provide any visual feedback to the user, does it? I think that could be confusing (unless you're throwing up an alert or something). – rdelmar May 06 '12 at 05:45
  • No, there is no visual feedback (unless you do some custom drawing), so your answer is probably better for most use cases, I just thought I'd provide an alternative. – Vervious May 06 '12 at 06:18
1

Yes, you just need to look at the subviews of the NSBox, which is typically just one NSView, and then your actual controls will be under the subviews of that.

Here's a quick C-style function I wrote to enable/disable most common UI controls, including NSBox...

void SetObjEnabled(NSObject * Obj, bool Enabled)
{
    //Universal way to enable/disable a UI object, including NSBox contents

    NSControl * C = (NSControl *)Obj;

    if([C respondsToSelector:@selector(setEnabled:)])
        [C setEnabled:Enabled];

    if([C.className compare:@"NSTextField"] == NSOrderedSame)
    {
        NSTextField * Ct = (NSTextField*)C;
        if(!Enabled)
            [Ct setTextColor:[NSColor disabledControlTextColor]];
        else //Enabled
            [Ct setTextColor:[NSColor controlTextColor]];
    }
    else if([C.className compare:@"NSBox"] == NSOrderedSame)
    {
        NSBox * Cb = (NSBox*)C;

        //There is typically just one subview at this level
        for(NSView * Sub in Cb.subviews)
        {
            //Here is where we'll get the actual objects within the NSBox
            for(NSView * SubSub in Sub.subviews)
                SetObjEnabled(SubSub, Enabled);
        }
    }
}
Wookie
  • 782
  • 8
  • 12