📄 textwidget.c
字号:
case TEXT_SET_CURSOR_LINE: i = wdt->firstline; j = wdt->cursor; if (p < 0) p = 0; if (p >= wdt->numlines) p = wdt->numlines - 1; wdt->cursor = p; if (p < wdt->firstline) CSetTextboxPos (wdt, TEXT_SET_LINE, p); else if (p > wdt->firstline + (wdt->height - FONT_PIX_PER_LINE - 6) / FONT_PIX_PER_LINE) CSetTextboxPos (wdt, TEXT_SET_LINE, p - (wdt->height - FONT_PIX_PER_LINE - 6) / FONT_PIX_PER_LINE); CPopFont (); return (i != wdt->firstline || j != wdt->cursor); }/* NLS ? */ CError ("settextpos: command not found.\n"); CPopFont (); return 0;}static void text_print_line (CWidget * w, long b, int row){ edit_draw_proportional (w, (void (*)(void *, long, cache_type *, int, int, int)) convert_text2, (int (*)(void *, long, long *, int)) calc_text_pos2, -w->firstcolumn * FONT_MEAN_WIDTH, w->winid, w->width, b, row, row * FONT_PIX_PER_LINE + EDIT_TEXT_VERTICAL_OFFSET, 0, FONT_PER_CHAR(' ') * TAB_SIZE);}/* ->firstline is line number of the top line in the window. ->firstcolumn is column shift (positive). ->current is actual char position of first line in display. ->numlines is the total number of lines. ->cursor is the number of the highlighted line. ->textlength is the length of text excluding trailing NULL. First three must be initialised to proper values (e.g. 0, 0 and 0). */extern int EditExposeRedraw;extern int EditClear;extern int highlight_this_line;extern unsigned long edit_normal_background_color;long render_textbox (CWidget * w, int redrawall){ long b; int c = 0, r = 0, row, height, isfocussed, wrap_width = 32000, curs, lines_drawn = 0; CPushFont ("editor", 0); if (w->options & TEXTBOX_WRAP) { wrap_width = (w->width - TEXTBOX_BDR) / FONT_MEAN_WIDTH; if (w->resized) { /* a resize will change the number lines if text is wrapping */ int firstline = w->firstline; w->numlines = strcountlines (w->text, 0, 1000000000, wrap_width) + 1; w->firstline = 0; w->current = w->cursor = 0; CSetTextboxPos (w, TEXT_SET_LINE, firstline); w->resized = 0; /* done */ } } if (redrawall) { EditExposeRedraw = 1; EditClear = 1; } b = w->current; height = w->height / FONT_PIX_PER_LINE + 1; isfocussed = (w->winid == CGetFocus ()); curs = !(w->options & TEXTBOX_NO_CURSOR || w->mark1 != w->mark2); /* don't draw the cursor line */ edit_set_foreground_colors (color_palette (option_text_fg_normal), color_palette (option_text_fg_bold), color_palette (option_text_fg_italic)); edit_set_background_colors (color_palette (option_text_bg_normal), color_palette (0), color_palette (option_text_bg_marked), color_palette (9), color_palette (option_text_bg_highlighted)); for (row = 0; row < height; row++) { if (row + w->firstline == w->cursor && isfocussed && curs) highlight_this_line = 1; else highlight_this_line = 0; if (row + w->firstline < w->numlines) { c = strmovelines (w->text, b, 1, wrap_width); if (c != b) { /* at last line strmovelines cannot move */ r = w->text[c]; w->text[c] = 0; /* mark where line wraps */ } lines_drawn++; text_print_line (w, b, row); if (c != b) w->text[c] = r; /* remove mark */ b = c; } else { text_print_line (w, w->textlength, row); /* print blank lines */ } } EditExposeRedraw = 0; EditClear = 0; (*look->render_textbox_tidbits) (w, isfocussed); CSetColor (edit_normal_background_color); CLine (w->winid, 3, 3, 3, w->height - 4); CPopFont (); return lines_drawn;}/* Count the number of lines that would be printed by the above routine, but don't print anything. If all is non-zero then count all the lines. */long count_textbox_lines (CWidget * wdt, int all){ int nroff, col = 0, row = 0, height, width; long from; unsigned char c; int wrap_mode; unsigned char *text; CPushFont ("editor", 0); nroff = (wdt->options & TEXTBOX_MAN_PAGE); wrap_mode = (wdt->options & TEXTBOX_WRAP); if (nroff) wrap_mode = 0; text = (unsigned char *) wdt->text; height = wdt->height / FONT_PIX_PER_LINE; width = (wdt->width - TEXTBOX_BDR) / FONT_MEAN_WIDTH; if (all) from = 0; else from = wdt->current; for (; row < height || all; from++) { c = text[from]; if (!c) break; if ((c == '\n') || (col == width && wrap_mode)) { col = 0; row++; if (c == '\n' || row >= height) continue; } if (c == '\r') continue; if (c == '\t') { col = (col / 8) * 8 + 8; continue; } col++; } CPopFont (); return row + 1;}/* move the text box cursor or the text window if there isn't one */int CTextboxCursorMove (CWidget * wdt, KeySym key){ int handled = 0; CPushFont ("editor", 0);/* when text is highlighted, the cursor must be off */ if (wdt->options & TEXTBOX_NO_CURSOR || wdt->mark1 != wdt->mark2) { int to_move = 0; switch ((int) key) { case CK_Up: handled = 1; to_move = -1; break; case CK_Down: handled = 1; to_move = 1; break; case CK_Page_Up: handled = 1; to_move = 1 - wdt->height / FONT_PIX_PER_LINE; break; case CK_Page_Down: handled = 1; to_move = wdt->height / FONT_PIX_PER_LINE - 1; break; case CK_Home: handled = 1; to_move = -32000; break; case CK_End: handled = 1; to_move = 32000; break; case CK_Left: handled = 1; if (wdt->firstcolumn > 0) wdt->firstcolumn--; break; case CK_Right: handled = 1; wdt->firstcolumn++; break; } CSetTextboxPos (wdt, TEXT_SET_LINE, wdt->firstline + to_move); } else { switch ((int) key) { case CK_Up: handled = 1; wdt->cursor--; break; case CK_Down: handled = 1; wdt->cursor++; break; case CK_Page_Up: handled = 1; wdt->cursor -= (wdt->height / FONT_PIX_PER_LINE - 1); break; case CK_Page_Down: handled = 1; wdt->cursor += (wdt->height / FONT_PIX_PER_LINE - 1); break; case CK_Home: handled = 1; wdt->cursor = 0; break; case CK_End: handled = 1; wdt->cursor = wdt->numlines; break; case CK_Left: handled = 1; if (wdt->firstcolumn > 0) { wdt->firstcolumn--; } break; case CK_Right: handled = 1; wdt->firstcolumn++; break; } CSetTextboxPos (wdt, TEXT_SET_CURSOR_LINE, wdt->cursor); /* just does some checks */ } CPopFont (); return handled;}static void text_mouse_mark (CWidget * w, XEvent * event, CEvent * ce){ CPushFont ("editor", 0); mouse_mark (event, ce->double_click, w->funcs); CPopFont ();}/* gets selected text into selection structure, stripping nroff */void text_get_selection (CWidget * w){ char *t; int len; len = abs (w->mark2 - w->mark1); t = CMalloc (len + 1); memcpy (t, w->text + min (w->mark1, w->mark2), len); t[len] = 0; if (selection.text) free (selection.text); selection.text = (unsigned char *) str_strip_nroff ((char *) t, &selection.len); free (t); if (!selection.text) { selection.text = CMalloc (1); selection.len = 0; } selection.text[selection.len] = 0;}void selection_send (XSelectionRequestEvent * rq);int eh_textbox (CWidget * w, XEvent * xevent, CEvent * cwevent){ int handled = 0, redrawall, count; redrawall = 0; switch (xevent->type) { case SelectionRequest: text_get_selection (w); selection_send (&(xevent->xselectionrequest)); return 1; case Expose: if (!xevent->xexpose.count) redrawall = 1; break; case ClientMessage: w->mark1 = w->mark2 = 0; break; case ButtonPress: CFocus (w); CPushFont ("editor", 0); if (xevent->xbutton.button == Button1) w->cursor = (xevent->xbutton.y - TEXTBOX_BDR) / FONT_PIX_PER_LINE + w->firstline; if (w->cursor > w->numlines - 1) w->cursor = w->numlines - 1; if (w->cursor < 0) w->cursor = 0; cwevent->ident = w->ident; cwevent->xt = (xevent->xbutton.x - 7) / FONT_MEAN_WIDTH + w->firstcolumn; cwevent->yt = w->cursor; CPopFont (); case ButtonRelease: case MotionNotify: if (!xevent->xmotion.state && xevent->type == MotionNotify) return 0; resolve_button (xevent, cwevent); text_mouse_mark (w, xevent, cwevent); break; case FocusIn: case FocusOut: break; case KeyPress: cwevent->ident = w->ident; if (!(TEXTBOX_NO_KEYS & w->options)) handled = CTextboxCursorMove (w, cwevent->command); break; default: return 0; }/* Now draw the changed text box, count will contain the number of textlines displayed */ count = render_textbox (w, redrawall);/* now update the scrollbar position */ if (w->vert_scrollbar) { w->vert_scrollbar->firstline = (double) 65535.0 *w->firstline / w->numlines; w->vert_scrollbar->numlines = (double) 65535.0 *count / w->numlines; w->vert_scrollbar->options = 0; render_scrollbar (w->vert_scrollbar); } return handled;}void link_scrollbar_to_textbox (CWidget * scrollbar, CWidget * textbox, XEvent * xevent, CEvent * cwevent, int whichscrbutton){ int redrawtext = 0, count = -1, c; static int r = 0; CPushFont ("editor", 0); if ((xevent->type == ButtonRelease || xevent->type == MotionNotify) && whichscrbutton == 3) { redrawtext = CSetTextboxPos (textbox, TEXT_SET_LINE, (double) scrollbar->firstline * textbox->numlines / 65535.0); } else if (xevent->type == ButtonPress && (cwevent->button == Button1 || cwevent->button == Button2)) { switch (whichscrbutton) { case 1: redrawtext = CSetTextboxPos (textbox, TEXT_SET_LINE, textbox->firstline - (textbox->height / FONT_PIX_PER_LINE - 2)); break; case 2: redrawtext = CSetTextboxPos (textbox, TEXT_SET_LINE, textbox->firstline - 1); break; case 5: redrawtext = CSetTextboxPos (textbox, TEXT_SET_LINE, textbox->firstline + 1); break; case 4: redrawtext = CSetTextboxPos (textbox, TEXT_SET_LINE, textbox->firstline + (textbox->height / FONT_PIX_PER_LINE - 2)); break; } } if (xevent->type == ButtonRelease) count = render_textbox (textbox, 0); else { c = CCheckWindowEvent (xevent->xany.window, ButtonReleaseMask | ButtonMotionMask, 0); if (redrawtext) { if (!c) { render_textbox (textbox, 0); r = 0; } else { r = 1; } } else if (c && r) { render_textbox (textbox, 0); r = 0; } } if (count < 0) count = count_textbox_lines (textbox, 0); if (!count) count = 1; scrollbar->firstline = (double) 65535.0 *textbox->firstline / textbox->numlines; scrollbar->numlines = (double) 65535.0 *count / textbox->numlines; CPopFont (); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -