summaryrefslogtreecommitdiffstats
path: root/generic/tkButton.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkButton.c')
-rw-r--r--generic/tkButton.c851
1 files changed, 470 insertions, 381 deletions
diff --git a/generic/tkButton.c b/generic/tkButton.c
index 3783985..4e3c06c 100644
--- a/generic/tkButton.c
+++ b/generic/tkButton.c
@@ -1,39 +1,40 @@
-/*
+/*
* tkButton.c --
*
- * This module implements a collection of button-like
- * widgets for the Tk toolkit. The widgets implemented
- * include labels, buttons, checkbuttons, and radiobuttons.
+ * This module implements a collection of button-like widgets for the Tk
+ * toolkit. The widgets implemented include buttons, checkbuttons,
+ * radiobuttons, and labels.
*
* Copyright (c) 1990-1994 The Regents of the University of California.
* Copyright (c) 1994-1998 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
+#include "tkInt.h"
#include "tkButton.h"
#include "default.h"
-typedef struct ThreadSpecificData {
+typedef struct ThreadSpecificData {
int defaultsInitialized;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
/*
- * Class names for buttons, indexed by one of the type values defined
- * in tkButton.h.
+ * Class names for buttons, indexed by one of the type values defined in
+ * tkButton.h.
*/
-static char *classNames[] = {"Label", "Button", "Checkbutton", "Radiobutton"};
+static const char *classNames[] = {"Label", "Button", "Checkbutton", "Radiobutton"};
/*
- * The following table defines the legal values for the -default option.
- * It is used together with the "enum defaultValue" declaration in tkButton.h.
+ * The following table defines the legal values for the -default option. It is
+ * used together with the "enum defaultValue" declaration in tkButton.h.
*/
-static char *defaultStrings[] = {
- "active", "disabled", "normal", (char *) NULL
+static const char *defaultStrings[] = {
+ "active", "disabled", "normal", NULL
};
/*
@@ -41,8 +42,8 @@ static char *defaultStrings[] = {
* It is used together with the "enum state" declaration in tkButton.h.
*/
-static char *stateStrings[] = {
- "active", "disabled", "normal", (char *) NULL
+static const char *stateStrings[] = {
+ "active", "disabled", "normal", NULL
};
/*
@@ -50,8 +51,8 @@ static char *stateStrings[] = {
* It is used with the "enum compound" declaration in tkButton.h
*/
-static char *compoundStrings[] = {
- "bottom", "center", "left", "none", "right", "top", (char *) NULL
+static const char *compoundStrings[] = {
+ "bottom", "center", "left", "none", "right", "top", NULL
};
char tkDefButtonBorderWidth[TCL_INTEGER_SPACE] = DEF_BUTTON_BORDER_WIDTH;
@@ -73,10 +74,10 @@ static Tk_OptionSpec labelOptionSpecs[] = {
{TK_OPTION_BORDER, "-background", "background", "Background",
DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder),
0, (ClientData) DEF_BUTTON_BG_MONO, 0},
- {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
- {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-background", 0},
+ {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-background", 0},
{TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap),
TK_OPTION_NULL_OK, 0, 0},
@@ -93,8 +94,8 @@ static Tk_OptionSpec labelOptionSpecs[] = {
"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
-1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK,
(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
- {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0},
+ {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
+ NULL, 0, -1, 0, (ClientData) "-foreground", 0},
{TK_OPTION_FONT, "-font", "font", "Font",
DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0},
{TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
@@ -143,8 +144,7 @@ static Tk_OptionSpec labelOptionSpecs[] = {
{TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLengthPtr),
Tk_Offset(TkButton, wrapLength), 0, 0, 0},
- {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0, 0, 0}
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0}
};
static Tk_OptionSpec buttonOptionSpecs[] = {
@@ -159,10 +159,10 @@ static Tk_OptionSpec buttonOptionSpecs[] = {
{TK_OPTION_BORDER, "-background", "background", "Background",
DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder),
0, (ClientData) DEF_BUTTON_BG_MONO, 0},
- {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
- {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-background", 0},
+ {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-background", 0},
{TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap),
TK_OPTION_NULL_OK, 0, 0},
@@ -185,8 +185,8 @@ static Tk_OptionSpec buttonOptionSpecs[] = {
"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
-1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK,
(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
- {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0},
+ {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
+ NULL, 0, -1, 0, (ClientData) "-foreground", 0},
{TK_OPTION_FONT, "-font", "font", "Font",
DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0},
{TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
@@ -245,8 +245,7 @@ static Tk_OptionSpec buttonOptionSpecs[] = {
{TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLengthPtr),
Tk_Offset(TkButton, wrapLength), 0, 0, 0},
- {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, 0, 0}
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};
static Tk_OptionSpec checkbuttonOptionSpecs[] = {
@@ -261,10 +260,10 @@ static Tk_OptionSpec checkbuttonOptionSpecs[] = {
{TK_OPTION_BORDER, "-background", "background", "Background",
DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder),
0, (ClientData) DEF_BUTTON_BG_MONO, 0},
- {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
- {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-background", 0},
+ {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-background", 0},
{TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap),
TK_OPTION_NULL_OK, 0, 0},
@@ -284,8 +283,8 @@ static Tk_OptionSpec checkbuttonOptionSpecs[] = {
"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
-1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK,
(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
- {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0},
+ {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
+ NULL, 0, -1, 0, (ClientData) "-foreground", 0},
{TK_OPTION_FONT, "-font", "font", "Font",
DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0},
{TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
@@ -344,6 +343,11 @@ static Tk_OptionSpec checkbuttonOptionSpecs[] = {
{TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1,
TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING, "-tristateimage", "tristateImage", "TristateImage",
+ DEF_BUTTON_IMAGE, Tk_Offset(TkButton, tristateImagePtr), -1,
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING, "-tristatevalue", "tristateValue", "TristateValue",
+ DEF_BUTTON_TRISTATE_VALUE, Tk_Offset(TkButton, tristateValuePtr), -1, 0, 0, 0},
{TK_OPTION_INT, "-underline", "underline", "Underline",
DEF_BUTTON_UNDERLINE, -1, Tk_Offset(TkButton, underline), 0, 0, 0},
{TK_OPTION_STRING, "-variable", "variable", "Variable",
@@ -354,8 +358,7 @@ static Tk_OptionSpec checkbuttonOptionSpecs[] = {
{TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLengthPtr),
Tk_Offset(TkButton, wrapLength), 0, 0, 0},
- {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, 0, 0}
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};
static Tk_OptionSpec radiobuttonOptionSpecs[] = {
@@ -370,10 +373,10 @@ static Tk_OptionSpec radiobuttonOptionSpecs[] = {
{TK_OPTION_BORDER, "-background", "background", "Background",
DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder),
0, (ClientData) DEF_BUTTON_BG_MONO, 0},
- {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
- {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-background", 0},
+ {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-background", 0},
{TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap),
TK_OPTION_NULL_OK, 0, 0},
@@ -393,8 +396,8 @@ static Tk_OptionSpec radiobuttonOptionSpecs[] = {
"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
-1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK,
(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
- {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0},
+ {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
+ NULL, 0, -1, 0, (ClientData) "-foreground", 0},
{TK_OPTION_FONT, "-font", "font", "Font",
DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0},
{TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
@@ -450,6 +453,11 @@ static Tk_OptionSpec radiobuttonOptionSpecs[] = {
{TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1,
TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING, "-tristateimage", "tristateImage", "TristateImage",
+ DEF_BUTTON_IMAGE, Tk_Offset(TkButton, tristateImagePtr), -1,
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING, "-tristatevalue", "tristateValue", "TristateValue",
+ DEF_BUTTON_TRISTATE_VALUE, Tk_Offset(TkButton, tristateValuePtr), -1, 0, 0, 0},
{TK_OPTION_INT, "-underline", "underline", "Underline",
DEF_BUTTON_UNDERLINE, -1, Tk_Offset(TkButton, underline), 0, 0, 0},
{TK_OPTION_STRING, "-value", "value", "Value",
@@ -462,17 +470,15 @@ static Tk_OptionSpec radiobuttonOptionSpecs[] = {
{TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLengthPtr),
Tk_Offset(TkButton, wrapLength), 0, 0, 0},
- {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, 0, 0}
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};
/*
- * The following table maps from one of the type values defined in
- * tkButton.h, such as TYPE_LABEL, to the option template for that
- * class of widgets.
+ * The following table maps from one of the type values defined in tkButton.h,
+ * such as TYPE_LABEL, to the option template for that class of widgets.
*/
-static Tk_OptionSpec *optionSpecs[] = {
+static Tk_OptionSpec * const optionSpecs[] = {
labelOptionSpecs,
buttonOptionSpecs,
checkbuttonOptionSpecs,
@@ -480,18 +486,17 @@ static Tk_OptionSpec *optionSpecs[] = {
};
/*
- * The following tables define the widget commands supported by
- * each of the classes, and map the indexes into the string tables
- * into a single enumerated type used to dispatch the widget command.
+ * The following tables define the widget commands supported by each of the
+ * classes, and map the indexes into the string tables into a single
+ * enumerated type used to dispatch the widget command.
*/
-static CONST char *commandNames[][8] = {
- {"cget", "configure", (char *) NULL},
- {"cget", "configure", "flash", "invoke", (char *) NULL},
- {"cget", "configure", "deselect", "flash", "invoke", "select",
- "toggle", (char *) NULL},
+static const char *commandNames[][8] = {
+ {"cget", "configure", NULL},
+ {"cget", "configure", "flash", "invoke", NULL},
{"cget", "configure", "deselect", "flash", "invoke", "select",
- (char *) NULL}
+ "toggle", NULL},
+ {"cget", "configure", "deselect", "flash", "invoke", "select", NULL}
};
enum command {
COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DESELECT, COMMAND_FLASH,
@@ -507,91 +512,92 @@ static enum command map[][8] = {
};
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for functions defined later in this file:
*/
-static void ButtonCmdDeletedProc _ANSI_ARGS_((
- ClientData clientData));
-static int ButtonCreate _ANSI_ARGS_((ClientData clientData,
+static void ButtonCmdDeletedProc(ClientData clientData);
+static int ButtonCreate(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[], int type));
-static void ButtonEventProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static void ButtonImageProc _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[], int type);
+static void ButtonEventProc(ClientData clientData,
+ XEvent *eventPtr);
+static void ButtonImageProc(ClientData clientData,
int x, int y, int width, int height,
- int imgWidth, int imgHeight));
-static void ButtonSelectImageProc _ANSI_ARGS_((
- ClientData clientData, int x, int y, int width,
- int height, int imgWidth, int imgHeight));
-static char * ButtonTextVarProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, CONST char *name1,
- CONST char *name2, int flags));
-static char * ButtonVarProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, CONST char *name1,
- CONST char *name2, int flags));
-static int ButtonWidgetObjCmd _ANSI_ARGS_((ClientData clientData,
+ int imgWidth, int imgHeight);
+static void ButtonSelectImageProc(ClientData clientData,
+ int x, int y, int width, int height,
+ int imgWidth, int imgHeight);
+static void ButtonTristateImageProc(ClientData clientData,
+ int x, int y, int width, int height,
+ int imgWidth, int imgHeight);
+static char * ButtonTextVarProc(ClientData clientData,
+ Tcl_Interp *interp, const char *name1,
+ const char *name2, int flags);
+static char * ButtonVarProc(ClientData clientData,
+ Tcl_Interp *interp, const char *name1,
+ const char *name2, int flags);
+static int ButtonWidgetObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int ConfigureButton _ANSI_ARGS_((Tcl_Interp *interp,
- TkButton *butPtr, int objc,
- Tcl_Obj *CONST objv[]));
-static void DestroyButton _ANSI_ARGS_((TkButton *butPtr));
+ Tcl_Obj *const objv[]);
+static int ConfigureButton(Tcl_Interp *interp, TkButton *butPtr,
+ int objc, Tcl_Obj *const objv[]);
+static void DestroyButton(TkButton *butPtr);
/*
*--------------------------------------------------------------
*
* Tk_ButtonCmd, Tk_CheckbuttonCmd, Tk_LabelCmd, Tk_RadiobuttonCmd --
*
- * These procedures are invoked to process the "button", "label",
- * "radiobutton", and "checkbutton" Tcl commands. See the
- * user documentation for details on what they do.
+ * These functions are invoked to process the "button", "label",
+ * "radiobutton", and "checkbutton" Tcl commands. See the user
+ * documentation for details on what they do.
*
* Results:
* A standard Tcl result.
*
* Side effects:
- * See the user documentation. These procedures are just wrappers;
- * they call ButtonCreate to do all of the real work.
+ * See the user documentation. These functions are just wrappers; they
+ * call ButtonCreate to do all of the real work.
*
*--------------------------------------------------------------
*/
int
-Tk_ButtonObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Either NULL or pointer to option table. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+Tk_ButtonObjCmd(
+ ClientData clientData, /* Either NULL or pointer to option table. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument values. */
{
return ButtonCreate(clientData, interp, objc, objv, TYPE_BUTTON);
}
int
-Tk_CheckbuttonObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Either NULL or pointer to option table. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+Tk_CheckbuttonObjCmd(
+ ClientData clientData, /* Either NULL or pointer to option table. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument values. */
{
return ButtonCreate(clientData, interp, objc, objv, TYPE_CHECK_BUTTON);
}
int
-Tk_LabelObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Either NULL or pointer to option table. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+Tk_LabelObjCmd(
+ ClientData clientData, /* Either NULL or pointer to option table. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument values. */
{
return ButtonCreate(clientData, interp, objc, objv, TYPE_LABEL);
}
int
-Tk_RadiobuttonObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Either NULL or pointer to option table. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+Tk_RadiobuttonObjCmd(
+ ClientData clientData, /* Either NULL or pointer to option table. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument values. */
{
return ButtonCreate(clientData, interp, objc, objv, TYPE_RADIO_BUTTON);
}
@@ -601,9 +607,9 @@ Tk_RadiobuttonObjCmd(clientData, interp, objc, objv)
*
* ButtonCreate --
*
- * This procedure does all the real work of implementing the
- * "button", "label", "radiobutton", and "checkbutton" Tcl
- * commands. See the user documentation for details on what it does.
+ * This function does all the real work of implementing the "button",
+ * "label", "radiobutton", and "checkbutton" Tcl commands. See the user
+ * documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -615,20 +621,20 @@ Tk_RadiobuttonObjCmd(clientData, interp, objc, objv)
*/
static int
-ButtonCreate(clientData, interp, objc, objv, type)
- ClientData clientData; /* NULL. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
- int type; /* Type of button to create: TYPE_LABEL,
+ButtonCreate(
+ ClientData clientData, /* NULL. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[], /* Argument values. */
+ int type) /* Type of button to create: TYPE_LABEL,
* TYPE_BUTTON, TYPE_CHECK_BUTTON, or
* TYPE_RADIO_BUTTON. */
{
TkButton *butPtr;
Tk_OptionTable optionTable;
Tk_Window tkwin;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (!tsdPtr->defaultsInitialized) {
TkpButtonSetDefaults(optionSpecs[type]);
@@ -645,14 +651,14 @@ ButtonCreate(clientData, interp, objc, objv, type)
*/
tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
- Tcl_GetString(objv[1]), (char *) NULL);
+ Tcl_GetString(objv[1]), NULL);
if (tkwin == NULL) {
return TCL_ERROR;
}
/*
- * Create the option table for this widget class. If it has already
- * been created, the cached pointer will be returned.
+ * Create the option table for this widget class. If it has already been
+ * created, the cached pointer will be returned.
*/
optionTable = Tk_CreateOptionTable(interp, optionSpecs[type]);
@@ -681,6 +687,8 @@ ButtonCreate(clientData, interp, objc, objv, type)
butPtr->image = NULL;
butPtr->selectImagePtr = NULL;
butPtr->selectImage = NULL;
+ butPtr->tristateImagePtr = NULL;
+ butPtr->tristateImage = NULL;
butPtr->state = STATE_NORMAL;
butPtr->normalBorder = NULL;
butPtr->activeBorder = NULL;
@@ -725,6 +733,7 @@ ButtonCreate(clientData, interp, objc, objv, type)
butPtr->selVarNamePtr = NULL;
butPtr->onValuePtr = NULL;
butPtr->offValuePtr = NULL;
+ butPtr->tristateValuePtr = NULL;
butPtr->cursor = None;
butPtr->takeFocusPtr = NULL;
butPtr->commandPtr = NULL;
@@ -754,9 +763,9 @@ ButtonCreate(clientData, interp, objc, objv, type)
*
* ButtonWidgetCmd --
*
- * This procedure is invoked to process the Tcl command
- * that corresponds to a widget managed by this module.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the Tcl command that corresponds
+ * to a widget managed by this module. See the user documentation for
+ * details on what it does.
*
* Results:
* A standard Tcl result.
@@ -768,11 +777,11 @@ ButtonCreate(clientData, interp, objc, objv, type)
*/
static int
-ButtonWidgetObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Information about button widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+ButtonWidgetObjCmd(
+ ClientData clientData, /* Information about button widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument values. */
{
TkButton *butPtr = (TkButton *) clientData;
int index;
@@ -791,137 +800,126 @@ ButtonWidgetObjCmd(clientData, interp, objc, objv)
Tcl_Preserve((ClientData) butPtr);
switch (map[butPtr->type][index]) {
- case COMMAND_CGET: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "cget option");
- goto error;
- }
- objPtr = Tk_GetOptionValue(interp, (char *) butPtr,
- butPtr->optionTable, objv[2], butPtr->tkwin);
+ case COMMAND_CGET:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "cget option");
+ goto error;
+ }
+ objPtr = Tk_GetOptionValue(interp, (char *) butPtr,
+ butPtr->optionTable, objv[2], butPtr->tkwin);
+ if (objPtr == NULL) {
+ goto error;
+ } else {
+ Tcl_SetObjResult(interp, objPtr);
+ }
+ break;
+
+ case COMMAND_CONFIGURE:
+ if (objc <= 3) {
+ objPtr = Tk_GetOptionInfo(interp, (char *) butPtr,
+ butPtr->optionTable, (objc == 3) ? objv[2] : NULL,
+ butPtr->tkwin);
if (objPtr == NULL) {
- goto error;
+ goto error;
} else {
Tcl_SetObjResult(interp, objPtr);
}
- break;
+ } else {
+ result = ConfigureButton(interp, butPtr, objc-2, objv+2);
}
+ break;
- case COMMAND_CONFIGURE: {
- if (objc <= 3) {
- objPtr = Tk_GetOptionInfo(interp, (char *) butPtr,
- butPtr->optionTable,
- (objc == 3) ? objv[2] : (Tcl_Obj *) NULL,
- butPtr->tkwin);
- if (objPtr == NULL) {
- goto error;
- } else {
- Tcl_SetObjResult(interp, objPtr);
- }
- } else {
- result = ConfigureButton(interp, butPtr, objc-2, objv+2);
- }
- break;
+ case COMMAND_DESELECT:
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "deselect");
+ goto error;
}
-
- case COMMAND_DESELECT: {
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "deselect");
+ if (butPtr->type == TYPE_CHECK_BUTTON) {
+ if (Tcl_ObjSetVar2(interp, butPtr->selVarNamePtr, NULL,
+ butPtr->offValuePtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
+ == NULL) {
goto error;
}
- if (butPtr->type == TYPE_CHECK_BUTTON) {
- if (Tcl_ObjSetVar2(interp, butPtr->selVarNamePtr, NULL,
- butPtr->offValuePtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
- == NULL) {
- goto error;
- }
- } else if (butPtr->flags & SELECTED) {
- if (Tcl_ObjSetVar2(interp,
- butPtr->selVarNamePtr, NULL, Tcl_NewObj(),
- TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
- == NULL) {
- goto error;
- }
+ } else if (butPtr->flags & SELECTED) {
+ if (Tcl_ObjSetVar2(interp, butPtr->selVarNamePtr, NULL,
+ Tcl_NewObj(), TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL){
+ goto error;
}
- break;
}
+ break;
- case COMMAND_FLASH: {
+ case COMMAND_FLASH:
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "flash");
+ goto error;
+ }
+ if (butPtr->state != STATE_DISABLED) {
int i;
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "flash");
- goto error;
- }
- if (butPtr->state != STATE_DISABLED) {
- for (i = 0; i < 4; i++) {
- if (butPtr->state == STATE_NORMAL) {
- butPtr->state = STATE_ACTIVE;
- Tk_SetBackgroundFromBorder(butPtr->tkwin,
- butPtr->activeBorder);
- } else {
- butPtr->state = STATE_NORMAL;
- Tk_SetBackgroundFromBorder(butPtr->tkwin,
- butPtr->normalBorder);
- }
- TkpDisplayButton((ClientData) butPtr);
-
- /*
- * Special note: must cancel any existing idle handler
- * for TkpDisplayButton; it's no longer needed, and
- * TkpDisplayButton cleared the REDRAW_PENDING flag.
- */
-
- Tcl_CancelIdleCall(TkpDisplayButton, (ClientData) butPtr);
- XFlush(butPtr->display);
- Tcl_Sleep(50);
+ for (i = 0; i < 4; i++) {
+ if (butPtr->state == STATE_NORMAL) {
+ butPtr->state = STATE_ACTIVE;
+ Tk_SetBackgroundFromBorder(butPtr->tkwin,
+ butPtr->activeBorder);
+ } else {
+ butPtr->state = STATE_NORMAL;
+ Tk_SetBackgroundFromBorder(butPtr->tkwin,
+ butPtr->normalBorder);
}
+ TkpDisplayButton((ClientData) butPtr);
+
+ /*
+ * Special note: must cancel any existing idle handler for
+ * TkpDisplayButton; it's no longer needed, and
+ * TkpDisplayButton cleared the REDRAW_PENDING flag.
+ */
+
+ Tcl_CancelIdleCall(TkpDisplayButton, (ClientData) butPtr);
+ XFlush(butPtr->display);
+ Tcl_Sleep(50);
}
- break;
}
+ break;
- case COMMAND_INVOKE: {
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "invoke");
- goto error;
- }
- if (butPtr->state != STATE_DISABLED) {
- result = TkInvokeButton(butPtr);
- }
- break;
+ case COMMAND_INVOKE:
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "invoke");
+ goto error;
+ }
+ if (butPtr->state != STATE_DISABLED) {
+ result = TkInvokeButton(butPtr);
}
+ break;
- case COMMAND_SELECT: {
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "select");
- goto error;
- }
- if (Tcl_ObjSetVar2(interp, butPtr->selVarNamePtr, NULL,
- butPtr->onValuePtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
- == NULL) {
- goto error;
- }
- break;
+ case COMMAND_SELECT:
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "select");
+ goto error;
}
+ if (Tcl_ObjSetVar2(interp, butPtr->selVarNamePtr, NULL,
+ butPtr->onValuePtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
+ == NULL) {
+ goto error;
+ }
+ break;
- case COMMAND_TOGGLE: {
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "toggle");
- goto error;
- }
- if (Tcl_ObjSetVar2(interp, butPtr->selVarNamePtr, NULL,
- (butPtr->flags & SELECTED) ? butPtr->offValuePtr
- : butPtr->onValuePtr,
- TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
- == NULL) {
- goto error;
- }
- break;
+ case COMMAND_TOGGLE:
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "toggle");
+ goto error;
+ }
+ if (Tcl_ObjSetVar2(interp, butPtr->selVarNamePtr, NULL,
+ (butPtr->flags & SELECTED) ? butPtr->offValuePtr
+ : butPtr->onValuePtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
+ == NULL) {
+ goto error;
}
+ break;
}
Tcl_Release((ClientData) butPtr);
return result;
- error:
+ error:
Tcl_Release((ClientData) butPtr);
return TCL_ERROR;
}
@@ -931,8 +929,8 @@ ButtonWidgetObjCmd(clientData, interp, objc, objv)
*
* DestroyButton --
*
- * This procedure is invoked by ButtonEventProc to free all the
- * resources of a button and clean up its state.
+ * This function is invoked by ButtonEventProc to free all the resources
+ * of a button and clean up its state.
*
* Results:
* None.
@@ -944,8 +942,8 @@ ButtonWidgetObjCmd(clientData, interp, objc, objv)
*/
static void
-DestroyButton(butPtr)
- TkButton *butPtr; /* Info about button widget. */
+DestroyButton(
+ TkButton *butPtr) /* Info about button widget. */
{
butPtr->flags |= BUTTON_DELETED;
TkpDestroyButton(butPtr);
@@ -955,9 +953,8 @@ DestroyButton(butPtr)
}
/*
- * Free up all the stuff that requires special handling, then
- * let Tk_FreeOptions handle all the standard option-related
- * stuff.
+ * Free up all the stuff that requires special handling, then let
+ * Tk_FreeOptions handle all the standard option-related stuff.
*/
Tcl_DeleteCommandFromToken(butPtr->interp, butPtr->widgetCmd);
@@ -972,6 +969,9 @@ DestroyButton(butPtr)
if (butPtr->selectImage != NULL) {
Tk_FreeImage(butPtr->selectImage);
}
+ if (butPtr->tristateImage != NULL) {
+ Tk_FreeImage(butPtr->tristateImage);
+ }
if (butPtr->normalTextGC != None) {
Tk_FreeGC(butPtr->display, butPtr->normalTextGC);
}
@@ -1009,28 +1009,28 @@ DestroyButton(butPtr)
*
* ConfigureButton --
*
- * This procedure is called to process an objc/objv list to set
+ * This function is called to process an objc/objv list to set
* configuration options for a button widget.
*
* Results:
- * The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then an error message is left in interp's result.
+ * The return value is a standard Tcl result. If TCL_ERROR is returned,
+ * then an error message is left in interp's result.
*
* Side effects:
- * Configuration information, such as text string, colors, font,
- * etc. get set for butPtr; old resources get freed, if there
- * were any. The button is redisplayed.
+ * Configuration information, such as text string, colors, font, etc. get
+ * set for butPtr; old resources get freed, if there were any. The button
+ * is redisplayed.
*
*----------------------------------------------------------------------
*/
static int
-ConfigureButton(interp, butPtr, objc, objv)
- Tcl_Interp *interp; /* Used for error reporting. */
- register TkButton *butPtr; /* Information about widget; may or may
+ConfigureButton(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ register TkButton *butPtr, /* Information about widget; may or may
* not already have values for some fields. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument values. */
{
Tk_SavedOptions savedOptions;
Tcl_Obj *errorResult = NULL;
@@ -1042,21 +1042,21 @@ ConfigureButton(interp, butPtr, objc, objv)
*/
if (butPtr->textVarNamePtr != NULL) {
- Tcl_UntraceVar(interp, Tcl_GetString(butPtr->textVarNamePtr),
+ Tcl_UntraceVar(interp, Tcl_GetString(butPtr->textVarNamePtr),
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ButtonTextVarProc, (ClientData) butPtr);
}
if (butPtr->selVarNamePtr != NULL) {
- Tcl_UntraceVar(interp, Tcl_GetString(butPtr->selVarNamePtr),
+ Tcl_UntraceVar(interp, Tcl_GetString(butPtr->selVarNamePtr),
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ButtonVarProc, (ClientData) butPtr);
}
/*
- * The following loop is potentially executed twice. During the
- * first pass configuration options get set to their new values.
- * If there is an error in this pass, we execute a second pass
- * to restore all the options to their previous values.
+ * The following loop is potentially executed twice. During the first pass
+ * configuration options get set to their new values. If there is an error
+ * in this pass, we execute a second pass to restore all the options to
+ * their previous values.
*/
for (error = 0; error <= 1; error++) {
@@ -1067,7 +1067,7 @@ ConfigureButton(interp, butPtr, objc, objv)
if (Tk_SetOptions(interp, (char *) butPtr,
butPtr->optionTable, objc, objv,
- butPtr->tkwin, &savedOptions, (int *) NULL) != TCL_OK) {
+ butPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
continue;
}
} else {
@@ -1089,8 +1089,8 @@ ConfigureButton(interp, butPtr, objc, objv)
/*
* A few options need special processing, such as setting the
- * background from a 3-D border, or filling in complicated
- * defaults that couldn't be specified to Tk_SetOptions.
+ * background from a 3-D border, or filling in complicated defaults
+ * that couldn't be specified to Tk_SetOptions.
*/
if ((butPtr->state == STATE_ACTIVE)
@@ -1114,28 +1114,43 @@ ConfigureButton(interp, butPtr, objc, objv)
if (butPtr->type >= TYPE_CHECK_BUTTON) {
Tcl_Obj *valuePtr, *namePtr;
-
+
if (butPtr->selVarNamePtr == NULL) {
butPtr->selVarNamePtr = Tcl_NewStringObj(
Tk_Name(butPtr->tkwin), -1);
Tcl_IncrRefCount(butPtr->selVarNamePtr);
}
namePtr = butPtr->selVarNamePtr;
-
+
/*
* Select the button if the associated variable has the
- * appropriate value, initialize the variable if it doesn't
- * exist, then set a trace on the variable to monitor future
- * changes to its value.
+ * appropriate value, initialize the variable if it doesn't exist,
+ * then set a trace on the variable to monitor future changes to
+ * its value.
*/
-
+
valuePtr = Tcl_ObjGetVar2(interp, namePtr, NULL, TCL_GLOBAL_ONLY);
butPtr->flags &= ~SELECTED;
+ butPtr->flags &= ~TRISTATED;
if (valuePtr != NULL) {
- if (strcmp(Tcl_GetString(valuePtr),
- Tcl_GetString(butPtr->onValuePtr)) == 0) {
+ const char *value = Tcl_GetString(valuePtr);
+ if (strcmp(value, Tcl_GetString(butPtr->onValuePtr)) == 0) {
butPtr->flags |= SELECTED;
- }
+ } else if (strcmp(value,
+ Tcl_GetString(butPtr->tristateValuePtr)) == 0) {
+ butPtr->flags |= TRISTATED;
+
+ /*
+ * For checkbuttons if the tristate value is the
+ * same as the offvalue then prefer off to tristate
+ */
+
+ if (butPtr->offValuePtr
+ && strcmp(value,
+ Tcl_GetString(butPtr->offValuePtr)) == 0) {
+ butPtr->flags &= ~TRISTATED;
+ }
+ }
} else {
if (Tcl_ObjSetVar2(interp, namePtr, NULL,
(butPtr->type == TYPE_CHECK_BUTTON)
@@ -1146,8 +1161,8 @@ ConfigureButton(interp, butPtr, objc, objv)
}
/*
- * If a radiobutton has the empty string as value
- * it should be selected.
+ * If a radiobutton has the empty string as value it should be
+ * selected.
*/
if ((butPtr->type == TYPE_RADIO_BUTTON) &&
@@ -1158,11 +1173,11 @@ ConfigureButton(interp, butPtr, objc, objv)
}
/*
- * Get the images for the widget, if there are any. Allocate the
- * new images before freeing the old ones, so that the reference
- * counts don't go to zero and cause image data to be discarded.
+ * Get the images for the widget, if there are any. Allocate the new
+ * images before freeing the old ones, so that the reference counts
+ * don't go to zero and cause image data to be discarded.
*/
-
+
if (butPtr->imagePtr != NULL) {
image = Tk_GetImage(butPtr->interp, butPtr->tkwin,
Tcl_GetString(butPtr->imagePtr), ButtonImageProc,
@@ -1191,6 +1206,20 @@ ConfigureButton(interp, butPtr, objc, objv)
Tk_FreeImage(butPtr->selectImage);
}
butPtr->selectImage = image;
+ if (butPtr->tristateImagePtr != NULL) {
+ image = Tk_GetImage(butPtr->interp, butPtr->tkwin,
+ Tcl_GetString(butPtr->tristateImagePtr),
+ ButtonTristateImageProc, (ClientData) butPtr);
+ if (image == NULL) {
+ continue;
+ }
+ } else {
+ image = NULL;
+ }
+ if (butPtr->tristateImage != NULL) {
+ Tk_FreeImage(butPtr->tristateImage);
+ }
+ butPtr->tristateImage = image;
haveImage = 0;
if (butPtr->imagePtr != NULL || butPtr->bitmap != None) {
@@ -1203,7 +1232,7 @@ ConfigureButton(interp, butPtr, objc, objv)
* on the variable's value, create the variable if it doesn't
* exist, and fetch its current value.
*/
-
+
Tcl_Obj *valuePtr, *namePtr;
namePtr = butPtr->textVarNamePtr;
@@ -1222,22 +1251,21 @@ ConfigureButton(interp, butPtr, objc, objv)
Tcl_IncrRefCount(butPtr->textPtr);
}
}
-
+
if ((butPtr->bitmap != None) || (butPtr->imagePtr != NULL)) {
/*
- * The button must display the contents of an image or
- * bitmap.
+ * The button must display the contents of an image or bitmap.
*/
if (Tk_GetPixelsFromObj(interp, butPtr->tkwin, butPtr->widthPtr,
&butPtr->width) != TCL_OK) {
- widthError:
+ widthError:
Tcl_AddErrorInfo(interp, "\n (processing -width option)");
continue;
}
if (Tk_GetPixelsFromObj(interp, butPtr->tkwin, butPtr->heightPtr,
&butPtr->height) != TCL_OK) {
- heightError:
+ heightError:
Tcl_AddErrorInfo(interp, "\n (processing -height option)");
continue;
}
@@ -1275,7 +1303,7 @@ ConfigureButton(interp, butPtr, objc, objv)
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ButtonVarProc, (ClientData) butPtr);
}
-
+
TkButtonWorldChanged((ClientData) butPtr);
if (error) {
Tcl_SetObjResult(interp, errorResult);
@@ -1291,9 +1319,9 @@ ConfigureButton(interp, butPtr, objc, objv)
*
* TkButtonWorldChanged --
*
- * This procedure is called when the world has changed in some
- * way and the widget needs to recompute all its graphics contexts
- * and determine its new geometry.
+ * This function is called when the world has changed in some way and the
+ * widget needs to recompute all its graphics contexts and determine its
+ * new geometry.
*
* Results:
* None.
@@ -1303,10 +1331,10 @@ ConfigureButton(interp, butPtr, objc, objv)
*
*---------------------------------------------------------------------------
*/
-
+
void
-TkButtonWorldChanged(instanceData)
- ClientData instanceData; /* Information about widget. */
+TkButtonWorldChanged(
+ ClientData instanceData) /* Information about widget. */
{
XGCValues gcValues;
GC newGC;
@@ -1322,7 +1350,7 @@ TkButtonWorldChanged(instanceData)
gcValues.font = Tk_FontId(butPtr->tkfont);
gcValues.foreground = butPtr->normalFg->pixel;
gcValues.background = Tk_3DBorderColor(butPtr->normalBorder)->pixel;
-
+
/*
* Note: GraphicsExpose events are disabled in normalTextGC because it's
* used to copy stuff from an off-screen pixmap onto the screen (we know
@@ -1369,8 +1397,8 @@ TkButtonWorldChanged(instanceData)
}
/*
- * Allocate the disabled graphics context, for drawing text in
- * its disabled state.
+ * Allocate the disabled graphics context, for drawing text in its
+ * disabled state.
*/
mask = GCForeground | GCBackground | GCFont;
@@ -1406,31 +1434,31 @@ TkButtonWorldChanged(instanceData)
*
* ButtonEventProc --
*
- * This procedure is invoked by the Tk dispatcher for various
- * events on buttons.
+ * This function is invoked by the Tk dispatcher for various events on
+ * buttons.
*
* Results:
* None.
*
* Side effects:
- * When the window gets deleted, internal structures get
- * cleaned up. When it gets exposed, it is redisplayed.
+ * When the window gets deleted, internal structures get cleaned up. When
+ * it gets exposed, it is redisplayed.
*
*--------------------------------------------------------------
*/
static void
-ButtonEventProc(clientData, eventPtr)
- ClientData clientData; /* Information about window. */
- XEvent *eventPtr; /* Information about event. */
+ButtonEventProc(
+ ClientData clientData, /* Information about window. */
+ XEvent *eventPtr) /* Information about event. */
{
TkButton *butPtr = (TkButton *) clientData;
if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
goto redraw;
} else if (eventPtr->type == ConfigureNotify) {
/*
- * Must redraw after size changes, since layout could have changed
- * and borders will need to be redrawn.
+ * Must redraw after size changes, since layout could have changed and
+ * borders will need to be redrawn.
*/
goto redraw;
@@ -1453,7 +1481,7 @@ ButtonEventProc(clientData, eventPtr)
}
return;
- redraw:
+ redraw:
if ((butPtr->tkwin != NULL) && !(butPtr->flags & REDRAW_PENDING)) {
Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr);
butPtr->flags |= REDRAW_PENDING;
@@ -1465,9 +1493,9 @@ ButtonEventProc(clientData, eventPtr)
*
* ButtonCmdDeletedProc --
*
- * This procedure is invoked when a widget command is deleted. If
- * the widget isn't already in the process of being destroyed,
- * this command destroys it.
+ * This function is invoked when a widget command is deleted. If the
+ * widget isn't already in the process of being destroyed, this command
+ * destroys it.
*
* Results:
* None.
@@ -1479,16 +1507,16 @@ ButtonEventProc(clientData, eventPtr)
*/
static void
-ButtonCmdDeletedProc(clientData)
- ClientData clientData; /* Pointer to widget record for widget. */
+ButtonCmdDeletedProc(
+ ClientData clientData) /* Pointer to widget record for widget. */
{
TkButton *butPtr = (TkButton *) clientData;
/*
- * This procedure could be invoked either because the window was
- * destroyed and the command was then deleted or because the command
- * was deleted, and then this procedure destroys the widget. The
- * BUTTON_DELETED flag distinguishes these cases.
+ * This function could be invoked either because the window was destroyed
+ * and the command was then deleted or because the command was deleted,
+ * and then this function destroys the widget. The BUTTON_DELETED flag
+ * distinguishes these cases.
*/
if (!(butPtr->flags & BUTTON_DELETED)) {
@@ -1501,14 +1529,14 @@ ButtonCmdDeletedProc(clientData)
*
* TkInvokeButton --
*
- * This procedure is called to carry out the actions associated
- * with a button, such as invoking a Tcl command or setting a
- * variable. This procedure is invoked, for example, when the
- * button is invoked via the mouse.
+ * This function is called to carry out the actions associated with a
+ * button, such as invoking a Tcl command or setting a variable. This
+ * function is invoked, for example, when the button is invoked via the
+ * mouse.
*
* Results:
- * A standard Tcl return value. Information is also left in
- * the interp's result.
+ * A standard Tcl return value. Information is also left in the interp's
+ * result.
*
* Side effects:
* Depends on the button and its associated command.
@@ -1517,8 +1545,8 @@ ButtonCmdDeletedProc(clientData)
*/
int
-TkInvokeButton(butPtr)
- TkButton *butPtr; /* Information about button. */
+TkInvokeButton(
+ TkButton *butPtr) /* Information about button. */
{
Tcl_Obj *namePtr = butPtr->selVarNamePtr;
@@ -1555,10 +1583,9 @@ TkInvokeButton(butPtr)
*
* ButtonVarProc --
*
- * This procedure is invoked when someone changes the
- * state variable associated with a radio button. Depending
- * on the new value of the button's variable, the button
- * may be selected or deselected.
+ * This function is invoked when someone changes the state variable
+ * associated with a radio button. Depending on the new value of the
+ * button's variable, the button may be selected or deselected.
*
* Results:
* NULL is always returned.
@@ -1571,12 +1598,12 @@ TkInvokeButton(butPtr)
/* ARGSUSED */
static char *
-ButtonVarProc(clientData, interp, name1, name2, flags)
- ClientData clientData; /* Information about button. */
- Tcl_Interp *interp; /* Interpreter containing variable. */
- CONST char *name1; /* Name of variable. */
- CONST char *name2; /* Second part of variable name. */
- int flags; /* Information about what happened. */
+ButtonVarProc(
+ ClientData clientData, /* Information about button. */
+ Tcl_Interp *interp, /* Interpreter containing variable. */
+ const char *name1, /* Name of variable. */
+ const char *name2, /* Second part of variable name. */
+ int flags) /* Information about what happened. */
{
register TkButton *butPtr = (TkButton *) clientData;
char *name, *value;
@@ -1585,12 +1612,13 @@ ButtonVarProc(clientData, interp, name1, name2, flags)
name = Tcl_GetString(butPtr->selVarNamePtr);
/*
- * If the variable is being unset, then just re-establish the
- * trace unless the whole interpreter is going away.
+ * If the variable is being unset, then just re-establish the trace unless
+ * the whole interpreter is going away.
*/
if (flags & TCL_TRACE_UNSETS) {
butPtr->flags &= ~SELECTED;
+ butPtr->flags &= ~TRISTATED;
if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {
Tcl_TraceVar(interp, name,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
@@ -1600,34 +1628,47 @@ ButtonVarProc(clientData, interp, name1, name2, flags)
}
/*
- * Use the value of the variable to update the selected status of
- * the button.
+ * Use the value of the variable to update the selected status of the
+ * button.
*/
valuePtr = Tcl_GetVar2Ex(interp, name, NULL, TCL_GLOBAL_ONLY);
if (valuePtr == NULL) {
- value = "";
+ value = Tcl_GetString(butPtr->tristateValuePtr);
} else {
value = Tcl_GetString(valuePtr);
}
if (strcmp(value, Tcl_GetString(butPtr->onValuePtr)) == 0) {
if (butPtr->flags & SELECTED) {
- return (char *) NULL;
+ return NULL;
}
butPtr->flags |= SELECTED;
- } else if (butPtr->flags & SELECTED) {
- butPtr->flags &= ~SELECTED;
+ butPtr->flags &= ~TRISTATED;
+ } else if (butPtr->offValuePtr
+ && strcmp(value, Tcl_GetString(butPtr->offValuePtr)) == 0) {
+ if (!(butPtr->flags & (SELECTED | TRISTATED))) {
+ return NULL;
+ }
+ butPtr->flags &= ~(SELECTED | TRISTATED);
+ } else if (strcmp(value, Tcl_GetString(butPtr->tristateValuePtr)) == 0) {
+ if (butPtr->flags & TRISTATED) {
+ return NULL;
+ }
+ butPtr->flags |= TRISTATED;
+ butPtr->flags &= ~SELECTED;
+ } else if (butPtr->flags & (SELECTED | TRISTATED)) {
+ butPtr->flags &= ~(SELECTED | TRISTATED);
} else {
- return (char *) NULL;
+ return NULL;
}
- redisplay:
+ redisplay:
if ((butPtr->tkwin != NULL) && Tk_IsMapped(butPtr->tkwin)
&& !(butPtr->flags & REDRAW_PENDING)) {
Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr);
butPtr->flags |= REDRAW_PENDING;
}
- return (char *) NULL;
+ return NULL;
}
/*
@@ -1635,52 +1676,51 @@ ButtonVarProc(clientData, interp, name1, name2, flags)
*
* ButtonTextVarProc --
*
- * This procedure is invoked when someone changes the variable
- * whose contents are to be displayed in a button.
+ * This function is invoked when someone changes the variable whose
+ * contents are to be displayed in a button.
*
* Results:
* NULL is always returned.
*
* Side effects:
- * The text displayed in the button will change to match the
- * variable.
+ * The text displayed in the button will change to match the variable.
*
*--------------------------------------------------------------
*/
/* ARGSUSED */
static char *
-ButtonTextVarProc(clientData, interp, name1, name2, flags)
- ClientData clientData; /* Information about button. */
- Tcl_Interp *interp; /* Interpreter containing variable. */
- CONST char *name1; /* Not used. */
- CONST char *name2; /* Not used. */
- int flags; /* Information about what happened. */
+ButtonTextVarProc(
+ ClientData clientData, /* Information about button. */
+ Tcl_Interp *interp, /* Interpreter containing variable. */
+ const char *name1, /* Not used. */
+ const char *name2, /* Not used. */
+ int flags) /* Information about what happened. */
{
TkButton *butPtr = (TkButton *) clientData;
char *name;
Tcl_Obj *valuePtr;
if (butPtr->flags & BUTTON_DELETED) {
- return (char *) NULL;
+ return NULL;
}
name = Tcl_GetString(butPtr->textVarNamePtr);
/*
- * If the variable is unset, then immediately recreate it unless
- * the whole interpreter is going away.
+ * If the variable is unset, then immediately recreate it unless the whole
+ * interpreter is going away.
*/
if (flags & TCL_TRACE_UNSETS) {
if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {
- Tcl_SetVar2Ex(interp, name, NULL, butPtr->textPtr,
+ Tcl_SetVar2Ex(interp, name, NULL, butPtr->textPtr,
TCL_GLOBAL_ONLY);
Tcl_TraceVar(interp, name,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ButtonTextVarProc, clientData);
}
- return (char *) NULL;
+ return NULL;
}
valuePtr = Tcl_GetVar2Ex(interp, name, NULL, TCL_GLOBAL_ONLY);
@@ -1697,7 +1737,7 @@ ButtonTextVarProc(clientData, interp, name1, name2, flags)
Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr);
butPtr->flags |= REDRAW_PENDING;
}
- return (char *) NULL;
+ return NULL;
}
/*
@@ -1705,9 +1745,9 @@ ButtonTextVarProc(clientData, interp, name1, name2, flags)
*
* ButtonImageProc --
*
- * This procedure is invoked by the image code whenever the manager
- * for an image does something that affects the size or contents
- * of an image displayed in a button.
+ * This function is invoked by the image code whenever the manager for an
+ * image does something that affects the size or contents of an image
+ * displayed in a button.
*
* Results:
* None.
@@ -1719,13 +1759,13 @@ ButtonTextVarProc(clientData, interp, name1, name2, flags)
*/
static void
-ButtonImageProc(clientData, x, y, width, height, imgWidth, imgHeight)
- ClientData clientData; /* Pointer to widget record. */
- int x, y; /* Upper left pixel (within image)
- * that must be redisplayed. */
- int width, height; /* Dimensions of area to redisplay
- * (may be <= 0). */
- int imgWidth, imgHeight; /* New dimensions of image. */
+ButtonImageProc(
+ ClientData clientData, /* Pointer to widget record. */
+ int x, int y, /* Upper left pixel (within image) that must
+ * be redisplayed. */
+ int width, int height, /* Dimensions of area to redisplay (might be
+ * <= 0). */
+ int imgWidth, int imgHeight)/* New dimensions of image. */
{
register TkButton *butPtr = (TkButton *) clientData;
@@ -1743,9 +1783,9 @@ ButtonImageProc(clientData, x, y, width, height, imgWidth, imgHeight)
*
* ButtonSelectImageProc --
*
- * This procedure is invoked by the image code whenever the manager
- * for an image does something that affects the size or contents
- * of the image displayed in a button when it is selected.
+ * This function is invoked by the image code whenever the manager for an
+ * image does something that affects the size or contents of the image
+ * displayed in a button when it is selected.
*
* Results:
* None.
@@ -1757,18 +1797,18 @@ ButtonImageProc(clientData, x, y, width, height, imgWidth, imgHeight)
*/
static void
-ButtonSelectImageProc(clientData, x, y, width, height, imgWidth, imgHeight)
- ClientData clientData; /* Pointer to widget record. */
- int x, y; /* Upper left pixel (within image)
- * that must be redisplayed. */
- int width, height; /* Dimensions of area to redisplay
- * (may be <= 0). */
- int imgWidth, imgHeight; /* New dimensions of image. */
+ButtonSelectImageProc(
+ ClientData clientData, /* Pointer to widget record. */
+ int x, int y, /* Upper left pixel (within image) that must
+ * be redisplayed. */
+ int width, int height, /* Dimensions of area to redisplay (might be
+ * <= 0). */
+ int imgWidth, int imgHeight)/* New dimensions of image. */
{
register TkButton *butPtr = (TkButton *) clientData;
/*
- * Don't recompute geometry: it's controlled by the primary image.
+ * Don't recompute geometry: it's controlled by the primary image.
*/
if ((butPtr->flags & SELECTED) && (butPtr->tkwin != NULL)
@@ -1778,3 +1818,52 @@ ButtonSelectImageProc(clientData, x, y, width, height, imgWidth, imgHeight)
butPtr->flags |= REDRAW_PENDING;
}
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ButtonTristateImageProc --
+ *
+ * This function is invoked by the image code whenever the manager for an
+ * image does something that affects the size or contents of the image
+ * displayed in a button when it is selected.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May arrange for the button to get redisplayed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ButtonTristateImageProc(
+ ClientData clientData, /* Pointer to widget record. */
+ int x, int y, /* Upper left pixel (within image) that must
+ * be redisplayed. */
+ int width, int height, /* Dimensions of area to redisplay (might be
+ * <= 0). */
+ int imgWidth, int imgHeight)/* New dimensions of image. */
+{
+ register TkButton *butPtr = (TkButton *) clientData;
+
+ /*
+ * Don't recompute geometry: it's controlled by the primary image.
+ */
+
+ if ((butPtr->flags & TRISTATED) && (butPtr->tkwin != NULL)
+ && Tk_IsMapped(butPtr->tkwin)
+ && !(butPtr->flags & REDRAW_PENDING)) {
+ Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr);
+ butPtr->flags |= REDRAW_PENDING;
+ }
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */