📄 xtext.c
字号:
return ret;}static int inlineget_char_width (GtkXText *xtext, unsigned char *str, int *mbl_ret, int is_mb){ int mbl, width; switch (xtext->fonttype) { case FONT_1BYTE: width = xtext->fontwidth[(int)*str]; mbl = 1; break; case FONT_2BYTE: width = gdk_text_width (xtext->font, str, 2); mbl = 2; break; default: /* FONT_SET: */ if (!is_mb) { width = xtext->fontwidth[(int)*str]; mbl = 1; } else { mbl = charlen (str); if (mbl == 1) width = xtext->fontwidth[(int)*str]; else if (mbl > 0) width = gdk_text_width (xtext->font, str, mbl); else width = 0; } break; } *mbl_ret = mbl; return width;}static intfind_x (GtkXText *xtext, textentry *ent, unsigned char *text, int x, int indent){ int xx = indent; int i = 0; int col = FALSE; int nc = 0; unsigned char *orig = text; int mbl; while (*text) { mbl = 1; if ((col && isdigit (*text) && nc < 2) || (col && *text == ',' && isdigit (*(text+1)) && nc < 3)) { nc++; if (*text == ',') nc = 0; text++; } else { col = FALSE; switch (*text) { case ATTR_COLOR: col = TRUE; nc = 0; case ATTR_BEEP: case ATTR_RESET: case ATTR_REVERSE: case ATTR_BOLD: case ATTR_UNDERLINE: text++; break; default: xx += get_char_width (xtext, text, &mbl, ent->mb); text += mbl; if (xx >= x) return i + (orig - ent->str); } } i += mbl; if (text - orig >= ent->str_len) return ent->str_len; } return ent->str_len;}static intgtk_xtext_find_x (GtkXText * xtext, int x, textentry * ent, int subline, int line, int *out_of_bounds){ int indent; unsigned char *str; if (subline < 1) indent = ent->indent; else indent = xtext->indent; if (line > xtext->adj->page_size || line < 0) return 0; if (xtext->grid_offset[line] > ent->str_len) return 0; if (xtext->grid_offset[line] < 0) return 0; str = ent->str + xtext->grid_offset[line]; if (x < indent) { *out_of_bounds = 1; return (str - ent->str); } *out_of_bounds = 0; return find_x (xtext, ent, str, x, indent);}static textentry *gtk_xtext_find_char (GtkXText * xtext, int x, int y, int *off, int *out_of_bounds){ textentry *ent; int line; int subline; int win_width; gdk_window_get_size (GTK_WIDGET (xtext)->window, &win_width, 0); win_width -= MARGIN; line = (y - xtext->font->descent + xtext->pixel_offset) / xtext->fontsize; subline = xtext->pagetop_subline; ent = gtk_xtext_nth (xtext, xtext->pagetop_ent, line, &subline); if (!ent) return 0; if (off) *off = gtk_xtext_find_x (xtext, x, ent, subline, line, out_of_bounds); return ent;}static gintgtk_xtext_expose (GtkWidget * widget, GdkEventExpose * event){ GtkXText *xtext = GTK_XTEXT (widget); textentry *ent_start, *ent_end; if (xtext->skip_exposure) { xtext->skip_exposure = FALSE; return FALSE; } if (event->area.x == 0 && event->area.y == 0 && event->area.height == widget->allocation.height && event->area.width == widget->allocation.width) { gtk_xtext_render_page (xtext); return FALSE; } gdk_draw_rectangle (xtext->draw_buf, xtext->bgc, 1, event->area.x, event->area.y, event->area.width, event->area.height); ent_start = gtk_xtext_find_char (xtext, event->area.x, event->area.y, NULL, NULL); ent_end = gtk_xtext_find_char (xtext, event->area.x + event->area.width, event->area.y + event->area.height + xtext->font->descent, NULL, NULL); xtext->skip_fills = TRUE; xtext->skip_border_fills = TRUE; gtk_xtext_render_ents (xtext, ent_start, ent_end, TRUE); xtext->skip_fills = FALSE; xtext->skip_border_fills = FALSE; gtk_xtext_draw_sep (xtext, -1); return FALSE;}static voidgtk_xtext_selection_render (GtkXText *xtext, textentry *start_ent, int start_offset, textentry *end_ent, int end_offset){ textentry *ent, *ent2; xtext->skip_border_fills = TRUE; xtext->skip_stamp = TRUE; /* marking downward? */ if (xtext->last_ent_start == start_ent && xtext->last_offset_start == start_offset) { ent = start_ent; while (ent) { if (ent == xtext->last_ent_end) { gtk_xtext_render_ents (xtext, ent, end_ent, TRUE); break; } if (ent == end_ent) { gtk_xtext_render_ents (xtext, ent, xtext->last_ent_end, TRUE); break; } ent = ent->next; } } /* marking upward? */ else if (xtext->last_ent_end == end_ent && xtext->last_offset_end == end_offset) { ent = start_ent; ent2 = xtext->last_ent_start; do { if (ent == xtext->last_ent_start) { gtk_xtext_render_ents (xtext, start_ent, ent, TRUE); break; } if (ent2 == start_ent) { gtk_xtext_render_ents (xtext, xtext->last_ent_start, start_ent, TRUE); break; } if (ent) ent = ent->next; if (ent2) ent2 = ent2->next; } while (ent || ent2); } else /* cross-over mark */ { gtk_xtext_render_ents (xtext, xtext->last_ent_start, xtext->last_ent_end, TRUE); gtk_xtext_render_ents (xtext, start_ent, end_ent, TRUE); } xtext->last_ent_start = start_ent; xtext->last_ent_end = end_ent; xtext->last_offset_start = start_offset; xtext->last_offset_end = end_offset; xtext->skip_border_fills = FALSE; xtext->skip_stamp = FALSE;}static voidgtk_xtext_selection_draw (GtkXText * xtext, GdkEventMotion * event){ textentry *ent; textentry *ent_end; textentry *ent_start; int offset_start; int offset_end; int low_x; int low_y; int high_x; int high_y; int tmp; if (xtext->select_start_y > xtext->select_end_y) { low_x = xtext->select_end_x; low_y = xtext->select_end_y; high_x = xtext->select_start_x; high_y = xtext->select_start_y; } else { low_x = xtext->select_start_x; low_y = xtext->select_start_y; high_x = xtext->select_end_x; high_y = xtext->select_end_y; } ent_start = gtk_xtext_find_char (xtext, low_x, low_y, &offset_start, &tmp); ent_end = gtk_xtext_find_char (xtext, high_x, high_y, &offset_end, &tmp); if (ent_start && !ent_end) { ent_end = xtext->text_last; offset_end = ent_end->str_len; } if (!ent_start || !ent_end) { if (xtext->adj->value != xtext->old_value) gtk_xtext_render_page (xtext); return; } gtk_xtext_selection_clear (xtext); /* marking less than a complete line? */ if (ent_start == ent_end) { ent_start->mark_start = MIN (offset_start, offset_end); ent_start->mark_end = MAX (offset_end, offset_start); if (offset_start == offset_end) { if (xtext->fonttype == FONT_SET) { int mbl; mbl = charlen (ent_start->str + offset_start); if (0 < mbl) ent_start->mark_end += mbl; } else { ent_start->mark_end++; } } } else { ent_start->mark_start = offset_start; ent_start->mark_end = ent_start->str_len; if (offset_end != 0) { ent_end->mark_start = 0; ent_end->mark_end = offset_end; } } if (ent_start != ent_end) { ent = ent_start->next; while (ent && ent != ent_end) { ent->mark_start = 0; ent->mark_end = ent->str_len; ent = ent->next; } } /* has the selection changed? Dont render unless necessary */ if (xtext->last_ent_start == ent_start && xtext->last_ent_end == ent_end && xtext->last_offset_start == offset_start && xtext->last_offset_end == offset_end) return; gtk_xtext_selection_render (xtext, ent_start, offset_start, ent_end, offset_end);}static gintgtk_xtext_scrolldown_timeout (GtkXText * xtext){ int p_y, win_height; gdk_window_get_pointer (GTK_WIDGET (xtext)->window, 0, &p_y, 0); gdk_window_get_size (GTK_WIDGET (xtext)->window, 0, &win_height); if (p_y > win_height && xtext->adj->value < (xtext->adj->upper - xtext->adj->page_size)) { xtext->adj->value++; gtk_adjustment_changed (xtext->adj); gtk_xtext_render_page (xtext); return 1; } xtext->scroll_tag = 0; return 0;}static gintgtk_xtext_scrollup_timeout (GtkXText * xtext){ int p_y; gdk_window_get_pointer (GTK_WIDGET (xtext)->window, 0, &p_y, 0); if (p_y < 0 && xtext->adj->value > 0.0) { xtext->adj->value--; gtk_adjustment_changed (xtext->adj); gtk_xtext_render_page (xtext); return 1; } xtext->scroll_tag = 0; return 0;}static voidgtk_xtext_selection_update (GtkXText * xtext, GdkEventMotion * event, int p_y){ int win_height; int moved; gdk_window_get_size (GTK_WIDGET (xtext)->window, 0, &win_height); /* selecting past top of window, scroll up! */ if (p_y < 0 && xtext->adj->value >= 0) { if (!xtext->scroll_tag) xtext->scroll_tag = g_timeout_add (100, (GSourceFunc) gtk_xtext_scrollup_timeout, xtext); return; } /* selecting past bottom of window, scroll down! */ if (p_y > win_height && xtext->adj->value < (xtext->adj->upper - xtext->adj->page_size)) { if (!xtext->scroll_tag) xtext->scroll_tag = g_timeout_add (100, (GSourceFunc) gtk_xtext_scrolldown_timeout, xtext); return; } moved = xtext->adj->value - xtext->select_start_adj; xtext->select_start_y -= (moved * xtext->fontsize); xtext->select_start_adj = xtext->adj->value; gtk_xtext_selection_draw (xtext, event);}static char *gtk_xtext_get_word (GtkXText * xtext, int x, int y, textentry ** ret_ent, int *ret_off, int *ret_len){ textentry *ent; int offset; unsigned char *str; unsigned char *word; int len; int out_of_bounds; ent = gtk_xtext_find_char (xtext, x, y, &offset, &out_of_bounds); if (!ent) return 0; if (out_of_bounds) return 0; if (offset == ent->str_len) return 0; if (offset < 1) return 0; offset--; str = ent->str + offset; while (!is_del (*str) && str != ent->str) str--; word = str + 1; len = 0; str = word; while (!is_del (*str) && len != ent->str_len) { str++; len++; } if (ret_ent) *ret_ent = ent; if (ret_off) *ret_off = word - ent->str; if (ret_len) *ret_len = str - word; return gtk_xtext_strip_color (word, len, xtext->scratch_buffer, NULL, xtext->fonttype, NULL);}#ifdef MOTION_MONITORstatic gintgtk_xtext_leave_notify (GtkWidget * widget, GdkEventCrossing * event){ GtkXText *xtext = GTK_XTEXT (widget); if (xtext->cursor_hand) { xtext->hilight_start = -1; xtext->hilight_end = -1; xtext->cursor_hand = FALSE; gdk_window_set_cursor (widget->window, 0); xtext->skip_border_fills = TRUE; xtext->do_underline_fills_only = TRUE; gtk_xtext_render_ents (xtext, xtext->hilight_ent, NULL, FALSE); xtext->skip_border_fills = FALSE; xtext->do_underline_fills_only = FALSE; xtext->hilight_ent = NULL; } return FALSE;}#endifstatic gintgtk_xtext_motion_notify (GtkWidget * widget, GdkEventMotion * event){ GtkXText *xtext = GTK_XTEXT (widget); int tmp, x, y, offset, len; unsigned char *word; textentry *word_ent, *old_ent; gdk_window_get_pointer (widget->window, &x, &y, 0); if (xtext->moving_separator) { if (x < (3 * widget->allocation.width) / 5 && x > 15) { tmp = xtext->indent; xtext->indent = x; gtk_xtext_fix_indent (xtext); if (tmp != xtext->indent) { gtk_xtext_recalc_widths (xtext, FALSE); if (xtext->scrollbar_down) gtk_adjustment_set_value (xtext->adj, xtext->adj->upper - xtext->adj->page_size); if (!xtext->io_tag) xtext->io_tag = g_timeout_add (REFRESH_TIMEOUT, (GSourceFunc) gtk_xtext_adjustment_timeout, xtext); } } return FALSE; } if (xtext->button_down) { gtk_grab_add (widget); /*gdk_pointer_grab (widget->window, TRUE, GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_MOTION_MASK, NULL, NULL, 0);*/ xtext->select_end_x = x; xtext->select_end_y = y; gtk_xtext_selection_update (xtext, event, y); return FALSE; }#ifdef MOTION_MONITOR if (xtext->urlcheck_function == NULL) return FALSE; word = gtk_xtext_get_word (xtext, x, y, &word_ent, &offset, &len); if (word) { if (xtext->urlcheck_function (GTK_WIDGET (xtext), word) > 0) { if (!xtext->cursor_hand || xtext->hilight_ent != word_ent || xtext->hilight_start != offset || xtext->hilight_end != offset + len) { if (!xtext->cursor_hand) { gdk_window_set_cursor (GTK_WIDGET (xtext)->window, xtext->hand_cursor); xtext->cursor_hand = TRUE; } old_ent = xtext->hilight_ent; xtext->hilight_ent = word_ent; xtext->hilight_start = offset; xtext->hilight_end = offset + len; xtext->skip_border_fills = TRUE; xtext->do_underline_fills_only = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -