Consolidated code that inputs characters into buffers

This commit is contained in:
Nathan Woods 2016-09-19 08:25:10 -04:00
parent ea15eb9111
commit 1a017c9302
19 changed files with 95 additions and 189 deletions

View File

@ -12,6 +12,7 @@
#include "ui/barcode.h"
#include "ui/ui.h"
#include "ui/utils.h"
namespace ui {
// itemrefs for key menu items
@ -67,7 +68,7 @@ void menu_barcode_reader::populate()
}
else
{
new_barcode = m_barcode_buffer;
new_barcode = m_barcode_buffer.c_str();
}
item_append(_("New Barcode:"), new_barcode, 0, ITEMREF_NEW_BARCODE);
@ -121,8 +122,7 @@ void menu_barcode_reader::handle()
{
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));
m_barcode_buffer.clear();
reset(reset_options::REMEMBER_POSITION);
}
}
@ -131,26 +131,14 @@ void menu_barcode_reader::handle()
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);
if (input_character(m_barcode_buffer, event->unichar, uchar_is_digit))
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));
m_barcode_buffer.clear();
break;
}
}

View File

@ -26,7 +26,7 @@ private:
virtual void populate() override;
virtual void handle() override;
char m_barcode_buffer[20];
std::string m_barcode_buffer;
};
} // namespace ui

View File

@ -945,7 +945,7 @@ void menu_rgb_ui::inkey_special(const event *menu_event)
if (!m_key_active)
{
int val = atoi(m_search);
int val = atoi(m_search.data());
val = m_color->clamp(val);
switch ((FPTR)menu_event->itemref)
@ -967,7 +967,7 @@ void menu_rgb_ui::inkey_special(const event *menu_event)
break;
}
m_search[0] = 0;
m_search.erase();
m_lock_ref = 0;
return;
}
@ -975,26 +975,11 @@ void menu_rgb_ui::inkey_special(const event *menu_event)
if (!m_key_active)
{
m_search[0] = 0;
m_search.erase();
return;
}
auto const buflen = std::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;
}
else if (buflen >= 3)
{
return;
}
else if ((menu_event->unichar >= '0' && menu_event->unichar <= '9'))
{
// if it's any other key and we're not maxed out, update
menu_event->append_char(m_search, buflen);
}
input_character(m_search, 3, menu_event->unichar, uchar_is_digit);
}
std::pair<const char *, const char *> const menu_palette_sel::s_palette[] = {

View File

@ -162,7 +162,7 @@ private:
void inkey_special(const event *menu_event);
rgb_t *m_color;
char m_search[4];
std::string m_search;
bool m_key_active;
int m_lock_ref;
std::string m_title;

View File

@ -342,19 +342,9 @@ void menu_add_change_folder::handle()
}
else if (menu_event->iptkey == IPT_SPECIAL)
{
auto const buflen = std::strlen(m_search);
bool update_selected = false;
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;
update_selected = true;
}
}
else if (menu_event->unichar == 0x09)
if (menu_event->unichar == 0x09)
{
// Tab key, save current path
std::string error_string;
@ -391,11 +381,10 @@ void menu_add_change_folder::handle()
reset_parent(reset_options::SELECT_FIRST);
stack_pop();
}
else if (menu_event->is_char_printable())
else
{
// if it's any other key and we're not maxed out, update
if (menu_event->append_char(m_search, buflen))
update_selected = true;
update_selected = input_character(m_search, menu_event->unichar, uchar_is_printable);
}
// check for entries which matches our search buffer
@ -406,12 +395,12 @@ void menu_add_change_folder::handle()
// from current item to the end
for (entry = cur_selected; entry < item.size(); entry++)
if (item[entry].ref != nullptr && m_search[0] != 0)
if (item[entry].ref != nullptr && !m_search.empty())
{
int match = 0;
for (int i = 0; i < ARRAY_LENGTH(m_search); i++)
for (int i = 0; i < m_search.size(); i++)
{
if (core_strnicmp(item[entry].text.c_str(), m_search, i) == 0)
if (core_strnicmp(item[entry].text.c_str(), m_search.data(), i) == 0)
match = i;
}
@ -425,12 +414,12 @@ void menu_add_change_folder::handle()
// and from the first item to current one
for (entry = 0; entry < cur_selected; entry++)
{
if (item[entry].ref != nullptr && m_search[0] != 0)
if (item[entry].ref != nullptr && !m_search.empty())
{
int match = 0;
for (int i = 0; i < ARRAY_LENGTH(m_search); i++)
for (int i = 0; i < m_search.size(); i++)
{
if (core_strnicmp(item[entry].text.c_str(), m_search, i) == 0)
if (core_strnicmp(item[entry].text.c_str(), m_search.data(), i) == 0)
match = i;
}
@ -447,8 +436,7 @@ void menu_add_change_folder::handle()
else if (menu_event->iptkey == IPT_UI_CANCEL)
{
// reset the char buffer also in this case
if (m_search[0] != 0)
m_search[0] = '\0';
m_search.clear();
}
}
}

View File

@ -108,7 +108,7 @@ private:
int m_ref;
std::string m_current_path;
char m_search[40];
std::string m_search;
bool m_change;
std::vector<std::string> m_folders;
};

View File

@ -15,6 +15,7 @@
#include "ui/filesel.h"
#include "ui/ui.h"
#include "ui/utils.h"
#include "imagedev/floppy.h"
@ -432,33 +433,11 @@ void menu_file_selector::handle()
}
else if (event->iptkey == IPT_SPECIAL)
{
bool update_selected = false;
if ((event->unichar == 8) || (event->unichar == 0x7f))
// if it's any other key and we're not maxed out, update
if (input_character(m_filename, event->unichar, uchar_is_printable))
{
// 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:

View File

@ -138,31 +138,6 @@ protected:
int iptkey; // one of the IPT_* values from inptport.h
unicode_char unichar; // unicode character if iptkey == IPT_SPECIAL
render_bounds mouse; // mouse position if iptkey == IPT_CUSTOM
bool is_char_printable() const
{
return
!(0x0001f >= unichar) && // C0 control
!((0x0007f <= unichar) && (0x0009f >= unichar)) && // DEL and C1 control
!((0x0fdd0 <= unichar) && (0x0fddf >= unichar)) && // noncharacters
!(0x0fffe == (unichar & 0x0ffff)) && // byte-order detection noncharacter
!(0x0ffff == (unichar & 0x0ffff)); // the other noncharacter
}
template <std::size_t N>
bool append_char(char (&buffer)[N], std::size_t offset) const
{
auto const chlen = utf8_from_uchar(&buffer[offset], N - offset - 1, unichar);
if (0 < chlen)
{
buffer[offset + chlen] = '\0';
return true;
}
else
{
return false;
}
}
};
int top_line; // main box top line

View File

@ -99,28 +99,14 @@ void menu_selector::handle()
}
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);
}
if (input_character(m_search, menu_event->unichar, uchar_is_printable))
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';
m_search.clear();
reset(reset_options::SELECT_FIRST);
}
}
@ -132,9 +118,9 @@ void menu_selector::handle()
void menu_selector::populate()
{
if (m_search[0] != 0)
if (!m_search.empty())
{
find_matches(m_search);
find_matches(m_search.c_str());
for (int curitem = 0; m_searchlist[curitem]; ++curitem)
item_append(*m_searchlist[curitem], "", 0, (void *)m_searchlist[curitem]);

View File

@ -47,7 +47,7 @@ private:
void find_matches(const char *str);
char m_search[40];
std::string m_search;
UINT16 &m_selector;
int m_category, m_hover;
bool m_first_pass;

View File

@ -967,23 +967,8 @@ void menu_select_game::inkey_special(const event *menu_event)
{
if (!isfavorite())
{
auto const buflen = std::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);
}
if (input_character(m_search, menu_event->unichar, uchar_is_printable))
reset(reset_options::SELECT_FIRST);
}
}

View File

@ -38,7 +38,7 @@ private:
};
enum { VISIBLE_GAMES_IN_SEARCH = 200 };
char m_search[40];
std::string m_search;
static bool first_start;
static int m_isabios;
int highlight;

View File

@ -488,7 +488,7 @@ void menu_select_software::populate()
else
{
find_matches(m_search, VISIBLE_GAMES_IN_SEARCH);
find_matches(m_search.c_str(), VISIBLE_GAMES_IN_SEARCH);
for (int curitem = 0; m_searchlist[curitem] != nullptr; ++curitem)
item_append(m_searchlist[curitem]->longname, m_searchlist[curitem]->devicetype,
@ -747,23 +747,8 @@ void menu_select_software::inkey_select(const event *menu_event)
void menu_select_software::inkey_special(const event *menu_event)
{
auto const buflen = std::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);
}
if (input_character(m_search, menu_event->unichar, uchar_is_printable))
reset(reset_options::SELECT_FIRST);
}

View File

@ -31,7 +31,7 @@ protected:
private:
enum { VISIBLE_GAMES_IN_SEARCH = 200 };
char m_search[40];
std::string m_search;
const game_driver *m_driver;
bool m_has_empty_start;
s_filter m_filter;

View File

