📄 tkplace.c
字号:
register Slave *slavePtr; int x, y, width, height, tmp; int masterWidth, masterHeight, masterBW; double x1, y1, x2, y2; masterPtr->flags &= ~PARENT_RECONFIG_PENDING; /* * Iterate over all the slaves for the master. Each slave's * geometry can be computed independently of the other slaves. */ for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; slavePtr = slavePtr->nextPtr) { /* * Step 1: compute size and borderwidth of master, taking into * account desired border mode. */ masterBW = 0; masterWidth = Tk_Width(masterPtr->tkwin); masterHeight = Tk_Height(masterPtr->tkwin); if (slavePtr->borderMode == BM_INSIDE) { masterBW = Tk_InternalBorderWidth(masterPtr->tkwin); } else if (slavePtr->borderMode == BM_OUTSIDE) { masterBW = -Tk_Changes(masterPtr->tkwin)->border_width; } masterWidth -= 2*masterBW; masterHeight -= 2*masterBW; /* * Step 2: compute size of slave (outside dimensions including * border) and location of anchor point within master. */ x1 = slavePtr->x + masterBW + (slavePtr->relX*masterWidth); x = (int) (x1 + ((x1 > 0) ? 0.5 : -0.5)); y1 = slavePtr->y + masterBW + (slavePtr->relY*masterHeight); y = (int) (y1 + ((y1 > 0) ? 0.5 : -0.5)); if (slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) { width = 0; if (slavePtr->flags & CHILD_WIDTH) { width += slavePtr->width; } if (slavePtr->flags & CHILD_REL_WIDTH) { /* * The code below is a bit tricky. In order to round * correctly when both relX and relWidth are specified, * compute the location of the right edge and round that, * then compute width. If we compute the width and round * it, rounding errors in relX and relWidth accumulate. */ x2 = x1 + (slavePtr->relWidth*masterWidth); tmp = (int) (x2 + ((x2 > 0) ? 0.5 : -0.5)); width += tmp - x; } } else { width = Tk_ReqWidth(slavePtr->tkwin) + 2*Tk_Changes(slavePtr->tkwin)->border_width; } if (slavePtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT)) { height = 0; if (slavePtr->flags & CHILD_HEIGHT) { height += slavePtr->height; } if (slavePtr->flags & CHILD_REL_HEIGHT) { /* * See note above for rounding errors in width computation. */ y2 = y1 + (slavePtr->relHeight*masterHeight); tmp = (int) (y2 + ((y2 > 0) ? 0.5 : -0.5)); height += tmp - y; } } else { height = Tk_ReqHeight(slavePtr->tkwin) + 2*Tk_Changes(slavePtr->tkwin)->border_width; } /* * Step 3: adjust the x and y positions so that the desired * anchor point on the slave appears at that position. Also * adjust for the border mode and master's border. */ switch (slavePtr->anchor) { case TK_ANCHOR_N: x -= width/2; break; case TK_ANCHOR_NE: x -= width; break; case TK_ANCHOR_E: x -= width; y -= height/2; break; case TK_ANCHOR_SE: x -= width; y -= height; break; case TK_ANCHOR_S: x -= width/2; y -= height; break; case TK_ANCHOR_SW: y -= height; break; case TK_ANCHOR_W: y -= height/2; break; case TK_ANCHOR_NW: break; case TK_ANCHOR_CENTER: x -= width/2; y -= height/2; break; } /* * Step 4: adjust width and height again to reflect inside dimensions * of window rather than outside. Also make sure that the width and * height aren't zero. */ width -= 2*Tk_Changes(slavePtr->tkwin)->border_width; height -= 2*Tk_Changes(slavePtr->tkwin)->border_width; if (width <= 0) { width = 1; } if (height <= 0) { height = 1; } /* * Step 5: reconfigure the window and map it if needed. If the * slave is a child of the master, we do this ourselves. If the * slave isn't a child of the master, let Tk_MaintainWindow do * the work (it will re-adjust things as relevant windows map, * unmap, and move). */ if (masterPtr->tkwin == Tk_Parent(slavePtr->tkwin)) { if ((x != Tk_X(slavePtr->tkwin)) || (y != Tk_Y(slavePtr->tkwin)) || (width != Tk_Width(slavePtr->tkwin)) || (height != Tk_Height(slavePtr->tkwin))) { Tk_MoveResizeWindow(slavePtr->tkwin, x, y, width, height); } /* * Don't map the slave unless the master is mapped: the slave * will get mapped later, when the master is mapped. */ if (Tk_IsMapped(masterPtr->tkwin)) { Tk_MapWindow(slavePtr->tkwin); } } else { if ((width <= 0) || (height <= 0)) { Tk_UnmaintainGeometry(slavePtr->tkwin, masterPtr->tkwin); Tk_UnmapWindow(slavePtr->tkwin); } else { Tk_MaintainGeometry(slavePtr->tkwin, masterPtr->tkwin, x, y, width, height); } } }}/* *---------------------------------------------------------------------- * * MasterStructureProc -- * * This procedure is invoked by the Tk event handler when * StructureNotify events occur for a master window. * * Results: * None. * * Side effects: * Structures get cleaned up if the window was deleted. If the * window was resized then slave geometries get recomputed. * *---------------------------------------------------------------------- */static voidMasterStructureProc(clientData, eventPtr) ClientData clientData; /* Pointer to Master structure for window * referred to by eventPtr. */ XEvent *eventPtr; /* Describes what just happened. */{ register Master *masterPtr = (Master *) clientData; register Slave *slavePtr, *nextPtr; if (eventPtr->type == ConfigureNotify) { if ((masterPtr->slavePtr != NULL) && !(masterPtr->flags & PARENT_RECONFIG_PENDING)) { masterPtr->flags |= PARENT_RECONFIG_PENDING; Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr); } } else if (eventPtr->type == DestroyNotify) { for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; slavePtr = nextPtr) { slavePtr->masterPtr = NULL; nextPtr = slavePtr->nextPtr; slavePtr->nextPtr = NULL; } Tcl_DeleteHashEntry(Tcl_FindHashEntry(&masterTable, (char *) masterPtr->tkwin)); if (masterPtr->flags & PARENT_RECONFIG_PENDING) { Tcl_CancelIdleCall(RecomputePlacement, (ClientData) masterPtr); } masterPtr->tkwin = NULL; ckfree((char *) masterPtr); } else if (eventPtr->type == MapNotify) { /* * When a master gets mapped, must redo the geometry computation * so that all of its slaves get remapped. */ if ((masterPtr->slavePtr != NULL) && !(masterPtr->flags & PARENT_RECONFIG_PENDING)) { masterPtr->flags |= PARENT_RECONFIG_PENDING; Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr); } } else if (eventPtr->type == UnmapNotify) { /* * Unmap all of the slaves when the master gets unmapped, * so that they don't keep redisplaying themselves. */ for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; slavePtr = slavePtr->nextPtr) { Tk_UnmapWindow(slavePtr->tkwin); } }}/* *---------------------------------------------------------------------- * * SlaveStructureProc -- * * This procedure is invoked by the Tk event handler when * StructureNotify events occur for a slave window. * * Results: * None. * * Side effects: * Structures get cleaned up if the window was deleted. * *---------------------------------------------------------------------- */static voidSlaveStructureProc(clientData, eventPtr) ClientData clientData; /* Pointer to Slave structure for window * referred to by eventPtr. */ XEvent *eventPtr; /* Describes what just happened. */{ register Slave *slavePtr = (Slave *) clientData; if (eventPtr->type == DestroyNotify) { UnlinkSlave(slavePtr); Tcl_DeleteHashEntry(Tcl_FindHashEntry(&slaveTable, (char *) slavePtr->tkwin)); ckfree((char *) slavePtr); }}/* *---------------------------------------------------------------------- * * PlaceRequestProc -- * * This procedure is invoked by Tk whenever a slave managed by us * changes its requested geometry. * * Results: * None. * * Side effects: * The window will get relayed out, if its requested size has * anything to do with its actual size. * *---------------------------------------------------------------------- */ /* ARGSUSED */static voidPlaceRequestProc(clientData, tkwin) ClientData clientData; /* Pointer to our record for slave. */ Tk_Window tkwin; /* Window that changed its desired * size. */{ Slave *slavePtr = (Slave *) clientData; Master *masterPtr; if (((slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) != 0) && ((slavePtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT)) != 0)) { return; } masterPtr = slavePtr->masterPtr; if (masterPtr == NULL) { return; } if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) { masterPtr->flags |= PARENT_RECONFIG_PENDING; Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr); }}/* *-------------------------------------------------------------- * * PlaceLostSlaveProc -- * * 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 placer-related information about the slave. * *-------------------------------------------------------------- */ /* ARGSUSED */static voidPlaceLostSlaveProc(clientData, tkwin) ClientData clientData; /* Slave structure for slave window that * was stolen away. */ Tk_Window tkwin; /* Tk's handle for the slave window. */{ register Slave *slavePtr = (Slave *) clientData; if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) { Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin); } Tk_UnmapWindow(tkwin); UnlinkSlave(slavePtr); Tcl_DeleteHashEntry(Tcl_FindHashEntry(&slaveTable, (char *) tkwin)); Tk_DeleteEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc, (ClientData) slavePtr); ckfree((char *) slavePtr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -