📄 view_gr.c
字号:
/* view_gr.c * (c) 2002 Mikulas Patocka * This file is a part of the Links program, released under GPL. */#include "cfg.h"#ifdef G#include "links.h"int *highlight_positions = NULL;int *highlight_lengths = NULL;int n_highlight_positions = 0;static int root_x = 0;static int root_y = 0;void g_get_search_data(struct f_data *f);struct g_object_text * g_find_nearest_object(struct f_data *f, int x, int y);int g_find_text_pos(struct g_object_text *, int);void g_get_search(struct f_data *, unsigned char *);void get_parents_sub(struct g_object *, struct g_object *);void g_set_current_link(struct f_data_c *, struct g_object_text *, int, int, int);void process_sb_event(struct f_data_c *, int, int);void process_sb_move(struct f_data_c *, int);static inline int ev_in_rect(struct event *, int, int, int, int);int skip_link(struct f_data_c *, int);int lr_link(struct f_data_c *, int);int g_next_link(struct f_data_c *, int);void unset_link(struct f_data_c *);void get_searched_sub(struct g_object *, struct g_object *);void find_nearest_sub(struct g_object *, struct g_object *);void find_next_sub(struct g_object *, struct g_object *);void g_find_next_str(struct f_data *);static int previous_link=-1; /* for mouse event handlers */void g_draw_background(struct graphics_device *dev, struct background *bg, int x, int y, int xw, int yw){ if (xw > 4096) { int halfx = x + xw / 2; if (dev->clip.x1 < halfx) g_draw_background(dev, bg, x, y, halfx - x, yw); if (dev->clip.x2 > halfx) g_draw_background(dev, bg, halfx, y, x + xw - halfx, yw); return; } if (yw > 4096) { int halfy = y + yw / 2; if (dev->clip.y1 < halfy) g_draw_background(dev, bg, x, y, xw, halfy - y); if (dev->clip.y2 > halfy) g_draw_background(dev, bg, x, halfy, xw, y + yw - halfy); return; } if (bg->img) { img_draw_decoded_image(dev, bg->u.img, x, y, xw, yw, x - root_x, y - root_y); } else { drv->fill_area(dev, x, y, x + xw, y + yw , dip_get_color_sRGB(bg->u.sRGB)); }}void g_release_background(struct background *bg){ if (bg->img) img_release_decoded_image(bg->u.img); mem_free(bg);}void g_dummy_draw(struct f_data_c *fd, struct g_object *t, int x, int y){}void g_tag_destruct(struct g_object *t){ mem_free(t);}void g_dummy_mouse(struct f_data_c *fd, struct g_object *a, int x, int y, int b){}int print_all_textarea = 0;/* returns byte index of x in t->text *//* x is relative coordinate within the text (can be out of bounds) */int g_find_text_pos(struct g_object_text *t, int x){ int i=0, p=0; unsigned char *text=t->text; int ox, oy; get_object_pos((struct g_object *)t, &ox, &oy); x -= ox; if (x<0) x=0; if (x>t->xw) x=t->xw; while(1) { unsigned c; unsigned char *old_text; int w; old_text=text; GET_UTF_8(text, c); if (!c) break; w=g_char_width(t->style, c); if (/*p<x&&*/x<(p+(w>>1))) break; p+=w; i+=text-old_text; if (p>=x) break; } return i;}void g_text_draw(struct f_data_c *fd, struct g_object_text *t, int x, int y){ struct form_control *form; struct form_state *fs; struct link *link = t->link_num >= 0 ? fd->f_data->links + t->link_num : NULL; int l; int ll; int i, j; int yy; int cur; struct line_info *ln, *lnx; if (link && ((form = link->form)) && ((fs = find_form_state(fd, form)))) { switch (form->type) { struct style *inv; int in; case FC_RADIO: if (link && fd->active && fd->vs->g_display_link && fd->vs->current_link == link - fd->f_data->links) inv = g_invert_style(t->style), in = 1; else inv = t->style, in = 0; g_print_text(drv, fd->ses->term->dev, x, y, inv, fs->state ? "[X]" : "[ ]", NULL); if (in) g_free_style(inv); return; case FC_CHECKBOX: if (link && fd->active && fd->vs->g_display_link && fd->vs->current_link == link - fd->f_data->links) inv = g_invert_style(t->style), in = 1; else inv = t->style, in = 0; g_print_text(drv, fd->ses->term->dev, x, y, inv, fs->state ? "[X]" : "[ ]", NULL); if (in) g_free_style(inv); return; case FC_SELECT: if (link && fd->active && fd->vs->g_display_link && fd->vs->current_link == link - fd->f_data->links) inv = g_invert_style(t->style), in = 1; else inv = t->style, in = 0; fixup_select_state(form, fs); l = 0; if (fs->state < form->nvalues) g_print_text(drv, fd->ses->term->dev, x, y, inv, form->labels[fs->state], &l); while (l < t->xw) g_print_text(drv, fd->ses->term->dev, x + l, y, inv, "_", &l); if (in) g_free_style(inv); return; case FC_TEXT: case FC_PASSWORD: case FC_FILE: /* if (fs->state >= fs->vpos + form->size) fs->vpos = fs->state - form->size + 1; if (fs->state < fs->vpos) fs->vpos = fs->state; */ while ((size_t)fs->vpos < strlen(fs->value) && utf8_diff(fs->value + fs->state, fs->value + fs->vpos) >= form->size) { unsigned char *p = fs->value + fs->vpos; FWD_UTF_8(p); fs->vpos = p - fs->value; } while (fs->vpos > fs->state) { unsigned char *p = fs->value + fs->vpos; BACK_UTF_8(p, fs->value); fs->vpos = p - fs->value; } l = 0; i = 0; ll = strlen(fs->value); while (l < t->xw) { struct style *st = t->style; int sm = 0; unsigned char tx[11]; if (fs->state == fs->vpos + i && t->link_num == fd->vs->current_link && fd->ses->locked_link) { st = g_invert_style(t->style); sm = 1; } tx[1] = 0; if (fs->vpos + i >= ll) tx[0] = '_', tx[1] = 0, i++; else { unsigned char *p = fs->value + fs->vpos + i; unsigned char *pp = p; FWD_UTF_8(p); if (p - pp > 10) { i++; goto xy; } memcpy(tx, pp, p - pp); tx[p - pp] = 0; i += strlen(tx); if (form->type == FC_PASSWORD) xy:tx[0] = '*'; } g_print_text(drv, fd->ses->term->dev, x + l, y, st, tx, &l); if (sm) g_free_style(st); } return; case FC_TEXTAREA: cur = _area_cursor(form, fs); if (!(lnx = format_text(fs->value, form->cols, form->wrap))) break; ln = lnx; yy = y - t->link_order * t->style->height; for (j = 0; j < fs->vypos; j++) if (ln->st) ln++; for (j = 0; j < form->rows; j++) { unsigned char *pp = ln->st; int xx = fs->vpos; while (pp < ln->en && xx > 0) { FWD_UTF_8(pp); xx--; } if (cur >= 0 && cur < form->cols && t->link_num == fd->vs->current_link && fd->ses->locked_link && fd->active) { unsigned char tx[11]; int xx = x; if (print_all_textarea || j == t->link_order) while (xx < x + t->xw) { struct style *st = t->style; unsigned char *ppp = pp; if (ln->st && pp < ln->en) { FWD_UTF_8(pp); memcpy(tx, ppp, pp - ppp); tx[pp - ppp] = 0; } else { tx[0] = '_'; tx[1] = 0; } if (!cur) { st = g_invert_style(t->style); } g_print_text(drv, fd->ses->term->dev, xx, yy + j * t->style->height, st, tx, &xx); if (!cur) { g_free_style(st); } cur--; } else cur -= form->cols; } else { if (print_all_textarea || j == t->link_order) { int aa; unsigned char *a; struct rect old; if (ln->st && pp < ln->en) a = memacpy(pp, ln->en - pp); else a = stracpy(""); for (aa = 0; aa < form->cols; aa += 4) add_to_strn(&a, "____"); restrict_clip_area(fd->ses->term->dev, &old, x, 0, x + t->xw, fd->ses->term->dev->size.y2); g_print_text(drv, fd->ses->term->dev, x, yy + j * t->style->height, t->style, a, NULL); drv->set_clip_area(fd->ses->term->dev, &old); mem_free(a); } cur -= form->cols; } if (ln->st) ln++; } mem_free(lnx); return; } } if (link && fd->active && fd->vs->g_display_link && fd->vs->current_link == link - fd->f_data->links) { struct style *inv; inv = g_invert_style(t->style); g_print_text(drv, fd->ses->term->dev, x, y, inv, t->text, NULL); g_free_style(inv); } else if ( (!fd->f_data->hlt_len) && (!highlight_positions || !n_highlight_positions)) { prn: g_print_text(drv, fd->ses->term->dev, x, y, t->style, t->text, NULL); } else { size_t tlen = strlen(t->text); int found; int start = t->srch_pos; int end = t->srch_pos + tlen; int hl_start, hl_len; unsigned char *mask; unsigned char *tx; int txl; int pmask; size_t ii; struct style *inv; intersect(fd->f_data->hlt_pos, fd->f_data->hlt_len, start, tlen, &hl_start, &hl_len); #define B_EQUAL(t, m) (highlight_positions[t] + highlight_lengths[t] > start && highlight_positions[t] < end)#define B_ABOVE(t, m) (highlight_positions[t] >= end) BIN_SEARCH(n_highlight_positions, B_EQUAL, B_ABOVE, *, found); mask = mem_calloc(tlen); if (found != -1) { while (found > 0 && B_EQUAL(found - 1, *)) found--; while (found < n_highlight_positions && !B_ABOVE(found, *)) { int pos = highlight_positions[found] - t->srch_pos; int ii = 0; for (ii = 0; ii < highlight_lengths[found]; ii++) { if (pos >= 0 && (size_t)pos < tlen) mask[pos] = 1; pos++; } found++; } if (hl_len) goto hl; } else if (hl_len) { int x; hl: for (x = 0; x < hl_len; x++) mask[hl_start - t->srch_pos + x] ^= 1; /*memset(mask+hl_start-t->srch_pos, 1, hl_len*sizeof(char));*/ } else { mem_free(mask); goto prn; } inv = g_invert_style(t->style); tx = init_str();; txl = 0; pmask = -1; for (ii = 0; ii < tlen; ii++) { if (mask[ii] != pmask) { g_print_text(drv, fd->ses->term->dev, x, y, pmask ? inv : t->style, tx, &x); mem_free(tx); tx = init_str(); txl = 0; } add_chr_to_str(&tx, &txl, t->text[ii]); pmask = mask[ii]; } g_print_text(drv, fd->ses->term->dev, x, y, pmask ? inv : t->style, tx, &x); mem_free(tx); g_free_style(inv); mem_free(mask); }}void g_text_destruct(struct g_object_text *t){ release_image_map(t->map); g_free_style(t->style); mem_free(t);}void g_line_draw(struct f_data_c *fd, struct g_object_line *l, int xx, int yy){ struct graphics_device *dev = fd->ses->term->dev; int i; int x = 0; for (i = 0; i < l->n_entries; i++) { struct g_object *o = (struct g_object *)l->entries[i]; if (o->x > x) g_draw_background(dev, l->bg, xx + x, yy, o->x - x, l->yw); if (o->y > 0) g_draw_background(dev, l->bg, xx + o->x, yy, o->xw, o->y); if (o->y + o->yw < l->yw) g_draw_background(dev, l->bg, xx + o->x, yy + o->y + o->yw, o->xw, l->yw - o->y - o->yw); o->draw(fd, o, xx + o->x, yy + o->y); x = o->x + o->xw; } if (x < l->xw) g_draw_background(dev, l->bg, xx + x, yy, l->xw - x, l->yw);}void g_line_destruct(struct g_object_line *l){ int i; for (i = 0; i < l->n_entries; i++) l->entries[i]->destruct(l->entries[i]); mem_free(l);}void g_line_bg_destruct(struct g_object_line *l){ g_release_background(l->bg); g_line_destruct(l);}void g_line_get_list(struct g_object_line *l, void (*f)(struct g_object *parent, struct g_object *child)){ int i; for (i = 0; i < l->n_entries; i++) f((struct g_object *)l, l->entries[i]);}#define OBJ_EQ(n, b) (*a[n]).y <= (b) && (*a[n]).y + (*a[n]).yw > (b)#define OBJ_ABOVE(n, b) (*a[n]).y > (b)static inline struct g_object **g_find_line(struct g_object **a, int n, int p){ int res = -1; BIN_SEARCH(n, OBJ_EQ, OBJ_ABOVE, p, res); if (res == -1) return NULL; return &a[res];}void g_area_draw(struct f_data_c *fd, struct g_object_area *a, int xx, int yy){ struct g_object **i; int rx = root_x, ry = root_y; int y1 = fd->ses->term->dev->clip.y1 - yy; int y2 = fd->ses->term->dev->clip.y2 - yy - 1; struct g_object **l1; struct g_object **l2; if (fd->ses->term->dev->clip.y1 == fd->ses->term->dev->clip.y2 || fd->ses->term->dev->clip.x1 == fd->ses->term->dev->clip.x2) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -