bool wxMacSearchFieldControl::SetFocus() { // NB: We have to implement SetFocus a little differently because kControlFocusNextPart // leads to setting the focus on the search icon rather than the text area. // We get around this by explicitly telling the control to set focus to the // text area. OSStatus err = SetKeyboardFocus( GetControlOwner( m_controlRef ), m_controlRef, kControlEditTextPart ); if ( err == errCouldntSetFocus ) return false ; SetUserFocusWindow(GetControlOwner( m_controlRef ) ); return true; }
//----------------------------------------------------------------------------- // ¥ SetPushButtonDefaultState //----------------------------------------------------------------------------- // Sets a push button's default flag. This lets the button know whether or not // to draw its default ring. // OSStatus SetPushButtonDefaultState( ControlHandle control, Boolean isDefault ) { OSStatus err = noErr; if ( control == nil ) return paramErr; if (isDefault) err = SetWindowDefaultButton( GetControlOwner( control ), control ); else err = SetWindowDefaultButton( GetControlOwner( control ), nil ); // nil means clear the default button return err; }
/***************************************************** * * Handle_ControlValueFieldOrHiliteChanged(inHandlerCallRef, inEvent, inUserData) * * Purpose: called to handle the change of the value or hilite of our custom view, we update the static text field * * 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_ControlValueFieldOrHiliteChanged(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData) { OSStatus status; HIViewRef customView = (HIViewRef)inUserData; // Finding our static text control HIViewRef statText; status = HIViewFindByID(HIViewGetRoot(GetControlOwner(customView)), kStaticTextID, &statText); require_noerr(status, ExitValueFieldChanged); // Grabbing the fields that we are interested in CFStringRef theCFString = CFStringCreateWithFormat(NULL, NULL, CFSTR("Value: %ld, Min: %ld, Max: %ld, Hilite: %d"), GetControl32BitValue(customView), GetControl32BitMinimum(customView), GetControl32BitMaximum(customView), GetControlHilite(customView)); require(theCFString != NULL, ExitValueFieldChanged); // Setting the text in the control #ifdef MAC_OS_X_VERSION_10_4 status = HIViewSetText(statText, theCFString); #else status = SetControlData(statText, kControlEntireControl, kControlStaticTextCFStringTag, sizeof(theCFString), &theCFString); #endif require_noerr(status, ExitValueFieldChanged); CFRelease(theCFString); ExitValueFieldChanged: if (status == noErr) status = eventNotHandledErr; return status; } // Handle_ControlValueFieldOrHiliteChanged
/***************************************************** * * Handle_PostLittleArrowsClick(inHandlerCallRef, inEvent, inUserData) * * Purpose: called to update the static text with the current value of the little arrows control * * 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_PostLittleArrowsClick(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData) { OSStatus status = eventNotHandledErr; ControlRef littleArrows = (ControlRef)inUserData; SInt32 value = GetControl32BitValue(littleArrows); HIViewID staticTextID = { 'STTC', 100 }; HIViewRef staticText; status = HIViewFindByID(HIViewGetRoot(GetControlOwner(littleArrows)), staticTextID, &staticText); require_noerr(status, HIViewFindByID); require(littleArrows != NULL, HIViewFindByID); CFStringRef theValueStr = CFStringCreateWithFormat(NULL, NULL, CFSTR("%ld"), value); require(theValueStr != NULL, CFStringCreateWithFormat); HIViewSetText(staticText, theValueStr); CFRelease(theValueStr); CFStringCreateWithFormat: HIViewFindByID: if (status == noErr) status = eventNotHandledErr; return status; } // Handle_PostLittleArrowsClick
void OSXCarbonWindow::createWindowFromExternal(HIViewRef viewRef) { // TODO: The Control is going to report the incorrect location with a // Metallic / Textured window. The default windows work just fine. // First get the HIViewRef / ControlRef mView = viewRef; mWindow = GetControlOwner(mView); // Lets try hiding the HIView //HIViewSetVisible(mView, false); // Get the rect bounds ::Rect ctrlBounds; GetControlBounds(mView, &ctrlBounds); GLint bufferRect[4]; bufferRect[0] = ctrlBounds.left; // left edge bufferRect[1] = ctrlBounds.bottom; // bottom edge bufferRect[2] = ctrlBounds.right - ctrlBounds.left; // width of buffer rect bufferRect[3] = ctrlBounds.bottom - ctrlBounds.top; // height of buffer rect aglSetInteger(mAGLContext, AGL_BUFFER_RECT, bufferRect); aglEnable(mAGLContext, AGL_BUFFER_RECT); mIsExternal = true; }
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; }
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Name: MyPDEInitialize Input Parameters: context : The plugins context parentUserPane : the user pane to your your controls into ref : the reference to this PDE printSession : this holds the PM tickets Output Parameters: flags : feature flags that are supported by this PDE err : returns the error status Description: Initializes client interface. Creates controls and sets initial values Change History (most recent first): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ static OSStatus MyPDEInitialize( PMPDEContext context, PMPDEFlags* flags, PMPDERef ref, ControlRef parentUserPane, PMPrintSession printSession) { OSStatus err = noErr; PrintDialogPDEOnlyContextPtr myContext = NULL; // Pointer to our context data. DebugMessage("PrintDialogPDE MyPDEInitialize called\n"); myContext = (PrintDialogPDEOnlyContextPtr) context; if ((myContext != NULL) && (printSession != NULL)) { WindowRef theWindow = NULL; short savedResFile = CurResFile(); UseResFile(myContext->theResFile); theWindow = GetControlOwner(parentUserPane); // get the windowref from the user pane // the user panes rect is the rect we should use to draw our // controls into. The printing system calculates the user pane // size based on the maxh and maxv sizes returned from the // Prologue function // Note that we are using the AutoToggleProc variant of the Radio Button control // This allows a hit on this control to be automatically processed by the ControlMgr // get controls myContext->thePrintSelTextOnlyControlRef = GetNewControl(kPrintDialogPDEControlID, theWindow); // embed controls EmbedControl(myContext->thePrintSelTextOnlyControlRef, parentUserPane); // set controls as visible SetControlVisibility(myContext->thePrintSelTextOnlyControlRef, true, false); // Set default value SetControlValue(myContext->thePrintSelTextOnlyControlRef, 0); // Set flags *flags = kPMPDENoFlags; // Initialize this plugins controls based on the information in the // PageSetup or PrintSettings ticket. err = MyPDESync(context, printSession, kSyncDirectionSetUserInterface); if (err == kPMKeyNotFound) err = noErr; UseResFile(savedResFile); } else err = kPMInvalidPDEContext; DebugPrintErr(err, "PrintDialogPDE Error from MyPDEInitialize returned %d\n"); return (err); }
// In this implementation, the control refs are stored in an array, and a pointer // to the start of the array is stored in the mlteUserData item. We provide // accessor functions to get the scroll control refs out of the mlteUserData // so that we could change the method of storing them without affecting this // function. void MyMLTEScrollInfoCallback( SInt32 value, SInt32 max, TXNScrollBarOrientation orientation, SInt32 mlteUserData) { OSStatus status; ControlRef vScrollControlRef, hScrollControlRef; if( orientation == kTXNVertical ) { vScrollControlRef = MLTEUserDataGetVerticalScrollBar( mlteUserData ); if( vScrollControlRef != NULL ) status = ControlUpdateValues( vScrollControlRef, value, max ); TextViewSetVertScrollCache( GetControlOwner( vScrollControlRef ), value, kMyMLTEDataStructProperty ); } else if ( orientation == kTXNHorizontal ) { hScrollControlRef = MLTEUserDataGetHorizontalScrollBar( mlteUserData ); if( hScrollControlRef != NULL ) status = ControlUpdateValues( hScrollControlRef, value, max ); TextViewSetHorizScrollCache( GetControlOwner( hScrollControlRef ), value, kMyMLTEDataStructProperty); } }
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); }
static void HIOpenGLViewSetContextWindowAndBounds (HIOpenGLViewData* inData) { if (inData == nil) return; if (inData->mControl == nil) return; if (inData->mContext == nil) return; // Determine the AGL_BUFFER_RECT for the control. The coordinate // system for this rectangle is relative to the owning window, with // the origin at the bottom left corner and the y-axis inverted. HIRect ctrlBounds, winBounds; HIViewGetBounds(inData->mControl, &ctrlBounds); WindowRef window = GetControlOwner(inData->mControl); ControlRef root = nil; GetRootControl(window, &root); HIViewGetBounds(root, &winBounds); HIViewConvertRect(&ctrlBounds, inData->mControl, root); GLint bufferRect[4] = { (int)ctrlBounds.origin.x, (int)((winBounds.size.height) - (ctrlBounds.origin.y + ctrlBounds.size.height)), (int)ctrlBounds.size.width, (int)ctrlBounds.size.height }; // Associate the OpenGL context with the control's window, and establish the buffer rect. aglSetDrawable(inData->mContext, GetWindowPort(window)); aglSetInteger(inData->mContext, AGL_BUFFER_RECT, bufferRect); aglEnable(inData->mContext, AGL_BUFFER_RECT); // Establish the clipping region for the OpenGL context. To properly handle clipping // within the view hierarchy, I'm walking the hierarchy to determine the intersection // of this view's bounds with its parents. Is there an easier way to do this? CGRect clipBounds = ctrlBounds; HIViewRef parent = HIViewGetSuperview(inData->mControl); while (parent != root) { CGRect parentBounds; HIViewGetBounds(parent, &parentBounds); HIViewConvertRect(&parentBounds, parent, root); clipBounds = CGRectIntersection(clipBounds, parentBounds); parent = HIViewGetSuperview(parent); } Rect rgnBounds = { (int)clipBounds.origin.y, (int)clipBounds.origin.x, (int)(clipBounds.origin.y + clipBounds.size.height), (int)(clipBounds.origin.x + clipBounds.size.width) }; RgnHandle rgn = NewRgn(); RectRgn(rgn, &rgnBounds); aglSetInteger(inData->mContext, AGL_CLIP_REGION, (const GLint*)rgn); aglEnable(inData->mContext, AGL_CLIP_REGION); }
void TActiveScroller::IndicatorProc(Point origPoint) { #if TARGET_API_MAC_CARBON==1 UPortSaver safe(GetControlOwner(scrollBar)); #else UPortSaver safe((**scrollBar).contrlOwner); #endif Point lastPoint,currentPoint; short value; short originalValue=GetScrollBarValue(); // While we're tracking the thumb, we're calculating its value based // on the current mouse location. That works great, assuming you // clicked _exactly_ in the center of the thumb. We calculate how // much we need to compensate the value caluculations based on the // click distance from the center of the thumb. valueSlop=0; // Important as the valueSlop is used in the CalcScrollBarValueFromPoint proc valueSlop=originalValue-CalcScrollBarValueFromPoint(origPoint); currentPoint=lastPoint=origPoint; while (StillDown()) { // Only attempt to update the value if the mouse moved. GetMouse(¤tPoint); if (EqualPt(currentPoint,lastPoint)) continue; // Remeber where the last mouse location was lastPoint=currentPoint; // Check to see if the user tracked outside of the slop rect. // If they did, restore the original value of the control. // This mimics the same behaviour as the standard scroll bar. if (FPointInRect(currentPoint,trackRect)) value=CalcScrollBarValueFromPoint(currentPoint); else value=originalValue; value=Limit(value,::GetControlMinimum(scrollBar),::GetControlMaximum(scrollBar)); SetScrollBarValue(value); } }
Boolean TActiveScroller::HandleMouseClick(Point inPoint) { #if TARGET_API_MAC_CARBON==1 UPortSaver safe(GetControlOwner(scrollBar)); #else UPortSaver safe((**scrollBar).contrlOwner); #endif short partCode; if (partCode=TestControl(scrollBar,inPoint)) { switch (partCode) { case kControlUpButtonPart: case kControlDownButtonPart: case kControlPageDownPart: case kControlPageUpPart: case kControlIndicatorPart: SetupScroll(); if (partCode==kControlIndicatorPart) { // Dim the thumb HiliteControl(scrollBar,kControlIndicatorPart); IndicatorProc(inPoint); // Undim the thumb HiliteControl(scrollBar,kControlNoPart); } else { // Must call this to pass the current object to the tracking proc SetTrackingObject(this); TrackControl(scrollBar,inPoint,scrollBarProcUPP); } ShutdownScroll(); return true; break; } } return false; // missed the scroll bar }
/***************************************************** * * Handle_TextInputEvent(inHandlerCallRef, inEvent, inUserData) * * Purpose: called to intercept keystrokes which are destined for a control * * 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_TextInputEvent(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData) { OSStatus status; UniChar ch = 0; status = GetEventParameter(inEvent, kEventParamTextInputSendText, typeUnicodeText, NULL, sizeof(ch), NULL, &ch); require_noerr(status, ExitTextInput); if ((ch == kReturnCharCode) || (ch == kEnterCharCode)) { // // we got return or enter so we validate the edit text control by sending a command // EventRef theEvent; CreateEvent(NULL, kEventClassCommand, kEventCommandProcess, GetCurrentEventTime(), kEventAttributeUserEvent, &theEvent); HICommandExtended theCommand; theCommand.attributes = kHICommandFromControl; theCommand.commandID = 'SVet'; theCommand.source.control = (ControlRef)inUserData; SetEventParameter(theEvent, kEventParamDirectObject, typeHICommand, sizeof(theCommand), &theCommand); SendEventToEventTarget(theEvent, GetWindowEventTarget(GetControlOwner((ControlRef)inUserData))); ReleaseEvent(theEvent); status = noErr; } if ( ((ch >= '0') && (ch <= '9')) || (ch == kBackspaceCharCode) || (ch == kLeftArrowCharCode) || (ch == kRightArrowCharCode) || (ch == kUpArrowCharCode) || (ch == kDownArrowCharCode) ) status = eventNotHandledErr; else status = noErr; ExitTextInput: return status; } // Handle_TextInputEvent
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; }
void TkpDisplayScrollbar( ClientData clientData) /* Information about window. */ { TkScrollbar *scrollPtr = (TkScrollbar *) clientData; MacScrollbar *macScrollPtr = (MacScrollbar *) clientData; Tk_Window tkwin = scrollPtr->tkwin; MacDrawable *macDraw; CGrafPtr saveWorld; GDHandle saveDevice; GWorldPtr destPort; WindowRef windowRef; if ((scrollPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) { goto done; } /* * Draw the focus or any 3D relief we may have. */ if (scrollPtr->highlightWidth != 0) { GC fgGC, bgGC; bgGC = Tk_GCForColor(scrollPtr->highlightBgColorPtr, Tk_WindowId(tkwin)); if (scrollPtr->flags & GOT_FOCUS) { fgGC = Tk_GCForColor(scrollPtr->highlightColorPtr, Tk_WindowId(tkwin)); TkpDrawHighlightBorder(tkwin, fgGC, bgGC, scrollPtr->highlightWidth, Tk_WindowId(tkwin)); } else { TkpDrawHighlightBorder(tkwin, bgGC, bgGC, scrollPtr->highlightWidth, Tk_WindowId(tkwin)); } } Tk_Draw3DRectangle(tkwin, Tk_WindowId(tkwin), scrollPtr->bgBorder, scrollPtr->highlightWidth, scrollPtr->highlightWidth, Tk_Width(tkwin) - 2*scrollPtr->highlightWidth, Tk_Height(tkwin) - 2*scrollPtr->highlightWidth, scrollPtr->borderWidth, scrollPtr->relief); /* * Set up port for drawing Macintosh control. */ macDraw = (MacDrawable *) Tk_WindowId(tkwin); destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin)); GetGWorld(&saveWorld, &saveDevice); SetGWorld(destPort, NULL); TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin)); if (macScrollPtr->sbHandle == NULL) { Rect r; SInt16 initialValue; SInt16 minValue; SInt16 maxValue; SInt16 procID; WindowRef frontNonFloating; r.left = r.top = 0; r.right = r.bottom = 1; minValue = MIN_SCROLLBAR_VALUE; maxValue = MAX_SCROLLBAR_VALUE; initialValue = (minValue + maxValue)/2; procID = kControlScrollBarLiveProc; windowRef = GetWindowFromPort(destPort); CreateScrollBarControl(windowRef, &r, initialValue, minValue, maxValue, maxValue - minValue, true, NULL, &(macScrollPtr->sbHandle)); SetControlReference(macScrollPtr->sbHandle, (SInt32) scrollPtr); /* * If we are foremost then make us active. */ frontNonFloating = FrontNonFloatingWindow(); if ((windowRef == FrontWindow()) || TkpIsWindowFloating(windowRef)) { macScrollPtr->macFlags |= ACTIVE; } } /* * Adjust the control size based on its width... */ if (macScrollPtr->info.width < 13) { SetControlData(macScrollPtr->sbHandle, kControlNoPart, kControlSizeTag, sizeof(kControlSizeSmall), (void *) kControlSizeSmall); } else { SetControlData(macScrollPtr->sbHandle, kControlNoPart, kControlSizeTag, sizeof(kControlSizeSmall), (void *) kControlSizeLarge); } /* * Update the control values before we draw. */ windowRef = GetControlOwner (macScrollPtr->sbHandle); UpdateControlValues(macScrollPtr); if (macScrollPtr->macFlags & ACTIVE) { Draw1Control(macScrollPtr->sbHandle); if (macScrollPtr->macFlags & DRAW_GROW) { DrawGrowIcon(windowRef); } } else { HiliteControl (macScrollPtr->sbHandle, 255 ); Draw1Control(macScrollPtr->sbHandle); if (macScrollPtr->macFlags & DRAW_GROW) { DrawGrowIcon(windowRef); Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), scrollPtr->bgBorder, Tk_Width(tkwin) - 13, Tk_Height(tkwin) - 13, Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT); } } SetGWorld(saveWorld, saveDevice); done: scrollPtr->flags &= ~REDRAW_PENDING; }
/***************************************************** * * Do_NewWindow() * * Purpose: called to create a new window that has been constructed with Interface Builder * * Inputs: none * * Returns: OSStatus - error code (0 == no error) */ OSStatus Do_NewWindow(void) { OSStatus status; static IBNibRef gIBNibRef = NULL; WindowRef aWindowRef = NULL; CFStringRef theTitle = NULL; CFMutableStringRef theNewTitle = NULL; if (gIBNibRef == NULL) { // Create a Nib reference passing the name of the nib file (without the .nib extension) // CreateNibReference only searches into the application bundle. status = CreateNibReference(CFSTR("main"), &gIBNibRef); require_noerr(status, CantGetNibRef); } require(gIBNibRef != NULL, CantGetNibRef); // Create a window. "MainWindow" is the name of the window object. This name is set in // InterfaceBuilder when the nib is created. status = CreateWindowFromNib(gIBNibRef, CFSTR("MainWindow"), &aWindowRef); require_noerr(status, CantCreateWindow); require(NULL != aWindowRef, CantCreateWindow); // Grab the title of the window and add the window count to it status = CopyWindowTitleAsCFString(aWindowRef, &theTitle); require_noerr(status, CantGetSetTitle); theNewTitle = CFStringCreateMutableCopy(NULL, 0, theTitle); require(NULL != theNewTitle, CantGetSetTitle); CFStringAppendFormat(theNewTitle, NULL, CFSTR(" %ld"), ++gWindowCount); status = SetWindowTitleWithCFString(aWindowRef, theNewTitle); require_noerr(status, CantGetSetTitle); // Create the custom view to be tested and embed it in our group box control HIViewRef groupBox; status = HIViewFindByID(HIViewGetRoot(aWindowRef), kGroupBoxID, &groupBox); require_noerr(status, CantFindGroupBox); require(groupBox != NULL, CantFindGroupBox); HIViewRef customView; status = HICreateCustomView(NULL, &customView); require_noerr(status, CantCreateCustom); require(customView != NULL, CantCreateCustom); HIRect groupBoxBounds; HIViewGetBounds(groupBox, &groupBoxBounds); groupBoxBounds.origin.x += 20; groupBoxBounds.origin.y += 34; groupBoxBounds.size.width -= 40; groupBoxBounds.size.height -= 54; HIViewSetFrame(customView, &groupBoxBounds); HIViewSetLayoutInfo(customView, &kBindToParentLayout); status = HIViewAddSubview(groupBox, customView); require_noerr(status, CantAddSubview); HIViewSetVisible(customView, true); // Let's react to User's commands. EventTypeSpec eventTypeCP = {kEventClassCommand, kEventCommandProcess}; status = InstallWindowEventHandler(aWindowRef, Handle_WindowCommandProcess, 1, &eventTypeCP, (void *)customView, NULL); require_noerr(status, CantInstallEventHandler); // Let's update our static text field whenever the value or hilite of our tested custom view changes EventTypeSpec eventTypeCVFC[] = { {kEventClassControl, kEventControlValueFieldChanged}, {kEventClassControl, kEventControlHiliteChanged} }; status = InstallControlEventHandler(customView, Handle_ControlValueFieldOrHiliteChanged, 2, eventTypeCVFC, (void *)customView, NULL); require_noerr(status, CantInstallEventHandler); // We accept only numbers in our Edit text control HIViewRef editText; HIViewFindByID(HIViewGetRoot(GetControlOwner(customView)), kSetValueEditID, &editText); #ifdef MAC_OS_X_VERSION_10_4 // in Tiger, only 1 event handler is necessary for the key filtering EventTypeSpec eventTypeTSCIR = {kEventClassTextField, kEventTextShouldChangeInRange}; status = InstallControlEventHandler(editText, Handle_TextShouldChangeInRange, 1, &eventTypeTSCIR, (void *)editText, NULL); require_noerr(status, CantInstallEventHandler); #else // pre-Tiger, we need a different event handler and a validation proc to handle pastes and drops. ControlEditTextValidationUPP textValidation = MyValidationProc; SetControlData(editText, kControlEntireControl, kControlEditTextValidationProcTag, sizeof(textValidation), &textValidation); EventTypeSpec eventTypeTIUFKE = {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent}; status = InstallControlEventHandler(editText, Handle_TextInputEvent, 1, &eventTypeTIUFKE, (void *)editText, NULL); require_noerr(status, CantInstallEventHandler); #endif // Finishing the custom view setup SetControl32BitMinimum(customView, 0); SetControl32BitMaximum(customView, 36); SetControl32BitValue(customView, 2); // We want window and thus our custom view to be able to respond to drops status = SetAutomaticControlDragTrackingEnabledForWindow(aWindowRef, true); require_noerr(status, SetAutomaticControlDragTrackingEnabledForWindow); ShowWindow(aWindowRef); SetWindowModified(aWindowRef, false); SetAutomaticControlDragTrackingEnabledForWindow: SetControlDragTrackingEnabled: CantAddSubview: CantCreateCustom: CantFindGroupBox: CantInstallEventHandler: CantGetSetTitle: CantAllocateWindowData: CantCreateWindow: CantGetNibRef: if (theTitle != NULL) CFRelease(theTitle); if (theNewTitle != NULL) CFRelease(theNewTitle); return status; } // Do_NewWindow
/***************************************************** * * 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
// Tracking the mouse in a scroll control via callback void MyTrackActionProcedure( ControlRef controlRef, ControlPartCode partCode ) { OSStatus status; SInt32 value; SInt32 textViewDelta, controlDelta, controlMin, controlMax; TXNScrollUnit scrollUnits; ControlID controlID = {0,0}; WindowRef window = NULL; // when user clicks on kControlPageUpPart or kControlPageDownPart // we need to know the viewRect height and width so we can update // the scrollbars with a delta of "one page" scrolled SInt32 viewHeight = 0; SInt32 viewWidth = 0; scrollUnits = kTXNScrollUnitsInPixels; textViewDelta = controlDelta = 0; // the controlID will tell us if it is a v or h scroller // based on the arbitrary signature we assigned it in the nib (Hscr or Vscr) status = GetControlID( controlRef, &controlID ); require_noerr( status, CantGetControlID ); // the window has cached scroll data we need, so we need to get the window window = GetControlOwner( controlRef ); require( window != NULL, CantGetWindow ); value = GetControl32BitValue( controlRef ); controlMin = GetControl32BitMinimum( controlRef ); controlMax = GetControl32BitMaximum( controlRef ); // calc view width or height ( for page up/down/left/right ) if( controlID.signature == kMyVerticalScrollBar ) viewHeight = TextViewGetHeight( window, kMyMLTEDataStructProperty ); else viewWidth = TextViewGetWidth( window, kMyMLTEDataStructProperty ); // which part of the scroll control was hit? switch ( partCode ) { case kControlDownButtonPart: textViewDelta = controlDelta = 1; scrollUnits = kTXNScrollUnitsInPixels; //kTXNScrollUnitsInLines; break; case kControlUpButtonPart: textViewDelta = controlDelta = -1; scrollUnits = kTXNScrollUnitsInPixels; //kTXNScrollUnitsInLines; break; case kControlPageUpPart: textViewDelta = -1; // units in viewRectHeight/Width(s) if( controlID.signature == kMyVerticalScrollBar ) controlDelta = ( viewHeight <= kMyINT32_MAX ? viewHeight : kMyINT32_MAX ); else controlDelta = ( viewWidth <= kMyINT32_MAX ? viewWidth : kMyINT32_MAX ); scrollUnits = kTXNScrollUnitsInViewRects; controlDelta = -controlDelta; break; case kControlPageDownPart: textViewDelta = 1; // units in viewRectHeight/Width(s) if( controlID.signature == kMyVerticalScrollBar ) controlDelta = ( viewHeight <= kMyINT32_MAX ? viewHeight : kMyINT32_MAX ); else controlDelta = ( viewWidth <= kMyINT32_MAX ? viewWidth : kMyINT32_MAX ); scrollUnits = kTXNScrollUnitsInViewRects; break; // we really do not want to do anything if the // kControlIndicatorPart is hit. It should be // handled by the Live Tracking procedure instead. case kControlIndicatorPart: { SInt32 cacheValue = 0; scrollUnits = kTXNScrollUnitsInPixels; // Which scrollbar is getting called by this callback? if( controlID.signature == kMyVerticalScrollBar ) { // we can find the degree of the change by comparing to // our last known value cacheValue = TextViewGetVertScrollCache( window, kMyMLTEDataStructProperty ); textViewDelta = value - (cacheValue <= kMyINT32_MAX ? cacheValue : kMyINT32_MAX ); } else // kMyHorizontalScrollBar { // we can find the degree of the change by comparing to // our last known value cacheValue = TextViewGetHorizScrollCache( window, kMyMLTEDataStructProperty ); textViewDelta = value - (cacheValue <= kMyINT32_MAX ? cacheValue : kMyINT32_MAX ); } } break; default: break; } if ( partCode != kControlIndicatorPart ) // only update the control for non-thumb hits { value += controlDelta; if( value < controlMin ) // don't go past max or min value = controlMin; if( value > controlMax ) value = controlMax; SetControl32BitValue( controlRef, value ); } status = TextViewCustomScroll( window, controlID.signature, scrollUnits, textViewDelta, value, kMyMLTEDataStructProperty ); CantGetWindow: CantGetControlID: return; }
/***************************************************** * * MPWindowEventHandlerProc ( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData ) * * Purpose: Window event handling routine * * Returns: OSStatus - eventNotHandledErr to allow other EventHandlers to run */ static pascal OSStatus MPWindowEventHandlerProc( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData ) { #pragma unused ( inCallRef, inUserData ) LongDateRec lDate; LongDateTime lSecs; unsigned long secs; ControlRef dateControl; WindowRef window; struct kevent kev; HICommand command; FSRef fsRef; CFURLRef urlRef = NULL; CFURLRef fullUrlRef = NULL; OSStatus err = eventNotHandledErr; UInt32 eventKind = GetEventKind( inEvent ); UInt32 eventClass = GetEventClass( inEvent ); switch ( eventClass ) { case kEventClassMP: if ( eventKind == kEventKQueue ) { // When we receive the kEventKQueue event, we update the date control associated with the path we are watching. GetEventParameter( inEvent, kEventParamDirectObject, typeKEvent, NULL, sizeof(struct kevent), NULL, &kev ); GetEventParameter( inEvent, kEventParamControlRef, typeControlRef, NULL, sizeof(ControlRef), NULL, &dateControl ); GetDateTime( &secs ); lSecs = secs; LongSecondsToDate( &lSecs, &lDate ); (void) SetControlData( dateControl, 0, kControlClockLongDateTag, sizeof(lDate), &lDate ); Draw1Control( dateControl ); PrintKEvent( GetControlOwner( dateControl ) , &kev ); // Display the kevent information } break; case kEventClassWindow: if ( eventKind == kEventWindowClose ) { GetEventParameter( inEvent, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef), NULL, &window ); ((MyMPTaskInfo*)GetWRefCon( window ))->done = true; // Flag the thread to terminate (thread checks at least every 30 seconds in this sample) } break; case kEventClassCommand: GetEventParameter( inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &command ); if ( eventKind == kEventCommandProcess ) { if ( command.commandID == 'Help' ) // Our 'Help' command, just have LaunchServices open the "kqueue.pdf" file within our bundle. { urlRef = CFBundleCopyResourcesDirectoryURL( CFBundleGetMainBundle() ); fullUrlRef = CFURLCreateCopyAppendingPathComponent( NULL, urlRef, CFSTR("kqueue.pdf"), false ); CFURLGetFSRef( fullUrlRef, &fsRef ); (void) LSOpenFSRef( &fsRef, NULL ); // Open the file if ( urlRef != NULL ) CFRelease( urlRef ); if ( urlRef != NULL ) CFRelease( fullUrlRef ); } } break; } return( err ); }
/* Event handler for the content view that gets attached to the menu frame. The content view will (eventually) contain the menu view. */ OSStatus ContentViewEventHandler( EventHandlerCallRef inCallRef, EventRef inEvent, void *refcon) { OSStatus retVal = eventNotHandledErr; if(GetEventClass(inEvent) == kEventClassMenu) { return noErr; } else if(GetEventClass(inEvent) == kEventClassControl) { HIViewRef hiSelf = NULL; verify_noerr(GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(hiSelf), NULL, &hiSelf)); if(hiSelf) { HIRect frame; HIViewGetFrame(hiSelf, &frame); switch(GetEventKind(inEvent)) { case kEventControlAddedSubControl : { HIViewRef subControl; ControlID subControlID; GetEventParameter(inEvent, kEventParamControlSubControl, typeControlRef, NULL, sizeof(subControl), NULL, &subControl ); GetControlID(subControl, &subControlID); // This should be comparing against kHIViewMenuContentID as shown inside the // #if 0. At the time of this writing, however, using that constant causes a // linker error (and a crash if you use ZeroLink). I extracted the signature // and id by determining the value at run-time the value I compare against. #if 0 if( kHIViewMenuContentID.signature == subControlID.signature && kHIViewMenuContentID.id == subControlID.id ) { #else if( 'menu' == subControlID.signature && 0 == subControlID.id ) { #endif // If we have the menu content view then set up some view bindings for it. HIRect bounds; HIViewGetBounds(hiSelf, &bounds); HIViewSetFrame(subControl, &bounds); HILayoutInfo contentLayout = { kHILayoutInfoVersionZero, { { NULL, kHILayoutBindTop }, { NULL, kHILayoutBindLeft }, { NULL, kHILayoutBindBottom }, { NULL, kHILayoutBindRight } }, { { NULL, kHILayoutScaleAbsolute, 0 }, { NULL, kHILayoutScaleAbsolute, 0 } }, { { NULL, kHILayoutPositionTop, 0 }, { NULL, kHILayoutPositionLeft, 0 } } }; verify_noerr(HIViewSetLayoutInfo(subControl, &contentLayout)); } retVal = noErr; } break; case kEventControlGetFrameMetrics : HIViewFrameMetrics metrics; // The offset from the frame view to the content view is // given by the kFrameOffset constant metrics.top = kFrameOffset; metrics.left = kFrameOffset; metrics.right = kFrameOffset; metrics.bottom = kFrameOffset; verify_noerr(SetEventParameter(inEvent, kEventParamControlFrameMetrics, typeControlFrameMetrics, sizeof(metrics), &metrics)); retVal = noErr; break; case kEventControlBoundsChanged : case kEventControlOwningWindowChanged : { // Maintain the QuickDraw port by changing its position to // match that of the content view. CGrafPtr windowPort = NULL; WindowRef window = GetControlOwner(hiSelf); if(window && (windowPort = GetWindowPort(window))) { CGrafPtr savePort; bool swapped = QDSwapPort(windowPort, &savePort); MovePortTo((short) frame.origin.x, (short) frame.origin.y); PortSize((short) frame.size.width, (short) frame.size.height); if(swapped) { QDSwapPort(savePort, NULL); } } retVal = noErr; } break; } // switch } // if (hiSelf) } return retVal; } /* ------------------------------------------ CreatePathForEntireStarMenu */ /* Create a path shape for the star frame. This looks an awful lot like CreatePathForEntireStarMenu in StarMenu.cpp but takes the radius to use as a parameter and then takes into account the kFrameOffest when creating the path. In true Core Foundation style, this is a CreateXXX routine and the caller is responsible for freeing the path that is returned. */ CGPathRef CreatePathForStarFrame(StarFrameData *menuData, float radius) { CGMutablePathRef retVal = CGPathCreateMutable(); MenuItemIndex numItems = CountMenuItems(menuData->menu); if(numItems > 0) { const CGPoint fullRadiusPoint = { radius, 0 }; const CGPoint halfRadiusPoint = { ((radius - kFrameOffset) / 2.0) + kFrameOffset , 0 }; float anglePerItem = 2 * pi / (float)numItems; // in radians naturally float halfAngle = anglePerItem / 2.0; CGPoint startPoint = halfRadiusPoint; CGAffineTransform midRotate = CGAffineTransformMakeRotation(halfAngle); CGPoint midPoint = CGPointApplyAffineTransform(fullRadiusPoint, midRotate); CGAffineTransform rotateToNext = CGAffineTransformMakeRotation(anglePerItem); CGPathMoveToPoint(retVal, NULL, startPoint.x, startPoint.y); CGPathAddLineToPoint(retVal, NULL, midPoint.x, midPoint.y); for(short ctr = 0; ctr < numItems; ctr++) { startPoint = CGPointApplyAffineTransform(startPoint, rotateToNext); midPoint = CGPointApplyAffineTransform(midPoint, rotateToNext); CGPathAddLineToPoint(retVal, NULL, startPoint.x, startPoint.y); CGPathAddLineToPoint(retVal, NULL, midPoint.x, midPoint.y); } CGPathCloseSubpath(retVal); } return retVal; }
extern OSStatus MyEmbedCustomControls ( MyCustomContext context, WindowRef nibWindow, ControlRef userPane ) { static const ControlID containerControlID = { kMozPDECreatorCode, 4000 }; static const ControlID radioGroupControlID = { kMozPDECreatorCode, 4001 }; static const ControlID printSelCheckControlID = { kMozPDECreatorCode, 4002 }; static const ControlID shrinkToFitCheckControlID = { kMozPDECreatorCode, 4003 }; static const ControlID printBGColorsCheckControlID = { kMozPDECreatorCode, 4004 }; static const ControlID printBGImagesCheckControlID = { kMozPDECreatorCode, 4005 }; static const ControlID headerLeftPopupControlID = { kMozPDECreatorCode, 4006 }; static const ControlID headerCenterPopupControlID = { kMozPDECreatorCode, 4007 }; static const ControlID headerRightPopupControlID = { kMozPDECreatorCode, 4008 }; static const ControlID footerLeftPopupControlID = { kMozPDECreatorCode, 4009 }; static const ControlID footerCenterPopupControlID = { kMozPDECreatorCode, 4010 }; static const ControlID footerRightPopupControlID = { kMozPDECreatorCode, 4011 }; OSStatus result = noErr; if (context != NULL) { ControlHandle paneControl = NULL; // The control we're embedding into the given // userPane is itself a user pane control. result = MyEmbedControl(nibWindow, userPane, &containerControlID, &paneControl); if (paneControl) { WindowRef controlOwner = GetControlOwner(paneControl); GetControlByID(controlOwner, &radioGroupControlID, &(context->controls.frameRadioGroup)); if (context->controls.frameRadioGroup != NULL) { // It doesn't seem to be possible to specify the titles of the // radio buttons within a radio group control, so do it by hand :-/ // This is not done as a loop, but instead using CFSTR("abc") so // that genstrings can grok this file. Maybe that's not worth it? CFStringRef radioTitle; ControlRef radioControl; if (GetIndexedSubControl(context->controls.frameRadioGroup, kFramesAsLaidOutIndex, &radioControl) == noErr) { radioTitle = CFCopyLocalizedStringFromTableInBundle( CFSTR("As laid out on the screen"), CFSTR("Localizable"), MyGetBundle(), "top radio title"); if (radioTitle) { SetControlTitleWithCFString(radioControl, radioTitle); CFRelease(radioTitle); } } if (GetIndexedSubControl(context->controls.frameRadioGroup, kFramesSelectedIndex, &radioControl) == noErr) { radioTitle = CFCopyLocalizedStringFromTableInBundle( CFSTR("The selected frame"), CFSTR("Localizable"), MyGetBundle(), "middle radio title"); if (radioTitle) { SetControlTitleWithCFString(radioControl, radioTitle); CFRelease(radioTitle); } } if (GetIndexedSubControl(context->controls.frameRadioGroup, kFramesEachSeparatelyIndex, &radioControl) == noErr) { radioTitle = CFCopyLocalizedStringFromTableInBundle( CFSTR("Each frame separately"), CFSTR("Localizable"), MyGetBundle(), "bottom radio title"); if (radioTitle) { SetControlTitleWithCFString(radioControl, radioTitle); CFRelease(radioTitle); } } } GetControlByID(controlOwner, &printSelCheckControlID, &(context->controls.printSelCheck)); GetControlByID(controlOwner, &shrinkToFitCheckControlID, &(context->controls.shrinkToFitCheck)); GetControlByID(controlOwner, &printBGColorsCheckControlID, &(context->controls.printBGColorsCheck)); GetControlByID(controlOwner, &printBGImagesCheckControlID, &(context->controls.printBGImagesCheck)); GetControlByID(controlOwner, &headerLeftPopupControlID, &(context->controls.headerLeftPopup)); GetControlByID(controlOwner, &headerCenterPopupControlID, &(context->controls.headerCenterPopup)); GetControlByID(controlOwner, &headerRightPopupControlID, &(context->controls.headerRightPopup)); GetControlByID(controlOwner, &footerLeftPopupControlID, &(context->controls.footerLeftPopup)); GetControlByID(controlOwner, &footerCenterPopupControlID, &(context->controls.footerCenterPopup)); GetControlByID(controlOwner, &footerRightPopupControlID, &(context->controls.footerRightPopup)); // Now that the controls are in, sync with data. SyncPaneFromSettings(context); } } return result; }
/***************************************************** * * Handle_TextShouldChangeInRange(inHandlerCallRef, inEvent, inUserData) * * Purpose: called to intercept text changes which are destined for a text control * * 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_TextShouldChangeInRange(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData) { OSStatus status; CFStringRef theCFString = NULL; status = GetEventParameter(inEvent, kEventParamCandidateText, typeCFStringRef, NULL, sizeof(theCFString), NULL, &theCFString); require_noerr(status, ExitShouldChange); require_action(theCFString != NULL, ExitShouldChange, status = userCanceledErr); UniChar *buffer = NULL; CFIndex i, j, len = CFStringGetLength(theCFString); if (len == 0) goto ExitShouldChange; // there's nothing to filter // Grabbing the characters as Unicode chars buffer = (UniChar *)malloc(len * sizeof(UniChar)); require(buffer != NULL, ExitShouldChange); CFStringGetCharacters(theCFString, CFRangeMake(0, len), buffer); // Checking if we just have the return code if ((len == 1) && (buffer[0] == kReturnCharCode)) { EventRef theEvent; CreateEvent(NULL, kEventClassCommand, kEventCommandProcess, GetCurrentEventTime(), kEventAttributeUserEvent, &theEvent); HICommandExtended theCommand; theCommand.attributes = kHICommandFromControl; theCommand.commandID = 'SVet'; theCommand.source.control = (ControlRef)inUserData; SetEventParameter(theEvent, kEventParamDirectObject, typeHICommand, sizeof(theCommand), &theCommand); SendEventToEventTarget(theEvent, GetWindowEventTarget(GetControlOwner((ControlRef)inUserData))); ReleaseEvent(theEvent); // we don't want the return character to be added to the text so we abort the input status = userCanceledErr; } else { // Checking to see if we have only digits Boolean ok = true; for (i = 0; (i < len) && ok; i++) ok = (buffer[i] >= '0') && (buffer[i] <= '9'); if (!ok) { // if not, we remove the offending characters for (i = 0, j = 0; i < len; i++) if ((buffer[i] >= '0') && (buffer[i] <= '9')) buffer[j++] = buffer[i]; if (j == 0) // not a single digit in the candidate text, we abort the inout status = userCanceledErr; else { theCFString = CFStringCreateWithCharacters(NULL, buffer, j); require_action(theCFString != NULL, ExitShouldChange, status = userCanceledErr); status = SetEventParameter(inEvent, kEventParamReplacementText, typeCFStringRef, sizeof(theCFString), &theCFString); require_noerr(status, ExitShouldChange); // if we reach here, status is already set to noErr so we don't set it again } } else // only digits, we just let the HIToolbox do its job status = eventNotHandledErr; } ExitShouldChange: if (buffer != NULL) free(buffer); return status; } // Handle_TextShouldChangeInRange
OSStatus YASTControlAttachToExistingControl(ControlRef theControl) { OSStatus err; YASTControlVars *varsp; UInt32 outCommandID; EventHandlerRef controlEvents, windowEvents; TXNObject theTXNObject; RgnHandle outlineRegion; /* set up our locals */ controlEvents = windowEvents = NULL; theTXNObject = NULL; outlineRegion = NULL; varsp = NULL; err = noErr; /* allocate our private storage and set up initial settings*/ varsp = (YASTControlVars *) malloc(sizeof(YASTControlVars)); if (varsp == NULL) { err = memFullErr; } else { varsp->fInFocus = false; varsp->fIsActive = true; varsp->fTXNObjectActive = false; varsp->fControl = theControl; varsp->fTabMovesFocus = true; varsp->fDrawFocusBox = true; varsp->fFocusDrawState = false; varsp->fIsReadOnly = false; varsp->fRTextOutlineRegion = NULL; varsp->fWindow = GetControlOwner(theControl); varsp->fGrafPtr = GetWindowPort(varsp->fWindow); } /* set our control's command id. we don't actually use it, but it must be non-zero for our control to be sent command events. only set it if it has not already been set. */ err = GetControlCommandID(theControl, &outCommandID); if (err == noErr) { if (outCommandID == 0) { err = SetControlCommandID(theControl, 1); } } /* calculate the rectangles used by the control */ if (err == noErr) { outlineRegion = NewRgn(); if (outlineRegion == NULL) { err = memFullErr; } else { Rect bounds; varsp->fRTextOutlineRegion = outlineRegion; GetControlBounds(theControl, &bounds); YASTControlCalculateBounds(varsp, &bounds); } } /* create the new edit field */ if (err == noErr) { err = TXNNewObject(NULL, varsp->fWindow, &varsp->fRTextArea, kTXNWantVScrollBarMask | kTXNAlwaysWrapAtViewEdgeMask, kTXNTextEditStyleFrameType, kTXNTextensionFile, kTXNSystemDefaultEncoding, &theTXNObject, &varsp->fTXNFrameID, (TXNObjectRefcon) varsp); if (err == noErr) { varsp->fTXNObject = theTXNObject; } } /* set the field's background */ if (err == noErr) { RGBColor rgbWhite = {0xFFFF, 0xFFFF, 0xFFFF}; TXNBackground tback; tback.bgType = kTXNBackgroundTypeRGB; tback.bg.color = rgbWhite; TXNSetBackground( varsp->fTXNObject, &tback); } /* set the margins for easier selection and display */ if (err == noErr) { TXNControlData txnCControlData; TXNControlTag txnControlTag = kTXNMarginsTag; TXNMargins txnMargins = { 2, 3, 2, 1 }; /* t,l,b,r */ txnCControlData.marginsPtr = &txnMargins; (void) TXNSetTXNObjectControls( varsp->fTXNObject, false, 1, &txnControlTag, &txnCControlData ); } /* install our carbon event handlers */ if (err == noErr) { static EventHandlerUPP gTPEventHandlerUPP = NULL; if (gTPEventHandlerUPP == NULL) gTPEventHandlerUPP = NewEventHandlerUPP(YASTControlCarbonEventHandler); /* carbon event handlers for the control */ err = InstallEventHandler( GetControlEventTarget( theControl ), gTPEventHandlerUPP, (sizeof(gYASTControlEvents)/sizeof(EventTypeSpec)), gYASTControlEvents, varsp, &controlEvents); if (err == noErr) { varsp->fControlEvents = windowEvents; /* carbon event handlers for the control's window */ err = InstallEventHandler( GetWindowEventTarget( varsp->fWindow ), gTPEventHandlerUPP, (sizeof(gYASTControlWindowEvents)/sizeof(EventTypeSpec)), gYASTControlWindowEvents, varsp, &windowEvents); if (err == noErr) { varsp->fWindowEvents = windowEvents; } } } /* perform final activations and setup for our text field. Here, we assume that the window is going to be the 'active' window. */ if (err == noErr) { SetTextActivation(varsp, (varsp->fIsActive && varsp->fInFocus)); } /* clean up on error */ if (err != noErr) { if (controlEvents != NULL) RemoveEventHandler(controlEvents); if (windowEvents != NULL) RemoveEventHandler(windowEvents); if (theTXNObject != NULL) TXNDeleteObject(theTXNObject); if (outlineRegion != NULL) DisposeRgn(outlineRegion); if (varsp != NULL) free((void*) varsp); } /* all done */ return err; }
//-------------------------------------------------------------------------------------------------// void OSXCarbonWindow::create( const String& name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams ) { bool hasDepthBuffer; String title = name; size_t fsaa_samples = 0; int left = 0; int top = 0; int depth = 32; if( miscParams ) { NameValuePairList::const_iterator opt = NULL; // Full screen anti aliasing opt = miscParams->find( "FSAA" ); if( opt != miscParams->end() ) fsaa_samples = StringConverter::parseUnsignedInt( opt->second ); opt = miscParams->find( "left" ); if( opt != miscParams->end() ) left = StringConverter::parseUnsignedInt( opt->second ); opt = miscParams->find( "top" ); if( opt != miscParams->end() ) top = StringConverter::parseUnsignedInt( opt->second ); opt = miscParams->find( "title" ); if( opt != miscParams->end() ) title = opt->second; opt = miscParams->find( "depthBuffer" ); if( opt != miscParams->end() ) hasDepthBuffer = StringConverter::parseBool( opt->second ); opt = miscParams->find( "colourDepth" ); if( opt != miscParams->end() ) depth = StringConverter::parseUnsignedInt( opt->second ); } if(fullScreen) { GLRenderSystem *rs = static_cast<GLRenderSystem*>(Root::getSingleton().getRenderSystem()); OSXContext *mainContext = (OSXContext*)rs->_getMainContext(); CGLContextObj share = NULL; if(mainContext == 0) { share = NULL; } else if(mainContext->getContextType() == "AGL") { OSXCarbonContext* aglShare = static_cast<OSXCarbonContext*>(mainContext); aglGetCGLContext(aglShare->getContext(), &((void*)share)); } else if(mainContext->getContextType() == "CGL") { OSXCGLContext* cglShare = static_cast<OSXCGLContext*>(mainContext); share = cglShare->getContext(); } // create the context createCGLFullscreen(width, height, depth, fsaa_samples, share); } else { int i = 0; AGLPixelFormat pixelFormat; GLint attribs[ 20 ]; attribs[ i++ ] = AGL_NO_RECOVERY; attribs[ i++ ] = GL_TRUE; attribs[ i++ ] = AGL_ACCELERATED; attribs[ i++ ] = GL_TRUE; attribs[ i++ ] = AGL_RGBA; attribs[ i++ ] = AGL_DOUBLEBUFFER; attribs[ i++ ] = AGL_ALPHA_SIZE; attribs[ i++ ] = 8; attribs[ i++ ] = AGL_STENCIL_SIZE; attribs[ i++ ] = 8; attribs[ i++ ] = AGL_DEPTH_SIZE; attribs[ i++ ] = depth; if(fsaa_samples > 1) { attribs[ i++ ] = AGL_MULTISAMPLE; attribs[ i++ ] = 1; attribs[ i++ ] = AGL_SAMPLE_BUFFERS_ARB; attribs[ i++ ] = fsaa_samples; } attribs[ i++ ] = AGL_NONE; pixelFormat = aglChoosePixelFormat( NULL, 0, attribs ); // Create the AGLContext from our pixel format // Share it with main GLRenderSystem *rs = static_cast<GLRenderSystem*>(Root::getSingleton().getRenderSystem()); OSXContext* mainContext = static_cast<OSXContext*>( rs->_getMainContext() ); if(mainContext == 0) { mAGLContext = aglCreateContext(pixelFormat, NULL); } else if(mainContext->getContextType() == "AGL") { OSXCarbonContext* context = static_cast<OSXCarbonContext*>( rs->_getMainContext() ); AGLContext shared = context->getContext(); mAGLContext = aglCreateContext(pixelFormat, context->getContext()); } else { // If we do not have an AGL, we can not clone it using this window LogManager::getSingleton().logMessage( "Warning: You asked to create a second window, " "when the previous window was not of this type. OgreOSXCarbonWindow can only share " "with an AGL context."); } NameValuePairList::const_iterator opt = 0; if(miscParams) opt = miscParams->find("externalWindowHandle"); if(!miscParams || opt == miscParams->end()) { // create the window rect in global coords ::Rect windowRect; windowRect.left = 0; windowRect.top = 0; windowRect.right = width; windowRect.bottom = height; // set the default attributes for the window WindowAttributes windowAttrs = kWindowStandardDocumentAttributes; // default: "resize" if (miscParams) { opt = miscParams->find("border"); if( opt != miscParams->end() ) { String borderType = opt->second; if( borderType == "none" ) windowAttrs = kWindowNoTitleBarAttribute; else if( borderType == "fixed" ) windowAttrs = kWindowStandardFloatingAttributes; } } windowAttrs |= kWindowStandardHandlerAttribute | kWindowInWindowMenuAttribute | kWindowHideOnFullScreenAttribute; // Create the window CreateNewWindow(kDocumentWindowClass, windowAttrs, &windowRect, &mWindow); // Color the window background black SetThemeWindowBackground (mWindow, kThemeBrushBlack, true); // Set the title of our window CFStringRef titleRef = CFStringCreateWithCString( kCFAllocatorDefault, title.c_str(), kCFStringEncodingASCII ); SetWindowTitleWithCFString( mWindow, titleRef ); // Center our window on the screen RepositionWindow( mWindow, NULL, kWindowCenterOnMainScreen ); // Get our view HIViewFindByID( HIViewGetRoot( mWindow ), kHIViewWindowContentID, &mView ); // Set up our UPP for Window Events EventTypeSpec eventSpecs[] = { {kEventClassWindow, kEventWindowActivated}, {kEventClassWindow, kEventWindowDeactivated}, {kEventClassWindow, kEventWindowShown}, {kEventClassWindow, kEventWindowHidden}, {kEventClassWindow, kEventWindowDragCompleted}, {kEventClassWindow, kEventWindowBoundsChanged}, {kEventClassWindow, kEventWindowExpanded}, {kEventClassWindow, kEventWindowCollapsed}, {kEventClassWindow, kEventWindowClosed}, {kEventClassWindow, kEventWindowClose} }; EventHandlerUPP handlerUPP = NewEventHandlerUPP(WindowEventUtilities::_CarbonWindowHandler); // Install the standard event handler for the window EventTargetRef target = GetWindowEventTarget(mWindow); InstallStandardEventHandler(target); // We also need to install the WindowEvent Handler, we pass along the window with our requests InstallEventHandler(target, handlerUPP, 10, eventSpecs, (void*)this, &mEventHandlerRef); // Display and select our window ShowWindow(mWindow); SelectWindow(mWindow); // Add our window to the window event listener class WindowEventUtilities::_addRenderWindow(this); } else { // TODO: The Contol is going to report the incorrect location with a // Metalic / Textured window. The default windows work just fine. // First get the HIViewRef / ControlRef mView = (HIViewRef)StringConverter::parseUnsignedLong(opt->second); mWindow = GetControlOwner(mView); // Lets try hiding the HIView //HIViewSetVisible(mView, false); // Get the rect bounds ::Rect ctrlBounds; GetControlBounds(mView, &ctrlBounds); GLint bufferRect[4]; bufferRect[0] = ctrlBounds.left; // left edge bufferRect[1] = ctrlBounds.bottom; // bottom edge bufferRect[2] = ctrlBounds.right - ctrlBounds.left; // width of buffer rect bufferRect[3] = ctrlBounds.bottom - ctrlBounds.top; // height of buffer rect aglSetInteger(mAGLContext, AGL_BUFFER_RECT, bufferRect); aglEnable (mAGLContext, AGL_BUFFER_RECT); mIsExternal = true; } // Set the drawable, and current context // If you do this last, there is a moment before the rendering window pops-up // This could go once inside each case above, before the window is displayed, // if desired. aglSetDrawable(mAGLContext, GetWindowPort(mWindow)); aglSetCurrentContext(mAGLContext); // Give a copy of our context to the render system mContext = new OSXCarbonContext(mAGLContext, pixelFormat); } mName = name; mWidth = width; mHeight = height; mActive = true; mClosed = false; mCreated = true; mIsFullScreen = fullScreen; }
/* Handle events of kEventClassControl that get sent to the Frame */ OSStatus HandleStarFrameControlEvents( EventHandlerCallRef inCallRef, EventRef inEvent, StarFrameData* frameData) { OSStatus retVal = eventNotHandledErr; switch(GetEventKind(inEvent)) { case kEventControlInitialize : retVal = HandleStarFrameInitialize(inCallRef, inEvent, frameData); break; case kEventControlOwningWindowChanged : { // We only want the star-shaped opaque area of our frame view to // draw. Everything else should be transparent. To accomplish that // we change the features of the owning window so that only the // content we draw shows up on screen WindowRef newWindow = GetControlOwner(frameData->hiSelf); HIWindowChangeFeatures(newWindow, 0, kWindowIsOpaque); } break; case kEventControlBoundsChanged : { retVal = HandleStarFrameBoundsChanged(inCallRef, inEvent, frameData); } break; case kEventControlDraw : { HIRect bounds; CGContextRef cgContext; HIViewGetBounds(frameData->hiSelf, &bounds); float radius = fmin(CGRectGetWidth(bounds) / 2.0, CGRectGetHeight(bounds) / 2.0); GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(cgContext), NULL, &cgContext ); if(NULL != cgContext) { HIThemeMenuDrawInfo drawInfo; CGPathRef starPath = CreatePathForStarFrame(frameData, radius); drawInfo.version = 0; drawInfo.menuType = frameData->menuType; // HIThemeDrawMenuBackground is designed to draw the pin striped background // of standard menus. Our menu is a star and so HIThemeDrawMenuBackground may not be // appropriate in this case. Nevertheless, we'll draw the standard menu background for // this menu and clip it to a star. CGContextClearRect(cgContext, bounds); CGContextSaveGState(cgContext); CGContextTranslateCTM(cgContext, radius, radius); CGContextAddPath(cgContext, starPath); CGContextClip(cgContext); CGContextTranslateCTM(cgContext, -radius, -radius); HIThemeDrawMenuBackground(&bounds, &drawInfo, cgContext, kHIThemeOrientationNormal); CGContextRestoreGState(cgContext); // The pin striping looks a bit odd sort of floating out by itself. We'll also add // a lovely gray line to help emphasize the boundary CGContextTranslateCTM(cgContext, radius, radius); CGContextAddPath(cgContext, starPath); CGContextSetRGBStrokeColor(cgContext, 0.8, 0.8, 0.8, 1.0); CGContextSetLineWidth(cgContext, 1.0); CGContextStrokePath(cgContext); CGPathRelease(starPath); starPath = NULL; } retVal = noErr; } break; // Mac OS X v10.4 introduced a Window Manager bug. // The workaround is to implement the kEventControlGetFrameMetrics handler. // Even after the bug is fixed, the workaround will not be harmful. case kEventControlGetFrameMetrics: { HIViewRef contentView = NULL; // If we can find our content view, ask it for our metrics verify_noerr(HIViewFindByID(frameData->hiSelf, kHIViewWindowContentID, &contentView)); if(NULL != contentView) { retVal = SendEventToEventTargetWithOptions( inEvent, GetControlEventTarget( contentView ), kEventTargetDontPropagate ); } } break; default: break; } return retVal; }
// ----------------------------------------------------------------------------- // HITestViewTrack // ----------------------------------------------------------------------------- // This is overkill, and probably #ifdef'd out, but is here as an example of // a custom tracking handler. // OSStatus HITestViewTrack( EventRef inEvent, HITestViewData* inData ) { OSStatus err; HIRect bounds; HIPoint where; ControlPartCode part; Boolean inside; Boolean wasInside; Point qdPt; MouseTrackingResult mouseResult; PixMapHandle portPixMap; // Extract the mouse location err = GetEventParameter( inEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof( HIPoint ), NULL, &where ); require_noerr( err, ParameterMissing ); // Is the mouse location in the view? err = HIViewGetBounds( inData->view, &bounds ); if ( CGRectContainsPoint( bounds, where ) ) part = 1; else part = kControlNoPart; HiliteControl( inData->view, part ); wasInside = true; // Need the port's pixMap's bounds to convert the mouse location portPixMap = GetPortPixMap( GetWindowPort( GetControlOwner( inData->view ) ) ); // The tracking loop while ( true ) { // Check again to see if the mouse is in the view if ( CGRectContainsPoint( bounds, where ) ) part = 1; else part = kControlNoPart; inside = ( part != kControlNoPart ); // If that changed, update if ( inside != wasInside ) HiliteControl( inData->view, part ); wasInside = inside; // Watch the mouse for change err = TrackMouseLocation( (GrafPtr)-1L, &qdPt, &mouseResult ); // Need to convert from global QDGlobalToLocalPoint( GetWindowPort( GetControlOwner( inData->view ) ), &qdPt ); where.x = qdPt.h - (**portPixMap).bounds.left; where.y = qdPt.v - (**portPixMap).bounds.top; HIViewConvertPoint( &where, NULL, inData->view ); // Bail out when the mouse is released if ( mouseResult == kMouseTrackingMouseReleased ) break; } // Restore the original highlight HiliteControl( inData->view, kControlNoPart ); // Send back the part upon which the mouse was released err = SetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode, sizeof( ControlPartCode ), &part ); ParameterMissing: return err; }
// -------------------------------------------------------------------------------------- static pascal OSStatus windowEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *junk) { #pragma unused (nextHandler, junk) OSStatus result = eventNotHandledErr; UInt32 eventClass, eventKind; WindowRef prefsWindow; Point mouseLocation, minWindowBounds; UInt32 modifiers; ControlRef listScrollBar; ListHandle iconList; Rect iconListRect; eventClass = GetEventClass(event); eventKind = GetEventKind(event); switch (eventClass) { case kEventClassWindow: GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef), NULL, &prefsWindow); switch (eventKind) { case kEventWindowActivated: HandleActivate(prefsWindow, true); result = noErr; break; case kEventWindowDeactivated: HandleActivate(prefsWindow, false); result = noErr; break; case kEventWindowHandleContentClick: GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &mouseLocation); GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers); HandleContentClick(prefsWindow, mouseLocation, (EventModifiers)modifiers); result = noErr; break; case kEventWindowGetMinimumSize: SetPt(&minWindowBounds, gPrefsWindowWidth, gPrefsWindowHeight); SetEventParameter(event, kEventParamDimensions, typeQDPoint, sizeof(Point), &minWindowBounds); result = noErr; break; case kEventWindowResizeCompleted: AdjustControls(prefsWindow); result = noErr; break; case kEventWindowClose: ClosePrefsWindow(prefsWindow); result = noErr; break; case kEventWindowDrawContent: HandleDrawContent(prefsWindow); result = noErr; break; case kEventWindowContextualMenuSelect: result = noErr; // eat contextual menu clicks break; } break; case kEventClassControl: // we need to respond to clicks in the list's scroll bar switch (eventKind) // kEventControlClick instead of kEventControlHit { // because the control click must be tracked case kEventControlClick: // with LClick instead of the default handler GetEventParameter(event, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &listScrollBar); prefsWindow = GetControlOwner(listScrollBar); GetWindowProperty(prefsWindow, kAppSignature, kIconListTag, sizeof(ListHandle), NULL, &iconList); if (listScrollBar == GetListVerticalScrollBar(iconList)) { GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &mouseLocation); GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers); HandleContentClick(prefsWindow, mouseLocation, (EventModifiers)modifiers); result = noErr; } break; } break; case kEventClassMouse: switch (eventKind) { case kEventMouseWheelMoved: GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &mouseLocation); GlobalToLocal(&mouseLocation); GetEventParameter(event, kEventParamWindowRef, typeWindowRef, NULL, sizeof(WindowRef), NULL, &prefsWindow); GetWindowProperty(prefsWindow, kAppSignature, kIconListTag, sizeof(ListHandle), NULL, &iconList); GetListViewBounds(iconList, &iconListRect); iconListRect.right += kScrollBarWidth; if (PtInRect(mouseLocation, &iconListRect)) { EventMouseWheelAxis axis; long mouseWheelDelta; SInt16 pixelDepth; Boolean isColorDevice; GetEventParameter(event, kEventParamMouseWheelAxis, typeMouseWheelAxis, NULL, sizeof(EventMouseWheelAxis), NULL, &axis); GetEventParameter(event, kEventParamMouseWheelDelta, typeLongInteger, NULL, sizeof(long), NULL, &mouseWheelDelta); GetWindowDeviceDepthAndColor(prefsWindow, &pixelDepth, &isColorDevice); SetThemeBackground(kThemeBrushWhite, pixelDepth, isColorDevice); // LScroll draws the newly visible cells immediately if (axis == kEventMouseWheelAxisX) // (no update event) LScroll(-mouseWheelDelta, 0, iconList); else // axis == kEventMouseWheelAxisY LScroll(0, -mouseWheelDelta, iconList); result = noErr; } break; } break; case kEventClassTextInput: switch (eventKind) { case kEventTextInputUnicodeForKeyEvent: prefsWindow = FrontNonFloatingWindow(); if (prefsWindow != NULL) { EventRef keyboardEvent; UInt32 keyCode; GetEventParameter(event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(EventRef), NULL, &keyboardEvent); GetEventParameter(keyboardEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode); HandleKeyDown((char)keyCode, prefsWindow); result = noErr; } break; } break; } return result; } // windowEventHandler