//************************************************************************************** // Filename: NibModalDialog.cp // Part of Contextual Menu Workshop by Abracode Inc. // http://free.abracode.com/cmworkshop/ // Copyright © 2002-2003 Abracode, Inc. All rights reserved. // // Description: A dialog created from nib resources // //************************************************************************************** // Revision History: // Saturday, June 7, 2003 - Original //************************************************************************************** #include "NibModalDialog.h" #include "IBCarbonRuntime.h" NibModalDialog::NibModalDialog(CFStringRef inNibName, CFStringRef inDlogWindowName) : mWindow(NULL), mDlgEventHandlerUPP(NULL), mCommand(kNullHICommand), mIsRunning(false) { IBNibRef theNib = NULL; OSStatus err = ::CreateNibReference(inNibName, &theNib); if((err == noErr) && (theNib != NULL)) { ::CreateWindowFromNib (theNib, inDlogWindowName, &mWindow); ::DisposeNibReference( theNib ); } if(mWindow == NULL) return; } NibModalDialog::NibModalDialog(CFBundleRef inBundleRef, CFStringRef inNibName, CFStringRef inDlogWindowName) : mWindow(NULL), mDlgEventHandlerUPP(NULL), mCommand(kNullHICommand), mIsRunning(false) { IBNibRef theNib = NULL; OSStatus err = ::CreateNibReferenceWithCFBundle(inBundleRef, inNibName, &theNib); if((err == noErr) && (theNib != NULL)) { ::CreateWindowFromNib (theNib, inDlogWindowName, &mWindow); ::DisposeNibReference( theNib ); } if(mWindow == NULL) return; } NibModalDialog::~NibModalDialog() { DisposeDialog(); if(mDlgEventHandlerUPP != NULL) { ::DisposeEventHandlerUPP(mDlgEventHandlerUPP); mDlgEventHandlerUPP = NULL; } } void NibModalDialog::DisposeDialog() { if(mWindow != NULL) { if(mIsRunning) { ::QuitAppModalLoopForWindow(mWindow); } ::DisposeWindow(mWindow); mWindow = NULL; } mCommand = kNullHICommand; mIsRunning = false; } //virtual, runs dialog modally //override if you need different behaviour void NibModalDialog::Run() { if(mWindow == NULL) return; Initialize(); InstallEventHandler(); ::ShowWindow(mWindow); mIsRunning = true; ::RunAppModalLoopForWindow(mWindow); } //virtual, override to make custom initialization before the window is shown void NibModalDialog::Initialize() { } //virtual, override when you want to handle other events, not only commands void NibModalDialog::InstallEventHandler() { if(mWindow == NULL) return; const EventTypeSpec windowEvents[] = { { kEventClassCommand, kEventCommandProcess }, { kEventClassWindow, kEventWindowClose } }; if ( mDlgEventHandlerUPP == NULL ) mDlgEventHandlerUPP = ::NewEventHandlerUPP( NibModalDialog::DialogEventHandlerProc ); OSStatus err = ::InstallWindowEventHandler( mWindow, mDlgEventHandlerUPP, GetEventTypeCount(windowEvents), windowEvents, this, NULL ); } //static, in most cases no need to change this, just override HandleEvent function //make sure that the user data passed to the handler is the pointer to NibModalDialog pascal OSStatus NibModalDialog::DialogEventHandlerProc( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData ) { NibModalDialog *theDialog = (NibModalDialog *)inUserData; if(theDialog == NULL) return paramErr; return theDialog->HandleEvent(inCallRef, inEvent); } //virtual, override when you want to handle more commands OSStatus NibModalDialog::HandleEvent(EventHandlerCallRef inCallRef, EventRef inEvent) { #pragma unused (inCallRef) if(mWindow == NULL) return paramErr; OSStatus err = eventNotHandledErr; UInt32 eventKind = ::GetEventKind( inEvent ); UInt32 eventClass = ::GetEventClass( inEvent ); if(eventClass == kEventClassCommand) { switch( eventKind ) { case kEventCommandProcess: { ::GetEventParameter( inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &mCommand ); err = ProcessCommand(); if( CommandShouldQuitDialog() ) { ::QuitAppModalLoopForWindow(mWindow); mIsRunning = false; err = noErr; } } break; } } else if((eventClass == kEventClassWindow) && (eventKind == kEventWindowClose)) { ::QuitAppModalLoopForWindow(mWindow); mIsRunning = false; err = noErr; } return err; } //virtual, override when you add buttons which are closing the dialog //standard closing commands are OK, Cancel and window close Boolean NibModalDialog::CommandShouldQuitDialog() { return ((mCommand.commandID == kHICommandOK) || (mCommand.commandID == kHICommandClose) || (mCommand.commandID == kHICommandCancel)); } //virtual, override to process your commands //returns noErr if command handled otherwise should return eventNotHandledErr OSStatus NibModalDialog::ProcessCommand() { return eventNotHandledErr; } #pragma mark - ControlRef NibModalDialog::GetControlByID(const ControlID &inControlID) { if(mWindow == NULL) return NULL; ControlRef theControl = NULL; OSStatus err = ::GetControlByID(mWindow, &inControlID, &theControl); if(err == noErr) return theControl; return NULL; }