@ -15,6 +15,7 @@
#include "ui/ui.h"
#include "ui/miscmenu.h"
#include "ui/optsmenu.h"
#include "ui/utils.h"
#include "audit.h"
#include "drivenum.h"
@ -33,8 +34,8 @@ namespace ui {
simple_menu_select_game::simple_menu_select_game(mame_ui_manager &mui, render_container &container, const char *gamename) : menu(mui, container), m_driverlist(driver_list::total() + 1)
{
build_driver_list();
if(gamename)
strcpy(m_search, gamename);
if (gamename)
m_search.assign(gamename);
m_matchlist[0] = -1;
}
@ -199,23 +200,12 @@ void simple_menu_select_game::inkey_cancel()
void simple_menu_select_game::inkey_special(const event *menu_event)
{
// typed characters append to the buffer
auto const buflen = std::strlen(m_search);
if ((menu_event->unichar == 8) || (menu_event->unichar == 0x7f))
size_t old_size = m_search.size();
if (input_character(m_search, menu_event->unichar, uchar_is_printable))
{
// 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;
if (m_search.size() < old_size)
m_rerandomize = true;
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);
reset(reset_options::SELECT_FIRST);
}
}
@ -249,7 +239,7 @@ void simple_menu_select_game::populate()
// otherwise, rebuild the match list
assert(m_drivlist != nullptr);
if (m_search[0] != 0 || m_matchlist[0] == -1 || m_rerandomize)
m_drivlist->find_approximate_matches(m_search, matchcount, m_matchlist);
m_drivlist->find_approximate_matches(m_search.c_str(), matchcount, m_matchlist);
m_rerandomize = false;
// iterate over entries

View File

@ -45,7 +45,7 @@ private:
// internal state
UINT8 m_error;
bool m_rerandomize;
char m_search[40];
std::string m_search;
int m_matchlist[VISIBLE_GAMES_IN_LIST];
std::vector<const game_driver *> m_driverlist;
std::unique_ptr<driver_enumerator> m_drivlist;

View File

@ -244,7 +244,7 @@ std::vector<std::string> tokenize(const std::string &text, char sep);
//-------------------------------------------------
template <typename F>
bool input_character(std::string &buffer, unicode_char unichar, F &&filter)
bool input_character(std::string &buffer, std::size_t size, unicode_char unichar, F &&filter)
{
bool result = false;
auto buflen = buffer.size();
@ -260,7 +260,7 @@ bool input_character(std::string &buffer, unicode_char unichar, F &&filter)
result = true;
}
}
else if ((unichar >= ' ') && filter(unichar))
else if ((unichar >= ' ') && (size == ~0 || buffer.size() < size) && filter(unichar))
{
// append this character
buffer += utf8_from_uchar(unichar);
@ -270,4 +270,16 @@ bool input_character(std::string &buffer, unicode_char unichar, F &&filter)
}
//-------------------------------------------------
// input_character - inputs a typed character
// into a buffer
//-------------------------------------------------
template <typename F>
bool input_character(std::string &buffer, unicode_char unichar, F &&filter)
{
return input_character(buffer, ~0, unichar, filter);
}
#endif /* __UI_UTILS_H__ */

View File

@ -22,6 +22,33 @@ bool uchar_isvalid(unicode_char uchar)
}
//-------------------------------------------------
// uchar_is_printable - tests to see if a unicode
// char is printable
//-------------------------------------------------
bool uchar_is_printable(unicode_char uchar)
{
return
!(0x0001f >= uchar) && // C0 control
!((0x0007f <= uchar) && (0x0009f >= uchar)) && // DEL and C1 control
!((0x0fdd0 <= uchar) && (0x0fddf >= uchar)) && // noncharacters
!(0x0fffe == (uchar & 0x0ffff)) && // byte-order detection noncharacter
!(0x0ffff == (uchar & 0x0ffff)); // the other noncharacter
}
//-------------------------------------------------
// uchar_is_digit - tests to see if a unicode
// char is a digit
//-------------------------------------------------
bool uchar_is_digit(unicode_char uchar)
{
return uchar >= '0' && uchar <= '9';
}
//-------------------------------------------------
// uchar_from_utf8 - convert a UTF-8 sequence
// into a unicode character

View File

@ -90,6 +90,12 @@ typedef UINT32 unicode_char;
// tests to see if a unicode char is a valid code point
bool uchar_isvalid(unicode_char uchar);
// tests to see if a unicode char is printable
bool uchar_is_printable(unicode_char uchar);
// tests to see if a unicode char is a digit
bool uchar_is_digit(unicode_char uchar);
// converting strings to 32-bit Unicode chars
int uchar_from_utf8(unicode_char *uchar, const char *utf8char, size_t count);
int uchar_from_utf16(unicode_char *uchar, const utf16_char *utf16char, size_t count);