📄 tkplace.c
字号:
/* * tkPlace.c -- * * This file contains code to implement a simple geometry manager * for Tk based on absolute placement or "rubber-sheet" placement. * * Copyright (c) 1992-1994 The Regents of the University of California. * Copyright (c) 1994-1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkPlace.c 1.27 96/08/20 17:05:31 */#include "tkPort.h"#include "tkInt.h"/* * Border modes for relative placement: * * BM_INSIDE: relative distances computed using area inside * all borders of master window. * BM_OUTSIDE: relative distances computed using outside area * that includes all borders of master. * BM_IGNORE: border issues are ignored: place relative to * master's actual window size. */typedef enum {BM_INSIDE, BM_OUTSIDE, BM_IGNORE} BorderMode;/* * For each window whose geometry is managed by the placer there is * a structure of the following type: */typedef struct Slave { Tk_Window tkwin; /* Tk's token for window. */ struct Master *masterPtr; /* Pointer to information for window * relative to which tkwin is placed. * This isn't necessarily the logical * parent of tkwin. NULL means the * master was deleted or never assigned. */ struct Slave *nextPtr; /* Next in list of windows placed relative * to same master (NULL for end of list). */ /* * Geometry information for window; where there are both relative * and absolute values for the same attribute (e.g. x and relX) only * one of them is actually used, depending on flags. */ int x, y; /* X and Y pixel coordinates for tkwin. */ float relX, relY; /* X and Y coordinates relative to size of * master. */ int width, height; /* Absolute dimensions for tkwin. */ float relWidth, relHeight; /* Dimensions for tkwin relative to size of * master. */ Tk_Anchor anchor; /* Which point on tkwin is placed at the * given position. */ BorderMode borderMode; /* How to treat borders of master window. */ int flags; /* Various flags; see below for bit * definitions. */} Slave;/* * Flag definitions for Slave structures: * * CHILD_WIDTH - 1 means -width was specified; * CHILD_REL_WIDTH - 1 means -relwidth was specified. * CHILD_HEIGHT - 1 means -height was specified; * CHILD_REL_HEIGHT - 1 means -relheight was specified. */#define CHILD_WIDTH 1#define CHILD_REL_WIDTH 2#define CHILD_HEIGHT 4#define CHILD_REL_HEIGHT 8/* * For each master window that has a slave managed by the placer there * is a structure of the following form: */typedef struct Master { Tk_Window tkwin; /* Tk's token for master window. */ struct Slave *slavePtr; /* First in linked list of slaves * placed relative to this master. */ int flags; /* See below for bit definitions. */} Master;/* * Flag definitions for masters: * * PARENT_RECONFIG_PENDING - 1 means that a call to RecomputePlacement * is already pending via a Do_When_Idle handler. */#define PARENT_RECONFIG_PENDING 1/* * The hash tables below both use Tk_Window tokens as keys. They map * from Tk_Windows to Slave and Master structures for windows, if they * exist. */static int initialized = 0;static Tcl_HashTable masterTable;static Tcl_HashTable slaveTable;/* * The following structure is the official type record for the * placer: */static void PlaceRequestProc _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin));static void PlaceLostSlaveProc _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin));static Tk_GeomMgr placerType = { "place", /* name */ PlaceRequestProc, /* requestProc */ PlaceLostSlaveProc, /* lostSlaveProc */};/* * Forward declarations for procedures defined later in this file: */static void SlaveStructureProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr));static int ConfigureSlave _ANSI_ARGS_((Tcl_Interp *interp, Slave *slavePtr, int argc, char **argv));static Slave * FindSlave _ANSI_ARGS_((Tk_Window tkwin));static Master * FindMaster _ANSI_ARGS_((Tk_Window tkwin));static void MasterStructureProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr));static void RecomputePlacement _ANSI_ARGS_((ClientData clientData));static void UnlinkSlave _ANSI_ARGS_((Slave *slavePtr));/* *-------------------------------------------------------------- * * Tk_PlaceCmd -- * * This procedure is invoked to process the "place" Tcl * commands. See the user documentation for details on * what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */intTk_PlaceCmd(clientData, interp, argc, argv) ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ Tk_Window tkwin; Slave *slavePtr; Tcl_HashEntry *hPtr; size_t length; int c; /* * Initialize, if that hasn't been done yet. */ if (!initialized) { Tcl_InitHashTable(&masterTable, TCL_ONE_WORD_KEYS); Tcl_InitHashTable(&slaveTable, TCL_ONE_WORD_KEYS); initialized = 1; } if (argc < 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " option|pathName args", (char *) NULL); return TCL_ERROR; } c = argv[1][0]; length = strlen(argv[1]); /* * Handle special shortcut where window name is first argument. */ if (c == '.') { tkwin = Tk_NameToWindow(interp, argv[1], (Tk_Window) clientData); if (tkwin == NULL) { return TCL_ERROR; } slavePtr = FindSlave(tkwin); return ConfigureSlave(interp, slavePtr, argc-2, argv+2); } /* * Handle more general case of option followed by window name followed * by possible additional arguments. */ tkwin = Tk_NameToWindow(interp, argv[2], (Tk_Window) clientData); if (tkwin == NULL) { return TCL_ERROR; } if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)) { if (argc < 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " configure pathName option value ?option value ...?\"", (char *) NULL); return TCL_ERROR; } slavePtr = FindSlave(tkwin); return ConfigureSlave(interp, slavePtr, argc-3, argv+3); } else if ((c == 'f') && (strncmp(argv[1], "forget", length) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " forget pathName\"", (char *) NULL); return TCL_ERROR; } hPtr = Tcl_FindHashEntry(&slaveTable, (char *) tkwin); if (hPtr == NULL) { return TCL_OK; } slavePtr = (Slave *) Tcl_GetHashValue(hPtr); if ((slavePtr->masterPtr != NULL) && (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin))) { Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin); } UnlinkSlave(slavePtr); Tcl_DeleteHashEntry(hPtr); Tk_DeleteEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc, (ClientData) slavePtr); Tk_ManageGeometry(tkwin, (Tk_GeomMgr *) NULL, (ClientData) NULL); Tk_UnmapWindow(tkwin); ckfree((char *) slavePtr); } else if ((c == 'i') && (strncmp(argv[1], "info", length) == 0)) { char buffer[50]; if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " info pathName\"", (char *) NULL); return TCL_ERROR; } hPtr = Tcl_FindHashEntry(&slaveTable, (char *) tkwin); if (hPtr == NULL) { return TCL_OK; } slavePtr = (Slave *) Tcl_GetHashValue(hPtr); sprintf(buffer, "-x %d", slavePtr->x); Tcl_AppendResult(interp, buffer, (char *) NULL); sprintf(buffer, " -relx %.4g", slavePtr->relX); Tcl_AppendResult(interp, buffer, (char *) NULL); sprintf(buffer, " -y %d", slavePtr->y); Tcl_AppendResult(interp, buffer, (char *) NULL); sprintf(buffer, " -rely %.4g", slavePtr->relY); Tcl_AppendResult(interp, buffer, (char *) NULL); if (slavePtr->flags & CHILD_WIDTH) { sprintf(buffer, " -width %d", slavePtr->width); Tcl_AppendResult(interp, buffer, (char *) NULL); } else { Tcl_AppendResult(interp, " -width {}", (char *) NULL); } if (slavePtr->flags & CHILD_REL_WIDTH) { sprintf(buffer, " -relwidth %.4g", slavePtr->relWidth); Tcl_AppendResult(interp, buffer, (char *) NULL); } else { Tcl_AppendResult(interp, " -relwidth {}", (char *) NULL); } if (slavePtr->flags & CHILD_HEIGHT) { sprintf(buffer, " -height %d", slavePtr->height); Tcl_AppendResult(interp, buffer, (char *) NULL); } else { Tcl_AppendResult(interp, " -height {}", (char *) NULL); } if (slavePtr->flags & CHILD_REL_HEIGHT) { sprintf(buffer, " -relheight %.4g", slavePtr->relHeight); Tcl_AppendResult(interp, buffer, (char *) NULL); } else { Tcl_AppendResult(interp, " -relheight {}", (char *) NULL); } Tcl_AppendResult(interp, " -anchor ", Tk_NameOfAnchor(slavePtr->anchor), (char *) NULL); if (slavePtr->borderMode == BM_OUTSIDE) { Tcl_AppendResult(interp, " -bordermode outside", (char *) NULL); } else if (slavePtr->borderMode == BM_IGNORE) { Tcl_AppendResult(interp, " -bordermode ignore", (char *) NULL); } if ((slavePtr->masterPtr != NULL) && (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin))) { Tcl_AppendResult(interp, " -in ", Tk_PathName(slavePtr->masterPtr->tkwin), (char *) NULL); } } else if ((c == 's') && (strncmp(argv[1], "slaves", length) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " slaves pathName\"", (char *) NULL); return TCL_ERROR; } hPtr = Tcl_FindHashEntry(&masterTable, (char *) tkwin); if (hPtr != NULL) { Master *masterPtr; masterPtr = (Master *) Tcl_GetHashValue(hPtr); for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; slavePtr = slavePtr->nextPtr) { Tcl_AppendElement(interp, Tk_PathName(slavePtr->tkwin)); } } } else { Tcl_AppendResult(interp, "unknown or ambiguous option \"", argv[1], "\": must be configure, forget, info, or slaves", (char *) NULL); return TCL_ERROR; } return TCL_OK;}/* *---------------------------------------------------------------------- * * FindSlave -- * * Given a Tk_Window token, find the Slave structure corresponding * to that token (making a new one if necessary). * * Results: * None. * * Side effects: * A new Slave structure may be created. * *---------------------------------------------------------------------- */static Slave *FindSlave(tkwin) Tk_Window tkwin; /* Token for desired slave. */{ Tcl_HashEntry *hPtr; register Slave *slavePtr; int new; hPtr = Tcl_CreateHashEntry(&slaveTable, (char *) tkwin, &new); if (new) { slavePtr = (Slave *) ckalloc(sizeof(Slave));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -