Exemplo n.º 1
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();
			}
		}
	}
}
Exemplo n.º 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();
		}
	}
}
Exemplo n.º 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();
		}
	}
}
Exemplo n.º 4
0
void menu_add_change_folder::handle()
{
	// process the menu
	const event *menu_event = process(0);

	if (menu_event != nullptr && menu_event->itemref != nullptr)
	{
		if (menu_event->iptkey == IPT_UI_SELECT)
		{
			int index = (uintptr_t)menu_event->itemref - 1;
			const menu_item &pitem = item[index];

			// go up to the parent path
			if (!strcmp(pitem.text.c_str(), ".."))
			{
				size_t first_sep = m_current_path.find_first_of(PATH_SEPARATOR[0]);
				size_t last_sep = m_current_path.find_last_of(PATH_SEPARATOR[0]);
				if (first_sep != last_sep)
					m_current_path.erase(++last_sep);
			}
			else
			{
				// if isn't a drive, appends the directory
				if (strcmp(pitem.subtext.c_str(), "[DRIVE]") != 0)
				{
					if (m_current_path[m_current_path.length() - 1] == PATH_SEPARATOR[0])
						m_current_path.append(pitem.text);
					else
						m_current_path.append(PATH_SEPARATOR).append(pitem.text);
				}
				else
					m_current_path = pitem.text;
			}

			// reset the char buffer also in this case
			m_search[0] = '\0';
			reset(reset_options::SELECT_FIRST);
		}
		else if (menu_event->iptkey == IPT_SPECIAL)
		{
			bool update_selected = false;

			if (menu_event->unichar == 0x09)
			{
				// Tab key, save current path
				std::string error_string;
				if (m_change)
				{
					if (ui().options().exists(s_folders[m_ref].option))
						ui().options().set_value(s_folders[m_ref].option, m_current_path.c_str(), OPTION_PRIORITY_CMDLINE, error_string);
					else if (strcmp(machine().options().value(s_folders[m_ref].option), m_current_path.c_str()) != 0)
					{
						machine().options().set_value(s_folders[m_ref].option, m_current_path.c_str(), OPTION_PRIORITY_CMDLINE, error_string);
						machine().options().mark_changed(s_folders[m_ref].option);
					}
				}
				else
				{
					m_folders.push_back(m_current_path);
					std::string tmppath;
					for (int x = 0; x < m_folders.size(); ++x)
					{
						tmppath.append(m_folders[x]);
						if (x != m_folders.size() - 1)
							tmppath.append(";");
					}

					if (ui().options().exists(s_folders[m_ref].option))
						ui().options().set_value(s_folders[m_ref].option, tmppath.c_str(), OPTION_PRIORITY_CMDLINE, error_string);
					else if (strcmp(machine().options().value(s_folders[m_ref].option), tmppath.c_str()) != 0)
					{
						machine().options().set_value(s_folders[m_ref].option, tmppath.c_str(), OPTION_PRIORITY_CMDLINE, error_string);
						machine().options().mark_changed(s_folders[m_ref].option);
					}
				}

				reset_parent(reset_options::SELECT_FIRST);
				stack_pop();
			}
			else
			{
				// if it's any other key and we're not maxed out, update
				update_selected = input_character(m_search, menu_event->unichar, uchar_is_printable);
			}

			// check for entries which matches our search buffer
			if (update_selected)
			{
				const int cur_selected = selected_index();
				int entry, bestmatch = 0;

				// from current item to the end
				for (entry = cur_selected; entry < item.size(); entry++)
					if (item[entry].ref != nullptr && !m_search.empty())
					{
						int match = 0;
						for (int i = 0; i < m_search.size() + 1; i++)
						{
							if (core_strnicmp(item[entry].text.c_str(), m_search.data(), i) == 0)
								match = i;
						}

						if (match > bestmatch)
						{
							bestmatch = match;
							selected = entry;
						}
					}

				// and from the first item to current one
				for (entry = 0; entry < cur_selected; entry++)
				{
					if (item[entry].ref != nullptr && !m_search.empty())
					{
						int match = 0;
						for (int i = 0; i < m_search.size() + 1; i++)
						{
							if (core_strnicmp(item[entry].text.c_str(), m_search.data(), i) == 0)
								match = i;
						}

						if (match > bestmatch)
						{
							bestmatch = match;
							selected = entry;
						}
					}
				}
				centre_selection();
			}
		}
		else if (menu_event->iptkey == IPT_UI_CANCEL)
		{
			// reset the char buffer also in this case
			m_search.clear();
		}
	}
}