The Widget Instance Command

   

Practical Programming in Tcl & Tk, Third Edition
By Brent B. Welch

Table of Contents
Chapter 46.  Writing a Tk Widget in C


For each instance of a widget, a new command is created that operates on that widget. This is called the widget instance command. Its name is the same as the Tk pathname of the widget. In the clock example, all that is done on instances is to query and change their attributes. Most of the work is done by Tk_ConfigureWidget and ClockConfigure, which are shown in the next section. The ClockInstanceCmd command procedure is shown in the next example:

Example 46-5 The ClockInstanceCmd command procedure.
 static int ClockInstanceCmd(clientData, interp, argc, argv)    ClientData clientData;/* A pointer to a Clock struct */    Tcl_Interp *interp;  /* The interpreter */    int argc;            /* The number of arguments */    char *argv[];        /* The command line arguments */ {    Clock *clockPtr = (Clock *)clientData;    int result = TCL_OK;    char c;    int len;    if (argc < 2) {       Tcl_AppendResult(interp, "wrong # args: should be \"",          argv[0], " option ?arg arg ...?\"", (char *) NULL);       return TCL_ERROR;    }    c = argv[1][0];    len = strlen(argv[1]);    if ((c == 'c') && (strncmp(argv[1], "cget", len) == 0)           && (len >= 2)) {       if (argc != 3) {          Tcl_AppendResult(interp,              "wrong # args: should be \"",             argv[0], " cget option\"",             (char *) NULL);          return TCL_ERROR;       }       result = Tk_ConfigureValue(interp, clockPtr->tkwin,           configSpecs, (char *) clockPtr, argv[2], 0);    } else if ((c == 'c') && (strncmp(argv[1], "configure", len)              == 0) && (len >= 2)) {       if (argc == 2) {          /*           * Return all configuration information.           */          result = Tk_ConfigureInfo(interp, clockPtr->tkwin,             configSpecs, (char *) clockPtr,             (char *) NULL,0);       } else if (argc == 3) {          /*           * Return info about one attribute, like cget.           */          result = Tk_ConfigureInfo(interp, clockPtr->tkwin,             configSpecs, (char *) clockPtr, argv[2], 0);       } else {          /*           * Change one or more attributes.           */           result = ClockConfigure(interp, clockPtr, argc-2,              argv+2,TK_CONFIG_ARGV_ONLY);       }    } else {       Tcl_AppendResult(interp, "bad option \"", argv[1],          "\": must be cget, configure, position, or size",          (char *) NULL);       return TCL_ERROR;    }    return result; } 

Example 46-6 shows the ClockInstanceObjCmd procedure. It uses the Tk_GetIndexFromObj routine to map the first argument to an index, which is then used in a switch statement. It uses the Tk_GetOptionValue and Tk_GetOptionInfo procedures to parse the widget configuration options.

Example 46-6 The ClockInstanceObjCmd command procedure.
 static int ClockInstanceObjCmd(clientData, interp, objc, objv)    ClientData clientData;/* A pointer to a Clock struct */    Tcl_Interp *interp; /* The interpreter */    int objc;           /* The number of arguments */    Tcl_Obj *objv[];    /* The command line arguments */ {    Clock *clockPtr = (Clock *)clientData;    char *commands[] = {"cget", "configure", NULL};    enum command {CLOCK_CGET, CLOCK_CONFIGURE};    int result;    Tcl_Obj *objPtr;    int index;    if (objc < 2) {       Tcl_WrongNumArgs(interp, 1, objv,          "option ?arg arg ...?");       return TCL_ERROR;    }    result = Tcl_GetIndexFromObj(interp, objv[1], commands,          "option", 0, &index);    if (result != TCL_OK) {       return result;    }    switch (index) {       case CLOCK_CGET: {          if (objc != 3) {             Tcl_WrongNumArgs(interp, 1, objv,                "cget option");             return TCL_ERROR;          }          objPtr = Tk_GetOptionValue(interp,                 (char *)clockPtr,                 clockPtr->optionTable,                 (objc == 3) ? objv[2] : NULL,                 clockPtr->tkwin);          if (objPtr == NULL) {             return TCL_ERROR;          } else {            Tcl_SetObjResult(interp, objPtr);          }          break;       }       case CLOCK_CONFIGURE: {          if (objc <= 3) {             /*              * Return one item if the option is given,              * or return all configuration information.              */             objPtr = Tk_GetOptionInfo(interp,                    (char *) clockPtr,                    clockPtr->optionTable,                    (objc == 3) ? objv[2] : NULL,                    clockPtr->tkwin);             if (objPtr == NULL) {                return TCL_ERROR;             } else {               Tcl_SetObjResult(interp, objPtr);             }          } else {             /*              * Change one or more attributes.              */             result = ClockObjConfigure(interp, clockPtr,                objc-2, objv+2);          }       }    }    return TCL_OK; } 

       
    Top
     



    Practical Programming in Tcl and Tk
    Practical Programming in Tcl and Tk (4th Edition)
    ISBN: 0130385603
    EAN: 2147483647
    Year: 1999
    Pages: 478

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net