Exemple #1
0
/*
 * Choose and create an instance of an object kind
 */
static void wiz_create_item(void)
{
	int tvals[TV_MAX];
	size_t i, n;

	menu_type *menu = menu_new(MN_SKIN_COLUMNS, &wiz_create_item_menu);

	menu->selections = all_letters;
	menu->title = "What kind of object?";

	/* Make a list of all tvals for the filter */
	for (i = 0, n = 0; i < TV_MAX; i++) {
		if (!kb_info[i].name)
			continue;

		tvals[n++] = i;
	}

	screen_save();
	clear_from(0);

	menu_setpriv(menu, TV_MAX, kb_info);
	menu_set_filter(menu, tvals, n);
	menu_layout(menu, &wiz_create_item_area);
	menu_select(menu, 0, FALSE);

	screen_load();
	
	/* Redraw map */
	p_ptr->redraw |= (PR_MAP | PR_ITEMLIST);
	handle_stuff(p_ptr);

}
Exemple #2
0
/**
 * Interact with some options
 */
static void option_toggle_menu(const char *name, int page)
{
	int i;
	
	struct menu *m = menu_new(MN_SKIN_SCROLL, &option_toggle_iter);

	/* for all menus */
	m->prompt = "Set option (y/n/t), '?' for information";
	m->cmd_keys = "?YyNnTt";
	m->selections = "abcdefghijklmopqrsuvwxz";
	m->flags = MN_DBL_TAP;

	/* We add 10 onto the page amount to indicate we're at birth */
	if (page == OPT_PAGE_BIRTH) {
		m->prompt = "You can only modify these options at character birth. '?' for information";
		m->cmd_keys = "?";
		m->flags = MN_NO_TAGS;
	} else if (page == OPT_PAGE_BIRTH + 10) {
		page -= 10;
	}

	/* for this particular menu */
	m->title = name;

	/* Find the number of valid entries */
	for (i = 0; i < OPT_PAGE_PER; i++) {
		if (option_page[page][i] == OPT_none)
			break;
	}

	/* Set the data to the player's options */
	menu_setpriv(m, OPT_MAX, &op_ptr->opt);
	menu_set_filter(m, option_page[page], i);
	menu_layout(m, &SCREEN_REGION);

	/* Run the menu */
	screen_save();

	clear_from(0);
	menu_select(m, 0, false);

	screen_load();

	mem_free(m);
}
/*
 * Interactive group by.
 * Recognises inscriptions, graphical symbols, lore
 */
