Beispiel #1
0
void ui_menu::draw_text_box()
{
	const char *text = item[0].text;
	const char *backtext = item[1].text;
	float line_height = ui_get_line_height(machine());
	float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
	float gutter_width = lr_arrow_width;
	float target_width, target_height, prior_width;
	float target_x, target_y;

	/* compute the multi-line target width/height */
	ui_draw_text_full(container, text, 0, 0, 1.0f - 2.0f * UI_BOX_LR_BORDER - 2.0f * gutter_width,
				JUSTIFY_LEFT, WRAP_WORD, DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &target_width, &target_height);
	target_height += 2.0f * line_height;
	if (target_height > 1.0f - 2.0f * UI_BOX_TB_BORDER)
		target_height = floor((1.0f - 2.0f * UI_BOX_TB_BORDER) / line_height) * line_height;

	/* maximum against "return to prior menu" text */
	prior_width = ui_get_string_width(machine(), backtext) + 2.0f * gutter_width;
	target_width = MAX(target_width, prior_width);

	/* determine the target location */
	target_x = 0.5f - 0.5f * target_width;
	target_y = 0.5f - 0.5f * target_height;

	/* make sure we stay on-screen */
	if (target_x < UI_BOX_LR_BORDER + gutter_width)
		target_x = UI_BOX_LR_BORDER + gutter_width;
	if (target_x + target_width + gutter_width + UI_BOX_LR_BORDER > 1.0f)
		target_x = 1.0f - UI_BOX_LR_BORDER - gutter_width - target_width;
	if (target_y < UI_BOX_TB_BORDER)
		target_y = UI_BOX_TB_BORDER;
	if (target_y + target_height + UI_BOX_TB_BORDER > 1.0f)
		target_y = 1.0f - UI_BOX_TB_BORDER - target_height;

	/* add a box around that */
	ui_draw_outlined_box(container, target_x - UI_BOX_LR_BORDER - gutter_width,
						target_y - UI_BOX_TB_BORDER,
						target_x + target_width + gutter_width + UI_BOX_LR_BORDER,
						target_y + target_height + UI_BOX_TB_BORDER, (item[0].flags & MENU_FLAG_REDTEXT) ?  UI_RED_COLOR : UI_BACKGROUND_COLOR);
	ui_draw_text_full(container, text, target_x, target_y, target_width,
				JUSTIFY_LEFT, WRAP_WORD, DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, NULL, NULL);

	/* draw the "return to prior menu" text with a hilight behind it */
	container->add_quad(
						target_x + 0.5f * UI_LINE_WIDTH,
						target_y + target_height - line_height,
						target_x + target_width - 0.5f * UI_LINE_WIDTH,
						target_y + target_height,
						UI_SELECTED_BG_COLOR,
						hilight_texture,
						PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
	ui_draw_text_full(container, backtext, target_x, target_y + target_height - line_height, target_width,
				JUSTIFY_CENTER, WRAP_TRUNCATE, DRAW_NORMAL, UI_SELECTED_COLOR, UI_SELECTED_BG_COLOR, NULL, NULL);

	/* artificially set the hover to the last item so a double-click exits */
	hover = numitems - 1;
}
Beispiel #2
0
void cheat_manager::render_text(render_container &container)
{
	// render any text and free it along the way
	for (int linenum = 0; linenum < ARRAY_LENGTH(m_output); linenum++)
		if (m_output[linenum])
		{
			// output the text
			ui_draw_text_full(&container, m_output[linenum],
					0.0f, (float)linenum * ui_get_line_height(machine()), 1.0f,
					m_justify[linenum], WRAP_NEVER, DRAW_OPAQUE,
					ARGB_WHITE, ARGB_BLACK, NULL, NULL);
		}
}
Beispiel #3
0
static void extra_text_draw_box(render_container *container, float origx1, float origx2, float origy, float yspan, const char *text, int direction)
{
    float text_width, text_height;
    float width, maxwidth;
    float x1, y1, x2, y2, temp;

    /* get the size of the text */
    ui_draw_text_full(container,text, 0.0f, 0.0f, 1.0f, JUSTIFY_LEFT, WRAP_WORD,
                      DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &text_width, &text_height);
    width = text_width + (2 * UI_BOX_LR_BORDER);
    maxwidth = MAX(width, origx2 - origx1);

    /* compute our bounds */
    x1 = 0.5f - 0.5f * maxwidth;
    x2 = x1 + maxwidth;
    y1 = origy + (yspan * direction);
    y2 = origy + (UI_BOX_TB_BORDER * direction);

    if (y1 > y2)
    {
        temp = y1;
        y1 = y2;
        y2 = temp;
    }

    /* draw a box */
    ui_draw_outlined_box(container,x1, y1, x2, y2, UI_BACKGROUND_COLOR);

    /* take off the borders */
    x1 += UI_BOX_LR_BORDER;
    x2 -= UI_BOX_LR_BORDER;
    y1 += UI_BOX_TB_BORDER;
    y2 -= UI_BOX_TB_BORDER;

    /* draw the text within it */
    ui_draw_text_full(container,text, x1, y1, text_width, JUSTIFY_LEFT, WRAP_WORD,
                      DRAW_NORMAL, ARGB_WHITE, ARGB_BLACK, NULL, NULL);
}
Beispiel #4
0
void ui_menu::draw(bool customonly)
{
	float line_height = ui_get_line_height(machine());
	float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
	float ud_arrow_width = line_height * machine().render().ui_aspect();
	float gutter_width = lr_arrow_width * 1.3f;
	float x1, y1, x2, y2;

	float effective_width, effective_left;
	float visible_width, visible_main_menu_height;
	float visible_extra_menu_height = 0;
	float visible_top, visible_left;
	int selected_subitem_too_big = FALSE;
	int visible_lines;
	int top_line;
	int itemnum, linenum;
	int mouse_hit, mouse_button;
	render_target *mouse_target;
	INT32 mouse_target_x, mouse_target_y;
	float mouse_x = -1, mouse_y = -1;

	/* compute the width and height of the full menu */
	visible_width = 0;
	visible_main_menu_height = 0;
	for (itemnum = 0; itemnum < numitems; itemnum++)
	{
		const ui_menu_item &pitem = item[itemnum];
		float total_width;

		/* compute width of left hand side */
		total_width = gutter_width + ui_get_string_width(machine(), pitem.text) + gutter_width;

		/* add in width of right hand side */
		if (pitem.subtext)
			total_width += 2.0f * gutter_width + ui_get_string_width(machine(), pitem.subtext);

		/* track the maximum */
		if (total_width > visible_width)
			visible_width = total_width;

		/* track the height as well */
		visible_main_menu_height += line_height;
	}

	/* account for extra space at the top and bottom */
	visible_extra_menu_height = customtop + custombottom;

	/* add a little bit of slop for rounding */
	visible_width += 0.01f;
	visible_main_menu_height += 0.01f;

	/* if we are too wide or too tall, clamp it down */
	if (visible_width + 2.0f * UI_BOX_LR_BORDER > 1.0f)
		visible_width = 1.0f - 2.0f * UI_BOX_LR_BORDER;

	/* if the menu and extra menu won't fit, take away part of the regular menu, it will scroll */
	if (visible_main_menu_height + visible_extra_menu_height + 2.0f * UI_BOX_TB_BORDER > 1.0f)
		visible_main_menu_height = 1.0f - 2.0f * UI_BOX_TB_BORDER - visible_extra_menu_height;

	visible_lines = floor(visible_main_menu_height / line_height);
	visible_main_menu_height = (float)visible_lines * line_height;

	/* compute top/left of inner menu area by centering */
	visible_left = (1.0f - visible_width) * 0.5f;
	visible_top = (1.0f - (visible_main_menu_height + visible_extra_menu_height)) * 0.5f;

	/* if the menu is at the bottom of the extra, adjust */
	visible_top += customtop;

	/* first add us a box */
	x1 = visible_left - UI_BOX_LR_BORDER;
	y1 = visible_top - UI_BOX_TB_BORDER;
	x2 = visible_left + visible_width + UI_BOX_LR_BORDER;
	y2 = visible_top + visible_main_menu_height + UI_BOX_TB_BORDER;
	if (!customonly)
		ui_draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);

	/* determine the first visible line based on the current selection */
	top_line = selected - visible_lines / 2;
	if (top_line < 0)
		top_line = 0;
	if (top_line + visible_lines >= numitems)
		top_line = numitems - visible_lines;

	/* determine effective positions taking into account the hilighting arrows */
	effective_width = visible_width - 2.0f * gutter_width;
	effective_left = visible_left + gutter_width;

	/* locate mouse */
	mouse_hit = FALSE;
	mouse_button = FALSE;
	if (!customonly)
	{
		mouse_target = ui_input_find_mouse(machine(), &mouse_target_x, &mouse_target_y, &mouse_button);
		if (mouse_target != NULL)
			if (mouse_target->map_point_container(mouse_target_x, mouse_target_y, *container, mouse_x, mouse_y))
				mouse_hit = TRUE;
	}

	/* loop over visible lines */
	hover = numitems + 1;
	if (!customonly)
		for (linenum = 0; linenum < visible_lines; linenum++)
		{
			float line_y = visible_top + (float)linenum * line_height;
			itemnum = top_line + linenum;
			const ui_menu_item &pitem = item[itemnum];
			const char *itemtext = pitem.text;
			rgb_t fgcolor = UI_TEXT_COLOR;
			rgb_t bgcolor = UI_TEXT_BG_COLOR;
			rgb_t fgcolor2 = UI_SUBITEM_COLOR;
			rgb_t fgcolor3 = UI_CLONE_COLOR;
			float line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
			float line_y0 = line_y;
			float line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
			float line_y1 = line_y + line_height;

			/* set the hover if this is our item */
			if (mouse_hit && line_x0 <= mouse_x && line_x1 > mouse_x && line_y0 <= mouse_y && line_y1 > mouse_y && pitem.is_selectable())
				hover = itemnum;

			/* if we're selected, draw with a different background */
			if (itemnum == selected)
			{
				fgcolor = UI_SELECTED_COLOR;
				bgcolor = UI_SELECTED_BG_COLOR;
				fgcolor2 = UI_SELECTED_COLOR;
				fgcolor3 = UI_SELECTED_COLOR;
			}

			/* else if the mouse is over this item, draw with a different background */
			else if (itemnum == hover)
			{
				fgcolor = UI_MOUSEOVER_COLOR;
				bgcolor = UI_MOUSEOVER_BG_COLOR;
				fgcolor2 = UI_MOUSEOVER_COLOR;
				fgcolor3 = UI_MOUSEOVER_COLOR;
			}

			/* if we have some background hilighting to do, add a quad behind everything else */
			if (bgcolor != UI_TEXT_BG_COLOR)
				container->add_quad(line_x0, line_y0, line_x1, line_y1, bgcolor, hilight_texture,
									PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));

			/* if we're on the top line, display the up arrow */
			if (linenum == 0 && top_line != 0)
			{
				container->add_quad(
									0.5f * (x1 + x2) - 0.5f * ud_arrow_width,
									line_y + 0.25f * line_height,
									0.5f * (x1 + x2) + 0.5f * ud_arrow_width,
									line_y + 0.75f * line_height,
									fgcolor,
									arrow_texture,
									PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT0));
				if (hover == itemnum)
					hover = -2;
			}

			/* if we're on the bottom line, display the down arrow */
			else if (linenum == visible_lines - 1 && itemnum != numitems - 1)
			{
				container->add_quad(
									0.5f * (x1 + x2) - 0.5f * ud_arrow_width,
									line_y + 0.25f * line_height,
									0.5f * (x1 + x2) + 0.5f * ud_arrow_width,
									line_y + 0.75f * line_height,
									fgcolor,
									arrow_texture,
									PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT0 ^ ORIENTATION_FLIP_Y));
				if (hover == itemnum)
					hover = -1;
			}

			/* if we're just a divider, draw a line */
			else if (strcmp(itemtext, MENU_SEPARATOR_ITEM) == 0)
				container->add_line(visible_left, line_y + 0.5f * line_height, visible_left + visible_width, line_y + 0.5f * line_height, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));

			/* if we don't have a subitem, just draw the string centered */
			else if (pitem.subtext == NULL)
				ui_draw_text_full(container, itemtext, effective_left, line_y, effective_width,
							JUSTIFY_CENTER, WRAP_TRUNCATE, DRAW_NORMAL, fgcolor, bgcolor, NULL, NULL);

			/* otherwise, draw the item on the left and the subitem text on the right */
			else
			{
				int subitem_invert = pitem.flags & MENU_FLAG_INVERT;
				const char *subitem_text = pitem.subtext;
				float item_width, subitem_width;

				/* draw the left-side text */
				ui_draw_text_full(container, itemtext, effective_left, line_y, effective_width,
							JUSTIFY_LEFT, WRAP_TRUNCATE, DRAW_NORMAL, fgcolor, bgcolor, &item_width, NULL);

				/* give 2 spaces worth of padding */
				item_width += 2.0f * gutter_width;

				/* if the subitem doesn't fit here, display dots */
				if (ui_get_string_width(machine(), subitem_text) > effective_width - item_width)
				{
					subitem_text = "...";
					if (itemnum == selected)
						selected_subitem_too_big = TRUE;
				}

				/* draw the subitem right-justified */
				ui_draw_text_full(container, subitem_text, effective_left + item_width, line_y, effective_width - item_width,
							JUSTIFY_RIGHT, WRAP_TRUNCATE, DRAW_NORMAL, subitem_invert ? fgcolor3 : fgcolor2, bgcolor, &subitem_width, NULL);

				/* apply arrows */
				if (itemnum == selected && (pitem.flags & MENU_FLAG_LEFT_ARROW))
				{
					container->add_quad(
										effective_left + effective_width - subitem_width - gutter_width,
										line_y + 0.1f * line_height,
										effective_left + effective_width - subitem_width - gutter_width + lr_arrow_width,
										line_y + 0.9f * line_height,
										fgcolor,
										arrow_texture,
										PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90 ^ ORIENTATION_FLIP_X));
				}
				if (itemnum == selected && (pitem.flags & MENU_FLAG_RIGHT_ARROW))
				{
					container->add_quad(
										effective_left + effective_width + gutter_width - lr_arrow_width,
										line_y + 0.1f * line_height,
										effective_left + effective_width + gutter_width,
										line_y + 0.9f * line_height,
										fgcolor,
										arrow_texture,
										PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90));
				}
			}
		}

	/* if the selected subitem is too big, display it in a separate offset box */
	if (selected_subitem_too_big)
	{
		const ui_menu_item &pitem = item[selected];
		int subitem_invert = pitem.flags & MENU_FLAG_INVERT;
		linenum = selected - top_line;
		float line_y = visible_top + (float)linenum * line_height;
		float target_width, target_height;
		float target_x, target_y;

		/* compute the multi-line target width/height */
		ui_draw_text_full(container, pitem.subtext, 0, 0, visible_width * 0.75f,
					JUSTIFY_RIGHT, WRAP_WORD, DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &target_width, &target_height);

		/* determine the target location */
		target_x = visible_left + visible_width - target_width - UI_BOX_LR_BORDER;
		target_y = line_y + line_height + UI_BOX_TB_BORDER;
		if (target_y + target_height + UI_BOX_TB_BORDER > visible_main_menu_height)
			target_y = line_y - target_height - UI_BOX_TB_BORDER;

		/* add a box around that */
		ui_draw_outlined_box(container, target_x - UI_BOX_LR_BORDER,
							target_y - UI_BOX_TB_BORDER,
							target_x + target_width + UI_BOX_LR_BORDER,
							target_y + target_height + UI_BOX_TB_BORDER, subitem_invert ? UI_SELECTED_BG_COLOR : UI_BACKGROUND_COLOR);
		ui_draw_text_full(container, pitem.subtext, target_x, target_y, target_width,
					JUSTIFY_RIGHT, WRAP_WORD, DRAW_NORMAL, UI_SELECTED_COLOR, UI_SELECTED_BG_COLOR, NULL, NULL);
	}

	/* if there is something special to add, do it by calling the virtual method */
	custom_render((selected >= 0 && selected < numitems) ? item[selected].ref : NULL, customtop, custombottom, x1, y1, x2, y2);

	/* return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow */
	visitems = visible_lines - (top_line != 0) - (top_line + visible_lines != numitems);
}