📄 tkwinbutton.c
字号:
* -relief on mouseover. Hence, we can tell if we are in mouse-over by * comparing relief against overRelief. This is an aweful kludge, but * it gives use the desired behavior while keeping the code backwards * compatible. */ relief = butPtr->relief; if ((butPtr->type >= TYPE_CHECK_BUTTON) && !butPtr->indicatorOn) { if (butPtr->flags & SELECTED) { relief = TK_RELIEF_SUNKEN; } else if (butPtr->overRelief != relief) { relief = butPtr->offRelief; } } /* * Compute width of default ring and offset for pushed buttons. */ if (butPtr->type == TYPE_BUTTON) { defaultWidth = ((butPtr->defaultState == DEFAULT_ACTIVE) ? butPtr->highlightWidth : 0); offset = 1; } else { defaultWidth = 0; if ((butPtr->type >= TYPE_CHECK_BUTTON) && !butPtr->indicatorOn) { offset = 1; } else { offset = 0; } } /* * In order to avoid screen flashes, this procedure redraws * the button in a pixmap, then copies the pixmap to the * screen in a single operation. This means that there's no * point in time where the on-sreen image has been cleared. */ pixmap = Tk_GetPixmap(butPtr->display, Tk_WindowId(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin)); Tk_Fill3DRectangle(tkwin, pixmap, border, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT); /* * Display image or bitmap or text for button. */ if (butPtr->image != None) { Tk_SizeOfImage(butPtr->image, &width, &height); haveImage = 1; } else if (butPtr->bitmap != None) { Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height); haveImage = 1; } imageWidth = width; imageHeight = height; haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0); if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) { int fullWidth = 0, fullHeight = 0; switch ((enum compound) butPtr->compound) { case COMPOUND_TOP: case COMPOUND_BOTTOM: { /* Image is above or below text */ if (butPtr->compound == COMPOUND_TOP) { textYOffset = height + butPtr->padY; } else { imageYOffset = butPtr->textHeight + butPtr->padY; } fullHeight = height + butPtr->textHeight + butPtr->padY; fullWidth = (width > butPtr->textWidth ? width : butPtr->textWidth); textXOffset = (fullWidth - butPtr->textWidth)/2; imageXOffset = (fullWidth - width)/2; break; } case COMPOUND_LEFT: case COMPOUND_RIGHT: { /* Image is left or right of text */ if (butPtr->compound == COMPOUND_LEFT) { textXOffset = width + butPtr->padX; } else { imageXOffset = butPtr->textWidth + butPtr->padX; } fullWidth = butPtr->textWidth + butPtr->padX + width; fullHeight = (height > butPtr->textHeight ? height : butPtr->textHeight); textYOffset = (fullHeight - butPtr->textHeight)/2; imageYOffset = (fullHeight - height)/2; break; } case COMPOUND_CENTER: { /* Image and text are superimposed */ fullWidth = (width > butPtr->textWidth ? width : butPtr->textWidth); fullHeight = (height > butPtr->textHeight ? height : butPtr->textHeight); textXOffset = (fullWidth - butPtr->textWidth)/2; imageXOffset = (fullWidth - width)/2; textYOffset = (fullHeight - butPtr->textHeight)/2; imageYOffset = (fullHeight - height)/2; break; } case COMPOUND_NONE: {break;} } TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY, butPtr->indicatorSpace + fullWidth, fullHeight, &x, &y); x += butPtr->indicatorSpace; if (relief == TK_RELIEF_SUNKEN) { x += offset; y += offset; } imageXOffset += x; imageYOffset += y; if (butPtr->image != NULL) { if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) { Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height, pixmap, imageXOffset, imageYOffset); } else { Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap, imageXOffset, imageYOffset); } } else { XSetClipOrigin(butPtr->display, gc, imageXOffset, imageYOffset); XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc, 0, 0, (unsigned int) width, (unsigned int) height, imageXOffset, imageYOffset, 1); XSetClipOrigin(butPtr->display, gc, 0, 0); } Tk_DrawTextLayout(butPtr->display, pixmap, gc, butPtr->textLayout, x + textXOffset, y + textYOffset, 0, -1); Tk_UnderlineTextLayout(butPtr->display, pixmap, gc, butPtr->textLayout, x + textXOffset, y + textYOffset, butPtr->underline); height = fullHeight; drawRing = 1; } else { if (haveImage) { TkComputeAnchor(butPtr->anchor, tkwin, 0, 0, butPtr->indicatorSpace + width, height, &x, &y); x += butPtr->indicatorSpace; if (relief == TK_RELIEF_SUNKEN) { x += offset; y += offset; } imageXOffset += x; imageYOffset += y; if (butPtr->image != NULL) { if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) { Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height, pixmap, imageXOffset, imageYOffset); } else { Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap, imageXOffset, imageYOffset); } } else { XSetClipOrigin(butPtr->display, gc, x, y); XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc, 0, 0, (unsigned int) width, (unsigned int) height, x, y, 1); XSetClipOrigin(butPtr->display, gc, 0, 0); } } else { TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY, butPtr->indicatorSpace + butPtr->textWidth, butPtr->textHeight, &x, &y); x += butPtr->indicatorSpace; if (relief == TK_RELIEF_SUNKEN) { x += offset; y += offset; } Tk_DrawTextLayout(butPtr->display, pixmap, gc, butPtr->textLayout, x, y, 0, -1); Tk_UnderlineTextLayout(butPtr->display, pixmap, gc, butPtr->textLayout, x, y, butPtr->underline); height = butPtr->textHeight; drawRing = 1; } } /* * Draw the focus ring. If this is a push button then we need to * put it around the inner edge of the border, otherwise we put it * around the text. The text offsets are only non-zero when this * is a compound button. */ if (drawRing && butPtr->flags & GOT_FOCUS && butPtr->type != TYPE_LABEL) { dc = TkWinGetDrawableDC(butPtr->display, pixmap, &state); if (butPtr->type == TYPE_BUTTON || !butPtr->indicatorOn) { rect.top = butPtr->borderWidth + 1 + defaultWidth; rect.left = rect.top; rect.right = Tk_Width(tkwin) - rect.left; rect.bottom = Tk_Height(tkwin) - rect.top; } else { rect.top = y-1 + textYOffset; rect.left = x-1 + textXOffset; rect.right = x+butPtr->textWidth + 1 + textXOffset; rect.bottom = y+butPtr->textHeight + 2 + textYOffset; } SetTextColor(dc, gc->foreground); SetBkColor(dc, gc->background); DrawFocusRect(dc, &rect); TkWinReleaseDrawableDC(pixmap, dc, &state); } y += height/2; /* * Draw the indicator for check buttons and radio buttons. At this * point x and y refer to the top-left corner of the text or image * or bitmap. */ if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn && tsdPtr->boxesPtr) { int xSrc, ySrc; x -= butPtr->indicatorSpace; y -= butPtr->indicatorDiameter / 2; xSrc = (butPtr->flags & SELECTED) ? tsdPtr->boxWidth : 0; if (butPtr->state == STATE_ACTIVE) { xSrc += tsdPtr->boxWidth*2; } ySrc = (butPtr->type == TYPE_RADIO_BUTTON) ? 0 : tsdPtr->boxHeight; /* * Update the palette in the boxes bitmap to reflect the current * button colors. Note that this code relies on the layout of the * bitmap's palette. Also, all of the colors used to draw the * bitmap must be in the palette that is selected into the DC of * the offscreen pixmap. This requires that the static colors * be placed into the palette. */ if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg == NULL)) { boxesPalette[PAL_CHECK] = FlipColor(TkWinGetBorderPixels(tkwin, border, TK_3D_DARK_GC)); } else { boxesPalette[PAL_CHECK] = FlipColor(gc->foreground); } boxesPalette[PAL_TOP_OUTER] = FlipColor(TkWinGetBorderPixels(tkwin, border, TK_3D_DARK_GC)); boxesPalette[PAL_TOP_INNER] = FlipColor(TkWinGetBorderPixels(tkwin, border, TK_3D_DARK2)); boxesPalette[PAL_BOTTOM_INNER] = FlipColor(TkWinGetBorderPixels(tkwin, border, TK_3D_LIGHT2)); boxesPalette[PAL_BOTTOM_OUTER] = FlipColor(TkWinGetBorderPixels(tkwin, border, TK_3D_LIGHT_GC)); if (butPtr->state == STATE_DISABLED) { boxesPalette[PAL_INTERIOR] = FlipColor(TkWinGetBorderPixels(tkwin, border, TK_3D_LIGHT2)); } else if (butPtr->selectBorder != NULL) { boxesPalette[PAL_INTERIOR] = FlipColor(TkWinGetBorderPixels(tkwin, butPtr->selectBorder, TK_3D_FLAT_GC)); } else { boxesPalette[PAL_INTERIOR] = FlipColor(GetSysColor(COLOR_WINDOW)); } boxesPalette[PAL_BACKGROUND] = FlipColor(TkWinGetBorderPixels(tkwin, border, TK_3D_FLAT_GC)); dc = TkWinGetDrawableDC(butPtr->display, pixmap, &state); StretchDIBits(dc, x, y, tsdPtr->boxWidth, tsdPtr->boxHeight, xSrc, ySrc, tsdPtr->boxWidth, tsdPtr->boxHeight, tsdPtr->boxesBits, (LPBITMAPINFO) tsdPtr->boxesPtr, DIB_RGB_COLORS, SRCCOPY); TkWinReleaseDrawableDC(pixmap, dc, &state); } /* * If the button is disabled with a stipple rather than a special * foreground color, generate the stippled effect. If the widget * is selected and we use a different background color when selected, * must temporarily modify the GC so the stippling is the right color. */ if ((butPtr->state == STATE_DISABLED) && ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) { if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn && (butPtr->selectBorder != NULL)) { XSetForeground(butPtr->display, butPtr->stippleGC, Tk_3DBorderColor(butPtr->selectBorder)->pixel); } /* * Stipple the whole button if no disabledFg was specified, * otherwise restrict stippling only to displayed image */ if (butPtr->disabledFg == NULL) { XFillRectangle(butPtr->display, pixmap, butPtr->stippleGC, 0, 0, (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin)); } else { XFillRectangle(butPtr->display, pixmap, butPtr->stippleGC, imageXOffset, imageYOffset, (unsigned) imageWidth, (unsigned) imageHeight); } if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn && (butPtr->selectBorder != NULL)) { XSetForeground(butPtr->display, butPtr->stippleGC, Tk_3DBorderColor(butPtr->normalBorder)->pixel); } } /* * Draw the border and traversal highlight last. This way, if the * button's contents overflow they'll be covered up by the border. */ if (relief != TK_RELIEF_FLAT) { Tk_Draw3DRectangle(tkwin, pixmap, border, defaultWidth, defaultWidth, Tk_Width(tkwin) - 2*defaultWidth, Tk_Height(tkwin) - 2*defaultWidth, butPtr->borderWidth, relief); } if (defaultWidth != 0) { dc = TkWinGetDrawableDC(butPtr->display, pixmap, &state); TkWinFillRect(dc, 0, 0, Tk_Width(tkwin), defaultWidth, butPtr->highlightColorPtr->pixel); TkWinFillRect(dc, 0, 0, defaultWidth, Tk_Height(tkwin), butPtr->highlightColorPtr->pixel); TkWinFillRect(dc, 0, Tk_Height(tkwin) - defaultWidth, Tk_Width(tkwin), defaultWidth, butPtr->highlightColorPtr->pixel); TkWinFillRect(dc, Tk_Width(tkwin) - defaultWidth, 0, defaultWidth, Tk_Height(tkwin), butPtr->highlightColorPtr->pixel); TkWinReleaseDrawableDC(pixmap, dc, &state); } if (butPtr->flags & GOT_FOCUS) { Tk_SetCaretPos(tkwin, x, y, 0 /* not used */); } /* * Copy the information from the off-screen pixmap onto the screen, * then delete the pixmap. */ XCopyArea(butPtr->display, pixmap, Tk_WindowId(tkwin), butPtr->copyGC, 0, 0, (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin), 0, 0); Tk_FreePixmap(butPtr->display, pixmap);}/* *---------------------------------------------------------------------- * * TkpComputeButtonGeometry -- * * After changes in a button's text or bitmap, this procedure * recomputes the button's geometry and passes this information * along to the geometry manager for the window. * * Results: * None. * * Side effects: * The button's window may change size. * *---------------------------------------------------------------------- */voidTkpComputeButtonGeometry(butPtr) register TkButton *butPtr; /* Button whose geometry may have changed. */{ int txtWidth, txtHeight; /* Width and height of text */ int imgWidth, imgHeight; /* Width and height of image */ int width = 0, height = 0; /* Width and height of button */ int haveImage, haveText; int avgWidth; int minWidth; /* Vertical and horizontal dialog units size in pixels. */ double vDLU, hDLU; Tk_FontMetrics fm; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (butPtr->highlightWidth < 0) { butPtr->highlightWidth = 0; } butPtr->inset = butPtr->highlightWidth + butPtr->borderWidth; butPtr->indicatorSpace = 0; if (!tsdPtr->boxesPtr) { InitBoxes(); } /* Figure out image metrics */ if (butPtr->image != NULL) { Tk_SizeOfImage(butPtr->image, &imgWidth, &imgHeight); haveImage = 1; } else if (butPtr->bitmap != None) { Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &imgWidth, &imgHeight); haveImage = 1; } else { imgWidth = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -