Modal Glue

Recently, Quentin Carnicelli of Rogue Amoeba asked if there were NSResponder methods that you could hook your “OK” and “Cancel” buttons to to dismiss a modal panel (or sheet). As far as I knew there wasn’t but, gosh darnit, that would be a useful thing to have.

To clarify what I’m talking about here, when you run your own modal window or sheet with “OK” and “Cancel” buttons (or some equivalents), you end up hooking those up to methods that dismiss the window/sheet, stop the modal session and return some code (either one for confirmation or cancellation). Most of the time, you end up writing the exact same code. It’s glue code that shouldn’t have to be written.

Now, if you look at NSResponder, you’ll see all sorts of action methods in place. Sticking these glue methods into NSResponder will allow you to hook up your “OK” and “Cancel” buttons to the “First Responder” in IB. The idea here is that there is a default implementation that will close the current modal window or sheet and set the return code to either NSOKButton or NSCancelButton. With this, your code can act more like it’s using NSRunAlertPanel() or NSBeginAlertSheet() by just interpreting the return code.

I’ve created an NSResponder category with the methods -confirmModal: and -cancelModal: to which you can hook up your “OK” and “Cancel” buttons in IB. Note that you may have to manually add the methods to NSResponder in IB as it doesn’t know about them.

Now NSResponder’s versions of these methods don’t actually do anything besides pass it on to the next responder. The main part is in NSWindow, which overrides it. It will check to see if it’s the current modal window or sheet, order itself out, stop the modal session and send back the appropriate code. By using the responder chain, this mechanism will find the “nearest” modal window. Note that it is assumed here that the buttons to dismiss a modal window are in the same window. If you want to dismiss it from a different window, it may or may not work (depending on the responder chain and other subtleties such as the odd specification of NSWindow’s -isSheet method). I can’t think of a non-contrived case where you’d want this or care but if one comes up, let me know.

So here’s the download. Suggestions, questions, bug reports appreciated.

Category: Cocoa, Downloads, OS X, Programming 2 comments »

2 Responses to “Modal Glue”

  1. Berbie

    I tried this but when the sheet drops down and I press any button the window gets the – stopModalWindowOrSheetWithCode:sender: call not the sheet. Therefore the isSheet part is never being executed.

    Although I like the idea…

    – berbie

  2. mr_noodle

    Hi Berbie,

    Are you running Tiger? I wasn’t able to replicate the behavior on Leopard but it does act funny on Tiger. I’ll take a look at it this weekend and put up an updated version with a fix (if possible).

Leave a Reply

Back to top