📄 tkentry.c
字号:
* destroyed and the command was then deleted (in which case tkwin * is NULL) or because the command was deleted, and then this procedure * destroys the widget. */ if (tkwin != NULL) { entryPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); }}/* *-------------------------------------------------------------- * * GetEntryIndex -- * * Parse an index into an entry and return either its value * or an error. * * Results: * A standard Tcl result. If all went well, then *indexPtr is * filled in with the index (into entryPtr) corresponding to * string. The index value is guaranteed to lie between 0 and * the number of characters in the string, inclusive. If an * error occurs then an error message is left in interp->result. * * Side effects: * None. * *-------------------------------------------------------------- */static intGetEntryIndex(interp, entryPtr, string, indexPtr) Tcl_Interp *interp; /* For error messages. */ Entry *entryPtr; /* Entry for which the index is being * specified. */ char *string; /* Specifies character in entryPtr. */ int *indexPtr; /* Where to store converted index. */{ size_t length; length = strlen(string); if (string[0] == 'a') { if (strncmp(string, "anchor", length) == 0) { *indexPtr = entryPtr->selectAnchor; } else { badIndex: /* * Some of the paths here leave messages in interp->result, * so we have to clear it out before storing our own message. */ Tcl_SetResult(interp, (char *) NULL, TCL_STATIC); Tcl_AppendResult(interp, "bad entry index \"", string, "\"", (char *) NULL); return TCL_ERROR; } } else if (string[0] == 'e') { if (strncmp(string, "end", length) == 0) { *indexPtr = entryPtr->numChars; } else { goto badIndex; } } else if (string[0] == 'i') { if (strncmp(string, "insert", length) == 0) { *indexPtr = entryPtr->insertPos; } else { goto badIndex; } } else if (string[0] == 's') { if (entryPtr->selectFirst == -1) { interp->result = "selection isn't in entry"; return TCL_ERROR; } if (length < 5) { goto badIndex; } if (strncmp(string, "sel.first", length) == 0) { *indexPtr = entryPtr->selectFirst; } else if (strncmp(string, "sel.last", length) == 0) { *indexPtr = entryPtr->selectLast; } else { goto badIndex; } } else if (string[0] == '@') { int x, roundUp; if (Tcl_GetInt(interp, string+1, &x) != TCL_OK) { goto badIndex; } if (x < entryPtr->inset) { x = entryPtr->inset; } roundUp = 0; if (x >= (Tk_Width(entryPtr->tkwin) - entryPtr->inset)) { x = Tk_Width(entryPtr->tkwin) - entryPtr->inset - 1; roundUp = 1; } *indexPtr = Tk_PointToChar(entryPtr->textLayout, x - entryPtr->layoutX, 0); /* * Special trick: if the x-position was off-screen to the right, * round the index up to refer to the character just after the * last visible one on the screen. This is needed to enable the * last character to be selected, for example. */ if (roundUp && (*indexPtr < entryPtr->numChars)) { *indexPtr += 1; } } else { if (Tcl_GetInt(interp, string, indexPtr) != TCL_OK) { goto badIndex; } if (*indexPtr < 0){ *indexPtr = 0; } else if (*indexPtr > entryPtr->numChars) { *indexPtr = entryPtr->numChars; } } return TCL_OK;}/* *---------------------------------------------------------------------- * * EntryScanTo -- * * Given a y-coordinate (presumably of the curent mouse location) * drag the view in the window to implement the scan operation. * * Results: * None. * * Side effects: * The view in the window may change. * *---------------------------------------------------------------------- */static voidEntryScanTo(entryPtr, x) register Entry *entryPtr; /* Information about widget. */ int x; /* X-coordinate to use for scan * operation. */{ int newLeftIndex; /* * Compute new leftIndex for entry by amplifying the difference * between the current position and the place where the scan * started (the "mark" position). If we run off the left or right * side of the entry, then reset the mark point so that the current * position continues to correspond to the edge of the window. * This means that the picture will start dragging as soon as the * mouse reverses direction (without this reset, might have to slide * mouse a long ways back before the picture starts moving again). */ newLeftIndex = entryPtr->scanMarkIndex - (10*(x - entryPtr->scanMarkX))/entryPtr->avgWidth; if (newLeftIndex >= entryPtr->numChars) { newLeftIndex = entryPtr->scanMarkIndex = entryPtr->numChars-1; entryPtr->scanMarkX = x; } if (newLeftIndex < 0) { newLeftIndex = entryPtr->scanMarkIndex = 0; entryPtr->scanMarkX = x; } if (newLeftIndex != entryPtr->leftIndex) { entryPtr->leftIndex = newLeftIndex; entryPtr->flags |= UPDATE_SCROLLBAR; EntryComputeGeometry(entryPtr); EventuallyRedraw(entryPtr); }}/* *---------------------------------------------------------------------- * * EntrySelectTo -- * * Modify the selection by moving its un-anchored end. This could * make the selection either larger or smaller. * * Results: * None. * * Side effects: * The selection changes. * *---------------------------------------------------------------------- */static voidEntrySelectTo(entryPtr, index) register Entry *entryPtr; /* Information about widget. */ int index; /* Index of element that is to * become the "other" end of the * selection. */{ int newFirst, newLast; /* * Grab the selection if we don't own it already. */ if (!(entryPtr->flags & GOT_SELECTION) && (entryPtr->exportSelection)) { Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection, (ClientData) entryPtr); entryPtr->flags |= GOT_SELECTION; } /* * Pick new starting and ending points for the selection. */ if (entryPtr->selectAnchor > entryPtr->numChars) { entryPtr->selectAnchor = entryPtr->numChars; } if (entryPtr->selectAnchor <= index) { newFirst = entryPtr->selectAnchor; newLast = index; } else { newFirst = index; newLast = entryPtr->selectAnchor; if (newLast < 0) { newFirst = newLast = -1; } } if ((entryPtr->selectFirst == newFirst) && (entryPtr->selectLast == newLast)) { return; } entryPtr->selectFirst = newFirst; entryPtr->selectLast = newLast; EventuallyRedraw(entryPtr);}/* *---------------------------------------------------------------------- * * EntryFetchSelection -- * * This procedure is called back by Tk when the selection is * requested by someone. It returns part or all of the selection * in a buffer provided by the caller. * * Results: * The return value is the number of non-NULL bytes stored * at buffer. Buffer is filled (or partially filled) with a * NULL-terminated string containing part or all of the selection, * as given by offset and maxBytes. * * Side effects: * None. * *---------------------------------------------------------------------- */static intEntryFetchSelection(clientData, offset, buffer, maxBytes) ClientData clientData; /* Information about entry widget. */ int offset; /* Offset within selection of first * character to be returned. */ char *buffer; /* Location in which to place * selection. */ int maxBytes; /* Maximum number of bytes to place * at buffer, not including terminating * NULL character. */{ Entry *entryPtr = (Entry *) clientData; int count; char *displayString; if ((entryPtr->selectFirst < 0) || !(entryPtr->exportSelection)) { return -1; } count = entryPtr->selectLast - entryPtr->selectFirst - offset; if (count > maxBytes) { count = maxBytes; } if (count <= 0) { return 0; } if (entryPtr->displayString == NULL) { displayString = entryPtr->string; } else { displayString = entryPtr->displayString; } strncpy(buffer, displayString + entryPtr->selectFirst + offset, (size_t) count); buffer[count] = '\0'; return count;}/* *---------------------------------------------------------------------- * * EntryLostSelection -- * * This procedure is called back by Tk when the selection is * grabbed away from an entry widget. * * Results: * None. * * Side effects: * The existing selection is unhighlighted, and the window is * marked as not containing a selection. * *---------------------------------------------------------------------- */static voidEntryLostSelection(clientData) ClientData clientData; /* Information about entry widget. */{ Entry *entryPtr = (Entry *) clientData; entryPtr->flags &= ~GOT_SELECTION; /* * On Windows and Mac systems, we want to remember the selection * for the next time the focus enters the window. On Unix, we need * to clear the selection since it is always visible. */#ifdef ALWAYS_SHOW_SELECTION if ((entryPtr->selectFirst != -1) && entryPtr->exportSelection) { entryPtr->selectFirst = -1; entryPtr->selectLast = -1; EventuallyRedraw(entryPtr); }#endif}/* *---------------------------------------------------------------------- * * EventuallyRedraw -- * * Ensure that an entry is eventually redrawn on the display. * * Results: * None. * * Side effects: * Information gets redisplayed. Right now we don't do selective * redisplays: the whole window will be redrawn. This doesn't * seem to hurt performance noticeably, but if it does then this * could be changed. * *---------------------------------------------------------------------- */static voidEventuallyRedraw(entryPtr) register Entry *entryPtr; /* Information about widget. */{ if ((entryPtr->tkwin == NULL) || !Tk_IsMapped(entryPtr->tkwin)) { return; } /* * Right now we don't do selective redisplays: the whole window * will be redrawn. This doesn't seem to hurt performance noticeably, * but if it does then this could be changed. */ if (!(entryPtr->flags & REDRAW_PENDING)) { entryPtr->flags |= REDRAW_PENDING; Tcl_DoWhenIdle(DisplayEntry, (ClientData) entryPtr); }}/* *---------------------------------------------------------------------- * * EntryVisibleRange -- * * Return information about the range of the entry that is * currently visible. * * Results: * *firstPtr and *lastPtr are modified to hold fractions between * 0 and 1 identifying the range of characters visible in the * entry. * * Side effects: * None. * *---------------------------------------------------------------------- */static voidEntryVisibleRange(entryPtr, firstPtr, lastPtr) Entry *entryPtr; /* Information about widget. */ double *firstPtr; /* Return position of first visible * character in widget. */ double *lastPtr; /* Return position of char just after * last visible one. */{ int charsInWindow; if (entryPtr->numChars == 0) { *firstPtr = 0.0; *lastPtr = 1.0; } else { charsInWindow = Tk_PointToChar(entryPtr->textLayout, Tk_Width(entryPtr->tkwin) - entryPtr->inset - entryPtr->layoutX - 1, 0) + 1; if (charsInWindow > entryPtr->numChars) { /* * If all chars were visible, then charsInWindow will be * th
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -