📄 bfu.c
字号:
/* bfu.c * (c) 2002 Mikulas Patocka * This file is a part of the Links program, released under GPL. */#include "links.h"int menu_font_size=G_BFU_DEFAULT_FONT_SIZE;unsigned G_BFU_FG_COLOR;unsigned G_BFU_BG_COLOR;unsigned G_SCROLL_BAR_AREA_COLOR;unsigned G_SCROLL_BAR_BAR_COLOR;unsigned G_SCROLL_BAR_FRAME_COLOR;/* prototypes */int is_in_str(unsigned char *, int);void select_menu(struct terminal *, struct menu *);void count_menu_size(struct terminal *, struct menu *);void scroll_menu(struct menu *, int);void display_menu_txt(struct terminal *, struct menu *);void display_menu_item_gfx(struct terminal *, struct menu *, int);void display_menu_gfx(struct terminal *, struct menu *);void display_mainmenu(struct terminal *, struct mainmenu *);void select_mainmenu(struct terminal *, struct mainmenu *);void u_display_dlg_item(struct terminal *, void *);void x_display_dlg_item(struct dialog_data *, struct dialog_item_data *, int);void dlg_select_item(struct dialog_data *, struct dialog_item_data *);void dlg_set_history(struct dialog_item_data *);int dlg_mouse(struct dialog_data *, struct dialog_item_data *, struct event *);void redraw_dialog_items(struct terminal *, struct dialog_data *);int dlg_is_braille_moving(struct dialog_data *);void redraw_dialog(struct terminal *, struct dialog_data *);void tab_compl(struct terminal *, unsigned char *, struct window *);void do_tab_compl(struct terminal *, struct list_head *, struct window *);int msg_box_button(struct dialog_data *, struct dialog_item_data *);int input_field_cancel(struct dialog_data *, struct dialog_item_data *);int input_field_ok(struct dialog_data *, struct dialog_item_data *);struct memory_list *getml(void *p, ...){ struct memory_list *ml; va_list ap; int n = 0; void *q = p; va_start(ap, p); while (q) { if (n == MAXINT) overalloc(); n++, q = va_arg(ap, void *); } if ((unsigned)n > (MAXINT - sizeof(struct memory_list)) / sizeof(void *)) overalloc(); ml = mem_alloc(sizeof(struct memory_list) + n * sizeof(void *)); ml->n = n; n = 0; q = p; va_end(ap); va_start(ap, p); while (q) ml->p[n++] = q, q = va_arg(ap, void *); va_end(ap); return ml;}void add_to_ml(struct memory_list **ml, ...){ struct memory_list *nml; va_list ap; int n = 0; void *q; if (!*ml) { *ml = mem_alloc(sizeof(struct memory_list)); (*ml)->n = 0; } va_start(ap, ml); while ((q = va_arg(ap, void *))) { if (n == MAXINT) overalloc(); n++; } if ((unsigned)n + (unsigned)((*ml)->n) > (MAXINT - sizeof(struct memory_list)) / sizeof(void *)) overalloc(); nml = mem_realloc(*ml, sizeof(struct memory_list) + (n + (*ml)->n) * sizeof(void *)); va_end(ap); va_start(ap, ml); while ((q = va_arg(ap, void *))) nml->p[nml->n++] = q; *ml = nml; va_end(ap);}void freeml(struct memory_list *ml){ int i; if (!ml) return; for (i = 0; i < ml->n; i++) mem_free(ml->p[i]); mem_free(ml);}#ifndef G#define txtlen (int)strlen#else#define txtlen(x) (F ? g_text_width(bfu_style_wb, x) : (int)strlen(x))#endif#ifdef Gint is_in_str(unsigned char *str, int u){ while (*str) { int v; GET_UTF_8(str, v); if (u >= 'a' && u <= 'z') u -= 'a' - 'A'; if (v >= 'a' && v <= 'z') v -= 'a' - 'A'; if (u == v) return 1; } return 0;}#endif#ifdef Gstruct style *bfu_style_wb, *bfu_style_wb_b, *bfu_style_bw, *bfu_style_bw_u;struct style *bfu_style_bw_mono;struct style *bfu_style_wb_mono, *bfu_style_wb_mono_u;long bfu_fg_color, bfu_bg_color;int G_DIALOG_FIELD_WIDTH;void init_bfu(void){ if (!F) return; bfu_bg_color = dip_get_color_sRGB(G_BFU_BG_COLOR); bfu_fg_color = dip_get_color_sRGB(G_BFU_FG_COLOR); bfu_style_wb = g_get_style(G_BFU_BG_COLOR, G_BFU_FG_COLOR, G_BFU_FONT_SIZE, G_BFU_DEFAULT_FONT, 0); bfu_style_wb_b = g_get_style(G_BFU_BG_COLOR, G_BFU_FG_COLOR, G_BFU_FONT_SIZE, G_BFU_DEFAULT_FONT, 0); bfu_style_bw = g_get_style(G_BFU_FG_COLOR, G_BFU_BG_COLOR, G_BFU_FONT_SIZE, G_BFU_DEFAULT_FONT, 0); bfu_style_bw_u = g_get_style(G_BFU_FG_COLOR, G_BFU_BG_COLOR, G_BFU_FONT_SIZE, G_BFU_DEFAULT_FONT, FF_UNDERLINE); bfu_style_bw_mono = g_get_style(G_BFU_FG_COLOR, G_BFU_BG_COLOR, G_BFU_FONT_SIZE, "monospaced", 0); bfu_style_wb_mono = g_get_style(G_BFU_BG_COLOR, G_BFU_FG_COLOR, G_BFU_FONT_SIZE, "monospaced", 0); bfu_style_wb_mono_u = g_get_style(G_BFU_BG_COLOR, G_BFU_FG_COLOR, G_BFU_FONT_SIZE, "monospaced", FF_UNDERLINE); G_DIALOG_FIELD_WIDTH = g_char_width(bfu_style_wb_mono, ' ');}void shutdown_bfu(void){ if (!F) return; g_free_style(bfu_style_wb); g_free_style(bfu_style_wb_b); g_free_style(bfu_style_bw); g_free_style(bfu_style_bw_u); g_free_style(bfu_style_bw_mono); g_free_style(bfu_style_wb_mono); g_free_style(bfu_style_wb_mono_u);}#elsevoid init_bfu(void) {}void shutdown_bfu(void) {}#endifvoid iinit_bfu(void){ G_BFU_FG_COLOR=G_DEFAULT_BFU_FG_COLOR; G_BFU_BG_COLOR=G_DEFAULT_BFU_BG_COLOR; G_SCROLL_BAR_AREA_COLOR=G_DEFAULT_SCROLL_BAR_AREA_COLOR; G_SCROLL_BAR_BAR_COLOR=G_DEFAULT_SCROLL_BAR_BAR_COLOR; G_SCROLL_BAR_FRAME_COLOR=G_DEFAULT_SCROLL_BAR_FRAME_COLOR;}unsigned char m_bar = 0;void do_menu_selected(struct terminal *term, struct menu_item *items, void *data, int selected){ struct menu *menu; menu = mem_alloc(sizeof(struct menu)); menu->selected = selected; menu->view = 0; menu->items = items; menu->data = data;#ifdef G if (F) { int n, i; for (n = 0; items[n].text; n++) if (n == MAXINT) overalloc(); if ((unsigned)n > MAXINT / sizeof(unsigned char *)) overalloc(); menu->hktxt1 = mem_calloc(n * sizeof(unsigned char *)); menu->hktxt2 = mem_calloc(n * sizeof(unsigned char *)); menu->hktxt3 = mem_calloc(n * sizeof(unsigned char *)); for (i = 0; i < n; i++) { unsigned char *txt = _(items[i].text, term); unsigned char *ext = _(items[i].hotkey, term); unsigned char *txt2, *txt3 = txt; if (ext != M_BAR) while (*txt3) { int u; txt2 = txt3; GET_UTF_8(txt3, u); if (is_in_str(ext, u)) { menu->hktxt1[i] = memacpy(txt, txt2 - txt); menu->hktxt2[i] = memacpy(txt2, txt3 - txt2); menu->hktxt3[i] = stracpy(txt3); goto x; } } menu->hktxt1[i] = stracpy(txt); menu->hktxt2[i] = stracpy(""); menu->hktxt3[i] = stracpy(""); x:; } }#endif add_window(term, menu_func, menu);}void do_menu(struct terminal *term, struct menu_item *items, void *data){ do_menu_selected(term, items, data, 0);}void select_menu(struct terminal *term, struct menu *menu){ struct menu_item *it = &menu->items[menu->selected]; void (*func)(struct terminal *, void *, void *) = it->func; void *data1 = it->data; void *data2 = menu->data; if (menu->selected < 0 || menu->selected >= menu->ni || it->hotkey == M_BAR) return; if (!it->in_m) { struct window *win, *win1; for (win = term->windows.next; (void *)win != &term->windows && (win->handler == menu_func || win->handler == mainmenu_func); win1 = win->next, delete_window(win), win = win1) ; } func(term, data1, data2);}void count_menu_size(struct terminal *term, struct menu *menu){ int sx = term->x; int sy = term->y; int mx = gf_val(4, 2 * (G_MENU_LEFT_BORDER + G_MENU_LEFT_INNER_BORDER)); int my; for (my = 0; menu->items[my].text; my++) { int s = txtlen(_(menu->items[my].text, term)) + txtlen(_(menu->items[my].rtext, term)) + gf_val(MENU_HOTKEY_SPACE, G_MENU_HOTKEY_SPACE) * (_(menu->items[my].rtext, term)[0] != 0) + gf_val(4, 2 * (G_MENU_LEFT_BORDER + G_MENU_LEFT_INNER_BORDER)); if (s > mx) mx = s; } menu->ni = my; my = gf_val(my, my * G_BFU_FONT_SIZE); my += gf_val(2, 2 * G_MENU_TOP_BORDER); if (mx > sx) mx = sx; if (my > sy) my = sy;#ifdef G if (F) { my -= 2 * G_MENU_TOP_BORDER; my -= my % G_BFU_FONT_SIZE; my += 2 * G_MENU_TOP_BORDER; }#endif menu->nview = gf_val(my - 2, (my - 2 * G_MENU_TOP_BORDER) / G_BFU_FONT_SIZE); menu->xw = mx; menu->yw = my; if ((menu->x = menu->xp) < 0) menu->x = 0; if ((menu->y = menu->yp) < 0) menu->y = 0; if (menu->x + mx > sx) menu->x = sx - mx; if (menu->y + my > sy) menu->y = sy - my; if (term->spec->braille) { menu->x = -1; menu->y = -1; menu->xw = term->x + 2; menu->yw = term->y + 2; menu->nview = term->y; }#ifdef G if (F) set_window_pos(menu->win, menu->x, menu->y, menu->x + menu->xw, menu->y + menu->yw);#endif}void scroll_menu(struct menu *menu, int d){ int c = 0; int w = menu->nview; int scr_i = SCROLL_ITEMS > (w-1)/2 ? (w-1)/2 : SCROLL_ITEMS; if (scr_i < 0) scr_i = 0; if (w < 0) w = 0; menu->selected += d; while (1) { if (c++ > menu->ni) { menu->selected = -1; menu->view = 0; return; } if (menu->selected < 0) menu->selected = 0; if (menu->selected >= menu->ni) menu->selected = menu->ni - 1; if (menu->ni && menu->items[menu->selected].hotkey != M_BAR) break; menu->selected += d; } if (menu->selected < menu->view + scr_i) menu->view = menu->selected - scr_i; if (menu->selected >= menu->view + w - scr_i - 1) menu->view = menu->selected - w + scr_i + 1; if (menu->view > menu->ni - w) menu->view = menu->ni - w; if (menu->view < 0) menu->view = 0;}void display_menu_txt(struct terminal *term, struct menu *menu){ int p, s; int setc = 0; fill_area(term, menu->x+1, menu->y+1, menu->xw-2, menu->yw-2, COLOR_MENU); draw_frame(term, menu->x, menu->y, menu->xw, menu->yw, COLOR_MENU_FRAME, 1); set_window_ptr(menu->win, menu->x, menu->y); for (p = menu->view, s = menu->y + 1; p < menu->ni && p < menu->view + menu->yw - 2; p++, s++) { int x; int h = 0; unsigned char c; unsigned char *tmptext = _(menu->items[p].text, term); int co = p == menu->selected ? h = 1, COLOR_MENU_SELECTED : COLOR_MENU; if (h) { setc = 1; set_cursor(term, menu->x + 1 + !!term->spec->braille, s, term->x - 1, term->y - 1); /*set_window_ptr(menu->win, menu->x+3, s+1);*/ set_window_ptr(menu->win, menu->x+menu->xw, s); fill_area(term, menu->x+1, s, menu->xw-2, 1, co); } if (term->spec->braille) h = 1; if (menu->items[p].hotkey != M_BAR || (tmptext[0])) { int l = strlen(_(menu->items[p].rtext, term)); unsigned char *rt = _(menu->items[p].rtext, term); unsigned char *ht = _(menu->items[p].hotkey, term); for (x = l - 1; x >= 0 && (term->spec->braille || menu->xw - 4 >= l - x) && (c = rt[x]); x--) { if (!term->spec->braille) set_char(term, menu->x + menu->xw - 2 - l + x, s, c | co); else set_char(term, menu->x + strlen(tmptext) + 4 + x + 2, s, c | COLOR_MENU_HOTKEY); } for (x = 0; x < menu->xw - 4 && (c = tmptext[x]); x++) set_char(term, menu->x + x + 2 + 2 * !!term->spec->braille, s, !h && strchr(ht, upcase(c)) ? h = 1, COLOR_MENU_HOTKEY | c : co | c); if (term->spec->braille && *ht) set_char(term, menu->x + 2, s, ht[0] | COLOR_MENU_HOTKEY); } else { set_char(term, menu->x, s, COLOR_MENU_FRAME | ATTR_FRAME | 0xc3); fill_area(term, menu->x+1, s, menu->xw-2, 1, COLOR_MENU_FRAME | ATTR_FRAME | 0xc4); set_char(term, menu->x+menu->xw-1, s, COLOR_MENU_FRAME | ATTR_FRAME | 0xb4); } } if (!setc && term->spec->braille) { set_cursor(term, menu->x + 1, menu->y + 1, term->x - 1, term->y - 1); }}int menu_oldview = -1;int menu_oldsel = -1;#ifdef Gint menu_ptr_set;void display_menu_item_gfx(struct terminal *term, struct menu *menu, int it){ struct menu_item *item = &menu->items[it]; struct graphics_device *dev = term->dev; int y; if (it < menu->view || it >= menu->ni || it >= menu->view + menu->nview) return; y = menu->y + G_MENU_TOP_BORDER + (it - menu->view) * G_BFU_FONT_SIZE; if (item->hotkey == M_BAR && !_(item->text, term)[0]) { drv->fill_area(dev, menu->x + (G_MENU_LEFT_BORDER - 1) / 2 + 1, y, menu->x + menu->xw - (G_MENU_LEFT_BORDER + 1) / 2, y + (G_BFU_FONT_SIZE - 1) / 2, bfu_bg_color); drv->draw_hline(dev, menu->x + (G_MENU_LEFT_BORDER - 1) / 2 + 1, y + (G_BFU_FONT_SIZE - 1) / 2, menu->x + menu->xw - G_MENU_LEFT_BORDER / 2, bfu_fg_color); drv->fill_area(dev, menu->x + (G_MENU_LEFT_BORDER - 1) / 2 + 1, y + (G_BFU_FONT_SIZE - 1) / 2 + 1, menu->x + menu->xw - (G_MENU_LEFT_BORDER + 1) / 2, y + G_BFU_FONT_SIZE, bfu_bg_color); } else { int p; struct rect r; unsigned char *rtext = _(item->rtext, term);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -