📄 dialog.c
字号:
select_button_by_flag(dlg_data, B_ESC); break; case ACT_MENU_NEXT_ITEM: case ACT_MENU_DOWN: case ACT_MENU_RIGHT: /* Cycle focus. */ cycle_widget_focus(dlg_data, 1); break; case ACT_MENU_PREVIOUS_ITEM: case ACT_MENU_UP: case ACT_MENU_LEFT: /* Cycle focus (reverse). */ cycle_widget_focus(dlg_data, -1); break; case ACT_MENU_REDRAW: redraw_terminal_cls(dlg_data->win->term); break; default: select_button_by_key(dlg_data); break; }}static voiddialog_ev_abort(struct dialog_data *dlg_data){ struct widget_data *widget_data; if (dlg_data->dlg->refresh) { struct dialog_refresh *refresh = dlg_data->dlg->refresh; if (refresh->timer != -1) kill_timer(refresh->timer); mem_free(refresh); } if (dlg_data->dlg->abort) dlg_data->dlg->abort(dlg_data); foreach_widget(dlg_data, widget_data) { mem_free_if(widget_data->cdata); if (widget_has_history(widget_data)) free_list(widget_data->info.field.history); } freeml(dlg_data->ml);}/* TODO: use EVENT_PROCESSED/EVENT_NOT_PROCESSED. */static voiddialog_func(struct window *win, struct term_event *ev){ struct dialog_data *dlg_data = win->data; dlg_data->win = win; dlg_data->term_event = ev; /* Look whether user event handlers can help us.. */ if (dlg_data->dlg->handle_event && (dlg_data->dlg->handle_event(dlg_data) == EVENT_PROCESSED)) { return; } switch (ev->ev) { case EVENT_INIT: dialog_ev_init(dlg_data); /* fallback */ case EVENT_RESIZE: case EVENT_REDRAW: redraw_dialog(dlg_data, 1); break; case EVENT_MOUSE:#ifdef CONFIG_MOUSE dialog_ev_mouse(dlg_data);#endif break; case EVENT_KBD: dialog_ev_kbd(dlg_data); break; case EVENT_ABORT: dialog_ev_abort(dlg_data); break; }}intcheck_dialog(struct dialog_data *dlg_data){ struct widget_data *widget_data; foreach_widget(dlg_data, widget_data) { if (widget_data->widget->type != WIDGET_CHECKBOX && !widget_is_textfield(widget_data)) continue; if (widget_data->widget->handler && widget_data->widget->handler(dlg_data, widget_data)) { select_widget(dlg_data, widget_data); redraw_dialog(dlg_data, 0); return 1; } } return 0;}t_handler_event_statuscancel_dialog(struct dialog_data *dlg_data, struct widget_data *xxx){ delete_window(dlg_data->win); return EVENT_PROCESSED;}intupdate_dialog_data(struct dialog_data *dlg_data){ struct widget_data *widget_data; foreach_widget(dlg_data, widget_data) { if (!widget_data->widget->datalen) continue; memcpy(widget_data->widget->data, widget_data->cdata, widget_data->widget->datalen); } return 0;}t_handler_event_statusok_dialog(struct dialog_data *dlg_data, struct widget_data *widget_data){ t_done_handler *done = widget_data->widget->info.button.done; void *done_data = widget_data->widget->info.button.done_data; if (check_dialog(dlg_data)) return EVENT_NOT_PROCESSED; update_dialog_data(dlg_data); if (done) done(done_data); return cancel_dialog(dlg_data, widget_data);}/* Clear dialog fields (if widget has clear callback). */t_handler_event_statusclear_dialog(struct dialog_data *dlg_data, struct widget_data *xxx){ struct widget_data *widget_data; foreach_widget(dlg_data, widget_data) { if (widget_data->widget->ops->clear) widget_data->widget->ops->clear(dlg_data, widget_data); } /* Move focus to the first widget. It helps with bookmark search dialog * (and others). */ select_widget_by_id(dlg_data, 0); redraw_dialog(dlg_data, 0); return EVENT_PROCESSED;}static voidformat_widgets(struct terminal *term, struct dialog_data *dlg_data, int x, int *y, int w, int h, int *rw){ struct widget_data *wdata = dlg_data->widgets_data; int widgets = dlg_data->number_of_widgets; /* TODO: Do something if (*y) gets > height. */ for (; widgets > 0; widgets--, wdata++, (*y)++) { switch (wdata->widget->type) { case WIDGET_FIELD_PASS: case WIDGET_FIELD: dlg_format_field(term, wdata, x, y, w, rw, ALIGN_LEFT); break; case WIDGET_LISTBOX: dlg_format_listbox(term, wdata, x, y, w, h, rw, ALIGN_LEFT); break; case WIDGET_TEXT: dlg_format_text(term, wdata, x, y, w, rw, h); break; case WIDGET_CHECKBOX: { int group = widget_has_group(wdata); if (group > 0 && dlg_data->dlg->layout.float_groups) { int size; /* Find group size */ for (size = 1; widgets > 0; size++, widgets--) { struct widget_data *next = &wdata[size]; if (group != widget_has_group(next)) break; } dlg_format_group(term, wdata, size, x, y, w, rw); wdata += size - 1; } else { /* No horizontal space between checkboxes belonging to * the same group. */ dlg_format_checkbox(term, wdata, x, y, w, rw, ALIGN_LEFT); if (widgets > 1 && group == widget_has_group(&wdata[1])) (*y)--; } } break; /* We assume that the buttons are all stuffed at the very end * of the dialog. */ case WIDGET_BUTTON: dlg_format_buttons(term, wdata, widgets, x, y, w, rw, ALIGN_CENTER); return; } }}voidgeneric_dialog_layouter(struct dialog_data *dlg_data){ struct terminal *term = dlg_data->win->term; int w = dialog_max_width(term); int height = dialog_max_height(term); int rw = int_min(w, strlen(dlg_data->dlg->title)); int y = dlg_data->dlg->layout.padding_top ? 0 : -1; int x = 0; format_widgets(NULL, dlg_data, x, &y, w, height, &rw); /* Update the width to respond to the required minimum width */ if (dlg_data->dlg->layout.fit_datalen) { int_lower_bound(&rw, dlg_data->dlg->widgets->datalen); int_upper_bound(&w, rw); } else if (!dlg_data->dlg->layout.maximize_width) { w = rw; } draw_dialog(dlg_data, w, y); y = dlg_data->box.y + DIALOG_TB + dlg_data->dlg->layout.padding_top; x = dlg_data->box.x + DIALOG_LB; format_widgets(term, dlg_data, x, &y, w, height, NULL);}voiddraw_dialog(struct dialog_data *dlg_data, int width, int height){ struct terminal *term = dlg_data->win->term; int dlg_width = int_min(term->width, width + 2 * DIALOG_LB); int dlg_height = int_min(term->height, height + 2 * DIALOG_TB); set_box(&dlg_data->box, (term->width - dlg_width) / 2, (term->height - dlg_height) / 2, dlg_width, dlg_height); draw_box(term, &dlg_data->box, ' ', 0, get_bfu_color(term, "dialog.generic")); if (get_opt_bool("ui.dialogs.shadows")) { /* Draw shadow */ draw_shadow(term, &dlg_data->box, get_bfu_color(term, "dialog.shadow"), 2, 1); }}static voiddo_refresh_dialog(struct dialog_data *dlg_data){ struct dialog_refresh *refresh = dlg_data->dlg->refresh; enum dlg_refresh_code refresh_code; assert(refresh && refresh->handler); refresh_code = refresh->handler(dlg_data, refresh->data); if (refresh_code == REFRESH_CANCEL || refresh_code == REFRESH_STOP) { refresh->timer = -1; if (refresh_code == REFRESH_CANCEL) cancel_dialog(dlg_data, NULL); return; } /* We want dialog_has_refresh() to be true while drawing * so we can not set the timer to -1. */ if (refresh_code == REFRESH_DIALOG) { redraw_dialog(dlg_data, 1); } refresh->timer = install_timer(RESOURCE_INFO_REFRESH, (void (*)(void *)) do_refresh_dialog, dlg_data);}voidrefresh_dialog(struct dialog_data *dlg_data, dialog_refresh_handler handler, void *data){ struct dialog_refresh *refresh = dlg_data->dlg->refresh; if (!refresh) { refresh = mem_calloc(1, sizeof(*refresh)); if (!refresh) return; dlg_data->dlg->refresh = refresh; } else if (refresh->timer != -1) { kill_timer(refresh->timer); } refresh->handler = handler; refresh->data = data; refresh->timer = install_timer(RESOURCE_INFO_REFRESH, (void (*)(void *)) do_refresh_dialog, dlg_data);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -