diff options
Diffstat (limited to 'tk/generic/tkPlace.c')
-rw-r--r-- | tk/generic/tkPlace.c | 749 |
1 files changed, 423 insertions, 326 deletions
diff --git a/tk/generic/tkPlace.c b/tk/generic/tkPlace.c index d48895b2d41..a2909799e87 100644 --- a/tk/generic/tkPlace.c +++ b/tk/generic/tkPlace.c @@ -16,6 +16,7 @@ #include "tkPort.h" #include "tkInt.h" + /* * Border modes for relative placement: * @@ -27,6 +28,10 @@ * master's actual window size. */ +static char *borderModeStrings[] = { + "inside", "outside", "ignore", (char *) NULL +}; + typedef enum {BM_INSIDE, BM_OUTSIDE, BM_IGNORE} BorderMode; /* @@ -36,6 +41,7 @@ typedef enum {BM_INSIDE, BM_OUTSIDE, BM_IGNORE} BorderMode; typedef struct Slave { Tk_Window tkwin; /* Tk's token for window. */ + Tk_Window inTkwin; /* Token for the -in window. */ struct Master *masterPtr; /* Pointer to information for window * relative to which tkwin is placed. * This isn't necessarily the logical @@ -43,7 +49,6 @@ typedef struct Slave { * master was deleted or never assigned. */ struct Slave *nextPtr; /* Next in list of windows placed relative * to same master (NULL for end of list). */ - /* * Geometry information for window; where there are both relative * and absolute values for the same attribute (e.g. x and relX) only @@ -51,11 +56,17 @@ typedef struct Slave { */ int x, y; /* X and Y pixel coordinates for tkwin. */ - float relX, relY; /* X and Y coordinates relative to size of + Tcl_Obj *xPtr, *yPtr; /* Tcl_Obj rep's of x, y coords, to keep + * pixel spec. information */ + double relX, relY; /* X and Y coordinates relative to size of * master. */ int width, height; /* Absolute dimensions for tkwin. */ - float relWidth, relHeight; /* Dimensions for tkwin relative to size of + Tcl_Obj *widthPtr; /* Tcl_Obj rep of width, to keep pixel spec */ + Tcl_Obj *heightPtr; /* Tcl_Obj rep of height, to keep pixel spec */ + double relWidth, relHeight; /* Dimensions for tkwin relative to size of * master. */ + Tcl_Obj *relWidthPtr; + Tcl_Obj *relHeightPtr; Tk_Anchor anchor; /* Which point on tkwin is placed at the * given position. */ BorderMode borderMode; /* How to treat borders of master window. */ @@ -64,6 +75,40 @@ typedef struct Slave { } Slave; /* + * Type masks for options: + */ +#define IN_MASK 1 + +static Tk_OptionSpec optionSpecs[] = { + {TK_OPTION_ANCHOR, "-anchor", NULL, NULL, "nw", -1, + Tk_Offset(Slave, anchor), 0, 0, 0}, + {TK_OPTION_STRING_TABLE, "-bordermode", NULL, NULL, "inside", -1, + Tk_Offset(Slave, borderMode), 0, (ClientData) borderModeStrings, 0}, + {TK_OPTION_PIXELS, "-height", NULL, NULL, "", Tk_Offset(Slave, heightPtr), + Tk_Offset(Slave, height), TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_WINDOW, "-in", NULL, NULL, "", -1, Tk_Offset(Slave, inTkwin), + 0, 0, IN_MASK}, + {TK_OPTION_DOUBLE, "-relheight", NULL, NULL, "", + Tk_Offset(Slave, relHeightPtr), Tk_Offset(Slave, relHeight), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_DOUBLE, "-relwidth", NULL, NULL, "", + Tk_Offset(Slave, relWidthPtr), Tk_Offset(Slave, relWidth), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_DOUBLE, "-relx", NULL, NULL, "0", -1, + Tk_Offset(Slave, relX), 0, 0, 0}, + {TK_OPTION_DOUBLE, "-rely", NULL, NULL, "0", -1, + Tk_Offset(Slave, relY), 0, 0, 0}, + {TK_OPTION_PIXELS, "-width", NULL, NULL, "", Tk_Offset(Slave, widthPtr), + Tk_Offset(Slave, width), TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_PIXELS, "-x", NULL, NULL, "0", Tk_Offset(Slave, xPtr), + Tk_Offset(Slave, x), TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_PIXELS, "-y", NULL, NULL, "0", Tk_Offset(Slave, yPtr), + Tk_Offset(Slave, y), TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, 0, 0} +}; + +/* * Flag definitions for Slave structures: * * CHILD_WIDTH - 1 means -width was specified; @@ -121,8 +166,13 @@ static Tk_GeomMgr placerType = { static void SlaveStructureProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr)); static int ConfigureSlave _ANSI_ARGS_((Tcl_Interp *interp, - Slave *slavePtr, int argc, char **argv)); + Tk_Window tkwin, Tk_OptionTable table, + int objc, Tcl_Obj *CONST objv[])); +static int PlaceInfoCommand _ANSI_ARGS_((Tcl_Interp *interp, + Tk_Window tkwin)); +static Slave * CreateSlave _ANSI_ARGS_((Tk_Window tkwin)); static Slave * FindSlave _ANSI_ARGS_((Tk_Window tkwin)); +static Master * CreateMaster _ANSI_ARGS_((Tk_Window tkwin)); static Master * FindMaster _ANSI_ARGS_((Tk_Window tkwin)); static void MasterStructureProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr)); @@ -132,7 +182,7 @@ static void UnlinkSlave _ANSI_ARGS_((Slave *slavePtr)); /* *-------------------------------------------------------------- * - * Tk_PlaceCmd -- + * Tk_PlaceObjCmd -- * * This procedure is invoked to process the "place" Tcl * commands. See the user documentation for details on @@ -148,33 +198,43 @@ static void UnlinkSlave _ANSI_ARGS_((Slave *slavePtr)); */ int -Tk_PlaceCmd(clientData, interp, argc, argv) - ClientData clientData; /* Main window associated with interpreter. */ +Tk_PlaceObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* NULL. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ { Tk_Window tkwin; Slave *slavePtr; - Tcl_HashEntry *hPtr; - size_t length; - int c; + char *string; TkDisplay *dispPtr; - - if (argc < 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " option|pathName args", (char *) NULL); + Tk_OptionTable optionTable; + static CONST char *optionStrings[] = { + "configure", "forget", "info", "slaves", (char *) NULL + }; + enum options { PLACE_CONFIGURE, PLACE_FORGET, PLACE_INFO, PLACE_SLAVES }; + int index; + + + if (objc < 3) { + Tcl_WrongNumArgs(interp, 1, objv, "option|pathName args"); return TCL_ERROR; } - c = argv[1][0]; - length = strlen(argv[1]); + + /* + * 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); /* * Handle special shortcut where window name is first argument. */ - if (c == '.') { - tkwin = Tk_NameToWindow(interp, argv[1], (Tk_Window) clientData); + string = Tcl_GetString(objv[1]); + if (string[0] == '.') { + tkwin = Tk_NameToWindow(interp, string, Tk_MainWindow(interp)); if (tkwin == NULL) { return TCL_ERROR; } @@ -190,8 +250,7 @@ Tk_PlaceCmd(clientData, interp, argc, argv) dispPtr->placeInit = 1; } - slavePtr = FindSlave(tkwin); - return ConfigureSlave(interp, slavePtr, argc-2, argv+2); + return ConfigureSlave(interp, tkwin, optionTable, objc-2, objv+2); } /* @@ -199,7 +258,8 @@ Tk_PlaceCmd(clientData, interp, argc, argv) * by possible additional arguments. */ - tkwin = Tk_NameToWindow(interp, argv[2], (Tk_Window) clientData); + tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), + Tk_MainWindow(interp)); if (tkwin == NULL) { return TCL_ERROR; } @@ -215,131 +275,102 @@ Tk_PlaceCmd(clientData, interp, argc, argv) dispPtr->placeInit = 1; } - if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)) { - if (argc < 5) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], - " configure pathName option value ?option value ...?\"", - (char *) NULL); - return TCL_ERROR; - } - slavePtr = FindSlave(tkwin); - return ConfigureSlave(interp, slavePtr, argc-3, argv+3); - } else if ((c == 'f') && (strncmp(argv[1], "forget", length) == 0)) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " forget pathName\"", (char *) NULL); - return TCL_ERROR; - } - hPtr = Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) tkwin); - if (hPtr == NULL) { - return TCL_OK; - } - slavePtr = (Slave *) Tcl_GetHashValue(hPtr); - if ((slavePtr->masterPtr != NULL) && - (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin))) { - Tk_UnmaintainGeometry(slavePtr->tkwin, - slavePtr->masterPtr->tkwin); - } - UnlinkSlave(slavePtr); - Tcl_DeleteHashEntry(hPtr); - Tk_DeleteEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc, - (ClientData) slavePtr); - Tk_ManageGeometry(tkwin, (Tk_GeomMgr *) NULL, (ClientData) NULL); - Tk_UnmapWindow(tkwin); - ckfree((char *) slavePtr); - } else if ((c == 'i') && (strncmp(argv[1], "info", length) == 0)) { - char buffer[32 + TCL_INTEGER_SPACE]; + if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, + &index) != TCL_OK) { + return TCL_ERROR; + } - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " info pathName\"", (char *) NULL); - return TCL_ERROR; - } - hPtr = Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) tkwin); - if (hPtr == NULL) { - return TCL_OK; - } - slavePtr = (Slave *) Tcl_GetHashValue(hPtr); - sprintf(buffer, "-x %d", slavePtr->x); - Tcl_AppendResult(interp, buffer, (char *) NULL); - sprintf(buffer, " -relx %.4g", slavePtr->relX); - Tcl_AppendResult(interp, buffer, (char *) NULL); - sprintf(buffer, " -y %d", slavePtr->y); - Tcl_AppendResult(interp, buffer, (char *) NULL); - sprintf(buffer, " -rely %.4g", slavePtr->relY); - Tcl_AppendResult(interp, buffer, (char *) NULL); - if (slavePtr->flags & CHILD_WIDTH) { - sprintf(buffer, " -width %d", slavePtr->width); - Tcl_AppendResult(interp, buffer, (char *) NULL); - } else { - Tcl_AppendResult(interp, " -width {}", (char *) NULL); - } - if (slavePtr->flags & CHILD_REL_WIDTH) { - sprintf(buffer, " -relwidth %.4g", slavePtr->relWidth); - Tcl_AppendResult(interp, buffer, (char *) NULL); - } else { - Tcl_AppendResult(interp, " -relwidth {}", (char *) NULL); + switch ((enum options) index) { + case PLACE_CONFIGURE: { + Tcl_Obj *objPtr; + if (objc == 3 || objc == 4) { + slavePtr = FindSlave(tkwin); + if (slavePtr == NULL) { + return TCL_OK; + } + objPtr = Tk_GetOptionInfo(interp, (char *) slavePtr, + optionTable, + (objc == 4) ? objv[3] : (Tcl_Obj *) NULL, tkwin); + if (objPtr == NULL) { + return TCL_ERROR; + } else { + Tcl_SetObjResult(interp, objPtr); + return TCL_OK; + } + } else { + return ConfigureSlave(interp, tkwin, optionTable, objc-3, + objv+3); + } } - if (slavePtr->flags & CHILD_HEIGHT) { - sprintf(buffer, " -height %d", slavePtr->height); - Tcl_AppendResult(interp, buffer, (char *) NULL); - } else { - Tcl_AppendResult(interp, " -height {}", (char *) NULL); + + case PLACE_FORGET: { + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "pathName"); + return TCL_ERROR; + } + slavePtr = FindSlave(tkwin); + if (slavePtr == NULL) { + return TCL_OK; + } + if ((slavePtr->masterPtr != NULL) && + (slavePtr->masterPtr->tkwin != + Tk_Parent(slavePtr->tkwin))) { + Tk_UnmaintainGeometry(slavePtr->tkwin, + slavePtr->masterPtr->tkwin); + } + UnlinkSlave(slavePtr); + Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable, + (char *) tkwin)); + Tk_DeleteEventHandler(tkwin, StructureNotifyMask, + SlaveStructureProc, (ClientData) slavePtr); + Tk_ManageGeometry(tkwin, (Tk_GeomMgr *) NULL, (ClientData) NULL); + Tk_UnmapWindow(tkwin); + ckfree((char *) slavePtr); + break; } - if (slavePtr->flags & CHILD_REL_HEIGHT) { - sprintf(buffer, " -relheight %.4g", slavePtr->relHeight); - Tcl_AppendResult(interp, buffer, (char *) NULL); - } else { - Tcl_AppendResult(interp, " -relheight {}", (char *) NULL); + + case PLACE_INFO: { + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "pathName"); + return TCL_ERROR; + } + return PlaceInfoCommand(interp, tkwin); } - Tcl_AppendResult(interp, " -anchor ", Tk_NameOfAnchor(slavePtr->anchor), - (char *) NULL); - if (slavePtr->borderMode == BM_OUTSIDE) { - Tcl_AppendResult(interp, " -bordermode outside", (char *) NULL); - } else if (slavePtr->borderMode == BM_IGNORE) { - Tcl_AppendResult(interp, " -bordermode ignore", (char *) NULL); - } - if ((slavePtr->masterPtr != NULL) - && (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin))) { - Tcl_AppendResult(interp, " -in ", - Tk_PathName(slavePtr->masterPtr->tkwin), (char *) NULL); - } - } else if ((c == 's') && (strncmp(argv[1], "slaves", length) == 0)) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " slaves pathName\"", (char *) NULL); - return TCL_ERROR; - } - hPtr = Tcl_FindHashEntry(&dispPtr->masterTable, (char *) tkwin); - if (hPtr != NULL) { + case PLACE_SLAVES: { Master *masterPtr; - masterPtr = (Master *) Tcl_GetHashValue(hPtr); - for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; - slavePtr = slavePtr->nextPtr) { - Tcl_AppendElement(interp, Tk_PathName(slavePtr->tkwin)); + Tcl_Obj *listPtr; + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "pathName"); + return TCL_ERROR; } + masterPtr = FindMaster(tkwin); + if (masterPtr != NULL) { + listPtr = Tcl_NewObj(); + for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; + slavePtr = slavePtr->nextPtr) { + Tcl_ListObjAppendElement(interp, listPtr, + Tcl_NewStringObj(Tk_PathName(slavePtr->tkwin),-1)); + } + Tcl_SetObjResult(interp, listPtr); + } + break; } - } else { - Tcl_AppendResult(interp, "unknown or ambiguous option \"", argv[1], - "\": must be configure, forget, info, or slaves", - (char *) NULL); - return TCL_ERROR; } + return TCL_OK; } /* *---------------------------------------------------------------------- * - * FindSlave -- + * CreateSlave -- * * Given a Tk_Window token, find the Slave structure corresponding - * to that token (making a new one if necessary). + * to that token, creating a new one if necessary. * * Results: - * None. + * Pointer to the Slave structure. * * Side effects: * A new Slave structure may be created. @@ -348,7 +379,7 @@ Tk_PlaceCmd(clientData, interp, argc, argv) */ static Slave * -FindSlave(tkwin) +CreateSlave(tkwin) Tk_Window tkwin; /* Token for desired slave. */ { Tcl_HashEntry *hPtr; @@ -359,16 +390,11 @@ FindSlave(tkwin) hPtr = Tcl_CreateHashEntry(&dispPtr->slaveTable, (char *) tkwin, &new); if (new) { slavePtr = (Slave *) ckalloc(sizeof(Slave)); - slavePtr->tkwin = tkwin; - slavePtr->masterPtr = NULL; - slavePtr->nextPtr = NULL; - slavePtr->x = slavePtr->y = 0; - slavePtr->relX = slavePtr->relY = (float) 0.0; - slavePtr->width = slavePtr->height = 0; - slavePtr->relWidth = slavePtr->relHeight = (float) 0.0; - slavePtr->anchor = TK_ANCHOR_NW; - slavePtr->borderMode = BM_INSIDE; - slavePtr->flags = 0; + memset(slavePtr, 0, sizeof(Slave)); + slavePtr->tkwin = tkwin; + slavePtr->inTkwin = None; + slavePtr->anchor = TK_ANCHOR_NW; + slavePtr->borderMode = BM_INSIDE; Tcl_SetHashValue(hPtr, slavePtr); Tk_CreateEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc, (ClientData) slavePtr); @@ -382,6 +408,40 @@ FindSlave(tkwin) /* *---------------------------------------------------------------------- * + * FindSlave -- + * + * Given a Tk_Window token, find the Slave structure corresponding + * to that token. This is purely a lookup function; it will not + * create a record if one does not yet exist. + * + * Results: + * Pointer to Slave structure; NULL if none exists. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static Slave * +FindSlave(tkwin) + Tk_Window tkwin; /* Token for desired slave. */ +{ + Tcl_HashEntry *hPtr; + register Slave *slavePtr; + TkDisplay * dispPtr = ((TkWindow *) tkwin)->dispPtr; + + hPtr = Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) tkwin); + if (hPtr == NULL) { + return NULL; + } + slavePtr = (Slave *) Tcl_GetHashValue(hPtr); + return slavePtr; +} + +/* + *---------------------------------------------------------------------- + * * UnlinkSlave -- * * This procedure removes a slave window from the chain of slaves @@ -427,13 +487,13 @@ UnlinkSlave(slavePtr) /* *---------------------------------------------------------------------- * - * FindMaster -- + * CreateMaster -- * * Given a Tk_Window token, find the Master structure corresponding - * to that token (making a new one if necessary). + * to that token, creating a new one if necessary. * * Results: - * None. + * Pointer to the Master structure. * * Side effects: * A new Master structure may be created. @@ -442,7 +502,7 @@ UnlinkSlave(slavePtr) */ static Master * -FindMaster(tkwin) +CreateMaster(tkwin) Tk_Window tkwin; /* Token for desired master. */ { Tcl_HashEntry *hPtr; @@ -453,9 +513,9 @@ FindMaster(tkwin) hPtr = Tcl_CreateHashEntry(&dispPtr->masterTable, (char *) tkwin, &new); if (new) { masterPtr = (Master *) ckalloc(sizeof(Master)); - masterPtr->tkwin = tkwin; - masterPtr->slavePtr = NULL; - masterPtr->flags = 0; + masterPtr->tkwin = tkwin; + masterPtr->slavePtr = NULL; + masterPtr->flags = 0; Tcl_SetHashValue(hPtr, masterPtr); Tk_CreateEventHandler(masterPtr->tkwin, StructureNotifyMask, MasterStructureProc, (ClientData) masterPtr); @@ -468,6 +528,41 @@ FindMaster(tkwin) /* *---------------------------------------------------------------------- * + * FindMaster -- + * + * Given a Tk_Window token, find the Master structure corresponding + * to that token. This is simply a lookup procedure; a new record + * will not be created if one does not already exist. + * + * Results: + * Pointer to the Master structure; NULL if one does not exist for + * the given Tk_Window token. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static Master * +FindMaster(tkwin) + Tk_Window tkwin; /* Token for desired master. */ +{ + Tcl_HashEntry *hPtr; + register Master *masterPtr; + TkDisplay * dispPtr = ((TkWindow *) tkwin)->dispPtr; + + hPtr = Tcl_FindHashEntry(&dispPtr->masterTable, (char *) tkwin); + if (hPtr == NULL) { + return NULL; + } + masterPtr = (Master *) Tcl_GetHashValue(hPtr); + return masterPtr; +} + +/* + *---------------------------------------------------------------------- + * * ConfigureSlave -- * * This procedure is called to process an argv/argc list to @@ -485,191 +580,107 @@ FindMaster(tkwin) */ static int -ConfigureSlave(interp, slavePtr, argc, argv) +ConfigureSlave(interp, tkwin, table, objc, objv) Tcl_Interp *interp; /* Used for error reporting. */ - Slave *slavePtr; /* Pointer to current information - * about slave. */ - int argc; /* Number of config arguments. */ - char **argv; /* String values for arguments. */ + Tk_Window tkwin; /* Token for the window to manipulate. */ + Tk_OptionTable table; /* Token for option table. */ + int objc; /* Number of config arguments. */ + Tcl_Obj *CONST objv[]; /* Object values for arguments. */ { register Master *masterPtr; - int c, result; - size_t length; - double d; - - result = TCL_OK; - if (Tk_IsTopLevel(slavePtr->tkwin)) { + Tk_SavedOptions savedOptions; + int mask; + int result = TCL_OK; + Slave *slavePtr; + + if (Tk_TopWinHierarchy(tkwin)) { Tcl_AppendResult(interp, "can't use placer on top-level window \"", - Tk_PathName(slavePtr->tkwin), "\"; use wm command instead", + Tk_PathName(tkwin), "\"; use wm command instead", (char *) NULL); return TCL_ERROR; } - for ( ; argc > 0; argc -= 2, argv += 2) { - if (argc < 2) { - Tcl_AppendResult(interp, "extra option \"", argv[0], - "\" (option with no value?)", (char *) NULL); - result = TCL_ERROR; - goto done; - } - length = strlen(argv[0]); - c = argv[0][1]; - if ((c == 'a') && (strncmp(argv[0], "-anchor", length) == 0)) { - if (Tk_GetAnchor(interp, argv[1], &slavePtr->anchor) != TCL_OK) { - result = TCL_ERROR; - goto done; - } - } else if ((c == 'b') - && (strncmp(argv[0], "-bordermode", length) == 0)) { - c = argv[1][0]; - length = strlen(argv[1]); - if ((c == 'i') && (strncmp(argv[1], "ignore", length) == 0) - && (length >= 2)) { - slavePtr->borderMode = BM_IGNORE; - } else if ((c == 'i') && (strncmp(argv[1], "inside", length) == 0) - && (length >= 2)) { - slavePtr->borderMode = BM_INSIDE; - } else if ((c == 'o') - && (strncmp(argv[1], "outside", length) == 0)) { - slavePtr->borderMode = BM_OUTSIDE; - } else { - Tcl_AppendResult(interp, "bad border mode \"", argv[1], - "\": must be ignore, inside, or outside", - (char *) NULL); - result = TCL_ERROR; - goto done; - } - } else if ((c == 'h') && (strncmp(argv[0], "-height", length) == 0)) { - if (argv[1][0] == 0) { - slavePtr->flags &= ~CHILD_HEIGHT; - } else { - if (Tk_GetPixels(interp, slavePtr->tkwin, argv[1], - &slavePtr->height) != TCL_OK) { - result = TCL_ERROR; - goto done; - } - slavePtr->flags |= CHILD_HEIGHT; - } - } else if ((c == 'i') && (strncmp(argv[0], "-in", length) == 0)) { - Tk_Window tkwin; - Tk_Window ancestor; - - tkwin = Tk_NameToWindow(interp, argv[1], slavePtr->tkwin); - if (tkwin == NULL) { - result = TCL_ERROR; - goto done; - } - /* - * Make sure that the new master is either the logical parent - * of the slave or a descendant of that window, and that the - * master and slave aren't the same. - */ + slavePtr = CreateSlave(tkwin); + + if (Tk_SetOptions(interp, (char *)slavePtr, table, objc, objv, + slavePtr->tkwin, &savedOptions, &mask) != TCL_OK) { + Tk_RestoreSavedOptions(&savedOptions); + result = TCL_ERROR; + goto done; + } - for (ancestor = tkwin; ; ancestor = Tk_Parent(ancestor)) { - if (ancestor == Tk_Parent(slavePtr->tkwin)) { - break; - } - if (Tk_IsTopLevel(ancestor)) { - Tcl_AppendResult(interp, "can't place ", - Tk_PathName(slavePtr->tkwin), " relative to ", - Tk_PathName(tkwin), (char *) NULL); - result = TCL_ERROR; - goto done; - } + if (mask & IN_MASK) { + /* -in changed */ + Tk_Window tkwin; + Tk_Window ancestor; + + tkwin = slavePtr->inTkwin; + + /* + * Make sure that the new master is either the logical parent + * of the slave or a descendant of that window, and that the + * master and slave aren't the same. + */ + + for (ancestor = tkwin; ; ancestor = Tk_Parent(ancestor)) { + if (ancestor == Tk_Parent(slavePtr->tkwin)) { + break; } - if (slavePtr->tkwin == tkwin) { + if (Tk_TopWinHierarchy(ancestor)) { Tcl_AppendResult(interp, "can't place ", - Tk_PathName(slavePtr->tkwin), " relative to itself", - (char *) NULL); - result = TCL_ERROR; - goto done; - } - if ((slavePtr->masterPtr != NULL) - && (slavePtr->masterPtr->tkwin == tkwin)) { - /* - * Re-using same old master. Nothing to do. - */ - } else { - if ((slavePtr->masterPtr != NULL) - && (slavePtr->masterPtr->tkwin - != Tk_Parent(slavePtr->tkwin))) { - Tk_UnmaintainGeometry(slavePtr->tkwin, - slavePtr->masterPtr->tkwin); - } - UnlinkSlave(slavePtr); - slavePtr->masterPtr = FindMaster(tkwin); - slavePtr->nextPtr = slavePtr->masterPtr->slavePtr; - slavePtr->masterPtr->slavePtr = slavePtr; - } - } else if ((c == 'r') && (strncmp(argv[0], "-relheight", length) == 0) - && (length >= 5)) { - if (argv[1][0] == 0) { - slavePtr->flags &= ~CHILD_REL_HEIGHT; - } else { - if (Tcl_GetDouble(interp, argv[1], &d) != TCL_OK) { - result = TCL_ERROR; - goto done; - } - slavePtr->relHeight = (float) d; - slavePtr->flags |= CHILD_REL_HEIGHT; - } - } else if ((c == 'r') && (strncmp(argv[0], "-relwidth", length) == 0) - && (length >= 5)) { - if (argv[1][0] == 0) { - slavePtr->flags &= ~CHILD_REL_WIDTH; - } else { - if (Tcl_GetDouble(interp, argv[1], &d) != TCL_OK) { - result = TCL_ERROR; - goto done; - } - slavePtr->relWidth = (float) d; - slavePtr->flags |= CHILD_REL_WIDTH; - } - } else if ((c == 'r') && (strncmp(argv[0], "-relx", length) == 0) - && (length >= 5)) { - if (Tcl_GetDouble(interp, argv[1], &d) != TCL_OK) { - result = TCL_ERROR; - goto done; - } - slavePtr->relX = (float) d; - } else if ((c == 'r') && (strncmp(argv[0], "-rely", length) == 0) - && (length >= 5)) { - if (Tcl_GetDouble(interp, argv[1], &d) != TCL_OK) { - result = TCL_ERROR; - goto done; - } - slavePtr->relY = (float) d; - } else if ((c == 'w') && (strncmp(argv[0], "-width", length) == 0)) { - if (argv[1][0] == 0) { - slavePtr->flags &= ~CHILD_WIDTH; - } else { - if (Tk_GetPixels(interp, slavePtr->tkwin, argv[1], - &slavePtr->width) != TCL_OK) { - result = TCL_ERROR; - goto done; - } - slavePtr->flags |= CHILD_WIDTH; - } - } else if ((c == 'x') && (strncmp(argv[0], "-x", length) == 0)) { - if (Tk_GetPixels(interp, slavePtr->tkwin, argv[1], - &slavePtr->x) != TCL_OK) { - result = TCL_ERROR; - goto done; - } - } else if ((c == 'y') && (strncmp(argv[0], "-y", length) == 0)) { - if (Tk_GetPixels(interp, slavePtr->tkwin, argv[1], - &slavePtr->y) != TCL_OK) { + Tk_PathName(slavePtr->tkwin), " relative to ", + Tk_PathName(tkwin), (char *) NULL); result = TCL_ERROR; + Tk_RestoreSavedOptions(&savedOptions); goto done; } - } else { - Tcl_AppendResult(interp, "unknown or ambiguous option \"", - argv[0], "\": must be -anchor, -bordermode, -height, ", - "-in, -relheight, -relwidth, -relx, -rely, -width, ", - "-x, or -y", (char *) NULL); + } + if (slavePtr->tkwin == tkwin) { + Tcl_AppendResult(interp, "can't place ", + Tk_PathName(slavePtr->tkwin), " relative to itself", + (char *) NULL); result = TCL_ERROR; + Tk_RestoreSavedOptions(&savedOptions); goto done; } + if ((slavePtr->masterPtr != NULL) + && (slavePtr->masterPtr->tkwin == tkwin)) { + /* + * Re-using same old master. Nothing to do. + */ + } else { + if ((slavePtr->masterPtr != NULL) + && (slavePtr->masterPtr->tkwin + != Tk_Parent(slavePtr->tkwin))) { + Tk_UnmaintainGeometry(slavePtr->tkwin, + slavePtr->masterPtr->tkwin); + } + UnlinkSlave(slavePtr); + slavePtr->masterPtr = CreateMaster(tkwin); + slavePtr->nextPtr = slavePtr->masterPtr->slavePtr; + slavePtr->masterPtr->slavePtr = slavePtr; + } + } + + /* + * Set slave flags. First clear the field, then add bits as needed. + */ + + slavePtr->flags = 0; + if (slavePtr->heightPtr) { + slavePtr->flags |= CHILD_HEIGHT; + } + + if (slavePtr->relHeightPtr) { + slavePtr->flags |= CHILD_REL_HEIGHT; + } + + if (slavePtr->relWidthPtr) { + slavePtr->flags |= CHILD_REL_WIDTH; + } + + if (slavePtr->widthPtr) { + slavePtr->flags |= CHILD_WIDTH; } /* @@ -677,14 +688,16 @@ ConfigureSlave(interp, slavePtr, argc, argv) * Then arrange for a placement recalculation in the master. */ + Tk_FreeSavedOptions(&savedOptions); done: masterPtr = slavePtr->masterPtr; if (masterPtr == NULL) { - masterPtr = FindMaster(Tk_Parent(slavePtr->tkwin)); + masterPtr = CreateMaster(Tk_Parent(slavePtr->tkwin)); slavePtr->masterPtr = masterPtr; slavePtr->nextPtr = masterPtr->slavePtr; masterPtr->slavePtr = slavePtr; } + slavePtr->inTkwin = masterPtr->tkwin; if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) { masterPtr->flags |= PARENT_RECONFIG_PENDING; Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr); @@ -695,6 +708,88 @@ ConfigureSlave(interp, slavePtr, argc, argv) /* *---------------------------------------------------------------------- * + * PlaceInfoCommand -- + * + * Implementation of the [place info] subcommand. See the user + * documentation for information on what it does. + * + * Results: + * Standard Tcl result. + * + * Side effects: + * If the given tkwin is managed by the placer, this function will + * put information about that placement in the interp's result. + * + *---------------------------------------------------------------------- + */ + +static int +PlaceInfoCommand(interp, tkwin) + Tcl_Interp *interp; /* Interp into which to place result. */ + Tk_Window tkwin; /* Token for the window to get info on. */ +{ + char buffer[32 + TCL_INTEGER_SPACE]; + Slave *slavePtr; + + slavePtr = FindSlave(tkwin); + if (slavePtr == NULL) { + return TCL_OK; + } + sprintf(buffer, "-x %d", slavePtr->x); + Tcl_AppendResult(interp, buffer, (char *) NULL); + sprintf(buffer, " -relx %.4g", slavePtr->relX); + Tcl_AppendResult(interp, buffer, (char *) NULL); + sprintf(buffer, " -y %d", slavePtr->y); + Tcl_AppendResult(interp, buffer, (char *) NULL); + sprintf(buffer, " -rely %.4g", slavePtr->relY); + Tcl_AppendResult(interp, buffer, (char *) NULL); + if (slavePtr->flags & CHILD_WIDTH) { + sprintf(buffer, " -width %d", slavePtr->width); + Tcl_AppendResult(interp, buffer, (char *) NULL); + } else { + Tcl_AppendResult(interp, " -width {}", (char *) NULL); + } + if (slavePtr->flags & CHILD_REL_WIDTH) { + sprintf(buffer, " -relwidth %.4g", slavePtr->relWidth); + Tcl_AppendResult(interp, buffer, (char *) NULL); + } else { + Tcl_AppendResult(interp, " -relwidth {}", (char *) NULL); + } + if (slavePtr->flags & CHILD_HEIGHT) { + sprintf(buffer, " -height %d", slavePtr->height); + Tcl_AppendResult(interp, buffer, (char *) NULL); + } else { + Tcl_AppendResult(interp, " -height {}", (char *) NULL); + } + if (slavePtr->flags & CHILD_REL_HEIGHT) { + sprintf(buffer, " -relheight %.4g", slavePtr->relHeight); + Tcl_AppendResult(interp, buffer, (char *) NULL); + } else { + Tcl_AppendResult(interp, " -relheight {}", (char *) NULL); + } + + Tcl_AppendResult(interp, " -anchor ", + Tk_NameOfAnchor(slavePtr->anchor), + (char *) NULL); + if (slavePtr->borderMode == BM_OUTSIDE) { + Tcl_AppendResult(interp, " -bordermode outside", + (char *) NULL); + } else if (slavePtr->borderMode == BM_IGNORE) { + Tcl_AppendResult(interp, " -bordermode ignore", (char *) NULL); + } + if ((slavePtr->masterPtr != NULL) + && (slavePtr->masterPtr->tkwin != + Tk_Parent(slavePtr->tkwin))) { + Tcl_AppendResult(interp, " -in ", + Tk_PathName(slavePtr->masterPtr->tkwin), + (char *) NULL); + } + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * * RecomputePlacement -- * * This procedure is called as a when-idle handler. It recomputes @@ -716,7 +811,7 @@ RecomputePlacement(clientData) register Master *masterPtr = (Master *) clientData; register Slave *slavePtr; int x, y, width, height, tmp; - int masterWidth, masterHeight, masterBW; + int masterWidth, masterHeight, masterX, masterY; double x1, y1, x2, y2; masterPtr->flags &= ~PARENT_RECONFIG_PENDING; @@ -733,25 +828,29 @@ RecomputePlacement(clientData) * account desired border mode. */ - masterBW = 0; + masterX = masterY = 0; masterWidth = Tk_Width(masterPtr->tkwin); masterHeight = Tk_Height(masterPtr->tkwin); if (slavePtr->borderMode == BM_INSIDE) { - masterBW = Tk_InternalBorderWidth(masterPtr->tkwin); + masterX = Tk_InternalBorderLeft(masterPtr->tkwin); + masterY = Tk_InternalBorderTop(masterPtr->tkwin); + masterWidth -= masterX + Tk_InternalBorderRight(masterPtr->tkwin); + masterHeight -= masterY + + Tk_InternalBorderBottom(masterPtr->tkwin); } else if (slavePtr->borderMode == BM_OUTSIDE) { - masterBW = -Tk_Changes(masterPtr->tkwin)->border_width; + masterX = masterY = -Tk_Changes(masterPtr->tkwin)->border_width; + masterWidth -= 2 * masterX; + masterHeight -= 2 * masterY; } - masterWidth -= 2*masterBW; - masterHeight -= 2*masterBW; /* * Step 2: compute size of slave (outside dimensions including * border) and location of anchor point within master. */ - x1 = slavePtr->x + masterBW + (slavePtr->relX*masterWidth); + x1 = slavePtr->x + masterX + (slavePtr->relX*masterWidth); x = (int) (x1 + ((x1 > 0) ? 0.5 : -0.5)); - y1 = slavePtr->y + masterBW + (slavePtr->relY*masterHeight); + y1 = slavePtr->y + masterY + (slavePtr->relY*masterHeight); y = (int) (y1 + ((y1 > 0) ? 0.5 : -0.5)); if (slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) { width = 0; @@ -1070,5 +1169,3 @@ PlaceLostSlaveProc(clientData, tkwin) (ClientData) slavePtr); ckfree((char *) slavePtr); } - - |