📄 bfu.c
字号:
select_mainmenu(win->term, menu); break; } if (ev->x == KBD_LEFT) { if (!menu->selected--) menu->selected = menu->ni - 1; s = 1; } if (ev->x == KBD_RIGHT) { if (++menu->selected >= menu->ni) menu->selected = 0; s = 1; } if (ev->x == KBD_HOME) { menu->selected = 0; s = 1; } if (ev->x == KBD_END) { menu->selected = menu->ni - 1; s = 1; } if ((ev->x == KBD_LEFT || ev->x == KBD_RIGHT) && fwd) { display_mainmenu(win->term, menu); select_mainmenu(win->term, menu); break; } if (ev->x > ' ' && ev->x < 256) { int i; s = 1; for (i = 0; i < menu->ni; i++) if (strchr(_(menu->items[i].hotkey, win->term), upcase(ev->x))) { menu->selected = i; s = 2; } } else if (!s) { delete_window_ev(win, (ev->x >= KBD_F1 && ev->x <= KBD_F12) || ev->y & KBD_ALT ? ev : NULL); break; } display_mainmenu(win->term, menu); if (s == 2) select_mainmenu(win->term, menu); break; case EV_ABORT: break; }}struct menu_item *new_menu(int free_i){ struct menu_item *mi; mi = mem_alloc(sizeof(struct menu_item)); memset(mi, 0, sizeof(struct menu_item)); mi->free_i = free_i; return mi;}void add_to_menu(struct menu_item **mi, unsigned char *text, unsigned char *rtext, unsigned char *hotkey, void (*func)(struct terminal *, void *, void *), void *data, int in_m){ struct menu_item *mii; int n; for (n = 0; (*mi)[n].text; n++) if (n == MAXINT) overalloc(); if (((unsigned)n + 2) > MAXINT / sizeof(struct menu_item)) overalloc(); mii = mem_realloc(*mi, (n + 2) * sizeof(struct menu_item)); *mi = mii; memcpy(mii + n + 1, mii + n, sizeof(struct menu_item)); mii[n].text = text; mii[n].rtext = rtext; mii[n].hotkey = hotkey; mii[n].func = func; mii[n].data = data; mii[n].in_m = in_m;}void do_dialog(struct terminal *term, struct dialog *dlg, struct memory_list *ml){ struct dialog_data *dd; struct dialog_item *d; int n = 0; for (d = dlg->items; d->type != D_END; d++) { if (n == MAXINT) overalloc(); n++; } if ((unsigned)n > (MAXINT - sizeof(struct dialog_data)) / sizeof(struct dialog_item_data)) overalloc(); dd = mem_alloc(sizeof(struct dialog_data) + sizeof(struct dialog_item_data) * n); dd->dlg = dlg; dd->n = n; dd->ml = ml; add_window(term, dialog_func, dd);}void display_dlg_item(struct dialog_data *dlg, struct dialog_item_data *di, int sel){ struct terminal *term = dlg->win->term; switch(di->item->type) { int co; unsigned char *text; case D_CHECKBOX: if (di->checked) print_text(term, di->x, di->y, 3, "[X]", COLOR_DIALOG_CHECKBOX); else print_text(term, di->x, di->y, 3, "[ ]", COLOR_DIALOG_CHECKBOX); if (sel) { set_cursor(term, di->x + 1, di->y, di->x + 1, di->y); set_window_ptr(dlg->win, di->x, di->y); } break; case D_FIELD_PASS: case D_FIELD: if (di->vpos + di->l <= di->cpos) di->vpos = di->cpos - di->l + 1; if (di->vpos > di->cpos) di->vpos = di->cpos; if (di->vpos < 0) di->vpos = 0; fill_area(term, di->x, di->y, di->l, 1, COLOR_DIALOG_FIELD); if (di->item->type == D_FIELD) { print_text(term, di->x, di->y, strlen(di->cdata + di->vpos) <= (size_t)di->l ? (int)strlen(di->cdata + di->vpos) : di->l, di->cdata + di->vpos, COLOR_DIALOG_FIELD_TEXT); } else { fill_area(term, di->x, di->y, strlen(di->cdata + di->vpos) <= (size_t)di->l ? (int)strlen(di->cdata + di->vpos) : di->l, 1, COLOR_DIALOG_FIELD_TEXT | '*'); } if (sel) { set_cursor(term, di->x + di->cpos - di->vpos, di->y, di->x + di->cpos - di->vpos, di->y); set_window_ptr(dlg->win, di->x, di->y); } break; case D_BUTTON: co = sel ? COLOR_DIALOG_BUTTON_SELECTED : COLOR_DIALOG_BUTTON; text = _(di->item->text, term); print_text(term, di->x, di->y, 2, "[ ", co); print_text(term, di->x + 2, di->y, strlen(text), text, co); print_text(term, di->x + 2 + strlen(text), di->y, 2, " ]", co); if (sel) { set_cursor(term, di->x + 2, di->y, di->x + 2, di->y); set_window_ptr(dlg->win, di->x, di->y); } break; case D_BOX: /* Draw a hierarchy box */ show_dlg_item_box(dlg, di); break; default: internal("Tried to draw unknown"); }}void dlg_select_item(struct dialog_data *dlg, struct dialog_item_data *di){ if (di->item->type == D_CHECKBOX) { if (!di->item->gid) di -> checked = *(int *)di->cdata = !*(int *)di->cdata; else { int i; for (i = 0; i < dlg->n; i++) { if (dlg->items[i].item->type == D_CHECKBOX && dlg->items[i].item->gid == di->item->gid) { *(int *)dlg->items[i].cdata = di->item->gnum; dlg->items[i].checked = 0; display_dlg_item(dlg, &dlg->items[i], 0); } } di->checked = 1; } display_dlg_item(dlg, di, 1); } else if (di->item->type == D_BUTTON) di->item->fn(dlg, di);}void dlg_set_history(struct dialog_item_data *di){ unsigned char *s = ""; int l; if ((void *)di->cur_hist != &di->history) s = di->cur_hist->d; if ((l = strlen(s)) > di->item->dlen) l = di->item->dlen - 1; memcpy(di->cdata, s, l); di->cdata[l] = 0; di->cpos = l; di->vpos = 0;}int dlg_mouse(struct dialog_data *dlg, struct dialog_item_data *di, struct event *ev){ switch (di->item->type) { case D_BUTTON: if (ev->y != di->y || ev->x < di->x || (size_t)ev->x >= di->x + strlen(_(di->item->text, dlg->win->term)) + 4) return 0; display_dlg_item(dlg, &dlg->items[dlg->selected], 0); dlg->selected = di - dlg->items; display_dlg_item(dlg, di, 1); if ((ev->b & BM_ACT) == B_UP) dlg_select_item(dlg, di); return 1; case D_FIELD_PASS: case D_FIELD: if (ev->y != di->y || ev->x < di->x || ev->x >= di->x + di->l) return 0; if ((size_t)(di->cpos = di->vpos + ev->x - di->x) > strlen(di->cdata)) di->cpos = strlen(di->cdata); display_dlg_item(dlg, &dlg->items[dlg->selected], 0); dlg->selected = di - dlg->items; display_dlg_item(dlg, di, 1); return 1; case D_CHECKBOX: if (ev->y != di->y || ev->x < di->x || ev->x >= di->x + 3) return 0; display_dlg_item(dlg, &dlg->items[dlg->selected], 0); dlg->selected = di - dlg->items; display_dlg_item(dlg, di, 1); if ((ev->b & BM_ACT) == B_UP) dlg_select_item(dlg, di); return 1; case D_BOX: if ((ev->b & BM_ACT) == B_UP) { if ( (ev->y >= di->y) && (ev->x >= di->x && ev->x <= di->l + di->x) ) { /* Clicked in the box. */ int offset; offset = ev->y - di->y; box_sel_set_visible(di, offset); display_dlg_item(dlg, di, 1); return 1; } } /*else if ((ev->b & BM_ACT) == B_DRAG) { debug("drag"); }*/ } return 0;}void redraw_dialog(struct dialog_data *dlg){ int i; struct terminal *term = dlg->win->term; draw_frame(term, dlg->x + DIALOG_LEFT_BORDER, dlg->y + DIALOG_TOP_BORDER, dlg->xw - 2 * DIALOG_LEFT_BORDER, dlg->yw - 2 * DIALOG_TOP_BORDER, COLOR_DIALOG_FRAME, DIALOG_FRAME); i = strlen(_(dlg->dlg->title, term)); print_text(term, (dlg->xw - i) / 2 + dlg->x - 1, dlg->y + DIALOG_TOP_BORDER, 1, " ", COLOR_DIALOG_TITLE); print_text(term, (dlg->xw - i) / 2 + dlg->x, dlg->y + DIALOG_TOP_BORDER, i, _(dlg->dlg->title, term), COLOR_DIALOG_TITLE); print_text(term, (dlg->xw - i) / 2 + dlg->x + i, dlg->y + DIALOG_TOP_BORDER, 1, " ", COLOR_DIALOG_TITLE); for (i = 0; i < dlg->n; i++) display_dlg_item(dlg, &dlg->items[i], i == dlg->selected); redraw_from_window(dlg->win);}void tab_compl(struct terminal *term, unsigned char *item, struct window *win){ struct event ev = {EV_REDRAW, 0, 0, 0}; struct dialog_item_data *di = &((struct dialog_data*)win->data)->items[((struct dialog_data*)win->data)->selected]; int l = strlen(item); if (l >= di->item->dlen) l = di->item->dlen - 1; memcpy(di->cdata, item, l); di->cdata[l] = 0; di->cpos = l; di->vpos = 0; ev.x = term->x; ev.y = term->y; dialog_func(win, &ev, 0);}void do_tab_compl(struct terminal *term, struct list_head *history, struct window *win){ unsigned char *cdata = ((struct dialog_data*)win->data)->items[((struct dialog_data*)win->data)->selected].cdata; int l = strlen(cdata), n = 0; struct history_item *hi; struct menu_item *items = DUMMY; foreach(hi, *history) if (!strncmp(cdata, hi->d, l)) { if (!(n & (ALLOC_GR - 1))) { if ((unsigned)n > MAXINT / sizeof(struct menu_item) - ALLOC_GR - 1) overalloc(); items = mem_realloc(items, (n + ALLOC_GR + 1) * sizeof(struct menu_item)); } items[n].text = hi->d; items[n].rtext = ""; items[n].hotkey = ""; items[n].func = (void(*)(struct terminal *, void *, void *))tab_compl; items[n].rtext = ""; items[n].data = hi->d; items[n].in_m = 0; items[n].free_i = 1; if (n == MAXINT) overalloc(); n++; } if (n == 1) { tab_compl(term, items->data, win); mem_free(items); return; } if (n) { memset(&items[n], 0, sizeof(struct menu_item)); do_menu_selected(term, items, win, n - 1); }}void dialog_func(struct window *win, struct event *ev, int fwd){ int i; struct terminal *term = win->term; struct dialog_data *dlg = win->data; struct dialog_item_data *di; dlg->win = win; /* Use nonstandard event handlers */ if (dlg->dlg->handle_event && ((dlg->dlg->handle_event)(dlg, ev) == EVENT_PROCESSED) ) { return; } switch (ev->ev) { case EV_INIT: for (i = 0; i < dlg->n; i++) { struct dialog_item_data *di = &dlg->items[i]; memset(di, 0, sizeof(struct dialog_item_data)); di->item = &dlg->dlg->items[i]; di->cdata = mem_alloc(di->item->dlen); memcpy(di->cdata, di->item->data, di->item->dlen); if (di->item->type == D_CHECKBOX) { if (di->item->gid) { if (*(int *)di->cdata == di->item->gnum) di->checked = 1; } else if (*(int *)di->cdata) di->checked = 1; } if (di->item->type == D_BOX) { /* Freed in bookmark_dialog_abort_handler() */ di->cdata = mem_alloc( sizeof(struct dlg_data_item_data_box) ); ((struct dlg_data_item_data_box*)di->cdata)->sel = -1; ((struct dlg_data_item_data_box*)di->cdata)->box_top = 0; ((struct dlg_data_item_data_box*)di->cdata)->list_len = -1; init_list(((struct dlg_data_item_data_box*)di->cdata)->items); } init_list(di->history); di->cur_hist = (struct history_item *)&di->history; if (di->item->type == D_FIELD || di->item->type == D_FIELD_PASS) { if (di->item->history) { struct history_item *j; /*int l = di->item->dlen;*/ foreach(j, di->item->history->items) { struct history_item *hi; hi = mem_alloc(sizeof(struct history_item) + strlen(j->d) + 1); strcpy(hi->d, j->d); add_to_list(di->history, hi); } } di->cpos = strlen(di->cdata); } } dlg->selected = 0; case EV_RESIZE: case EV_REDRAW: dlg->dlg->fn(dlg); redraw_dialog(dlg); break; case EV_MOUSE: for (i = 0; i < dlg->n; i++) if (dlg_mouse(dlg, &dlg->items[i], ev)) break; break; case EV_KBD: di = &dlg->items[dlg->selected]; if (di->item->type == D_FIELD || di->item->type == D_FIELD_PASS) { switch (kbd_action(KM_EDIT, ev)) { case ACT_UP: if ((void *)di->cur_hist->prev != &di->history) { di->cur_hist = di->cur_hist->prev; dlg_set_history(di); goto dsp_f; } break; case ACT_DOWN: if ((void *)di->cur_hist != &di->history) { di->cur_hist = di->cur_hist->next; dlg_set_history(di); goto dsp_f; } break; case ACT_RIGHT: if ((size_t)di->cpos < strlen(di->cdata)) di->cpos++; goto dsp_f; case ACT_LEFT: if (di->cpos > 0) di->cpos--; goto dsp_f; case ACT_HOME: di->cpos = 0; goto dsp_f; case ACT_END: di->cpos = strlen(di->cdata); goto dsp_f; case ACT_BACKSPACE: if (di->cpos) { memmove(di->cdata + di->cpos - 1, di->cdata + di->cpos, strlen(di->cdata) - di->cpos + 1); di->cpos--; } goto dsp_f; case ACT_DELETE: if ((size_t)di->cpos < strlen(di->cdata))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -