summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
Diffstat (limited to 'win')
-rw-r--r--win/tkWinButton.c230
1 files changed, 131 insertions, 99 deletions
diff --git a/win/tkWinButton.c b/win/tkWinButton.c
index 87fa858..42cdc3f 100644
--- a/win/tkWinButton.c
+++ b/win/tkWinButton.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWinButton.c,v 1.13 2001/11/17 22:44:04 hobbs Exp $
+ * RCS: @(#) $Id: tkWinButton.c,v 1.14 2001/12/29 00:30:30 hobbs Exp $
*/
#define OEMRESOURCE
@@ -744,9 +744,11 @@ TkpComputeButtonGeometry(butPtr)
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));
@@ -778,7 +780,6 @@ TkpComputeButtonGeometry(butPtr)
* Figure out font metrics (even if we don't have text because we need
* DLUs (based on font, not text) for some spacing calculations below).
*/
-
Tk_FreeTextLayout(butPtr->textLayout);
butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
@@ -810,95 +811,114 @@ TkpComputeButtonGeometry(butPtr)
/*
* Set width and height by button type; See User Experience table, p449.
*/
- if (haveText) {
- switch (butPtr->type) {
- case TYPE_BUTTON: {
- width = (int)(0.5 + (50 * hDLU));
- /*
- * If the text is wider than the default button width,
- * adjust the button width up to suit. We'll allow 6 DLUs
- * left and right. There is no rule but this is consistent
- * with the fact that button text is 8 DLUs high and buttons
- * are 14 DLUs high.
- */
- if (txtWidth + (int)(0.5 + (6 * hDLU)) > width) {
+ switch (butPtr->type) {
+ case TYPE_BUTTON: {
+ if (haveText) {
+ /*
+ * First compute the minimum width of the button in
+ * characters. MWUE says that the button should be
+ * 50 DLUs. We allow 6 DLUs padding left and right.
+ * (There is no rule but this is consistent with the
+ * fact that button text is 8 DLUs high and buttons
+ * are 14 DLUs high.)
+ *
+ * The width is specified in characters. A character
+ * is, by definition, 4 DLUs wide. 11 char * 4 DLU
+ * is 44 DLU + 6 DLU padding = 50 DLU. Therefore,
+ * width = -11 -> MWUE compliant buttons.
+ */
+ if (butPtr->width < 0) {
+ /* Min width in characters */
+ minWidth = -(butPtr->width);
+ /* Allow for characters */
+ width = avgWidth * minWidth;
+ /* Add for padding */
+ width += (int)(0.5 + (6 * hDLU));
+ }
+
+ /*
+ * If shrink-wrapping was requested (width = 0) or
+ * if the text is wider than the default button width,
+ * adjust the button width up to suit.
+ */
+ if (butPtr->width == 0
+ || (txtWidth + (int)(0.5 + (6 * hDLU)) > width)) {
width = txtWidth + (int)(0.5 + (6 * hDLU));
}
- /*
- * The User Experience says 14 DLUs. Since text is, by
- * definition, 8 DLU/line, this allows for multi-line text
- * while working perfectly for single-line text.
- */
- height = txtHeight + (int)(0.5 + (6 * vDLU));
-
- /*
- * The above includes 6 DLUs of padding which should include
- * defaults of 1 pixel of highlightwidth, 2 pixels of
- * borderwidth, 1 pixel of padding and 1 pixel of extra inset
- * on each side. Those will be added later so reduce width
- * and height now to compensate.
- */
- width -= 10;
- height -= 10;
-
- /*
- * Extra inset for the focus ring.
- */
-
- butPtr->inset += 1;
- break;
- }
-
- case TYPE_LABEL: {
- /*
- * The User Experience says, "as wide as needed".
- */
- width = txtWidth;
-
- /*
- * The User Experience says, "8 (DLUs) per line of text."
- * Since text is, by definition, 8 DLU/line, this allows
- * for multi-line text while working perfectly for single-line
- * text.
- */
- height = txtHeight;
- break;
- }
-
- case TYPE_RADIO_BUTTON:
- case TYPE_CHECK_BUTTON: {
- /* See note for TYPE_LABEL */
- width = txtWidth;
- /*
- * The User Experience says 10 DLUs. (Is that one DLU above
- * and below for the focus ring?) See note above about
- * multi-line text and 8 DLU/line.
- */
- height = txtHeight + (int)(0.5 + (2.0 * vDLU));
-
- /*
- * The above includes 2 DLUs of padding which should include
- * defaults of 1 pixel of highlightwidth, 0 pixels of
- * borderwidth, and 1 pixel of padding on each side. Those
- * will be added later so reduce height now to compensate.
- */
- height -= 4;
-
- /*
- * Extra inset for the focus ring.
- */
-
- butPtr->inset += 1;
- break;
- }
-
- default:
- {
- /* WUZ - error here */
- }
- } /* switch */
- }
+ /*
+ * The User Experience says 14 DLUs. Since text is, by
+ * definition, 8 DLU/line, this allows for multi-line text
+ * while working perfectly for single-line text.
+ */
+ height = txtHeight + (int)(0.5 + (6 * vDLU));
+
+ /*
+ * The above includes 6 DLUs of padding which should include
+ * defaults of 1 pixel of highlightwidth, 2 pixels of
+ * borderwidth, 1 pixel of padding and 1 pixel of extra inset
+ * on each side. Those will be added later so reduce width
+ * and height now to compensate.
+ */
+ width -= 10;
+ height -= 10;
+
+ /*
+ * Extra inset for the focus ring.
+ */
+ butPtr->inset += 1;
+ }
+ break;
+ }
+
+ case TYPE_LABEL: {
+ /*
+ * The User Experience says, "as wide as needed".
+ */
+ width = txtWidth;
+
+ /*
+ * The User Experience says, "8 (DLUs) per line of text."
+ * Since text is, by definition, 8 DLU/line, this allows
+ * for multi-line text while working perfectly for single-line
+ * text.
+ */
+ if (txtHeight) {
+ height = txtHeight;
+ } else {
+ /* If there's no text, we want the height to be one linespace */
+ /* WUZ - and no image? */
+ height = fm.linespace;
+ }
+ break;
+ }
+
+ case TYPE_RADIO_BUTTON:
+ case TYPE_CHECK_BUTTON: {
+ /* See note for TYPE_LABEL */
+ width = txtWidth;
+ /*
+ * The User Experience says 10 DLUs. (Is that one DLU above
+ * and below for the focus ring?) See note above about
+ * multi-line text and 8 DLU/line.
+ */
+ height = txtHeight + (int)(0.5 + (2.0 * vDLU));
+
+ /*
+ * The above includes 2 DLUs of padding which should include
+ * defaults of 1 pixel of highlightwidth, 0 pixels of
+ * borderwidth, and 1 pixel of padding on each side. Those
+ * will be added later so reduce height now to compensate.
+ */
+ height -= 4;
+
+ /*
+ * Extra inset for the focus ring.
+ */
+ butPtr->inset += 1;
+ break;
+ }
+ }/* switch */
/*
* At this point, the width and height are correct for a Tk text
@@ -913,7 +933,6 @@ TkpComputeButtonGeometry(butPtr)
* We only honor the compound bit if the button has both text and an
* image, because otherwise it is not really a compound button.
*/
-
if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
switch ((enum compound) butPtr->compound) {
case COMPOUND_TOP:
@@ -953,18 +972,21 @@ TkpComputeButtonGeometry(butPtr)
}
} /* switch */
- if (butPtr->width > 0) {
+ /* Fix up for minimum width */
+ if (butPtr->width < 0) {
+ /* minWidth in pixels (because there's an image */
+ minWidth = -(butPtr->width);
+ if (width < minWidth) {
+ width = minWidth;
+ }
+ } else if (butPtr->width > 0) {
width = butPtr->width;
}
+
if (butPtr->height > 0) {
height = butPtr->height;
}
- if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
- butPtr->indicatorSpace = tsdPtr->boxWidth * 2;
- butPtr->indicatorDiameter = tsdPtr->boxHeight;
- }
-
width += 2*butPtr->padX;
height += 2*butPtr->padY;
} else if (haveImage) {
@@ -979,11 +1001,13 @@ TkpComputeButtonGeometry(butPtr)
height = imgHeight;
}
} else {
- /*
+ /* No image. May or may not be text. May or may not be compound. */
+
+ /*
* butPtr->width is in characters. We need to allow for that
* many characters on the face, not in the over-all button width
*/
- if (butPtr->width > 0) {
+ if (butPtr->width > 0) {
width = butPtr->width * avgWidth;
}
@@ -1000,12 +1024,20 @@ TkpComputeButtonGeometry(butPtr)
height += 2 * butPtr->padY;
}
- /* Compute indicator spacing for radio and check buttons. */
+ /* Fix up width and height for indicator sizing and spacing */
if (butPtr->type == TYPE_RADIO_BUTTON
- || butPtr->type == TYPE_CHECK_BUTTON) {
+ || butPtr->type == TYPE_CHECK_BUTTON) {
if (butPtr->indicatorOn) {
butPtr->indicatorDiameter = tsdPtr->boxHeight;
+ /*
+ * Make sure we can see the whole indicator, even if the text
+ * or image is very small.
+ */
+ if (height < butPtr->indicatorDiameter) {
+ height = butPtr->indicatorDiameter;
+ }
+
/*
* There is no rule for space between the indicator and
* the text (the two are atomic on 'Windows) but the User