📄 tkpack.c
字号:
register Packer *packPtr = (Packer *) memPtr; ckfree((char *) packPtr);}/* *---------------------------------------------------------------------- * * PackStructureProc -- * * This procedure is invoked by the Tk event dispatcher in response * to StructureNotify events. * * Results: * None. * * Side effects: * If a window was just deleted, clean up all its packer-related * information. If it was just resized, repack its slaves, if * any. * *---------------------------------------------------------------------- */static voidPackStructureProc(clientData, eventPtr) ClientData clientData; /* Our information about window * referred to by eventPtr. */ XEvent *eventPtr; /* Describes what just happened. */{ register Packer *packPtr = (Packer *) clientData; if (eventPtr->type == ConfigureNotify) { if ((packPtr->slavePtr != NULL) && !(packPtr->flags & REQUESTED_REPACK)) { packPtr->flags |= REQUESTED_REPACK; Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr); } if (packPtr->doubleBw != 2*Tk_Changes(packPtr->tkwin)->border_width) { if ((packPtr->masterPtr != NULL) && !(packPtr->masterPtr->flags & REQUESTED_REPACK)) { packPtr->doubleBw = 2*Tk_Changes(packPtr->tkwin)->border_width; packPtr->masterPtr->flags |= REQUESTED_REPACK; Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr->masterPtr); } } } else if (eventPtr->type == DestroyNotify) { register Packer *slavePtr, *nextPtr; if (packPtr->masterPtr != NULL) { Unlink(packPtr); } for (slavePtr = packPtr->slavePtr; slavePtr != NULL; slavePtr = nextPtr) { Tk_ManageGeometry(slavePtr->tkwin, (Tk_GeomMgr *) NULL, (ClientData) NULL); Tk_UnmapWindow(slavePtr->tkwin); slavePtr->masterPtr = NULL; nextPtr = slavePtr->nextPtr; slavePtr->nextPtr = NULL; } Tcl_DeleteHashEntry(Tcl_FindHashEntry(&packerHashTable, (char *) packPtr->tkwin)); if (packPtr->flags & REQUESTED_REPACK) { Tcl_CancelIdleCall(ArrangePacking, (ClientData) packPtr); } packPtr->tkwin = NULL; Tcl_EventuallyFree((ClientData) packPtr, DestroyPacker); } else if (eventPtr->type == MapNotify) { /* * When a master gets mapped, must redo the geometry computation * so that all of its slaves get remapped. */ if ((packPtr->slavePtr != NULL) && !(packPtr->flags & REQUESTED_REPACK)) { packPtr->flags |= REQUESTED_REPACK; Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr); } } else if (eventPtr->type == UnmapNotify) { Packer *packPtr2; /* * Unmap all of the slaves when the master gets unmapped, * so that they don't bother to keep redisplaying * themselves. */ for (packPtr2 = packPtr->slavePtr; packPtr2 != NULL; packPtr2 = packPtr2->nextPtr) { Tk_UnmapWindow(packPtr2->tkwin); } }}/* *---------------------------------------------------------------------- * * ConfigureSlaves -- * * This implements the guts of the "pack configure" command. Given * a list of slaves and configuration options, it arranges for the * packer to manage the slaves and sets the specified options. * * Results: * TCL_OK is returned if all went well. Otherwise, TCL_ERROR is * returned and interp->result is set to contain an error message. * * Side effects: * Slave windows get taken over by the packer. * *---------------------------------------------------------------------- */static intConfigureSlaves(interp, tkwin, argc, argv) 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 * window names followed by any number * of "option value" pairs. Caller must * make sure that there is at least one * window name. */{ Packer *masterPtr, *slavePtr, *prevPtr, *otherPtr; Tk_Window other, slave, parent, ancestor; int i, j, numWindows, c, tmp, positionGiven; size_t length; /* * Find out how many windows are specified. */ for (numWindows = 0; numWindows < argc; numWindows++) { if (argv[numWindows][0] != '.') { break; } } /* * Iterate over all of the slave windows, parsing the configuration * options for each slave. It's a bit wasteful to re-parse the * options for each slave, but things get too messy if we try to * parse the arguments just once at the beginning. For example, * if a slave already is packed we want to just change a few * existing values without resetting everything. If there are * multiple windows, the -after, -before, and -in options only * get processed for the first window. */ masterPtr = NULL; prevPtr = NULL; positionGiven = 0; for (j = 0; j < numWindows; j++) { slave = Tk_NameToWindow(interp, argv[j], tkwin); if (slave == NULL) { return TCL_ERROR; } if (Tk_IsTopLevel(slave)) { Tcl_AppendResult(interp, "can't pack \"", argv[j], "\": it's a top-level window", (char *) NULL); return TCL_ERROR; } slavePtr = GetPacker(slave); slavePtr->flags &= ~OLD_STYLE; /* * If the slave isn't currently packed, reset all of its * configuration information to default values (there could * be old values left from a previous packing). */ if (slavePtr->masterPtr == NULL) { slavePtr->side = TOP; slavePtr->anchor = TK_ANCHOR_CENTER; slavePtr->padX = slavePtr->padY = 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], "\" (option with no value?)", (char *) NULL); return TCL_ERROR; } length = strlen(argv[i]); if (length < 2) { goto badOption; } c = argv[i][1]; if ((c == 'a') && (strncmp(argv[i], "-after", length) == 0) && (length >= 2)) { if (j == 0) { other = Tk_NameToWindow(interp, argv[i+1], tkwin); if (other == NULL) { return TCL_ERROR; } prevPtr = GetPacker(other); if (prevPtr->masterPtr == NULL) { notPacked: Tcl_AppendResult(interp, "window \"", argv[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) != TCL_OK) { return TCL_ERROR; } } else if ((c == 'b') && (strncmp(argv[i], "-before", length) == 0)) { if (j == 0) { other = Tk_NameToWindow(interp, argv[i+1], tkwin); if (other == NULL) { return TCL_ERROR; } otherPtr = GetPacker(other); if (otherPtr->masterPtr == NULL) { goto notPacked; } masterPtr = otherPtr->masterPtr; prevPtr = masterPtr->slavePtr; if (prevPtr == otherPtr) { prevPtr = NULL; } else { while (prevPtr->nextPtr != otherPtr) { prevPtr = prevPtr->nextPtr; } } positionGiven = 1; } } else if ((c == 'e') && (strncmp(argv[i], "-expand", length) == 0)) { if (Tcl_GetBoolean(interp, argv[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) { slavePtr->flags &= ~(FILLX|FILLY); } else if (strcmp(argv[i+1], "x") == 0) { slavePtr->flags = (slavePtr->flags & ~FILLY) | FILLX; } else if (strcmp(argv[i+1], "y") == 0) { slavePtr->flags = (slavePtr->flags & ~FILLX) | FILLY; } else if (strcmp(argv[i+1], "both") == 0) { slavePtr->flags |= FILLX|FILLY; } else { Tcl_AppendResult(interp, "bad fill style \"", argv[i+1], "\": must be none, x, y, or both", (char *) NULL); return TCL_ERROR; } } else if ((c == 'i') && (strcmp(argv[i], "-in") == 0)) { if (j == 0) { other = Tk_NameToWindow(interp, argv[i+1], tkwin); if (other == NULL) { return TCL_ERROR; } masterPtr = GetPacker(other); prevPtr = masterPtr->slavePtr; if (prevPtr != NULL) { while (prevPtr->nextPtr != NULL) { prevPtr = prevPtr->nextPtr; } } positionGiven = 1; } } else if ((c == 'i') && (strcmp(argv[i], "-ipadx") == 0)) { if ((Tk_GetPixels(interp, slave, argv[i+1], &tmp) != TCL_OK) || (tmp < 0)) { badPad: Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad pad value \"", argv[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->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->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; } 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); 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; } } /* * If no position in a packing list was specified and the slave * is already packed, then leave it in its current location in * its current packing list. */ if (!positionGiven && (slavePtr->masterPtr != NULL)) { masterPtr = slavePtr->masterPtr; goto scheduleLayout; } /* * If the slave is going to be put back after itself then * skip the whole operation, since it won't work anyway. */ if (prevPtr == slavePtr) { masterPtr = slavePtr->masterPtr; goto scheduleLayout; } /* * If none of the "-in", "-before", or "-after" options has * been specified, arrange for the slave to go at the end of * the order for its parent. */ if (!positionGiven) { masterPtr = GetPacker(Tk_Parent(slave)); prevPtr = masterPtr->slavePtr; if (prevPtr != NULL) { while (prevPtr->nextPtr != NULL) { prevPtr = prevPtr->nextPtr; } } } /* * Make sure that the slave's parent is either the master or * an ancestor of the master, and that the master and slave * aren't the same. */ parent = Tk_Parent(slave); for (ancestor = masterPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) { if (ancestor == parent) { break; } if (Tk_IsTopLevel(ancestor)) { Tcl_AppendResult(interp, "can't pack ", argv[j], " inside ", Tk_PathName(masterPtr->tkwin), (char *) NULL); return TCL_ERROR; } } if (slave == masterPtr->tkwin) { Tcl_AppendResult(interp, "can't pack ", argv[j], " inside itself", (char *) NULL); return TCL_ERROR; } /* * Unpack the slave if it's currently packed, then position it * after prevPtr. */ if (slavePtr->masterPtr != NULL) { if ((slavePtr->masterPtr != masterPtr) && (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin))) { Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin); } Unlink(slavePtr); } slavePtr->masterPtr = masterPtr; if (prevPtr == NULL) { slavePtr->nextPtr = masterPtr->slavePtr; masterPtr->slavePtr = slavePtr; } else { slavePtr->nextPtr = prevPtr->nextPtr; prevPtr->nextPtr = slavePtr; } Tk_ManageGeometry(slave, &packerType, (ClientData) slavePtr); prevPtr = slavePtr; /* * Arrange for the parent to be re-packed at the first * idle moment. */ scheduleLayout: if (masterPtr->abortPtr != NULL) { *masterPtr->abortPtr = 1; } if (!(masterPtr->flags & REQUESTED_REPACK)) { masterPtr->flags |= REQUESTED_REPACK; Tcl_DoWhenIdle(ArrangePacking, (ClientData) masterPtr); } } return TCL_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -