summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorericm <ericm>2000-05-13 00:39:06 (GMT)
committerericm <ericm>2000-05-13 00:39:06 (GMT)
commitbfa082e9202bf219a84a4bb0d997d6cf1f834516 (patch)
treeb61f779971a9663ee07b65009e60aa206dd22e32
parent32c00bd4e54bd4254300852356a6fff59d388d45 (diff)
downloadtk-bfa082e9202bf219a84a4bb0d997d6cf1f834516.zip
tk-bfa082e9202bf219a84a4bb0d997d6cf1f834516.tar.gz
tk-bfa082e9202bf219a84a4bb0d997d6cf1f834516.tar.bz2
* unix/tkUnixButton.c (TkpDisplayButton, TkpComputeButtonGeometry):
* mac/tkMacButton.c (TkpDisplayButton, TkpComputeButtonGeometry): * win/tkWinButton.c (TkpDisplayButton, TkpComputeButtonGeometry): Added code for drawing compound buttons. * tests/button.test: Added configuration tests for -repeatdelay, -repeatinterval, -compound. * library/button.tcl: Added support for -repeatedelay, -repeatinterval options. * generic/tkOldConfig.c: Changed handling of link relief so that proper error messages are used. * generic/tkButton.h: Added -compound, -repeatdelay, -repeatinterval options. * generic/tkButton.c: Added event watchers for enter/leave events, for link relief support. * generic/tk3d.c: Changed handling of link relief so that proper error messages are used. * generic/tk.h: Changed values of TK_OPTION_LINK_OK/TK_CONFIG_LINK_OK for link relief support.
-rw-r--r--ChangeLog28
-rw-r--r--doc/button.n27
-rw-r--r--generic/tk.h22
-rw-r--r--generic/tk3d.c6
-rw-r--r--generic/tkButton.c37
-rw-r--r--generic/tkButton.h32
-rw-r--r--generic/tkOldConfig.c40
-rw-r--r--library/button.tcl73
-rw-r--r--mac/tkMacButton.c311
-rw-r--r--mac/tkMacDefault.h5
-rw-r--r--tests/button.test7
-rw-r--r--unix/tkUnixButton.c300
-rw-r--r--unix/tkUnixDefault.h5
-rw-r--r--win/tkWinButton.c326
-rw-r--r--win/tkWinDefault.h11
15 files changed, 961 insertions, 269 deletions
diff --git a/ChangeLog b/ChangeLog
index 0b17905..e8180f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2000-05-12 Eric Melski <ericm@scriptics.com>
+
+ * unix/tkUnixButton.c (TkpDisplayButton, TkpComputeButtonGeometry):
+ * mac/tkMacButton.c (TkpDisplayButton, TkpComputeButtonGeometry):
+ * win/tkWinButton.c (TkpDisplayButton, TkpComputeButtonGeometry):
+ Added code for drawing compound buttons.
+
+ * tests/button.test: Added configuration tests for -repeatdelay,
+ -repeatinterval, -compound.
+
+ * library/button.tcl: Added support for -repeatedelay,
+ -repeatinterval options.
+
+ * generic/tkOldConfig.c: Changed handling of link relief so that
+ proper error messages are used.
+
+ * generic/tkButton.h: Added -compound, -repeatdelay,
+ -repeatinterval options.
+
+ * generic/tkButton.c: Added event watchers for enter/leave events,
+ for link relief support.
+
+ * generic/tk3d.c: Changed handling of link relief so that proper
+ error messages are used.
+
+ * generic/tk.h: Changed values of
+ TK_OPTION_LINK_OK/TK_CONFIG_LINK_OK for link relief support.
+
2000-05-12 Jeff Hobbs <hobbs@scriptics.com>
* win/tkWinFont.c (LoadFontRanges): improved support for all chars
diff --git a/doc/button.n b/doc/button.n
index 28b29ff..3cddf77 100644
--- a/doc/button.n
+++ b/doc/button.n
@@ -5,7 +5,7 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-'\" RCS: @(#) $Id: button.n,v 1.3 2000/05/10 00:09:38 ericm Exp $
+'\" RCS: @(#) $Id: button.n,v 1.4 2000/05/13 00:39:06 ericm Exp $
'\"
.so man.macros
.TH button n 4.4 Tk "Tk Built-In Commands"
@@ -16,18 +16,31 @@ button \- Create and manipulate button widgets
.SH SYNOPSIS
\fBbutton\fR \fIpathName \fR?\fIoptions\fR?
.SO
-\-activebackground \-cursor \-highlightthickness \-takefocus
-\-activeforeground \-disabledforeground \-image \-text
-\-anchor \-font \-justify \-textvariable
-\-background \-foreground \-padx \-underline
-\-bitmap \-highlightbackground \-pady \-wraplength
-\-borderwidth \-highlightcolor \-relief
+\-activebackground \-activeforeground \-anchor
+\-background \-bitmap \-borderwidth
+\-cursor \-disabledforeground \-font
+\-foreground \-highlightbackground \-highlightcolor
+\-highlightthickness \-image \-justify
+\-padx \-pady \-relief
+\-repeatdelay \-repeatinterval \-takefocus
+\-text \-textvariable \-underline
+\-wraplength
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-command command Command
Specifies a Tcl command to associate with the button. This command
is typically invoked when mouse button 1 is released over the button
window.
+.VS 8.4
+.OP \-compound compound Compound
+Specifies whether the button should display both an image and text,
+and if so, where the image should be placed relative to the text.
+Valid values for this option are \fBbottom\fR, \fBcenter\fR,
+\fBleft\fR, \fBnone\fR, \fBright\fR and \fBtop\fR. The default value
+is \fBnone\fR, meaning that the button will display either an image or
+text, depending on the values of the \fB\-image\fR and \fB\-bitmap\fR
+options.
+.VE
.OP \-default default Default
.VS
Specifies one of three states for the default ring: \fBnormal\fR,
diff --git a/generic/tk.h b/generic/tk.h
index cd31a16..62fab06 100644
--- a/generic/tk.h
+++ b/generic/tk.h
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tk.h,v 1.41 2000/05/10 00:09:38 ericm Exp $
+ * RCS: @(#) $Id: tk.h,v 1.42 2000/05/13 00:39:07 ericm Exp $
*/
#ifndef _TK
@@ -201,11 +201,11 @@ typedef struct Tk_OptionSpec {
* carefully.
*/
-#define TK_OPTION_NULL_OK 1
-#define TK_OPTION_DONT_SET_DEFAULT 8
+#define TK_OPTION_NULL_OK (1 << 0)
+#define TK_OPTION_DONT_SET_DEFAULT (1 << 3)
/* This widget allows the link relief */
-#define TK_OPTION_LINK_OK (1 << 9)
+#define TK_OPTION_LINK_OK (1 << 6)
/*
* Macro to use to fill in "offset" fields of the Tk_OptionSpec.
@@ -363,14 +363,14 @@ typedef enum {
* tkOldConfig.c (internal-use-only flags are defined there).
*/
-#define TK_CONFIG_NULL_OK 1
-#define TK_CONFIG_COLOR_ONLY 2
-#define TK_CONFIG_MONO_ONLY 4
-#define TK_CONFIG_DONT_SET_DEFAULT 8
-#define TK_CONFIG_OPTION_SPECIFIED 0x10
-#define TK_CONFIG_USER_BIT 0x100
+#define TK_CONFIG_NULL_OK (1 << 0)
+#define TK_CONFIG_COLOR_ONLY (1 << 1)
+#define TK_CONFIG_MONO_ONLY (1 << 2)
+#define TK_CONFIG_DONT_SET_DEFAULT (1 << 3)
+#define TK_CONFIG_OPTION_SPECIFIED (1 << 4)
/* This widget allows the link relief */
-#define TK_CONFIG_LINK_OK (1 << 9)
+#define TK_CONFIG_LINK_OK (1 << 6)
+#define TK_CONFIG_USER_BIT 0x100
#endif /* __NO_OLD_CONFIG */
/*
diff --git a/generic/tk3d.c b/generic/tk3d.c
index 5147e95..98375f6 100644
--- a/generic/tk3d.c
+++ b/generic/tk3d.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tk3d.c,v 1.8 2000/05/11 22:37:06 hobbs Exp $
+ * RCS: @(#) $Id: tk3d.c,v 1.9 2000/05/13 00:39:07 ericm Exp $
*/
#include "tk3d.h"
@@ -665,8 +665,6 @@ Tk_GetRelief(interp, name, reliefPtr)
} else if ((c == 'g') && (strncmp(name, "groove", length) == 0)
&& (length >= 2)) {
*reliefPtr = TK_RELIEF_GROOVE;
- } else if ((c == 'l') && (strncmp(name, "link", length) == 0)) {
- *reliefPtr = TK_RELIEF_LINK;
} else if ((c == 'r') && (strncmp(name, "raised", length) == 0)
&& (length >= 2)) {
*reliefPtr = TK_RELIEF_RAISED;
@@ -680,7 +678,7 @@ Tk_GetRelief(interp, name, reliefPtr)
char buf[200];
sprintf(buf, "bad relief type \"%.50s\": must be %s",
- name, "flat, groove, link, raised, ridge, solid, or sunken");
+ name, "flat, groove, raised, ridge, solid, or sunken");
Tcl_SetResult(interp, buf, TCL_VOLATILE);
return TCL_ERROR;
}
diff --git a/generic/tkButton.c b/generic/tkButton.c
index 51d928d..e3c9d86 100644
--- a/generic/tkButton.c
+++ b/generic/tkButton.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkButton.c,v 1.5 2000/05/10 00:09:39 ericm Exp $
+ * RCS: @(#) $Id: tkButton.c,v 1.6 2000/05/13 00:39:07 ericm Exp $
*/
#include "tkButton.h"
@@ -43,6 +43,15 @@ static char *stateStrings[] = {
};
/*
+ * The following table defines the legal values for the -compound option.
+ * It is used with the "enum compound" declaration in tkButton.h
+ */
+
+static char *compoundStrings[] = {
+ "bottom", "center", "left", "none", "right", "top", (char *) NULL
+};
+
+/*
* Information used for parsing configuration options. There is a
* separate table for each of the four widget classes.
*/
@@ -63,6 +72,9 @@ static Tk_OptionSpec labelOptionSpecs[] = {
{TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
DEF_BUTTON_BORDER_WIDTH, Tk_Offset(TkButton, borderWidthPtr),
Tk_Offset(TkButton, borderWidth), 0, 0, 0},
+ {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
+ DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound), 0,
+ (ClientData) compoundStrings, 0},
{TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor),
TK_OPTION_NULL_OK, 0, 0},
@@ -149,6 +161,9 @@ static Tk_OptionSpec buttonOptionSpecs[] = {
{TK_OPTION_STRING, "-command", "command", "Command",
DEF_BUTTON_COMMAND, Tk_Offset(TkButton, commandPtr), -1,
TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
+ DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound), 0,
+ (ClientData) compoundStrings, 0},
{TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor),
TK_OPTION_NULL_OK, 0, 0},
@@ -192,6 +207,12 @@ static Tk_OptionSpec buttonOptionSpecs[] = {
{TK_OPTION_RELIEF, "-relief", "relief", "Relief",
DEF_BUTTON_RELIEF, -1, Tk_Offset(TkButton, relief),
TK_OPTION_LINK_OK, 0, 0},
+ {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
+ DEF_BUTTON_REPEAT_DELAY, -1, Tk_Offset(TkButton, repeatDelay),
+ 0, 0, 0},
+ {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
+ DEF_BUTTON_REPEAT_INTERVAL, -1, Tk_Offset(TkButton, repeatInterval),
+ 0, 0, 0},
{TK_OPTION_STRING_TABLE, "-state", "state", "State",
DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state),
0, (ClientData) stateStrings, 0},
@@ -239,6 +260,9 @@ static Tk_OptionSpec checkbuttonOptionSpecs[] = {
{TK_OPTION_STRING, "-command", "command", "Command",
DEF_BUTTON_COMMAND, Tk_Offset(TkButton, commandPtr), -1,
TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
+ DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound), 0,
+ (ClientData) compoundStrings, 0},
{TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor),
TK_OPTION_NULL_OK, 0, 0},
@@ -340,6 +364,9 @@ static Tk_OptionSpec radiobuttonOptionSpecs[] = {
{TK_OPTION_STRING, "-command", "command", "Command",
DEF_BUTTON_COMMAND, Tk_Offset(TkButton, commandPtr), -1,
TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
+ DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound), 0,
+ (ClientData) compoundStrings, 0},
{TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor),
TK_OPTION_NULL_OK, 0, 0},
@@ -686,7 +713,7 @@ ButtonCreate(clientData, interp, objc, objv, type)
butPtr->flags = 0;
Tk_CreateEventHandler(butPtr->tkwin,
- ExposureMask|StructureNotifyMask|FocusChangeMask,
+ ExposureMask|StructureNotifyMask|FocusChangeMask|EnterWindowMask|LeaveWindowMask,
ButtonEventProc, (ClientData) butPtr);
if (Tk_InitOptions(interp, (char *) butPtr, optionTable, tkwin)
@@ -1370,6 +1397,12 @@ ButtonEventProc(clientData, eventPtr)
goto redraw;
}
}
+ } else if (eventPtr->type == EnterNotify) {
+ butPtr->flags |= MOUSE_IN_BUTTON;
+ goto redraw;
+ } else if (eventPtr->type == LeaveNotify) {
+ butPtr->flags &= ~MOUSE_IN_BUTTON;
+ goto redraw;
}
return;
diff --git a/generic/tkButton.h b/generic/tkButton.h
index ae24bae..cb774f9 100644
--- a/generic/tkButton.h
+++ b/generic/tkButton.h
@@ -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: tkButton.h,v 1.5 1999/04/16 01:51:11 stanton Exp $
+ * RCS: @(#) $Id: tkButton.h,v 1.6 2000/05/13 00:39:07 ericm Exp $
*/
#ifndef _TKBUTTON
@@ -25,6 +25,15 @@
#endif
/*
+ * Legal values for the "compound" field of TkButton records.
+ */
+
+enum compound {
+ COMPOUND_BOTTOM, COMPOUND_CENTER, COMPOUND_LEFT, COMPOUND_NONE,
+ COMPOUND_RIGHT, COMPOUND_TOP
+};
+
+/*
* Legal values for the "state" field of TkButton records.
*/
@@ -226,6 +235,15 @@ typedef struct {
* to execute when button is invoked. If
* widget is label or has no command, this
* is NULL. */
+ int compound; /* Value of -compound option; specifies whether
+ * the button should show both an image and
+ * text, and, if so, how. */
+ int repeatDelay; /* Value of -repeatdelay option; specifies
+ * the number of ms after which the button will
+ * start to auto-repeat its command. */
+ int repeatInterval; /* Value of -repeatinterval option; specifies
+ * the number of ms between auto-repeat
+ * invocataions of the button command. */
int flags; /* Various flags; see below for
* definitions. */
} TkButton;
@@ -255,13 +273,15 @@ typedef struct {
* BUTTON_DELETED: Non-zero needs that this button has been
* deleted, or is in the process of being
* deleted.
+ * MOUSE_IN_BUTTON: Non-zero means that the mouse is currently
+ * over the button.
*/
-#define REDRAW_PENDING 1
-#define SELECTED 2
-#define GOT_FOCUS 4
-#define BUTTON_DELETED 0x8
-
+#define REDRAW_PENDING (1 << 0)
+#define SELECTED (1 << 1)
+#define GOT_FOCUS (1 << 2)
+#define BUTTON_DELETED (1 << 3)
+#define MOUSE_IN_BUTTON (1 << 4)
/*
* Declaration of variables shared between the files in the button module.
*/
diff --git a/generic/tkOldConfig.c b/generic/tkOldConfig.c
index 135e83c..3a373c0 100644
--- a/generic/tkOldConfig.c
+++ b/generic/tkOldConfig.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkOldConfig.c,v 1.7 2000/05/10 00:09:39 ericm Exp $
+ * RCS: @(#) $Id: tkOldConfig.c,v 1.8 2000/05/13 00:39:07 ericm Exp $
*/
#include "tkPort.h"
@@ -483,24 +483,32 @@ DoConfig(interp, tkwin, specPtr, value, valueIsUid, widgRec)
}
case TK_CONFIG_RELIEF:
uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
- if (Tk_GetRelief(interp, uid, (int *) ptr) != TCL_OK) {
- return TCL_ERROR;
- }
-
/*
- * Not all widgets allow the link relief. If the given
- * relief is "link" and this widget does not support it,
- * display the "invalid relief" error message and return
- * TCL_ERROR.
+ * In order that error messages be handled properly, we let
+ * GetRelief do the first pass check on the relief
+ * string. If it fails there, and the option spec doesn't
+ * allow for LINK relief, return an error. If the option spec
+ * does allow LINK relief, see if the string matches "link".
*/
-
- if ((*ptr == TK_RELIEF_LINK) && \
- ((specPtr->specFlags & TK_CONFIG_LINK_OK) == 0)) {
- Tcl_SetResult(interp, "invalid relief \"link\": must be "
- "flat, groove, raised, ridge, solid, or sunken",
- TCL_STATIC);
- return TCL_ERROR;
+
+ if (Tk_GetRelief(interp, uid, (int *) ptr) != TCL_OK) {
+ if ((specPtr->specFlags & TK_CONFIG_LINK_OK) == 0) {
+ return TCL_ERROR;
+ } else {
+ if (uid[0] == 'l' && strcmp(uid, "link") == 0) {
+ *ptr = TK_RELIEF_LINK;
+ Tcl_ResetResult(interp);
+ } else {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "bad relief \"",
+ uid, "\": must be flat, groove, link, "
+ "raised, ridge, solid, or sunken",
+ (char *)NULL);
+ return TCL_ERROR;
+ }
+ }
}
+
break;
case TK_CONFIG_CURSOR:
case TK_CONFIG_ACTIVE_CURSOR: {
diff --git a/library/button.tcl b/library/button.tcl
index 8feeba8..0184648 100644
--- a/library/button.tcl
+++ b/library/button.tcl
@@ -4,7 +4,7 @@
# checkbutton, and radiobutton widgets and provides procedures
# that help in implementing those bindings.
#
-# RCS: @(#) $Id: button.tcl,v 1.6 1999/09/02 17:02:52 hobbs Exp $
+# RCS: @(#) $Id: button.tcl,v 1.7 2000/05/13 00:39:08 ericm Exp $
#
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
@@ -203,6 +203,14 @@ proc tkButtonDown w {
if {[string compare [$w cget -state] "disabled"]} {
set tkPriv(buttonWindow) $w
$w configure -relief sunken -state active
+
+ # If this button has a repeatdelay set up, get it going with an after
+ after cancel $tkPriv(afterId)
+ set delay [$w cget -repeatdelay]
+ set tkPriv(repeated) 0
+ if {$delay > 0} {
+ set tkPriv(afterId) [after $delay [list tkButtonAutoInvoke $w]]
+ }
}
}
@@ -240,7 +248,12 @@ proc tkButtonUp w {
if {[string equal $tkPriv(window) $w]
&& [string compare [$w cget -state] "disabled"]} {
$w configure -state normal
- uplevel #0 [list $w invoke]
+
+ # Only invoke the command if it wasn't already invoked by the
+ # auto-repeater functionality
+ if { $tkPriv(repeated) == 0 } {
+ uplevel #0 [list $w invoke]
+ }
}
}
}
@@ -308,6 +321,14 @@ proc tkButtonDown w {
if {[string compare [$w cget -state] "disabled"]} {
set tkPriv(buttonWindow) $w
$w configure -relief sunken
+
+ # If this button has a repeatdelay set up, get it going with an after
+ after cancel $tkPriv(afterId)
+ set delay [$w cget -repeatdelay]
+ set tkPriv(repeated) 0
+ if {$delay > 0} {
+ set tkPriv(afterId) [after $delay [list tkButtonAutoInvoke $w]]
+ }
}
}
@@ -324,9 +345,15 @@ proc tkButtonUp w {
if {[string equal $w $tkPriv(buttonWindow)]} {
set tkPriv(buttonWindow) ""
$w configure -relief $tkPriv(relief)
+ after cancel $tkPriv(afterId)
if {[string equal $w $tkPriv(window)] \
&& [string compare [$w cget -state] "disabled"]} {
- uplevel #0 [list $w invoke]
+
+ # Only invoke the command if it wasn't already invoked by the
+ # auto-repeater functionality
+ if { $tkPriv(repeated) == 0 } {
+ uplevel #0 [list $w invoke]
+ }
}
}
}
@@ -389,6 +416,14 @@ proc tkButtonDown w {
if {[string compare [$w cget -state] "disabled"]} {
set tkPriv(buttonWindow) $w
$w configure -state active
+
+ # If this button has a repeatdelay set up, get it going with an after
+ after cancel $tkPriv(afterId)
+ set delay [$w cget -repeatdelay]
+ set tkPriv(repeated) 0
+ if {$delay > 0} {
+ set tkPriv(afterId) [after $delay [list tkButtonAutoInvoke $w]]
+ }
}
}
@@ -407,7 +442,11 @@ proc tkButtonUp w {
set tkPriv(buttonWindow) ""
if {[string equal $w $tkPriv(window)]
&& [string compare [$w cget -state] "disabled"]} {
- uplevel #0 [list $w invoke]
+ # Only invoke the command if it wasn't already invoked by the
+ # auto-repeater functionality
+ if { $tkPriv(repeated) == 0 } {
+ uplevel #0 [list $w invoke]
+ }
}
}
}
@@ -437,6 +476,32 @@ proc tkButtonInvoke w {
}
}
+# tkButtonAutoInvoke --
+#
+# Invoke an auto-repeating button, and set it up to continue to repeat.
+#
+# Arguments:
+# w button to invoke.
+#
+# Results:
+# None.
+#
+# Side effects:
+# May create an after event to call tkButtonAutoInvoke.
+
+proc tkButtonAutoInvoke {w} {
+ global tkPriv
+ after cancel $tkPriv(afterId)
+ set delay [$w cget -repeatinterval]
+ if { [string equal $tkPriv(window) $w] } {
+ incr tkPriv(repeated)
+ uplevel #0 [list $w invoke]
+ }
+ if {$delay > 0} {
+ set tkPriv(afterId) [after $delay [list tkButtonAutoInvoke $w]]
+ }
+}
+
# tkCheckRadioInvoke --
# The procedure below is invoked when the mouse button is pressed in
# a checkbutton or radiobutton widget, or when the widget is invoked
diff --git a/mac/tkMacButton.c b/mac/tkMacButton.c
index dc4ecc1..b726c82 100644
--- a/mac/tkMacButton.c
+++ b/mac/tkMacButton.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: tkMacButton.c,v 1.11 2000/05/10 00:09:39 ericm Exp $
+ * RCS: @(#) $Id: tkMacButton.c,v 1.12 2000/05/13 00:39:08 ericm Exp $
*/
#include "tkButton.h"
@@ -167,7 +167,9 @@ TkpDisplayButton(
* compiler warning. */
int y, relief;
register Tk_Window tkwin = butPtr->tkwin;
- int width, height;
+ int width, height, fullWidth, fullHeight;
+ int imageXOffset, imageYOffset, textXOffset, textYOffset;
+ int haveImage = 0, haveText = 0;
int offset; /* 0 means this is a normal widget. 1 means
* it is an image button, so we offset the
* image to make the button appear to move
@@ -237,7 +239,7 @@ TkpDisplayButton(
*/
if ((butPtr->type == TYPE_BUTTON) && butPtr->relief == TK_RELIEF_LINK) {
- if (butPtr->state == STATE_ACTIVE) {
+ if ((butPtr->flags & MOUSE_IN_BUTTON) == MOUSE_IN_BUTTON) {
relief = TK_RELIEF_RAISED;
} else {
relief = TK_RELIEF_FLAT;
@@ -339,51 +341,157 @@ TkpDisplayButton(
if ((drawType == DRAW_BEVEL) && TkMacHaveAppearance()) {
/* Empty Body */
- } else if (butPtr->image != None) {
- Tk_SizeOfImage(butPtr->image, &width, &height);
-
- imageOrBitmap:
- TkComputeAnchor(butPtr->anchor, tkwin, 0, 0,
- butPtr->indicatorSpace + width, height, &x, &y);
- x += butPtr->indicatorSpace;
-
- x += offset;
- y += offset;
- if (relief == TK_RELIEF_RAISED) {
- x -= offset;
- y -= offset;
- } else if (relief == TK_RELIEF_SUNKEN) {
+ } else {
+ 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;
+ }
+ haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0);
+
+ if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
+ imageXOffset = 0;
+ imageYOffset = 0;
+ textXOffset = 0;
+ textYOffset = 0;
+ 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;
+
x += offset;
y += offset;
- }
- if (butPtr->image != NULL) {
- if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) {
- Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height,
- pixmap, x, y);
+ if (relief == TK_RELIEF_RAISED) {
+ x -= offset;
+ y -= offset;
+ } else if (relief == TK_RELIEF_SUNKEN) {
+ x += offset;
+ y += offset;
+ }
+
+ if (butPtr->image != NULL) {
+ if ((butPtr->selectImage != NULL) &&
+ (butPtr->flags & SELECTED)) {
+ Tk_RedrawImage(butPtr->selectImage, 0, 0,
+ width, height, pixmap, x + imageXOffset,
+ y + imageYOffset);
+ } else {
+ Tk_RedrawImage(butPtr->image, 0, 0, width,
+ height, pixmap, x + imageXOffset,
+ y + imageYOffset);
+ }
} else {
- Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap,
- x, y);
+ XSetClipOrigin(butPtr->display, gc, x + imageXOffset,
+ y + imageYOffset);
+ XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc,
+ 0, 0, (unsigned int) width,
+ (unsigned int) height, x + imageXOffset,
+ y + 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);
+ y += fullHeight/2;
} 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);
+ if (haveImage) {
+ TkComputeAnchor(butPtr->anchor, tkwin, 0, 0,
+ butPtr->indicatorSpace + width, height, &x, &y);
+ x += butPtr->indicatorSpace;
+
+ x += offset;
+ y += offset;
+ if (relief == TK_RELIEF_RAISED) {
+ x -= offset;
+ y -= offset;
+ } else if (relief == TK_RELIEF_SUNKEN) {
+ x += offset;
+ y += offset;
+ }
+ if (butPtr->image != NULL) {
+ if ((butPtr->selectImage != NULL) &&
+ (butPtr->flags & SELECTED)) {
+ Tk_RedrawImage(butPtr->selectImage, 0, 0, width,
+ height, pixmap, x, y);
+ } else {
+ Tk_RedrawImage(butPtr->image, 0, 0, width, height,
+ pixmap, x, y);
+ }
+ } 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);
+ }
+ y += height/2;
+ } else {
+ TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX,
+ butPtr->padY,
+ butPtr->indicatorSpace + butPtr->textWidth,
+ butPtr->textHeight, &x, &y);
+
+ x += butPtr->indicatorSpace;
+
+ Tk_DrawTextLayout(butPtr->display, pixmap, gc,
+ butPtr->textLayout, x, y, 0, -1);
+ y += butPtr->textHeight/2;
+ }
}
- y += height/2;
- } else if (butPtr->bitmap != None) {
- Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
- goto imageOrBitmap;
- } else {
- TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
- butPtr->indicatorSpace + butPtr->textWidth, butPtr->textHeight,
- &x, &y);
-
- x += butPtr->indicatorSpace;
-
- Tk_DrawTextLayout(butPtr->display, pixmap, gc, butPtr->textLayout,
- x, y, 0, -1);
- y += butPtr->textHeight/2;
}
/*
@@ -458,10 +566,10 @@ void
TkpComputeButtonGeometry(
TkButton *butPtr) /* Button whose geometry may have changed. */
{
- int width, height, avgWidth;
+ int width, height, avgWidth, haveImage = 0;
+ int txtWidth, txtHeight;
Tk_FontMetrics fm;
-
/*
* First figure out the size of the contents of the button.
*/
@@ -469,47 +577,114 @@ TkpComputeButtonGeometry(
butPtr->indicatorSpace = 0;
if (butPtr->image != NULL) {
Tk_SizeOfImage(butPtr->image, &width, &height);
- imageOrBitmap:
- if (butPtr->width > 0) {
- width = butPtr->width;
- }
- if (butPtr->height > 0) {
- height = butPtr->height;
- }
- if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
- butPtr->indicatorSpace = height;
- if (butPtr->type == TYPE_CHECK_BUTTON) {
- butPtr->indicatorDiameter = (65*height)/100;
- } else {
- butPtr->indicatorDiameter = (75*height)/100;
- }
- }
+ haveImage = 1;
} else if (butPtr->bitmap != None) {
Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
- goto imageOrBitmap;
- } else {
+ haveImage = 1;
+ }
+
+ width = 0;
+ height = 0;
+ txtWidth = 0;
+ txtHeight = 0;
+ avgWidth = 0;
+
+ if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) {
Tk_FreeTextLayout(butPtr->textLayout);
butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);
- width = butPtr->textWidth;
- height = butPtr->textHeight;
+ txtWidth = butPtr->textWidth;
+ txtHeight = butPtr->textHeight;
avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
Tk_GetFontMetrics(butPtr->tkfont, &fm);
+ haveText = (txtWidth != 0 && txtHeight != 0);
+ }
+
+ /*
+ * If the button is compound (ie, it shows both an image and text),
+ * the new geometry is a combination of the image and text geometry.
+ * 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:
+ case COMPOUND_BOTTOM: {
+ /* Image is above or below text */
+ height += txtHeight + butPtr->padY;
+ width = (width > txtWidth ? width : txtWidth);
+ break;
+ }
+ case COMPOUND_LEFT:
+ case COMPOUND_RIGHT: {
+ /* Image is left or right of text */
+ width += txtWidth + butPtr->padX;
+ height = (height > txtHeight ? height : txtHeight);
+ break;
+ }
+ case COMPOUND_CENTER: {
+ /* Image and text are superimposed */
+ width = (width > txtWidth ? width : txtWidth);
+ height = (height > txtHeight ? height : txtHeight);
+ break;
+ }
+ case COMPOUND_NONE: {break;}
+ }
if (butPtr->width > 0) {
- width = butPtr->width * avgWidth;
+ width = butPtr->width;
}
if (butPtr->height > 0) {
- height = butPtr->height * fm.linespace;
+ height = butPtr->height;
}
+
if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
- butPtr->indicatorDiameter = fm.linespace;
+ butPtr->indicatorSpace = height;
if (butPtr->type == TYPE_CHECK_BUTTON) {
- butPtr->indicatorDiameter = (80*butPtr->indicatorDiameter)/100;
+ butPtr->indicatorDiameter = (65*height)/100;
+ } else {
+ butPtr->indicatorDiameter = (75*height)/100;
+ }
+ }
+
+ width += 2*butPtr->padX;
+ height += 2*butPtr->padY;
+
+ } else {
+ if (haveImage) {
+ if (butPtr->width > 0) {
+ width = butPtr->width;
+ }
+ if (butPtr->height > 0) {
+ height = butPtr->height;
+ }
+ if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
+ butPtr->indicatorSpace = height;
+ if (butPtr->type == TYPE_CHECK_BUTTON) {
+ butPtr->indicatorDiameter = (65*height)/100;
+ } else {
+ butPtr->indicatorDiameter = (75*height)/100;
+ }
+ }
+ } else {
+ width = txtWidth;
+ height = txtHeight;
+ if (butPtr->width > 0) {
+ 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;
}
- butPtr->indicatorSpace = butPtr->indicatorDiameter + avgWidth;
}
}
diff --git a/mac/tkMacDefault.h b/mac/tkMacDefault.h
index 9c149b5..e37bafe 100644
--- a/mac/tkMacDefault.h
+++ b/mac/tkMacDefault.h
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMacDefault.h,v 1.4 1999/11/17 02:40:55 ericm Exp $
+ * RCS: @(#) $Id: tkMacDefault.h,v 1.5 2000/05/13 00:39:08 ericm Exp $
*/
#ifndef _TKMACDEFAULT
@@ -54,6 +54,7 @@
#define DEF_BUTTON_BORDER_WIDTH "2"
#define DEF_BUTTON_CURSOR ""
#define DEF_BUTTON_COMMAND ""
+#define DEF_BUTTON_COMPOUND "none"
#define DEF_BUTTON_DEFAULT "disabled"
#define DEF_BUTTON_DISABLED_FG_COLOR DISABLED
#define DEF_BUTTON_DISABLED_FG_MONO ""
@@ -77,6 +78,8 @@
#define DEF_LABCHKRAD_PADY "1"
#define DEF_BUTTON_RELIEF "flat"
#define DEF_LABCHKRAD_RELIEF "flat"
+#define DEF_BUTTON_REPEAT_DELAY "0"
+#define DEF_BUTTON_REPEAT_INTERVAL "0"
#define DEF_BUTTON_SELECT_COLOR INDICATOR
#define DEF_BUTTON_SELECT_MONO BLACK
#define DEF_BUTTON_SELECT_IMAGE (char *) NULL
diff --git a/tests/button.test b/tests/button.test
index 145dddb..67e0a3b 100644
--- a/tests/button.test
+++ b/tests/button.test
@@ -7,7 +7,7 @@
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
-# RCS: @(#) $Id: button.test,v 1.6 2000/05/10 00:09:40 ericm Exp $
+# RCS: @(#) $Id: button.test,v 1.7 2000/05/13 00:39:09 ericm Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
source [file join [pwd] [file dirname [info script]] defs.tcl]
@@ -64,6 +64,7 @@ foreach test {
{1 1 1 1}}
{-borderwidth 1.3 1.3 badValue {bad screen distance "badValue"} {1 1 1 1}}
{-command "set x" {set x} {} {} {0 1 1 1}}
+ {-compound left left bogus {bad compound "bogus": must be bottom, center, left, none, right, or top} {1 1 1 1}}
{-cursor arrow arrow badValue {bad cursor spec "badValue"} {1 1 1 1}}
{-default active active huh?
{bad default "huh?": must be active, disabled, or normal}
@@ -88,6 +89,8 @@ foreach test {
{-offvalue fantastic fantastic {} {} {0 0 1 0}}
{-padx 12m 12m 420x {bad screen distance "420x"} {1 1 1 1}}
{-pady 12m 12m 420x {bad screen distance "420x"} {1 1 1 1}}
+ {-repeatdelay 100 100 foo {expected integer but got "foo"} {0 1 0 0}}
+ {-repeatinterval 100 100 foo {expected integer but got "foo"} {0 1 0 0}}
{-selectcolor #110022 #110022 bogus {unknown color name "bogus"} {0 0 1 1}}
{-selectimage image1 image1 bogus {image "bogus" doesn't exist} {0 0 1 1}}
{-state normal normal bogus {bad state "bogus": must be active, disabled, or normal} {1 1 1 1}}
@@ -236,7 +239,7 @@ test button-4.13 {ButtonWidgetCmd procedure, "cget" option} {
} {1 {unknown option "-onvalue"}}
test button-4.14 {ButtonWidgetCmd procedure, "configure" option} {
llength [.c configure]
-} {36}
+} {37}
test button-4.15 {ButtonWidgetCmd procedure, "configure" option} {
list [catch {.b configure -gorp} msg] $msg
} {1 {unknown option "-gorp"}}
diff --git a/unix/tkUnixButton.c b/unix/tkUnixButton.c
index 5cce667..ce9ffac 100644
--- a/unix/tkUnixButton.c
+++ b/unix/tkUnixButton.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: tkUnixButton.c,v 1.4 2000/05/10 00:09:40 ericm Exp $
+ * RCS: @(#) $Id: tkUnixButton.c,v 1.5 2000/05/13 00:39:09 ericm Exp $
*/
#include "tkButton.h"
@@ -86,10 +86,13 @@ TkpDisplayButton(clientData)
* compiler warning. */
int y, relief;
Tk_Window tkwin = butPtr->tkwin;
- int width, height;
+ int width, height, fullWidth, fullHeight;
+ int imageXOffset, imageYOffset, textXOffset, textYOffset;
+ int haveImage = 0, haveText = 0;
int offset; /* 1 means this is a button widget, so we
* offset the text to make the button appear
- * to move up and down as the relief changes. */
+ * to move up and down as the relief changes.
+ */
butPtr->flags &= ~REDRAW_PENDING;
if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
@@ -129,7 +132,7 @@ TkpDisplayButton(clientData)
*/
if ((butPtr->type == TYPE_BUTTON) && butPtr->relief == TK_RELIEF_LINK) {
- if (butPtr->state == STATE_ACTIVE) {
+ if ((butPtr->flags & MOUSE_IN_BUTTON) == MOUSE_IN_BUTTON) {
relief = TK_RELIEF_RAISED;
} else {
relief = TK_RELIEF_FLAT;
@@ -156,12 +159,72 @@ TkpDisplayButton(clientData)
if (butPtr->image != NULL) {
Tk_SizeOfImage(butPtr->image, &width, &height);
+ haveImage = 1;
+ } else if (butPtr->bitmap != None) {
+ Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
+ haveImage = 1;
+ }
+ haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0);
+
+ if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
+ imageXOffset = 0;
+ imageYOffset = 0;
+ textXOffset = 0;
+ textYOffset = 0;
+ 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);
- imageOrBitmap:
- TkComputeAnchor(butPtr->anchor, tkwin, 0, 0,
- butPtr->indicatorSpace + width, height, &x, &y);
x += butPtr->indicatorSpace;
-
+
x += offset;
y += offset;
if (relief == TK_RELIEF_RAISED) {
@@ -171,47 +234,87 @@ TkpDisplayButton(clientData)
x += offset;
y += offset;
}
+
if (butPtr->image != NULL) {
if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) {
- Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height, pixmap,
- x, y);
+ Tk_RedrawImage(butPtr->selectImage, 0, 0,
+ width, height, pixmap, x + imageXOffset,
+ y + imageYOffset);
} else {
- Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap,
- x, y);
+ Tk_RedrawImage(butPtr->image, 0, 0, width,
+ height, pixmap, x + imageXOffset, y + 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, x + imageXOffset,
+ y + imageYOffset);
+ XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc,
+ 0, 0, (unsigned int) width,
+ (unsigned int) height, x + imageXOffset,
+ y + imageYOffset, 1);
XSetClipOrigin(butPtr->display, gc, 0, 0);
}
- y += height/2;
- } else if (butPtr->bitmap != None) {
- Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
- goto imageOrBitmap;
- } else {
- TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
- butPtr->indicatorSpace + butPtr->textWidth, butPtr->textHeight,
- &x, &y);
-
- x += butPtr->indicatorSpace;
- x += offset;
- y += offset;
- if (relief == TK_RELIEF_RAISED) {
- x -= offset;
- y -= offset;
- } else if (relief == TK_RELIEF_SUNKEN) {
+ 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);
+ y += fullHeight/2;
+ } else {
+ if (haveImage) {
+ TkComputeAnchor(butPtr->anchor, tkwin, 0, 0,
+ butPtr->indicatorSpace + width, height, &x, &y);
+ x += butPtr->indicatorSpace;
+
x += offset;
y += offset;
+ if (relief == TK_RELIEF_RAISED) {
+ x -= offset;
+ y -= offset;
+ } else if (relief == TK_RELIEF_SUNKEN) {
+ x += offset;
+ y += offset;
+ }
+ if (butPtr->image != NULL) {
+ if ((butPtr->selectImage != NULL) &&
+ (butPtr->flags & SELECTED)) {
+ Tk_RedrawImage(butPtr->selectImage, 0, 0, width,
+ height, pixmap, x, y);
+ } else {
+ Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap,
+ x, y);
+ }
+ } 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);
+ }
+ y += height/2;
+ } else {
+ TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
+ butPtr->indicatorSpace + butPtr->textWidth,
+ butPtr->textHeight, &x, &y);
+
+ x += butPtr->indicatorSpace;
+
+ x += offset;
+ y += offset;
+ if (relief == TK_RELIEF_RAISED) {
+ x -= offset;
+ y -= offset;
+ } else 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);
+ y += butPtr->textHeight/2;
}
- Tk_DrawTextLayout(butPtr->display, pixmap, gc, butPtr->textLayout,
- x, y, 0, -1);
- Tk_UnderlineTextLayout(butPtr->display, pixmap, gc,
- butPtr->textLayout, x, y, butPtr->underline);
- y += butPtr->textHeight/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
@@ -408,7 +511,8 @@ void
TkpComputeButtonGeometry(butPtr)
register TkButton *butPtr; /* Button whose geometry may have changed. */
{
- int width, height, avgWidth;
+ int width, height, avgWidth, txtWidth, txtHeight;
+ int haveImage = 0, haveText = 0;
Tk_FontMetrics fm;
butPtr->inset = butPtr->highlightWidth + butPtr->borderWidth;
@@ -421,15 +525,73 @@ TkpComputeButtonGeometry(butPtr)
butPtr->inset += 5;
}
butPtr->indicatorSpace = 0;
+
+ width = 0;
+ height = 0;
+ txtWidth = 0;
+ txtHeight = 0;
+ avgWidth = 0;
+
if (butPtr->image != NULL) {
Tk_SizeOfImage(butPtr->image, &width, &height);
- imageOrBitmap:
+ haveImage = 1;
+ } else if (butPtr->bitmap != None) {
+ Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
+ haveImage = 1;
+ }
+
+ if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) {
+ Tk_FreeTextLayout(butPtr->textLayout);
+
+ butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
+ Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
+ butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);
+
+ txtWidth = butPtr->textWidth;
+ txtHeight = butPtr->textHeight;
+ avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
+ Tk_GetFontMetrics(butPtr->tkfont, &fm);
+ haveText = (txtWidth != 0 && txtHeight != 0);
+ }
+
+ /*
+ * If the button is compound (ie, it shows both an image and text),
+ * the new geometry is a combination of the image and text geometry.
+ * 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:
+ case COMPOUND_BOTTOM: {
+ /* Image is above or below text */
+ height += txtHeight + butPtr->padY;
+ width = (width > txtWidth ? width : txtWidth);
+ break;
+ }
+ case COMPOUND_LEFT:
+ case COMPOUND_RIGHT: {
+ /* Image is left or right of text */
+ width += txtWidth + butPtr->padX;
+ height = (height > txtHeight ? height : txtHeight);
+ break;
+ }
+ case COMPOUND_CENTER: {
+ /* Image and text are superimposed */
+ width = (width > txtWidth ? width : txtWidth);
+ height = (height > txtHeight ? height : txtHeight);
+ break;
+ }
+ case COMPOUND_NONE: {break;}
+ }
if (butPtr->width > 0) {
width = butPtr->width;
}
if (butPtr->height > 0) {
height = butPtr->height;
}
+
if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
butPtr->indicatorSpace = height;
if (butPtr->type == TYPE_CHECK_BUTTON) {
@@ -438,33 +600,45 @@ TkpComputeButtonGeometry(butPtr)
butPtr->indicatorDiameter = (75*height)/100;
}
}
- } else if (butPtr->bitmap != None) {
- Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
- goto imageOrBitmap;
- } else {
- Tk_FreeTextLayout(butPtr->textLayout);
- butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
- Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
- butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);
-
- width = butPtr->textWidth;
- height = butPtr->textHeight;
- avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
- Tk_GetFontMetrics(butPtr->tkfont, &fm);
+ width += 2*butPtr->padX;
+ height += 2*butPtr->padY;
- if (butPtr->width > 0) {
- 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;
+ } else {
+ if (haveImage) {
+ if (butPtr->width > 0) {
+ width = butPtr->width;
+ }
+ if (butPtr->height > 0) {
+ height = butPtr->height;
+ }
+
+ if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
+ butPtr->indicatorSpace = height;
+ if (butPtr->type == TYPE_CHECK_BUTTON) {
+ butPtr->indicatorDiameter = (65*height)/100;
+ } else {
+ butPtr->indicatorDiameter = (75*height)/100;
+ }
+ }
+ } else {
+ width = txtWidth;
+ height = txtHeight;
+
+ if (butPtr->width > 0) {
+ 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;
}
- butPtr->indicatorSpace = butPtr->indicatorDiameter + avgWidth;
}
}
diff --git a/unix/tkUnixDefault.h b/unix/tkUnixDefault.h
index f5f1040..02f1d99 100644
--- a/unix/tkUnixDefault.h
+++ b/unix/tkUnixDefault.h
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkUnixDefault.h,v 1.4 1999/11/17 02:40:55 ericm Exp $
+ * RCS: @(#) $Id: tkUnixDefault.h,v 1.5 2000/05/13 00:39:09 ericm Exp $
*/
#ifndef _TKUNIXDEFAULT
@@ -51,6 +51,7 @@
#define DEF_BUTTON_BITMAP ""
#define DEF_BUTTON_BORDER_WIDTH "2"
#define DEF_BUTTON_CURSOR ""
+#define DEF_BUTTON_COMPOUND "none"
#define DEF_BUTTON_COMMAND ""
#define DEF_BUTTON_DEFAULT "disabled"
#define DEF_BUTTON_DISABLED_FG_COLOR DISABLED
@@ -75,6 +76,8 @@
#define DEF_LABCHKRAD_PADY "1"
#define DEF_BUTTON_RELIEF "raised"
#define DEF_LABCHKRAD_RELIEF "flat"
+#define DEF_BUTTON_REPEAT_DELAY "0"
+#define DEF_BUTTON_REPEAT_INTERVAL "0"
#define DEF_BUTTON_SELECT_COLOR INDICATOR
#define DEF_BUTTON_SELECT_MONO BLACK
#define DEF_BUTTON_SELECT_IMAGE (char *) NULL
diff --git a/win/tkWinButton.c b/win/tkWinButton.c
index 3a78d29..f40e9ba 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.7 2000/05/11 00:40:16 ericm Exp $
+ * RCS: @(#) $Id: tkWinButton.c,v 1.8 2000/05/13 00:39:09 ericm Exp $
*/
#define OEMRESOURCE
@@ -346,7 +346,8 @@ TkpDisplayButton(clientData)
* compiler warning. */
int y, relief;
register Tk_Window tkwin = butPtr->tkwin;
- int width, height;
+ int width, height, haveImage = 0, haveText = 0, drawRing = 0;
+ RECT rect;
int defaultWidth; /* Width of default ring. */
int offset; /* 0 means this is a label widget. 1 means
* it is a flavor of button, so we offset
@@ -396,7 +397,7 @@ TkpDisplayButton(clientData)
*/
if ((butPtr->type == TYPE_BUTTON) && butPtr->relief == TK_RELIEF_LINK) {
- if (butPtr->state == STATE_ACTIVE) {
+ if ((butPtr->flags & MOUSE_IN_BUTTON) == MOUSE_IN_BUTTON) {
relief = TK_RELIEF_RAISED;
} else {
relief = TK_RELIEF_FLAT;
@@ -438,78 +439,178 @@ TkpDisplayButton(clientData)
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;
+ }
- imageOrBitmap:
- TkComputeAnchor(butPtr->anchor, tkwin, 0, 0,
- butPtr->indicatorSpace + width, height, &x, &y);
+ haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0);
+
+ if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
+ int imageXOffset, imageYOffset, textXOffset, textYOffset, fullWidth,
+ fullHeight;
+ imageXOffset = 0;
+ imageYOffset = 0;
+ textXOffset = 0;
+ textYOffset = 0;
+ 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;
}
+
if (butPtr->image != NULL) {
if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) {
- Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height,
- pixmap, x, y);
+ Tk_RedrawImage(butPtr->selectImage, 0, 0,
+ width, height, pixmap, x + imageXOffset,
+ y + imageYOffset);
} else {
- Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap,
- x, y);
+ Tk_RedrawImage(butPtr->image, 0, 0, width,
+ height, pixmap, x + imageXOffset, y + 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, x + imageXOffset,
+ y + imageYOffset);
+ XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc,
+ 0, 0, (unsigned int) width,
+ (unsigned int) height, x + imageXOffset,
+ y + imageYOffset, 1);
XSetClipOrigin(butPtr->display, gc, 0, 0);
}
- y += height/2;
- } else if (butPtr->bitmap != None) {
- Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
- goto imageOrBitmap;
- } else {
- RECT rect;
- 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);
+ x + textXOffset, y + textYOffset, 0, -1);
Tk_UnderlineTextLayout(butPtr->display, pixmap, gc,
- butPtr->textLayout, x, y, butPtr->underline);
-
- /*
- * 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.
- */
-
- if (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;
+ 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;
+ }
+ if (butPtr->image != NULL) {
+ if ((butPtr->selectImage != NULL) &&
+ (butPtr->flags & SELECTED)) {
+ Tk_RedrawImage(butPtr->selectImage, 0, 0, width, height,
+ pixmap, x, y);
+ } else {
+ Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap,
+ x, y);
+ }
} else {
- rect.top = y-2;
- rect.left = x-2;
- rect.right = x+butPtr->textWidth + 1;
- rect.bottom = y+butPtr->textHeight + 1;
+ 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;
}
- SetTextColor(dc, gc->foreground);
- SetBkColor(dc, gc->background);
- DrawFocusRect(dc, &rect);
- TkWinReleaseDrawableDC(pixmap, dc, &state);
+ 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.
+ */
+
+ 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-2;
+ rect.left = x-2;
+ rect.right = x+butPtr->textWidth + 1;
+ rect.bottom = y+butPtr->textHeight + 1;
}
- y += butPtr->textHeight/2;
+ 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
@@ -652,7 +753,8 @@ void
TkpComputeButtonGeometry(butPtr)
register TkButton *butPtr; /* Button whose geometry may have changed. */
{
- int width, height, avgWidth;
+ int width, height, avgWidth, txtWidth, txtHeight, drawRing = 0;
+ int haveImage = 0, haveText = 0;
Tk_FontMetrics fm;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
@@ -667,55 +769,119 @@ TkpComputeButtonGeometry(butPtr)
InitBoxes();
}
+ width = 0;
+ height = 0;
+ txtWidth = 0;
+ txtHeight = 0;
+ avgWidth = 0;
+
if (butPtr->image != NULL) {
Tk_SizeOfImage(butPtr->image, &width, &height);
- imageOrBitmap:
- 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;
- }
+ haveImage = 1;
} else if (butPtr->bitmap != None) {
Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
- goto imageOrBitmap;
- } else {
+ haveImage = 1;
+ }
+
+ if (!haveImage || butPtr->compound != COMPOUND_NONE) {
+ /* Calculate geometry for the text */
Tk_FreeTextLayout(butPtr->textLayout);
butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);
- width = butPtr->textWidth;
- height = butPtr->textHeight;
+ txtWidth = butPtr->textWidth;
+ txtHeight = butPtr->textHeight;
+ haveText = (txtWidth != 0 && txtHeight != 0);
avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
Tk_GetFontMetrics(butPtr->tkfont, &fm);
+ }
+
+ /*
+ * If the button is compound (ie, it shows both an image and text),
+ * the new geometry is a combination of the image and text geometry.
+ * 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:
+ case COMPOUND_BOTTOM: {
+ /* Image is above or below text */
+ height += txtHeight + butPtr->padY;
+ width = (width > txtWidth ? width : txtWidth);
+ break;
+ }
+ case COMPOUND_LEFT:
+ case COMPOUND_RIGHT: {
+ /* Image is left or right of text */
+ width += txtWidth + butPtr->padX;
+ height = (height > txtHeight ? height : txtHeight);
+ break;
+ }
+ case COMPOUND_CENTER: {
+ /* Image and text are superimposed */
+ width = (width > txtWidth ? width : txtWidth);
+ height = (height > txtHeight ? height : txtHeight);
+ break;
+ }
+ case COMPOUND_NONE: {break;}
+ }
if (butPtr->width > 0) {
- width = butPtr->width * avgWidth;
+ width = butPtr->width;
}
if (butPtr->height > 0) {
- height = butPtr->height * fm.linespace;
+ height = butPtr->height;
}
-
+
if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
+ butPtr->indicatorSpace = tsdPtr->boxWidth * 2;
butPtr->indicatorDiameter = tsdPtr->boxHeight;
- butPtr->indicatorSpace = butPtr->indicatorDiameter + avgWidth;
}
- /*
- * Increase the inset to allow for the focus ring.
- */
-
- if (butPtr->type != TYPE_LABEL) {
- butPtr->inset += 3;
+ width += 2*butPtr->padX;
+ height += 2*butPtr->padY;
+ drawRing = 1;
+ } else {
+ if (haveImage) {
+ 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;
+ }
+ } else {
+ width = txtWidth;
+ height = txtHeight;
+ if (butPtr->width > 0) {
+ width = butPtr->width * avgWidth;
+ }
+ if (butPtr->height > 0) {
+ height = butPtr->height * fm.linespace;
+ }
+
+ if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
+ butPtr->indicatorDiameter = tsdPtr->boxHeight;
+ butPtr->indicatorSpace = butPtr->indicatorDiameter + avgWidth;
+ }
+ drawRing = 1;
}
}
/*
+ * Increase the inset to allow for the focus ring.
+ */
+
+ if (drawRing && butPtr->type != TYPE_LABEL) {
+ butPtr->inset += 3;
+ }
+
+ /*
* When issuing the geometry request, add extra space for the indicator,
* if any, and for the border and padding, plus an extra pixel so the
* display can be offset by 1 pixel in either direction for the raised
diff --git a/win/tkWinDefault.h b/win/tkWinDefault.h
index ff964d5..cac2d71 100644
--- a/win/tkWinDefault.h
+++ b/win/tkWinDefault.h
@@ -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: tkWinDefault.h,v 1.4 1999/11/17 02:40:55 ericm Exp $
+ * RCS: @(#) $Id: tkWinDefault.h,v 1.5 2000/05/13 00:39:09 ericm Exp $
*/
#ifndef _TKWINDEFAULT
@@ -58,6 +58,7 @@
#define DEF_BUTTON_BORDER_WIDTH "2"
#define DEF_BUTTON_CURSOR ""
#define DEF_BUTTON_COMMAND ""
+#define DEF_BUTTON_COMPOUND "none"
#define DEF_BUTTON_DEFAULT "disabled"
#define DEF_BUTTON_DISABLED_FG_COLOR DISABLED
#define DEF_BUTTON_DISABLED_FG_MONO ""
@@ -75,13 +76,15 @@
#define DEF_BUTTON_JUSTIFY "center"
#define DEF_BUTTON_OFF_VALUE "0"
#define DEF_BUTTON_ON_VALUE "1"
-#define DEF_BUTTON_PADX "1"
+#define DEF_BUTTON_PADX "1"
#define DEF_LABCHKRAD_PADX "1"
-#define DEF_BUTTON_PADY "1"
+#define DEF_BUTTON_PADY "1"
#define DEF_LABCHKRAD_PADY "1"
#define DEF_BUTTON_RELIEF "raised"
#define DEF_LABCHKRAD_RELIEF "flat"
-#define DEF_BUTTON_SELECT_COLOR INDICATOR
+#define DEF_BUTTON_REPEAT_DELAY "0"
+#define DEF_BUTTON_REPEAT_INTERVAL "0"
+#define DEF_BUTTON_SELECT_COLOR INDICATOR
#define DEF_BUTTON_SELECT_MONO BLACK
#define DEF_BUTTON_SELECT_IMAGE (char *) NULL
#define DEF_BUTTON_STATE "normal"