⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dialog.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Dialog box implementation. *//* $Id: dialog.c,v 1.188.4.4 2005/04/06 11:00:57 jonas Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdlib.h>#include <string.h>#include "elinks.h"#include "bfu/dialog.h"#include "config/kbdbind.h"#include "config/options.h"#include "intl/gettext/libintl.h"#include "terminal/draw.h"#include "lowlevel/select.h"#include "terminal/kbd.h"#include "terminal/terminal.h"#include "terminal/window.h"#include "util/color.h"#include "util/conv.h"#include "util/error.h"#include "util/memlist.h"#include "util/memory.h"#include "util/string.h"static window_handler dialog_func;struct dialog_data *do_dialog(struct terminal *term, struct dialog *dlg,	  struct memory_list *ml){	struct dialog_data *dlg_data;	dlg_data = mem_calloc(1, sizeof(*dlg_data) +			      sizeof(struct widget_data) * dlg->number_of_widgets);	if (!dlg_data) {		/* Worry not: freeml() checks whether its argument is NULL. */		freeml(ml);		return NULL;	}	dlg_data->dlg = dlg;	dlg_data->number_of_widgets = dlg->number_of_widgets;	dlg_data->ml = ml;	add_window(term, dialog_func, dlg_data);	return dlg_data;}static void cycle_widget_focus(struct dialog_data *dlg_data, int direction);static voidupdate_all_widgets(struct dialog_data *dlg_data){	struct widget_data *widget_data;	foreach_widget(dlg_data, widget_data) {		display_widget(dlg_data, widget_data);	}}voidredraw_dialog(struct dialog_data *dlg_data, int layout){	struct terminal *term = dlg_data->win->term;	struct color_pair *title_color;	if (layout) {		dlg_data->dlg->layouter(dlg_data);		/* This might not be the best place. We need to be able		 * to make focusability of widgets dynamic so widgets		 * like scrollable text don't receive focus when there		 * is nothing to scroll. */		if (!widget_is_focusable(selected_widget(dlg_data)))			cycle_widget_focus(dlg_data, 1);	}	if (!dlg_data->dlg->layout.only_widgets) {		struct box box;		set_box(&box,			dlg_data->box.x + (DIALOG_LEFT_BORDER + 1),			dlg_data->box.y + (DIALOG_TOP_BORDER + 1),			dlg_data->box.width - 2 * (DIALOG_LEFT_BORDER + 1),			dlg_data->box.height - 2 * (DIALOG_TOP_BORDER + 1));		draw_border(term, &box, get_bfu_color(term, "dialog.frame"), DIALOG_FRAME);		assert(dlg_data->dlg->title);		title_color = get_bfu_color(term, "dialog.title");		if (title_color && box.width > 2) {			unsigned char *title = dlg_data->dlg->title;			int titlelen = int_min(box.width - 2, strlen(title));			int x = (box.width - titlelen) / 2 + box.x;			int y = box.y - 1;			draw_text(term, x - 1, y, " ", 1, 0, title_color);			draw_text(term, x, y, title, titlelen, 0, title_color);			draw_text(term, x + titlelen, y, " ", 1, 0, title_color);		}	}	update_all_widgets(dlg_data);	redraw_from_window(dlg_data->win);}static voidselect_dlg_item(struct dialog_data *dlg_data, struct widget_data *widget_data){	select_widget(dlg_data, widget_data);	if (widget_data->widget->ops->select)		widget_data->widget->ops->select(dlg_data, widget_data);}static struct widget_ops *widget_type_to_ops[] = {	&checkbox_ops,	&field_ops,	&field_pass_ops,	&button_ops,	&listbox_ops,	&text_ops,};static struct widget_data *init_widget(struct dialog_data *dlg_data, int i){	struct widget_data *widget_data = &dlg_data->widgets_data[i];	memset(widget_data, 0, sizeof(*widget_data));	widget_data->widget = &dlg_data->dlg->widgets[i];	if (widget_data->widget->datalen) {		widget_data->cdata = mem_alloc(widget_data->widget->datalen);		if (!widget_data->cdata) {			return NULL;		}		memcpy(widget_data->cdata,		       widget_data->widget->data,		       widget_data->widget->datalen);	}	widget_data->widget->ops = widget_type_to_ops[widget_data->widget->type];	if (widget_has_history(widget_data)) {		init_list(widget_data->info.field.history);		widget_data->info.field.cur_hist =			(struct input_history_entry *) &widget_data->info.field.history;	}	if (widget_data->widget->ops->init)		widget_data->widget->ops->init(dlg_data, widget_data);	return widget_data;}voidselect_widget(struct dialog_data *dlg_data, struct widget_data *widget_data){	struct widget_data *previously_selected_widget;	previously_selected_widget = selected_widget(dlg_data);	dlg_data->selected_widget_id = widget_data - dlg_data->widgets_data;	display_widget(dlg_data, previously_selected_widget);	display_widget(dlg_data, widget_data);}struct widget_data *select_widget_by_id(struct dialog_data *dlg_data, int i){	struct widget_data *widget_data = &dlg_data->widgets_data[i];	select_widget(dlg_data, widget_data);	return widget_data;}static voidcycle_widget_focus(struct dialog_data *dlg_data, int direction){	int prev_selected = dlg_data->selected_widget_id;	struct widget_data *previously_selected_widget;	previously_selected_widget = selected_widget(dlg_data);	do {		dlg_data->selected_widget_id += direction;		if (dlg_data->selected_widget_id >= dlg_data->number_of_widgets)			dlg_data->selected_widget_id = 0;		else if (dlg_data->selected_widget_id < 0)			dlg_data->selected_widget_id = dlg_data->number_of_widgets - 1;	} while (!widget_is_focusable(selected_widget(dlg_data))		 && dlg_data->selected_widget_id != prev_selected);	display_widget(dlg_data, previously_selected_widget);	display_widget(dlg_data, selected_widget(dlg_data));	redraw_from_window(dlg_data->win);}static voiddialog_ev_init(struct dialog_data *dlg_data){	int i;	/* TODO: foreachback_widget() */	for (i = dlg_data->number_of_widgets - 1; i >= 0; i--) {		struct widget_data *widget_data;		widget_data = init_widget(dlg_data, i);		/* Make sure the selected widget is focusable */		if (widget_data		    && widget_is_focusable(widget_data))			dlg_data->selected_widget_id = i;	}}#ifdef CONFIG_MOUSEstatic voiddialog_ev_mouse(struct dialog_data *dlg_data){	struct widget_data *widget_data;	foreach_widget(dlg_data, widget_data) {		if (widget_data->widget->ops->mouse		    && widget_data->widget->ops->mouse(dlg_data, widget_data)		       == EVENT_PROCESSED)			break;	}}#endif /* CONFIG_MOUSE *//* Look up for a button with matching flag. */static voidselect_button_by_flag(struct dialog_data *dlg_data, int flag){	struct widget_data *widget_data;	foreach_widget(dlg_data, widget_data) {		if (widget_data->widget->type == WIDGET_BUTTON		    && widget_data->widget->info.button.flags & flag) {			select_dlg_item(dlg_data, widget_data);			break;		}	}}/* Look up for a button with matching starting letter. */static voidselect_button_by_key(struct dialog_data *dlg_data){	unsigned char key;	struct widget_data *widget_data;	struct term_event *ev = dlg_data->term_event;	if (!check_kbd_label_key(ev)) return;	key = toupper(get_kbd_key(ev));	foreach_widget(dlg_data, widget_data) {		int hk_pos;		if (widget_data->widget->type != WIDGET_BUTTON)			continue;		/* We first try to match marked hotkey if there is		 * one else we fallback to first character in button		 * name. */		hk_pos = widget_data->widget->info.button.hotkey_pos;		if (hk_pos >= 0) {			if (toupper(widget_data->widget->text[hk_pos + 1]) != key)				continue;		} else {			if (toupper(widget_data->widget->text[0]) != key)				continue;		}		select_dlg_item(dlg_data, widget_data);		break;	}}static voiddialog_ev_kbd(struct dialog_data *dlg_data){	struct widget_data *widget_data = selected_widget(dlg_data);	struct widget_ops *ops = widget_data->widget->ops;	/* XXX: KEYMAP_EDIT ? --pasky */	enum menu_action action;	struct term_event *ev = dlg_data->term_event;	/* First let the widget try out. */	if (ops->kbd && ops->kbd(dlg_data, widget_data) == EVENT_PROCESSED)		return;	action = kbd_action(KEYMAP_MENU, ev, NULL);	switch (action) {	case ACT_MENU_SELECT:		/* Can we select? */		if (ops->select) {			ops->select(dlg_data, widget_data);		}		break;	case ACT_MENU_ENTER:		/* Submit button. */		if (ops->select) {			ops->select(dlg_data, widget_data);			break;		}		if (widget_is_textfield(widget_data)		    || check_kbd_modifier(ev, KBD_CTRL)		    || check_kbd_modifier(ev, KBD_ALT)) {			select_button_by_flag(dlg_data, B_ENTER);		}		break;	case ACT_MENU_CANCEL:		/* Cancel button. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -