summaryrefslogtreecommitdiffstats
path: root/win/tkWinButton.c
diff options
context:
space:
mode:
Diffstat (limited to 'win/tkWinButton.c')
-rw-r--r--win/tkWinButton.c495
1 files changed, 335 insertions, 160 deletions
diff --git a/win/tkWinButton.c b/win/tkWinButton.c
index d6af35b..e0998b5 100644
--- a/win/tkWinButton.c
+++ b/win/tkWinButton.c
@@ -4,7 +4,7 @@
* This file implements the Windows specific portion of the button
* widgets.
*
- * Copyright (c) 1996-1998 Sun Microsystems, Inc.
+ * Copyright © 1996-1998 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -36,41 +36,72 @@ typedef struct WinButton {
} WinButton;
/*
- * The following macro reverses the order of RGB bytes to convert between
- * RGBQUAD and COLORREF values.
+ * Cached information about the checkbutton and radiobutton indicator boxes
*/
-#define FlipColor(rgb) (RGB(GetBValue(rgb),GetGValue(rgb),GetRValue(rgb)))
+typedef struct {
+ BOOLEAN initialized;
+ int boxSize; /* Width & height of the box. */
+} ThreadSpecificData;
+static Tcl_ThreadDataKey dataKey;
/*
- * The following enumeration defines the meaning of the palette entries in the
- * "buttons" image used to draw checkbox and radiobutton indicators.
+ * Data of the SVG images used for drawing the indicators
*/
-enum {
- PAL_CHECK = 0,
- PAL_TOP_OUTER = 1,
- PAL_BOTTOM_OUTER = 2,
- PAL_BOTTOM_INNER = 3,
- PAL_INTERIOR = 4,
- PAL_TOP_INNER = 5,
- PAL_BACKGROUND = 6
-};
-
-/*
- * Cached information about the boxes bitmap, and the default border width for
- * a button in string form for use in Tk_OptionSpec for the various button
- * widget classes.
- */
-
-typedef struct {
- BITMAPINFOHEADER *boxesPtr; /* Information about the bitmap. */
- DWORD *boxesPalette; /* Pointer to color palette. */
- LPSTR boxesBits; /* Pointer to bitmap data. */
- DWORD boxHeight; /* Height of each sub-image. */
- DWORD boxWidth; /* Width of each sub-image. */
-} ThreadSpecificData;
-static Tcl_ThreadDataKey dataKey;
+static const char checkbtnOffData[] = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <path d='m0 0v15h1v-14h14v-1z' fill='#a0a0a0'/>\n\
+ <path d='m1 1v13h1v-12h12v-1z' fill='#696969'/>\n\
+ <path d='m14 1v13h-13v1h14v-14z' fill='#e3e3e3'/>\n\
+ <path d='m15 0v15h-15v1h16v-16z' fill='#eeeeee'/>\n\
+ <rect x='2' y='2' width='12' height='12' fill='#ffffff'/>\n\
+ </svg>";
+
+static const char checkbtnOnData[] = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <path d='m0 0v15h1v-14h14v-1z' fill='#a0a0a0'/>\n\
+ <path d='m1 1v13h1v-12h12v-1z' fill='#696969'/>\n\
+ <path d='m14 1v13h-13v1h14v-14z' fill='#e3e3e3'/>\n\
+ <path d='m15 0v15h-15v1h16v-16z' fill='#eeeeee'/>\n\
+ <rect x='2' y='2' width='12' height='12' fill='#ffffff'/>\n\
+ <path d='m4.5 8 3 3 4-6' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'/>\n\
+ </svg>";
+
+static const char radiobtnOffData[] = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <defs>\n\
+ <linearGradient id='linearGradientOuter' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n\
+ <stop stop-color='#a0a0a0' offset='0'/>\n\
+ <stop stop-color='#eeeeee' offset='1'/>\n\
+ </linearGradient>\n\
+ <linearGradient id='linearGradientInner' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n\
+ <stop stop-color='#696969' offset='0'/>\n\
+ <stop stop-color='#e3e3e3' offset='1'/>\n\
+ </linearGradient>\n\
+ </defs>\n\
+ <circle cx='8' cy='8' r='8' fill='url(#linearGradientOuter)'/>\n\
+ <circle cx='8' cy='8' r='7' fill='url(#linearGradientInner)'/>\n\
+ <circle cx='8' cy='8' r='6' fill='#ffffff'/>\n\
+ </svg>";
+
+static const char radiobtnOnData[] = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <defs>\n\
+ <linearGradient id='linearGradientOuter' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n\
+ <stop stop-color='#a0a0a0' offset='0'/>\n\
+ <stop stop-color='#eeeeee' offset='1'/>\n\
+ </linearGradient>\n\
+ <linearGradient id='linearGradientInner' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n\
+ <stop stop-color='#696969' offset='0'/>\n\
+ <stop stop-color='#e3e3e3' offset='1'/>\n\
+ </linearGradient>\n\
+ </defs>\n\
+ <circle cx='8' cy='8' r='8' fill='url(#linearGradientOuter)'/>\n\
+ <circle cx='8' cy='8' r='7' fill='url(#linearGradientInner)'/>\n\
+ <circle cx='8' cy='8' r='6' fill='#ffffff'/>\n\
+ <circle cx='8' cy='8' r='3' fill='#000000'/>\n\
+ </svg>";
/*
* Declarations for functions defined in this file.
@@ -79,8 +110,14 @@ static Tcl_ThreadDataKey dataKey;
static LRESULT CALLBACK ButtonProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam);
static Window CreateProc(Tk_Window tkwin, Window parent,
- ClientData instanceData);
-static void InitBoxes(void);
+ void *instanceData);
+static void InitBoxes(Tk_Window tkwin);
+static void ColorToStr(COLORREF color, char *colorStr);
+static void ImageChanged(void *clientData,
+ int x, int y, int width, int height,
+ int imageWidth, int imageHeight);
+static void TkpDrawIndicator(TkButton *butPtr, Drawable d,
+ Tk_3DBorder border, GC gc, int dim, int x, int y);
/*
* The class procedure table for the button widgets.
@@ -90,7 +127,7 @@ const Tk_ClassProcs tkpButtonProcs = {
sizeof(Tk_ClassProcs), /* size */
TkButtonWorldChanged, /* worldChangedProc */
CreateProc, /* createProc */
- NULL /* modalProc */
+ NULL /* modalProc */
};
@@ -99,68 +136,27 @@ const Tk_ClassProcs tkpButtonProcs = {
*
* InitBoxes --
*
- * This function load the Tk 3d button bitmap. "buttons" is a 16 color
- * bitmap that is laid out such that the top row contains the 4 checkbox
- * images, and the bottom row contains the radio button images. Note that
- * the bitmap is stored in bottom-up format. Also, the first seven
- * palette entries are used to identify the different parts of the
- * bitmaps so we can do the appropriate color mappings based on the
- * current button colors.
+ * This function computes the size of the checkbutton and radiobutton
+ * indicator boxes, according to the display's scaling percentage.
*
* Results:
* None.
*
* Side effects:
- * Loads the "buttons" resource.
+ * Populates the thread-private data.
*
*----------------------------------------------------------------------
*/
static void
-InitBoxes(void)
+InitBoxes(Tk_Window tkwin)
{
- /*
- * For DLLs like Tk, the HINSTANCE is the same as the HMODULE.
- */
-
- HMODULE module = (HINSTANCE) Tk_GetHINSTANCE();
- HRSRC hrsrc;
- HGLOBAL hblk;
- LPBITMAPINFOHEADER newBitmap;
- size_t size;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ double scalingLevel = TkScalingLevel(tkwin);
- hrsrc = FindResourceW(module, L"buttons", (LPWSTR) RT_BITMAP);
- if (hrsrc == NULL) {
- Tcl_Panic("FindResourceW() failed for buttons bitmap resource, "
- "resources in tk_base.rc must be linked into Tk dll or static executable");
- } else {
- hblk = LoadResource(module, hrsrc);
- tsdPtr->boxesPtr = (LPBITMAPINFOHEADER)LockResource(hblk);
- }
-
- /*
- * Copy the DIBitmap into writable memory.
- */
-
- if (tsdPtr->boxesPtr != NULL && !(tsdPtr->boxesPtr->biWidth % 4)
- && !(tsdPtr->boxesPtr->biHeight % 2)) {
- size = tsdPtr->boxesPtr->biSize
- + (sizeof(RGBQUAD) << tsdPtr->boxesPtr->biBitCount)
- + tsdPtr->boxesPtr->biSizeImage;
- newBitmap = (LPBITMAPINFOHEADER)ckalloc(size);
- memcpy(newBitmap, tsdPtr->boxesPtr, size);
- tsdPtr->boxesPtr = newBitmap;
- tsdPtr->boxWidth = tsdPtr->boxesPtr->biWidth / 4;
- tsdPtr->boxHeight = tsdPtr->boxesPtr->biHeight / 2;
- tsdPtr->boxesPalette = (DWORD*) (((LPSTR) tsdPtr->boxesPtr)
- + tsdPtr->boxesPtr->biSize);
- tsdPtr->boxesBits = ((LPSTR) tsdPtr->boxesPalette)
- + (sizeof(RGBQUAD) << tsdPtr->boxesPtr->biBitCount);
- } else {
- tsdPtr->boxesPtr = NULL;
- }
+ tsdPtr->boxSize = (int)(16.0 * scalingLevel);
+ tsdPtr->initialized = TRUE;
}
/*
@@ -238,7 +234,7 @@ static Window
CreateProc(
Tk_Window tkwin, /* Token for window. */
Window parentWin, /* Parent of new window. */
- ClientData instanceData) /* Button instance data. */
+ void *instanceData) /* Button instance data. */
{
Window window;
HWND parent;
@@ -296,6 +292,228 @@ TkpDestroyButton(
/*
*----------------------------------------------------------------------
*
+ * ColorToStr --
+ *
+ * Writes a given color to a string, in the format "RRGGBB".
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes the content of the memory area pointed to by the 2nd argument.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ColorToStr(
+ COLORREF color, /* specifies a color */
+ char *colorStr) /* memory area to which the color is to be
+ output in the format "RRGGBB" */
+{
+ snprintf(colorStr, 7, "%02x%02x%02x",
+ GetRValue(color), GetGValue(color), GetBValue(color));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ImageChanged --
+ *
+ * Dummy function to be passed to Tk_GetImage().
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ImageChanged(
+ void *clientData,
+ int x, int y, int width, int height,
+ int imageWidth, int imageHeight)
+{
+ (void)clientData;
+ (void)x; (void)y; (void)width; (void)height;
+ (void)imageWidth; (void)imageHeight;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpDrawIndicator -
+ *
+ * Draws the indicator image in the drawable at the (x,y) location.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * An image is drawn in the drawable at the given location.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TkpDrawIndicator(
+ TkButton *butPtr, /* checkbutton or radiobutton */
+ Drawable d, /* what to draw on */
+ Tk_3DBorder border, /* colors of the border */
+ GC gc, /* graphics context */
+ int dim, /* width & height of the indicator */
+ int x, int y) /* where to draw */
+{
+ Tk_Window tkwin = butPtr->tkwin;
+ char topOuterColorStr[7], btmOuterColorStr[7], topInnerColorStr[7],
+ btmInnerColorStr[7], interiorColorStr[7], checkColorStr[7];
+ Tcl_Interp *interp = Tk_Interp(tkwin);
+ char imgName[80];
+ Tk_Image img;
+ const char *svgDataPtr;
+ size_t svgDataLen;
+ char *svgDataCopy;
+ char *topOuterColorPtr, *btmOuterColorPtr, *topInnerColorPtr,
+ *btmInnerColorPtr, *interiorColorPtr, *checkColorPtr;
+ const char *cmdFmt;
+ size_t scriptSize;
+ char *script;
+ int code;
+
+ /*
+ * Construct the color strings topOuterColorStr, btmOuterColorStr,
+ * topInnerColorStr, btmInnerColorStr, interiorColorStr, and checkColorStr
+ */
+
+ ColorToStr(TkWinGetBorderPixels(tkwin, border, TK_3D_DARK_GC),
+ topOuterColorStr);
+ ColorToStr(TkWinGetBorderPixels(tkwin, border, TK_3D_LIGHT_GC),
+ btmOuterColorStr);
+ ColorToStr(TkWinGetBorderPixels(tkwin, border, TK_3D_DARK2),
+ topInnerColorStr);
+ ColorToStr(TkWinGetBorderPixels(tkwin, border, TK_3D_LIGHT2),
+ btmInnerColorStr);
+
+ if (butPtr->state == STATE_ACTIVE) {
+ ColorToStr(TkWinGetBorderPixels(tkwin, butPtr->activeBorder,
+ TK_3D_FLAT_GC), interiorColorStr);
+ } else if (butPtr->state == STATE_DISABLED || (butPtr->flags & TRISTATED)) {
+ ColorToStr(TkWinGetBorderPixels(tkwin, border, TK_3D_LIGHT2),
+ interiorColorStr);
+ } else if (butPtr->selectBorder != NULL) {
+ ColorToStr(TkWinGetBorderPixels(tkwin, butPtr->selectBorder,
+ TK_3D_FLAT_GC), interiorColorStr);
+ } else {
+ ColorToStr(GetSysColor(COLOR_WINDOW), interiorColorStr);
+ }
+
+ if (butPtr->state == STATE_DISABLED && butPtr->disabledFg == NULL) {
+ ColorToStr(TkWinGetBorderPixels(tkwin, border, TK_3D_DARK_GC),
+ checkColorStr);
+ } else {
+ ColorToStr(gc->foreground, checkColorStr);
+ }
+
+ /*
+ * Check whether there is an SVG image of this size for the indicator's
+ * type (0 = checkbtn, 1 = radiobtn) and these color strings
+ */
+
+ snprintf(imgName, sizeof(imgName),
+ "::tk::icons::indicator%d_%d_%s_%s_%s_%s_%s_%s",
+ dim, butPtr->type == TYPE_RADIO_BUTTON,
+ topOuterColorStr, btmOuterColorStr, topInnerColorStr,
+ btmInnerColorStr, interiorColorStr,
+ (butPtr->flags & (SELECTED|TRISTATED)) ? checkColorStr : "XXXXXX");
+ img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
+ if (img == NULL) {
+ /*
+ * Determine the SVG data to use for the photo image
+ */
+
+ if (butPtr->type == TYPE_CHECK_BUTTON) {
+ svgDataPtr = ((butPtr->flags & (SELECTED|TRISTATED)) ?
+ checkbtnOnData : checkbtnOffData);
+ } else {
+ svgDataPtr = ((butPtr->flags & (SELECTED|TRISTATED)) ?
+ radiobtnOnData : radiobtnOffData);
+ }
+
+ /*
+ * Copy the string pointed to by svgDataPtr to
+ * a newly allocated memory area svgDataCopy
+ */
+
+ svgDataLen = strlen(svgDataPtr);
+ svgDataCopy = (char *)attemptckalloc(svgDataLen + 1);
+ if (svgDataCopy == NULL) {
+ return;
+ }
+ memcpy(svgDataCopy, svgDataPtr, svgDataLen);
+ svgDataCopy[svgDataLen] = '\0';
+
+ /*
+ * Update the colors within svgDataCopy
+ */
+
+ topOuterColorPtr = strstr(svgDataCopy, "a0a0a0");
+ btmOuterColorPtr = strstr(svgDataCopy, "eeeeee");
+ topInnerColorPtr = strstr(svgDataCopy, "696969");
+ btmInnerColorPtr = strstr(svgDataCopy, "e3e3e3");
+ interiorColorPtr = strstr(svgDataCopy, "ffffff");
+ checkColorPtr = strstr(svgDataCopy, "000000");
+
+ assert(topOuterColorPtr);
+ assert(btmOuterColorPtr);
+ assert(topInnerColorPtr);
+ assert(btmInnerColorPtr);
+ assert(interiorColorPtr);
+
+ memcpy(topOuterColorPtr, topOuterColorStr, 6);
+ memcpy(btmOuterColorPtr, btmOuterColorStr, 6);
+ memcpy(topInnerColorPtr, topInnerColorStr, 6);
+ memcpy(btmInnerColorPtr, btmInnerColorStr, 6);
+ memcpy(interiorColorPtr, interiorColorStr, 6);
+ if (checkColorPtr != NULL) {
+ memcpy(checkColorPtr, checkColorStr, 6);
+ }
+
+ /*
+ * Create an SVG photo image from svgDataCopy
+ */
+
+ cmdFmt = "image create photo %s -format $::tk::svgFmt -data {%s}";
+ scriptSize = strlen(cmdFmt) + strlen(imgName) + svgDataLen;
+ script = (char *)attemptckalloc(scriptSize);
+ if (script == NULL) {
+ ckfree(svgDataCopy);
+ return;
+ }
+ snprintf(script, scriptSize, cmdFmt, imgName, svgDataCopy);
+ ckfree(svgDataCopy);
+ code = Tcl_EvalEx(interp, script, TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
+ ckfree(script);
+ if (code != TCL_OK) {
+ Tcl_BackgroundException(interp, code);
+ return;
+ }
+ img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
+ }
+
+ /*
+ * Display the image
+ */
+
+ Tk_RedrawImage(img, 0, 0, dim, dim, d, x, y);
+ Tk_FreeImage(img);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TkpDisplayButton --
*
* This procedure is invoked to display a button widget. It is normally
@@ -312,7 +530,7 @@ TkpDestroyButton(
void
TkpDisplayButton(
- ClientData clientData) /* Information about widget. */
+ void *clientData) /* Information about widget. */
{
TkWinDCState state;
HDC dc;
@@ -338,17 +556,20 @@ TkpDisplayButton(
int imageXOffset = 0, imageYOffset = 0;
/* Image information that will be used to
* restrict disabled pixmap as well. */
- DWORD *boxesPalette;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
- boxesPalette= tsdPtr->boxesPalette;
butPtr->flags &= ~REDRAW_PENDING;
if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
return;
}
+ Tk_GetPixelsFromObj(NULL, tkwin, butPtr->borderWidthPtr, &butPtr->borderWidth);
+ Tk_GetPixelsFromObj(NULL, tkwin, butPtr->highlightWidthPtr, &butPtr->highlightWidth);
+ Tk_GetPixelsFromObj(NULL, tkwin, butPtr->padXPtr, &butPtr->padX);
+ Tk_GetPixelsFromObj(NULL, tkwin, butPtr->padYPtr, &butPtr->padY);
+
border = butPtr->normalBorder;
if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) {
gc = butPtr->disabledGC;
@@ -407,7 +628,7 @@ TkpDisplayButton(
if (butPtr->type == TYPE_LABEL) {
defaultWidth = butPtr->highlightWidth;
- offset = 0;
+ offset = 0;
} else if (butPtr->type == TYPE_BUTTON) {
defaultWidth = ((butPtr->defaultState == DEFAULT_ACTIVE)
? butPtr->highlightWidth : 0);
@@ -653,65 +874,16 @@ TkpDisplayButton(
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.
+ * 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;
-
+ && tsdPtr->initialized) {
x -= butPtr->indicatorSpace;
y -= butPtr->indicatorDiameter / 2;
- xSrc = (butPtr->flags & (SELECTED|TRISTATED)) ? 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) || (butPtr->flags & TRISTATED)) {
- 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, (int)tsdPtr->boxWidth, (int)tsdPtr->boxHeight,
- xSrc, ySrc, (int)tsdPtr->boxWidth, (int)tsdPtr->boxHeight,
- tsdPtr->boxesBits, (LPBITMAPINFO) tsdPtr->boxesPtr,
- DIB_RGB_COLORS, SRCCOPY);
- TkWinReleaseDrawableDC(pixmap, dc, &state);
+ TkpDrawIndicator(butPtr, pixmap, border, gc, tsdPtr->boxSize, x, y + 1);
}
/*
@@ -757,19 +929,19 @@ TkpDisplayButton(
if (relief != TK_RELIEF_FLAT) {
Tk_Draw3DRectangle(tkwin, pixmap, border,
defaultWidth, defaultWidth,
- Tk_Width(tkwin) - 2*defaultWidth,
- Tk_Height(tkwin) - 2*defaultWidth,
+ Tk_Width(tkwin) - 2 * defaultWidth,
+ Tk_Height(tkwin) - 2 * defaultWidth,
butPtr->borderWidth, relief);
}
if (defaultWidth != 0) {
- int highlightColor;
+ int highlightColor;
dc = TkWinGetDrawableDC(butPtr->display, pixmap, &state);
- if (butPtr->type == TYPE_LABEL) {
- highlightColor = (int) Tk_3DBorderColor(butPtr->highlightBorder)->pixel;
- } else {
- highlightColor = (int) butPtr->highlightColorPtr->pixel;
- }
+ if (butPtr->type == TYPE_LABEL) {
+ highlightColor = (int) Tk_3DBorderColor(butPtr->highlightBorder)->pixel;
+ } else {
+ highlightColor = (int) butPtr->highlightColorPtr->pixel;
+ }
TkWinFillRect(dc, 0, 0, Tk_Width(tkwin), defaultWidth,
highlightColor);
TkWinFillRect(dc, 0, 0, defaultWidth, Tk_Height(tkwin),
@@ -833,14 +1005,14 @@ TkpComputeButtonGeometry(
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
- if (butPtr->highlightWidth < 0) {
- butPtr->highlightWidth = 0;
- }
+ Tk_GetPixelsFromObj(NULL, butPtr->tkwin, butPtr->highlightWidthPtr, &butPtr->highlightWidth);
+ Tk_GetPixelsFromObj(NULL, butPtr->tkwin, butPtr->borderWidthPtr, &butPtr->borderWidth);
+
butPtr->inset = butPtr->highlightWidth + butPtr->borderWidth;
butPtr->indicatorSpace = 0;
- if (!tsdPtr->boxesPtr) {
- InitBoxes();
+ if (!tsdPtr->initialized) {
+ InitBoxes(butPtr->tkwin);
}
/*
@@ -867,7 +1039,7 @@ TkpComputeButtonGeometry(
Tk_FreeTextLayout(butPtr->textLayout);
butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
- Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
+ Tcl_GetString(butPtr->textPtr), TCL_INDEX_NONE, butPtr->wrapLength,
butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);
txtWidth = butPtr->textWidth;
@@ -1028,6 +1200,9 @@ TkpComputeButtonGeometry(
* because otherwise it is not really a compound button.
*/
+ Tk_GetPixelsFromObj(NULL, butPtr->tkwin, butPtr->padXPtr, &butPtr->padX);
+ Tk_GetPixelsFromObj(NULL, butPtr->tkwin, butPtr->padYPtr, &butPtr->padY);
+
if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
switch ((enum compound) butPtr->compound) {
case COMPOUND_TOP:
@@ -1098,8 +1273,8 @@ TkpComputeButtonGeometry(
height = butPtr->height;
}
- width += 2*butPtr->padX;
- height += 2*butPtr->padY;
+ width += 2 * butPtr->padX;
+ height += 2 * butPtr->padY;
} else if (haveImage) {
if (butPtr->width > 0) {
width = butPtr->width;
@@ -1162,7 +1337,7 @@ TkpComputeButtonGeometry(
if (butPtr->type == TYPE_RADIO_BUTTON
|| butPtr->type == TYPE_CHECK_BUTTON) {
if (butPtr->indicatorOn) {
- butPtr->indicatorDiameter = tsdPtr->boxHeight;
+ butPtr->indicatorDiameter = tsdPtr->boxSize;
/*
* Make sure we can see the whole indicator, even if the text or
@@ -1202,8 +1377,8 @@ TkpComputeButtonGeometry(
*
* ButtonProc --
*
- * This function is call by Windows whenever an event occurs on a button
- * control created by Tk.
+ * This function is called by Windows whenever an event occurs on a
+ * button control created by Tk.
*
* Results:
* Standard Windows return value.
@@ -1282,7 +1457,7 @@ ButtonProc(
* causes all buttons to fire once a second, so we need to make sure
* that we are not dealing with the chromium life check.
*/
- if (wParam != 0 || lParam != 0) {
+ if (wParam != 0 || lParam != 0) {
int code;
Tcl_Interp *interp = butPtr->info.interp;
@@ -1302,7 +1477,7 @@ ButtonProc(
}
/* FALLTHRU */
default:
- if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
+ if (TkTranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
return result;
}
}