diff --git a/src/cuboid_rectangle.h b/src/cuboid_rectangle.h index 19ac3e91c9cfc..b951dbd564f06 100644 --- a/src/cuboid_rectangle.h +++ b/src/cuboid_rectangle.h @@ -154,6 +154,42 @@ Tripoint clamp( const Tripoint &p, const inclusive_cuboid &c ) clamp( Traits::z( p ), Traits::z( c.p_min ), Traits::z( c.p_max ) ) ); } +template +int run_for_point_in( const std::map> &m, const Point &p, + const std::function> & )> &func, + bool first_only = true ) +{ + int cnt = 0; + for( const std::pair> &mp : m ) { + if( mp.second.contains( p ) ) { + func( mp ); + cnt++; + if( first_only ) { + break; + } + } + } + return cnt; +} + +template +int run_for_point_in( const std::map> &m, const Point &p, + const std::function> & )> &func, + bool first_only = true ) +{ + int cnt = 0; + for( const std::pair> &mp : m ) { + if( mp.second.contains( p ) ) { + func( mp ); + cnt++; + if( first_only ) { + break; + } + } + } + return cnt; +} + static constexpr rectangle rectangle_zero( point_zero, point_zero ); static constexpr cuboid cuboid_zero( tripoint_zero, tripoint_zero ); diff --git a/src/help.cpp b/src/help.cpp index f3ca97fc701ad..3df8105b7be27 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -194,17 +194,17 @@ void help::display_help() const // Mouse selection if( action == "MOUSE_MOVE" || action == "SELECT" ) { cata::optional coord = ctxt.get_coordinates_text( w_help ); - for( const auto &opt : opt_map ) { - if( coord.has_value() && opt.second.contains( coord.value() ) ) { - sel = opt.first; - if( action == "SELECT" ) { - auto iter = hotkeys.find( sel ); - if( iter != hotkeys.end() && !iter->second.empty() ) { - sInput = iter->second.front(); - action = "CONFIRM"; - } + if( !!coord ) { + int cnt = run_for_point_in( opt_map, *coord, + [&sel]( const std::pair> &p ) { + sel = p.first; + } ); + if( cnt > 0 && action == "SELECT" ) { + auto iter = hotkeys.find( sel ); + if( iter != hotkeys.end() && !iter->second.empty() ) { + sInput = iter->second.front(); + action = "CONFIRM"; } - break; } } } diff --git a/src/options.cpp b/src/options.cpp index ca1ac3b71904c..ae108149946b2 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -2985,48 +2985,45 @@ std::string options_manager::show( bool ingame, const bool world_options_only, if( action == "MOUSE_MOVE" || action == "SELECT" ) { bool found_opt = false; sel_worldgen_tab = 1; - if( world_options_only ) { + cata::optional coord = ctxt.get_coordinates_text( w_options_border ); + if( world_options_only && !!coord ) { // worldgen tabs - cata::optional coord = ctxt.get_coordinates_text( w_options_border ); - for( const auto &ent : worldgen_tab_map ) { - if( coord.has_value() && ent.second.contains( coord.value() ) ) { - found_opt = true; - sel_worldgen_tab = ent.first; - if( action == "SELECT" && sel_worldgen_tab != 1 ) { - return sel_worldgen_tab == 0 ? "PREV_TAB" : "NEXT_TAB"; - } - break; - } + found_opt = run_for_point_in( worldgen_tab_map, *coord, + [&sel_worldgen_tab]( const std::pair> &p ) { + sel_worldgen_tab = p.first; + } ) > 0; + if( found_opt && action == "SELECT" && sel_worldgen_tab != 1 ) { + return sel_worldgen_tab == 0 ? "PREV_TAB" : "NEXT_TAB"; } } - if( !found_opt ) { + if( !found_opt && !!coord ) { // option category tabs - cata::optional coord = ctxt.get_coordinates_text( w_options_header ); - for( const auto &ent : opt_tab_map ) { - if( coord.has_value() && ent.second.contains( coord.value() ) ) { - found_opt = true; - if( iCurrentPage != ent.first ) { - iCurrentLine = 0; - iStartPos = 0; - recalc_startpos = true; - iCurrentPage = clamp( ent.first, 0, pages_.size() - 1 ); - sfx::play_variant_sound( "menu_move", "default", 100 ); - } - break; - } + coord = ctxt.get_coordinates_text( w_options_header ); + bool new_val = false; + const int psize = pages_.size(); + found_opt = run_for_point_in( opt_tab_map, *coord, + [&iCurrentPage, &new_val, &psize]( const std::pair> &p ) { + new_val = true; + iCurrentPage = clamp( p.first, 0, psize - 1 ); + } ) > 0; + if( new_val ) { + iCurrentLine = 0; + iStartPos = 0; + recalc_startpos = true; + sfx::play_variant_sound( "menu_move", "default", 100 ); } } if( !found_opt ) { // option lines - cata::optional coord = ctxt.get_coordinates_text( w_options ); - for( const auto &ent : opt_line_map ) { - if( coord.has_value() && ent.second.contains( coord.value() ) ) { - found_opt = true; - iCurrentLine = clamp( ent.first, 0, page_items.size() - 1 ); - if( action == "SELECT" ) { - action = "CONFIRM"; - } - break; + coord = ctxt.get_coordinates_text( w_options ); + if( !!coord ) { + const int psize = page_items.size(); + found_opt = run_for_point_in( opt_line_map, *coord, + [&iCurrentLine, &psize]( const std::pair> &p ) { + iCurrentLine = clamp( p.first, 0, psize - 1 ); + } ) > 0; + if( found_opt && action == "SELECT" ) { + action = "CONFIRM"; } } } diff --git a/src/worldfactory.cpp b/src/worldfactory.cpp index 939a3ccbc3cf7..9124da15c9371 100644 --- a/src/worldfactory.cpp +++ b/src/worldfactory.cpp @@ -418,7 +418,7 @@ WORLDPTR worldfactory::pick_world( bool show_prompt, bool empty_only ) mapLines[3] = true; std::map > world_pages; - std::vector, int>> button_map; + std::map> button_map; point world_list_top_left; int world_list_width = 0; int sel = 0; @@ -511,7 +511,7 @@ WORLDPTR worldfactory::pick_world( bool show_prompt, bool empty_only ) const bool sel_this = static_cast( i ) == sel; inclusive_rectangle btn( world_list_top_left + point( 4, i ), world_list_top_left + point( world_list_width - 1, i ) ); - button_map.emplace_back( btn, i ); + button_map.emplace( i, btn ); mvwprintz( w_worlds, point( 0, static_cast( i ) ), c_white, "%d", i + 1 ); wmove( w_worlds, point( 4, static_cast( i ) ) ); @@ -580,17 +580,19 @@ WORLDPTR worldfactory::pick_world( bool show_prompt, bool empty_only ) // handle mouse click if( action == "SELECT" || action == "MOUSE_MOVE" ) { cata::optional coord = ctxt.get_coordinates_text( catacurses::stdscr ); - for( const auto &it : button_map ) { - if( coord.has_value() && it.first.contains( coord.value() ) ) { - if( sel != it.second ) { + if( !!coord ) { + int cnt = run_for_point_in( button_map, *coord, + [&sel, &on_move]( const std::pair> &p ) { + if( sel != p.first ) { on_move( false ); - sel = it.second; + sel = p.first; } + } ); + if( cnt > 0 ) { if( action == "SELECT" ) { action = "CONFIRM"; } ui_manager::redraw(); - break; } } } @@ -922,10 +924,11 @@ void worldfactory::show_active_world_mods( const std::vector &world_mods if( !world_mods.empty() && action == "MOUSE_MOVE" ) { cata::optional coord = ctxt.get_coordinates_text( w_mods ); - for( const auto &ent : ent_map ) { - if( coord.has_value() && ent.second.contains( coord.value() ) ) { - cursor = ent.first; - } + if( !!coord ) { + run_for_point_in( ent_map, *coord, + [&cursor]( const std::pair> &p ) { + cursor = p.first; + } ); } } @@ -1303,61 +1306,65 @@ int worldfactory::show_worldgen_tab_modselection( const catacurses::window &win, if( action == "MOUSE_MOVE" || action == "SELECT" ) { bool found_opt = false; sel_top_tab = 0; - // Mod tabs cata::optional coord = ctxt.get_coordinates_text( win ); - for( const auto &ent : mod_tab_map ) { - if( coord.has_value() && ent.second.contains( coord.value() ) ) { - found_opt = true; - if( static_cast( iCurrentTab ) != ent.first ) { - active_header = 0; - startsel[0] = 0; - cursel[0] = 0; - recalc_start = true; - iCurrentTab = clamp( ent.first, 0, get_mod_list_tabs().size() - 1 ); + if( !!coord ) { + // Mod tabs + bool new_val = false; + found_opt = run_for_point_in( mod_tab_map, *coord, + [&iCurrentTab, &new_val]( const std::pair> &p ) { + if( static_cast( iCurrentTab ) != p.first ) { + new_val = true; + iCurrentTab = clamp( p.first, 0, get_mod_list_tabs().size() - 1 ); } - break; + } ) > 0; + if( new_val ) { + active_header = 0; + startsel[0] = 0; + cursel[0] = 0; + recalc_start = true; } } - if( !found_opt ) { + if( !found_opt && !!coord ) { // Top tabs - coord = ctxt.get_coordinates_text( win ); - for( const auto &ent : top_tab_map ) { - if( coord.has_value() && ent.second.contains( coord.value() ) ) { - found_opt = true; - sel_top_tab = ent.first; - if( action == "SELECT" ) { - tab_output = sel_top_tab; - } - break; + found_opt = run_for_point_in( top_tab_map, *coord, + [&sel_top_tab]( const std::pair> &p ) { + sel_top_tab = p.first; + } ) > 0; + if( found_opt ) { + if( action == "SELECT" ) { + tab_output = sel_top_tab; } } } if( !found_opt ) { // Inactive mod list coord = ctxt.get_coordinates_text( w_list ); - for( const auto &ent : inact_mod_map ) { - if( coord.has_value() && ent.second.contains( coord.value() ) ) { - found_opt = true; - cursel[0] = ent.first; - active_header = 0; - if( action == "SELECT" ) { - action = "CONFIRM"; - } - break; + if( !!coord ) { + found_opt = run_for_point_in( inact_mod_map, *coord, + [&cursel]( const std::pair> &p ) { + cursel[0] = p.first; + } ); + } + if( found_opt ) { + active_header = 0; + if( action == "SELECT" ) { + action = "CONFIRM"; } } } if( !found_opt ) { // Active mod list coord = ctxt.get_coordinates_text( w_active ); - for( const auto &ent : act_mod_map ) { - if( coord.has_value() && ent.second.contains( coord.value() ) ) { - cursel[1] = ent.first; - active_header = 1; - if( action == "SELECT" ) { - action = "CONFIRM"; - } - break; + if( !!coord ) { + found_opt = run_for_point_in( act_mod_map, *coord, + [&cursel]( const std::pair> &p ) { + cursel[1] = p.first; + } ); + } + if( found_opt ) { + active_header = 1; + if( action == "SELECT" ) { + action = "CONFIRM"; } } } @@ -1407,7 +1414,6 @@ int worldfactory::show_worldgen_tab_modselection( const catacurses::window &win, active_header = 0; } } - recalc_start = true; } else if( action == "ADD_MOD" ) { if( active_header == 1 && active_mod_order.size() > 1 ) { mman_ui->try_shift( '+', cursel[1], active_mod_order ); @@ -1583,13 +1589,13 @@ int worldfactory::show_worldgen_tab_confirm( const catacurses::window &win, WORL if( action == "MOUSE_MOVE" || action == "SELECT" ) { sel_top_tab = 2; cata::optional coord = ctxt.get_coordinates_text( win ); - for( const auto &ent : tab_map ) { - if( coord.has_value() && ent.second.contains( coord.value() ) ) { - sel_top_tab = ent.first; - if( action == "SELECT" && sel_top_tab != 2 ) { - return sel_top_tab - 2; - } - break; + if( !!coord ) { + int cnt = run_for_point_in( tab_map, *coord, + [&sel_top_tab]( const std::pair> &p ) { + sel_top_tab = p.first; + } ); + if( cnt > 0 && action == "SELECT" && sel_top_tab != 2 ) { + return sel_top_tab - 2; } } } else if( action == "NEXT_TAB" ) {