?? textfield.c
字號:
/*----------------------------------------------------------------------------- * TextField A single line text entry widget * * Copyright (c) 1995 Robert W. McMullen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * Author: Rob McMullen <rwmcm@orion.ae.utexas.edu> * http://www.ae.utexas.edu/~rwmcm */#define _TextField_#include <X11/IntrinsicP.h>#include <X11/StringDefs.h>#include <X11/Xatom.h>#include <X11/Xmu/Xmu.h>#include <stdio.h>/*#include <stdlib.h> */#include "TextFieldP.h"#define offset(field) XtOffsetOf(TextFieldRec, text.field)static XtResource resources[] ={ {XtNallowSelection, XtCBoolean, XtRBoolean, sizeof(Boolean), offset(AllowSelection), XtRString, "True"}, {XtNdisplayCaret, XtCBoolean, XtRBoolean, sizeof(Boolean), offset(DisplayCursor), XtRString, "True"}, {XtNecho, XtCBoolean, XtRBoolean, sizeof(Boolean), offset(Echo), XtRString, "True"}, {XtNeditable, XtCBoolean, XtRBoolean, sizeof(Boolean), offset(Editable), XtRString, "True"}, {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), offset(font), XtRString, XtDefaultFont}, {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), offset(foreground_pixel), XtRString, XtDefaultForeground}, {XtNinsertPosition, XtCInsertPosition, XtRInt, sizeof(int), offset(CursorPos), XtRString, "0"}, {XtNlength, XtCLength, XtRInt, sizeof(int), offset(TextMaxLen), XtRString, "0"}, {XtNmargin, XtCMargin, XtRDimension, sizeof(Dimension), offset(Margin), XtRString, "3"}, {XtNpendingDelete, XtCBoolean, XtRBoolean, sizeof(Boolean), offset(PendingDelete), XtRString, "True"}, {XtNstring, XtCString, XtRString, sizeof(char *), offset(DefaultString), XtRString, NULL}, {XtNactivateCallback, XtCCallback, XtRCallback, sizeof(XtPointer), offset(ActivateCallback), XtRCallback, NULL}, {XtNfocusCallback, XtCCallback, XtRCallback, sizeof(XtPointer), offset(focusCallback), XtRCallback, NULL}, {XtNlosingFocusCallback, XtCCallback, XtRCallback, sizeof(XtPointer), offset(losingFocusCallback), XtRCallback, NULL}, {XtNgainPrimaryCallback, XtCCallback, XtRCallback, sizeof(XtPointer), offset(gainPrimaryCallback), XtRCallback, NULL}, {XtNlosePrimaryCallback, XtCCallback, XtRCallback, sizeof(XtPointer), offset(losePrimaryCallback), XtRCallback, NULL}, {XtNmodifyVerifyCallback, XtCCallback, XtRCallback, sizeof(XtPointer), offset(modifyVerifyCallback), XtRCallback, NULL}, {XtNvalueChangedCallback, XtCCallback, XtRCallback, sizeof(XtPointer), offset(valueChangedCallback), XtRCallback, NULL}, {XtNmotionVerifyCallback, XtCCallback, XtRCallback, sizeof(XtPointer), offset(motionVerifyCallback), XtRCallback, NULL},};#undef offsetstatic void Initialize();static void Destroy();static void Redisplay();static void Resize();static Boolean SetValues();static void Draw(), DrawInsert(), MassiveChangeDraw(), DrawTextReposition(), ClearHighlight(), DrawHighlight(), DrawCursor(), EraseCursor();static Boolean PositionCursor(), MassiveCursorAdjust();static void Nothing(), Activate(), InsertChar(), ForwardChar(), BackwardChar(), DeleteNext(), DeletePrev(), SelectStart(), ExtendStart(), ExtendAdjust(), ExtendEnd(), InsertSelection();static void TfFocusIn(), TfFocusOut(), HomeChar(), EndChar() ;/* * In order for tab-chaining of fields not to be too irritating, * you ought to be able to get back to a previous field by * clicking on it, even if you haven't moved the mouse. This is * why I added focus-in() to Btn1Down. Note that what we end up * with is kind of a weird hybrid between "pointer focus" and * "explicit focus" - you can change focus to a particular field * either by moving the mouse into it, or by clicking on it, if * the mouse is already in it. This may seem weird, but for me * it works ok. - Mark */static char defaultTranslations[] ="<Key>Right: forward-char()\n\ <Key>KP_Right: forward-char()\n\ Ctrl<Key>F: forward-char()\n\ <Key>Left: backward-char()\n\ <Key>KP_Left: backward-char()\n\ Ctrl<Key>B: backward-char()\n\ <Key>Home: home-char()\n\ <Key>KP_Home: home-char()\n\ Ctrl<Key>A: home-char()\n\ <Key>End: end-char()\n\ <Key>KP_End: end-char()\n\ Ctrl<Key>E: end-char()\n\ <Key>Delete: delete-next-char()\n\ <Key>BackSpace: delete-previous-char()\n\ <Key>Return: activate()\n\ <Key>: insert-char()\n\ Shift<Btn1Down>: extend-start()\n\ <Btn1Down>: select-start() focus-in()\n\ <Btn1Motion>: extend-adjust()\n\ <Btn1Up>: extend-end()\n\ <Btn2Down>: insert-selection()\n\ <Btn3Down>: extend-start()\n\ <Btn3Motion>: extend-adjust()\n\ <Btn3Up>: extend-end()\n\ <EnterWindow>: focus-in() enter-window()\n\ <LeaveWindow>: focus-out() leave-window()\n\ <FocusIn>: focus-in()\n\ <FocusOut>: focus-out()";static XtActionsRec actions[] ={ {"insert-char", InsertChar}, {"forward-char", ForwardChar}, {"backward-char", BackwardChar}, {"home-char", HomeChar}, {"end-char", EndChar}, {"delete-next-char", DeleteNext}, {"delete-previous-char", DeletePrev}, {"activate", Activate}, {"select-start", SelectStart}, {"extend-start", ExtendStart}, {"extend-adjust", ExtendAdjust}, {"extend-end", ExtendEnd}, {"insert-selection", InsertSelection}, {"enter-window", Nothing}, {"leave-window", Nothing}, {"focus-in", TfFocusIn}, {"focus-out", TfFocusOut},};TextFieldClassRec textfieldClassRec ={ { /* core_class fields */ /* superclass */ (WidgetClass) & widgetClassRec, /* class_name */ "TextField", /* widget_size */ sizeof(TextFieldRec), /* class_initialize */ NULL, /* class_part_initialize */ NULL, /* class_inited */ False, /* initialize */ Initialize, /* initialize_hook */ NULL, /* realize */ XtInheritRealize, /* actions */ actions, /* num_actions */ XtNumber(actions), /* resources */ resources, /* num_resources */ XtNumber(resources), /* xrm_class */ NULLQUARK, /* compress_motion */ True, /* compress_exposure */ XtExposeCompressMultiple, /* compress_enterleave */ True, /* visible_interest */ True, /* destroy */ Destroy, /* resize */ Resize, /* expose */ Redisplay, /* set_values */ SetValues, /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, /* accept_focus */ NULL, /* version */ XtVersion, /* callback_private */ NULL, /* tm_table */ defaultTranslations, /* query_geometry */ XtInheritQueryGeometry, /* display_accelerator */ XtInheritDisplayAccelerator, /* extension */ NULL }, { /* extension */ NULL }};WidgetClass textfieldWidgetClass = (WidgetClass) & textfieldClassRec;/* Convenience macros */#define TopMargin(w) (int)(w->text.Margin - 1)#define BottomMargin(w) (int)(w->text.Margin)/* Font functions */#define FontHeight(f) (int)(f->max_bounds.ascent + f->max_bounds.descent)#define FontDescent(f) (int)(f->max_bounds.descent)#define FontAscent(f) (int)(f->max_bounds.ascent)#define FontTextWidth(f,c,l) (int)XTextWidth(f, c, l)static voidInitializeGC(TextFieldWidget w){ static char dots[] = {2, 1, 1}; XGCValues values; XtGCMask mask; values.line_style = LineSolid; values.line_width = 0; values.fill_style = FillSolid; values.font = w->text.font->fid; values.background = w->core.background_pixel; values.foreground = w->text.foreground_pixel; mask = GCLineStyle | GCLineWidth | GCFillStyle | GCForeground | GCBackground | GCFont; w->text.drawGC = XtGetGC((Widget) w, mask, &values); values.foreground = w->core.background_pixel; values.background = w->text.foreground_pixel; w->text.highlightGC = XtGetGC((Widget) w, mask, &values); values.line_style = LineSolid; values.line_width = 0; values.background = w->core.background_pixel; values.foreground = w->text.foreground_pixel; mask = GCLineStyle | GCLineWidth | GCForeground | GCBackground; w->text.cursorGC = XtGetGC((Widget) w, mask, &values); values.foreground = w->core.background_pixel; values.background = w->text.foreground_pixel; w->text.eraseGC = XtGetGC((Widget) w, mask, &values); values.line_style = LineOnOffDash; values.background = w->core.background_pixel; values.foreground = w->text.foreground_pixel; w->text.dashGC = XtGetGC((Widget) w, mask, &values); XSetDashes(XtDisplay(w), w->text.dashGC, 0, &dots[1], (int) dots[0]); w->text.YOffset = TopMargin(w) + FontAscent(w->text.font);}static voidClipGC(TextFieldWidget w){ XRectangle clip; clip.x = 0; clip.y = w->text.YOffset - FontAscent(w->text.font) + 1; clip.width = w->text.ViewWidth + 1; clip.height = FontHeight(w->text.font); XSetClipRectangles(XtDisplay((Widget) w), w->text.drawGC, w->text.Margin, 0, &clip, 1, Unsorted); XSetClipRectangles(XtDisplay((Widget) w), w->text.highlightGC, w->text.Margin, 0, &clip, 1, Unsorted);}static voidSetString(TextFieldWidget w, char *s){ int len; if (s) { len = strlen(s); if (len > w->text.TextAlloc) { w->text.TextAlloc += len; w->text.Text = XtRealloc(w->text.Text, w->text.TextAlloc); } strcpy(w->text.Text, s); w->text.TextLen = len; w->text.TextWidth = w->text.OldTextWidth = FontTextWidth(w->text.font, w->text.Text, w->text.TextLen); if ((w->text.TextMaxLen > 0) && (w->text.TextLen > w->text.TextMaxLen)) w->text.TextMaxLen = w->text.TextLen; } w->text.DefaultString = w->text.Text;}static voidInitialize(Widget treq, Widget tnew, ArgList args, Cardinal * num){ TextFieldWidget new; int height; new = (TextFieldWidget) tnew; new->text.timer_id = (XtIntervalId) 0; new->text.multi_click_time = XtGetMultiClickTime(XtDisplay((Widget) new)); new->text.highlight_time = new->text.multi_click_time / 2; if (new->text.TextMaxLen > 0) { new->text.TextAlloc = new->text.TextMaxLen + 1; } else { new->text.TextAlloc = TEXTFIELD_ALLOC_SIZE; } new->text.Text = (char *) XtMalloc(new->text.TextAlloc); new->text.TextLen = 0; new->text.SelectionText = NULL; new->text.TextWidth = new->text.OldTextWidth = 0; if (new->text.DefaultString) SetString(new, new->text.DefaultString); if (new->text.CursorPos > 0) { if (new->text.CursorPos > new->text.TextLen) { new->text.CursorPos = new->text.TextLen; } } else { new->text.CursorPos = 0; } new->text.OldCursorX = -1; new->text.HighlightStart = new->text.HighlightEnd = -1; new->text.OldHighlightStart = new->text.OldHighlightEnd = -1; height = FontHeight(new->text.font); if (treq->core.height == 0) new->core.height = (Dimension) height + TopMargin(new) + BottomMargin(new); if (treq->core.width == 0) { new->text.ViewWidth = 200; new->core.width = new->text.ViewWidth + 2 * new->text.Margin; } else { int width; width = (int) new->core.width - 2 * new->text.Margin; if (width < 0) new->text.ViewWidth = new->core.width; else new->text.ViewWidth = width; } new->text.XOffset = new->text.OldXOffset = 0; InitializeGC(new); ClipGC(new);}static voidDestroy(TextFieldWidget w){ XtReleaseGC((Widget) w, w->text.drawGC); XtReleaseGC((Widget) w, w->text.highlightGC); if (w->text.SelectionText) XtFree(w->text.SelectionText); XtFree(w->text.Text);}static voidRedisplay(Widget aw, XExposeEvent * event, Region region){ TextFieldWidget w = (TextFieldWidget) aw; Draw(w);}static BooleanSetValues(Widget current, Widget request, Widget reply, ArgList args, Cardinal * nargs){ TextFieldWidget w = (TextFieldWidget) current; TextFieldWidget new = (TextFieldWidget) reply; Boolean redraw = False; if ((w->text.foreground_pixel != new->text.foreground_pixel) || (w->core.background_pixel != new->core.background_pixel) || (w->text.font != new->text.font)) { XtReleaseGC((Widget) w, w->text.drawGC); XtReleaseGC((Widget) w, w->text.highlightGC); XtReleaseGC((Widget) w, w->text.cursorGC); XtReleaseGC((Widget) w, w->text.eraseGC); XtReleaseGC((Widget) w, w->text.dashGC); InitializeGC(new); redraw = True; } if ((w->text.CursorPos != new->text.CursorPos) || (w->text.DisplayCursor != new->text.DisplayCursor)) { redraw = True; } if (w->text.DefaultString != new->text.DefaultString) { redraw = True; SetString(new, new->text.DefaultString); new->text.HighlightStart = new->text.HighlightEnd = -1; new->text.CursorPos = new->text.TextLen;#ifdef DEBUG_TF printf("SetValues: %s\n", new->text.DefaultString);#endif } return redraw;}static voidResize(Widget aw){ TextFieldWidget w = (TextFieldWidget) aw; int width, height;if (!w->core.width || !w->core.height) { fprintf(stderr, "Somebody's forcing %d x %d dims on us!\n", w->core.width, w->core.height);} width = w->core.width - 2 * w->text.Margin; if (width < 0) w->text.ViewWidth = w->core.width; else w->text.ViewWidth = width; height = (((int) w->core.height - FontHeight(w->text.font)) / 2) + FontAscent(w->text.font); w->text.YOffset = height; ClipGC(w); MassiveChangeDraw(w);}static voidTextDelete(TextFieldWidget w, int start, int len){ int i; if (len > 0) { for (i = start + len; i < w->text.TextLen; i++) w->text.Text[i - len] = w->text.Text[i]; w->text.TextLen -= len; w->text.TextWidth = FontTextWidth(w->text.font, w->text.Text, w->text.TextLen); w->text.Text[w->text.TextLen] = 0; }}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -