diff --git a/data/raw/keybindings.json b/data/raw/keybindings.json index cb34c869efeb3..421572bf11fff 100644 --- a/data/raw/keybindings.json +++ b/data/raw/keybindings.json @@ -2889,5 +2889,26 @@ { "input_method": "keyboard", "key": "SPACE" }, { "input_method": "keyboard", "key": "RETURN" } ] + }, + { + "type": "keybinding", + "id": "CREATURE", + "category": "EXTENDED_DESCRIPTION", + "name": "Describe creature", + "bindings": [ { "input_method": "keyboard", "key": "c" } ] + }, + { + "type": "keybinding", + "id": "FURNITURE", + "category": "EXTENDED_DESCRIPTION", + "name": "Describe furniture", + "bindings": [ { "input_method": "keyboard", "key": "f" } ] + }, + { + "type": "keybinding", + "id": "TERRAIN", + "category": "EXTENDED_DESCRIPTION", + "name": "Describe terrain", + "bindings": [ { "input_method": "keyboard", "key": "t" } ] } ] diff --git a/src/descriptions.cpp b/src/descriptions.cpp index 1f90ad56bc574..a301d8caa4245 100644 --- a/src/descriptions.cpp +++ b/src/descriptions.cpp @@ -39,25 +39,23 @@ static const Creature *seen_critter( const game &g, const tripoint &p ) void game::extended_description( const tripoint &p ) { - const int left = 0; - const int right = TERMX; + ui_adaptor ui; const int top = 3; - const int bottom = TERMY; - const int width = right - left; - const int height = bottom - top; - catacurses::window w_head = catacurses::newwin( top, TERMX, point_zero ); - catacurses::window w_main = catacurses::newwin( height, width, point( left, top ) ); - // TODO: De-hardcode - std::string header_message = - _( "c to describe creatures, f to describe furniture, t to describe terrain, Esc/Enter to close." ); - mvwprintz( w_head, point_zero, c_white, header_message ); - - // Set up line drawings - for( int i = 0; i < TERMX; i++ ) { - mvwputch( w_head, point( i, top - 1 ), c_white, LINE_OXOX ); - } + int width = 0; + catacurses::window w_head; + catacurses::window w_main; + ui.on_screen_resize( [&]( ui_adaptor & ui ) { + const int left = 0; + const int right = TERMX; + const int bottom = TERMY; + width = right - left; + const int height = bottom - top; + w_head = catacurses::newwin( top, TERMX, point_zero ); + w_main = catacurses::newwin( height, width, point( left, top ) ); + ui.position( point_zero, point( TERMX, TERMY ) ); + } ); + ui.mark_resize(); - wrefresh( w_head ); // Default to critter (if any), furniture (if any), then terrain. description_target cur_target = description_target::terrain; if( seen_critter( *this, p ) != nullptr ) { @@ -65,12 +63,31 @@ void game::extended_description( const tripoint &p ) } else if( g->m.has_furn( p ) ) { cur_target = description_target::furniture; } - int ch = 'c'; - // FIXME: temporarily disable redrawing of lower UIs before this UI is migrated to `ui_adaptor` - ui_adaptor ui( ui_adaptor::disable_uis_below {} ); + std::string action; + input_context ctxt( "EXTENDED_DESCRIPTION" ); + ctxt.register_action( "CREATURE" ); + ctxt.register_action( "FURNITURE" ); + ctxt.register_action( "TERRAIN" ); + ctxt.register_action( "CONFIRM" ); + ctxt.register_action( "QUIT" ); + ctxt.register_action( "HELP_KEYBINDINGS" ); + + ui.on_redraw( [&]( const ui_adaptor & ) { + werase( w_head ); + mvwprintz( w_head, point_zero, c_white, + _( "[%s] describe creatures, [%s] describe furniture, " + "[%s] describe terrain, [%s] close." ), + ctxt.get_desc( "CREATURE" ), ctxt.get_desc( "FURNITURE" ), + ctxt.get_desc( "TERRAIN" ), ctxt.get_desc( "QUIT" ) ); + + // Set up line drawings + for( int i = 0; i < TERMX; i++ ) { + mvwputch( w_head, point( i, top - 1 ), c_white, LINE_OXOX ); + } + + wrefresh( w_head ); - do { std::string desc; // Allow looking at invisible tiles - player may want to examine hallucinations etc. switch( cur_target ) { @@ -111,21 +128,19 @@ void game::extended_description( const tripoint &p ) werase( w_main ); fold_and_print_from( w_main, point_zero, width, 0, c_light_gray, desc ); wrefresh( w_main ); - // TODO: use input context - ch = inp_mngr.get_input_event().get_first_input(); - switch( ch ) { - case 'c': - cur_target = description_target::creature; - break; - case 'f': - cur_target = description_target::furniture; - break; - case 't': - cur_target = description_target::terrain; - break; - } + } ); - } while( ch != KEY_ESCAPE && ch != '\n' ); + do { + ui_manager::redraw(); + action = ctxt.handle_input(); + if( action == "CREATURE" ) { + cur_target = description_target::creature; + } else if( action == "FURNITURE" ) { + cur_target = description_target::furniture; + } else if( action == "TERRAIN" ) { + cur_target = description_target::terrain; + } + } while( action != "CONFIRM" && action != "QUIT" ); } std::string map_data_common_t::extended_description() const diff --git a/src/faction.cpp b/src/faction.cpp index c12168311ae08..9a64be917041e 100644 --- a/src/faction.cpp +++ b/src/faction.cpp @@ -665,11 +665,22 @@ int npc::faction_display( const catacurses::window &fac_w, const int width ) con void faction_manager::display() const { - int term_x = TERMY > FULL_SCREEN_HEIGHT ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0; - int term_y = TERMX > FULL_SCREEN_WIDTH ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0; + catacurses::window w_missions; + int entries_per_page = 0; - catacurses::window w_missions = catacurses::newwin( FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, - point( term_y, term_x ) ); + ui_adaptor ui; + ui.on_screen_resize( [&]( ui_adaptor & ui ) { + const int term_x = TERMY > FULL_SCREEN_HEIGHT ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0; + const int term_y = TERMX > FULL_SCREEN_WIDTH ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0; + + w_missions = catacurses::newwin( FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, + point( term_y, term_x ) ); + + entries_per_page = FULL_SCREEN_HEIGHT - 4; + + ui.position_from_window( w_missions ); + } ); + ui.mark_resize(); enum class tab_mode : int { TAB_MYFACTION = 0, @@ -682,7 +693,6 @@ void faction_manager::display() const g->validate_camps(); g->validate_npc_followers(); tab_mode tab = tab_mode::FIRST_TAB; - const int entries_per_page = FULL_SCREEN_HEIGHT - 4; size_t selection = 0; input_context ctxt( "FACTION MANAGER" ); ctxt.register_cardinal(); @@ -692,66 +702,20 @@ void faction_manager::display() const ctxt.register_action( "PREV_TAB" ); ctxt.register_action( "CONFIRM" ); ctxt.register_action( "QUIT" ); - - // FIXME: temporarily disable redrawing of lower UIs before this UI is migrated to `ui_adaptor` - ui_adaptor ui( ui_adaptor::disable_uis_below {} ); - - while( true ) { + ctxt.register_action( "HELP_KEYBINDINGS" ); + + std::vector followers; + std::vector valfac; // Factions that we know of. + npc *guy = nullptr; + const faction *cur_fac = nullptr; + bool interactable = false; + bool radio_interactable = false; + basecamp *camp = nullptr; + std::vector camps; + size_t active_vec_size = 0; + + ui.on_redraw( [&]( const ui_adaptor & ) { werase( w_missions ); - // create a list of NPCs, visible and the ones on overmapbuffer - std::vector followers; - for( auto &elem : g->get_follower_list() ) { - shared_ptr_fast npc_to_get = overmap_buffer.find_npc( elem ); - if( !npc_to_get ) { - continue; - } - npc *npc_to_add = npc_to_get.get(); - followers.push_back( npc_to_add ); - } - std::vector valfac; // Factions that we know of. - for( const auto &elem : g->faction_manager_ptr->all() ) { - if( elem.second.known_by_u && elem.second.id != faction_id( "your_followers" ) ) { - valfac.push_back( &elem.second ); - } - } - npc *guy = nullptr; - const faction *cur_fac = nullptr; - bool interactable = false; - bool radio_interactable = false; - basecamp *camp = nullptr; - // create a list of faction camps - std::vector camps; - for( auto elem : g->u.camps ) { - cata::optional p = overmap_buffer.find_camp( elem.xy() ); - if( !p ) { - continue; - } - basecamp *temp_camp = *p; - camps.push_back( temp_camp ); - } - if( tab < tab_mode::FIRST_TAB || tab >= tab_mode::NUM_TABS ) { - debugmsg( "The sanity check failed because tab=%d", static_cast( tab ) ); - tab = tab_mode::FIRST_TAB; - } - size_t active_vec_size = camps.size(); - // entries_per_page * page number - const size_t top_of_page = entries_per_page * ( selection / entries_per_page ); - if( tab == tab_mode::TAB_FOLLOWERS ) { - if( selection < followers.size() ) { - guy = followers[selection]; - } - active_vec_size = followers.size(); - } else if( tab == tab_mode::TAB_MYFACTION ) { - if( selection < camps.size() ) { - camp = camps[selection]; - } - active_vec_size = camps.size(); - } else if( tab == tab_mode::TAB_OTHERFACTIONS ) { - if( selection < valfac.size() ) { - cur_fac = valfac[selection]; - } - active_vec_size = valfac.size(); - } for( int i = 3; i < FULL_SCREEN_HEIGHT - 1; i++ ) { mvwputch( w_missions, point( 30, i ), BORDER_COLOR, LINE_XOXO ); @@ -770,6 +734,9 @@ void faction_manager::display() const mvwputch( w_missions, point( 30, FULL_SCREEN_HEIGHT - 1 ), BORDER_COLOR, LINE_XXOX ); // _|_ const nc_color col = c_white; + // entries_per_page * page number + const size_t top_of_page = entries_per_page * ( selection / entries_per_page ); + switch( tab ) { case tab_mode::TAB_MYFACTION: { const std::string no_camp = _( "You have no camps" ); @@ -843,6 +810,63 @@ void faction_manager::display() const break; } wrefresh( w_missions ); + } ); + + while( true ) { + // create a list of NPCs, visible and the ones on overmapbuffer + followers.clear(); + for( auto &elem : g->get_follower_list() ) { + shared_ptr_fast npc_to_get = overmap_buffer.find_npc( elem ); + if( !npc_to_get ) { + continue; + } + npc *npc_to_add = npc_to_get.get(); + followers.push_back( npc_to_add ); + } + valfac.clear(); + for( const auto &elem : g->faction_manager_ptr->all() ) { + if( elem.second.known_by_u && elem.second.id != faction_id( "your_followers" ) ) { + valfac.push_back( &elem.second ); + } + } + guy = nullptr; + cur_fac = nullptr; + interactable = false; + radio_interactable = false; + camp = nullptr; + // create a list of faction camps + camps.clear(); + for( auto elem : g->u.camps ) { + cata::optional p = overmap_buffer.find_camp( elem.xy() ); + if( !p ) { + continue; + } + basecamp *temp_camp = *p; + camps.push_back( temp_camp ); + } + if( tab < tab_mode::FIRST_TAB || tab >= tab_mode::NUM_TABS ) { + debugmsg( "The sanity check failed because tab=%d", static_cast( tab ) ); + tab = tab_mode::FIRST_TAB; + } + active_vec_size = camps.size(); + if( tab == tab_mode::TAB_FOLLOWERS ) { + if( selection < followers.size() ) { + guy = followers[selection]; + } + active_vec_size = followers.size(); + } else if( tab == tab_mode::TAB_MYFACTION ) { + if( selection < camps.size() ) { + camp = camps[selection]; + } + active_vec_size = camps.size(); + } else if( tab == tab_mode::TAB_OTHERFACTIONS ) { + if( selection < valfac.size() ) { + cur_fac = valfac[selection]; + } + active_vec_size = valfac.size(); + } + + ui_manager::redraw(); const std::string action = ctxt.handle_input(); if( action == "NEXT_TAB" || action == "RIGHT" ) { tab = static_cast( static_cast( tab ) + 1 ); @@ -877,6 +901,4 @@ void faction_manager::display() const break; } } - - g->refresh_all(); } diff --git a/src/faction_camp.cpp b/src/faction_camp.cpp index 1f9f12e6207fb..95c8115f7f7c6 100644 --- a/src/faction_camp.cpp +++ b/src/faction_camp.cpp @@ -1640,39 +1640,39 @@ void basecamp::abandon_camp() void basecamp::worker_assignment_ui() { - int term_x = TERMY > FULL_SCREEN_HEIGHT ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0; - int term_y = TERMX > FULL_SCREEN_WIDTH ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0; + int entries_per_page = 0; + catacurses::window w_followers; + + ui_adaptor ui; + ui.on_screen_resize( [&]( ui_adaptor & ui ) { + const int term_x = TERMY > FULL_SCREEN_HEIGHT ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0; + const int term_y = TERMX > FULL_SCREEN_WIDTH ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0; + + w_followers = catacurses::newwin( FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, + point( term_y, term_x ) ); + entries_per_page = FULL_SCREEN_HEIGHT - 4; + + ui.position_from_window( w_followers ); + } ); + ui.mark_resize(); - catacurses::window w_followers = catacurses::newwin( FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, - point( term_y, term_x ) ); - const int entries_per_page = FULL_SCREEN_HEIGHT - 4; size_t selection = 0; input_context ctxt( "FACTION MANAGER" ); - ctxt.register_cardinal(); ctxt.register_updown(); - ctxt.register_action( "ANY_INPUT" ); ctxt.register_action( "CONFIRM" ); ctxt.register_action( "QUIT" ); + ctxt.register_action( "HELP_KEYBINDINGS" ); validate_assignees(); g->validate_npc_followers(); - while( true ) { + + std::vector followers; + npc *cur_npc = nullptr; + + ui.on_redraw( [&]( const ui_adaptor & ) { werase( w_followers ); - // create a list of npcs stationed at this camp - std::vector followers; - for( const character_id &elem : g->get_follower_list() ) { - shared_ptr_fast npc_to_get = overmap_buffer.find_npc( elem ); - if( !npc_to_get || !npc_to_get->is_following() ) { - continue; - } - npc *npc_to_add = npc_to_get.get(); - followers.push_back( npc_to_add ); - } - npc *cur_npc = nullptr; + // entries_per_page * page number const size_t top_of_page = entries_per_page * ( selection / entries_per_page ); - if( !followers.empty() ) { - cur_npc = followers[selection]; - } for( int i = 0; i < FULL_SCREEN_HEIGHT - 1; i++ ) { mvwputch( w_followers, point( 45, i ), BORDER_COLOR, LINE_XOXO ); @@ -1694,6 +1694,25 @@ void basecamp::worker_assignment_ui() mvwprintz( w_followers, point( 1, FULL_SCREEN_HEIGHT - 1 ), c_light_gray, _( "Press %s to assign this follower to this camp." ), ctxt.get_desc( "CONFIRM" ) ); wrefresh( w_followers ); + } ); + + while( true ) { + // create a list of npcs stationed at this camp + followers.clear(); + for( const character_id &elem : g->get_follower_list() ) { + shared_ptr_fast npc_to_get = overmap_buffer.find_npc( elem ); + if( !npc_to_get || !npc_to_get->is_following() ) { + continue; + } + npc *npc_to_add = npc_to_get.get(); + followers.push_back( npc_to_add ); + } + cur_npc = nullptr; + if( !followers.empty() ) { + cur_npc = followers[selection]; + } + + ui_manager::redraw(); const std::string action = ctxt.handle_input(); if( action == "DOWN" ) { selection++; @@ -1714,44 +1733,41 @@ void basecamp::worker_assignment_ui() break; } } - - g->refresh_all(); } void basecamp::job_assignment_ui() { - int term_x = TERMY > FULL_SCREEN_HEIGHT ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0; - int term_y = TERMX > FULL_SCREEN_WIDTH ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0; + int entries_per_page = 0; + catacurses::window w_jobs; + + ui_adaptor ui; + ui.on_screen_resize( [&]( ui_adaptor & ui ) { + const int term_x = TERMY > FULL_SCREEN_HEIGHT ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0; + const int term_y = TERMX > FULL_SCREEN_WIDTH ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0; + + w_jobs = catacurses::newwin( FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, + point( term_y, term_x ) ); + + entries_per_page = FULL_SCREEN_HEIGHT - 4; + + ui.position_from_window( w_jobs ); + } ); + ui.mark_resize(); - catacurses::window w_jobs = catacurses::newwin( FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, - point( term_y, term_x ) ); - const int entries_per_page = FULL_SCREEN_HEIGHT - 4; size_t selection = 0; input_context ctxt( "FACTION MANAGER" ); - ctxt.register_cardinal(); ctxt.register_updown(); - ctxt.register_action( "ANY_INPUT" ); ctxt.register_action( "CONFIRM" ); ctxt.register_action( "QUIT" ); - // FIXME: temporarily disable redrawing of lower UIs before this UI is migrated to `ui_adaptor` - ui_adaptor ui( ui_adaptor::disable_uis_below {} ); + ctxt.register_action( "HELP_KEYBINDINGS" ); validate_assignees(); - while( true ) { + + std::vector stationed_npcs; + npc *cur_npc = nullptr; + + ui.on_redraw( [&]( const ui_adaptor & ) { werase( w_jobs ); - // create a list of npcs stationed at this camp - std::vector stationed_npcs; - for( const auto &elem : get_npcs_assigned() ) { - if( elem ) { - stationed_npcs.push_back( elem.get() ); - } - } - npc *cur_npc = nullptr; - // entries_per_page * page number const size_t top_of_page = entries_per_page * ( selection / entries_per_page ); - if( !stationed_npcs.empty() ) { - cur_npc = stationed_npcs[selection]; - } - for( int i = 0; i < FULL_SCREEN_HEIGHT - 1; i++ ) { mvwputch( w_jobs, point( 45, i ), BORDER_COLOR, LINE_XOXO ); } @@ -1791,6 +1807,24 @@ void basecamp::job_assignment_ui() mvwprintz( w_jobs, point( 1, FULL_SCREEN_HEIGHT - 1 ), c_light_gray, _( "Press %s to change this workers job priorities." ), ctxt.get_desc( "CONFIRM" ) ); wrefresh( w_jobs ); + } ); + + while( true ) { + // create a list of npcs stationed at this camp + stationed_npcs.clear(); + for( const auto &elem : get_npcs_assigned() ) { + if( elem ) { + stationed_npcs.push_back( elem.get() ); + } + } + cur_npc = nullptr; + // entries_per_page * page number + if( !stationed_npcs.empty() ) { + cur_npc = stationed_npcs[selection]; + } + + ui_manager::redraw(); + const std::string action = ctxt.handle_input(); if( action == "DOWN" ) { selection++; @@ -1843,8 +1877,6 @@ void basecamp::job_assignment_ui() break; } } - - g->refresh_all(); } void basecamp::start_menial_labor()