📄 tkmacbutton.c
字号:
width = butPtr->width * avgWidth; } if (butPtr->height > 0) { height = butPtr->height * fm.linespace; } if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) { butPtr->indicatorDiameter = fm.linespace; if (butPtr->type == TYPE_CHECK_BUTTON) { butPtr->indicatorDiameter = (80*butPtr->indicatorDiameter)/100; } butPtr->indicatorSpace = butPtr->indicatorDiameter + avgWidth; } } /* * Now figure out the size of the border decorations for the button. */ if (butPtr->highlightWidth < 0) { butPtr->highlightWidth = 0; } /* * The width and height calculation for Appearance buttons with images & * non-Appearance buttons with images is different. In the latter case, * we add the borderwidth to the inset, since we are going to stamp a * 3-D border over the image. In the former, we add it to the height, * directly, since Appearance will draw the border as part of our control. * * When issuing the geometry request, add extra space for the indicator, * if any, and for the border and padding, plus if this is an image two * extra pixels so the display can be offset by 1 pixel in either * direction for the raised or lowered effect. * * The highlight width corresponds to the default ring on the Macintosh. * As such, the highlight width is only added if the button is the default * button. The actual width of the default ring is one less than the * highlight width as there is also one pixel of spacing. * Appearance buttons with images do not have a highlight ring, because the * Bevel button type does not support one. */ if ((butPtr->image == None) && (butPtr->bitmap == None)) { width += 2*butPtr->padX; height += 2*butPtr->padY; } if ((butPtr->type == TYPE_BUTTON)) { if ((butPtr->image == None) && (butPtr->bitmap == None)) { butPtr->inset = 0; if (butPtr->defaultState != tkDisabledUid) { butPtr->inset += butPtr->highlightWidth; } } else if (TkMacHaveAppearance()) { butPtr->inset = 0; width += (2 * butPtr->borderWidth + 4); height += (2 * butPtr->borderWidth + 4); } else { butPtr->inset = butPtr->borderWidth; width += 2; height += 2; if (butPtr->defaultState != tkDisabledUid) { butPtr->inset += butPtr->highlightWidth; } } } else if ((butPtr->type != TYPE_LABEL)) { if (butPtr->indicatorOn) { butPtr->inset = 0; } else { /* * Under Appearance, the Checkbutton or radiobutton with an image * is represented by a BevelButton with the Sticky defProc... * So we must set its height in the same way as the Button * with an image or bitmap. */ if (((butPtr->image != None) || (butPtr->bitmap != None)) && TkMacHaveAppearance()) { int border; butPtr->inset = 0; if ( butPtr->borderWidth <= 2 ) { border = 6; } else { border = 2 * butPtr->borderWidth + 2; } width += border; height += border; } else { butPtr->inset = butPtr->borderWidth; } } } else { butPtr->inset = butPtr->borderWidth; } Tk_GeometryRequest(butPtr->tkwin, (int) (width + butPtr->indicatorSpace + 2*butPtr->inset), (int) (height + 2*butPtr->inset)); Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);}/* *---------------------------------------------------------------------- * * TkpDestroyButton -- * * Free data structures associated with the button control. * * Results: * None. * * Side effects: * Restores the default control state. * *---------------------------------------------------------------------- */voidTkpDestroyButton( TkButton *butPtr){ /* Do nothing. */}/* *-------------------------------------------------------------- * * DrawBufferedControl -- * * This function uses a dummy Macintosh window to allow * drawing Mac controls to any GWorld (including off-screen * bitmaps). In addition, this code may apply custom * colors passed in the TkButton. * * Results: * None. * * Side effects: * Control is to the GWorld. Static state created on * first invocation of this routine. * *-------------------------------------------------------------- */static voidDrawBufferedControl( TkButton *butPtr, /* Tk button. */ GWorldPtr destPort, /* Off screen GWorld. */ GC gc, /* The GC we are drawing into - needed for * the bevel button */ Pixmap pixmap /* The pixmap we are drawing into - needed for the bevel button */ ) { ControlRef controlHandle; CCTabHandle ccTabHandle; int windowColorChanged = false; RGBColor saveBackColor; int isBevel = 0; if (windowRef == NULL) { InitSampleControls(); } /* * Now swap in the passed in GWorld for the portBits of our fake * window. We also adjust various fields in the WindowRecord to make * the system think this is a normal window. * Note, we can use DrawControlInCurrentPort under Appearance, so we don't * need to swap pixmaps. */ if (!TkMacHaveAppearance()) { ((CWindowPeek) windowRef)->port.portPixMap = destPort->portPixMap; } ((CWindowPeek) windowRef)->port.portRect = destPort->portRect; RectRgn(((CWindowPeek) windowRef)->port.visRgn, &destPort->portRect); RectRgn(((CWindowPeek) windowRef)->strucRgn, &destPort->portRect); RectRgn(((CWindowPeek) windowRef)->updateRgn, &destPort->portRect); RectRgn(((CWindowPeek) windowRef)->contRgn, &destPort->portRect); PortChanged(windowRef); /* * Set up control in hidden window to match what we need * to draw in the buffered window. */ isBevel = 0; switch (butPtr->type) { case TYPE_BUTTON: if (TkMacHaveAppearance()) { if ((butPtr->image == None) && (butPtr->bitmap == None)) { controlHandle = buttonHandle; ccTabHandle = buttonTabHandle; } else { if (butPtr->borderWidth <= 2) { controlHandle = smallBevelHandle; } else if (butPtr->borderWidth == 3) { controlHandle = medBevelHandle; } else { controlHandle = largeBevelHandle; } ccTabHandle = buttonTabHandle; SetupBevelButton(butPtr, controlHandle, destPort, gc, pixmap); isBevel = 1; } } else { controlHandle = buttonHandle; ccTabHandle = buttonTabHandle; } break; case TYPE_RADIO_BUTTON: if (TkMacHaveAppearance()) { if (((butPtr->image == None) && (butPtr->bitmap == None)) || (butPtr->indicatorOn)) { controlHandle = radioHandle; ccTabHandle = radioTabHandle; } else { if (butPtr->borderWidth <= 2) { controlHandle = smallStickyBevelHandle; } else if (butPtr->borderWidth == 3) { controlHandle = medStickyBevelHandle; } else { controlHandle = largeStickyBevelHandle; } ccTabHandle = radioTabHandle; SetupBevelButton(butPtr, controlHandle, destPort, gc, pixmap); isBevel = 1; } } else { controlHandle = radioHandle; ccTabHandle = radioTabHandle; } break; case TYPE_CHECK_BUTTON: if (TkMacHaveAppearance()) { if (((butPtr->image == None) && (butPtr->bitmap == None)) || (butPtr->indicatorOn)) { controlHandle = checkHandle; ccTabHandle = checkTabHandle; } else { if (butPtr->borderWidth <= 2) { controlHandle = smallStickyBevelHandle; } else if (butPtr->borderWidth == 3) { controlHandle = medStickyBevelHandle; } else { controlHandle = largeStickyBevelHandle; } ccTabHandle = checkTabHandle; SetupBevelButton(butPtr, controlHandle, destPort, gc, pixmap); isBevel = 1; } } else { controlHandle = checkHandle; ccTabHandle = checkTabHandle; } break; } (**controlHandle).contrlRect.left = butPtr->inset; (**controlHandle).contrlRect.top = butPtr->inset; (**controlHandle).contrlRect.right = Tk_Width(butPtr->tkwin) - butPtr->inset; (**controlHandle).contrlRect.bottom = Tk_Height(butPtr->tkwin) - butPtr->inset; /* * Setting the control visibility by hand does not * seem to work under Appearance. */ if (TkMacHaveAppearance()) { SetControlVisibility(controlHandle, true, false); (**userPaneHandle).contrlRect.left = 0; (**userPaneHandle).contrlRect.top = 0; (**userPaneHandle).contrlRect.right = Tk_Width(butPtr->tkwin); (**userPaneHandle).contrlRect.bottom = Tk_Height(butPtr->tkwin); } else { (**controlHandle).contrlVis = 255; } if (butPtr->flags & SELECTED) { (**controlHandle).contrlValue = 1; } else { (**controlHandle).contrlValue = 0; } if (butPtr->state == tkActiveUid) { if (isBevel) { (**controlHandle).contrlHilite = kControlButtonPart; } else { switch (butPtr->type) { case TYPE_BUTTON: (**controlHandle).contrlHilite = kControlButtonPart; break; case TYPE_RADIO_BUTTON: (**controlHandle).contrlHilite = kControlRadioButtonPart; break; case TYPE_CHECK_BUTTON: (**controlHandle).contrlHilite = kControlCheckBoxPart; break; } } } else if (butPtr->state == tkDisabledUid) { (**controlHandle).contrlHilite = kControlInactivePart; } else { (**controlHandle).contrlHilite = kControlNoPart; } /* * Before we draw the control we must add the hidden window back to the * main window list. Otherwise, radiobuttons and checkbuttons will draw * incorrectly. I don't really know why - but clearly the control draw * proc needs to have the controls window in the window list. */ ((CWindowPeek) windowRef)->nextWindow = (CWindowPeek) LMGetWindowList(); LMSetWindowList(windowRef); /* * Now we can set the port to our doctered up window. We next need * to muck with the colors for the port & window to draw the control * with the proper Tk colors. If we need to we also draw a default * ring for buttons. * Under Appearance, we draw the control directly into destPort, and * just set the default control data. */ if (TkMacHaveAppearance()) { SetPort((GrafPort *) destPort); } else { SetPort(windowRef); } windowColorChanged = UpdateControlColors(butPtr, controlHandle, ccTabHandle, &saveBackColor); if ((butPtr->type == TYPE_BUTTON) && TkMacHaveAppearance()) { Boolean isDefault; if (butPtr->defaultState == tkActiveUid) { isDefault = true; } else { isDefault = false; } SetControlData(controlHandle, kControlNoPart, kControlPushButtonDefaultTag, sizeof(isDefault), (Ptr) &isDefault); } if (TkMacHaveAppearance()) { DrawControlInCurrentPort(userPaneHandle); } else { Draw1Control(controlHandle); } if (!TkMacHaveAppearance() && (butPtr->type == TYPE_BUTTON) && (butPtr->defaultState == tkActiveUid)) { Rect box = (**controlHandle).contrlRect; RGBColor rgbColor; TkSetMacColor(butPtr->highlightColorPtr->pixel, &rgbColor); RGBForeColor(&rgbColor); PenSize(butPtr->highlightWidth - 1, butPtr->highlightWidth - 1); InsetRect(&box, -butPtr->highlightWidth, -butPtr->highlightWidth); FrameRoundRect(&box, 16, 16); } if (windowColorChanged) { RGBColor dummyColor; ChangeBackgroundWindowColor(windowRef, saveBackColor, &dummyColor); } /* * Clean up: remove the hidden window from the main window list, and * hide the control we drew. */ if (TkMacHaveAppearance()) { SetControlVisibility(controlHandle, false, false); if (isBevel) { KillPicture(bevelButtonContent.u.picture); } } else { (**controlHandle).contrlVis = 0; } LMSetWindowList((WindowRef) ((CWindowPeek) windowRef)->nextWindow);}/* *-------------------------------------------------------------- * * InitSampleControls -- * * This function initializes a dummy Macintosh window and * sample controls to allow drawing Mac controls to any GWorld * (including off-screen bitmaps). * * Results: * None. * * Side effects: * Controls & a window are created. * *-------------------------------------------------------------- */static voidInitSampleControls(){ Rect geometry = {0, 0, 10, 10}; CWindowPeek windowList; /* * Create a dummy window that we can draw to. We will * actually replace this window's bitmap with the one * we want to draw to at a later time. This window and * the data structures attached to it are only deallocated * on exit of the application. */ windowRef = NewCWindow(NULL, &geometry, "\pempty", false, zoomDocProc, (WindowRef) -1, true, 0); if (windowRef == NULL) { panic("Can't allocate buffer window."); } /* * Now add the three standard controls to hidden window. We * only create one of each and reuse them for every widget in * Tk. * Under Appearance, we have to embed the controls in a UserPane * control, so that we can color the background text in * radiobuttons and checkbuttons. */ SetPort(windowRef); if (TkMacHaveAppearance()) { OSErr err; ControlRef dontCare; /* Adding UserPaneBackgroundProcs to the root control does * not seem to work, so we have to add another UserPane to * the root control. */ err = CreateRootControl(windowRef, &dontCare); if (err != noErr) { panic("Can't create root control in DrawBufferedControl"); } userPaneHandle = NewControl(windowRef, &geometry, "\p", true, kControlSupportsEmbedding|kControlHasSpecialBackground, 0, 1, kControlUserPaneProc, (SInt32) 0); SetUserPaneSetUpSpecialBackgroundProc(userPaneHandle, UserPaneBackgroundProc); SetUserPaneDrawProc(userPaneHandle, UserPaneDraw); buttonHandle = NewControl(windowRef, &geometry, "\p", false, 1, 0, 1, kControlPushButtonProc, (SInt32) 0); EmbedControl(buttonHandle, userPaneHandle); checkHandle = NewControl(windowRef, &geometry, "\p", false, 1, 0, 1, kControlCheckBoxProc, (SInt32) 0); EmbedControl(checkHandle, userPaneHandle); radioHandle = NewControl(windowRef, &geometry, "\p", false, 1, 0, 1, kControlRadioButtonProc, (SInt32) 0); EmbedControl(radioHandle, userPaneHandle); smallBevelHandle = NewControl(windowRef, &geometry, "\p", false, 0, 0, kControlBehaviorOffsetContents << 16 | kControlContentPictHandle, kControlBevelButtonSmallBevelProc, (SInt32) 0); EmbedControl(smallBevelHandle, userPaneHandle); medBevelHandle = NewControl(windowRef, &geometry, "\p",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -