From bfa082e9202bf219a84a4bb0d997d6cf1f834516 Mon Sep 17 00:00:00 2001 From: ericm Date: Sat, 13 May 2000 00:39:06 +0000 Subject: * 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. --- ChangeLog | 28 +++++ doc/button.n | 27 +++-- generic/tk.h | 22 ++-- generic/tk3d.c | 6 +- generic/tkButton.c | 37 +++++- generic/tkButton.h | 32 ++++- generic/tkOldConfig.c | 40 ++++--- library/button.tcl | 73 ++++++++++- mac/tkMacButton.c | 311 ++++++++++++++++++++++++++++++++++++----------- mac/tkMacDefault.h | 5 +- tests/button.test | 7 +- unix/tkUnixButton.c | 300 ++++++++++++++++++++++++++++++++++++---------- unix/tkUnixDefault.h | 5 +- win/tkWinButton.c | 326 +++++++++++++++++++++++++++++++++++++------------- win/tkWinDefault.h | 11 +- 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 + + * 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 * 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" -- cgit v0.12