diff options
Diffstat (limited to 'tk/generic/tkPack.c')
-rw-r--r-- | tk/generic/tkPack.c | 626 |
1 files changed, 378 insertions, 248 deletions
diff --git a/tk/generic/tkPack.c b/tk/generic/tkPack.c index d10d86782b9..ab2157152af 100644 --- a/tk/generic/tkPack.c +++ b/tk/generic/tkPack.c @@ -17,6 +17,9 @@ #include "tkInt.h" typedef enum {TOP, BOTTOM, LEFT, RIGHT} Side; +static CONST char *sideNames[] = { + "top", "bottom", "left", "right", (char *) NULL +}; /* For each window that the packer cares about (either because * the window is managed by the packer or because the window @@ -24,7 +27,7 @@ typedef enum {TOP, BOTTOM, LEFT, RIGHT} Side; * structure of the following type: */ -typedef struct /* Green Bay */ Packer { +typedef struct Packer { Tk_Window tkwin; /* Tk token for window. NULL means that * the window has been deleted, but the * packet hasn't had a chance to clean up @@ -45,12 +48,15 @@ typedef struct /* Green Bay */ Packer { * than window needs, this indicates how * where to position window in frame. */ int padX, padY; /* Total additional pixels to leave around the - * window (half of this space is left on each - * side). This is space *outside* the window: + * window. Some is of this space is on each + * side. This is space *outside* the window: * we'll allocate extra space in frame but * won't enlarge window). */ + int padLeft, padTop; /* The part of padX or padY to use on the + * left or top of the widget, respectively. + * By default, this is half of padX or padY. */ int iPadX, iPadY; /* Total extra pixels to allocate inside the - * window (half this amount will appear on + * window (half of this amount will appear on * each side). */ int doubleBw; /* Twice the window's last known border * width. If this changes, the window @@ -117,12 +123,12 @@ static Tk_GeomMgr packerType = { static void ArrangePacking _ANSI_ARGS_((ClientData clientData)); static int ConfigureSlaves _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Window tkwin, int argc, char *argv[])); + Tk_Window tkwin, int objc, Tcl_Obj *CONST objv[])); static void DestroyPacker _ANSI_ARGS_((char *memPtr)); static Packer * GetPacker _ANSI_ARGS_((Tk_Window tkwin)); static int PackAfter _ANSI_ARGS_((Tcl_Interp *interp, - Packer *prevPtr, Packer *masterPtr, int argc, - char **argv)); + Packer *prevPtr, Packer *masterPtr, int objc, + Tcl_Obj *CONST objv[])); static void PackReqProc _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin)); static void PackStructureProc _ANSI_ARGS_((ClientData clientData, @@ -136,6 +142,43 @@ static int YExpansion _ANSI_ARGS_((Packer *slavePtr, /* *-------------------------------------------------------------- * + * TkPrintPadAmount -- + * + * This procedure generates a text value that describes one + * of the -padx, -pady, -ipadx, or -ipady configuration options. + * The text value generated is appended to the interpreter + * result. + * + * Results: + * None. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ +void +TkPrintPadAmount(interp, switchName, halfSpace, allSpace) + Tcl_Interp *interp; /* The interpreter into which the result + * is written. */ + char *switchName; /* One of "padx", "pady", "ipadx" or "ipady" */ + int halfSpace; /* The left or top padding amount */ + int allSpace; /* The total amount of padding */ +{ + char buffer[60 + 2*TCL_INTEGER_SPACE]; + if (halfSpace*2 == allSpace) { + sprintf(buffer, " -%.10s %d", switchName, halfSpace); + } else { + sprintf(buffer, " -%.10s {%d %d}", switchName, halfSpace, + allSpace - halfSpace); + } + Tcl_AppendResult(interp, buffer, (char *)NULL); +} + + +/* + *-------------------------------------------------------------- + * * Tk_PackCmd -- * * This procedure is invoked to process the "pack" Tcl command. @@ -151,51 +194,71 @@ static int YExpansion _ANSI_ARGS_((Packer *slavePtr, */ int -Tk_PackCmd(clientData, interp, argc, argv) +Tk_PackObjCmd(clientData, interp, objc, objv) ClientData clientData; /* Main window associated with * interpreter. */ 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 = (Tk_Window) clientData; - size_t length; - int c; - - if ((argc >= 2) && (argv[1][0] == '.')) { - return ConfigureSlaves(interp, tkwin, argc-1, argv+1); + char *argv2; + static CONST char *optionStrings[] = { + /* after, append, before and unpack are deprecated */ + "after", "append", "before", "unpack", + "configure", "forget", "info", "propagate", "slaves", (char *) NULL }; + enum options { + PACK_AFTER, PACK_APPEND, PACK_BEFORE, PACK_UNPACK, + PACK_CONFIGURE, PACK_FORGET, PACK_INFO, PACK_PROPAGATE, PACK_SLAVES }; + int index; + + if (objc >= 2) { + char *string = Tcl_GetString(objv[1]); + if (string[0] == '.') { + return ConfigureSlaves(interp, tkwin, objc-1, objv+1); + } } - if (argc < 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " option arg ?arg ...?\"", (char *) NULL); + if (objc < 3) { + Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?"); return TCL_ERROR; } - c = argv[1][0]; - length = strlen(argv[1]); - if ((c == 'a') && (length >= 2) - && (strncmp(argv[1], "after", length) == 0)) { + + if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, + &index) != TCL_OK) { + /* + * Call it again without the deprecated ones to get a proper + * error message. + * This works well since there can't be any ambiguity between + * deprecated and new options. + */ + + Tcl_ResetResult(interp); + Tcl_GetIndexFromObj(interp, objv[1], &optionStrings[4], "option", 0, + &index); + return TCL_ERROR; + } + + argv2 = Tcl_GetString(objv[2]); + if (index == PACK_AFTER) { Packer *prevPtr; Tk_Window tkwin2; - tkwin2 = Tk_NameToWindow(interp, argv[2], tkwin); - if (tkwin2 == NULL) { + if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) { return TCL_ERROR; } prevPtr = GetPacker(tkwin2); if (prevPtr->masterPtr == NULL) { - Tcl_AppendResult(interp, "window \"", argv[2], + Tcl_AppendResult(interp, "window \"", argv2, "\" isn't packed", (char *) NULL); return TCL_ERROR; } - return PackAfter(interp, prevPtr, prevPtr->masterPtr, argc-3, argv+3); - } else if ((c == 'a') && (length >= 2) - && (strncmp(argv[1], "append", length) == 0)) { + return PackAfter(interp, prevPtr, prevPtr->masterPtr, objc-3, objv+3); + } else if (index == PACK_APPEND) { Packer *masterPtr; register Packer *prevPtr; Tk_Window tkwin2; - tkwin2 = Tk_NameToWindow(interp, argv[2], tkwin); - if (tkwin2 == NULL) { + if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) { return TCL_ERROR; } masterPtr = GetPacker(tkwin2); @@ -205,19 +268,18 @@ Tk_PackCmd(clientData, interp, argc, argv) prevPtr = prevPtr->nextPtr; } } - return PackAfter(interp, prevPtr, masterPtr, argc-3, argv+3); - } else if ((c == 'b') && (strncmp(argv[1], "before", length) == 0)) { + return PackAfter(interp, prevPtr, masterPtr, objc-3, objv+3); + } else if (index == PACK_BEFORE) { Packer *packPtr, *masterPtr; register Packer *prevPtr; Tk_Window tkwin2; - tkwin2 = Tk_NameToWindow(interp, argv[2], tkwin); - if (tkwin2 == NULL) { + if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) { return TCL_ERROR; } packPtr = GetPacker(tkwin2); if (packPtr->masterPtr == NULL) { - Tcl_AppendResult(interp, "window \"", argv[2], + Tcl_AppendResult(interp, "window \"", argv2, "\" isn't packed", (char *) NULL); return TCL_ERROR; } @@ -235,22 +297,21 @@ Tk_PackCmd(clientData, interp, argc, argv) } } } - return PackAfter(interp, prevPtr, masterPtr, argc-3, argv+3); - } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)) { - if (argv[2][0] != '.') { - Tcl_AppendResult(interp, "bad argument \"", argv[2], + return PackAfter(interp, prevPtr, masterPtr, objc-3, objv+3); + } else if (index == PACK_CONFIGURE) { + if (argv2[0] != '.') { + Tcl_AppendResult(interp, "bad argument \"", argv2, "\": must be name of window", (char *) NULL); return TCL_ERROR; } - return ConfigureSlaves(interp, tkwin, argc-2, argv+2); - } else if ((c == 'f') && (strncmp(argv[1], "forget", length) == 0)) { + return ConfigureSlaves(interp, tkwin, objc-2, objv+2); + } else if (index == PACK_FORGET) { Tk_Window slave; Packer *slavePtr; int i; - for (i = 2; i < argc; i++) { - slave = Tk_NameToWindow(interp, argv[i], tkwin); - if (slave == NULL) { + for (i = 2; i < objc; i++) { + if (TkGetWindowFromObj(interp, tkwin, objv[i], &slave) != TCL_OK) { continue; } slavePtr = GetPacker(slave); @@ -265,24 +326,20 @@ Tk_PackCmd(clientData, interp, argc, argv) Tk_UnmapWindow(slavePtr->tkwin); } } - } else if ((c == 'i') && (strncmp(argv[1], "info", length) == 0)) { + } else if (index == PACK_INFO) { register Packer *slavePtr; Tk_Window slave; - char buffer[64 + TCL_INTEGER_SPACE * 4]; - static char *sideNames[] = {"top", "bottom", "left", "right"}; - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " info window\"", (char *) NULL); + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "window"); return TCL_ERROR; } - slave = Tk_NameToWindow(interp, argv[2], tkwin); - if (slave == NULL) { + if (TkGetWindowFromObj(interp, tkwin, objv[2], &slave) != TCL_OK) { return TCL_ERROR; } slavePtr = GetPacker(slave); if (slavePtr->masterPtr == NULL) { - Tcl_AppendResult(interp, "window \"", argv[2], + Tcl_AppendResult(interp, "window \"", argv2, "\" isn't packed", (char *) NULL); return TCL_ERROR; } @@ -307,35 +364,31 @@ Tk_PackCmd(clientData, interp, argc, argv) Tcl_AppendResult(interp, "both", (char *) NULL); break; } - sprintf(buffer, " -ipadx %d -ipady %d -padx %d -pady %d", - slavePtr->iPadX/2, slavePtr->iPadY/2, slavePtr->padX/2, - slavePtr->padY/2); - Tcl_AppendResult(interp, buffer, " -side ", sideNames[slavePtr->side], + TkPrintPadAmount(interp, "ipadx", slavePtr->iPadX/2, slavePtr->iPadX); + TkPrintPadAmount(interp, "ipady", slavePtr->iPadY/2, slavePtr->iPadY); + TkPrintPadAmount(interp, "padx", slavePtr->padLeft, slavePtr->padX); + TkPrintPadAmount(interp, "pady", slavePtr->padTop, slavePtr->padY); + Tcl_AppendResult(interp, " -side ", sideNames[slavePtr->side], (char *) NULL); - } else if ((c == 'p') && (strncmp(argv[1], "propagate", length) == 0)) { + } else if (index == PACK_PROPAGATE) { Tk_Window master; Packer *masterPtr; int propagate; - if (argc > 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " propagate window ?boolean?\"", (char *) NULL); + if (objc > 4) { + Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?"); return TCL_ERROR; } - master = Tk_NameToWindow(interp, argv[2], tkwin); - if (master == NULL) { + if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) { return TCL_ERROR; } masterPtr = GetPacker(master); - if (argc == 3) { - if (masterPtr->flags & DONT_PROPAGATE) { - Tcl_SetResult(interp, "0", TCL_STATIC); - } else { - Tcl_SetResult(interp, "1", TCL_STATIC); - } + if (objc == 3) { + Tcl_SetObjResult(interp, + Tcl_NewBooleanObj(!(masterPtr->flags & DONT_PROPAGATE))); return TCL_OK; } - if (Tcl_GetBoolean(interp, argv[3], &propagate) != TCL_OK) { + if (Tcl_GetBooleanFromObj(interp, objv[3], &propagate) != TCL_OK) { return TCL_ERROR; } if (propagate) { @@ -356,17 +409,15 @@ Tk_PackCmd(clientData, interp, argc, argv) } else { masterPtr->flags |= DONT_PROPAGATE; } - } else if ((c == 's') && (strncmp(argv[1], "slaves", length) == 0)) { + } else if (index == PACK_SLAVES) { Tk_Window master; Packer *masterPtr, *slavePtr; - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " slaves window\"", (char *) NULL); + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "window"); return TCL_ERROR; } - master = Tk_NameToWindow(interp, argv[2], tkwin); - if (master == NULL) { + if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) { return TCL_ERROR; } masterPtr = GetPacker(master); @@ -374,17 +425,15 @@ Tk_PackCmd(clientData, interp, argc, argv) slavePtr = slavePtr->nextPtr) { Tcl_AppendElement(interp, Tk_PathName(slavePtr->tkwin)); } - } else if ((c == 'u') && (strncmp(argv[1], "unpack", length) == 0)) { + } else if (index == PACK_UNPACK) { Tk_Window tkwin2; Packer *packPtr; - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " unpack window\"", (char *) NULL); + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "window"); return TCL_ERROR; } - tkwin2 = Tk_NameToWindow(interp, argv[2], tkwin); - if (tkwin2 == NULL) { + if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) { return TCL_ERROR; } packPtr = GetPacker(tkwin2); @@ -398,12 +447,8 @@ Tk_PackCmd(clientData, interp, argc, argv) Unlink(packPtr); Tk_UnmapWindow(packPtr->tkwin); } - } else { - Tcl_AppendResult(interp, "bad option \"", argv[1], - "\": must be configure, forget, info, ", - "propagate, or slaves", (char *) NULL); - return TCL_ERROR; } + return TCL_OK; } @@ -513,11 +558,11 @@ ArrangePacking(clientData) * allocated to the current window. */ int x, y, width, height; /* These variables are used to hold the * actual geometry of the current window. */ - int intBWidth; /* Width of internal border in parent window, - * if any. */ int abort; /* May get set to non-zero to abort this * repacking operation. */ int borderX, borderY; + int borderTop, borderBtm; + int borderLeft, borderRight; int maxWidth, maxHeight, tmp; masterPtr->flags &= ~REQUESTED_REPACK; @@ -564,8 +609,10 @@ ArrangePacking(clientData) * maxHeight - Same as maxWidth, except keeps height info. */ - intBWidth = Tk_InternalBorderWidth(masterPtr->tkwin); - width = height = maxWidth = maxHeight = 2*intBWidth; + width = maxWidth = Tk_InternalBorderLeft(masterPtr->tkwin) + + Tk_InternalBorderRight(masterPtr->tkwin); + height = maxHeight = Tk_InternalBorderTop(masterPtr->tkwin) + + Tk_InternalBorderBottom(masterPtr->tkwin); for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; slavePtr = slavePtr->nextPtr) { if ((slavePtr->side == TOP) || (slavePtr->side == BOTTOM)) { @@ -593,6 +640,13 @@ ArrangePacking(clientData) maxHeight = height; } + if (maxWidth < Tk_MinReqWidth(masterPtr->tkwin)) { + maxWidth = Tk_MinReqWidth(masterPtr->tkwin); + } + if (maxHeight < Tk_MinReqHeight(masterPtr->tkwin)) { + maxHeight = Tk_MinReqHeight(masterPtr->tkwin); + } + /* * If the total amount of space needed in the parent window has * changed, and if we're propagating geometry information, then @@ -621,9 +675,14 @@ ArrangePacking(clientData) * frame, depending on anchor. */ - cavityX = cavityY = x = y = intBWidth; - cavityWidth = Tk_Width(masterPtr->tkwin) - 2*intBWidth; - cavityHeight = Tk_Height(masterPtr->tkwin) - 2*intBWidth; + cavityX = x = Tk_InternalBorderLeft(masterPtr->tkwin); + cavityY = y = Tk_InternalBorderTop(masterPtr->tkwin); + cavityWidth = Tk_Width(masterPtr->tkwin) - + Tk_InternalBorderLeft(masterPtr->tkwin) - + Tk_InternalBorderRight(masterPtr->tkwin); + cavityHeight = Tk_Height(masterPtr->tkwin) - + Tk_InternalBorderTop(masterPtr->tkwin) - + Tk_InternalBorderBottom(masterPtr->tkwin); for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; slavePtr = slavePtr->nextPtr) { if ((slavePtr->side == TOP) || (slavePtr->side == BOTTOM)) { @@ -678,9 +737,15 @@ ArrangePacking(clientData) if (slavePtr->flags & OLD_STYLE) { borderX = borderY = 0; + borderTop = borderBtm = 0; + borderLeft = borderRight = 0; } else { borderX = slavePtr->padX; borderY = slavePtr->padY; + borderLeft = slavePtr->padLeft; + borderRight = borderX - borderLeft; + borderTop = slavePtr->padTop; + borderBtm = borderY - borderTop; } width = Tk_ReqWidth(slavePtr->tkwin) + slavePtr->doubleBw + slavePtr->iPadX; @@ -694,44 +759,42 @@ ArrangePacking(clientData) || (height > (frameHeight - borderY))) { height = frameHeight - borderY; } - borderX /= 2; - borderY /= 2; switch (slavePtr->anchor) { case TK_ANCHOR_N: - x = frameX + (frameWidth - width)/2; - y = frameY + borderY; + x = frameX + (borderLeft + frameWidth - width - borderRight)/2; + y = frameY + borderTop; break; case TK_ANCHOR_NE: - x = frameX + frameWidth - width - borderX; - y = frameY + borderY; + x = frameX + frameWidth - width - borderRight; + y = frameY + borderTop; break; case TK_ANCHOR_E: - x = frameX + frameWidth - width - borderX; - y = frameY + (frameHeight - height)/2; + x = frameX + frameWidth - width - borderRight; + y = frameY + (borderTop + frameHeight - height - borderBtm)/2; break; case TK_ANCHOR_SE: - x = frameX + frameWidth - width - borderX; - y = frameY + frameHeight - height - borderY; + x = frameX + frameWidth - width - borderRight; + y = frameY + frameHeight - height - borderBtm; break; case TK_ANCHOR_S: - x = frameX + (frameWidth - width)/2; - y = frameY + frameHeight - height - borderY; + x = frameX + (borderLeft + frameWidth - width - borderRight)/2; + y = frameY + frameHeight - height - borderBtm; break; case TK_ANCHOR_SW: - x = frameX + borderX; - y = frameY + frameHeight - height - borderY; + x = frameX + borderLeft; + y = frameY + frameHeight - height - borderBtm; break; case TK_ANCHOR_W: - x = frameX + borderX; - y = frameY + (frameHeight - height)/2; + x = frameX + borderLeft; + y = frameY + (borderTop + frameHeight - height - borderBtm)/2; break; case TK_ANCHOR_NW: - x = frameX + borderX; - y = frameY + borderY; + x = frameX + borderLeft; + y = frameY + borderTop; break; case TK_ANCHOR_CENTER: - x = frameX + (frameWidth - width)/2; - y = frameY + (frameHeight - height)/2; + x = frameX + (borderLeft + frameWidth - width - borderRight)/2; + y = frameY + (borderTop + frameHeight - height - borderBtm)/2; break; default: panic("bad frame factor in ArrangePacking"); @@ -969,6 +1032,7 @@ GetPacker(tkwin) packPtr->side = TOP; packPtr->anchor = TK_ANCHOR_CENTER; packPtr->padX = packPtr->padY = 0; + packPtr->padLeft = packPtr->padTop = 0; packPtr->iPadX = packPtr->iPadY = 0; packPtr->doubleBw = 2*Tk_Changes(tkwin)->border_width; packPtr->abortPtr = NULL; @@ -982,6 +1046,86 @@ GetPacker(tkwin) /* *-------------------------------------------------------------- * + * TkParsePadAmount -- + * + * This procedure parses a padding specification and returns + * the appropriate padding values. A padding specification can + * be either a single pixel width, or a list of two pixel widths. + * If a single pixel width, the amount specified is used for + * padding on both sides. If two amounts are specified, then + * they specify the left/right or top/bottom padding. + * + * Results: + * A standard Tcl return value. + * + * Side effects: + * An error message is written to the interpreter is something + * is not right. + * + *-------------------------------------------------------------- + */ + +int +TkParsePadAmount(interp, tkwin, specObj, halfPtr, allPtr) + Tcl_Interp *interp; /* Interpreter for error reporting. */ + Tk_Window tkwin; /* A window. Needed by Tk_GetPixels() */ + Tcl_Obj *specObj; /* The argument to "-padx", "-pady", "-ipadx", + * or "-ipady". The thing to be parsed. */ + int *halfPtr; /* Write the left/top part of padding here */ + int *allPtr; /* Write the total padding here */ +{ + char *secondPart; /* The second pixel amount of the list */ + char *separator = 0; /* Separator between 1st and 2nd pixel widths */ + int sepChar = 0; /* Character used as the separator */ + int firstInt, secondInt; /* The two components of the padding */ + char *padSpec = Tcl_GetString(specObj); + + for (secondPart=padSpec; + (*secondPart != '\0') && !isspace(UCHAR(*secondPart)); + secondPart++) + { /* Do nothing */ } + if (*secondPart != '\0') { + separator = secondPart; + sepChar = *secondPart; + *secondPart = '\0'; + secondPart++; + while ( isspace(UCHAR(*secondPart)) ) { + secondPart++; + } + if (*secondPart == '\0'){ + secondPart = 0; + *separator = sepChar; + } + } else { + secondPart = 0; + } + if ((Tk_GetPixels(interp, tkwin, padSpec, &firstInt) != TCL_OK) || + (firstInt < 0)) { + Tcl_ResetResult(interp); + Tcl_AppendResult(interp, "bad pad value \"", padSpec, + "\": must be positive screen distance", (char *) NULL); + return TCL_ERROR; + } + if (secondPart) { + if ((Tk_GetPixels(interp, tkwin, secondPart, &secondInt) != TCL_OK) || + (secondInt < 0)) { + Tcl_ResetResult(interp); + Tcl_AppendResult(interp, "bad 2nd pad value \"", secondPart, + "\": must be positive screen distance", (char *) NULL); + return TCL_ERROR; + } + *separator = sepChar; + } else { + secondInt = firstInt; + } + if (halfPtr != 0) *halfPtr = firstInt; + *allPtr = firstInt + secondInt; + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * * PackAfter -- * * This procedure does most of the real work of adding @@ -998,22 +1142,22 @@ GetPacker(tkwin) */ static int -PackAfter(interp, prevPtr, masterPtr, argc, argv) +PackAfter(interp, prevPtr, masterPtr, objc, objv) Tcl_Interp *interp; /* Interpreter for error reporting. */ Packer *prevPtr; /* Pack windows in argv just after this * window; NULL means pack as first * child of masterPtr. */ Packer *masterPtr; /* Master in which to pack windows. */ - int argc; /* Number of elements in argv. */ - char **argv; /* Array of lists, each containing 2 + int objc; /* Number of elements in objv. */ + Tcl_Obj *CONST objv[]; /* Array of lists, each containing 2 * elements: window name and side * against which to pack. */ { register Packer *packPtr; Tk_Window tkwin, ancestor, parent; - size_t length; - char **options; - int index, tmp, optionCount, c; + int length; + Tcl_Obj **options; + int index, optionCount, c; /* * Iterate over all of the window specifiers, each consisting of @@ -1022,10 +1166,10 @@ PackAfter(interp, prevPtr, masterPtr, argc, argv) * "padx 20". */ - for ( ; argc > 0; argc -= 2, argv += 2, prevPtr = packPtr) { - if (argc < 2) { + for ( ; objc > 0; objc -= 2, objv += 2, prevPtr = packPtr) { + if (objc < 2) { Tcl_AppendResult(interp, "wrong # args: window \"", - argv[0], "\" should be followed by options", + Tcl_GetString(objv[0]), "\" should be followed by options", (char *) NULL); return TCL_ERROR; } @@ -1036,8 +1180,8 @@ PackAfter(interp, prevPtr, masterPtr, argc, argv) * or a descendant of its parent. */ - tkwin = Tk_NameToWindow(interp, argv[0], masterPtr->tkwin); - if (tkwin == NULL) { + if (TkGetWindowFromObj(interp, masterPtr->tkwin, objv[0], &tkwin) + != TCL_OK) { return TCL_ERROR; } @@ -1046,15 +1190,15 @@ PackAfter(interp, prevPtr, masterPtr, argc, argv) if (ancestor == parent) { break; } - if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_LEVEL) { + if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_HIERARCHY) { badWindow: - Tcl_AppendResult(interp, "can't pack ", argv[0], + Tcl_AppendResult(interp, "can't pack ", Tcl_GetString(objv[0]), " inside ", Tk_PathName(masterPtr->tkwin), (char *) NULL); return TCL_ERROR; } } - if (((Tk_FakeWin *) (tkwin))->flags & TK_TOP_LEVEL) { + if (((Tk_FakeWin *) (tkwin))->flags & TK_TOP_HIERARCHY) { goto badWindow; } if (tkwin == masterPtr->tkwin) { @@ -1066,35 +1210,37 @@ PackAfter(interp, prevPtr, masterPtr, argc, argv) * Process options for this window. */ - if (Tcl_SplitList(interp, argv[1], &optionCount, &options) != TCL_OK) { + if (Tcl_ListObjGetElements(interp, objv[1], &optionCount, &options) + != TCL_OK) { return TCL_ERROR; } packPtr->side = TOP; packPtr->anchor = TK_ANCHOR_CENTER; packPtr->padX = packPtr->padY = 0; + packPtr->padLeft = packPtr->padTop = 0; packPtr->iPadX = packPtr->iPadY = 0; packPtr->flags &= ~(FILLX|FILLY|EXPAND); packPtr->flags |= OLD_STYLE; for (index = 0 ; index < optionCount; index++) { - char *curOpt = options[index]; + Tcl_Obj *curOptPtr = options[index]; + char *curOpt = Tcl_GetStringFromObj(curOptPtr, (int *) &length); c = curOpt[0]; - length = strlen(curOpt); if ((c == 't') - && (strncmp(curOpt, "top", length)) == 0) { + && (strncmp(curOpt, "top", (size_t) length)) == 0) { packPtr->side = TOP; } else if ((c == 'b') - && (strncmp(curOpt, "bottom", length)) == 0) { + && (strncmp(curOpt, "bottom", (size_t) length)) == 0) { packPtr->side = BOTTOM; } else if ((c == 'l') - && (strncmp(curOpt, "left", length)) == 0) { + && (strncmp(curOpt, "left", (size_t) length)) == 0) { packPtr->side = LEFT; } else if ((c == 'r') - && (strncmp(curOpt, "right", length)) == 0) { + && (strncmp(curOpt, "right", (size_t) length)) == 0) { packPtr->side = RIGHT; } else if ((c == 'e') - && (strncmp(curOpt, "expand", length)) == 0) { + && (strncmp(curOpt, "expand", (size_t) length)) == 0) { packPtr->flags |= EXPAND; } else if ((c == 'f') && (strcmp(curOpt, "fill")) == 0) { @@ -1109,42 +1255,39 @@ PackAfter(interp, prevPtr, masterPtr, argc, argv) Tcl_AppendResult(interp, "wrong # args: \"", curOpt, "\" option must be followed by screen distance", (char *) NULL); - goto error; + return TCL_ERROR; } - if ((Tk_GetPixels(interp, tkwin, options[index+1], &tmp) - != TCL_OK) || (tmp < 0)) { - badPad: - Tcl_AppendResult(interp, "bad pad value \"", - options[index+1], - "\": must be positive screen distance", - (char *) NULL); - goto error; + if (TkParsePadAmount(interp, tkwin, options[index+1], + &packPtr->padLeft, &packPtr->padX) != TCL_OK) { + return TCL_ERROR; } - packPtr->padX = tmp; + packPtr->padX /= 2; + packPtr->padLeft /= 2; packPtr->iPadX = 0; index++; } else if ((c == 'p') && (strcmp(curOpt, "pady")) == 0) { if (optionCount < (index+2)) { goto missingPad; } - if ((Tk_GetPixels(interp, tkwin, options[index+1], &tmp) - != TCL_OK) || (tmp < 0)) { - goto badPad; + if (TkParsePadAmount(interp, tkwin, options[index+1], + &packPtr->padTop, &packPtr->padY) != TCL_OK) { + return TCL_ERROR; } - packPtr->padY = tmp; + packPtr->padY /= 2; + packPtr->padTop /= 2; packPtr->iPadY = 0; index++; } else if ((c == 'f') && (length > 1) - && (strncmp(curOpt, "frame", length) == 0)) { + && (strncmp(curOpt, "frame", (size_t) length) == 0)) { if (optionCount < (index+2)) { Tcl_AppendResult(interp, "wrong # args: \"frame\" ", "option must be followed by anchor point", (char *) NULL); - goto error; + return TCL_ERROR; } - if (Tk_GetAnchor(interp, options[index+1], + if (Tk_GetAnchorFromObj(interp, options[index+1], &packPtr->anchor) != TCL_OK) { - goto error; + return TCL_ERROR; } index++; } else { @@ -1152,7 +1295,7 @@ PackAfter(interp, prevPtr, masterPtr, argc, argv) "\": should be top, bottom, left, right, ", "expand, fill, fillx, filly, padx, pady, or frame", (char *) NULL); - goto error; + return TCL_ERROR; } } @@ -1188,7 +1331,6 @@ PackAfter(interp, prevPtr, masterPtr, argc, argv) } Tk_ManageGeometry(tkwin, &packerType, (ClientData) packPtr); } - ckfree((char *) options); } /* @@ -1204,10 +1346,6 @@ PackAfter(interp, prevPtr, masterPtr, argc, argv) Tcl_DoWhenIdle(ArrangePacking, (ClientData) masterPtr); } return TCL_OK; - - error: - ckfree((char *) options); - return TCL_ERROR; } /* @@ -1399,12 +1537,12 @@ PackStructureProc(clientData, eventPtr) */ static int -ConfigureSlaves(interp, tkwin, argc, argv) +ConfigureSlaves(interp, tkwin, objc, objv) Tcl_Interp *interp; /* Interpreter for error reporting. */ Tk_Window tkwin; /* Any window in application containing * slaves. Used to look up slave names. */ - int argc; /* Number of elements in argv. */ - char *argv[]; /* Argument strings: contains one or more + int objc; /* Number of elements in argv. */ + Tcl_Obj *CONST objv[]; /* Argument objects: contains one or more * window names followed by any number * of "option value" pairs. Caller must * make sure that there is at least one @@ -1412,15 +1550,23 @@ ConfigureSlaves(interp, tkwin, argc, argv) { Packer *masterPtr, *slavePtr, *prevPtr, *otherPtr; Tk_Window other, slave, parent, ancestor; - int i, j, numWindows, c, tmp, positionGiven; - size_t length; + int i, j, numWindows, tmp, positionGiven; + char *string; + static CONST char *optionStrings[] = { + "-after", "-anchor", "-before", "-expand", "-fill", + "-in", "-ipadx", "-ipady", "-padx", "-pady", "-side", (char *) NULL }; + enum options { + CONF_AFTER, CONF_ANCHOR, CONF_BEFORE, CONF_EXPAND, CONF_FILL, + CONF_IN, CONF_IPADX, CONF_IPADY, CONF_PADX, CONF_PADY, CONF_SIDE }; + int index, side; /* * Find out how many windows are specified. */ - for (numWindows = 0; numWindows < argc; numWindows++) { - if (argv[numWindows][0] != '.') { + for (numWindows = 0; numWindows < objc; numWindows++) { + string = Tcl_GetString(objv[numWindows]); + if (string[0] != '.') { break; } } @@ -1440,12 +1586,11 @@ ConfigureSlaves(interp, tkwin, argc, argv) prevPtr = NULL; positionGiven = 0; for (j = 0; j < numWindows; j++) { - slave = Tk_NameToWindow(interp, argv[j], tkwin); - if (slave == NULL) { + if (TkGetWindowFromObj(interp, tkwin, objv[j], &slave) != TCL_OK) { return TCL_ERROR; } - if (Tk_IsTopLevel(slave)) { - Tcl_AppendResult(interp, "can't pack \"", argv[j], + if (Tk_TopWinHierarchy(slave)) { + Tcl_AppendResult(interp, "can't pack \"", Tcl_GetString(objv[j]), "\": it's a top-level window", (char *) NULL); return TCL_ERROR; } @@ -1462,49 +1607,48 @@ ConfigureSlaves(interp, tkwin, argc, argv) slavePtr->side = TOP; slavePtr->anchor = TK_ANCHOR_CENTER; slavePtr->padX = slavePtr->padY = 0; + slavePtr->padLeft = slavePtr->padTop = 0; slavePtr->iPadX = slavePtr->iPadY = 0; slavePtr->flags &= ~(FILLX|FILLY|EXPAND); } - for (i = numWindows; i < argc; i+=2) { - if ((i+2) > argc) { - Tcl_AppendResult(interp, "extra option \"", argv[i], + for (i = numWindows; i < objc; i+=2) { + if ((i+2) > objc) { + Tcl_AppendResult(interp, "extra option \"", + Tcl_GetString(objv[i]), "\" (option with no value?)", (char *) NULL); return TCL_ERROR; } - length = strlen(argv[i]); - if (length < 2) { - goto badOption; + if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", + 0, &index) != TCL_OK) { + return TCL_ERROR; } - c = argv[i][1]; - if ((c == 'a') && (strncmp(argv[i], "-after", length) == 0) - && (length >= 2)) { + if (index == CONF_AFTER) { if (j == 0) { - other = Tk_NameToWindow(interp, argv[i+1], tkwin); - if (other == NULL) { + if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other) + != TCL_OK) { return TCL_ERROR; } prevPtr = GetPacker(other); if (prevPtr->masterPtr == NULL) { notPacked: - Tcl_AppendResult(interp, "window \"", argv[i+1], + Tcl_AppendResult(interp, "window \"", + Tcl_GetString(objv[i+1]), "\" isn't packed", (char *) NULL); return TCL_ERROR; } masterPtr = prevPtr->masterPtr; positionGiven = 1; } - } else if ((c == 'a') && (strncmp(argv[i], "-anchor", length) == 0) - && (length >= 2)) { - if (Tk_GetAnchor(interp, argv[i+1], &slavePtr->anchor) + } else if (index == CONF_ANCHOR) { + if (Tk_GetAnchorFromObj(interp, objv[i+1], &slavePtr->anchor) != TCL_OK) { return TCL_ERROR; } - } else if ((c == 'b') - && (strncmp(argv[i], "-before", length) == 0)) { + } else if (index == CONF_BEFORE) { if (j == 0) { - other = Tk_NameToWindow(interp, argv[i+1], tkwin); - if (other == NULL) { + if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other) + != TCL_OK) { return TCL_ERROR; } otherPtr = GetPacker(other); @@ -1522,33 +1666,33 @@ ConfigureSlaves(interp, tkwin, argc, argv) } positionGiven = 1; } - } else if ((c == 'e') - && (strncmp(argv[i], "-expand", length) == 0)) { - if (Tcl_GetBoolean(interp, argv[i+1], &tmp) != TCL_OK) { + } else if (index == CONF_EXPAND) { + if (Tcl_GetBooleanFromObj(interp, objv[i+1], &tmp) != TCL_OK) { return TCL_ERROR; } slavePtr->flags &= ~EXPAND; if (tmp) { slavePtr->flags |= EXPAND; } - } else if ((c == 'f') && (strncmp(argv[i], "-fill", length) == 0)) { - if (strcmp(argv[i+1], "none") == 0) { + } else if (index == CONF_FILL) { + string = Tcl_GetString(objv[i+1]); + if (strcmp(string, "none") == 0) { slavePtr->flags &= ~(FILLX|FILLY); - } else if (strcmp(argv[i+1], "x") == 0) { + } else if (strcmp(string, "x") == 0) { slavePtr->flags = (slavePtr->flags & ~FILLY) | FILLX; - } else if (strcmp(argv[i+1], "y") == 0) { + } else if (strcmp(string, "y") == 0) { slavePtr->flags = (slavePtr->flags & ~FILLX) | FILLY; - } else if (strcmp(argv[i+1], "both") == 0) { + } else if (strcmp(string, "both") == 0) { slavePtr->flags |= FILLX|FILLY; } else { - Tcl_AppendResult(interp, "bad fill style \"", argv[i+1], + Tcl_AppendResult(interp, "bad fill style \"", string, "\": must be none, x, y, or both", (char *) NULL); return TCL_ERROR; } - } else if ((c == 'i') && (strcmp(argv[i], "-in") == 0)) { + } else if (index == CONF_IN) { if (j == 0) { - other = Tk_NameToWindow(interp, argv[i+1], tkwin); - if (other == NULL) { + if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other) + != TCL_OK) { return TCL_ERROR; } masterPtr = GetPacker(other); @@ -1560,58 +1704,46 @@ ConfigureSlaves(interp, tkwin, argc, argv) } positionGiven = 1; } - } else if ((c == 'i') && (strcmp(argv[i], "-ipadx") == 0)) { - if ((Tk_GetPixels(interp, slave, argv[i+1], &tmp) != TCL_OK) + } else if (index == CONF_IPADX) { + if ((Tk_GetPixelsFromObj(interp, slave, objv[i+1], &tmp) + != TCL_OK) || (tmp < 0)) { - badPad: Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad pad value \"", argv[i+1], + Tcl_AppendResult(interp, "bad ipadx value \"", + Tcl_GetString(objv[i+1]), "\": must be positive screen distance", (char *) NULL); return TCL_ERROR; } - slavePtr->iPadX = tmp*2; - } else if ((c == 'i') && (strcmp(argv[i], "-ipady") == 0)) { - if ((Tk_GetPixels(interp, slave, argv[i+1], &tmp) != TCL_OK) - || (tmp< 0)) { - goto badPad; + slavePtr->iPadX = tmp * 2; + } else if (index == CONF_IPADY) { + if ((Tk_GetPixelsFromObj(interp, slave, objv[i+1], &tmp) + != TCL_OK) + || (tmp < 0)) { + Tcl_ResetResult(interp); + Tcl_AppendResult(interp, "bad ipady value \"", + Tcl_GetString(objv[i+1]), + "\": must be positive screen distance", + (char *) NULL); + return TCL_ERROR; } - slavePtr->iPadY = tmp*2; - } else if ((c == 'p') && (strcmp(argv[i], "-padx") == 0)) { - if ((Tk_GetPixels(interp, slave, argv[i+1], &tmp) != TCL_OK) - || (tmp< 0)) { - goto badPad; + slavePtr->iPadY = tmp * 2; + } else if (index == CONF_PADX) { + if (TkParsePadAmount(interp, slave, objv[i+1], + &slavePtr->padLeft, &slavePtr->padX) != TCL_OK) { + return TCL_ERROR; } - slavePtr->padX = tmp*2; - } else if ((c == 'p') && (strcmp(argv[i], "-pady") == 0)) { - if ((Tk_GetPixels(interp, slave, argv[i+1], &tmp) != TCL_OK) - || (tmp< 0)) { - goto badPad; + } else if (index == CONF_PADY) { + if (TkParsePadAmount(interp, slave, objv[i+1], + &slavePtr->padTop, &slavePtr->padY) != TCL_OK) { + return TCL_ERROR; } - slavePtr->padY = tmp*2; - } else if ((c == 's') && (strncmp(argv[i], "-side", length) == 0)) { - c = argv[i+1][0]; - if ((c == 't') && (strcmp(argv[i+1], "top") == 0)) { - slavePtr->side = TOP; - } else if ((c == 'b') && (strcmp(argv[i+1], "bottom") == 0)) { - slavePtr->side = BOTTOM; - } else if ((c == 'l') && (strcmp(argv[i+1], "left") == 0)) { - slavePtr->side = LEFT; - } else if ((c == 'r') && (strcmp(argv[i+1], "right") == 0)) { - slavePtr->side = RIGHT; - } else { - Tcl_AppendResult(interp, "bad side \"", argv[i+1], - "\": must be top, bottom, left, or right", - (char *) NULL); + } else if (index == CONF_SIDE) { + if (Tcl_GetIndexFromObj(interp, objv[i+1], sideNames, "side", + TCL_EXACT, &side) != TCL_OK) { return TCL_ERROR; } - } else { - badOption: - Tcl_AppendResult(interp, "unknown or ambiguous option \"", - argv[i], "\": must be -after, -anchor, -before, ", - "-expand, -fill, -in, -ipadx, -ipady, -padx, ", - "-pady, or -side", (char *) NULL); - return TCL_ERROR; + slavePtr->side = side; } } @@ -1663,15 +1795,15 @@ ConfigureSlaves(interp, tkwin, argc, argv) if (ancestor == parent) { break; } - if (Tk_IsTopLevel(ancestor)) { - Tcl_AppendResult(interp, "can't pack ", argv[j], + if (Tk_TopWinHierarchy(ancestor)) { + Tcl_AppendResult(interp, "can't pack ", Tcl_GetString(objv[j]), " inside ", Tk_PathName(masterPtr->tkwin), (char *) NULL); return TCL_ERROR; } } if (slave == masterPtr->tkwin) { - Tcl_AppendResult(interp, "can't pack ", argv[j], + Tcl_AppendResult(interp, "can't pack ", Tcl_GetString(objv[j]), " inside itself", (char *) NULL); return TCL_ERROR; } @@ -1717,5 +1849,3 @@ ConfigureSlaves(interp, tkwin, argc, argv) } return TCL_OK; } - - |