Exemple #1
0
void menu_barcode_reader::populate()
{
	if (current_device())
	{
		std::string buffer;
		const char *new_barcode;

		// selected device
		item_append(current_display_name(), "", current_display_flags(), ITEMREF_SELECT_READER);

		// append the "New Barcode" item
		if (get_selection_ref() == ITEMREF_NEW_BARCODE)
		{
			buffer.append(m_barcode_buffer);
			new_barcode = buffer.c_str();
		}
		else
		{
			new_barcode = m_barcode_buffer;
		}

		item_append(_("New Barcode:"), new_barcode, 0, ITEMREF_NEW_BARCODE);

		// finish up the menu
		item_append(menu_item_type::SEPARATOR);
		item_append(_("Enter Code"), "", 0, ITEMREF_ENTER_BARCODE);

		customtop = ui().get_line_height() + 3.0f * UI_BOX_TB_BORDER;
	}
}
Exemple #2
0
void menu_software_list::handle()
{
	const entry_info *selected_entry = nullptr;
	int bestmatch = 0;

	// process the menu
	const event *event = process(0);

	if (event && event->itemref)
	{
		if ((uintptr_t)event->itemref == 1 && event->iptkey == IPT_UI_SELECT)
		{
			m_ordered_by_shortname = !m_ordered_by_shortname;

			// reset the char buffer if we change ordering criterion
			m_filename_buffer.clear();

			// reload the menu with the new order
			reset(reset_options::REMEMBER_REF);
			machine().popmessage(_("Switched Order: entries now ordered by %s"), m_ordered_by_shortname ? _("shortname") : _("description"));
		}
		// handle selections
		else if (event->iptkey == IPT_UI_SELECT)
		{
			entry_info *info = (entry_info *) event->itemref;
			m_result = info->short_name;
			stack_pop();
		}
		else if (event->iptkey == IPT_SPECIAL)
		{
			if (input_character(m_filename_buffer, event->unichar, &is_valid_softlist_part_char))
			{
				// display the popup
				ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename_buffer);

				// identify the selected entry
				entry_info const *const cur_selected = (uintptr_t(event->itemref) != 1)
						? reinterpret_cast<entry_info const *>(get_selection_ref())
						: nullptr;

				// loop through all entries
				for (auto &entry : m_entrylist)
				{
					// is this entry the selected entry?
					if (cur_selected != &entry)
					{
						auto &compare_name = m_ordered_by_shortname ? entry.short_name : entry.long_name;

						int match = 0;
						for (int i = 0; i < m_filename_buffer.size() + 1; i++)
						{
							if (core_strnicmp(compare_name.c_str(), m_filename_buffer.c_str(), i) == 0)
								match = i;
						}

						if (match > bestmatch)
						{
							bestmatch = match;
							selected_entry = &entry;
						}
					}
				}

				if (selected_entry != nullptr && selected_entry != cur_selected)
				{
					set_selection((void *)selected_entry);
					centre_selection();
				}
			}
		}
		else if (event->iptkey == IPT_UI_CANCEL)
		{
			// reset the char buffer also in this case
			m_filename_buffer.clear();
			m_result = m_filename_buffer;
			stack_pop();
		}
	}
}
Exemple #3
0
void menu_file_selector::handle()
{
	osd_file::error err;
	const file_selector_entry *selected_entry = nullptr;
	int bestmatch = 0;

	// process the menu
	const event *event = process(0);
	if (event != nullptr && event->itemref != nullptr)
	{
		// handle selections
		if (event->iptkey == IPT_UI_SELECT)
		{
			auto entry = (const file_selector_entry *) event->itemref;
			switch (entry->type)
			{
			case SELECTOR_ENTRY_TYPE_EMPTY:
				// empty slot - unload
				m_result = result::EMPTY;
				stack_pop();
				break;

			case SELECTOR_ENTRY_TYPE_CREATE:
				// create
				m_result = result::CREATE;
				stack_pop();
				break;

			case SELECTOR_ENTRY_TYPE_SOFTWARE_LIST:
				m_result = result::SOFTLIST;
				stack_pop();
				break;

			case SELECTOR_ENTRY_TYPE_DRIVE:
			case SELECTOR_ENTRY_TYPE_DIRECTORY:
				// drive/directory - first check the path
				err = util::zippath_opendir(entry->fullpath, nullptr);
				if (err != osd_file::error::NONE)
				{
					// this path is problematic; present the user with an error and bail
					ui().popup_time(1, "Error accessing %s", entry->fullpath);
					break;
				}
				m_current_directory.assign(entry->fullpath);
				reset(reset_options::SELECT_FIRST);
				break;

			case SELECTOR_ENTRY_TYPE_FILE:
				// file
				m_current_file.assign(entry->fullpath);
				m_result = result::FILE;
				stack_pop();
				break;
			}

			// reset the char buffer when pressing IPT_UI_SELECT
			m_filename.clear();
		}
		else if (event->iptkey == IPT_SPECIAL)
		{
			// if it's any other key and we're not maxed out, update
			if (input_character(m_filename, event->unichar, uchar_is_printable))
			{
				ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename.c_str());

				file_selector_entry const *const cur_selected(reinterpret_cast<file_selector_entry const *>(get_selection_ref()));

				// check for entries which matches our m_filename_buffer:
				for (auto &entry : m_entrylist)
				{
					if (cur_selected != &entry)
					{
						int match = 0;
						for (int i = 0; i < m_filename.size() + 1; i++)
						{
							if (core_strnicmp(entry.basename.c_str(), m_filename.c_str(), i) == 0)
								match = i;
						}

						if (match > bestmatch)
						{
							bestmatch = match;
							selected_entry = &entry;
						}
					}
				}

				if (selected_entry != nullptr && selected_entry != cur_selected)
				{
					set_selection((void *)selected_entry);
					centre_selection();
				}
			}
		}
		else if (event->iptkey == IPT_UI_CANCEL)
		{
			// reset the char buffer also in this case
			m_filename.clear();
		}
	}
}
Exemple #4
0
void menu_dats_view::draw(uint32_t flags)
{
	auto line_height = ui().get_line_height();
	auto ud_arrow_width = line_height * machine().render().ui_aspect();
	auto gutter_width = 0.52f * line_height * machine().render().ui_aspect();
	mouse_x = -1, mouse_y = -1;
	float visible_width = 1.0f - 2.0f * UI_BOX_LR_BORDER;
	float visible_left = (1.0f - visible_width) * 0.5f;

	draw_background();

	hover = item.size() + 1;
	visible_items = item.size() - 2;
	float extra_height = 2.0f * line_height;
	float visible_extra_menu_height = customtop + custombottom + extra_height;

	// locate mouse
	mouse_hit = false;
	mouse_button = false;
	mouse_target = machine().ui_input().find_mouse(&mouse_target_x, &mouse_target_y, &mouse_button);
	if (mouse_target != nullptr)
		if (mouse_target->map_point_container(mouse_target_x, mouse_target_y, container(), mouse_x, mouse_y))
			mouse_hit = true;

	// account for extra space at the top and bottom
	float visible_main_menu_height = 1.0f - 2.0f * UI_BOX_TB_BORDER - visible_extra_menu_height;
	m_visible_lines = int(std::trunc(visible_main_menu_height / line_height));
	visible_main_menu_height = float(m_visible_lines) * line_height;

	// compute top/left of inner menu area by centering
	float 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;

	// compute left box size
	float x1 = visible_left;
	float y1 = visible_top - UI_BOX_TB_BORDER;
	float x2 = x1 + visible_width;
	float y2 = visible_top + visible_main_menu_height + UI_BOX_TB_BORDER + extra_height;
	float line = visible_top + float(m_visible_lines) * line_height;

	ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_BACKGROUND_COLOR);

	m_visible_lines = (std::min)(visible_items, m_visible_lines);
	top_line = (std::max)(0, top_line);
	if (top_line + m_visible_lines >= visible_items)
		top_line = visible_items - m_visible_lines;

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

	int const n_loop = (std::min)(visible_items, m_visible_lines);
	for (int linenum = 0; linenum < n_loop; linenum++)
	{
		float line_y = visible_top + (float)linenum * line_height;
		int itemnum = top_line + linenum;
		const menu_item &pitem = item[itemnum];
		const char *itemtext = pitem.text.c_str();
		rgb_t fgcolor = UI_TEXT_COLOR;
		rgb_t bgcolor = UI_TEXT_BG_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;

		// if we're on the top line, display the up arrow
		if (linenum == 0 && top_line != 0)
		{
			draw_arrow(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, ROT0);

			if (mouse_hit && line_x0 <= mouse_x && line_x1 > mouse_x && line_y0 <= mouse_y && line_y1 > mouse_y)
			{
				fgcolor = UI_MOUSEOVER_COLOR;
				bgcolor = UI_MOUSEOVER_BG_COLOR;
				highlight(line_x0, line_y0, line_x1, line_y1, bgcolor);
				hover = HOVER_ARROW_UP;
			}
		}
		// if we're on the bottom line, display the down arrow
		else if (linenum == m_visible_lines - 1 && itemnum != visible_items - 1)
		{
			draw_arrow(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, ROT0 ^ ORIENTATION_FLIP_Y);

			if (mouse_hit && line_x0 <= mouse_x && line_x1 > mouse_x && line_y0 <= mouse_y && line_y1 > mouse_y)
			{
				fgcolor = UI_MOUSEOVER_COLOR;
				bgcolor = UI_MOUSEOVER_BG_COLOR;
				highlight(line_x0, line_y0, line_x1, line_y1, bgcolor);
				hover = HOVER_ARROW_DOWN;
			}
		}

		// draw dats text
		else if (pitem.subtext.empty())
		{
			ui().draw_text_full(container(), itemtext, effective_left, line_y, effective_width, ui::text_layout::LEFT, ui::text_layout::NEVER,
				mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr);
		}
	}

	for (size_t count = visible_items; count < item.size(); count++)
	{
		const menu_item &pitem = item[count];
		const char *itemtext = pitem.text.c_str();
		float line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
		float line_y0 = line;
		float line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
		float line_y1 = line + line_height;
		rgb_t fgcolor = UI_SELECTED_COLOR;
		rgb_t bgcolor = UI_SELECTED_BG_COLOR;

		if (mouse_hit && line_x0 <= mouse_x && line_x1 > mouse_x && line_y0 <= mouse_y && line_y1 > mouse_y && is_selectable(pitem))
			hover = count;

		if (pitem.type == menu_item_type::SEPARATOR)
			container().add_line(visible_left, line + 0.5f * line_height, visible_left + visible_width, line + 0.5f * line_height,
				UI_LINE_WIDTH, UI_TEXT_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
		else
		{
			highlight(line_x0, line_y0, line_x1, line_y1, bgcolor);
			ui().draw_text_full(container(), itemtext, effective_left, line, effective_width, ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
				mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr);
		}
		line += line_height;
	}

	// if there is something special to add, do it by calling the virtual method
	custom_render(get_selection_ref(), customtop, custombottom, x1, y1, x2, y2);

	// return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
	m_visible_items = m_visible_lines - (top_line != 0) - (top_line + m_visible_lines != visible_items);
}
Exemple #5
0
void menu_barcode_reader::handle()
{
	// rebuild the menu (so to update the selected device, if the user has pressed L or R)
	reset(reset_options::REMEMBER_POSITION);
	populate();

	// process the menu
	const event *event = process(PROCESS_LR_REPEAT);

	// process the event
	if (event)
	{
		// handle selections
		switch (event->iptkey)
		{
		case IPT_UI_LEFT:
			if (event->itemref == ITEMREF_SELECT_READER)
				previous();
			break;

		case IPT_UI_RIGHT:
			if (event->itemref == ITEMREF_SELECT_READER)
				next();
			break;

		case IPT_UI_SELECT:
			if (event->itemref == ITEMREF_ENTER_BARCODE)
			{
				std::string tmp_file(m_barcode_buffer);
				//printf("code %s\n", m_barcode_buffer);
				if (!current_device()->is_valid(tmp_file.length()))
					ui().popup_time(5, "%s", _("Barcode length invalid!"));
				else
				{
					current_device()->write_code(tmp_file.c_str(), tmp_file.length());
					// if sending was successful, reset char buffer
					if (m_barcode_buffer[0] != '\0')
						memset(m_barcode_buffer, '\0', ARRAY_LENGTH(m_barcode_buffer));
					reset(reset_options::REMEMBER_POSITION);
				}
			}
			break;

		case IPT_SPECIAL:
			if (get_selection_ref() == ITEMREF_NEW_BARCODE)
			{
				auto const buflen = std::strlen(m_barcode_buffer);

				// if it's a backspace and we can handle it, do so
				if ((event->unichar == 8) || (event->unichar == 0x7f))
				{
					if (0 < buflen)
						*const_cast<char *>(utf8_previous_char(&m_barcode_buffer[buflen])) = 0;
				}
				else if ((event->unichar >= '0') && (event->unichar <= '9'))
				{
					event->append_char(m_barcode_buffer, buflen);
				}
				reset(reset_options::REMEMBER_POSITION);
			}
			break;

		case IPT_UI_CANCEL:
			// reset the char buffer also in this case
			if (m_barcode_buffer[0] != '\0')
				memset(m_barcode_buffer, '\0', ARRAY_LENGTH(m_barcode_buffer));
			break;
		}
	}
}
Exemple #6
0
void menu_file_selector::type_search_char(char32_t ch)
{
	std::string const current(m_filename);
	if (input_character(m_filename, ch, uchar_is_printable))
	{
		ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename.c_str());

		file_selector_entry const *const cur_selected(reinterpret_cast<file_selector_entry const *>(get_selection_ref()));

		// if it's a perfect match for the current selection, don't move it
		if (!cur_selected || core_strnicmp(cur_selected->basename.c_str(), m_filename.c_str(), m_filename.size()))
		{
			std::string::size_type bestmatch(0);
			file_selector_entry const *selected_entry(cur_selected);
			for (auto &entry : m_entrylist)
			{
				// TODO: more efficient "common prefix" code
				std::string::size_type match(0);
				for (std::string::size_type i = 1; m_filename.size() >= i; ++i)
				{
					if (!core_strnicmp(entry.basename.c_str(), m_filename.c_str(), i))
						match = i;
					else
						break;
				}

				if (match > bestmatch)
				{
					bestmatch = match;
					selected_entry = &entry;
				}
			}

			if (selected_entry && (selected_entry != cur_selected))
			{
				set_selection((void *)selected_entry);
				centre_selection();
			}
		}
	}
}