diff options
Diffstat (limited to 'src/frontend/mame/ui/filesel.cpp')
-rw-r--r-- | src/frontend/mame/ui/filesel.cpp | 383 |
1 files changed, 48 insertions, 335 deletions
diff --git a/src/frontend/mame/ui/filesel.cpp b/src/frontend/mame/ui/filesel.cpp index deaef81c3d0..34e86c99fe8 100644 --- a/src/frontend/mame/ui/filesel.cpp +++ b/src/frontend/mame/ui/filesel.cpp @@ -4,10 +4,9 @@ ui/filesel.cpp - MESS's clunky built-in file manager + MAME's clunky built-in file manager TODO - - Support image creation arguments - Restrict empty slot if image required ***************************************************************************/ @@ -36,250 +35,6 @@ namespace ui { // time (in seconds) to display errors #define ERROR_MESSAGE_TIME 5 -// itemrefs for key menu items -#define ITEMREF_NEW_IMAGE_NAME ((void *) 0x0001) -#define ITEMREF_CREATE ((void *) 0x0002) -#define ITEMREF_FORMAT ((void *) 0x0003) -#define ITEMREF_NO ((void *) 0x0004) -#define ITEMREF_YES ((void *) 0x0005) - - -/*************************************************************************** - MENU HELPERS -***************************************************************************/ - -//------------------------------------------------- -// input_character - inputs a typed character -// into a buffer -//------------------------------------------------- - -template <std::size_t N, typename F> -static void input_character(char (&buffer)[N], unicode_char unichar, F &&filter) -{ - auto buflen = std::strlen(buffer); - - if ((unichar == 8) || (unichar == 0x7f)) - { - if (0 < buflen) - *const_cast<char *>(utf8_previous_char(&buffer[buflen])) = 0; - } - else if ((unichar >= ' ') && (!filter || filter(unichar))) - { - auto const chlen = utf8_from_uchar(&buffer[buflen], N - buflen - 1, unichar); - if (0 <= chlen) - { - buflen += chlen; - buffer[buflen] = 0; - } - } -} - - -/*************************************************************************** - CONFIRM SAVE AS MENU -***************************************************************************/ - -//------------------------------------------------- -// ctor -//------------------------------------------------- - -menu_confirm_save_as::menu_confirm_save_as(mame_ui_manager &mui, render_container *container, bool *yes) - : menu(mui, container) -{ - m_yes = yes; - *m_yes = false; -} - - -//------------------------------------------------- -// dtor -//------------------------------------------------- - -menu_confirm_save_as::~menu_confirm_save_as() -{ -} - - -//------------------------------------------------- -// populate -//------------------------------------------------- - -void menu_confirm_save_as::populate() -{ - item_append(_("File Already Exists - Override?"), "", FLAG_DISABLE, nullptr); - item_append(menu_item_type::SEPARATOR); - item_append(_("No"), "", 0, ITEMREF_NO); - item_append(_("Yes"), "", 0, ITEMREF_YES); -} - -//------------------------------------------------- -// handle - confirm save as menu -//------------------------------------------------- - -void menu_confirm_save_as::handle() -{ - // process the menu - const event *event = process(0); - - // process the event - if ((event != nullptr) && (event->iptkey == IPT_UI_SELECT)) - { - if (event->itemref == ITEMREF_YES) - *m_yes = true; - - // no matter what, pop out - menu::stack_pop(machine()); - } -} - - - -/*************************************************************************** - FILE CREATE MENU -***************************************************************************/ - -//------------------------------------------------- -// is_valid_filename_char - tests to see if a -// character is valid in a filename -//------------------------------------------------- - -static int is_valid_filename_char(unicode_char unichar) -{ - // this should really be in the OSD layer, and it shouldn't be 7-bit bullshit - static const char valid_filename_char[] = - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00-0f - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10-1f - 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, // !"#$%&'()*+,-./ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 0123456789:;<=>? - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // @ABCDEFGHIJKLMNO - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // PQRSTUVWXYZ[\]^_ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // `abcdefghijklmno - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, // pqrstuvwxyz{|}~ - }; - return (unichar < ARRAY_LENGTH(valid_filename_char)) && valid_filename_char[unichar]; -} - - -//------------------------------------------------- -// ctor -//------------------------------------------------- - -menu_file_create::menu_file_create(mame_ui_manager &mui, render_container *container, device_image_interface *image, std::string ¤t_directory, std::string ¤t_file, bool *ok) - : menu(mui, container) - , m_current_directory(current_directory) - , m_current_file(current_file) - , m_current_format(nullptr) -{ - m_image = image; - m_ok = ok; - *m_ok = true; - auto const sep = current_file.rfind(PATH_SEPARATOR); - std::strncpy(m_filename_buffer, current_file.c_str() + ((std::string::npos == sep) ? 0 : (sep + 1)), sizeof(m_filename_buffer)); -} - - -//------------------------------------------------- -// dtor -//------------------------------------------------- - -menu_file_create::~menu_file_create() -{ -} - - -//------------------------------------------------- -// custom_render - perform our special rendering -//------------------------------------------------- - -void menu_file_create::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2) -{ - extra_text_render(top, bottom, origx1, origy1, origx2, origy2, - m_current_directory.c_str(), - nullptr); -} - - -//------------------------------------------------- -// populate - populates the file creator menu -//------------------------------------------------- - -void menu_file_create::populate() -{ - std::string buffer; - const image_device_format *format; - const char *new_image_name; - - // append the "New Image Name" item - if (get_selection() == ITEMREF_NEW_IMAGE_NAME) - { - buffer.append(m_filename_buffer).append("_"); - new_image_name = buffer.c_str(); - } - else - { - new_image_name = m_filename_buffer; - } - item_append(_("New Image Name:"), new_image_name, 0, ITEMREF_NEW_IMAGE_NAME); - - // do we support multiple formats? - if (ENABLE_FORMATS) format = m_image->formatlist().front().get(); - if (ENABLE_FORMATS && (format != nullptr)) - { - item_append(_("Image Format:"), m_current_format->description(), 0, ITEMREF_FORMAT); - m_current_format = format; - } - - // finish up the menu - item_append(menu_item_type::SEPARATOR); - item_append(_("Create"), "", 0, ITEMREF_CREATE); - - customtop = ui().get_line_height() + 3.0f * UI_BOX_TB_BORDER; -} - - -//------------------------------------------------- -// handle - file creator menu -//------------------------------------------------- - -void menu_file_create::handle() -{ - // process the menu - const event *event = process(0); - - // process the event - if (event) - { - // handle selections - switch (event->iptkey) - { - case IPT_UI_SELECT: - if ((event->itemref == ITEMREF_CREATE) || (event->itemref == ITEMREF_NEW_IMAGE_NAME)) - { - std::string tmp_file(m_filename_buffer); - if (tmp_file.find(".") != -1 && tmp_file.find(".") < tmp_file.length() - 1) - { - m_current_file = m_filename_buffer; - menu::stack_pop(machine()); - } - else - ui().popup_time(1, "%s", _("Please enter a file extension too")); - } - break; - - case IPT_SPECIAL: - if (get_selection() == ITEMREF_NEW_IMAGE_NAME) - { - input_character(m_filename_buffer,event->unichar, &is_valid_filename_char); - reset(reset_options::REMEMBER_POSITION); - } - break; - case IPT_UI_CANCEL: - *m_ok = false; - break; - } - } -} /*************************************************************************** FILE SELECTOR MENU @@ -289,16 +44,16 @@ void menu_file_create::handle() // ctor //------------------------------------------------- -menu_file_selector::menu_file_selector(mame_ui_manager &mui, render_container *container, device_image_interface *image, std::string ¤t_directory, std::string ¤t_file, bool has_empty, bool has_softlist, bool has_create, int *result) +menu_file_selector::menu_file_selector(mame_ui_manager &mui, render_container *container, device_image_interface *image, std::string ¤t_directory, std::string ¤t_file, bool has_empty, bool has_softlist, bool has_create, menu_file_selector::result &result) : menu(mui, container) , m_current_directory(current_directory) , m_current_file(current_file) + , m_result(result) { m_image = image; m_has_empty = has_empty; m_has_softlist = has_softlist; m_has_create = has_create; - m_result = result; } @@ -340,7 +95,7 @@ void menu_file_selector::custom_render(void *selectedref, float top, float botto // we're hovering over a directory! highlight it auto target_dir_start = m_current_directory.rfind(PATH_SEPARATOR, hit_start) + 1; auto target_dir_end = m_current_directory.find(PATH_SEPARATOR, hit_start + hit_span); - m_hover_directory = m_current_directory.substr(0, target_dir_end); + m_hover_directory = m_current_directory.substr(0, target_dir_end + strlen(PATH_SEPARATOR)); // highlight the text in question rgb_t fgcolor = UI_MOUSEOVER_COLOR; @@ -473,7 +228,7 @@ menu_file_selector::file_selector_entry *menu_file_selector::append_dirent_entry } // determine the full path - util::zippath_combine(buffer, m_current_directory.c_str(), dirent->name); + buffer = util::zippath_combine(m_current_directory.c_str(), dirent->name); // create the file selector entry entry = &append_entry( @@ -555,7 +310,7 @@ void menu_file_selector::populate() append_entry(SELECTOR_ENTRY_TYPE_EMPTY, "", ""); } - if (m_has_create) + if (m_has_create && !util::zippath_is_zip(directory)) { // add the "[create]" entry append_entry(SELECTOR_ENTRY_TYPE_CREATE, "", ""); @@ -636,18 +391,18 @@ void menu_file_selector::handle() { case SELECTOR_ENTRY_TYPE_EMPTY: // empty slot - unload - *m_result = R_EMPTY; + m_result = result::EMPTY; menu::stack_pop(machine()); break; case SELECTOR_ENTRY_TYPE_CREATE: // create - *m_result = R_CREATE; + m_result = result::CREATE; menu::stack_pop(machine()); break; case SELECTOR_ENTRY_TYPE_SOFTWARE_LIST: - *m_result = R_SOFTLIST; + m_result = result::SOFTLIST; menu::stack_pop(machine()); break; @@ -668,45 +423,44 @@ void menu_file_selector::handle() case SELECTOR_ENTRY_TYPE_FILE: // file m_current_file.assign(entry->fullpath); - *m_result = R_FILE; + m_result = result::FILE; 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)); + m_filename.clear(); } else if (event->iptkey == IPT_SPECIAL) { - auto const buflen = std::strlen(m_filename_buffer); - bool update_selected = FALSE; + 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) { - *const_cast<char *>(utf8_previous_char(&m_filename_buffer[buflen])) = 0; - update_selected = TRUE; + 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_buffer); + 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 - if (event->append_char(m_filename_buffer, buflen)) - { - update_selected = TRUE; + m_filename += utf8_from_uchar(event->unichar); + update_selected = true; - ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename_buffer); - } + ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename.c_str()); } if (update_selected) { - const file_selector_entry *cur_selected = (const file_selector_entry *)get_selection(); + 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) @@ -714,9 +468,9 @@ void menu_file_selector::handle() if (cur_selected != &entry) { int match = 0; - for (int i = 0; i < ARRAY_LENGTH(m_filename_buffer); i++) + for (int i = 0; i < m_filename.size(); i++) { - if (core_strnicmp(entry.basename.c_str(), m_filename_buffer, i) == 0) + if (core_strnicmp(entry.basename.c_str(), m_filename.c_str(), i) == 0) match = i; } @@ -731,15 +485,14 @@ void menu_file_selector::handle() if (selected_entry != nullptr && selected_entry != cur_selected) { set_selection((void *)selected_entry); - top_line = selected - (visible_lines / 2); + centre_selection(); } } } 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_filename.clear(); } } } @@ -747,20 +500,19 @@ void menu_file_selector::handle() /*************************************************************************** - SELECT FORMAT MENU + SELECT RW ***************************************************************************/ //------------------------------------------------- // ctor //------------------------------------------------- -menu_select_format::menu_select_format(mame_ui_manager &mui, render_container *container, floppy_image_format_t **formats, int ext_match, int total_usable, int *result) - : menu(mui, container) +menu_select_rw::menu_select_rw(mame_ui_manager &mui, render_container *container, + bool can_in_place, result &result) + : menu(mui, container), + m_can_in_place(can_in_place), + m_result(result) { - m_formats = formats; - m_ext_match = ext_match; - m_total_usable = total_usable; - m_result = result; } @@ -768,7 +520,7 @@ menu_select_format::menu_select_format(mame_ui_manager &mui, render_container *c // dtor //------------------------------------------------- -menu_select_format::~menu_select_format() +menu_select_rw::~menu_select_rw() { } @@ -777,17 +529,14 @@ menu_select_format::~menu_select_format() // populate //------------------------------------------------- -void menu_select_format::populate() +void menu_select_rw::populate() { - item_append(_("Select image format"), "", FLAG_DISABLE, nullptr); - for (int i = 0; i < m_total_usable; i++) - { - const floppy_image_format_t *fmt = m_formats[i]; - - if (i && i == m_ext_match) - item_append(menu_item_type::SEPARATOR); - item_append(fmt->description(), fmt->name(), 0, (void *)(FPTR)i); - } + item_append(_("Select access mode"), "", FLAG_DISABLE, nullptr); + item_append(_("Read-only"), "", 0, itemref_from_result(result::READONLY)); + if (m_can_in_place) + item_append(_("Read-write"), "", 0, itemref_from_result(result::READWRITE)); + item_append(_("Read this image, write to another image"), "", 0, itemref_from_result(result::WRITE_OTHER)); + item_append(_("Read this image, write to diff"), "", 0, itemref_from_result(result::WRITE_DIFF)); } @@ -795,72 +544,36 @@ void menu_select_format::populate() // handle //------------------------------------------------- -void menu_select_format::handle() +void menu_select_rw::handle() { // process the menu const event *event = process(0); if (event != nullptr && event->iptkey == IPT_UI_SELECT) { - *m_result = int(FPTR(event->itemref)); + m_result = result_from_itemref(event->itemref); menu::stack_pop(machine()); } } -/*************************************************************************** - SELECT RW -***************************************************************************/ - //------------------------------------------------- -// ctor +// itemref_from_result //------------------------------------------------- -menu_select_rw::menu_select_rw(mame_ui_manager &mui, render_container *container, - bool can_in_place, int *result) - : menu(mui, container) +void *menu_select_rw::itemref_from_result(menu_select_rw::result result) { - m_can_in_place = can_in_place; - m_result = result; + return (void *)(FPTR)(unsigned int)result; } //------------------------------------------------- -// dtor +// result_from_itemref //------------------------------------------------- -menu_select_rw::~menu_select_rw() +menu_select_rw::result menu_select_rw::result_from_itemref(void *itemref) { + return (menu_select_rw::result) (unsigned int) (FPTR)itemref; } -//------------------------------------------------- -// populate -//------------------------------------------------- - -void menu_select_rw::populate() -{ - item_append(_("Select access mode"), "", FLAG_DISABLE, nullptr); - item_append(_("Read-only"), "", 0, (void *)READONLY); - if (m_can_in_place) - item_append(_("Read-write"), "", 0, (void *)READWRITE); - item_append(_("Read this image, write to another image"), "", 0, (void *)WRITE_OTHER); - item_append(_("Read this image, write to diff"), "", 0, (void *)WRITE_DIFF); -} - - -//------------------------------------------------- -// handle -//------------------------------------------------- - -void menu_select_rw::handle() -{ - // process the menu - const event *event = process(0); - if (event != nullptr && event->iptkey == IPT_UI_SELECT) - { - *m_result = int(FPTR(event->itemref)); - menu::stack_pop(machine()); - } -} - } // namespace ui |