Move newmenu_item max_value into union

This commit is contained in:
Kp 2016-07-31 22:25:50 +00:00
parent 26904ea6b3
commit c9aba5b04e
3 changed files with 53 additions and 16 deletions

View file

@ -64,11 +64,23 @@ class newmenu_item
static constexpr std::integral_constant<unsigned, NM_TYPE_RADIO> nm_type{};
int group; // What group this belongs to for radio buttons.
};
struct number_slider_common_type
{
int max_value;
};
struct number_specific_type : number_slider_common_type
{
static constexpr std::integral_constant<unsigned, NM_TYPE_NUMBER> nm_type{};
};
struct imenu_specific_type
{
static constexpr std::integral_constant<unsigned, NM_TYPE_INPUT_MENU> nm_type{};
int group;
};
struct slider_specific_type : number_slider_common_type
{
static constexpr std::integral_constant<unsigned, NM_TYPE_SLIDER> nm_type{};
};
template <typename T, unsigned expected_type = T::nm_type>
T &get_union_member(T &v)
{
@ -83,17 +95,30 @@ class newmenu_item
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
int min_value, max_value; // For sliders and number bars.
int min_value; // For sliders and number bars.
union {
radio_specific_type nm_private_radio;
number_specific_type nm_private_number;
imenu_specific_type nm_private_imenu;
slider_specific_type nm_private_slider;
};
radio_specific_type &radio() {
return get_union_member(nm_private_radio);
}
number_specific_type &number() {
return get_union_member(nm_private_number);
}
imenu_specific_type &imenu() {
return get_union_member(nm_private_imenu);
}
slider_specific_type &slider() {
return get_union_member(nm_private_slider);
}
number_slider_common_type *number_or_slider() {
return (type == nm_private_number.nm_type || type == nm_private_slider.nm_type)
? &nm_private_number
: nullptr;
}
int text_len; // The maximum length of characters that can be entered by this inputboxes
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!!
@ -388,7 +413,8 @@ static inline void nm_set_item_number(newmenu_item &ni, const char *text, unsign
ni.text = const_cast<char *>(text);
ni.value = now;
ni.min_value = low;
ni.max_value = high;
auto &number = ni.number();
number.max_value = high;
}
__attribute_nonnull()
@ -398,7 +424,8 @@ static inline void nm_set_item_slider(newmenu_item &ni, const char *text, unsign
ni.text = const_cast<char *>(text);
ni.value = now;
ni.min_value = low;
ni.max_value = high;
auto &slider = ni.slider();
slider.max_value = high;
}
#define NEWMENU_MOUSE

View file

@ -3675,6 +3675,7 @@ static int net_udp_game_param_handler( newmenu *menu,const d_event &event, param
}
#endif
auto &slider = menus[opt->maxnet].slider();
if (menus[opt->coop].value)
{
if (menus[opt->maxnet].value>2)
@ -3682,9 +3683,9 @@ static int net_udp_game_param_handler( newmenu *menu,const d_event &event, param
menus[opt->maxnet].value=2;
}
if (menus[opt->maxnet].max_value>2)
if (slider.max_value > 2)
{
menus[opt->maxnet].max_value=2;
slider.max_value = 2;
}
opt->update_netgame_max_players();
@ -3699,10 +3700,10 @@ static int net_udp_game_param_handler( newmenu *menu,const d_event &event, param
}
else // if !Coop game
{
if (menus[opt->maxnet].max_value<6)
if (slider.max_value < 6)
{
menus[opt->maxnet].value=6;
menus[opt->maxnet].max_value=6;
slider.max_value = 6;
opt->update_netgame_max_players();
}
}

View file

@ -375,9 +375,11 @@ static void draw_item( newmenu_item *item, int is_current, int tiny, int tabs_fl
{
int i;
if (item->value < item->min_value) item->value=item->min_value;
if (item->value > item->max_value) item->value=item->max_value;
auto &slider = item->slider();
if (item->value > slider.max_value)
item->value = slider.max_value;
i = snprintf(item->saved_text.data(), item->saved_text.size(), "%s\t%s", item->text, SLIDER_LEFT);
for (uint_fast32_t j = (item->max_value-item->min_value+1); j--;)
for (uint_fast32_t j = (slider.max_value - item->min_value + 1); j--;)
{
i += snprintf(item->saved_text.data() + i, item->saved_text.size() - i, "%s", SLIDER_MIDDLE);
}
@ -409,7 +411,9 @@ static void draw_item( newmenu_item *item, int is_current, int tiny, int tabs_fl
{
char text[sizeof("-2147483647")];
if (item->value < item->min_value) item->value=item->min_value;
if (item->value > item->max_value) item->value=item->max_value;
auto &number = item->number();
if (item->value > number.max_value)
item->value = number.max_value;
nm_string(item->w, item->x, item->y - (line_spacing * scroll_offset), item->text, tabs_flag);
snprintf(text, sizeof(text), "%d", item->value );
nm_rstring(item->right_offset,item->x, item->y - (line_spacing * scroll_offset), text);
@ -794,10 +798,11 @@ static window_event_result newmenu_mouse(window *wind,const d_event &event, newm
x1 = grd_curcanv->cv_bitmap.bm_x + citem.x + citem.w - slider_width;
x2 = x1 + slider_width + sright_width;
int new_value;
auto &slider = citem.slider();
if (
(mx > x1 && mx < x1 + sleft_width && (new_value = citem.min_value, true)) ||
(mx < x2 && mx > x2 - sright_width && (new_value = citem.max_value, true)) ||
(mx > x1 + sleft_width && mx < x2 - sright_width - sleft_width && (new_value = (mx - x1 - sleft_width) / ((slider_width - sleft_width - sright_width) / (citem.max_value - citem.min_value + 1)), true))
(mx < x2 && mx > x2 - sright_width && (new_value = slider.max_value, true)) ||
(mx > x1 + sleft_width && mx < x2 - sright_width - sleft_width && (new_value = (mx - x1 - sleft_width) / ((slider_width - sleft_width - sright_width) / (slider.max_value - citem.min_value + 1)), true))
)
if (citem.value != new_value)
{
@ -1123,7 +1128,7 @@ static window_event_result newmenu_key_command(window *, const d_event &event, n
}
}
if ( (citem.type == NM_TYPE_NUMBER) || (citem.type == NM_TYPE_SLIDER))
if (const auto ns = citem.number_or_slider())
{
switch( k ) {
case KEY_LEFT:
@ -1151,7 +1156,9 @@ static window_event_result newmenu_key_command(window *, const d_event &event, n
}
if (citem.value < citem.min_value) citem.value = citem.min_value;
if (citem.value > citem.max_value) citem.value = citem.max_value;
auto &max_value = ns->max_value;
if (citem.value > max_value)
citem.value = max_value;
}
}
@ -1219,7 +1226,8 @@ static void newmenu_create_structure( newmenu *menu )
int index,w1;
nothers++;
index = snprintf (i.saved_text.data(), i.saved_text.size(), "%s", SLIDER_LEFT);
for (uint_fast32_t j = (i.max_value - i.min_value + 1); j--;)
auto &slider = i.slider();
for (uint_fast32_t j = (slider.max_value - i.min_value + 1); j--;)
{
index += snprintf(i.saved_text.data() + index, i.saved_text.size() - index, "%s", SLIDER_MIDDLE);
}
@ -1260,7 +1268,8 @@ static void newmenu_create_structure( newmenu *menu )
int w1;
char test_text[20];
nothers++;
snprintf(test_text, sizeof(test_text), "%d", i.max_value);
auto &number = i.number();
snprintf(test_text, sizeof(test_text), "%d", number.max_value);
gr_get_string_size(test_text, &w1, nullptr, nullptr);
i.right_offset = w1;
snprintf(test_text, sizeof(test_text), "%d", i.min_value);