diff options
Diffstat (limited to 'macosx/tkMacOSXMenubutton.c')
-rw-r--r-- | macosx/tkMacOSXMenubutton.c | 970 |
1 files changed, 472 insertions, 498 deletions
diff --git a/macosx/tkMacOSXMenubutton.c b/macosx/tkMacOSXMenubutton.c index d5ae817..acf507a 100644 --- a/macosx/tkMacOSXMenubutton.c +++ b/macosx/tkMacOSXMenubutton.c @@ -1,16 +1,17 @@ -/* +/* * tkMacOSXMenubutton.c -- * - * This file implements the Macintosh specific portion of the - * menubutton widget. + * This file implements the Macintosh specific portion of the + * menubutton widget. * * Copyright (c) 1996 by Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXMenubutton.c,v 1.2.2.9 2006/07/20 06:27:34 das Exp $ + * RCS: @(#) $Id: tkMacOSXMenubutton.c,v 1.2.2.10 2007/04/29 02:26:49 das Exp $ */ #include "tkMacOSXInt.h" @@ -19,33 +20,29 @@ #include "tkMacOSXFont.h" #include "tkMacOSXDebug.h" -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 - /* Define constants only available on Mac OS X 10.3 or later */ - #define kMenuAttrDoNotUseUserCommandKeys (1 << 7) -#endif - -#define kShadowOffset (3) /* amount to offset shadow from frame */ -#define kTriangleWidth (11) /* width of the triangle */ -#define kTriangleHeight (6) /* height of the triangle */ -#define kTriangleMargin (5) /* margin around triangle */ +#define kShadowOffset (3) /* amount to offset shadow from frame */ +#define kTriangleWidth (11) /* width of the triangle */ +#define kTriangleHeight (6) /* height of the triangle */ +#define kTriangleMargin (5) /* margin around triangle */ -#define TK_POPUP_OFFSET 32 /* size of popup marker */ +#define TK_POPUP_OFFSET 32 /* size of popup marker */ -MODULE_SCOPE int TkMacOSXGetNewMenuID _ANSI_ARGS_((Tcl_Interp *interp, TkMenu *menuInstPtr, int cascade, short *menuIDPtr)); -MODULE_SCOPE void TkMacOSXFreeMenuID _ANSI_ARGS_((short menuID)); +MODULE_SCOPE int TkMacOSXGetNewMenuID(Tcl_Interp *interp, TkMenu *menuInstPtr, + int cascade, short *menuIDPtr); +MODULE_SCOPE void TkMacOSXFreeMenuID(short menuID); typedef struct { SInt16 initialValue; SInt16 minValue; SInt16 maxValue; SInt16 procID; - int isBevel; + int isBevel; } MenuButtonControlParams; typedef struct { - int len; - Str255 title; - ControlFontStyleRec style; + int len; + Str255 title; + ControlFontStyleRec style; } ControlTitleParams; /* @@ -53,41 +50,39 @@ typedef struct { */ typedef struct MacMenuButton { - TkMenuButton info; /* Generic button info. */ - WindowRef windowRef; - ControlRef userPane; - ControlRef control; - MenuRef menuRef; - RGBColor userPaneBackground; - MenuButtonControlParams params; - ControlTitleParams titleParams; + TkMenuButton info; /* Generic button info. */ + WindowRef windowRef; + ControlRef userPane; + ControlRef control; + MenuRef menuRef; + unsigned long userPaneBackground; + int flags; + MenuButtonControlParams params; + ControlTitleParams titleParams; ControlButtonContentInfo bevelButtonContent; - OpenCPicParams picParams; - int flags; + OpenCPicParams picParams; } MacMenuButton; /* * Forward declarations for procedures defined later in this file: */ -static OSErr SetUserPaneDrawProc(ControlRef control, - ControlUserPaneDrawProcPtr upp); -static OSErr SetUserPaneSetUpSpecialBackgroundProc(ControlRef control, - ControlUserPaneBackgroundProcPtr upp); +static OSStatus SetUserPaneDrawProc(ControlRef control, + ControlUserPaneDrawProcPtr upp); +static OSStatus SetUserPaneSetUpSpecialBackgroundProc(ControlRef control, + ControlUserPaneBackgroundProcPtr upp); static void UserPaneDraw(ControlRef control, ControlPartCode cpc); static void UserPaneBackgroundProc(ControlHandle, - ControlBackgroundPtr info); -static int MenuButtonInitControl ( MacMenuButton *mbPtr, Rect *paneRect, Rect *cntrRect ); - -static int UpdateControlColors _ANSI_ARGS_((MacMenuButton *mbPtr )); -static void ComputeMenuButtonControlParams _ANSI_ARGS_((TkMenuButton * mbPtr, MenuButtonControlParams * paramsPtr)); -static void ComputeControlTitleParams _ANSI_ARGS_((TkMenuButton * mbPtr, ControlTitleParams * paramsPtr)); -static void CompareControlTitleParams( - ControlTitleParams * p1Ptr, - ControlTitleParams * p2Ptr, - int * titleChanged, - int * styleChanged -); + ControlBackgroundPtr info); +static int MenuButtonInitControl (MacMenuButton *mbPtr, Rect *paneRect, + Rect *cntrRect ); +static int UpdateControlColors(MacMenuButton *mbPtr); +static void ComputeMenuButtonControlParams(TkMenuButton *mbPtr, + MenuButtonControlParams * paramsPtr); +static void ComputeControlTitleParams(TkMenuButton *mbPtr, + ControlTitleParams *paramsPtr); +static void CompareControlTitleParams(ControlTitleParams *p1Ptr, + ControlTitleParams *p2Ptr, int *titleChanged, int *styleChanged); /* * The structure below defines menubutton class behavior by means of @@ -95,22 +90,23 @@ static void CompareControlTitleParams( */ Tk_ClassProcs tkpMenubuttonClass = { - sizeof(Tk_ClassProcs), /* size */ - TkMenuButtonWorldChanged, /* worldChangedProc */ + sizeof(Tk_ClassProcs), /* size */ + TkMenuButtonWorldChanged, /* worldChangedProc */ }; + /* *---------------------------------------------------------------------- * * TkpCreateMenuButton -- * - * Allocate a new TkMenuButton structure. + * Allocate a new TkMenuButton structure. * * Results: - * Returns a newly allocated TkMenuButton structure. + * Returns a newly allocated TkMenuButton structure. * * Side effects: - * Registers an event handler for the widget. + * Registers an event handler for the widget. * *---------------------------------------------------------------------- */ @@ -120,9 +116,7 @@ TkpCreateMenuButton( Tk_Window tkwin) { MacMenuButton *mbPtr = (MacMenuButton *) ckalloc(sizeof(MacMenuButton)); - mbPtr->userPaneBackground.red = 0; - mbPtr->userPaneBackground.green = 0; - mbPtr->userPaneBackground.blue = ~0; + mbPtr->userPaneBackground = PIXEL_MAGIC << 24; mbPtr->flags = 0; mbPtr->userPane = NULL; mbPtr->control = NULL; @@ -146,45 +140,41 @@ TkpCreateMenuButton( * * TkpDisplayMenuButton -- * - * This procedure is invoked to display a menubutton widget. + * This procedure is invoked to display a menubutton widget. * * Results: - * None. + * None. * * Side effects: - * Commands are output to X to display the menubutton in its - * current mode. + * Commands are output to X to display the menubutton in its + * current mode. * *---------------------------------------------------------------------- */ void TkpDisplayMenuButton( - ClientData clientData) /* Information about widget. */ + ClientData clientData) /* Information about widget. */ { TkMenuButton *butPtr = (TkMenuButton *) clientData; Tk_Window tkwin = butPtr->tkwin; - TkWindow * winPtr; - Pixmap pixmap; - MacMenuButton * mbPtr = (MacMenuButton *) butPtr; - GWorldPtr dstPort; - CGrafPtr saveWorld; - GDHandle saveDevice; - int hasImageOrBitmap = 0; - int width, height; - int err; + TkWindow *winPtr; + Pixmap pixmap; + MacMenuButton *mbPtr = (MacMenuButton *) butPtr; + CGrafPtr destPort, savePort; + Boolean portChanged; + int hasImageOrBitmap = 0, width, height; + OSStatus err; ControlButtonGraphicAlignment theAlignment; - Rect paneRect, cntrRect; butPtr->flags &= ~REDRAW_PENDING; if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) { - return; + return; } - pixmap = ( Pixmap )Tk_WindowId(tkwin); - GetGWorld(&saveWorld, &saveDevice); - dstPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin)); - SetGWorld(dstPort, NULL); + pixmap = (Pixmap) Tk_WindowId(tkwin); + destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin)); + portChanged = QDSwapPort(destPort, &savePort); TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin)); winPtr = (TkWindow *)butPtr->tkwin; @@ -192,172 +182,168 @@ TkpDisplayMenuButton( paneRect.top = winPtr->privatePtr->yOff; paneRect.right = paneRect.left+Tk_Width(butPtr->tkwin)-1; paneRect.bottom = paneRect.top+Tk_Height(butPtr->tkwin)-1; - + cntrRect = paneRect; - + cntrRect.left += butPtr->inset; cntrRect.top += butPtr->inset; cntrRect.right -= butPtr->inset; cntrRect.bottom -= butPtr->inset; if (mbPtr->userPane) { - MenuButtonControlParams params; - bzero(¶ms, sizeof(params)); - ComputeMenuButtonControlParams(butPtr, ¶ms ); - if (bcmp(¶ms,&mbPtr->params,sizeof(params))) { - if (mbPtr->userPane) { - DisposeControl(mbPtr->userPane); - mbPtr->userPane = NULL; - mbPtr->control = NULL; - } - } - } - if (!mbPtr->userPane) { - if (MenuButtonInitControl(mbPtr,&paneRect,&cntrRect ) ) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"Init Control failed\n" ); -#endif - return; - } - } + MenuButtonControlParams params; + bzero(¶ms, sizeof(params)); + ComputeMenuButtonControlParams(butPtr, ¶ms ); + if (bcmp(¶ms,&mbPtr->params,sizeof(params))) { + if (mbPtr->userPane) { + DisposeControl(mbPtr->userPane); + mbPtr->userPane = NULL; + mbPtr->control = NULL; + } + } + } + if (!mbPtr->userPane) { + if (MenuButtonInitControl(mbPtr, &paneRect, &cntrRect)) { + TkMacOSXDbgMsg("Init Control failed"); + return; + } + } SetControlBounds(mbPtr->userPane,&paneRect); - SetControlBounds(mbPtr->control,&cntrRect); + SetControlBounds(mbPtr->control,&cntrRect); /* * We need to cache the title and its style */ - if (!(mbPtr->flags&2)) { - ControlTitleParams titleParams; - int titleChanged; - int styleChanged; - ComputeControlTitleParams(butPtr,&titleParams); - CompareControlTitleParams(&titleParams,&mbPtr->titleParams, - &titleChanged,&styleChanged); - if (titleChanged) { - CFStringRef cf; - cf = CFStringCreateWithCString(NULL, - (char*) titleParams.title, kCFStringEncodingUTF8); - if (hasImageOrBitmap) { - SetControlTitleWithCFString(mbPtr->control, cf); - } else { - SetMenuItemTextWithCFString(mbPtr->menuRef, 1, cf); - } - CFRelease(cf); - bcopy(titleParams.title,mbPtr->titleParams.title,titleParams.len+1); - mbPtr->titleParams.len = titleParams.len; - } - if ((titleChanged||styleChanged) && titleParams .len) { - if (hasImageOrBitmap) { - err = SetControlFontStyle(mbPtr->control,&titleParams.style); - if (err !=noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"SetControlFontStyle failed %d\n", err); -#endif - return; - } - } - bcopy(&titleParams.style,&mbPtr->titleParams.style,sizeof(titleParams.style)); - } + + if (!(mbPtr->flags & 2)) { + ControlTitleParams titleParams; + int titleChanged; + int styleChanged; + + ComputeControlTitleParams(butPtr,&titleParams); + CompareControlTitleParams(&titleParams,&mbPtr->titleParams, + &titleChanged,&styleChanged); + if (titleChanged) { + CFStringRef cf = CFStringCreateWithCString(NULL, + (char*) titleParams.title, kCFStringEncodingUTF8); + + if (hasImageOrBitmap) { + SetControlTitleWithCFString(mbPtr->control, cf); + } else { + SetMenuItemTextWithCFString(mbPtr->menuRef, 1, cf); + } + CFRelease(cf); + bcopy(titleParams.title, mbPtr->titleParams.title, + titleParams.len + 1); + mbPtr->titleParams.len = titleParams.len; + } + if ((titleChanged||styleChanged) && titleParams .len) { + if (hasImageOrBitmap) { + err = ChkErr(SetControlFontStyle, mbPtr->control, + &titleParams.style); + if (err != noErr) { + return; + } + } + bcopy(&titleParams.style, &mbPtr->titleParams.style, + sizeof(titleParams.style)); + } } if (butPtr->image != None) { - Tk_SizeOfImage(butPtr->image, &width, &height); - hasImageOrBitmap = 1; + Tk_SizeOfImage(butPtr->image, &width, &height); + hasImageOrBitmap = 1; } else if (butPtr->bitmap != None) { - Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height); - hasImageOrBitmap = 1; + Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height); + hasImageOrBitmap = 1; } if (hasImageOrBitmap) { - mbPtr->picParams.srcRect.right = width; - mbPtr->picParams.srcRect.bottom = height; - /* Set the flag to circumvent clipping and bounds problems with OS 10.0.4 */ - tkPictureIsOpen = 1; - if (!(mbPtr->bevelButtonContent.u.picture = OpenCPicture(&mbPtr->picParams)) ) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"OpenCPicture failed\n"); -#endif - } - /* - * TO DO - There is one case where XCopyPlane calls CopyDeepMask, - * which does not get recorded in the picture. So the bitmap code - * will fail in that case. - */ - if (butPtr->image != NULL) { - Tk_RedrawImage(butPtr->image, 0, 0, width, - height, pixmap, 0, 0); - } else { - XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, NULL, 0, 0, - (unsigned int) width, (unsigned int) height, 0, 0, 1); - } - ClosePicture(); - - tkPictureIsOpen = 0; - err = SetControlData(mbPtr->control, kControlButtonPart, - kControlBevelButtonContentTag, - sizeof(ControlButtonContentInfo), - (char *) &mbPtr->bevelButtonContent); - if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"SetControlData BevelButtonContent failed, %d\n", err ); -#endif - } - switch (butPtr->anchor) { - case TK_ANCHOR_N: - theAlignment = kControlBevelButtonAlignTop; - break; - case TK_ANCHOR_NE: - theAlignment = kControlBevelButtonAlignTopRight; - break; - case TK_ANCHOR_E: - theAlignment = kControlBevelButtonAlignRight; - break; - case TK_ANCHOR_SE: - theAlignment = kControlBevelButtonAlignBottomRight; - break; - case TK_ANCHOR_S: - theAlignment = kControlBevelButtonAlignBottom; - break; - case TK_ANCHOR_SW: - theAlignment = kControlBevelButtonAlignBottomLeft; - break; - case TK_ANCHOR_W: - theAlignment = kControlBevelButtonAlignLeft; - break; - case TK_ANCHOR_NW: - theAlignment = kControlBevelButtonAlignTopLeft; - break; - case TK_ANCHOR_CENTER: - theAlignment = kControlBevelButtonAlignCenter; - break; - } - - err = SetControlData(mbPtr->control, kControlButtonPart, - kControlBevelButtonGraphicAlignTag, - sizeof(ControlButtonGraphicAlignment), - (char *) &theAlignment); - if (err != noErr ) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"SetControlData BevelButtonGraphicAlign failed, %d\n", err ); -#endif - } + mbPtr->picParams.srcRect.right = width; + mbPtr->picParams.srcRect.bottom = height; + + /* + * Set the flag to circumvent clipping and bounds problems with OS + * 10.0.4 + */ + + tkPictureIsOpen = 1; + mbPtr->bevelButtonContent.u.picture = OpenCPicture(&mbPtr->picParams); + if (!mbPtr->bevelButtonContent.u.picture) { + TkMacOSXDbgMsg("OpenCPicture failed"); + } + + /* + * TO DO - There is one case where XCopyPlane calls CopyDeepMask, + * which does not get recorded in the picture. So the bitmap code + * will fail in that case. + */ + + if (butPtr->image != NULL) { + Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap, 0, 0); + } else { + XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, NULL, 0, 0, + width, height, 0, 0, 1); + } + ClosePicture(); + + tkPictureIsOpen = 0; + ChkErr(SetControlData, mbPtr->control, kControlButtonPart, + kControlBevelButtonContentTag, + sizeof(ControlButtonContentInfo), + (char *) &mbPtr->bevelButtonContent); + switch (butPtr->anchor) { + case TK_ANCHOR_N: + theAlignment = kControlBevelButtonAlignTop; + break; + case TK_ANCHOR_NE: + theAlignment = kControlBevelButtonAlignTopRight; + break; + case TK_ANCHOR_E: + theAlignment = kControlBevelButtonAlignRight; + break; + case TK_ANCHOR_SE: + theAlignment = kControlBevelButtonAlignBottomRight; + break; + case TK_ANCHOR_S: + theAlignment = kControlBevelButtonAlignBottom; + break; + case TK_ANCHOR_SW: + theAlignment = kControlBevelButtonAlignBottomLeft; + break; + case TK_ANCHOR_W: + theAlignment = kControlBevelButtonAlignLeft; + break; + case TK_ANCHOR_NW: + theAlignment = kControlBevelButtonAlignTopLeft; + break; + case TK_ANCHOR_CENTER: + theAlignment = kControlBevelButtonAlignCenter; + break; + } + + ChkErr(SetControlData, mbPtr->control, kControlButtonPart, + kControlBevelButtonGraphicAlignTag, + sizeof(ControlButtonGraphicAlignment), (char *) &theAlignment); } if (butPtr->flags & GOT_FOCUS) { - HiliteControl(mbPtr->control,kControlButtonPart); + HiliteControl(mbPtr->control,kControlButtonPart); } else { - HiliteControl(mbPtr->control,kControlNoPart); + HiliteControl(mbPtr->control,kControlNoPart); } UpdateControlColors(mbPtr); if (mbPtr->flags&2) { - ShowControl(mbPtr->control); - ShowControl(mbPtr->userPane); - mbPtr->flags ^= 2; + ShowControl(mbPtr->control); + ShowControl(mbPtr->userPane); + mbPtr->flags ^= 2; } else { - Draw1Control(mbPtr->userPane); - SetControlVisibility(mbPtr->control, true, true); + Draw1Control(mbPtr->userPane); + SetControlVisibility(mbPtr->control, true, true); } if (hasImageOrBitmap) { - KillPicture(mbPtr->bevelButtonContent.u.picture); + KillPicture(mbPtr->bevelButtonContent.u.picture); + } + if (portChanged) { + QDSwapPort(savePort, NULL); } - SetGWorld(saveWorld, saveDevice); } /* @@ -365,13 +351,13 @@ TkpDisplayMenuButton( * * TkpDestroyMenuButton -- * - * Free data structures associated with the menubutton control. + * Free data structures associated with the menubutton control. * * Results: - * None. + * None. * * Side effects: - * Restores the default control state. + * Restores the default control state. * *---------------------------------------------------------------------- */ @@ -380,17 +366,18 @@ void TkpDestroyMenuButton( TkMenuButton *mbPtr) { - MacMenuButton * macMbPtr = (MacMenuButton *)mbPtr; + MacMenuButton *macMbPtr = (MacMenuButton *) mbPtr; + if (macMbPtr->userPane) { - DisposeControl(macMbPtr->userPane); - macMbPtr->userPane = NULL; + DisposeControl(macMbPtr->userPane); + macMbPtr->userPane = NULL; } if (macMbPtr->menuRef) { - short menuID; - menuID = GetMenuID(macMbPtr->menuRef); - TkMacOSXFreeMenuID(menuID); - DisposeMenu(macMbPtr->menuRef); - macMbPtr->menuRef = NULL; + short menuID = GetMenuID(macMbPtr->menuRef); + + TkMacOSXFreeMenuID(menuID); + DisposeMenu(macMbPtr->menuRef); + macMbPtr->menuRef = NULL; } } @@ -399,82 +386,82 @@ TkpDestroyMenuButton( * * TkpComputeMenuButtonGeometry -- * - * After changes in a menu button's text or bitmap, this procedure - * recomputes the menu button's geometry and passes this information - * along to the geometry manager for the window. + * After changes in a menu button's text or bitmap, this procedure + * recomputes the menu button's geometry and passes this information + * along to the geometry manager for the window. * * Results: - * None. + * None. * * Side effects: - * The menu button's window may change size. + * The menu button's window may change size. * *---------------------------------------------------------------------- */ void TkpComputeMenuButtonGeometry(mbPtr) - register TkMenuButton *mbPtr; /* Widget record for menu button. */ + register TkMenuButton *mbPtr; /* Widget record for menu button. */ { int width, height, mm, pixels; int hasImageOrBitmap = 0; mbPtr->inset = mbPtr->highlightWidth + mbPtr->borderWidth; if (mbPtr->image != None) { - Tk_SizeOfImage(mbPtr->image, &width, &height); - if (mbPtr->width > 0) { - width = mbPtr->width; - } - if (mbPtr->height > 0) { - height = mbPtr->height; - } - hasImageOrBitmap = 1; + Tk_SizeOfImage(mbPtr->image, &width, &height); + if (mbPtr->width > 0) { + width = mbPtr->width; + } + if (mbPtr->height > 0) { + height = mbPtr->height; + } + hasImageOrBitmap = 1; } else if (mbPtr->bitmap != None) { - Tk_SizeOfBitmap(mbPtr->display, mbPtr->bitmap, &width, &height); - if (mbPtr->width > 0) { - width = mbPtr->width; - } - if (mbPtr->height > 0) { - height = mbPtr->height; - } - hasImageOrBitmap = 1; + Tk_SizeOfBitmap(mbPtr->display, mbPtr->bitmap, &width, &height); + if (mbPtr->width > 0) { + width = mbPtr->width; + } + if (mbPtr->height > 0) { + height = mbPtr->height; + } + hasImageOrBitmap = 1; } else { - hasImageOrBitmap = 0; - Tk_FreeTextLayout(mbPtr->textLayout); - mbPtr->textLayout = Tk_ComputeTextLayout(mbPtr->tkfont, mbPtr->text, - -1, mbPtr->wrapLength, mbPtr->justify, 0, &mbPtr->textWidth, - &mbPtr->textHeight); - width = mbPtr->textWidth; - height = mbPtr->textHeight; - if (mbPtr->width > 0) { - width = mbPtr->width * Tk_TextWidth(mbPtr->tkfont, "0", 1); - } - if (mbPtr->height > 0) { - Tk_FontMetrics fm; - - Tk_GetFontMetrics(mbPtr->tkfont, &fm); - height = mbPtr->height * fm.linespace; - } - width += 2*mbPtr->padX; - height += 2*mbPtr->padY; + hasImageOrBitmap = 0; + Tk_FreeTextLayout(mbPtr->textLayout); + mbPtr->textLayout = Tk_ComputeTextLayout(mbPtr->tkfont, mbPtr->text, + -1, mbPtr->wrapLength, mbPtr->justify, 0, &mbPtr->textWidth, + &mbPtr->textHeight); + width = mbPtr->textWidth; + height = mbPtr->textHeight; + if (mbPtr->width > 0) { + width = mbPtr->width * Tk_TextWidth(mbPtr->tkfont, "0", 1); + } + if (mbPtr->height > 0) { + Tk_FontMetrics fm; + + Tk_GetFontMetrics(mbPtr->tkfont, &fm); + height = mbPtr->height * fm.linespace; + } + width += 2*mbPtr->padX; + height += 2*mbPtr->padY; } if (mbPtr->indicatorOn) { - mm = WidthMMOfScreen(Tk_Screen(mbPtr->tkwin)); - pixels = WidthOfScreen(Tk_Screen(mbPtr->tkwin)); - mbPtr->indicatorHeight = kTriangleHeight; - mbPtr->indicatorWidth = kTriangleWidth + kTriangleMargin; - width += mbPtr->indicatorWidth; + mm = WidthMMOfScreen(Tk_Screen(mbPtr->tkwin)); + pixels = WidthOfScreen(Tk_Screen(mbPtr->tkwin)); + mbPtr->indicatorHeight = kTriangleHeight; + mbPtr->indicatorWidth = kTriangleWidth + kTriangleMargin; + width += mbPtr->indicatorWidth; } else { - mbPtr->indicatorHeight = 0; - mbPtr->indicatorWidth = 0; + mbPtr->indicatorHeight = 0; + mbPtr->indicatorWidth = 0; } if (!hasImageOrBitmap) { - width += TK_POPUP_OFFSET; + width += TK_POPUP_OFFSET; } Tk_GeometryRequest(mbPtr->tkwin, (int) (width + 2*mbPtr->inset), - (int) (height + 2*mbPtr->inset)); + (int) (height + 2*mbPtr->inset)); Tk_SetInternalBorder(mbPtr->tkwin, mbPtr->inset); } @@ -483,26 +470,27 @@ TkpComputeMenuButtonGeometry(mbPtr) * * ComputeMenuButtonControlParams -- * - * This procedure computes the various parameters used - * when creating a Carbon control (NewControl) - * These are determined by the various tk menu button parameters + * This procedure computes the various parameters used + * when creating a Carbon control (NewControl) + * These are determined by the various tk menu button parameters * * Results: - * None. + * None. * * Side effects: - * Sets the control initialisation parameters + * Sets the control initialisation parameters * *---------------------------------------------------------------------- */ static void -ComputeMenuButtonControlParams(TkMenuButton * mbPtr, - MenuButtonControlParams * paramsPtr ) +ComputeMenuButtonControlParams( + TkMenuButton *mbPtr, + MenuButtonControlParams *paramsPtr) { int fakeMenuID = 256; - /* + /* * Determine ProcID based on button type and dimensions * * We need to set minValue to some non-zero value, @@ -512,26 +500,26 @@ ComputeMenuButtonControlParams(TkMenuButton * mbPtr, paramsPtr->minValue = kControlBehaviorMultiValueMenu; paramsPtr->maxValue = 0; if (mbPtr->image || mbPtr->bitmap) { - paramsPtr->isBevel = 1; - if (mbPtr->borderWidth <= 2) { - paramsPtr->procID = kControlBevelButtonSmallBevelProc; - } else if (mbPtr->borderWidth == 3) { - paramsPtr->procID = kControlBevelButtonNormalBevelProc; - } else { - paramsPtr->procID = kControlBevelButtonLargeBevelProc; - } - if (mbPtr->indicatorOn) { - paramsPtr->initialValue = fakeMenuID; - } else { - paramsPtr->initialValue = 0; - } + paramsPtr->isBevel = 1; + if (mbPtr->borderWidth <= 2) { + paramsPtr->procID = kControlBevelButtonSmallBevelProc; + } else if (mbPtr->borderWidth == 3) { + paramsPtr->procID = kControlBevelButtonNormalBevelProc; + } else { + paramsPtr->procID = kControlBevelButtonLargeBevelProc; + } + if (mbPtr->indicatorOn) { + paramsPtr->initialValue = fakeMenuID; + } else { + paramsPtr->initialValue = 0; + } } else { - paramsPtr->isBevel = 0; - paramsPtr->procID = kControlPopupButtonProc - + kControlPopupVariableWidthVariant; - paramsPtr->minValue = -12345; - paramsPtr->maxValue = -1; - paramsPtr->initialValue = 0; + paramsPtr->isBevel = 0; + paramsPtr->procID = kControlPopupButtonProc + + kControlPopupVariableWidthVariant; + paramsPtr->minValue = -12345; + paramsPtr->maxValue = -1; + paramsPtr->initialValue = 0; } } @@ -539,201 +527,181 @@ ComputeMenuButtonControlParams(TkMenuButton * mbPtr, *---------------------------------------------------------------------- * * returns 0 if same, 1 otherwise + * *---------------------------------------------------------------------- */ + static void -CompareControlTitleParams( - ControlTitleParams * p1Ptr, - ControlTitleParams * p2Ptr, - int * titleChanged, - int * styleChanged -) +CompareControlTitleParams( + ControlTitleParams *p1Ptr, + ControlTitleParams *p2Ptr, + int *titleChanged, + int *styleChanged) { if (p1Ptr->len != p2Ptr->len) { - *titleChanged = 1; + *titleChanged = 1; + } else if (bcmp(p1Ptr->title,p2Ptr->title,p1Ptr->len)) { + *titleChanged = 1; } else { - if (bcmp(p1Ptr->title,p2Ptr->title,p1Ptr->len)) { - *titleChanged = 1; - } else { - *titleChanged = 0; - } + *titleChanged = 0; } + if (p1Ptr->len && p2Ptr->len) { - *styleChanged = bcmp(&p1Ptr->style, &p2Ptr->style, sizeof(p2Ptr->style)); + *styleChanged = bcmp(&p1Ptr->style, &p2Ptr->style, + sizeof(p2Ptr->style)); } else { - *styleChanged = p1Ptr->len||p2Ptr->len; + *styleChanged = p1Ptr->len||p2Ptr->len; } } - + static void -ComputeControlTitleParams(TkMenuButton * butPtr, ControlTitleParams * paramsPtr ) +ComputeControlTitleParams( + TkMenuButton *butPtr, + ControlTitleParams *paramsPtr) { Tk_Font font; - paramsPtr->len =TkFontGetFirstTextLayout(butPtr->textLayout,&font, (char*) paramsPtr->title); - paramsPtr->title [paramsPtr->len] = 0; + + paramsPtr->len = TkFontGetFirstTextLayout(butPtr->textLayout, &font, + (char*) paramsPtr->title); + paramsPtr->title[paramsPtr->len] = 0; if (paramsPtr->len) { - TkMacOSXInitControlFontStyle(font,¶msPtr->style); + TkMacOSXInitControlFontStyle(font,¶msPtr->style); } } - /* *---------------------------------------------------------------------- * * MenuButtonInitControl -- * - * This procedure initialises a Carbon control + * This procedure initialises a Carbon control * * Results: - * 0 on success, 1 on failure. + * 0 on success, 1 on failure. * * Side effects: - * A background pane control and the control itself is created - * The contol is embedded in the background control - * The background control is embedded in the root control - * of the containing window - * The creation parameters for the control are also computed + * A background pane control and the control itself is created + * The contol is embedded in the background control + * The background control is embedded in the root control + * of the containing window + * The creation parameters for the control are also computed * *---------------------------------------------------------------------- */ int -MenuButtonInitControl ( - MacMenuButton *mbPtr, /* Mac button. */ - Rect *paneRect, - Rect *cntrRect -) +MenuButtonInitControl( + MacMenuButton *mbPtr, /* Mac button. */ + Rect *paneRect, + Rect *cntrRect) { - OSStatus err; - TkMenuButton * butPtr = ( TkMenuButton * )mbPtr; - ControlRef rootControl; - SInt16 procID; - Boolean initiallyVisible; - SInt16 initialValue; - SInt16 minValue; - SInt16 maxValue; - SInt32 controlReference; - short menuID; - - rootControl = TkMacOSXGetRootControl(Tk_WindowId(butPtr->tkwin)); - mbPtr->windowRef = GetWindowFromPort(TkMacOSXGetDrawablePort(Tk_WindowId(butPtr->tkwin))); - /* + OSStatus err; + TkMenuButton *butPtr = (TkMenuButton *) mbPtr; + SInt16 procID, initialValue, minValue, maxValue; + Boolean initiallyVisible; + SInt32 controlReference; + short menuID; + ControlRef rootControl = + TkMacOSXGetRootControl(Tk_WindowId(butPtr->tkwin)); + + mbPtr->windowRef = GetWindowFromPort( + TkMacOSXGetDrawablePort(Tk_WindowId(butPtr->tkwin))); + + /* * Set up the user pane */ + initiallyVisible = false; - initialValue = kControlSupportsEmbedding| - kControlHasSpecialBackground; + initialValue = kControlSupportsEmbedding | kControlHasSpecialBackground; minValue = 0; maxValue = 1; procID = kControlUserPaneProc; controlReference = (SInt32)mbPtr; - mbPtr->userPane = NewControl(mbPtr->windowRef, - paneRect, "\p", - initiallyVisible, - initialValue, - minValue, - maxValue, - procID, - controlReference ); + mbPtr->userPane = NewControl(mbPtr->windowRef, paneRect, "\p", + initiallyVisible, initialValue, minValue, maxValue, procID, + controlReference); if (!mbPtr->userPane) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"Failed to create user pane control\n"); -#endif - return 1; + TkMacOSXDbgMsg("Failed to create user pane control"); + return 1; } - err = EmbedControl(mbPtr->userPane,rootControl); + err = ChkErr(EmbedControl, mbPtr->userPane, rootControl); if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"Failed to embed user pane control %d\n", (int) err); -#endif - return 1; + return 1; } SetUserPaneSetUpSpecialBackgroundProc(mbPtr->userPane, - UserPaneBackgroundProc); + UserPaneBackgroundProc); SetUserPaneDrawProc(mbPtr->userPane,UserPaneDraw); initiallyVisible = false; ComputeMenuButtonControlParams(butPtr,&mbPtr->params); - /* Do this only if we are using bevel buttons */ + + /* + * Do this only if we are using bevel buttons. + */ + ComputeControlTitleParams(butPtr,&mbPtr->titleParams); mbPtr->control = NewControl(mbPtr->windowRef, - cntrRect, "\p", //mbPtr->titleParams.title, - initiallyVisible, - mbPtr->params.initialValue, - mbPtr->params.minValue, - mbPtr->params.maxValue, - mbPtr->params.procID, - controlReference ); + cntrRect, "\p" /* mbPtr->titleParams.title */, + initiallyVisible, mbPtr->params.initialValue, + mbPtr->params.minValue, mbPtr->params.maxValue, + mbPtr->params.procID, controlReference); if (!mbPtr->control) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"failed to create control of type %d : line %d\n",mbPtr->params.procID, __LINE__); -#endif - return 1; + TkMacOSXDbgMsg("Failed to create control of type %d", + mbPtr->params.procID); + return 1; } - err = EmbedControl(mbPtr->control,mbPtr->userPane); + err = ChkErr(EmbedControl, mbPtr->control, mbPtr->userPane); if (err != noErr ) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"failed to embed control of type %d,%d\n",procID, (int) err); -#endif - return 1; + return 1; } if (mbPtr->params.isBevel) { - CFStringRef cf; - cf = CFStringCreateWithCString(NULL, - (char*) mbPtr->titleParams.title, kCFStringEncodingUTF8); - SetControlTitleWithCFString(mbPtr->control, cf); - CFRelease(cf); - if (mbPtr->titleParams.len) { - err = SetControlFontStyle(mbPtr->control,&mbPtr->titleParams.style); - if (err !=noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"SetControlFontStyle failed %d\n", (int) err); -#endif - return 1; - } - } + CFStringRef cf = CFStringCreateWithCString(NULL, + (char*) mbPtr->titleParams.title, kCFStringEncodingUTF8); + + SetControlTitleWithCFString(mbPtr->control, cf); + CFRelease(cf); + if (mbPtr->titleParams.len) { + err = ChkErr(SetControlFontStyle, mbPtr->control, + &mbPtr->titleParams.style); + if (err != noErr) { + return 1; + } + } } else { - CFStringRef cfStr; - err = TkMacOSXGetNewMenuID(mbPtr->info.interp, (TkMenu *)mbPtr, 0, &menuID); - if (err != TCL_OK) { - return 1; - } - err = CreateNewMenu(menuID, kMenuAttrDoNotUseUserCommandKeys, - &(mbPtr->menuRef)); - if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"CreateNewMenu failed, %d.\n", (int) err); -#endif - return 1; - } - cfStr = CFStringCreateWithCString(NULL, Tk_PathName(mbPtr->info.tkwin), - kCFStringEncodingUTF8); - if (!cfStr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"CFStringCreateWithCString failed.\n"); -#endif - return 1; - } - err = SetMenuTitleWithCFString(mbPtr->menuRef, cfStr); - CFRelease(cfStr); - if (err != noErr) { -#ifdef TK_MAC_DEBUG - fprintf(stderr,"SetMenuTitleWithCFString failed, %d.\n", (int) err); -#endif - return 1; - } - cfStr = CFStringCreateWithCString(NULL, - (char*) mbPtr->titleParams.title, kCFStringEncodingUTF8); - AppendMenuItemText(mbPtr->menuRef, "\px"); - if (cfStr) { - SetMenuItemTextWithCFString(mbPtr->menuRef, 1, cfStr); - CFRelease(cfStr); - } - err = SetControlData(mbPtr->control, - kControlNoPart, - kControlPopupButtonMenuRefTag, - sizeof(mbPtr->menuRef), &mbPtr->menuRef); - SetControlMinimum(mbPtr->control, 1); - SetControlMaximum(mbPtr->control, 1); - SetControlValue(mbPtr->control, 1); + CFStringRef cfStr; + + err = TkMacOSXGetNewMenuID(mbPtr->info.interp, (TkMenu *) mbPtr, 0, + &menuID); + if (err != TCL_OK) { + return 1; + } + err = ChkErr(CreateNewMenu, menuID, kMenuAttrDoNotUseUserCommandKeys, + &(mbPtr->menuRef)); + if (err != noErr) { + return 1; + } + cfStr = CFStringCreateWithCString(NULL, Tk_PathName(mbPtr->info.tkwin), + kCFStringEncodingUTF8); + if (!cfStr) { + TkMacOSXDbgMsg("CFStringCreateWithCString failed"); + return 1; + } + err = ChkErr(SetMenuTitleWithCFString, mbPtr->menuRef, cfStr); + CFRelease(cfStr); + if (err != noErr) { + return 1; + } + cfStr = CFStringCreateWithCString(NULL, + (char*) mbPtr->titleParams.title, kCFStringEncodingUTF8); + AppendMenuItemText(mbPtr->menuRef, "\px"); + if (cfStr) { + SetMenuItemTextWithCFString(mbPtr->menuRef, 1, cfStr); + CFRelease(cfStr); + } + ChkErr(SetControlData, mbPtr->control, kControlNoPart, + kControlPopupButtonMenuRefTag, sizeof(mbPtr->menuRef), + &mbPtr->menuRef); + SetControlMinimum(mbPtr->control, 1); + SetControlMaximum(mbPtr->control, 1); + SetControlValue(mbPtr->control, 1); } mbPtr->flags |= 2; return 0; @@ -744,28 +712,28 @@ MenuButtonInitControl ( * * SetUserPane * - * Utility function to add a UserPaneDrawProc - * to a userPane control. From MoreControls code - * from Apple DTS. + * Utility function to add a UserPaneDrawProc + * to a userPane control. From MoreControls code + * from Apple DTS. * * Results: - * MacOS system error. + * MacOS system error. * * Side effects: - * The user pane gets a new UserPaneDrawProc. + * The user pane gets a new UserPaneDrawProc. * *-------------------------------------------------------------- */ -OSErr SetUserPaneDrawProc ( +OSStatus +SetUserPaneDrawProc( ControlRef control, ControlUserPaneDrawProcPtr upp) { - ControlUserPaneDrawUPP myControlUserPaneDrawUPP; - myControlUserPaneDrawUPP = NewControlUserPaneDrawUPP(upp); - return SetControlData (control, - kControlNoPart, kControlUserPaneDrawProcTag, - sizeof(myControlUserPaneDrawUPP), - (Ptr) &myControlUserPaneDrawUPP); + ControlUserPaneDrawUPP myControlUserPaneDrawUPP = + NewControlUserPaneDrawUPP(upp); + + return SetControlData(control, kControlNoPart,kControlUserPaneDrawProcTag, + sizeof(myControlUserPaneDrawUPP), (Ptr)&myControlUserPaneDrawUPP); } /* @@ -773,28 +741,30 @@ OSErr SetUserPaneDrawProc ( * * SetUserPaneSetUpSpecialBackgroundProc -- * - * Utility function to add a UserPaneBackgroundProc - * to a userPane control + * Utility function to add a UserPaneBackgroundProc + * to a userPane control * * Results: - * MacOS system error. + * MacOS system error. * * Side effects: - * The user pane gets a new UserPaneBackgroundProc. + * The user pane gets a new UserPaneBackgroundProc. * *-------------------------------------------------------------- */ -OSErr + +OSStatus SetUserPaneSetUpSpecialBackgroundProc( - ControlRef control, + ControlRef control, ControlUserPaneBackgroundProcPtr upp) { - ControlUserPaneBackgroundUPP myControlUserPaneBackgroundUPP; - myControlUserPaneBackgroundUPP = NewControlUserPaneBackgroundUPP(upp); - return SetControlData (control, kControlNoPart, - kControlUserPaneBackgroundProcTag, - sizeof(myControlUserPaneBackgroundUPP), - (Ptr) &myControlUserPaneBackgroundUPP); + ControlUserPaneBackgroundUPP myControlUserPaneBackgroundUPP = + NewControlUserPaneBackgroundUPP(upp); + + return SetControlData(control, kControlNoPart, + kControlUserPaneBackgroundProcTag, + sizeof(myControlUserPaneBackgroundUPP), + (Ptr) &myControlUserPaneBackgroundUPP); } /* @@ -802,27 +772,29 @@ SetUserPaneSetUpSpecialBackgroundProc( * * UserPaneDraw -- * - * This function draws the background of the user pane that will - * lie under checkboxes and radiobuttons. + * This function draws the background of the user pane that will + * lie under checkboxes and radiobuttons. * * Results: - * None. + * None. * * Side effects: - * The user pane gets updated to the current color. + * The user pane gets updated to the current color. * *-------------------------------------------------------------- */ + void UserPaneDraw( ControlRef control, ControlPartCode cpc) { Rect contrlRect; - MacMenuButton * mbPtr; - mbPtr = ( MacMenuButton *)GetControlReference(control); + MacMenuButton * mbPtr = + (MacMenuButton *)(intptr_t)GetControlReference(control); + GetControlBounds(control,&contrlRect); - RGBBackColor (&mbPtr->userPaneBackground); + TkMacOSXSetColorInPort(mbPtr->userPaneBackground, 0, NULL); EraseRect (&contrlRect); } @@ -831,14 +803,14 @@ UserPaneDraw( * * UserPaneBackgroundProc -- * - * This function sets up the background of the user pane that will - * lie under checkboxes and radiobuttons. + * This function sets up the background of the user pane that will + * lie under checkboxes and radiobuttons. * * Results: - * None. + * None. * * Side effects: - * The user pane background gets set to the current color. + * The user pane background gets set to the current color. * *-------------------------------------------------------------- */ @@ -848,45 +820,47 @@ UserPaneBackgroundProc( ControlHandle control, ControlBackgroundPtr info) { - MacMenuButton * mbPtr; - mbPtr = (MacMenuButton *)GetControlReference(control); + MacMenuButton *mbPtr = + (MacMenuButton *)(intptr_t)GetControlReference(control); + if (info->colorDevice) { - RGBBackColor (&mbPtr->userPaneBackground); + TkMacOSXSetColorInPort(mbPtr->userPaneBackground, 0, NULL); } } -/* +/* *-------------------------------------------------------------- - * + * * UpdateControlColors -- - * - * This function will review the colors used to display - * a Macintosh button. If any non-standard colors are - * used we create a custom palette for the button, populate - * with the colors for the button and install the palette. - * - * Under Appearance, we just set the pointer that will be - * used by the UserPaneDrawProc. - * + * + * This function will review the colors used to display + * a Macintosh button. If any non-standard colors are + * used we create a custom palette for the button, populate + * with the colors for the button and install the palette. + * + * Under Appearance, we just set the pointer that will be + * used by the UserPaneDrawProc. + * * Results: - * None. - * + * None. + * * Side effects: - * The Macintosh control may get a custom palette installed. + * The Macintosh control may get a custom palette installed. * *-------------------------------------------------------------- */ static int -UpdateControlColors(MacMenuButton * mbPtr) +UpdateControlColors( + MacMenuButton *mbPtr) { XColor *xcolor; TkMenuButton * butPtr = ( TkMenuButton * )mbPtr; - + /* * Under Appearance we cannot change the background of the - * button itself. However, the color we are setting is the color - * of the containing userPane. This will be the color that peeks + * button itself. However, the color we are setting is the color + * of the containing userPane. This will be the color that peeks * around the rounded corners of the button. * We make this the highlightbackground rather than the background, * because if you color the background of a frame containing a @@ -895,7 +869,7 @@ UpdateControlColors(MacMenuButton * mbPtr) */ xcolor = Tk_3DBorderColor(butPtr->normalBorder); - TkSetMacColor(xcolor->pixel, &mbPtr->userPaneBackground); - + mbPtr->userPaneBackground = xcolor->pixel; + return false; } |