📄 view.c
字号:
#ifdef G { int i = 0; while (t2 > t1) { FWD_UTF_8(t1); i++; } return i; }#endif}struct line_info *format_text(unsigned char *text, int width, int wrap){ struct line_info *ln = DUMMY; int lnn = 0; unsigned char *b = text; int sk, ps = 0; while (*text) { unsigned char *s; if (*text == '\n') { sk = 1; put: if (!(lnn & (ALLOC_GR-1))) { if ((unsigned)lnn > MAXINT / sizeof(struct line_info) - ALLOC_GR) overalloc(); ln = mem_realloc(ln, (lnn + ALLOC_GR) * sizeof(struct line_info)); } ln[lnn].st = b; ln[lnn++].en = text; b = text += sk; continue; } if (!wrap || utf8_diff(text, b) < width) { if (!F) text++;#ifdef G else FWD_UTF_8(text);#endif continue; } for (s = text; s >= b; s--) if (*s == ' ') { text = s; if (wrap == 2) { *s = '\n'; for (s++; *s; s++) if (*s == '\n') { if (s[1] != '\n') *s = ' '; break; } } sk = 1; goto put; } sk = 0; goto put; } if (ps < 2) { ps++; sk = 0; goto put; } ln[lnn - 1].st = ln[lnn - 1].en = NULL; return ln;}int _area_cursor(struct form_control *form, struct form_state *fs){ struct line_info *ln; int q = 0; if ((ln = format_text(fs->value, form->cols, form->wrap))) { int x, y; for (y = 0; ln[y].st; y++) if (fs->value + fs->state >= ln[y].st && fs->value + fs->state < ln[y].en + (ln[y+1].st != ln[y].en)) { x = utf8_diff(fs->value + fs->state, ln[y].st); if (form->wrap && x == form->cols) x--; if (x >= form->cols + fs->vpos) fs->vpos = x - form->cols + 1; if (x < fs->vpos) fs->vpos = x; if (y >= form->rows + fs->vypos) fs->vypos = y - form->rows + 1; if (y < fs->vypos) fs->vypos = y; x -= fs->vpos; y -= fs->vypos; q = y * form->cols + x; break; } mem_free(ln); } return q;}void draw_link(struct terminal *t, struct f_data_c *scr, int l){ struct link *link = &scr->f_data->links[l]; int xp = scr->xp; int yp = scr->yp; int xw = scr->xw; int yw = scr->yw; int vx, vy; struct view_state *vs = scr->vs; int f = 0; vx = vs->view_posx; vy = vs->view_pos; if (scr->link_bg) { internal("link background not empty"); mem_free(scr->link_bg); } if (l == -1) return; switch (link->type) { int i; int q; case L_LINK: case L_CHECKBOX: case L_BUTTON: case L_SELECT: case L_FIELD: case L_AREA: q = 0; if (link->type == L_FIELD) { struct form_state *fs = find_form_state(scr, link->form); if (fs) q = fs->state - fs->vpos; /*else internal("link has no form control");*/ } else if (link->type == L_AREA) { struct form_state *fs = find_form_state(scr, link->form); if (fs) q = _area_cursor(link->form, fs); /*else internal("link has no form control");*/ } if ((unsigned)link->n > MAXINT / sizeof(struct link_bg)) overalloc(); scr->link_bg = mem_alloc(link->n * sizeof(struct link_bg)); scr->link_bg_n = link->n; for (i = 0; i < link->n; i++) { int x = link->pos[i].x + xp - vx; int y = link->pos[i].y + yp - vy; if (x >= xp && y >= yp && x < xp+xw && y < yp+yw) { unsigned co; co = get_char(t, x, y); if (scr->link_bg) scr->link_bg[i].x = x, scr->link_bg[i].y = y, scr->link_bg[i].c = co; if (t->spec->braille && !vs->brl_in_field) goto skip_link; if (!f || (link->type == L_CHECKBOX && i == 1) || (link->type == L_BUTTON && i == 2) || ((link->type == L_FIELD || link->type == L_AREA) && i == q)) { int xx = x, yy = y; if (link->type != L_FIELD && link->type != L_AREA) { if (((co >> 8) & 0x38) != (link->sel_color & 0x38)) xx = xp + xw - 1, yy = yp + yw - 1; } set_cursor(t, x, y, xx, yy); set_window_ptr(scr->ses->win, x, y); f = 1; } skip_link:; set_color(t, x, y, /*((link->sel_color << 3) | (co >> 11 & 7)) << 8*/ link->sel_color << 8); } else scr->link_bg[i].x = scr->link_bg[i].y = scr->link_bg[i].c = -1; } break; default: internal("bad link type"); }}void free_link(struct f_data_c *scr){ if (scr->link_bg) { mem_free(scr->link_bg); scr->link_bg = NULL; } scr->link_bg_n = 0;}void clear_link(struct terminal *t, struct f_data_c *scr){ if (scr->link_bg) { int i; for (i = scr->link_bg_n - 1; i >= 0; i--) set_char(t, scr->link_bg[i].x, scr->link_bg[i].y, scr->link_bg[i].c); free_link(scr); }}int get_range(struct f_data *f, int y, int yw, int l, struct search **s1, struct search **s2){ int i; *s1 = *s2 = NULL; for (i = y < 0 ? 0 : y; i < y + yw && i < f->y; i++) { if (f->slines1[i] && (!*s1 || f->slines1[i] < *s1)) *s1 = f->slines1[i]; if (f->slines2[i] && (!*s2 || f->slines2[i] > *s2)) *s2 = f->slines2[i]; } if (!*s1 || !*s2) return -1; *s1 -= l; if (*s1 < f->search) *s1 = f->search; if (*s2 + l > f->search + f->nsearch) *s2 = f->search + f->nsearch - l; if (*s1 > *s2) *s1 = *s2 = NULL; if (!*s1 || !*s2) return -1; return 0;}int is_in_range(struct f_data *f, int y, int yw, unsigned char *txt, int *min, int *max){ int found = 0; int l = strlen(txt); struct search *s1, *s2; if (min || max) *min = MAXINT, *max = 0; if (get_range(f, y, yw, l, &s1, &s2)) return 0; for (; s1 <= s2; s1++) { int i; if (s1->c != txt[0]) { unable_to_handle_kernel_paging_request___oops: continue; } for (i = 1; i < l; i++) if (s1[i].c != txt[i]) goto unable_to_handle_kernel_paging_request___oops; for (i = 0; i < l; i++) if (s1[i].y >= y && s1[i].y < y + yw && s1[i].n) goto in_view; continue; in_view: if (!min && !max) return 1; found = 1; for (i = 0; i < l; i++) if (s1[i].n) { if (s1[i].x < *min) *min = s1[i].x; if (s1[i].x + s1[i].n > *max) *max = s1[i].x + s1[i].n; } } return found;}void get_searched(struct f_data_c *scr, struct point **pt, int *pl){ int xp = scr->xp; int yp = scr->yp; int xw = scr->xw; int yw = scr->yw; int vx = scr->vs->view_posx; int vy = scr->vs->view_pos; struct search *s1, *s2; int l; unsigned char c; struct point *points = DUMMY; int len = 0; unsigned char *w = scr->ses->search_word; if (!w || !*w) return; get_search_data(scr->f_data); l = strlen(w); c = w[0]; if (get_range(scr->f_data, scr->vs->view_pos, scr->yw, l, &s1, &s2)) goto ret; for (; s1 <= s2; s1++) { int i, j; if (s1->c != c) { c:continue; } for (i = 1; i < l; i++) if (s1[i].c != w[i]) goto c; for (i = 0; i < l && (!scr->ses->term->spec->braille || i < 1); i++) for (j = 0; j < s1[i].n; j++) { int x = s1[i].x + j + xp - vx; int y = s1[i].y + yp - vy; if (x >= xp && y >= yp && x < xp + xw && y < yp + yw) { /*unsigned co; co = get_char(t, x, y); co = ((co >> 3) & 0x0700) | ((co << 3) & 0x3800); set_color(t, x, y, co);*/ if (!(len & (ALLOC_GR - 1))) { if ((unsigned)len > MAXINT / sizeof(struct point) - ALLOC_GR) overalloc(); points = mem_realloc(points, sizeof(struct point) * (len + ALLOC_GR)); } points[len].x = s1[i].x + j; points[len++].y = s1[i].y; } } } ret: *pt = points; *pl = len;}void draw_searched(struct terminal *t, struct f_data_c *scr){ int xp = scr->xp; int yp = scr->yp; int vx = scr->vs->view_posx; int vy = scr->vs->view_pos; struct point *pt; int len, i; if (!scr->ses->search_word || !scr->ses->search_word[0]) return; get_searched(scr, &pt, &len); for (i = 0; i < len; i++) { int x = pt[i].x + xp - vx, y = pt[i].y + yp - vy; unsigned co; co = get_char(t, x, y); co = ((co >> 3) & 0x0700) | ((co << 3) & 0x3800); set_color(t, x, y, co); } mem_free(pt);}void draw_current_link(struct terminal *t, struct f_data_c *scr){ draw_link(t, scr, scr->vs->current_link); draw_searched(t, scr);}struct link *get_first_link(struct f_data_c *f){ int i; struct link *l = f->f_data->links + f->f_data->nlinks; for (i = f->vs->view_pos; i < f->vs->view_pos + f->yw; i++) if (i >= 0 && i < f->f_data->y && f->f_data->lines1[i] && f->f_data->lines1[i] < l) l = f->f_data->lines1[i]; if (l == f->f_data->links + f->f_data->nlinks) l = NULL; return l;}struct link *get_last_link(struct f_data_c *f){ int i; struct link *l = NULL; for (i = f->vs->view_pos; i < f->vs->view_pos + f->yw; i++) if (i >= 0 && i < f->f_data->y && f->f_data->lines2[i] > l) l = f->f_data->lines2[i]; return l;}void fixup_select_state(struct form_control *fc, struct form_state *fs){ int inited = 0; int i; retry: if (fs->state >= 0 && fs->state < fc->nvalues && !strcmp(fc->values[fs->state], fs->value)) return; for (i = 0; i < fc->nvalues; i++) { if (!strcmp(fc->values[i], fs->value)) { fs->state = i; return; } } if (!inited) { init_ctrl(fc, fs); inited = 1; goto retry; } fs->state = 0; if (fs->value) mem_free(fs->value); if (fc->nvalues) fs->value = stracpy(fc->values[0]); else fs->value = stracpy("");}void init_ctrl(struct form_control *form, struct form_state *fs){ if (fs->value) mem_free(fs->value), fs->value = NULL; switch (form->type) { case FC_TEXT: case FC_PASSWORD: case FC_TEXTAREA: fs->value = stracpy(form->default_value); fs->state = strlen(form->default_value); fs->vpos = 0; break; case FC_FILE: fs->value = stracpy(""); fs->state = 0; fs->vpos = 0; break; case FC_CHECKBOX: case FC_RADIO: fs->state = form->default_state; break; case FC_SELECT: fs->value = stracpy(form->default_value); fs->state = form->default_state; fixup_select_state(form, fs); break; }}struct form_state *find_form_state(struct f_data_c *f, struct form_control *form){ struct view_state *vs = f->vs; struct form_state *fs; int n = form->g_ctrl_num; if (n < vs->form_info_len) fs = &vs->form_info[n]; else { if ((unsigned)n > MAXINT / sizeof(struct form_state) - 1) overalloc(); fs = mem_realloc(vs->form_info, (n + 1) * sizeof(struct form_state)); vs->form_info = fs; memset(fs + vs->form_info_len, 0, (n + 1 - vs->form_info_len) * sizeof(struct form_state)); vs->form_info_len = n + 1; fs = &vs->form_info[n]; } if (fs->form_num == form->form_num && fs->ctrl_num == form->ctrl_num && fs->g_ctrl_num == form->g_ctrl_num && /*fs->position == form->position &&*/ fs->type == form->type) return fs; if (fs->value) mem_free(fs->value); memset(fs, 0, sizeof(struct form_state)); fs->form_num = form->form_num; fs->ctrl_num = form->ctrl_num; fs->g_ctrl_num = form->g_ctrl_num; fs->position = form->position; fs->type = form->type; init_ctrl(form, fs); return fs;}void draw_form_entry(struct terminal *t, struct f_data_c *f, struct link *l){ int xp = f->xp; int yp = f->yp; int xw = f->xw; int yw = f->yw; struct view_state *vs = f->vs; int vx = vs->view_posx; int vy = vs->view_pos; struct form_state *fs; struct form_control *form = l->form; int i, x, y; if (!form) { internal("link %d has no form", (int)(l - f->f_data->links)); return; } if (!(fs = find_form_state(f, form))) return; switch (form->type) { unsigned char *s; struct line_info *ln, *lnx; int sl; 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; if (!l->n) break; x = l->pos[0].x + xp - vx; y = l->pos[0].y + yp - vy; for (i = 0; i < form->size; i++, x++) if (x >= xp && y >= yp && x < xp+xw && y < yp+yw) { if (fs->value && i >= -fs->vpos && (size_t)i < strlen(fs->value) - fs->vpos) set_only_char(t, x, y, form->type != FC_PASSWORD ? fs->value[i + fs->vpos] : '*'); else set_only_char(t, x, y, '_'); } break; case FC_TEXTAREA: if (!l->n) break; x = l->pos[0].x + xp - vx; y = l->pos[0].y + yp - vy; _area_cursor(form, fs); if (!(lnx = format_text(fs->value, form->cols, form->wrap))) break; ln = lnx; sl = fs->vypos; while (ln->st && sl) sl--, ln++; for (; ln->st && y < l->pos[0].y + yp - vy + form->rows; ln++, y++) { for (i = 0; i < form->cols; i++) { if (x+i >= xp && y >= yp && x+i < xp+xw && y < yp+yw) { if (fs->value && i >= -fs->vpos && i + fs->vpos < ln->en - ln->st) set_only_char(t, x+i, y, ln->st[i + fs->vpos]); else set_only_char(t, x+i, y, '_'); } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -