NSButton::setState & bindings

Discussion in 'Mac Programming' started by zeppenwolf, Jul 10, 2011.

  1. zeppenwolf macrumors regular

    zeppenwolf

    Joined:
    Nov 17, 2009
    #1
    My interface has a number of buttons which are a subclass of NSButton I've named "StickyOnButton". That means they mimic the behavior of radio buttons or tabs/tab panels-- once you click one On, clicking it again does nothing. It can only be turned Off by turning On another one of the group.

    And that means that I need to use setState:false programmatically to turn the previous button Off when the next button is clicked On.

    And that means that the binding to NSUserDef'sCon'r is not tripped-- the value is not updated by a call to setState.

    I would like to override setState in my StickyOnButton class, (and it strikes me as appropriate), like:

    Code:
    - (void)setState:(NSInteger)value {
    
        [super setState:value];
    
        if ( value ) return;
    
        // This line can only be reached from my own code
        anyoneWhoIsObservingMePleaseUpdateAnyBoundKeyToTheNewValue();
    }
    Maybe someday it will all seem very simple to me, but right now the docs are killing me; nothing seems to remotely fit.

    Can anyone help? Is it even possible with the public API?
     
  2. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #2
    What are you expecting to accomplish from the red-hilited code?

    If you're trying to prevent responding to the click by turning itself off, I don't think the code does that. For example, you've already called super setState, so if you're planning to prevent something from happening (i.e. a state change), then that horse has already left the barn.

    All the code is doing is preventing the call to anyoneWhoIsObservingMePleaseUpdateAnyBoundKeyToTheNewValue() when the new value is non-zero. That seems wacky to me.

    The logic I think you need is that if the state is "on" (whatever that means for the integer values, and it may mean different things for buttons with different numbers of states, i.e. see NSButton ref doc and look for mixed state), then the button doesn't respond to clicks by changing state.

    I'm also thinking you should look at Apple's sample projects for one with radio buttons, and then see how those are setup. It's possible that something in there could lead you to not need a subclass of NSButton. For example, radio buttons seem to work with no special subclassing, which makes me question the apparent assertion that a subclass is needed.
     
  3. zeppenwolf thread starter macrumors regular

    zeppenwolf

    Joined:
    Nov 17, 2009
    #3
    I probably wasn't being clear.

    The problem with setState not tripping the binding observer only exists when the button is On and must be turned Off. That is because turning it Off must be done in my code, not as a response to a user's click.

    When a button which is Off is clicked, it should turn On in the completely normal manner, meaning it should follow the default Apple code.

    This is what the red-hilited line accomplishes: I want to call observerPleaseUpdate() if and only if value is false in setState:value


    >If you're trying to prevent responding to the click by turning itself off, I don't think the code does that.

    No, the code to prevent an On button responding to a click exists elsewhere. The above snippet I want to implement has nothing to do with the clicking issue. I mean, directly.


    > For example, you've already called super setState, so if you're planning to prevent something from happening (i.e. a state change), then that horse has already left the barn.

    I absolutely want setState:value to do what it always should. It is just that when setState:false is called, I *also* need to call observerPleaseNotice().


    >All the code is doing is preventing the call to anyoneWhoIsObservingMePleaseUpdateAnyBoundKeyToTheNewValue() when the new value is non-zero.

    Yes.


    >That seems wacky to me.

    But it seems you weren't understanding what I'm after. Have I cleared it up?


    >The logic I think you need is that if the state is "on" [...] then the button doesn't respond to clicks by changing state.

    Yes, and that part works fine.


    > I'm also thinking you should look at Apple's sample projects for one with radio buttons, and then see how those are setup. It's possible that something in there could lead you to not need a subclass of NSButton. For example, radio buttons seem to work with no special subclassing, which makes me question the apparent assertion that a subclass is needed.

    This is not a case where subclassing radio buttons will work. The window is a custom graphic, and all the controls are custom graphics, arranged in non-standard ways... I mentioned radio buttons just to try to explain why I had to call setState: manually.
     
  4. jiminaus, Jul 10, 2011
    Last edited: Jul 10, 2011

    jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #4
    I am wonder if your approaching this from the wrong way. In terms of MVC, controls update in responce to model changes. It seems the NSUserDefaultsController is acting as a model controller, and the defaults themselves being part of the your app's model.

    So I'm wonder if you should be tying your button states to the model. A click on a button would update the model. In reaction to the model change, the buttons would update their state, including the clicked button remaining on, and the previously on button going off.


    Also I wondering if you're putting this co-ordination logic in the wrong place. My instinct is to put it in a view controller that controllers that set of "radio" buttons, instead of trying to distribute it across the individual buttons.
     

Share This Page