📄 fieldedtextbox.c
字号:
(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, 0, 0, DndFile};CWidget *CDrawFieldedTextbox (const char *identifier, Window parent, int x, int y, int width, int height, int line, int column, char **(*get_line) (void *, int, int *, int *), long options, void *data){ char *scroll; int numlines; CWidget *wdt; int *tab, wf; int w, h, x_hint, y_hint; CPushFont ("editor", 0); tab = get_field_sizes (data, &numlines, &wf, get_line); if (width == AUTO_WIDTH) w = wf + 6; else w = width; if (height == AUTO_HEIGHT) h = (max (1, numlines)) * FONT_PIX_PER_LINE + 6; else h = height; wdt = CSetupWidget (identifier, parent, x, y, w, h, C_FIELDED_TEXTBOX_WIDGET, INPUT_KEY, color_palette (option_text_bg_normal), 1); xdnd_set_type_list (CDndClass, wdt->winid, xdnd_typelist_send[DndText]); wdt->eh = eh_fielded_textbox; wdt->options = options | WIDGET_TAKES_SELECTION; wdt->firstline = line; wdt->firstcolumn = column; wdt->column = wf; wdt->cursor = 0; wdt->numlines = numlines; wdt->tab = tab; wdt->get_line = get_line; wdt->hook = data; wdt->funcs = mouse_funcs_new (wdt, &fielded_mouse_funcs); if (h > 80 && height != AUTO_HEIGHT) { wdt->vert_scrollbar = CDrawVerticalScrollbar (scroll = catstrs (identifier, ".vsc", 0), parent, x + w + WIDGET_SPACING, y, h, AUTO_WIDTH, 0, 0); CSetScrollbarCallback (wdt->vert_scrollbar->ident, wdt->ident, link_scrollbar_to_fielded_textbox); CGetHintPos (&x_hint, 0); } else { x_hint = x + w + WIDGET_SPACING; } if (w > 80 && width != AUTO_WIDTH) { wdt->hori_scrollbar = CDrawHorizontalScrollbar (scroll = catstrs (identifier, ".hsc", 0), parent, x, y + h + WIDGET_SPACING, w, (*look->get_fielded_textbox_hscrollbar_width) (), 0, 65535); CSetScrollbarCallback (wdt->hori_scrollbar->ident, wdt->ident, link_h_scrollbar_to_fielded_textbox); CGetHintPos (0, &y_hint); } else { y_hint = y + h + WIDGET_SPACING; } set_hint_pos (x_hint, y_hint); CPopFont (); return wdt;}CWidget *CRedrawFieldedTextbox (const char *identifier, int preserve){ int numlines; CWidget *wdt; int *tab, w; CPushFont ("editor", 0); wdt = CIdent (identifier); tab = get_field_sizes (wdt->hook, &numlines, &w, wdt->get_line); if (!preserve) { wdt->firstline = 0; wdt->firstcolumn = 0; wdt->cursor = 0; } wdt->column = w; wdt->numlines = numlines; if (wdt->tab) free (wdt->tab); wdt->tab = tab; wdt->mark1 = wdt->mark2 = -1; CSetColor (color_palette (option_text_bg_normal)); CRectangle (wdt->winid, 3, 3, wdt->width - 3 - 1, wdt->height - 3 - 1); CExpose (identifier); CPopFont (); return wdt;}static int calc_text_pos_fielded_textbox (CWidget *w, long b, long *q, int l){ int x = 0, c, xn = 0, tagged; unsigned char *text; long k; void *data = 0; if ((b >> 16) < w->numlines) data = w->hook; text = compose_line_cached (data, b >> 16, w->tab, w->get_line, &tagged); k = b & 0xFFFFL; if (k == 0xFFFFL) k = 0; for (;;) { c = text[k]; switch (c) { case '\0': case '\n': *q = b; return x; case '\f': xn = x + text[k + 1]; if (xn > l) { *q = b; return x; break; } k++; b++; break; case '\b': case '\r': xn = x + FONT_PER_CHAR(text[k + 1]); if (xn > l) { *q = b; return x; break; } k++; b++; break; case '\v': xn = x + pixmap_width (text[k + 1]); if (xn > l) { *q = b; return x; break; } k++; b++; break; default: xn = x + FONT_PER_CHAR(c); break; } if (xn > l) break; x = xn; b++; k++; } *q = b; return x;}extern int highlight_this_line;/* here upper 16 bits of q are the line, lowe 16, the column */static void convert_text_fielded_textbox (CWidget * w, long q, cache_type *line, int x, int x_max, int row){ unsigned char *text; int c, tagged, bold = 0, italic = 0; cache_type *p; long m1, m2, k; void *data = 0; m1 = min (w->mark1, w->mark2); m2 = max (w->mark1, w->mark2); if ((q >> 16) < w->numlines) data = w->hook; text = compose_line_cached (data, q >> 16, w->tab, w->get_line, &tagged); k = q & 0xFFFFL; if (k == 0xFFFFL) k = 0; p = line; p->c.ch = p->style = 0; for (;;) { c = text[k]; p[1].style = p[1].c.ch = 0; p->c.fg = p->c.bg = 0xFF; /* default background colors */ if (highlight_this_line) p->c.style |= MOD_HIGHLIGHTED; if (tagged) p->c.style |= MOD_INVERSE; if (q >= m1 && q < m2) p->c.style |= MOD_MARKED; switch (c) { case '\0': case '\n': (p++)->c.ch = ' '; if (highlight_this_line || tagged) { q--; k--; x += FONT_PER_CHAR(' '); } else return; break; case '\f': k++; q++; p->c.style |= MOD_TAB; (p++)->c.ch = text[k]; x += text[k]; break; case '\b': bold = 2; break; case '\r': italic = 2; break; case '\v': k++; q++; p->c.style |= MOD_TAB; (p++)->c.ch = text[k]; x += pixmap_width (text[k]); break; default: x += FONT_PER_CHAR(c); p->c.ch = c; if (italic > 0) p->c.style |= MOD_ITALIC; if (bold > 0) p->c.style |= MOD_BOLD; p++; break; } italic--; bold--; if (x > x_max) break; q++; k++; } p->c.ch = p->style = 0;}static void fielded_text_print_line (CWidget * w, long b, int row){ edit_draw_proportional (w, (void (*)(void *, long, cache_type *, int, int, int)) convert_text_fielded_textbox, (int (*)(void *, long, long *, int)) calc_text_pos_fielded_textbox, -w->firstcolumn * FONT_MEAN_WIDTH, w->winid, w->width, b, row, row * FONT_PIX_PER_LINE + EDIT_TEXT_VERTICAL_OFFSET, 0, 1);}/* ->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 unsigned long edit_normal_background_color;void render_fielded_textbox (CWidget * w, int redrawall){ int row, height, isfocussed, curs, i, x; static Window last_win = 0; static int last_firstcolumn = 0; CPushFont ("editor", 0); if (redrawall) { EditExposeRedraw = 1; EditClear = 1; } if (last_win == w->winid && last_firstcolumn != w->firstcolumn) { x = 0; CSetColor (color_palette (option_text_bg_normal)); for (i = 0;; i++) { x += w->tab[i]; if (x >= w->column) break; CLine (w->winid, x + LINE_OFFSET - (last_firstcolumn * FONT_MEAN_WIDTH), 3, x + LINE_OFFSET - (last_firstcolumn * FONT_MEAN_WIDTH), (w->numlines - w->firstline) * FONT_PIX_PER_LINE); } } last_firstcolumn = w->firstcolumn; last_win = w->winid; height = w->height / FONT_PIX_PER_LINE; 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; fielded_text_print_line (w, (row + w->firstline) << 16, row); } x = 0; CSetColor (COLOR_FLAT); for (i = 0;; i++) { x += w->tab[i]; if (x >= w->column) break; CLine (w->winid, x + LINE_OFFSET - (w->firstcolumn * FONT_MEAN_WIDTH), 3, x + LINE_OFFSET - (w->firstcolumn * FONT_MEAN_WIDTH), (w->numlines - w->firstline) * FONT_PIX_PER_LINE + 3); } if ((w->numlines - w->firstline) * FONT_PIX_PER_LINE < w->height) { x = 0; CSetColor (color_palette (option_text_bg_normal)); for (i = 0;; i++) { x += w->tab[i]; if (x >= w->column) break; CLine (w->winid, x + LINE_OFFSET - (w->firstcolumn * FONT_MEAN_WIDTH), (w->numlines - w->firstline) * FONT_PIX_PER_LINE + 3, x + LINE_OFFSET - (w->firstcolumn * FONT_MEAN_WIDTH), w->height - 3); } } EditExposeRedraw = 0; EditClear = 0; (*look->render_fielded_textbox_tidbits) (w, isfocussed); CPopFont (); return;}/* 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. */static long count_fielded_textbox_lines (CWidget * wdt){ long height; height = wdt->height / FONT_PIX_PER_LINE; if (wdt->numlines - wdt->firstline < height) return wdt->numlines - wdt->firstline; return height;}static void fielded_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 fielded_text_get_selection (CWidget * w){ int type; if (selection.text) free (selection.text); selection.text = (unsigned char *) get_block (w, 0, 0, &type, &selection.len);}void selection_send (XSelectionRequestEvent * rq);int eh_fielded_textbox (CWidget * w, XEvent * xevent, CEvent * cwevent){ int handled = 0, redrawall = 0, count; switch (xevent->type) { case SelectionRequest: fielded_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: CPushFont ("editor", 0); CFocus (w); if (xevent->xbutton.button == Button1) w->cursor = (xevent->xbutton.y - 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); fielded_text_mouse_mark (w, xevent, cwevent); break; case FocusIn: case FocusOut: break; case KeyPress: cwevent->ident = w->ident; if (!(TEXTBOX_NO_KEYS & w->options)) { if (w->options & TEXTBOX_FILE_LIST && w->hook) { if (cwevent->key == XK_Insert || cwevent->key == XK_KP_Insert) { if (w->mark1 == w->mark2) { struct file_entry *f; f = (struct file_entry *) w->hook; if (f[w->cursor].options & FILELIST_TAGGED_ENTRY) f[w->cursor].options &= (0xFFFFFFFFUL - FILELIST_TAGGED_ENTRY); else f[w->cursor].options |= FILELIST_TAGGED_ENTRY; CTextboxCursorMove (w, CK_Down); handled = 1; break; } } } handled = CTextboxCursorMove (w, cwevent->command); } break; default: return 0; }/* Now draw the changed text box, count will contain the number of textlines displayed */ render_fielded_textbox (w, redrawall); count = count_fielded_textbox_lines (w);/* now update the scrollbar position */ if (w->vert_scrollbar && w->numlines) { w->vert_scrollbar->firstline = (double) 65535.0 *w->firstline / (w->numlines ? w->numlines : 1); w->vert_scrollbar->numlines = (double) 65535.0 *count / (w->numlines ? w->numlines : 1); w->vert_scrollbar->options = 0; render_scrollbar (w->vert_scrollbar); } if (w->hori_scrollbar && w->column) { w->hori_scrollbar->firstline = (double) 65535.0 *(w->firstcolumn * FONT_MEAN_WIDTH) / w->column; w->hori_scrollbar->numlines = (double) 65535.0 *(w->width - 6) / w->column; w->hori_scrollbar->options = 0; render_scrollbar (w->hori_scrollbar); } return handled;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -