void ui_menu_rgb_ui::inkey_special(const ui_menu_event *m_event) { if (m_event->iptkey == IPT_UI_SELECT) { m_key_active = !m_key_active; m_lock_ref = (FPTR)m_event->itemref; if (!m_key_active) { int val = atoi(m_search); val = m_color->clamp(val); switch ((FPTR)m_event->itemref) { case RGB_ALPHA: m_color->set_a(val); break; case RGB_RED: m_color->set_r(val); break; case RGB_GREEN: m_color->set_g(val); break; case RGB_BLUE: m_color->set_b(val); break; } m_search[0] = 0; m_lock_ref = 0; return; } } if (!m_key_active) { m_search[0] = 0; return; } int buflen = strlen(m_search); // if it's a backspace and we can handle it, do so if (((m_event->unichar == 8 || m_event->unichar == 0x7f) && buflen > 0)) *(char *)utf8_previous_char(&m_search[buflen]) = 0; else if (buflen >= 3) return; // if it's any other key and we're not maxed out, update else if ((m_event->unichar >= '0' && m_event->unichar <= '9')) buflen += utf8_from_uchar(&m_search[buflen], ARRAY_LENGTH(m_search) - buflen, m_event->unichar); m_search[buflen] = 0; }
static void input_character(char *buffer, size_t buffer_length, unicode_char unichar, int (*filter)(unicode_char)) { size_t buflen = strlen(buffer); if ((unichar == 8 || unichar == 0x7f) && (buflen > 0)) { *(char *)utf8_previous_char(&buffer[buflen]) = 0; } else if ((unichar > ' ') && ((filter == NULL) || (*filter)(unichar))) { buflen += utf8_from_uchar(&buffer[buflen], buffer_length - buflen, unichar); buffer[buflen] = 0; } }
void ui_menu_select_game::inkey_special(const ui_menu_event *menu_event) { // typed characters append to the buffer int buflen = strlen(m_search); // if it's a backspace and we can handle it, do so if ((menu_event->unichar == 8 || menu_event->unichar == 0x7f) && buflen > 0) { *(char *)utf8_previous_char(&m_search[buflen]) = 0; m_rerandomize = true; reset(UI_MENU_RESET_SELECT_FIRST); } // if it's any other key and we're not maxed out, update else if (menu_event->unichar >= ' ' && menu_event->unichar < 0x7f) { buflen += utf8_from_uchar(&m_search[buflen], ARRAY_LENGTH(m_search) - buflen, menu_event->unichar); m_search[buflen] = 0; reset(UI_MENU_RESET_SELECT_FIRST); } }
void ui_menu_barcode_reader::handle() { // rebuild the menu (so to update the selected device, if the user has pressed L or R) reset(UI_MENU_RESET_REMEMBER_POSITION); populate(); // process the menu const ui_menu_event *event = process(UI_MENU_PROCESS_LR_REPEAT); // process the event if (event != NULL) { // 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())) machine().ui().popup_time(5, "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(UI_MENU_RESET_REMEMBER_POSITION); } } break; case IPT_SPECIAL: if (get_selection() == ITEMREF_NEW_BARCODE) { int buflen = strlen(m_barcode_buffer); // if it's a backspace and we can handle it, do so if ((event->unichar == 8 || event->unichar == 0x7f) && buflen > 0) *(char *)utf8_previous_char(&m_barcode_buffer[buflen]) = 0; else if (event->unichar >= '0' && event->unichar <= '9') { buflen += utf8_from_uchar(&m_barcode_buffer[buflen], ARRAY_LENGTH(m_barcode_buffer) - buflen, event->unichar); m_barcode_buffer[buflen] = 0; } reset(UI_MENU_RESET_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; } } }
void menu_selector::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) { for (size_t idx = 0; idx < m_str_items.size(); ++idx) if ((void*)&m_str_items[idx] == menu_event->itemref) m_selector = idx; switch (m_category) { case INIFILE: mame_machine_manager::instance()->inifile().set_file(m_selector); mame_machine_manager::instance()->inifile().set_cat(0); reset_parent(reset_options::REMEMBER_REF); break; case CATEGORY: mame_machine_manager::instance()->inifile().set_cat(m_selector); reset_parent(reset_options::REMEMBER_REF); break; case GAME: main_filters::actual = m_hover; reset_parent(reset_options::SELECT_FIRST); break; case SOFTWARE: sw_filters::actual = m_hover; reset_parent(reset_options::SELECT_FIRST); break; default: reset_parent(reset_options::REMEMBER_REF); break; } ui_globals::switch_image = true; stack_pop(); } else if (menu_event->iptkey == IPT_SPECIAL) { auto const buflen = strlen(m_search); if ((menu_event->unichar == 8) || (menu_event->unichar == 0x7f)) { // if it's a backspace and we can handle it, do so if (0 < buflen) { *const_cast<char *>(utf8_previous_char(&m_search[buflen])) = 0; reset(reset_options::SELECT_FIRST); } } else if (menu_event->is_char_printable()) { // if it's any other key and we're not maxed out, update if (menu_event->append_char(m_search, buflen)) reset(reset_options::SELECT_FIRST); } } // escape pressed with non-empty text clears the text else if (menu_event->iptkey == IPT_UI_CANCEL && m_search[0] != 0) { m_search[0] = '\0'; reset(reset_options::SELECT_FIRST); } } }
void ui_menu_file_selector::handle() { file_error err; const file_selector_entry *entry; const file_selector_entry *selected_entry = NULL; int bestmatch = 0; // process the menu const ui_menu_event *event = process(0); if (event != NULL && event->itemref != NULL) { // handle selections if (event->iptkey == IPT_UI_SELECT) { entry = (const file_selector_entry *) event->itemref; switch(entry->type) { case SELECTOR_ENTRY_TYPE_EMPTY: // empty slot - unload *m_result = R_EMPTY; ui_menu::stack_pop(machine()); break; case SELECTOR_ENTRY_TYPE_CREATE: // create *m_result = R_CREATE; ui_menu::stack_pop(machine()); break; case SELECTOR_ENTRY_TYPE_SOFTWARE_LIST: *m_result = R_SOFTLIST; ui_menu::stack_pop(machine()); break; case SELECTOR_ENTRY_TYPE_DRIVE: case SELECTOR_ENTRY_TYPE_DIRECTORY: // drive/directory - first check the path err = zippath_opendir(entry->fullpath, NULL); if (err != FILERR_NONE) { // this path is problematic; present the user with an error and bail machine().ui().popup_time(1, "Error accessing %s", entry->fullpath); break; } m_current_directory.assign(entry->fullpath); reset((ui_menu_reset_options)0); break; case SELECTOR_ENTRY_TYPE_FILE: // file m_current_file.assign(entry->fullpath); *m_result = R_FILE; ui_menu::stack_pop(machine()); break; } // reset the char buffer when pressing IPT_UI_SELECT if (m_filename_buffer[0] != '\0') memset(m_filename_buffer, '\0', ARRAY_LENGTH(m_filename_buffer)); } else if (event->iptkey == IPT_SPECIAL) { int buflen = strlen(m_filename_buffer); bool update_selected = FALSE; // if it's a backspace and we can handle it, do so if ((event->unichar == 8 || event->unichar == 0x7f) && buflen > 0) { *(char *)utf8_previous_char(&m_filename_buffer[buflen]) = 0; update_selected = TRUE; if (ARRAY_LENGTH(m_filename_buffer) > 0) machine().ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename_buffer); } // if it's any other key and we're not maxed out, update else if (event->unichar >= ' ' && event->unichar < 0x7f) { buflen += utf8_from_uchar(&m_filename_buffer[buflen], ARRAY_LENGTH(m_filename_buffer) - buflen, event->unichar); m_filename_buffer[buflen] = 0; update_selected = TRUE; if (ARRAY_LENGTH(m_filename_buffer) > 0) machine().ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename_buffer); } if (update_selected) { const file_selector_entry *cur_selected = (const file_selector_entry *)get_selection(); // check for entries which matches our m_filename_buffer: // from current entry to the end for (entry = cur_selected; entry != NULL; entry = entry->next) { if (entry->basename != NULL && m_filename_buffer != NULL) { int match = 0; for (int i = 0; i < ARRAY_LENGTH(m_filename_buffer); i++) { if (core_strnicmp(entry->basename, m_filename_buffer, i) == 0) match = i; } if (match > bestmatch) { bestmatch = match; selected_entry = entry; } } } // and from the first entry to current one for (entry = m_entrylist; entry != cur_selected; entry = entry->next) { if (entry->basename != NULL && m_filename_buffer != NULL) { int match = 0; for (int i = 0; i < ARRAY_LENGTH(m_filename_buffer); i++) { if (core_strnicmp(entry->basename, m_filename_buffer, i) == 0) match = i; } if (match > bestmatch) { bestmatch = match; selected_entry = entry; } } } if (selected_entry != NULL && selected_entry != cur_selected) set_selection((void *) selected_entry); } } else if (event->iptkey == IPT_UI_CANCEL) { // reset the char buffer also in this case if (m_filename_buffer[0] != '\0') memset(m_filename_buffer, '\0', ARRAY_LENGTH(m_filename_buffer)); } } }
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; } } }
void ui_menu_selector::handle() { // process the menu const ui_menu_event *m_event = process(0); if (m_event != nullptr && m_event->itemref != nullptr) { if (m_event->iptkey == IPT_UI_SELECT) { for (size_t idx = 0; idx < m_str_items.size(); ++idx) if ((void*)&m_str_items[idx] == m_event->itemref) m_selector = idx; switch (m_category) { case SELECTOR_INIFILE: machine().inifile().current_file = m_selector; machine().inifile().current_category = 0; ui_menu::menu_stack->parent->reset(UI_MENU_RESET_REMEMBER_REF); break; case SELECTOR_CATEGORY: machine().inifile().current_category = m_selector; ui_menu::menu_stack->parent->reset(UI_MENU_RESET_REMEMBER_REF); break; case SELECTOR_GAME: main_filters::actual = m_hover; ui_menu::menu_stack->parent->reset(UI_MENU_RESET_SELECT_FIRST); break; case SELECTOR_SOFTWARE: sw_filters::actual = m_hover; ui_menu::menu_stack->parent->reset(UI_MENU_RESET_SELECT_FIRST); break; default: ui_menu::menu_stack->parent->reset(UI_MENU_RESET_REMEMBER_REF); break; } ui_globals::switch_image = true; ui_menu::stack_pop(machine()); } else if (m_event->iptkey == IPT_SPECIAL) { int buflen = strlen(m_search); // if it's a backspace and we can handle it, do so if ((m_event->unichar == 8 || m_event->unichar == 0x7f) && buflen > 0) { *(char *)utf8_previous_char(&m_search[buflen]) = 0; reset(UI_MENU_RESET_SELECT_FIRST); } // if it's any other key and we're not maxed out, update else if (m_event->unichar >= ' ' && m_event->unichar < 0x7f) { buflen += utf8_from_uchar(&m_search[buflen], ARRAY_LENGTH(m_search) - buflen, m_event->unichar); m_search[buflen] = 0; reset(UI_MENU_RESET_SELECT_FIRST); } } // escape pressed with non-empty text clears the text else if (m_event->iptkey == IPT_UI_CANCEL && m_search[0] != 0) { m_search[0] = '\0'; reset(UI_MENU_RESET_SELECT_FIRST); } } }
void ui_menu_add_change_folder::handle() { // process the menu const ui_menu_event *m_event = process(0); if (m_event != nullptr && m_event->itemref != nullptr) { if (m_event->iptkey == IPT_UI_SELECT) { int index = (FPTR)m_event->itemref - 1; const ui_menu_item &pitem = item[index]; // go up to the parent path if (!strcmp(pitem.text, "..")) { 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, "[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 if (m_search[0] != 0) m_search[0] = '\0'; reset(UI_MENU_RESET_SELECT_FIRST); } else if (m_event->iptkey == IPT_SPECIAL) { int buflen = strlen(m_search); bool update_selected = FALSE; // if it's a backspace and we can handle it, do so if ((m_event->unichar == 8 || m_event->unichar == 0x7f) && buflen > 0) { *(char *)utf8_previous_char(&m_search[buflen]) = 0; update_selected = TRUE; } // if it's any other key and we're not maxed out, update else if (m_event->unichar >= ' ' && m_event->unichar < 0x7f) { buflen += utf8_from_uchar(&m_search[buflen], ARRAY_LENGTH(m_search) - buflen, m_event->unichar); m_search[buflen] = 0; update_selected = TRUE; } // Tab key, save current path else if (m_event->unichar == 0x09) { std::string error_string; if (m_change) { machine().options().set_value(s_folders_entry[m_ref].option, m_current_path.c_str(), OPTION_PRIORITY_CMDLINE, error_string); machine().datfile().reset_run(); } else { std::string tmppath = std::string(machine().options().value(s_folders_entry[m_ref].option)).append(";").append(m_current_path.c_str()); machine().options().set_value(s_folders_entry[m_ref].option, tmppath.c_str(), OPTION_PRIORITY_CMDLINE, error_string); } ui_menu::menu_stack->parent->reset(UI_MENU_RESET_SELECT_FIRST); ui_menu::stack_pop(machine()); } // check for entries which matches our search buffer if (update_selected) { const int cur_selected = selected; 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[0] != 0) { int match = 0; for (int i = 0; i < ARRAY_LENGTH(m_search); i++) { if (core_strnicmp(item[entry].text, m_search, 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[0] != 0) { int match = 0; for (int i = 0; i < ARRAY_LENGTH(m_search); i++) { if (core_strnicmp(item[entry].text, m_search, i) == 0) match = i; } if (match > bestmatch) { bestmatch = match; selected = entry; } } } } } else if (m_event->iptkey == IPT_UI_CANCEL) { // reset the char buffer also in this case if (m_search[0] != 0) m_search[0] = '\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.c_str(), 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) { bool update_selected = false; if ((event->unichar == 8) || (event->unichar == 0x7f)) { // if it's a backspace and we can handle it, do so auto const buflen = m_filename.size(); if (0 < buflen) { auto buffer_oldend = m_filename.c_str() + buflen; auto buffer_newend = utf8_previous_char(buffer_oldend); m_filename.resize(buffer_newend - m_filename.c_str()); update_selected = true; ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename.c_str()); } } else if (event->is_char_printable()) { // if it's any other key and we're not maxed out, update m_filename += utf8_from_uchar(event->unichar); update_selected = true; ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename.c_str()); } if (update_selected) { 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(); 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(); } } }
void menu_software_list::handle() { const entry_info *entry; const entry_info *selected_entry = nullptr; int bestmatch = 0; // process the menu const event *event = process(0); if (event && event->itemref) { if ((FPTR)event->itemref == 1 && event->iptkey == IPT_UI_SELECT) { m_ordered_by_shortname = !m_ordered_by_shortname; m_entrylist = nullptr; // reset the char buffer if we change ordering criterion memset(m_filename_buffer, '\0', ARRAY_LENGTH(m_filename_buffer)); // 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; menu::stack_pop(machine()); } else if (event->iptkey == IPT_SPECIAL) { auto const buflen = std::strlen(m_filename_buffer); bool update_selected = false; if ((event->unichar == 8) || (event->unichar == 0x7f)) { // if it's a backspace and we can handle it, do so if (0 < buflen) { *const_cast<char *>(utf8_previous_char(&m_filename_buffer[buflen])) = 0; update_selected = true; ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename_buffer); } } else if (event->is_char_printable()) { // if it's any other key and we're not maxed out, update if (event->append_char(m_filename_buffer, buflen)) { update_selected = true; ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename_buffer); } } if (update_selected) { const entry_info *cur_selected; // if the current selection is a software entry, start search from here if ((FPTR)event->itemref != 1) cur_selected= (const entry_info *)get_selection(); // else (if we are on the 'Switch Order' entry) start from the beginning else cur_selected = m_entrylist; // check for entries which matches our filename_buffer: // from current entry to the end for (entry = cur_selected; entry != nullptr; entry = entry->next) { const char *compare_name = m_ordered_by_shortname ? entry->short_name : entry->long_name; if (compare_name != nullptr && m_filename_buffer != nullptr) { int match = 0; for (int i = 0; i < ARRAY_LENGTH(m_filename_buffer); i++) { if (core_strnicmp(compare_name, m_filename_buffer, i) == 0) match = i; } if (match > bestmatch) { bestmatch = match; selected_entry = entry; } } } // and from the first entry to current one for (entry = m_entrylist; entry != cur_selected; entry = entry->next) { const char *compare_name = m_ordered_by_shortname ? entry->short_name : entry->long_name; if (compare_name != nullptr && m_filename_buffer != nullptr) { int match = 0; for (int i = 0; i < ARRAY_LENGTH(m_filename_buffer); i++) { if (core_strnicmp(compare_name, m_filename_buffer, 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); top_line = selected - (visible_lines / 2); } } } else if (event->iptkey == IPT_UI_CANCEL) { // reset the char buffer also in this case if (m_filename_buffer[0] != '\0') memset(m_filename_buffer, '\0', ARRAY_LENGTH(m_filename_buffer)); m_result = m_filename_buffer; menu::stack_pop(machine()); } } }