📄 inpfield.c
字号:
/* Input field widget implementation. *//* $Id: inpfield.c,v 1.190.2.6 2005/04/06 09:10:41 jonas Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <errno.h>#include <stdlib.h>#include <string.h>#include "elinks.h"#include "bfu/button.h"#include "bfu/dialog.h"#include "bfu/inpfield.h"#include "bfu/inphist.h"#include "bfu/msgbox.h"#include "bfu/text.h"#include "config/kbdbind.h"#include "intl/gettext/libintl.h"#include "osdep/osdep.h"#include "sched/session.h"#include "terminal/draw.h"#include "terminal/mouse.h"#include "terminal/terminal.h"#include "terminal/window.h"#include "util/color.h"#include "util/memlist.h"#include "util/memory.h"voidadd_dlg_field_do(struct dialog *dlg, enum widget_type type, unsigned char *label, int min, int max, t_widget_handler *handler, int datalen, void *data, struct input_history *history, enum inpfield_flags flags){ struct widget *widget; widget = &dlg->widgets[dlg->number_of_widgets++]; widget->type = type; widget->text = label; widget->handler = handler; widget->datalen = datalen; widget->data = data; widget->info.field.history = history; widget->info.field.flags = flags; widget->info.field.min = min; widget->info.field.max = max;}t_handler_event_statuscheck_number(struct dialog_data *dlg_data, struct widget_data *widget_data){ struct widget *widget = widget_data->widget; unsigned char *end; long l; errno = 0; l = strtol(widget_data->cdata, (char **) &end, 10); if (errno || !*widget_data->cdata || *end) { info_box(dlg_data->win->term, 0, N_("Bad number"), ALIGN_CENTER, N_("Number expected in field")); return EVENT_NOT_PROCESSED; } if (l < widget->info.field.min || l > widget->info.field.max) { info_box(dlg_data->win->term, MSGBOX_FREE_TEXT, N_("Bad number"), ALIGN_CENTER, msg_text(dlg_data->win->term, N_("Number should be in the range from %d to %d."), widget->info.field.min, widget->info.field.max)); return EVENT_NOT_PROCESSED; } return EVENT_PROCESSED;}t_handler_event_statuscheck_nonempty(struct dialog_data *dlg_data, struct widget_data *widget_data){ unsigned char *p; for (p = widget_data->cdata; *p; p++) if (*p > ' ') return EVENT_PROCESSED; info_box(dlg_data->win->term, 0, N_("Bad string"), ALIGN_CENTER, N_("Empty string not allowed")); return EVENT_NOT_PROCESSED;}voiddlg_format_field(struct terminal *term, struct widget_data *widget_data, int x, int *y, int w, int *rw, enum format_align align){ static int max_label_width; static int *prev_y; /* Assert the uniqueness of y */ unsigned char *label = widget_data->widget->text; struct color_pair *text_color = NULL; int label_width = 0; int float_label = widget_data->widget->info.field.flags & (INPFIELD_FLOAT|INPFIELD_FLOAT2); if (label && float_label) { label_width = strlen(label); if (prev_y == y) { int_lower_bound(&max_label_width, label_width); } else { max_label_width = label_width; prev_y = y; } /* Right align the floating label up against the * input field */ x += max_label_width - label_width; w -= max_label_width - label_width; } if (label) { if (term) text_color = get_bfu_color(term, "dialog.text"); dlg_format_text_do(term, label, x, y, w, rw, text_color, ALIGN_LEFT); } /* XXX: We want the field and label on the same line if the terminal * width allows it. */ if (label && float_label) { if (widget_data->widget->info.field.flags & INPFIELD_FLOAT) { (*y)--; dlg_format_text_do(term, ":", x + label_width, y, w, rw, text_color, ALIGN_LEFT); w -= 2; x += 2; } /* FIXME: Is 5 chars for input field enough? --jonas */ if (label_width < w - 5) { (*y)--; w -= label_width; x += label_width; } } if (rw) int_lower_bound(rw, int_min(w, DIALOG_MIN_WIDTH)); set_box(&widget_data->box, x, *y, w, 1); (*y)++;}static t_handler_event_statusinput_field_cancel(struct dialog_data *dlg_data, struct widget_data *widget_data){ void (*fn)(void *) = widget_data->widget->data; void *data = dlg_data->dlg->udata2; if (fn) fn(data); return cancel_dialog(dlg_data, widget_data);}static t_handler_event_statusinput_field_ok(struct dialog_data *dlg_data, struct widget_data *widget_data){ void (*fn)(void *, unsigned char *) = widget_data->widget->data; void *data = dlg_data->dlg->udata2; unsigned char *text = dlg_data->widgets_data->cdata; if (check_dialog(dlg_data)) return EVENT_NOT_PROCESSED; if (widget_has_history(dlg_data->widgets_data)) add_to_input_history(dlg_data->dlg->widgets->info.field.history, text, 1); if (fn) fn(data, text); return cancel_dialog(dlg_data, widget_data);}voidinput_field(struct terminal *term, struct memory_list *ml, int intl, unsigned char *title, unsigned char *text, unsigned char *okbutton, unsigned char *cancelbutton, void *data, struct input_history *history, int l, unsigned char *def, int min, int max, t_handler_event_status (*check)(struct dialog_data *, struct widget_data *), void (*fn)(void *, unsigned char *), void (*cancelfn)(void *)){ struct dialog *dlg; unsigned char *field; if (intl) { title = _(title, term); text = _(text, term); okbutton = _(okbutton, term); cancelbutton = _(cancelbutton, term); }#define INPUT_WIDGETS_COUNT 3 dlg = calloc_dialog(INPUT_WIDGETS_COUNT, l); if (!dlg) return; /* @field is automatically cleared by calloc() */ field = get_dialog_offset(dlg, INPUT_WIDGETS_COUNT); if (def) { int defsize = strlen(def) + 1; memcpy(field, def, (defsize > l) ? l - 1 : defsize); } dlg->title = title; dlg->layouter = generic_dialog_layouter; dlg->layout.fit_datalen = 1; dlg->udata2 = data; add_dlg_field(dlg, text, min, max, check, l, field, history); add_dlg_button(dlg, okbutton, B_ENTER, input_field_ok, fn); add_dlg_button(dlg, cancelbutton, B_ESC, input_field_cancel, cancelfn); add_dlg_end(dlg, INPUT_WIDGETS_COUNT); add_to_ml(&ml, dlg, NULL); do_dialog(term, dlg, ml);}voidinput_dialog(struct terminal *term, struct memory_list *ml, unsigned char *title, unsigned char *text, void *data, struct input_history *history, int l, unsigned char *def, int min, int max, t_widget_handler *check, void (*fn)(void *, unsigned char *), void (*cancelfn)(void *)){ input_field(term, ml, 1, title, text, N_("~OK"), N_("~Cancel"), data, history, l, def, min, max, check, fn, cancelfn);}static t_handler_event_statusdisplay_field_do(struct dialog_data *dlg_data, struct widget_data *widget_data, int hide){ struct terminal *term = dlg_data->win->term; struct color_pair *color; int sel = is_selected_widget(dlg_data, widget_data); int_bounds(&widget_data->info.field.vpos, widget_data->info.field.cpos - widget_data->box.width + 1, widget_data->info.field.cpos); int_lower_bound(&widget_data->info.field.vpos, 0); color = get_bfu_color(term, "dialog.field"); if (color) draw_box(term, &widget_data->box, ' ', 0, color); color = get_bfu_color(term, "dialog.field-text"); if (color) { int len = strlen(widget_data->cdata + widget_data->info.field.vpos); int w = int_min(len, widget_data->box.width); if (!hide) { draw_text(term, widget_data->box.x, widget_data->box.y, widget_data->cdata + widget_data->info.field.vpos, w, 0, color); } else { struct box box; copy_box(&box, &widget_data->box); box.width = w; draw_box(term, &box, '*', 0, color); } } if (sel) { int x = widget_data->box.x + widget_data->info.field.cpos - widget_data->info.field.vpos; set_cursor(term, x, widget_data->box.y, 0); set_window_ptr(dlg_data->win, widget_data->box.x, widget_data->box.y); } return EVENT_PROCESSED;}static t_handler_event_statusdisplay_field(struct dialog_data *dlg_data, struct widget_data *widget_data){ return display_field_do(dlg_data, widget_data, 0);}static t_handler_event_statusdisplay_field_pass(struct dialog_data *dlg_data, struct widget_data *widget_data){ return display_field_do(dlg_data, widget_data, 1);}static t_handler_event_statusinit_field(struct dialog_data *dlg_data, struct widget_data *widget_data){ if (widget_has_history(widget_data)) { struct input_history_entry *entry; foreach (entry, widget_data->widget->info.field.history->entries) { int datalen = strlen(entry->data); struct input_history_entry *new_entry; /* One byte is reserved in struct input_history_entry. */ new_entry = mem_alloc(sizeof(*new_entry) + datalen); if (!new_entry) continue; memcpy(new_entry->data, entry->data, datalen + 1); add_to_list(widget_data->info.field.history, new_entry); } } widget_data->info.field.cpos = strlen(widget_data->cdata); return EVENT_PROCESSED;}static t_handler_event_statusmouse_field(struct dialog_data *dlg_data, struct widget_data *widget_data){ struct term_event *ev = dlg_data->term_event; if (!widget_has_history(widget_data)) return EVENT_NOT_PROCESSED; if (!check_mouse_position(ev, &widget_data->box)) return EVENT_NOT_PROCESSED; switch (get_mouse_button(ev)) { case B_WHEEL_UP: if (check_mouse_action(ev, B_DOWN) && (void *) widget_data->info.field.cur_hist->prev != &widget_data->info.field.history) { widget_data->info.field.cur_hist = widget_data->info.field.cur_hist->prev; dlg_set_history(widget_data); select_widget(dlg_data, widget_data);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -