📄 inputwidget.c
字号:
s += m1 - wdt->firstcolumn; } if (x < w - h && m2 > wdt->firstcolumn) { m1 = max (wdt->firstcolumn, m1); CSetBackgroundColor (COLOR_BLACK); CSetColor (COLOR_WHITE); CImageText (win, FONT_OFFSET_X + 3 + TEXTINPUT_RELIEF + x, FONT_OFFSET_Y + 3 + TEXTINPUT_RELIEF, s, m2 - m1); x += CImageTextWidth (s, m2 - m1); s += m2 - m1; } if (x < w - h) { CSetBackgroundColor (COLOR_WHITE); CSetColor (COLOR_BLACK); CImageString (win, FONT_OFFSET_X + 3 + TEXTINPUT_RELIEF + x, FONT_OFFSET_Y + 3 + TEXTINPUT_RELIEF, s); } (*look->render_textinput_tidbits) (wdt, isfocussed); set_cursor_position (win, wc, 5, 0, h - 5, CURSOR_TYPE_TEXTINPUT, 0, 0, 0, 0); CPopFont(); return;}void text_input_destroy (CWidget * w){ CAddToTextInputHistory (w->ident, w->text);}static void xy (int x, int y, int *x_return, int *y_return){ *x_return = x - (3 + TEXTINPUT_RELIEF + 1); *y_return = 0;}static long cp (CWidget * wdt, int x, int y){ int i; i = wdt->firstcolumn; for (;;) { int a; a = CImageTextWidth (wdt->text + wdt->firstcolumn, i - wdt->firstcolumn); if (a > x) { if (i > 0) return i - 1; return 0; } if (!wdt->text[i]) break; i++; } return strlen (wdt->text);}/* return 1 if not marked */static int marks (CWidget * w, long *start, long *end){ if (w->mark1 == w->mark2) return 1; *start = min (w->mark1, w->mark2); *end = max (w->mark1, w->mark2); return 0;}extern int range (CWidget * w, long start, long end, int click);static void move_mark (CWidget * w){ w->mark2 = w->mark1 = w->cursor;}static void fin_mark (CWidget * w){ w->mark2 = w->mark1 = -1;}static void release_mark (CWidget * w, XEvent * event){ w->mark2 = w->cursor; if (w->mark2 != w->mark1 && event) XSetSelectionOwner (CDisplay, XA_PRIMARY, w->winid, event->xbutton.time);}static char *get_block (CWidget * w, long start_mark, long end_mark, int *type, int *l){ char *t; if (w->options & TEXTINPUT_PASSWORD) { *type = DndText; *l = 0; return (char *) strdup (""); } *l = abs (w->mark2 - w->mark1); t = CMalloc (*l + 1); memcpy (t, w->text + min (w->mark1, w->mark2), *l); t[*l] = 0; if (*type == DndFile || *type == DndFiles) { char *s; int i; s = CDndFileList (t, l, &i); free (t); t = s; } return t;}static void move (CWidget * w, long click, int row){ w->cursor = click; if (w->mark2 == -1) w->mark1 = click; w->mark2 = click;}static void motion (CWidget * w, long click){ w->mark2 = click;}void input_insert (CWidget * w, int c);char *filename_from_url (char *data, int size, int i);static int insert_drop (CWidget * w, Window from, unsigned char *data, int size, int xs, int ys, Atom type, Atom action){ int cursor; char *f; int x, y, i; if (xs < 0 || ys < 0 || xs >= w->width || ys >= w->height) return 1; xy (xs, ys, &x, &y); f = filename_from_url ((char *) data, size, 0); data = (unsigned char *) f; cursor = w->cursor = cp (w, x, y); if (type == XInternAtom (CDisplay, "url/url", False) || \ type == XInternAtom (CDisplay, "text/uri-list", False)) if (!strncmp ((char *) data, "file:/", 6)) data += 5; for (i = 0; i < size && data[i] != '\n' && data[i]; i++) input_insert (w, data[i] < ' ' ? ' ' : data[i]); if (cursor > strlen (w->text)) cursor = strlen (w->text); w->cursor = cursor; free (f); return 0;}static char *mime_majors[3] ={"text", 0};static struct mouse_funcs input_mouse_funcs ={ 0, (void (*)(int, int, int *, int *)) xy, (long (*)(void *, int, int)) cp, (int (*)(void *, long *, long *)) marks, (int (*)(void *, long, long, long)) range, (void (*)(void *)) fin_mark, (void (*)(void *)) move_mark, (void (*)(void *, XEvent *)) release_mark, (char *(*)(void *, long, long, int *, int *)) get_block, (void (*)(void *, long, int)) move, (void (*)(void *, long)) motion, 0, 0, (int (*)(void *, Window, unsigned char *, int, int, int, Atom, Atom)) insert_drop, 0, DndText, mime_majors};/* This will reallocate a previous draw of the same identifier. so you can draw the same widget over and over without flicker */CWidget *CDrawTextInput (const char *identifier, Window parent, int x, int y, int width, int height, int maxlen, const char *text){ CWidget *wdt; if (text == TEXTINPUT_LAST_INPUT) text = CLastInput (identifier); CPushFont ("editor", 0); if (!(wdt = CIdent (identifier))) { int w, h; if (width == AUTO_WIDTH || height == AUTO_HEIGHT) CTextSize (&w, &h, text); if (width == AUTO_WIDTH) width = w + 6 + TEXTINPUT_RELIEF * 2; if (height == AUTO_HEIGHT) height = FONT_PIX_PER_LINE + 6 + TEXTINPUT_RELIEF * 2; set_hint_pos (x + width + WIDGET_SPACING, y + height + WIDGET_SPACING); wdt = CSetupWidget (identifier, parent, x, y, width, height, C_TEXTINPUT_WIDGET, INPUT_KEY, COLOR_FLAT, 1);/* For the text input widget we need enough memory allocated to the label for it to grow to maxlen, so reallocate it */ wdt->text = CMalloc (maxlen + 16); strcpy (wdt->text, text); wdt->cursor = strlen (text); wdt->firstcolumn = 0; wdt->textlength = maxlen; wdt->destroy = text_input_destroy; wdt->options |= WIDGET_TAKES_SELECTION; wdt->funcs = mouse_funcs_new (wdt, &input_mouse_funcs); xdnd_set_dnd_aware (CDndClass, wdt->winid, 0); xdnd_set_type_list (CDndClass, wdt->winid, xdnd_typelist_send[DndText]); } else { /*redraw the thing so it doesn't flicker if its redrawn in the same place. Also, this doesn't need an undraw */ CSetWidgetSize (identifier, width, height); wdt->x = x; wdt->y = y; XMoveWindow (CDisplay, wdt->winid, x, y); free (wdt->text); wdt->text = CMalloc (maxlen + 16); strcpy (wdt->text, text); wdt->cursor = strlen (text); wdt->firstcolumn = 0; wdt->textlength = maxlen; wdt->keypressed = 0; render_textinput (wdt); } CPopFont(); return wdt;}void paste_prop (void *data, void (*insert) (void *, int), Window win, unsigned prop, int delete);void input_insert (CWidget * w, int c){ if (strlen ((char *) w->text) < w->textlength) { if (!w->keypressed) { w->keypressed = 1; w->cursor = 0; w->text[0] = '\0'; } memmove ((char *) w->text + w->cursor + 1, w->text + w->cursor, strlen ((char *) w->text) - w->cursor + 1); w->text[w->cursor] = c; w->cursor++; }}static void xy (int x, int y, int *x_return, int *y_return);static long cp (CWidget * wdt, int x, int y);void text_get_selection (CWidget * w);void selection_send (XSelectionRequestEvent * rq);int eh_textinput (CWidget * w, XEvent * xevent, CEvent * cwevent){ int handled = 0, save_options; int cursor; char *u; switch (xevent->type) { case FocusIn: case FocusOut: render_textinput (w); break; case SelectionRequest: text_get_selection (w); selection_send (&(xevent->xselectionrequest)); render_textinput (w); return 1; case SelectionNotify: cursor = w->keypressed ? w->cursor : 0; paste_prop ((void *) w, (void (*)(void *, int)) input_insert, xevent->xselection.requestor, xevent->xselection.property, True); w->mark1 = w->mark2 = 0; w->cursor = cursor; render_textinput (w); break; case ButtonPress: resolve_button (xevent, cwevent); if (!(w->options & TEXTINPUT_PASSWORD)) { if (xevent->xbutton.x >= w->width - w->height) { char *p; w->options &= 0xFFFFFFFFUL - BUTTON_PRESSED - BUTTON_HIGHLIGHT; w->options |= BUTTON_PRESSED; p = draw_text_input_history (w); if (p) { strncpy (w->text, p, w->textlength); w->keypressed = 1; w->cursor = strlen (w->text); w->firstcolumn = 0; } } else { input_mouse_mark (w, xevent, cwevent); w->options &= 0xFFFFFFFFUL - BUTTON_PRESSED - BUTTON_HIGHLIGHT; } } render_textinput (w); CFocus (w); case ButtonRelease: if (!(w->options & TEXTINPUT_PASSWORD)) input_mouse_mark (w, xevent, cwevent); render_textinput (w); break; case Expose: if (xevent->xexpose.count) return 0; case EnterNotify: w->options &= 0xFFFFFFFFUL - BUTTON_PRESSED - BUTTON_HIGHLIGHT; if (xevent->xbutton.x >= w->width - w->height) w->options |= BUTTON_HIGHLIGHT; render_textinput (w); break; case MotionNotify: save_options = w->options; w->options &= ~(BUTTON_PRESSED | BUTTON_HIGHLIGHT); if (xevent->xmotion.x >= w->width - w->height) { w->options |= BUTTON_HIGHLIGHT; if (save_options != w->options) render_textinput (w); return 0; } else { if (!xevent->xmotion.state) { if (save_options != w->options) render_textinput (w); return 0; } } if (!(w->options & TEXTINPUT_PASSWORD)) input_mouse_mark (w, xevent, cwevent); render_textinput (w); break; case LeaveNotify: w->options &= 0xFFFFFFFFUL - BUTTON_PRESSED - BUTTON_HIGHLIGHT; render_textinput (w); break; case KeyPress: cwevent->ident = w->ident; cwevent->state = xevent->xkey.state; cursor = w->cursor; if (cwevent->insert > 0) { if (!((w->options & TEXTINPUT_NUMBERS) && !(cwevent->insert >= '0' && cwevent->insert <= '9'))) input_insert (w, cwevent->insert); handled = 1; } else { unsigned char *intext; intext = (unsigned char *) w->text; switch (cwevent->command) { case CK_Insert_Unicode: u = (char *) CGetUnichar (CRoot, "Unicode characters"); if (u) while (*u) input_insert (w, *u++); handled = 1; break; case CK_XPaste: if (!XGetSelectionOwner (CDisplay, XA_PRIMARY)) { cursor = w->cursor; paste_prop ((void *) w, (void (*)(void *, int)) input_insert, CRoot, XA_CUT_BUFFER0, False); w->cursor = cursor; } else { XConvertSelection (CDisplay, XA_PRIMARY, XA_STRING, XInternAtom (CDisplay, "VT_SELECTION", False), w->winid, CurrentTime); return 0; } handled = 1; break; case CK_BackSpace: if (w->mark1 != w->mark2) { memmove (intext + min (w->mark1, w->mark2), intext + max (w->mark1, w->mark2), strlen ((char *) intext + max (w->mark1, w->mark2)) + 1); w->cursor = min (w->mark1, w->mark2); } else if (w->cursor > 0) { memmove ((char *) intext + w->cursor - 1, intext + w->cursor, strlen ((char *) intext) - w->cursor + 1); w->cursor--; } handled = 1; break; case CK_Left: if (w->cursor > 0) w->cursor--; handled = 1; break; case CK_Down: case CK_Up: case CK_Down_Highlight: case CK_Up_Highlight: if (cwevent->state & ShiftMask) { char *p; w->options |= BUTTON_PRESSED; p = draw_text_input_history (w); if (p) { strncpy (w->text, p, w->textlength); w->keypressed = 1; w->cursor = strlen (w->text); w->firstcolumn = 0; } w->options &= 0xFFFFFFFFUL - BUTTON_PRESSED - BUTTON_HIGHLIGHT; handled = 1; } break; case CK_Right: if (w->cursor < strlen ((char *) intext)) w->cursor++; handled = 1; break; case CK_Delete: if (w->mark1 != w->mark2) { memmove (intext + min (w->mark1, w->mark2), intext + max (w->mark1, w->mark2), strlen ((char *) intext + max (w->mark1, w->mark2)) + 1); w->cursor = min (w->mark1, w->mark2); } else if (w->cursor < strlen ((char *) intext)) memmove (intext + w->cursor, intext + w->cursor + 1, strlen ((char *) intext) - w->cursor + 1); handled = 1; break; case CK_Home: w->cursor = 0; handled = 1; break; case CK_End: w->cursor = strlen ((char *) intext); handled = 1; break; } w->keypressed |= handled; } if (handled) { w->mark1 = w->mark2 = 0; render_textinput (w); } cwevent->text = w->text; } return handled;}void input_mouse_mark (CWidget * w, XEvent * event, CEvent * ce){ CPushFont ("editor", 0); mouse_mark (event, ce->double_click, w->funcs); CPopFont ();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -