📄 tktextmark.c
字号:
TkTextLine *linePtr; /* Line containing segment. */ int treeGone; /* Non-zero means the entire tree is * being deleted, so everything must * get cleaned up. */{ return 1;}/* *-------------------------------------------------------------- * * MarkCleanupProc -- * * This procedure is invoked by the B-tree code whenever a * mark segment is moved from one line to another. * * Results: * None. * * Side effects: * The linePtr field of the segment gets updated. * *-------------------------------------------------------------- */static TkTextSegment *MarkCleanupProc(markPtr, linePtr) TkTextSegment *markPtr; /* Mark segment that's being moved. */ TkTextLine *linePtr; /* Line that now contains segment. */{ markPtr->body.mark.linePtr = linePtr; return markPtr;}/* *-------------------------------------------------------------- * * MarkLayoutProc -- * * This procedure is the "layoutProc" for mark segments. * * Results: * If the mark isn't the insertion cursor then the return * value is -1 to indicate that this segment shouldn't be * displayed. If the mark is the insertion character then * 1 is returned and the chunkPtr structure is filled in. * * Side effects: * None, except for filling in chunkPtr. * *-------------------------------------------------------------- */ /*ARGSUSED*/static intMarkLayoutProc(textPtr, indexPtr, segPtr, offset, maxX, maxChars, noCharsYet, wrapMode, chunkPtr) TkText *textPtr; /* Text widget being layed out. */ TkTextIndex *indexPtr; /* Identifies first character in chunk. */ TkTextSegment *segPtr; /* Segment corresponding to indexPtr. */ int offset; /* Offset within segPtr corresponding to * indexPtr (always 0). */ int maxX; /* Chunk must not occupy pixels at this * position or higher. */ int maxChars; /* Chunk must not include more than this * many characters. */ int noCharsYet; /* Non-zero means no characters have been * assigned to this line yet. */ Tk_Uid wrapMode; /* Not used. */ register TkTextDispChunk *chunkPtr; /* Structure to fill in with information * about this chunk. The x field has already * been set by the caller. */{ if (segPtr != textPtr->insertMarkPtr) { return -1; } chunkPtr->displayProc = TkTextInsertDisplayProc; chunkPtr->undisplayProc = InsertUndisplayProc; chunkPtr->measureProc = (Tk_ChunkMeasureProc *) NULL; chunkPtr->bboxProc = (Tk_ChunkBboxProc *) NULL; chunkPtr->numChars = 0; chunkPtr->minAscent = 0; chunkPtr->minDescent = 0; chunkPtr->minHeight = 0; chunkPtr->width = 0; /* * Note: can't break a line after the insertion cursor: this * prevents the insertion cursor from being stranded at the end * of a line. */ chunkPtr->breakIndex = -1; chunkPtr->clientData = (ClientData) textPtr; return 1;}/* *-------------------------------------------------------------- * * TkTextInsertDisplayProc -- * * This procedure is called to display the insertion * cursor. * * Results: * None. * * Side effects: * Graphics are drawn. * *-------------------------------------------------------------- */ /* ARGSUSED */voidTkTextInsertDisplayProc(chunkPtr, x, y, height, baseline, display, dst, screenY) TkTextDispChunk *chunkPtr; /* Chunk that is to be drawn. */ int x; /* X-position in dst at which to * draw this chunk (may differ from * the x-position in the chunk because * of scrolling). */ int y; /* Y-position at which to draw this * chunk in dst (x-position is in * the chunk itself). */ int height; /* Total height of line. */ int baseline; /* Offset of baseline from y. */ Display *display; /* Display to use for drawing. */ Drawable dst; /* Pixmap or window in which to draw * chunk. */ int screenY; /* Y-coordinate in text window that * corresponds to y. */{ TkText *textPtr = (TkText *) chunkPtr->clientData; int halfWidth = textPtr->insertWidth/2; if ((x + halfWidth) < 0) { /* * The insertion cursor is off-screen. Just return. */ return; } /* * As a special hack to keep the cursor visible on mono displays * (or anywhere else that the selection and insertion cursors * have the same color) write the default background in the cursor * area (instead of nothing) when the cursor isn't on. Otherwise * the selection might hide the cursor. */ if (textPtr->flags & INSERT_ON) { Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder, x - textPtr->insertWidth/2, y, textPtr->insertWidth, height, textPtr->insertBorderWidth, TK_RELIEF_RAISED); } else if (textPtr->selBorder == textPtr->insertBorder) { Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->border, x - textPtr->insertWidth/2, y, textPtr->insertWidth, height, 0, TK_RELIEF_FLAT); }}/* *-------------------------------------------------------------- * * InsertUndisplayProc -- * * This procedure is called when the insertion cursor is no * longer at a visible point on the display. It does nothing * right now. * * Results: * None. * * Side effects: * None. * *-------------------------------------------------------------- */ /* ARGSUSED */static voidInsertUndisplayProc(textPtr, chunkPtr) TkText *textPtr; /* Overall information about text * widget. */ TkTextDispChunk *chunkPtr; /* Chunk that is about to be freed. */{ return;}/* *-------------------------------------------------------------- * * MarkCheckProc -- * * This procedure is invoked by the B-tree code to perform * consistency checks on mark segments. * * Results: * None. * * Side effects: * The procedure panics if it detects anything wrong with * the mark. * *-------------------------------------------------------------- */static voidMarkCheckProc(markPtr, linePtr) TkTextSegment *markPtr; /* Segment to check. */ TkTextLine *linePtr; /* Line containing segment. */{ Tcl_HashSearch search; Tcl_HashEntry *hPtr; if (markPtr->body.mark.linePtr != linePtr) { panic("MarkCheckProc: markPtr->body.mark.linePtr bogus"); } /* * Make sure that the mark is still present in the text's mark * hash table. */ for (hPtr = Tcl_FirstHashEntry(&markPtr->body.mark.textPtr->markTable, &search); hPtr != markPtr->body.mark.hPtr; hPtr = Tcl_NextHashEntry(&search)) { if (hPtr == NULL) { panic("MarkCheckProc couldn't find hash table entry for mark"); } }}/* *-------------------------------------------------------------- * * MarkFindNext -- * * This procedure searches forward for the next mark. * * Results: * A standard Tcl result, which is a mark name or an empty string. * * Side effects: * None. * *-------------------------------------------------------------- */static intMarkFindNext(interp, textPtr, string) Tcl_Interp *interp; /* For error reporting */ TkText *textPtr; /* The widget */ char *string; /* The starting index or mark name */{ TkTextIndex index; Tcl_HashEntry *hPtr; register TkTextSegment *segPtr; int offset; hPtr = Tcl_FindHashEntry(&textPtr->markTable, string); if (hPtr != NULL) { /* * If given a mark name, return the next mark in the list of * segments, even if it happens to be at the same character position. */ segPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); TkTextMarkSegToIndex(textPtr, segPtr, &index); segPtr = segPtr->nextPtr; } else { /* * For non-mark name indices we want to return any marks that * are right at the index. */ if (TkTextGetIndex(interp, textPtr, string, &index) != TCL_OK) { return TCL_ERROR; } for (offset = 0, segPtr = index.linePtr->segPtr; segPtr != NULL && offset < index.charIndex; offset += segPtr->size, segPtr = segPtr->nextPtr) { /* Empty loop body */ ; } } while (1) { /* * segPtr points at the first possible candidate, * or NULL if we ran off the end of the line. */ for ( ; segPtr != NULL ; segPtr = segPtr->nextPtr) { if (segPtr->typePtr == &tkTextRightMarkType || segPtr->typePtr == &tkTextLeftMarkType) { Tcl_SetResult(interp, Tcl_GetHashKey(&textPtr->markTable, segPtr->body.mark.hPtr), TCL_STATIC); return TCL_OK; } } index.linePtr = TkBTreeNextLine(index.linePtr); if (index.linePtr == (TkTextLine *) NULL) { return TCL_OK; } index.charIndex = 0; segPtr = index.linePtr->segPtr; }}/* *-------------------------------------------------------------- * * MarkFindPrev -- * * This procedure searches backwards for the previous mark. * * Results: * A standard Tcl result, which is a mark name or an empty string. * * Side effects: * None. * *-------------------------------------------------------------- */static intMarkFindPrev(interp, textPtr, string) Tcl_Interp *interp; /* For error reporting */ TkText *textPtr; /* The widget */ char *string; /* The starting index or mark name */{ TkTextIndex index; Tcl_HashEntry *hPtr; register TkTextSegment *segPtr, *seg2Ptr, *prevPtr; int offset; hPtr = Tcl_FindHashEntry(&textPtr->markTable, string); if (hPtr != NULL) { /* * If given a mark name, return the previous mark in the list of * segments, even if it happens to be at the same character position. */ segPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); TkTextMarkSegToIndex(textPtr, segPtr, &index); } else { /* * For non-mark name indices we do not return any marks that * are right at the index. */ if (TkTextGetIndex(interp, textPtr, string, &index) != TCL_OK) { return TCL_ERROR; } for (offset = 0, segPtr = index.linePtr->segPtr; segPtr != NULL && offset < index.charIndex; offset += segPtr->size, segPtr = segPtr->nextPtr) { /* Empty loop body */ ; } } while (1) { /* * segPtr points just past the first possible candidate, * or at the begining of the line. */ for (prevPtr = NULL, seg2Ptr = index.linePtr->segPtr; seg2Ptr != NULL && seg2Ptr != segPtr; seg2Ptr = seg2Ptr->nextPtr) { if (seg2Ptr->typePtr == &tkTextRightMarkType || seg2Ptr->typePtr == &tkTextLeftMarkType) { prevPtr = seg2Ptr; } } if (prevPtr != NULL) { Tcl_SetResult(interp, Tcl_GetHashKey(&textPtr->markTable, prevPtr->body.mark.hPtr), TCL_STATIC); return TCL_OK; } index.linePtr = TkBTreePreviousLine(index.linePtr); if (index.linePtr == (TkTextLine *) NULL) { return TCL_OK; } segPtr = NULL; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -