📄 textfield.c
字号:
static voidTextDeleteHighlighted(TextFieldWidget w){ if (w->text.HighlightStart >= 0) { TextDelete(w, w->text.HighlightStart, w->text.HighlightEnd - w->text.HighlightStart); w->text.CursorPos = w->text.HighlightStart; w->text.HighlightStart = w->text.HighlightEnd = -1; }}/* returns value indicating if the text can be redrawn using the fast * method */static BooleanTextInsert(TextFieldWidget w, char *buf, int len){ int i; Boolean regular_copy, fast_insert; fast_insert = True; if (len > 0) { if (w->text.HighlightStart >= 0) { fast_insert = False; if (w->text.PendingDelete) TextDeleteHighlighted(w); else ClearHighlight(w); } regular_copy = True; if (w->text.TextMaxLen > 0) { if (w->text.TextLen + len > w->text.TextMaxLen) regular_copy = False; } else if (w->text.TextLen + len > w->text.TextAlloc) { i = TEXTFIELD_ALLOC_SIZE; if (i < len) i = len; w->text.TextAlloc += i + 1; w->text.Text = XtRealloc(w->text.Text, w->text.TextAlloc);#ifdef DEBUG_TF printf("TextInsert: Alloced new space: %d bytes\n", w->text.TextAlloc);#endif } if (regular_copy) { for (i = w->text.TextLen - 1; i >= w->text.CursorPos; i--) w->text.Text[i + len] = w->text.Text[i]; strncpy(&w->text.Text[w->text.CursorPos], buf, len); w->text.FastInsertCursorStart = w->text.CursorPos; w->text.FastInsertTextLen = len; w->text.TextLen += len; w->text.CursorPos += len; } else { int i1; for (i = w->text.TextLen - 1; i >= w->text.CursorPos; i--) if (i + len < w->text.TextMaxLen) w->text.Text[i + len] = w->text.Text[i]; w->text.TextLen += len; if (w->text.TextLen > w->text.TextMaxLen) w->text.TextLen = w->text.TextMaxLen; i1 = w->text.CursorPos; for (i = 0; i < len; i++) { if (i1 < w->text.TextMaxLen) w->text.Text[i1] = *buf++; else break; i1++; } w->text.FastInsertCursorStart = w->text.CursorPos; w->text.FastInsertTextLen = i1 - w->text.CursorPos; w->text.CursorPos = i1; } w->text.TextWidth = FontTextWidth(w->text.font, w->text.Text, w->text.TextLen); w->text.Text[w->text.TextLen] = 0; } return fast_insert;}static intTextPixelToPos(TextFieldWidget w, int x){ int i, tot, cur, pos; pos = 0; x -= (int) w->text.Margin + w->text.XOffset;/* check if the cursor is before the 1st character */ if (x <= 0) { pos = 0; }/* OK, how 'bout after the last character */ else if (x > FontTextWidth(w->text.font, w->text.Text, w->text.TextLen)) { pos = w->text.TextLen; }/* must be in between somewhere... */ else { tot = 0; pos = -1; for (i = 0; i < w->text.TextLen; i++) { cur = FontTextWidth(w->text.font, &w->text.Text[i], 1); if (x < tot + (cur / 2)) { pos = i; break; } tot += cur; } if (pos < 0) pos = w->text.TextLen; } return pos;}/* * TextField Widget Action procedures */ /* shorthand utility: call callbacks */static voidtextfieldCallbacks(TextFieldWidget w, XtCallbackList callbacks, int reason, XEvent *event, String str){ TextFieldReturnStruct cbs; if( callbacks ) { cbs.reason = reason ; cbs.event = event; cbs.string = str ; XtCallCallbackList((Widget)w, callbacks, &cbs); }}/* ARGSUSED */static voidNothing(Widget aw, XEvent * event, String * params, Cardinal * num_params){}/* ARGSUSED */static voidTfFocusIn(Widget aw, XEvent * event, String * params, Cardinal * num_params){ TextFieldWidget w = (TextFieldWidget) aw; if( w->text.focusCallback ) textfieldCallbacks(w, w->text.focusCallback, TF_FOCUS, event, w->text.Text);}/* ARGSUSED */static voidTfFocusOut(Widget aw, XEvent * event, String * params, Cardinal * num_params){ TextFieldWidget w = (TextFieldWidget) aw; if( w->text.losingFocusCallback ) { TextFieldVerifyStruct cbs; cbs.reason = TF_LOSING_FOCUS ; cbs.event = event; cbs.curInsert = cbs.newInsert = w->text.CursorPos ; cbs.startPos = cbs.endPos = 0 ; cbs.text = NULL ; XtCallCallbackList(aw, w->text.losingFocusCallback, &cbs); }}/* ARGSUSED */static voidActivate(Widget aw, XEvent * event, String * params, Cardinal * num_params){ TextFieldWidget w = (TextFieldWidget) aw; if( w->text.ActivateCallback ) textfieldCallbacks(w, w->text.ActivateCallback, TF_ACTIVATE, event, w->text.Text);} /* Shorthand utility: verify cursor motion */static BoolmotionVerify(TextFieldWidget w, XEvent *event, int newpos){ TextFieldVerifyStruct cbs; if( w->text.motionVerifyCallback == NULL ) return True ; /* allow callback procs to veto */ /* TODO: verify that these values are correct. */ cbs.reason = TF_MOVING_INSERT_CURSOR ; cbs.event = event ; cbs.doit = True ; cbs.curInsert = w->text.CursorPos ; cbs.newInsert = newpos ; cbs.startPos = cbs.endPos = -1 ; cbs.text = NULL ; XtCallCallbackList((Widget)w, w->text.motionVerifyCallback, &cbs); return cbs.doit ;}/* ARGSUSED */static voidForwardChar(Widget aw, XEvent * event, String * params, Cardinal * num_params){ TextFieldWidget w = (TextFieldWidget) aw; if (!w->text.Editable) return; if (w->text.CursorPos < w->text.TextLen && motionVerify(w, event, w->text.CursorPos + 1) ) { ClearHighlight(w); w->text.CursorPos++; EraseCursor(w); if (PositionCursor(w)) DrawTextReposition(w); DrawCursor(w); }}/* ARGSUSED */static voidBackwardChar(Widget aw, XEvent * event, String * params, Cardinal * num_params){ TextFieldWidget w = (TextFieldWidget) aw; if (!w->text.Editable) return; if (w->text.CursorPos > 0 && motionVerify(w, event, w->text.CursorPos - 1) ) { ClearHighlight(w); w->text.CursorPos--; EraseCursor(w); if (PositionCursor(w)) DrawTextReposition(w); DrawCursor(w); }}/* ARGSUSED */static voidHomeChar(Widget aw, XEvent * event, String * params, Cardinal * num_params){ TextFieldWidget w = (TextFieldWidget) aw; if (!w->text.Editable) return; if (w->text.CursorPos > 0 && motionVerify(w, event, 0) ) { ClearHighlight(w); w->text.CursorPos = 0; EraseCursor(w); if (PositionCursor(w)) DrawTextReposition(w); DrawCursor(w); }}/* ARGSUSED */static voidEndChar(Widget aw, XEvent * event, String * params, Cardinal * num_params){ TextFieldWidget w = (TextFieldWidget) aw; if (!w->text.Editable) return; if (w->text.CursorPos < w->text.TextLen && motionVerify(w, event, w->text.TextLen) ) { ClearHighlight(w); w->text.CursorPos = w->text.TextLen; EraseCursor(w); if (PositionCursor(w)) DrawTextReposition(w); DrawCursor(w); }}/* ARGSUSED */static voidInsertChar(Widget aw, XEvent * event, String * params, Cardinal * num_params){ TextFieldWidget w = (TextFieldWidget) aw; TextFieldBlockRec textblock ; int len;#define INSERTCHARBUFSIZ 32 char buf[INSERTCHARBUFSIZ]; if (!w->text.Editable) return; len = XLookupString((XKeyEvent *) event, buf, sizeof(buf), NULL, NULL); textblock.ptr = buf ; textblock.length = len ; if (len > 0) { if( w->text.modifyVerifyCallback ) { TextFieldVerifyStruct cbs; /* allow callback procs to veto */ /* TODO: verify that these values are correct. */ cbs.reason = TF_MODIFYING_TEXT_VALUE ; cbs.event = event ; cbs.doit = True ; if (w->text.HighlightStart >= 0 && w->text.PendingDelete) { cbs.curInsert = w->text.HighlightStart ; cbs.newInsert =w->text.HighlightStart + len ; cbs.startPos =w->text.HighlightStart ; cbs.endPos =w->text.HighlightEnd ; } else { cbs.curInsert = w->text.CursorPos ; cbs.newInsert = w->text.CursorPos + len ; cbs.startPos = -1 ; cbs.endPos = -1 ; } cbs.text = &textblock ; textblock.ptr = buf ; textblock.length = len ; textblock.format = 0 ; XtCallCallbackList(aw, w->text.modifyVerifyCallback, &cbs); if( !cbs.doit ) return ; } EraseCursor(w); if (TextInsert(w, textblock.ptr, textblock.length)) DrawInsert(w); else Draw(w); if( w->text.valueChangedCallback ) textfieldCallbacks(w, w->text.valueChangedCallback, TF_VALUE_CHANGED, event, w->text.Text); }}/* ARGSUSED */static voidDeleteNext(Widget aw, XEvent * event, String * params, Cardinal * num_params){ TextFieldWidget w = (TextFieldWidget) aw; Bool changed = False ; if (!w->text.Editable) return; if( w->text.modifyVerifyCallback ) { TextFieldVerifyStruct cbs; /* allow callback procs to veto */ /* TODO: verify that these values are correct. */ cbs.reason = TF_MODIFYING_TEXT_VALUE ; cbs.event = event ; cbs.doit = True ; if (w->text.HighlightStart >= 0 && w->text.PendingDelete) { cbs.curInsert = w->text.CursorPos ; cbs.newInsert =w->text.HighlightStart ; cbs.startPos =w->text.HighlightStart ; cbs.endPos =w->text.HighlightEnd ; } else { cbs.curInsert = w->text.CursorPos ; cbs.newInsert =w->text.CursorPos ; cbs.startPos =w->text.CursorPos ; cbs.endPos =w->text.CursorPos ; } cbs.text = NULL ; XtCallCallbackList(aw, w->text.modifyVerifyCallback, &cbs); if( !cbs.doit ) return ; } if (w->text.HighlightStart >= 0 && w->text.PendingDelete) { TextDeleteHighlighted(w); MassiveChangeDraw(w); changed = True ; } else if (w->text.CursorPos < w->text.TextLen) { ClearHighlight(w); TextDelete(w, w->text.CursorPos, 1); Draw(w); } if( changed && w->text.valueChangedCallback ) textfieldCallbacks(w, w->text.valueChangedCallback, TF_VALUE_CHANGED, event, w->text.Text);}/* ARGSUSED */static voidDeletePrev(Widget aw, XEvent * event, String * params, Cardinal * num_params){ TextFieldWidget w = (TextFieldWidget) aw; Bool changed = False ; if (!w->text.Editable) return; if( w->text.modifyVerifyCallback ) { TextFieldVerifyStruct cbs; /* allow callback procs to veto */ /* TODO: verify that these values are correct. */ cbs.reason = TF_MODIFYING_TEXT_VALUE ; cbs.event = event ; cbs.doit = True ; if (w->text.HighlightStart >= 0 && w->text.PendingDelete) { cbs.curInsert = w->text.CursorPos ; cbs.newInsert =w->text.HighlightStart ; cbs.startPos =w->text.HighlightStart ; cbs.endPos =w->text.HighlightEnd ; } else { cbs.curInsert = w->text.CursorPos ; cbs.newInsert =w->text.CursorPos - 1 ; cbs.startPos =w->text.CursorPos - 1 ; cbs.endPos =w->text.CursorPos - 1 ; } cbs.text = NULL ; XtCallCallbackList(aw, w->text.modifyVerifyCallback, &cbs); if( !cbs.doit ) return ; } if (w->text.HighlightStart >= 0 && w->text.PendingDelete) { TextDeleteHighlighted(w); MassiveChangeDraw(w);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -