Move newmenu_item text_len into union

This commit is contained in:
Kp 2016-07-31 22:25:51 +00:00
parent 52d0ded9ee
commit 3f051100a5
3 changed files with 31 additions and 8 deletions

View file

@ -59,6 +59,20 @@ struct listbox;
class newmenu_item
{
struct input_common_type
{
int text_len;
/* Only used by imenu, but placing it in imenu_specific_type
* makes newmenu_item non-POD. Some users expect newmenu_item
* to be POD. Placing group here does not increase overall size
* since number_slider_common_type also has two int members.
*/
int group;
};
struct input_specific_type : input_common_type
{
static constexpr std::integral_constant<unsigned, NM_TYPE_INPUT> nm_type{};
};
struct radio_specific_type
{
static constexpr std::integral_constant<unsigned, NM_TYPE_RADIO> nm_type{};
@ -73,10 +87,9 @@ class newmenu_item
{
static constexpr std::integral_constant<unsigned, NM_TYPE_NUMBER> nm_type{};
};
struct imenu_specific_type
struct imenu_specific_type : input_common_type
{
static constexpr std::integral_constant<unsigned, NM_TYPE_INPUT_MENU> nm_type{};
int group;
};
struct slider_specific_type : number_slider_common_type
{
@ -97,11 +110,15 @@ public:
int type; // What kind of item this is, see NM_TYPE_????? defines
int value; // For checkboxes and radio buttons, this is 1 if marked initially, else 0
union {
input_specific_type nm_private_input;
radio_specific_type nm_private_radio;
number_specific_type nm_private_number;
imenu_specific_type nm_private_imenu;
slider_specific_type nm_private_slider;
};
input_specific_type &input() {
return get_union_member(nm_private_input);
}
radio_specific_type &radio() {
return get_union_member(nm_private_radio);
}
@ -119,7 +136,11 @@ public:
? &nm_private_number
: nullptr;
}
int text_len; // The maximum length of characters that can be entered by this inputboxes
input_common_type *input_or_menu() {
return (type == nm_private_input.nm_type || type == nm_private_imenu.nm_type)
? &nm_private_input
: nullptr;
}
char *text; // The text associated with this item.
// The rest of these are used internally by by the menu system, so don't set 'em!!
short x, y;
@ -350,7 +371,7 @@ static inline void nm_set_item_input(newmenu_item &ni, unsigned len, char *text)
{
ni.type = NM_TYPE_INPUT;
ni.text = text;
ni.text_len = len-1;
ni.input().text_len = len - 1;
}
template <std::size_t len>

View file

@ -1080,7 +1080,7 @@ static window_event_result newmenu_key_command(window *, const d_event &event, n
rval = window_event_result::handled;
} else {
auto ascii = key_ascii();
if ((ascii < 255 ) && (citem.value < citem.text_len ))
if (ascii < 255 && citem.value < citem.input_or_menu()->text_len)
{
if (citem.value == -1) {
citem.value = 0;
@ -1282,10 +1282,11 @@ static void newmenu_create_structure( newmenu *menu )
i.right_offset = w1;
}
if (i.type == NM_TYPE_INPUT || i.type == NM_TYPE_INPUT_MENU)
if (const auto input_or_menu = i.input_or_menu())
{
i.saved_text.copy_if(i.text);
string_width = i.text_len * fspacx(8) + i.text_len;
const auto text_len = input_or_menu->text_len;
string_width = text_len * fspacx(8) + text_len;
if (i.type == NM_TYPE_INPUT && string_width > MAX_TEXT_WIDTH)
string_width = MAX_TEXT_WIDTH;

View file

@ -697,9 +697,10 @@ static int state_get_savegame_filename(char * fname, char * dsc, const char * ca
if (dsc == NULL) m[i+1].type = NM_TYPE_TEXT;
}
if (dsc != NULL) {
auto &mi = m[i + 1];
m[i+1].type = NM_TYPE_INPUT_MENU;
mi.imenu().text_len = DESC_LENGTH - 1;
}
m[i+1].text_len = DESC_LENGTH-1;
m[i+1].text = desc[i];
}