//----------------------------------------------------------------------------------- static void DoTheTracking(EventRef inEvent, MTViewData* data) { MouseTrackingResult mouseResult; ControlPartCode part; Point qdPt; HIPoint where; // Extract the mouse location (local coordinates!) GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(HIPoint), NULL, &where); CGAffineTransform m = CGAffineTransformIdentity; // Reset the path if (data->thePath != NULL) CGPathRelease(data->thePath); data->thePath = CGPathCreateMutable(); #if CG_COORDINATES where.y = FlipHIViewYCoordinate(data->theView, where.y); #endif CGPathMoveToPoint(data->thePath, &m, where.x, where.y); // fprintf(stderr, "StartPt: (%g, %g\n", where.x, where.y); while (true) { // Watch the mouse for change: qdPt comes back in global coordinates! TrackMouseLocation((GrafPtr)(-1), &qdPt, &mouseResult); // Bail out when the mouse is released if ( mouseResult == kMouseTrackingMouseReleased ) { HIViewSetNeedsDisplay(data->theView, true); break; } // Need to convert from global where = QDGlobalToHIViewLocal(qdPt, data->theView); #if CG_COORDINATES where.y = FlipHIViewYCoordinate(data->theView, where.y); #endif CGPathAddLineToPoint(data->thePath, &m, where.x, where.y); // fprintf(stderr, "TrackPt: (%g, %g\n", where.x, where.y); part = 0; SetEventParameter(inEvent, kEventParamControlPart, typeControlPartCode, sizeof(ControlPartCode), &part); HIViewSetNeedsDisplay(data->theView, true); } // Send back the part upon which the mouse was released part = kControlEntireControl; SetEventParameter(inEvent, kEventParamControlPart, typeControlPartCode, sizeof(ControlPartCode), &part); }
OSStatus TextViewReadCFURL( HIViewRef textView, CFURLRef cfURL ) { OSStatus status = paramErr; CFDictionaryRef dataOptions = NULL; static const CFStringRef taskCFStr = CFSTR("TaskReadCFURL"); static const CFStringRef taskErrorCFStr = CFSTR("TaskReadCFURLError"); status = TXNReadFromCFURL( HITextViewGetTXNObject(textView), kTXNStartOffset, kTXNEndOffset, dataOptions, cfURL, NULL /*docAttributes*/ ); if( status != noErr ) { WarnStatusString( "TXNReadFromCFURL returned: %lu ", status ); SignalHelpMessage( HIViewGetWindow( textView ), taskErrorCFStr ); } else { CMLTEViewData* mlteData = NULL; SignalHelpMessage( HIViewGetWindow( textView ), taskCFStr ); HIViewSetNeedsDisplay( textView, true ); // in some scenarios, it is useful to remember where we got the file // data from at a later time, so save the URL in our custom instance data object mlteData = TextViewRetrieveMLTEInstanceData( textView ); if( mlteData != NULL ) mlteData->SetURL( cfURL ); } return status; }
static pascal OSStatus MacOSXDialogCommandProcess(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void* inUserData) { HICommand aCommand; OSStatus status = eventNotHandledErr; GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &aCommand); switch (aCommand.commandID) { case kHICommandOK: // we got a valid click on the OK button so let's quit our local run loop QuitAppModalLoopForWindow((WindowRef) inUserData); break; case 'CBED': { // we still enable or disable the custom spot view depending on whether the box is checked or not HIViewRef checkBox = ((HICommandExtended *)&aCommand)->source.control; SInt32 enable = GetControl32BitValue(checkBox); HIViewID hidcsv = {0, 13}; HIViewRef customSpotView; HIViewFindByID(HIViewGetRoot(GetControlOwner(checkBox)), hidcsv, &customSpotView); if (enable) ActivateControl(customSpotView); else DeactivateControl(customSpotView); HIViewSetNeedsDisplay(customSpotView, true); } break; } return status; }
static void SelectTabPane (HIViewRef tabControl, SInt16 index) { HIViewRef sup, userPane, selectedPane = NULL; HIViewID cid; lastTabIndex = index; sup = HIViewGetSuperview(tabControl); cid.signature = 'tabs'; for (int i = 1; i < tabList[0] + 1; i++) { cid.id = tabList[i]; HIViewFindByID(sup, cid, &userPane); if (i == index) selectedPane = userPane; else HIViewSetVisible(userPane, false); } if (selectedPane != NULL) HIViewSetVisible(selectedPane, true); HIViewSetNeedsDisplay(tabControl, true); }
void IGraphicsCarbon::EndUserInput(bool commit) { if (mTextEntryHandler) { RemoveEventHandler(mTextEntryHandler); mTextEntryHandler = 0; } else { return; } if (commit) { // Get the text CharsHandle textHandle; TXNGetDataEncoded(mTextEntryView, kTXNStartOffset, kTXNEndOffset, &textHandle, kTXNTextData); // Check that we have some worthwhile data if (textHandle != NULL && GetHandleSize(textHandle) > 0) { const long textLength = GetHandleSize(textHandle); char txt[257]; strncpy(txt, *textHandle, (textLength > 255) ? 255 : textLength); txt[(textLength > 255) ? 255 : textLength] = '\0'; if (mEdParam) mGraphicsMac->SetFromStringAfterPrompt(mEdControl, mEdParam, txt); else mEdControl->TextFromTextEntry(txt); } } if (mTextEntryView) { TXNFocus(mTextEntryView, false); TXNClear(mTextEntryView); TXNDeleteObject(mTextEntryView); mTextEntryView = 0; } if (mIsComposited) { HIViewSetNeedsDisplay(mView, true); } else { mEdControl->SetDirty(false); mEdControl->Redraw(); } SetThemeCursor(kThemeArrowCursor); SetUserFocusWindow(kUserFocusAuto); mEdControl = 0; mEdParam = 0; }
static pascal void MusicBoxTimerHandler(EventLoopTimerRef inHandlerCallRef, void *userData) { #pragma unused (inHandlerCallRef) OSStatus err; if (showIndicator) err = HIViewSetNeedsDisplay((HIViewRef) userData, true); }
// ----------------------------------------------------------------------------- // HITestViewChanged // ----------------------------------------------------------------------------- // Handler for bounds or hilite changed events // OSStatus HITestViewChanged( EventRef inEvent, HITestViewData* inData ) { #pragma unused( inEvent ) OSStatus err = noErr; // Due to the change, the view needs to redraw HIViewSetNeedsDisplay( inData->view, true ); return err; }
OSStatus TextViewSpellingSupport( HIViewRef textView, Boolean on ) { OSStatus status = noErr; TXNCommandEventSupportOptions options = 0; TXNObject txnObj = HITextViewGetTXNObject(textView); // Got TXNObject? require( txnObj != NULL, EXIT ); // Get existing option settings... status = TXNGetCommandEventSupport( txnObj, &options ); require_noerr( status, EXIT ); // add or subtract spelling support as requested // (and enable/disable menu items appropriately) if( on ) { options |= kTXNSupportSpellCheckCommandProcessing; options |= kTXNSupportSpellCheckCommandUpdating; EnableMenuCommand(NULL, kHICommandShowSpellingPanel); EnableMenuCommand(NULL, kToggleAutoSpellcheckCommand); verify_noerr( SignalHelpMessage( HIViewGetWindow( textView ), CFSTR("SpellSupportEnable") )); } else { if( options & kTXNSupportSpellCheckCommandProcessing ) options ^= kTXNSupportSpellCheckCommandProcessing; if( options & kTXNSupportSpellCheckCommandUpdating ) options ^= kTXNSupportSpellCheckCommandUpdating; DisableMenuCommand(NULL, kHICommandShowSpellingPanel); DisableMenuCommand(NULL, kToggleAutoSpellcheckCommand); verify_noerr( SignalHelpMessage( HIViewGetWindow( textView ), CFSTR("SpellSupportDisable") )); } // Set auto spell check state accordingly status = TextViewSpellCheckAsYouType(textView, on); verify_noerr( status ); // reset modified options status = TXNSetCommandEventSupport(txnObj, options); verify_noerr( status ); HIViewSetNeedsDisplay( textView, true ); EXIT: ; return status; }
static OSStatus UpdateTextControlView (HIViewRef control) { OSStatus err; WindowAttributes attr; err = GetWindowAttributes(GetControlOwner(control), &attr); if (err == noErr) { if (attr & kWindowCompositingAttribute) err = HIViewSetNeedsDisplay(control, true); else Draw1Control(control); } return (err); }
void IGraphicsCarbon::EndUserInput(bool commit) { RemoveEventHandler(mTextEntryHandler); mTextEntryHandler = 0; if (commit) { CFStringRef str; if (GetControlData(mTextEntryView, kControlEditTextPart, kControlEditTextCFStringTag, sizeof(str), &str, NULL) == noErr) { char txt[MAX_PARAM_LEN]; CFStringGetCString(str, txt, MAX_PARAM_LEN, kCFStringEncodingUTF8); CFRelease(str); if (mEdParam) mGraphicsMac->SetFromStringAfterPrompt(mEdControl, mEdParam, txt); else mEdControl->TextFromTextEntry(txt); } } HIViewSetVisible(mTextEntryView, false); HIViewRemoveFromSuperview(mTextEntryView); if (mIsComposited) { //IRECT* pR = mEdControl->GetRECT(); //HIViewSetNeedsDisplayInRect(mView, &CGRectMake(pR->L, pR->T, pR->W(), pR->H()), true); HIViewSetNeedsDisplay(mView, true); } else { if (mEdControl) { mEdControl->SetDirty(false); mEdControl->Redraw(); } } SetThemeCursor(kThemeArrowCursor); SetUserFocusWindow(kUserFocusAuto); mTextEntryView = 0; mEdControl = 0; mEdParam = 0; }
extern OSStatus RedrawWindows( void ) { OSStatus err = noErr; WindowListItem *currentItem = gWindowList; // search through the window list while( currentItem != NULL ) { HIViewSetNeedsDisplay( ((DrawContextStruct*)GetWRefCon(currentItem->windowRef))->viewRef, true); // grab the next context currentItem = currentItem->nextItem; } return err; }
/***************************************************** * * UserPaneHandler(inHandlerCallRef, inEvent, inUserData) * * Purpose: called to handle the UserPane used as an embedder in the HIScrollView * * Inputs: inHandlerCallRef - reference to the current handler call chain * inEvent - the event * inUserData - app-specified data you passed in the call to InstallEventHandler * * Returns: OSStatus - noErr indicates the event was handled * eventNotHandledErr indicates the event was not handled and the Toolbox should take over */ static pascal OSStatus UserPaneHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void * inUserData) { OSStatus status = eventNotHandledErr; HIViewRef userPane = (HIViewRef)inUserData; HIRect bounds; HIViewGetBounds(userPane, &bounds); // the following is a very straightforward simple yet complete implementation of the // kEventClassScrollable protocol which is enough to make the User Pane scrolls along its embedded content switch (GetEventKind(inEvent)) { #pragma mark * kEventScrollableGetInfo case kEventScrollableGetInfo: { // we're being asked to return information about the scrolled view that we set as Event Parameters HISize lineSize = { 1, 1 }, imageSize = {3000, 2000}; SetEventParameter(inEvent, kEventParamViewSize, typeHISize, sizeof(bounds.size), &bounds.size); SetEventParameter(inEvent, kEventParamImageSize, typeHISize, sizeof(imageSize), &imageSize); SetEventParameter(inEvent, kEventParamLineSize, typeHISize, sizeof(lineSize), &lineSize); SetEventParameter(inEvent, kEventParamOrigin, typeHIPoint, sizeof(bounds.origin), &bounds.origin); status = noErr; break; } #pragma mark * kEventScrollableScrollTo case kEventScrollableScrollTo: { // we're being asked to scroll, we just do a sanity check and ask for a redraw if the location is different HIPoint where; GetEventParameter(inEvent, kEventParamOrigin, typeHIPoint, NULL, sizeof(where), NULL, &where); if ((bounds.origin.y != where.y) || (bounds.origin.x != where.x)) { HIViewSetBoundsOrigin(userPane, where.x, where.y); HIViewSetNeedsDisplay(userPane, true); } status = noErr; break; } } } // UserPaneHandler
extern OSStatus InvalidateAndRedrawWindows( void ) { OSStatus err = noErr; WindowListItem *currentItem = gWindowList; DrawContextStruct *windowContext; // search through the window list while( currentItem != NULL ) { // get the draw context struct from the window's refCon windowContext = (DrawContextStruct *) GetWRefCon( currentItem->windowRef ); // make sure that we have a context if ( windowContext != NULL ) { // if we have a text layout, then make sure that we get rid of it. // This really is invalidation! if ( windowContext->layoutObject != NULL ) { err = ATSUDisposeTextLayout( windowContext->layoutObject ); require_noerr( err, InvalidateAndRedrawWindows_err ); windowContext->layoutObject = NULL; } // nifty. Now, we need to redraw the window HIViewSetNeedsDisplay( ((DrawContextStruct*)GetWRefCon(currentItem->windowRef))->viewRef, true); } // grab the next context currentItem = currentItem->nextItem; } InvalidateAndRedrawWindows_err: return err; }
void wxToolBarTool::UpdateToggleImage( bool toggle ) { #ifdef __WXMAC_OSX__ if ( toggle ) { int w = m_bmpNormal.GetWidth() ; int h = m_bmpNormal.GetHeight() ; wxBitmap bmp( w , h ) ; wxMemoryDC dc ; dc.SelectObject( bmp ) ; dc.SetPen( wxNullPen ) ; dc.SetBackground( *wxWHITE ) ; dc.DrawRectangle( 0 , 0 , w , h ) ; dc.DrawBitmap( m_bmpNormal , 0 , 0 , true) ; dc.SelectObject( wxNullBitmap ) ; ControlButtonContentInfo info ; wxMacCreateBitmapButton( &info , bmp ) ; SetControlData( m_controlHandle , 0, kControlIconContentTag, sizeof( info ), (Ptr)&info ); wxMacReleaseBitmapButton( &info ) ; } else { ControlButtonContentInfo info ; wxMacCreateBitmapButton( &info , m_bmpNormal ) ; SetControlData( m_controlHandle , 0, kControlIconContentTag, sizeof( info ), (Ptr)&info ); wxMacReleaseBitmapButton( &info ) ; } IconTransformType transform = toggle ? kTransformSelected : kTransformNone ; SetControlData( m_controlHandle, 0, kControlIconTransformTag, sizeof( transform ), (Ptr)&transform ); HIViewSetNeedsDisplay( m_controlHandle , true ) ; #else ::SetControl32BitValue( m_controlHandle , toggle ) ; #endif }
// MW-2011-09-11: [[ Redraw ]] Force an immediate update of the window within the given // region. The actual rendering is done by deferring to the 'redrawwindow' method. void MCStack::updatewindow(MCRegionRef p_region) { HIViewRef t_root; GetRootControl((WindowPtr)window -> handle . window, &t_root); HIViewRef t_view; GetIndexedSubControl(t_root, 1, &t_view); // MW-2011-10-07: [[ Bug 9792 ]] If the mask hasn't changed, use the update region, // else redraw the whole view. if (!getextendedstate(ECS_MASK_CHANGED)) HIViewSetNeedsDisplayInRegion(t_view, (RgnHandle)p_region, TRUE); else { HIViewSetNeedsDisplay(t_view, TRUE); DisableScreenUpdates(); } HIViewRender(t_view); // MW-2012-09-04: [[ Bug 10333 ]] Flush the window immediately to make sure // we see every update. // MW-2012-09-10: [[ Revert Bug 10333 ]] Delayed until IDE issues can be resolved. // HIWindowFlush((WindowPtr)window -> handle . window); // Update the shadow, if required. if (getextendedstate(ECS_MASK_CHANGED)) { // MW-2012-09-10: [[ Revert Bug 10333 ]] Delayed until IDE issues can be resolved. HIWindowFlush((WindowPtr)window -> handle . window); HIWindowInvalidateShadow((WindowPtr)window -> handle . window); EnableScreenUpdates(); setextendedstate(False, ECS_MASK_CHANGED); } }
static OSStatus HandleKeyEvent( EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData ) { #pragma unused( inHandlerCallRef ) OSStatus err; EventRef keyboardEvent; ByteCount dataSize; UniCharCount numNewCharacters; DrawContextStruct *context = inUserData; // get the keyboard event err = GetEventParameter( inEvent, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof( EventRef ), NULL, &keyboardEvent ); require_noerr( err, HandleKeyEvent_err ); // get the data size of the event err = GetEventParameter( keyboardEvent, kEventParamKeyUnicodes, typeUnicodeText, NULL, 0, &dataSize, NULL ); require_noerr( err, HandleKeyEvent_err ); // calculate the number of characters based on the data size numNewCharacters = dataSize / sizeof( UniChar ); // check to see if the buffer is large enough to fit the key if ( context->textBufferSize < ( context->characterCount + numNewCharacters ) ) { ByteCount newSize; // nope. We need to resize the buffer. First, we need to pick a // size. if ( context->textBufferSize == 0 ) { // the buffer has never been allocated. So, set it to a default // size plus whatever we got newSize = dataSize + kDefaultUnicodeBufferSize; } else { // the buffer has been allocated, so just double it's current // size. This is actually one of the most efficient ways to // use realloc newSize = dataSize + (context->textBufferSize * 2); } // allocate the new buffer context->textBuffer = realloc( context->textBuffer, newSize ); require_action( context->textBuffer != NULL, HandleKeyEvent_err, err = memFullErr ); // reset the text pointer, if there is one if ( context->layoutObject != NULL ) { err = ATSUSetTextPointerLocation( context->layoutObject, context->textBuffer, kATSUFromTextBeginning, kATSUToTextEnd, context->characterCount ); require_noerr( err, HandleKeyEvent_err ); } // set the new size in the buffer size context->textBufferSize = newSize / sizeof( UniChar ); } // add the keys to the buffer from the event err = GetEventParameter( keyboardEvent, kEventParamKeyUnicodes, typeUnicodeText, NULL, dataSize, NULL, (void*) ( context->textBuffer + context->characterCount ) ); require_noerr( err, HandleKeyEvent_err ); // if the layout's already been allocated, then add the characters // to it. Otherwise, do nothing and let the draw function handle // everything if ( context->layoutObject != NULL ) { // insert the text into the layout err = ATSUTextInserted( context->layoutObject, context->characterCount, numNewCharacters ); require_noerr( err, HandleKeyEvent_err ); } // increment the character count stored in the context context->characterCount += numNewCharacters; // send message to draw the context HIViewSetNeedsDisplay( context->viewRef, true); HandleKeyEvent_err: return err; }
OSStatus HIOpenGLViewEventControlHiliteChanged (EventHandlerCallRef, EventRef, HIOpenGLViewData* inData) { HIViewSetNeedsDisplay(inData->mControl, true); return noErr; }
/***************************************************** * * Handle_WindowCommandProcess(inHandlerCallRef, inEvent, inUserData) * * Purpose: called to handle of the events generated by the various controls of the HICustomView_Tester window * * Inputs: inHandlerCallRef - reference to the current handler call chain * inEvent - the event * inUserData - app-specified data you passed in the call to InstallEventHandler * * Returns: OSStatus - noErr indicates the event was handled * eventNotHandledErr indicates the event was not handled and the Toolbox should take over */ static pascal OSStatus Handle_WindowCommandProcess(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData) { OSStatus status; HIViewRef customView = (HIViewRef)inUserData; // getting the command HICommandExtended aCommand; status = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(aCommand), NULL, &aCommand); require_noerr(status, ExitCommandProcess); status = eventNotHandledErr; // cheking that the command came from a control if ( ! (aCommand.attributes & kHICommandFromControl) ) goto ExitCommandProcess; switch (aCommand.commandID) { // // Asking for a refresh of the custom view // case 'SNDt': HIViewSetNeedsDisplay(customView, true); status = noErr; break; // // Setting the control value of the custom view // case 'SV00': SetControl32BitValue(customView, 0); status = noErr; break; case 'SV01': SetControl32BitValue(customView, 1); status = noErr; break; case 'SV17': SetControl32BitValue(customView, 17); status = noErr; break; case 'SVTH': SetControl32BitValue(customView, 1000); status = noErr; break; case 'SVet': { HIViewRef editText; HIViewFindByID(HIViewGetRoot(GetControlOwner(customView)), kSetValueEditID, &editText); char buffer[11]; Size actualSize; GetControlData(editText, kControlEntireControl, kControlEditTextTextTag, 10, buffer, &actualSize); if (actualSize > 10) actualSize = 10; buffer[actualSize] = 0; SetControl32BitValue(customView, atoi(buffer)); } status = noErr; break; // // Setting the state of the custom view // case 'CHlt': // setting the hilite to non-0 also stomps the previous hilite state if any // and we don't want that in our testing if (GetControl32BitValue(aCommand.source.control) == 1) HiliteControl(customView, 1); else HiliteControl(customView, 0); status = noErr; break; case 'CEnb': { HIViewRef hiliteControl; HIViewFindByID(HIViewGetRoot(GetControlOwner(customView)), kCheckHiliteID, &hiliteControl); if (GetControl32BitValue(aCommand.source.control) == 1) EnableControl(customView); else DisableControl(customView); UInt16 prevHilite = GetControlHilite(customView); if ((prevHilite == kControlInactivePart) || (prevHilite == kControlDisabledPart)) DisableControl(hiliteControl); else EnableControl(hiliteControl); HIViewSetNeedsDisplay(customView, true); } status = noErr; break; case 'CAct': { HIViewRef hiliteControl; HIViewFindByID(HIViewGetRoot(GetControlOwner(customView)), kCheckHiliteID, &hiliteControl); if (GetControl32BitValue(aCommand.source.control) == 1) ActivateControl(customView); else DeactivateControl(customView); UInt16 prevHilite = GetControlHilite(customView); if ((prevHilite == kControlInactivePart) || (prevHilite == kControlDisabledPart)) DisableControl(hiliteControl); else EnableControl(hiliteControl); HIViewSetNeedsDisplay(customView, true); } status = noErr; break; // // Testing the custom view in or as a scroller in a HIScrollView // case 'CTiS': case 'CTaS': if (GetControl32BitValue(aCommand.source.control) == 1) { // create a HIScrollView and install it where and as the custom view was HIViewRef scrollView; status = HIScrollViewCreate(kHIScrollViewValidOptions, &scrollView); require_noerr(status, ExitCommandProcess); HIRect frame; status = HIViewGetFrame(customView, &frame); require_noerr(status, ExitCommandProcess); status = HIViewSetFrame(scrollView, &frame); require_noerr(status, ExitCommandProcess); HIViewSetLayoutInfo(scrollView, &kBindToParentLayout); HIViewSetLayoutInfo(customView, &kNoBindLayout); status = HIViewAddSubview(HIViewGetSuperview(customView), scrollView); require_noerr(status, ExitCommandProcess); if (aCommand.commandID == 'CTiS') { // if we are testing the custom view in a scroller, we embed it in a scrolling User Pane // that we embed in the HIScrollView Rect boundsRect = {0, 0, 1000, 1000}; HIViewRef userPane; status = CreateUserPaneControl(NULL, &boundsRect, kControlSupportsEmbedding, &userPane); require_noerr(status, ExitCommandProcess); EventTypeSpec userPaneEvents[] = { {kEventClassScrollable, kEventScrollableGetInfo}, {kEventClassScrollable, kEventScrollableScrollTo} }; InstallControlEventHandler(userPane, UserPaneHandler, 2, userPaneEvents, userPane, NULL); status = HIViewAddSubview(scrollView, userPane); require_noerr(status, ExitCommandProcess); status = HIViewAddSubview(userPane, customView); require_noerr(status, ExitCommandProcess); HIViewSetVisible(userPane, true); } else { // else we just embed the custom view directly in the HIScrollView status = HIViewAddSubview(scrollView, customView); require_noerr(status, ExitCommandProcess); } HIViewSetVisible(scrollView, true); // the 2 modes are not compatible so we disable the other check box HIViewRef otherCheckToDisable; if (aCommand.commandID == 'CTiS') HIViewFindByID(HIViewGetRoot(GetControlOwner(customView)), kCheckTestAsScrollID, &otherCheckToDisable); else HIViewFindByID(HIViewGetRoot(GetControlOwner(customView)), kCheckTestInScrollID, &otherCheckToDisable); require_noerr(status, ExitCommandProcess); DisableControl(otherCheckToDisable); // if we reach here, status is already set to noErr so we don't set it again } else { // we remove the HIScrollView and set the custom view back to where and as it was HIViewRef scrollView; if (aCommand.commandID == 'CTiS') scrollView = HIViewGetSuperview(HIViewGetSuperview(customView)); else scrollView = HIViewGetSuperview(customView); status = HIViewAddSubview(HIViewGetSuperview(scrollView), customView); require_noerr(status, ExitCommandProcess); HIRect frame; status = HIViewGetFrame(scrollView, &frame); require_noerr(status, ExitCommandProcess); status = HIViewSetFrame(customView, &frame); require_noerr(status, ExitCommandProcess); HIViewSetLayoutInfo(customView, &kBindToParentLayout); // by releasing the HIScrollView, we also release the scrolling User Pane if any // which was embedded inside CFRelease(scrollView); // we renable the other check box HIViewRef otherCheckToEnable; if (aCommand.commandID == 'CTiS') HIViewFindByID(HIViewGetRoot(GetControlOwner(customView)), kCheckTestAsScrollID, &otherCheckToEnable); else HIViewFindByID(HIViewGetRoot(GetControlOwner(customView)), kCheckTestInScrollID, &otherCheckToEnable); require_noerr(status, ExitCommandProcess); EnableControl(otherCheckToEnable); // if we reach here, status is already set to noErr so we don't set it again } break; } ExitCommandProcess: return status; } // Handle_WindowCommandProcess
static pascal OSStatus CustomSpotViewHandler(EventHandlerCallRef inCaller, EventRef inEvent, void* inRefcon) { OSStatus result = eventNotHandledErr; CustomSpotViewData* myData = (CustomSpotViewData*)inRefcon; switch (GetEventClass(inEvent)) { case kEventClassHIObject: switch (GetEventKind(inEvent)) { case kEventHIObjectConstruct: { myData = (CustomSpotViewData*) calloc(1, sizeof(CustomSpotViewData)); GetEventParameter(inEvent, kEventParamHIObjectInstance, typeHIObjectRef, NULL, sizeof(myData->view), NULL, &myData->view); result = SetEventParameter(inEvent, kEventParamHIObjectInstance, typeVoidPtr, sizeof(myData), &myData); break; } case kEventHIObjectInitialize: { HIRect bounds; GetEventParameter(inEvent, kEventParamBounds, typeHIRect, NULL, sizeof(bounds), NULL, &bounds); myData->spot.x = CGRectGetMidX(bounds) - CGRectGetMinX(bounds); myData->spot.y = CGRectGetMidY(bounds) - CGRectGetMinY(bounds); HIViewSetVisible(myData->view, true); break; } case kEventHIObjectDestruct: { free(myData); result = noErr; break; } default: break; } break; case kEventClassControl: switch (GetEventKind(inEvent)) { case kEventControlDraw: { CGContextRef context; HIRect bounds; result = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(context), NULL, &context); HIViewGetBounds(myData->view, &bounds); if (!IsControlActive(myData->view)) { CGContextSetGrayStrokeColor(context, 0.5, 0.3); CGContextSetGrayFillColor(context, 0.5, 0.3); } else { CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 0.7); CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 0.7); } CGContextSetLineWidth(context, 3.0); CGContextStrokeRect(context, bounds); HIRect spot = { {myData->spot.x - 4.0, myData->spot.y - 4.0}, {8.0, 8.0} }; CGContextFillRect(context, spot); result = noErr; break; } case kEventControlBoundsChanged: { HIRect newHIBounds; GetEventParameter(inEvent, kEventParamCurrentBounds, typeHIRect, NULL, sizeof(newHIBounds), NULL, &newHIBounds); myData->spot.x = CGRectGetMidX(newHIBounds) - CGRectGetMinX(newHIBounds); myData->spot.y = CGRectGetMidY(newHIBounds) - CGRectGetMinY(newHIBounds); break; } case kEventControlHitTest: { HIPoint pt; HIRect bounds; GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(pt), NULL, &pt); HIViewGetBounds(myData->view, &bounds); ControlPartCode part = (CGRectContainsPoint(bounds, pt))?kControlButtonPart:kControlNoPart; result = SetEventParameter(inEvent, kEventParamControlPart, typeControlPartCode, sizeof(part), &part); break; } case kEventControlTrack: { Point qdPoint; Rect qdWindowBounds; HIPoint hiPoint; HIRect hiViewBounds; MouseTrackingResult mouseStatus = kMouseTrackingMouseDown; HIViewGetBounds(myData->view, &hiViewBounds); GetWindowBounds(GetControlOwner(myData->view), kWindowStructureRgn, &qdWindowBounds); // handle the first mouseDown before moving GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(hiPoint), NULL, &hiPoint); while (mouseStatus != kMouseTrackingMouseUp) { if (CGRectContainsPoint(hiViewBounds, hiPoint)) { if (hiPoint.x < hiViewBounds.origin.x+4) hiPoint.x = hiViewBounds.origin.x+4; if (hiPoint.x > hiViewBounds.origin.x+hiViewBounds.size.width-4) hiPoint.x = hiViewBounds.origin.x+hiViewBounds.size.width-4; if (hiPoint.y < hiViewBounds.origin.y+4) hiPoint.y = hiViewBounds.origin.y+4; if (hiPoint.y > hiViewBounds.origin.y+hiViewBounds.size.height-4) hiPoint.y = hiViewBounds.origin.y+hiViewBounds.size.height-4; myData->spot = hiPoint; HIViewSetNeedsDisplay(myData->view, true); } // a -1 GrafPtr to TrackMouseLocation yields global coordinates TrackMouseLocation((GrafPtr)-1L, &qdPoint, &mouseStatus); // convert to window-relative coordinates hiPoint.x = qdPoint.h - qdWindowBounds.left; hiPoint.y = qdPoint.v - qdWindowBounds.top; // convert to view-relative coordinates HIViewConvertPoint(&hiPoint, NULL, myData->view); } break; } default: break; } break; default: break; } return result; }
static pascal OSStatus MultiCartPaneEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) { OSStatus err, result = eventNotHandledErr; HIViewRef view; DragRef drag; PasteboardRef pasteboard; PasteboardItemID itemID; CFArrayRef array; CFStringRef flavorType; CFIndex numFlavors; ItemCount numItems; int index = *((int *) inUserData); switch (GetEventClass(inEvent)) { case kEventClassControl: { switch (GetEventKind(inEvent)) { case kEventControlDraw: { err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view); if (err == noErr) { CGContextRef ctx; err = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(CGContextRef), NULL, &ctx); if (err == noErr) { HIThemeFrameDrawInfo info; HIRect bounds, frame; HIViewGetBounds(view, &bounds); CGContextSetRGBFillColor(ctx, 1.0f, 1.0f, 1.0f, 1.0f); CGContextFillRect(ctx, bounds); info.version = 0; info.kind = kHIThemeFrameTextFieldSquare; info.state = kThemeStateInactive; info.isFocused = false; err = HIThemeDrawFrame(&bounds, &info, ctx, kHIThemeOrientationNormal); if (multiCartDragHilite == index && systemVersion >= 0x1040) { err = HIThemeSetStroke(kThemeBrushDragHilite, NULL, ctx, kHIThemeOrientationNormal); frame = CGRectInset(bounds, 1, 1); CGContextBeginPath(ctx); CGContextAddRect(ctx, frame); CGContextStrokePath(ctx); } } } result = noErr; break; } case kEventControlDragEnter: { err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view); if (err == noErr) { err = GetEventParameter(inEvent, kEventParamDragRef, typeDragRef, NULL, sizeof(DragRef), NULL, &drag); if (err == noErr) { err = GetDragPasteboard(drag, &pasteboard); if (err == noErr) { err = PasteboardGetItemCount(pasteboard, &numItems); if (err == noErr && numItems == 1) { err = PasteboardGetItemIdentifier(pasteboard, 1, &itemID); if (err == noErr) { err = PasteboardCopyItemFlavors(pasteboard, itemID, &array); if (err == noErr) { numFlavors = CFArrayGetCount(array); for (CFIndex i = 0; i < numFlavors; i++) { flavorType = (CFStringRef) CFArrayGetValueAtIndex(array, i); if (UTTypeConformsTo(flavorType, CFSTR("public.file-url"))) { Boolean accept = true; err = SetEventParameter(inEvent, kEventParamControlWouldAcceptDrop, typeBoolean, sizeof(Boolean), &accept); if (err == noErr) { multiCartDragHilite = index; HIViewSetNeedsDisplay(view, true); result = noErr; } } } CFRelease(array); } } } } } } break; } case kEventControlDragWithin: { result = noErr; break; } case kEventControlDragLeave: { err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view); if (err == noErr) { multiCartDragHilite = -1; HIViewSetNeedsDisplay(view, true); } result = noErr; break; } case kEventControlDragReceive: { err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view); if (err == noErr) { err = GetEventParameter(inEvent, kEventParamDragRef, typeDragRef, NULL, sizeof(DragRef), NULL, &drag); if (err == noErr) { multiCartDragHilite = -1; HIViewSetNeedsDisplay(view, true); err = GetDragPasteboard(drag, &pasteboard); if (err == noErr) { err = PasteboardGetItemIdentifier(pasteboard, 1, &itemID); if (err == noErr) { err = PasteboardCopyItemFlavors(pasteboard, itemID, &array); if (err == noErr) { numFlavors = CFArrayGetCount(array); for (CFIndex i = 0; i < numFlavors; i++) { flavorType = (CFStringRef) CFArrayGetValueAtIndex(array, i); if (UTTypeConformsTo(flavorType, CFSTR("public.file-url"))) { CFDataRef flavorData; err = PasteboardCopyItemFlavorData(pasteboard, itemID, flavorType, &flavorData); if (err == noErr) { CFIndex dataSize; UInt8 *data; dataSize = CFDataGetLength(flavorData); data = (UInt8 *) malloc(dataSize); if (data) { CFDataGetBytes(flavorData, CFRangeMake(0, dataSize), data); HIViewRef ctl; HIViewID cid; CFStringRef str; CFURLRef url; GetControlID(view, &cid); cid.signature = 'MNAM'; HIViewFindByID(view, cid, &ctl); url = CFURLCreateWithBytes(kCFAllocatorDefault, data, dataSize, kCFStringEncodingUTF8, NULL); str = CFURLCopyLastPathComponent(url); SetStaticTextCFString(ctl, str, true); CFRelease(str); str = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); if (multiCartPath[cid.id]) CFRelease(multiCartPath[cid.id]); multiCartPath[cid.id] = str; CFRelease(url); result = noErr; free(data); } CFRelease(flavorData); } } } CFRelease(array); } } } } } } } } } return (result); }
/*----------------------------------------------------------------------------------------------------------*/ pascal OSStatus ScrollingTextViewHandler(EventHandlerCallRef inCaller, EventRef inEvent, void* inRefcon) { OSStatus result = eventNotHandledErr; ScrollingTextBoxData* myData = (ScrollingTextBoxData*)inRefcon; switch (GetEventClass(inEvent)) { case kEventClassHIObject: switch (GetEventKind(inEvent)) { case kEventHIObjectConstruct: { // allocate some instance data myData = (ScrollingTextBoxData*) calloc(1, sizeof(ScrollingTextBoxData)); // get our superclass instance HIViewRef epView; GetEventParameter(inEvent, kEventParamHIObjectInstance, typeHIObjectRef, NULL, sizeof(epView), NULL, &epView); // remember our superclass in our instance data and initialize other fields myData->view = epView; // set the control ID so that we can find it later with HIViewFindByID result = SetControlID(myData->view, &kScrollingTextBoxViewID); // store our instance data into the event result = SetEventParameter(inEvent, kEventParamHIObjectInstance, typeVoidPtr, sizeof(myData), &myData); break; } case kEventHIObjectDestruct: { if (myData->theTimer != NULL) RemoveEventLoopTimer(myData->theTimer); CFRelease(myData->theText); free(myData); result = noErr; break; } case kEventHIObjectInitialize: { // always begin kEventHIObjectInitialize by calling through to the previous handler result = CallNextEventHandler(inCaller, inEvent); // if that succeeded, do our own initialization if (result == noErr) { GetEventParameter(inEvent, kEventParamScrollingText, typeCFStringRef, NULL, sizeof(myData->theText), NULL, &myData->theText); CFRetain(myData->theText); GetEventParameter(inEvent, kEventParamAutoScroll, typeBoolean, NULL, sizeof(myData->autoScroll), NULL, &myData->autoScroll); GetEventParameter(inEvent, kEventParamDelayBeforeAutoScroll, typeUInt32, NULL, sizeof(myData->delayBeforeAutoScroll), NULL, &myData->delayBeforeAutoScroll); GetEventParameter(inEvent, kEventParamDelayBetweenAutoScroll, typeUInt32, NULL, sizeof(myData->delayBetweenAutoScroll), NULL, &myData->delayBetweenAutoScroll); GetEventParameter(inEvent, kEventParamAutoScrollAmount, typeSInt16, NULL, sizeof(myData->autoScrollAmount), NULL, &myData->autoScrollAmount); myData->theTimer = NULL; } break; } default: break; } break; case kEventClassScrollable: switch (GetEventKind(inEvent)) { case kEventScrollableGetInfo: { // we're being asked to return information about the scrolled view that we set as Event Parameters HISize imageSize = {50.0, myData->height}; SetEventParameter(inEvent, kEventParamImageSize, typeHISize, sizeof(imageSize), &imageSize); HISize lineSize = {50.0, 20.0}; SetEventParameter(inEvent, kEventParamLineSize, typeHISize, sizeof(lineSize), &lineSize); HIRect bounds; HIViewGetBounds(myData->view, &bounds); SetEventParameter(inEvent, kEventParamViewSize, typeHISize, sizeof(bounds.size), &bounds.size); SetEventParameter(inEvent, kEventParamOrigin, typeHIPoint, sizeof(myData->originPoint), &myData->originPoint); result = noErr; break; } case kEventScrollableScrollTo: { // we're being asked to scroll, we just do a sanity check and ask for a redraw HIPoint where; GetEventParameter(inEvent, kEventParamOrigin, typeHIPoint, NULL, sizeof(where), NULL, &where); HIViewSetNeedsDisplay(myData->view, true); myData->originPoint.y = (where.y < 0.0)?0.0:where.y; HIViewSetBoundsOrigin(myData->view, 0, myData->originPoint.y); break; } default: break; } break; case kEventClassControl: switch (GetEventKind(inEvent)) { // sets the feature of the view. case kEventControlInitialize: { result = CallNextEventHandler(inCaller, inEvent); if (result != noErr) break; UInt32 features = 0; result = GetEventParameter(inEvent, kEventParamControlFeatures, typeUInt32, NULL, sizeof(features), NULL, &features); if (result == noErr) features |= kControlSupportsEmbedding; else features = kControlSupportsEmbedding; result = SetEventParameter(inEvent, kEventParamControlFeatures, typeUInt32, sizeof features, &features); break; } // Our parent view just changed dimensions, so we determined our new height. case kEventControlSetData: CFRelease(myData->theText); CFStringRef *p; GetEventParameter(inEvent, kEventParamControlDataBuffer, typePtr, NULL, sizeof(p), NULL, &p); myData->theText = *p; CFRetain(myData->theText); // fallthrough case kEventControlBoundsChanged: { HIRect bounds; HIViewGetBounds(myData->view, &bounds); // // If we're building on Panther (or later) then HIThemeGetTextDimensions is available, else we use GetThemeTextDimensions // #if PANTHER_BUILD // // Furthermore, if we're running on Panther then we can call HIThemeGetTextDimensions else we call GetThemeTextDimensions // if (GetHIToolboxVersion() >= Panther_HIToolbox_Version) { HIThemeTextInfo textInfo = {0, kThemeStateActive, kScrollingTextBoxFontID, kHIThemeTextHorizontalFlushLeft, kHIThemeTextVerticalFlushTop, kHIThemeTextBoxOptionStronglyVertical, kHIThemeTextTruncationNone, 0, false}; HIThemeGetTextDimensions(myData->theText, bounds.size.width - kMargin - kMargin, &textInfo, NULL, &myData->height, NULL); } else #endif { Point pointBounds; pointBounds.h = (int)(bounds.size.width - kMargin - kMargin); GetThemeTextDimensions(myData->theText, kScrollingTextBoxFontID, kThemeStateActive, true, &pointBounds, NULL); myData->height = pointBounds.v; } myData->height += 2.0 * kMargin; HIViewSetNeedsDisplay(myData->view, true); result = eventNotHandledErr; break; } // Draw the view. case kEventControlDraw: { CGContextRef context; result = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(context), NULL, &context); HIRect bounds; HIViewGetBounds(myData->view, &bounds); CGContextSaveGState(context); CGAffineTransform transform = CGAffineTransformIdentity; // adjust the transform so the text doesn't draw upside down transform = CGAffineTransformScale(transform, 1, -1); CGContextSetTextMatrix(context, transform); // now that the proper parameters and configurations have been dealt with, let's draw result = ScrollingTextBoxDraw(context, &bounds, myData); CGContextRestoreGState(context); if (myData->autoScroll) CGContextStrokeRect(context, bounds); // we postpone starting the autoscroll timer until after we do our first drawing if ( (myData->autoScroll) && (myData->theTimer == NULL) ) InstallEventLoopTimer(GetCurrentEventLoop(), TicksToEventTime(myData->delayBeforeAutoScroll), TicksToEventTime(myData->delayBetweenAutoScroll), myScrollingTextTimeProc, myData, &myData->theTimer); result = noErr; break; } default: break; } break; default: break; } return result; }
static pascal OSStatus PreferencesEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) { OSStatus err, result = eventNotHandledErr; WindowRef tWindowRef = (WindowRef) inUserData; switch (GetEventClass(inEvent)) { case kEventClassWindow: { switch (GetEventKind(inEvent)) { case kEventWindowClose: { QuitAppModalLoopForWindow(tWindowRef); result = noErr; break; } } break; } case kEventClassCommand: { switch (GetEventKind(inEvent)) { HICommand tHICommand; case kEventCommandUpdateStatus: { err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand); if (err == noErr && tHICommand.commandID == 'clos') { UpdateMenuCommandStatus(true); result = noErr; } break; } case kEventCommandProcess: { HIViewRef ctl, root; HIViewID cid; SInt32 value; FSRef ref; bool8 r; root = HIViewGetRoot(tWindowRef); err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand); if (err == noErr) { switch (tHICommand.commandID) { case 'S_EF': { HideWindow(tWindowRef); ConfigureSoundEffects(); ShowWindow(tWindowRef); result = noErr; break; } case 'G_FL': { if (systemVersion >= 0x1040) { HideWindow(tWindowRef); ConfigureCoreImageFilter(); ShowWindow(tWindowRef); } result = noErr; break; } case 'G__7': { cid.signature = 'grap'; cid.id = iNibGGLStretch; HIViewFindByID(root, cid, &ctl); value = GetControl32BitValue(ctl); cid.id = iNibGAspectRatio; HIViewFindByID(root, cid, &ctl); if (value) ActivateControl(ctl); else DeactivateControl(ctl); result = noErr; break; } case 'G_13': { cid.signature = 'grap'; cid.id = iNibGScreenCurvature; HIViewFindByID(root, cid, &ctl); value = GetControl32BitValue(ctl); cid.id = iNibGCurvatureWarp; HIViewFindByID(root, cid, &ctl); if (value) ActivateControl(ctl); else DeactivateControl(ctl); result = noErr; break; } case 'S__3': { cid.signature = 'snd_'; cid.id = iNibSStereo; HIViewFindByID(root, cid, &ctl); value = GetControl32BitValue(ctl); cid.id = iNibSReverseStereo; HIViewFindByID(root, cid, &ctl); if (value) ActivateControl(ctl); else DeactivateControl(ctl); result = noErr; break; } case 'F_FL': { UInt32 modifierkey; err = GetEventParameter(inEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifierkey); if (err == noErr) { if (modifierkey & optionKey) { CFStringRef str; MenuRef menu; str = CFCopyLocalizedString(CFSTR("NoneSelected"), "NoneSelected"); cid.signature = 'othe'; cid.id = iNibOSaveFolder; HIViewFindByID(root, cid, &ctl); SetControl32BitValue(ctl, 3); err = GetControlData(ctl, kControlMenuPart, kControlPopupButtonMenuRefTag, sizeof(MenuRef), &menu, NULL); err = SetMenuItemTextWithCFString(menu, iNibSaveFolderNameMenuItem, str); DisableMenuItem(menu, iNibSaveFolderNameMenuItem); HIViewSetNeedsDisplay(ctl, true); CFRelease(str); if (saveFolderPath) CFRelease(saveFolderPath); saveFolderPath = NULL; } else r = NavBeginChooseFolderSheet(tWindowRef); } result = noErr; break; } case 'NvDn': { r = NavEndChooseFolderSheet(&ref); if (r) { CFStringRef str; CFURLRef url; MenuRef menu; url = CFURLCreateFromFSRef(kCFAllocatorDefault, &ref); str = CFURLCopyLastPathComponent(url); cid.signature = 'othe'; cid.id = iNibOSaveFolder; HIViewFindByID(root, cid, &ctl); SetControl32BitValue(ctl, iNibSaveFolderNameMenuItem); err = GetControlData(ctl, kControlMenuPart, kControlPopupButtonMenuRefTag, sizeof(MenuRef), &menu, NULL); err = SetMenuItemTextWithCFString(menu, iNibSaveFolderNameMenuItem, str); EnableMenuItem(menu, iNibSaveFolderNameMenuItem); HIViewSetNeedsDisplay(ctl, true); CFRelease(str); str = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); if (saveFolderPath) CFRelease(saveFolderPath); saveFolderPath = str; CFRelease(url); } result = noErr; break; } } } break; } } break; } } return (result); }
/***************************************************** * * Internal_HICustomViewHandler(inHandlerCallRef, inEvent, inUserData) * * Purpose: Event handler that implements our HICustomView custom view * * Inputs: inHandlerCallRef - reference to the current handler call chain * inEvent - the event * inUserData - app-specified data you passed in the call to InstallEventHandler * * Returns: OSStatus - error code (0 == no error) */ static pascal OSStatus Internal_HICustomViewHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void * inUserData) { OSStatus status = eventNotHandledErr; HICustomViewData * myData = (HICustomViewData *)inUserData; switch (GetEventClass(inEvent)) { case kEventClassHIObject: switch (GetEventKind(inEvent)) { case kEventHIObjectConstruct: { // allocate some instance data myData = (HICustomViewData *) calloc(1, sizeof(HICustomViewData)); require_action(myData != NULL, ConstructExit, status = memFullErr); // get our superclass instance HIViewRef epView; status = GetEventParameter(inEvent, kEventParamHIObjectInstance, typeHIObjectRef, NULL, sizeof(epView), NULL, &epView); require_noerr(status, ConstructExit); // remember our superclass in our instance data myData->view = epView; // store our instance data into the event status = SetEventParameter(inEvent, kEventParamHIObjectInstance, typeVoidPtr, sizeof(myData), &myData); require_noerr(status, ConstructExit); ConstructExit: break; } #pragma mark * kEventHIObjectInitialize case kEventHIObjectInitialize: { // always begin kEventHIObjectInitialize by calling through to the previous handler status = CallNextEventHandler(inHandlerCallRef, inEvent); require_noerr(status, InitializeExit); // if that succeeded, do our own initialization // in this sample code, there is nothing to do InitializeExit: break; } case kEventHIObjectDestruct: { // freeing our storage if (myData != NULL) free(myData); status = noErr; break; } default: break; } break; case kEventClassControl: switch (GetEventKind(inEvent)) { #pragma mark * kEventControlDraw case kEventControlDraw: { CGContextRef context; status = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(context), NULL, &context); require_noerr(status, ControlDrawExit); HIRect bounds, viewBounds; HIViewGetBounds(myData->view, &viewBounds); // setting our colors according to state: IsControlEnabled, IsControlActive, IsControlHilited if (!IsControlEnabled(myData->view)) { CGContextSetRGBFillColor(context, 0.3, 0.3, 0.3, 0.8); CGContextSetRGBStrokeColor(context, 0.5, 0.5, 0.5, 0.8); } else if (!IsControlActive(myData->view)) { CGContextSetRGBFillColor(context, 0.7, 0.7, 0.7, 0.8); CGContextSetRGBStrokeColor(context, 0.8, 0.8, 0.8, 0.8); } else if (!IsControlHilited(myData->view)) { CGContextSetRGBFillColor(context, 1, 0, 0, 0.8); CGContextSetRGBStrokeColor(context, 0, 0, 1, 0.8); } else { CGContextSetRGBFillColor(context, 0.7, 0, 0, 0.8); CGContextSetRGBStrokeColor(context, 0, 0, 0.7, 0.8); } // using a line thickness of 3 CGContextSetLineWidth(context, 3); bounds = CGRectInset(viewBounds, 3, 3); float minDim = (bounds.size.height < bounds.size.width) ? bounds.size.height / 2 : bounds.size.width / 2; float cx = bounds.origin.x + minDim, cy = bounds.origin.y + minDim; UInt32 i, n = GetControl32BitValue(myData->view); // having some fun with geometric shapes based on the value of the custom view CGContextBeginPath(context); switch (n) { case 0: CGContextAddArc(context, cx, cy, minDim, 0, 2 * pi, true); break; case 1: CGContextAddEllipseInRect(context, CGRectInset(bounds, bounds.size.width * 0.4, 0)); break; default: { float deltangle = pi / n, angle = 0, r = minDim / 2; CGContextMoveToPoint(context, cx + minDim, cy); for (i = 0; i < n; i++) { angle += deltangle; CGContextAddLineToPoint(context, cx + r * cos(angle), cy + r * sin(angle)); angle += deltangle; CGContextAddLineToPoint(context, cx + minDim * cos(angle), cy + minDim * sin(angle)); } CGContextAddLineToPoint(context, cx + minDim, cy); } } CGContextClosePath(context); CGContextDrawPath(context, kCGPathFillStroke); status = noErr; ControlDrawExit: break; } #pragma mark * kEventControl___Changed case kEventControlValueFieldChanged: case kEventControlHiliteChanged: { // just asking for a refresh HIViewSetNeedsDisplay(myData->view, true); break; } default: break; } break; default: break; } return status; } // Internal_HICustomViewHandler
static OSStatus ResizeDemoWindow( EventRef inEvent, WindowRef windowRef ) { OSStatus err; Rect newBounds; Rect oldBounds; short newWidth; short newLength; HIViewRef myHIViewRef; // get the event parameter which will tell us the new size err = GetEventParameter( inEvent, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof( Rect ), NULL, &newBounds ); require_noerr( err, ResizeDemoWindow_err ); // get the old bounds, just to see if we don't need to draw anything err = GetEventParameter( inEvent, kEventParamPreviousBounds, typeQDRectangle, NULL, sizeof( Rect ), NULL, &oldBounds ); require_noerr( err, ResizeDemoWindow_err ); // calculate the new width and length newWidth = newBounds.right - newBounds.left; newLength = newBounds.bottom - newBounds.top; // check to see if we need to redraw. If this is a simple translation, // then we don't. if ( ( newLength != ( oldBounds.bottom - oldBounds.top ) ) || ( newWidth != ( oldBounds.right - oldBounds.left ) ) ) { DrawContextStruct *windowContext; CGrafPtr windowPort; // get the draw context struct from the window's refCon windowContext = (DrawContextStruct *) GetWRefCon( windowRef ); #if BUGWORKAROUNDS // get the window port windowPort = GetWindowPort( windowRef ); if (windowContext->cgContext == NULL) return err; // okay, so this is really, really lame. I'm going to get rid of // the current cg context and get a new one. This is because I // don't have the time right now to figure out how to synchronize the // clipping regions and such for the window and the context. This // is really bad, beacuse the text layout needs to have the new // cg context tag set in it, which will invalidate the layout. // I only need to dispose of the context each time until I figure // out what's going wrong with the Quickdraw clipping regions. // dispose of the context // make sure that the context is re-set in the ATSUI object if ( windowContext->layoutObject != NULL ) { ATSUAttributeTag tag = kATSUCGContextTag; ByteCount valueSize = sizeof( CGContextRef ); ATSUAttributeValuePtr valuePtr = &windowContext->cgContext; err = ATSUSetLayoutControls( windowContext->layoutObject, 1, &tag, &valueSize, &valuePtr ); require_noerr( err, ResizeDemoWindow_err ); } #endif // redraw the context HIViewFindByID(HIViewGetRoot(windowRef), myHIViewID, &myHIViewRef); HIViewSetNeedsDisplay( myHIViewRef, true); } ResizeDemoWindow_err: return eventNotHandledErr; }