diff --git a/common/main/newmenu.h b/common/main/newmenu.h index 9c9d3ff40..3a6868624 100644 --- a/common/main/newmenu.h +++ b/common/main/newmenu.h @@ -64,11 +64,23 @@ class newmenu_item static constexpr std::integral_constant 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 nm_type{}; + }; struct imenu_specific_type { static constexpr std::integral_constant nm_type{}; int group; }; + struct slider_specific_type : number_slider_common_type + { + static constexpr std::integral_constant nm_type{}; + }; template 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(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(text); ni.value = now; ni.min_value = low; - ni.max_value = high; + auto &slider = ni.slider(); + slider.max_value = high; } #define NEWMENU_MOUSE diff --git a/similar/main/net_udp.cpp b/similar/main/net_udp.cpp index b11fe3171..3a32ac6bc 100644 --- a/similar/main/net_udp.cpp +++ b/similar/main/net_udp.cpp @@ -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(); } } diff --git a/similar/main/newmenu.cpp b/similar/main/newmenu.cpp index d32dd8db6..c5076eaff 100644 --- a/similar/main/newmenu.cpp +++ b/similar/main/newmenu.cpp @@ -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);