static void display_knowledge(const char *title, int *obj_list,
							  int o_count, group_funcs g_funcs,
							  member_funcs o_funcs,
							  const char *otherfields)
{
	/* maximum number of groups to display */
	int max_group = g_funcs.maxnum < o_count ? g_funcs.maxnum : o_count;

	/* This could (should?) be (void **) */
	int *g_list, *g_offset;

	const char **g_names;

	int g_name_len = 8;			/* group name length, minumum is 8 */

	int grp_cnt = 0;			/* total number groups */

	int g_cur = 0, grp_old = -1;	/* group list positions */
	int o_cur = 0;				/* object list positions */
	int g_o_count = 0;			/* object count for group */
	int oid = -1;				/* object identifiers */

	region title_area = { 0, 0, 0, 4 };
	region group_region = { 0, 6, MISSING, -2 };
	region object_region = { MISSING, 6, 0, -2 };

	/* display state variables */
	bool tiles = (current_graphics_mode != NULL);
	bool tile_picker = FALSE;
	bool glyph_picker = FALSE;
	byte attr_top = 0;
	byte char_left = 0;

	int delay = 0;

	menu_type group_menu;
	menu_type object_menu;
	menu_iter object_iter =
		{ NULL, NULL, display_group_member, NULL, NULL };

	/* Panel state */
	/* These are swapped in parallel whenever the actively browsing " */
	/* changes */
	int *active_cursor = &g_cur, *inactive_cursor = &o_cur;
	menu_type *active_menu = &group_menu, *inactive_menu = &object_menu;
	int panel = 0;

	void *swapspace;
	bool do_swap = FALSE;

	bool flag = FALSE;
	bool redraw = TRUE;

	int browser_rows;
	int wid, hgt;
	int i;
	int prev_g = -1;

	int omode = OPT(rogue_like_commands);
	ui_event ke;

	/* Get size */
	Term_get_size(&wid, &hgt);
	browser_rows = hgt - 8;

	/* Disable the roguelike commands for the duration */
	OPT(rogue_like_commands) = FALSE;

	/* Determine if using tiles or not */
	if (tiles)
		tiles = (current_graphics_mode->grafID != 0);

	if (g_funcs.gcomp)
		sort(obj_list, o_count, sizeof(*obj_list), g_funcs.gcomp);

	/* Sort everything into group order */
	g_list = C_ZNEW(max_group + 1, int);
	g_offset = C_ZNEW(max_group + 1, int);

	for (i = 0; i < o_count; i++) {
		if (prev_g != g_funcs.group(obj_list[i])) {
			prev_g = g_funcs.group(obj_list[i]);
			g_offset[grp_cnt] = i;
			g_list[grp_cnt++] = prev_g;
		}
	}

	g_offset[grp_cnt] = o_count;
	g_list[grp_cnt] = -1;


	/* The compact set of group names, in display order */
	g_names = C_ZNEW(grp_cnt, const char *);

	for (i = 0; i < grp_cnt; i++) {
		int len;
		g_names[i] = g_funcs.name(g_list[i]);
		len = strlen(g_names[i]);
		if (len > g_name_len)
			g_name_len = len;
	}

	/* Reasonable max group name len */
	if (g_name_len >= 20)
		g_name_len = 20;

	object_region.col = g_name_len + 3;
	group_region.width = g_name_len;


	/* Leave room for the group summary information */
	if (g_funcs.summary)
		object_region.page_rows = -3;


	/* Set up the two menus */
	menu_init(&group_menu, MN_SKIN_SCROLL,
			  menu_find_iter(MN_ITER_STRINGS));
	menu_setpriv(&group_menu, grp_cnt, g_names);
	menu_layout(&group_menu, &group_region);

	menu_init(&object_menu, MN_SKIN_SCROLL, &object_iter);
	menu_setpriv(&object_menu, 0, &o_funcs);
	menu_layout(&object_menu, &object_region);

	o_funcs.is_visual = FALSE;

	/* Save screen */
	screen_save();
	clear_from(0);


	/* This is the event loop for a multi-region panel */
	/* Panels are -- text panels, two menus, and visual browser */
	/* with "pop-up menu" for lore */
	while ((!flag) && (grp_cnt)) {
		bool recall = FALSE;

		if (redraw) {
			/* Print the title bits */
			region_erase(&title_area);
			prt(format("Knowledge - %s", title), 2, 0);
			prt("Group", 4, 0);
			prt("Name", 4, g_name_len + 3);

			if (otherfields)
				prt(otherfields, 4, 46);


			/* Print dividers: horizontal and vertical */
			for (i = 0; i < 79; i++)
				Term_putch(i, 5, TERM_WHITE, '=');

			for (i = 0; i < browser_rows; i++)
				Term_putch(g_name_len + 1, 6 + i, TERM_WHITE, '|');


			/* Reset redraw flag */
			redraw = FALSE;
		}

		if (g_cur != grp_old) {
			grp_old = g_cur;
			o_cur = 0;
			g_o_count = g_offset[g_cur + 1] - g_offset[g_cur];
			menu_set_filter(&object_menu, obj_list + g_offset[g_cur],
							g_o_count);
			group_menu.cursor = g_cur;
			object_menu.cursor = 0;
		}

		/* HACK ... */
		if (!(tile_picker || glyph_picker)) {
			/* ... The object menu may be browsing the entire group... */
			o_funcs.is_visual = FALSE;
			menu_set_filter(&object_menu, obj_list + g_offset[g_cur],
							g_o_count);
			object_menu.cursor = o_cur;
		} else {
			/* ... or just a single element in the group. */
			o_funcs.is_visual = TRUE;
			menu_set_filter(&object_menu,
							obj_list + o_cur + g_offset[g_cur], 1);
			object_menu.cursor = 0;
		}

		oid = obj_list[g_offset[g_cur] + o_cur];

		/* Print prompt */
		{
			const char *pedit =
				(!o_funcs.xattr) ? "" : (!(attr_idx | char_idx) ?
										 ", 'c' to copy" :
										 ", 'c', 'p' to paste");
			const char *xtra =
				o_funcs.xtra_prompt ? o_funcs.xtra_prompt(oid) : "";
			const char *pvs = "";

			if (tile_picker)
				pvs = ", ENTER to accept";
			else if (glyph_picker)
				pvs = ", 'i' to insert, ENTER to accept";
			else if (o_funcs.xattr)
				pvs = ", 'v' for visuals";

			prt(format("<dir>%s%s%s, ESC", pvs, pedit, xtra), hgt - 1, 0);
		}

		if (do_swap) {
			do_swap = FALSE;
			swap(active_menu, inactive_menu);
			swap(active_cursor, inactive_cursor);
			panel = 1 - panel;
		}

		if (g_funcs.summary && !tile_picker && !glyph_picker) {
			g_funcs.summary(g_cur, obj_list, g_o_count, g_offset[g_cur],
							object_menu.active.row +
							object_menu.active.page_rows,
							object_region.col);
		}

		menu_refresh(inactive_menu, FALSE);
		menu_refresh(active_menu, FALSE);

		handle_stuff(p_ptr);

		if (tile_picker) {
			bigcurs = TRUE;
			display_tiles(g_name_len + 3, 7, browser_rows - 1,
						  wid - (g_name_len + 3), attr_top, char_left);
			place_tile_cursor(g_name_len + 3, 7, *o_funcs.xattr(oid),
							  (byte) * o_funcs.xchar(oid), attr_top,
							  char_left);
		}

		if (glyph_picker) {
			display_glyphs(g_name_len + 3, 7, browser_rows - 1,
						   wid - (g_name_len + 3), *o_funcs.xattr(oid),
						   *o_funcs.xchar(oid));
		}

		if (delay) {
			/* Force screen update */
			Term_fresh();

			/* Delay */
			Term_xtra(TERM_XTRA_DELAY, delay);

			delay = 0;
		}

		ke = inkey_ex();
		if (!tile_picker && !glyph_picker) {
			ui_event ke0 = EVENT_EMPTY;

			if (ke.type == EVT_MOUSE)
				menu_handle_mouse(active_menu, &ke, &ke0);
			else if (ke.type == EVT_KBRD)
				menu_handle_keypress(active_menu, &ke, &ke0);

			if (ke0.type != EVT_NONE)
				ke = ke0;
		}

		/* XXX Do visual mode command if needed */
		if (o_funcs.xattr && o_funcs.xchar) {
			if (tiles) {
				if (tile_picker_command(ke, &tile_picker, browser_rows - 1,
										wid - (g_name_len + 3), &attr_top,
										&char_left, o_funcs.xattr(oid),
										(byte *) o_funcs.xchar(oid),
										g_name_len + 3, 7, &delay))
					continue;
			} else {
				if (glyph_command(ke, &glyph_picker, browser_rows - 1,
								  wid - (g_name_len + 3),
								  o_funcs.xattr(oid), o_funcs.xchar(oid),
								  g_name_len + 3, 7))
					continue;
			}
		}

		switch (ke.type) {
		case EVT_KBRD:
			{
				if (ke.key.code == 'r' || ke.key.code == 'R')
					recall = TRUE;
				else if (o_funcs.xtra_act)
					o_funcs.xtra_act(ke.key, oid);

				break;
			}

		case EVT_MOUSE:
			{
				/* Change active panels */
				if (region_inside(&inactive_menu->boundary, &ke)) {
					swap(active_menu, inactive_menu);
					swap(active_cursor, inactive_cursor);
					panel = 1 - panel;
				}

				continue;
			}

		case EVT_ESCAPE:
			{
				if (panel == 1)
					do_swap = TRUE;
				else
					flag = TRUE;

				break;
			}

		case EVT_SELECT:
			{
				if (panel == 0)
					do_swap = TRUE;
				else if (panel == 1 && oid >= 0
						 && o_cur == active_menu->cursor)
					recall = TRUE;
				break;
			}

		case EVT_MOVE:
			{
				*active_cursor = active_menu->cursor;
				break;
			}

		default:
			{
				break;
			}
		}

		/* Recall on screen */
		if (recall) {
			if (oid >= 0)
				o_funcs.lore(oid);

			redraw = TRUE;
		}
	}

	/* Restore roguelike option */
	OPT(rogue_like_commands) = omode;

	/* Prompt */
	if (!grp_cnt)
		prt(format("No %s known.", title), 15, 0);

	FREE(g_names);
	FREE(g_offset);
	FREE(g_list);

	screen_load();
}