diff --git a/data/raw/keybindings.json b/data/raw/keybindings.json index b2870868e4f90..218093b723719 100644 --- a/data/raw/keybindings.json +++ b/data/raw/keybindings.json @@ -2080,6 +2080,20 @@ "name": "Toggle activate/examine", "bindings": [ { "input_method": "keyboard_char", "key": "!" }, { "input_method": "keyboard_code", "key": "1", "mod": [ "shift" ] } ] }, + { + "type": "keybinding", + "id": "SCROLL_TRAIT_INFO_UP", + "category": "MUTATIONS", + "name": "Scroll mutation info up", + "bindings": [ { "input_method": "keyboard_char", "key": "<" }, { "input_method": "keyboard_code", "key": ",", "mod": [ "shift" ] } ] + }, + { + "type": "keybinding", + "id": "SCROLL_TRAIT_INFO_DOWN", + "category": "MUTATIONS", + "name": "Scroll mutation info down", + "bindings": [ { "input_method": "keyboard_char", "key": ">" }, { "input_method": "keyboard_code", "key": ".", "mod": [ "shift" ] } ] + }, { "type": "keybinding", "id": "APPLY", diff --git a/src/mutation_ui.cpp b/src/mutation_ui.cpp index 5d47e07c9f82a..0cb6c03d2c71a 100644 --- a/src/mutation_ui.cpp +++ b/src/mutation_ui.cpp @@ -153,6 +153,7 @@ void avatar::power_mutations() int second_column = 0; int scroll_position = 0; + int examine_pos = 0; int cursor = 0; int max_scroll_position = 0; int list_height = 0; @@ -199,6 +200,7 @@ void avatar::power_mutations() point( START.x + 1, TITLE_START_Y ) ); recalc_max_scroll_position(); + examine_pos = 0; // X-coordinate of the list of active mutations second_column = 32 + ( TERMX - FULL_SCREEN_WIDTH ) / 4; @@ -215,6 +217,8 @@ void avatar::power_mutations() ctxt.register_action( "REASSIGN" ); ctxt.register_action( "NEXT_TAB" ); ctxt.register_action( "PREV_TAB" ); + ctxt.register_action( "SCROLL_TRAIT_INFO_UP" ); + ctxt.register_action( "SCROLL_TRAIT_INFO_DOWN" ); ctxt.register_action( "CONFIRM" ); ctxt.register_action( "HELP_KEYBINDINGS" ); ctxt.register_action( "QUIT" ); @@ -337,13 +341,23 @@ void avatar::power_mutations() draw_scrollbar( wBio, scroll_position, list_height, mutations_count, point( 0, list_start_y ), c_white, true ); - wnoutrefresh( wBio ); - show_mutations_titlebar( w_title, menu_mode, ctxt ); if( menu_mode == mutation_menu_mode::examining && examine_id.has_value() ) { werase( w_description ); - fold_and_print( w_description, point_zero, WIDTH - 2, c_light_blue, - mutation_desc( examine_id.value() ) ); + std::vector desc = foldstring( mutation_desc( examine_id.value() ), WIDTH - 2 ); + const int winh = catacurses::getmaxy( w_description ); + const bool do_scroll = desc.size() > static_cast( std::abs( winh ) ); + const int fline = do_scroll ? examine_pos % ( desc.size() + 1 - winh ) : 0; + const int lline = do_scroll ? fline + winh : desc.size(); + for( int i = fline; i < lline; i++ ) { + trim_and_print( w_description, point( 0, i - fline ), WIDTH - 2, c_light_blue, desc[i] ); + } + draw_scrollbar( wBio, fline, winh, desc.size(), point( 0, catacurses::getmaxy( wBio ) - winh - 1 ), + c_white, true ); + } + wnoutrefresh( wBio ); + show_mutations_titlebar( w_title, menu_mode, ctxt ); + if( menu_mode == mutation_menu_mode::examining && examine_id.has_value() ) { wnoutrefresh( w_description ); } } ); @@ -474,6 +488,7 @@ void avatar::power_mutations() if( scroll_position > 0 && cursor - scroll_position < half_list_view_location ) { scroll_position = std::max( cursor - half_list_view_location, 0 ); } + examine_pos = 0; // Draw the description, shabby workaround examine_id = GetTrait( active, passive, cursor, tab_mode ); @@ -502,8 +517,12 @@ void avatar::power_mutations() std::max( std::min( lim + 1 - list_height, cursor - half_list_view_location ), 0 ); } + examine_pos = 0; examine_id = GetTrait( active, passive, cursor, tab_mode ); + } else if( ( action == "SCROLL_TRAIT_INFO_UP" || action == "SCROLL_TRAIT_INFO_DOWN" ) && + menu_mode == mutation_menu_mode::examining ) { + examine_pos += action == "SCROLL_TRAIT_INFO_UP" ? -1 : 1; } else if( action == "NEXT_TAB" || action == "PREV_TAB" ) { if( tab_mode == mutation_tab_mode::active && !passive.empty() ) { tab_mode = mutation_tab_mode::passive; @@ -513,6 +532,7 @@ void avatar::power_mutations() continue; } scroll_position = 0; + examine_pos = 0; cursor = 0; examine_id = GetTrait( active, passive, cursor, tab_mode ); } else if( action == "CONFIRM" ) { @@ -616,7 +636,12 @@ void avatar::power_mutations() // switches between activation and examination menu_mode = menu_mode == mutation_menu_mode::activating ? mutation_menu_mode::examining : mutation_menu_mode::activating; - examine_id = std::nullopt; + if( menu_mode == mutation_menu_mode::examining ) { + examine_id = GetTrait( active, passive, cursor, tab_mode ); + } else { + examine_id = std::nullopt; + } + examine_pos = 0; } else if( action == "TOGGLE_SPRITE" ) { menu_mode = mutation_menu_mode::hiding; examine_id = std::nullopt; diff --git a/src/player_display.cpp b/src/player_display.cpp index d5516bd58b4e6..c0ed9def5c3b3 100644 --- a/src/player_display.cpp +++ b/src/player_display.cpp @@ -632,14 +632,25 @@ static void draw_traits_tab( ui_adaptor &ui, const catacurses::window &w_traits, } static void draw_traits_info( const catacurses::window &w_info, const unsigned line, - const std::vector &traitslist ) + const std::vector &traitslist, const unsigned info_line ) { werase( w_info ); if( line < traitslist.size() ) { const trait_and_var &cur = traitslist[line]; - // NOLINTNEXTLINE(cata-use-named-point-constants) - fold_and_print( w_info, point( 1, 0 ), FULL_SCREEN_WIDTH - 2, c_light_gray, string_format( "%s: %s", - colorize( cur.name(), cur.trait->get_display_color() ), cur.desc() ) ); + std::vector desc = + foldstring( string_format( "%s: %s", colorize( cur.name(), cur.trait->get_display_color() ), + cur.desc() ), FULL_SCREEN_WIDTH - 3 ); + const int winh = catacurses::getmaxy( w_info ); + const bool do_scroll = desc.size() > static_cast( std::abs( winh ) ); + const int fline = do_scroll ? info_line % ( desc.size() + 1 - winh ) : 0; + const int lline = do_scroll ? fline + winh : desc.size(); + for( int i = fline; i < lline; i++ ) { + trim_and_print( w_info, point( 1, i - fline ), FULL_SCREEN_WIDTH - 3, c_light_gray, desc[i] ); + } + if( do_scroll ) { + draw_scrollbar( w_info, fline, winh, desc.size(), point( FULL_SCREEN_WIDTH - 3, 0 ), c_white, + true ); + } } wnoutrefresh( w_info ); } @@ -1057,7 +1068,7 @@ static void draw_info_window( const catacurses::window &w_info, const Character draw_skills_info( w_info, you, line, skillslist ); break; case player_display_tab::traits: - draw_traits_info( w_info, line, traitslist ); + draw_traits_info( w_info, line, traitslist, info_line ); break; case player_display_tab::bionics: draw_bionics_info( w_info, line, bionicslist );