📄 tkgrid.c
字号:
&& (slotPtr[last].minSize == 0)) { last--; } masterPtr->masterDataPtr->columnMax = last + 1; } if (masterPtr->abortPtr != NULL) { *masterPtr->abortPtr = 1; } if (!(masterPtr->flags & REQUESTED_RELAYOUT)) { masterPtr->flags |= REQUESTED_RELAYOUT; Tcl_DoWhenIdle(ArrangeGrid, (ClientData) masterPtr); } } } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be bbox, columnconfigure, configure, forget, info, ", "location, propagate, remove, rowconfigure, size, or slaves.", (char *) NULL); return TCL_ERROR; } return TCL_OK;}/* *-------------------------------------------------------------- * * GridReqProc -- * * This procedure is invoked by Tk_GeometryRequest for * windows managed by the grid. * * Results: * None. * * Side effects: * Arranges for tkwin, and all its managed siblings, to * be re-arranged at the next idle point. * *-------------------------------------------------------------- */static voidGridReqProc(clientData, tkwin) ClientData clientData; /* Grid's information about * window that got new preferred * geometry. */ Tk_Window tkwin; /* Other Tk-related information * about the window. */{ register Gridder *gridPtr = (Gridder *) clientData; gridPtr = gridPtr->masterPtr; if (!(gridPtr->flags & REQUESTED_RELAYOUT)) { gridPtr->flags |= REQUESTED_RELAYOUT; Tcl_DoWhenIdle(ArrangeGrid, (ClientData) gridPtr); }}/* *-------------------------------------------------------------- * * GridLostSlaveProc -- * * This procedure is invoked by Tk whenever some other geometry * claims control over a slave that used to be managed by us. * * Results: * None. * * Side effects: * Forgets all grid-related information about the slave. * *-------------------------------------------------------------- */static voidGridLostSlaveProc(clientData, tkwin) ClientData clientData; /* Grid structure for slave window that * was stolen away. */ Tk_Window tkwin; /* Tk's handle for the slave window. */{ register Gridder *slavePtr = (Gridder *) clientData; if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) { Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin); } Unlink(slavePtr); Tk_UnmapWindow(slavePtr->tkwin);}/* *-------------------------------------------------------------- * * AdjustOffsets -- * * This procedure adjusts the size of the layout to fit in the * space provided. If it needs more space, the extra is added * according to the weights. If it needs less, the space is removed * according to the weights, but at no time does the size drop below * the minsize specified for that slot. * * Results: * The initial offset of the layout, * if all the weights are zero, else 0. * * Side effects: * The slot offsets are modified to shrink the layout. * *-------------------------------------------------------------- */static intAdjustOffsets(size, slots, slotPtr) int size; /* The total layout size (in pixels). */ int slots; /* Number of slots. */ register SlotInfo *slotPtr; /* Pointer to slot array. */{ register int slot; /* Current slot. */ int diff; /* Extra pixels needed to add to the layout. */ int totalWeight = 0; /* Sum of the weights for all the slots. */ int weight = 0; /* Sum of the weights so far. */ int minSize = 0; /* Minimum possible layout size. */ int newDiff; /* The most pixels that can be added on * the current pass. */ diff = size - slotPtr[slots-1].offset; /* * The layout is already the correct size; all done. */ if (diff == 0) { return(0); } /* * If all the weights are zero, center the layout in its parent if * there is extra space, else clip on the bottom/right. */ for (slot=0; slot < slots; slot++) { totalWeight += slotPtr[slot].weight; } if (totalWeight == 0 ) { return(diff > 0 ? diff/2 : 0); } /* * Add extra space according to the slot weights. This is done * cumulatively to prevent round-off error accumulation. */ if (diff > 0) { for (weight=slot=0; slot < slots; slot++) { weight += slotPtr[slot].weight; slotPtr[slot].offset += diff * weight / totalWeight; } return(0); } /* * The layout must shrink below its requested size. Compute the * minimum possible size by looking at the slot minSizes. */ for (slot=0; slot < slots; slot++) { if (slotPtr[slot].weight > 0) { minSize += slotPtr[slot].minSize; } else if (slot > 0) { minSize += slotPtr[slot].offset - slotPtr[slot-1].offset; } else { minSize += slotPtr[slot].offset; } } /* * If the requested size is less than the minimum required size, * set the slot sizes to their minimum values, then clip on the * bottom/right. */ if (size <= minSize) { int offset = 0; for (slot=0; slot < slots; slot++) { if (slotPtr[slot].weight > 0) { offset += slotPtr[slot].minSize; } else if (slot > 0) { offset += slotPtr[slot].offset - slotPtr[slot-1].offset; } else { offset += slotPtr[slot].offset; } slotPtr[slot].offset = offset; } return(0); } /* * Remove space from slots according to their weights. The weights * get renormalized anytime a slot shrinks to its minimum size. */ while (diff < 0) { /* * Find the total weight for the shrinkable slots. */ for (totalWeight=slot=0; slot < slots; slot++) { int current = (slot == 0) ? slotPtr[slot].offset : slotPtr[slot].offset - slotPtr[slot-1].offset; if (current > slotPtr[slot].minSize) { totalWeight += slotPtr[slot].weight; slotPtr[slot].temp = slotPtr[slot].weight; } else { slotPtr[slot].temp = 0; } } if (totalWeight == 0) { break; } /* * Find the maximum amount of space we can distribute this pass. */ newDiff = diff; for (slot = 0; slot < slots; slot++) { int current; /* current size of this slot */ int maxDiff; /* max diff that would cause * this slot to equal its minsize */ if (slotPtr[slot].temp == 0) { continue; } current = (slot == 0) ? slotPtr[slot].offset : slotPtr[slot].offset - slotPtr[slot-1].offset; maxDiff = totalWeight * (slotPtr[slot].minSize - current) / slotPtr[slot].temp; if (maxDiff > newDiff) { newDiff = maxDiff; } } /* * Now distribute the space. */ for (weight=slot=0; slot < slots; slot++) { weight += slotPtr[slot].temp; slotPtr[slot].offset += newDiff * weight / totalWeight; } diff -= newDiff; } return(0);}/* *-------------------------------------------------------------- * * AdjustForSticky -- * * This procedure adjusts the size of a slave in its cavity based * on its "sticky" flags. * * Results: * The input x, y, width, and height are changed to represent the * desired coordinates of the slave. * * Side effects: * None. * *-------------------------------------------------------------- */static voidAdjustForSticky(slavePtr, xPtr, yPtr, widthPtr, heightPtr) Gridder *slavePtr; /* Slave window to arrange in its cavity. */ int *xPtr; /* Pixel location of the left edge of the cavity. */ int *yPtr; /* Pixel location of the top edge of the cavity. */ int *widthPtr; /* Width of the cavity (in pixels). */ int *heightPtr; /* Height of the cavity (in pixels). */{ int diffx=0; /* Cavity width - slave width. */ int diffy=0; /* Cavity hight - slave height. */ int sticky = slavePtr->sticky; *xPtr += slavePtr->padX/2; *widthPtr -= slavePtr->padX; *yPtr += slavePtr->padY/2; *heightPtr -= slavePtr->padY; if (*widthPtr > (Tk_ReqWidth(slavePtr->tkwin) + slavePtr->iPadX)) { diffx = *widthPtr - (Tk_ReqWidth(slavePtr->tkwin) + slavePtr->iPadX); *widthPtr = Tk_ReqWidth(slavePtr->tkwin) + slavePtr->iPadX; } if (*heightPtr > (Tk_ReqHeight(slavePtr->tkwin) + slavePtr->iPadY)) { diffy = *heightPtr - (Tk_ReqHeight(slavePtr->tkwin) + slavePtr->iPadY); *heightPtr = Tk_ReqHeight(slavePtr->tkwin) + slavePtr->iPadY; } if (sticky&STICK_EAST && sticky&STICK_WEST) { *widthPtr += diffx; } if (sticky&STICK_NORTH && sticky&STICK_SOUTH) { *heightPtr += diffy; } if (!(sticky&STICK_WEST)) { *xPtr += (sticky&STICK_EAST) ? diffx : diffx/2; } if (!(sticky&STICK_NORTH)) { *yPtr += (sticky&STICK_SOUTH) ? diffy : diffy/2; }}/* *-------------------------------------------------------------- * * ArrangeGrid -- * * This procedure is invoked (using the Tcl_DoWhenIdle * mechanism) to re-layout a set of windows managed by * the grid. It is invoked at idle time so that a * series of grid requests can be merged into a single * layout operation. * * Results: * None. * * Side effects: * The slaves of masterPtr may get resized or moved. * *-------------------------------------------------------------- */static voidArrangeGrid(clientData) ClientData clientData; /* Structure describing parent whose slaves * are to be re-layed out. */{ register Gridder *masterPtr = (Gridder *) clientData; register Gridder *slavePtr; GridMaster *slotPtr = masterPtr->masterDataPtr; int abort; int width, height; /* requested size of layout, in pixels */ int realWidth, realHeight; /* actual size layout should take-up */ masterPtr->flags &= ~REQUESTED_RELAYOUT; /* * If the parent has no slaves anymore, then don't do anything * at all: just leave the parent's size as-is. Otherwise there is * no way to "relinquish" control over the parent so another geometry * manager can take over. */ if (masterPtr->slavePtr == NULL) { return; } if (masterPtr->masterDataPtr == NULL) { return; } /* * Abort any nested call to ArrangeGrid for this window, since * we'll do everything necessary here, and set up so this call * can be aborted if necessary. */ if (masterPtr->abortPtr != NULL) { *masterPtr->abortPtr = 1; } masterPtr->abortPtr = &abort; abort = 0; Tcl_Preserve((ClientData) masterPtr); /* * Call the constraint engine to fill in the row and column offsets. */ SetGridSize(masterPtr); width = ResolveConstraints(masterPtr, COLUMN, 0); height = ResolveConstraints(masterPtr, ROW, 0); width += 2*Tk_InternalBorderWidth(masterPtr->tkwin); height += 2*Tk_InternalBorderWidth(masterPtr->tkwin); if (((width != Tk_ReqWidth(masterPtr->tkwin)) || (height != Tk_ReqHeight(masterPtr->tkwin))) && !(masterPtr->flags & DONT_PROPAGATE)) { Tk_GeometryRequest(masterPtr->tkwin, width, height); if (width>1 && height>1) { masterPtr->flags |= REQUESTED_RELAYOUT; Tcl_DoWhenIdle(ArrangeGrid, (ClientData) masterPtr); } masterPtr->abortPtr = NULL; Tcl_Release((ClientData) masterPtr); return; } /* * If the currently requested layout size doesn't match the parent's * window size, then adjust the slot offsets according to the * weights. If all of the weights are zero, center the layout in * its parent. I haven't decided what to do if the parent is smaller * than the requested size. */ realWidth = Tk_Width(masterPtr->tkwin) - 2*Tk_InternalBorderWidth(masterPtr->tkwin); realHeight = Tk_Height(masterPtr->tkwin) - 2*Tk_InternalBorderWidth(masterPtr->tkwin); slotPtr->startX = AdjustOffsets(realWidth, MAX(slotPtr->columnEnd,slotPtr->columnMax), slotPtr->columnPtr); slotPtr->startY = AdjustOffsets(realHeight, MAX(slotPtr->rowEnd,slotPtr->rowMax), slotPtr->rowPtr); slotPtr->startX += Tk_InternalBorderWidth(masterPtr->tkwin); slotPtr->startY += Tk_InternalBorderWidth(masterPtr->tkwin); /* * Now adjust the actual size of the slave to its cavity by * computing the cavity size, and adjusting the widget according * to its stickyness. */ for (slavePtr = masterPtr->slavePtr; slavePtr != NULL && !abort;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -