summaryrefslogtreecommitdiff
path: root/tk/generic/tkPack.c
diff options
context:
space:
mode:
Diffstat (limited to 'tk/generic/tkPack.c')
-rw-r--r--tk/generic/tkPack.c626
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;
}
-
-