Skip to content

Commit

Permalink
inventory_ui: only hide entries added recursively (#52709)
Browse files Browse the repository at this point in the history
* inventory_ui: don't collapse recursively

nested items are properly hidden now so there's no need to collapse
the entire chain
  • Loading branch information
andrei8l authored Nov 10, 2021
1 parent 2d60627 commit 6db9695
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 39 deletions.
4 changes: 2 additions & 2 deletions src/game_inventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ void game_menus::inv::common( avatar &you )
do {
you.inv->restack( you );
inv_s.clear_items();
inv_s.add_character_items( you, false );
inv_s.add_character_items( you );
inv_s.set_filter( filter );
if( location != item_location::nowhere ) {
inv_s.select( location );
Expand Down Expand Up @@ -1840,7 +1840,7 @@ drop_locations game_menus::inv::multidrop( avatar &you )

inventory_drop_selector inv_s( you, preset );

inv_s.add_character_items( you, false );
inv_s.add_character_items( you );
inv_s.set_title( _( "Multidrop" ) );
inv_s.set_hint( _( "To drop x items, type a number before selecting." ) );

Expand Down
82 changes: 49 additions & 33 deletions src/inventory_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@
#include <unordered_map>
#include <vector>

namespace
{

// get topmost visible parent in an unbroken chain
item *get_topmost_parent( item *topmost, item_location loc,
inventory_selector_preset const &preset )
{
return preset.is_shown( loc ) ? topmost != nullptr ? topmost : loc.get_item() : nullptr;
}

} // namespace

/** The maximum distance from the screen edge, to snap a window to it */
static const size_t max_win_snap_distance = 4;
/** The minimal gap between two cells */
Expand Down Expand Up @@ -143,11 +155,19 @@ bool inventory_entry::is_hidden() const
return false;
}
item_location it = locations.front();
if( !it.has_parent() ) {
return false;
bool hidden = false;
if( topmost_parent != nullptr ) {
while( it.has_parent() ) {
item_location const prnt = it.parent_item();
hidden |= prnt.get_item()->contained_where( *it )->settings.is_collapsed();
if( prnt.get_item() == topmost_parent ) {
break;
}
it = prnt;
}
}
item_location prnt = it.parent_item();
return prnt.get_item()->contained_where( *it )->settings.is_collapsed();

return hidden;
}

int inventory_entry::get_total_charges() const
Expand Down Expand Up @@ -704,24 +724,12 @@ void inventory_column::set_stack_favorite( std::vector<item_location> &locations
void inventory_column::set_collapsed( inventory_entry &entry, const bool collapse )
{
std::vector<item_location> &locations = entry.locations;
std::function<void( item_pocket *, bool )> do_collapse;
do_collapse = [ collapse, &do_collapse ]( item_pocket * pock, bool clps ) {
pock->settings.set_collapse( collapse );
for( item *lctn : pock->all_items_top() ) {
if( lctn->is_container() ) {
for( item_pocket *pocket : lctn->get_all_contained_pockets().value() ) {
do_collapse( pocket, clps );
}
}
}
};

bool collapsed = false;
for( item_location &loc : locations ) {
if( loc.get_item()->is_container() ) {
for( item_pocket *pocket : loc->get_all_contained_pockets().value() ) {
pocket->settings.set_collapse( collapse );
do_collapse( pocket, collapse );
collapsed = true;
}
}
Expand Down Expand Up @@ -888,8 +896,9 @@ void inventory_column::add_entry( const inventory_entry &entry )
has_loc = true;
std::vector<item_location> locations = entry_with_loc->locations;
locations.insert( locations.end(), entry.locations.begin(), entry.locations.end() );
entries.erase( entry_with_loc );
inventory_entry nentry( locations, entry.get_category_ptr() );
nentry.topmost_parent = entry_with_loc->topmost_parent;
entries.erase( entry_with_loc );
add_entry( nentry );
}
}
Expand Down Expand Up @@ -1411,7 +1420,7 @@ const item_category *inventory_selector::naturalize_category( const item_categor
void inventory_selector::add_entry( inventory_column &target_column,
std::vector<item_location> &&locations,
const item_category *custom_category,
const size_t chosen_count )
const size_t chosen_count, item *topmost_parent )
{
if( !preset.is_shown( locations.front() ) ) {
return;
Expand All @@ -1423,6 +1432,7 @@ void inventory_selector::add_entry( inventory_column &target_column,
/*chosen_count=*/chosen_count );

entry.collapsed = locations.front()->is_collapsed();
entry.topmost_parent = topmost_parent;
target_column.add_entry( entry );

shared_ptr_fast<ui_adaptor> current_ui = ui.lock();
Expand All @@ -1434,13 +1444,14 @@ void inventory_selector::add_entry( inventory_column &target_column,
void inventory_selector::add_item( inventory_column &target_column,
item_location &&location,
const item_category *custom_category,
const bool include_hidden )
item *topmost_parent )
{
add_entry( target_column,
std::vector<item_location>( 1, location ),
custom_category );
custom_category, 0, topmost_parent );
for( item *it : location->all_items_top( item_pocket::pocket_type::CONTAINER ) ) {
add_item( target_column, item_location( location, it ), custom_category, include_hidden );
add_item( target_column, item_location( location, it ), custom_category,
get_topmost_parent( topmost_parent, location, preset ) );
}
}

Expand Down Expand Up @@ -1472,22 +1483,23 @@ void inventory_selector::add_contained_items( item_location &container )
}

void inventory_selector::add_contained_items( item_location &container, inventory_column &column,
const item_category *const custom_category )
const item_category *const custom_category, item *topmost_parent )
{
if( container->has_flag( STATIC( flag_id( "NO_UNLOAD" ) ) ) ) {
return;
}

for( item *it : container->all_items_top() ) {
item_location child( container, it );
add_contained_items( child, column, custom_category );
add_contained_items( child, column, custom_category, get_topmost_parent( topmost_parent, child,
preset ) );
const item_category *nat_category = nullptr;
if( custom_category == nullptr ) {
nat_category = &child->get_category_of_contents();
} else if( preset.is_shown( child ) ) {
nat_category = naturalize_category( *custom_category, child.position() );
}
add_entry( column, std::vector<item_location>( 1, child ), nat_category );
add_entry( column, std::vector<item_location>( 1, child ), nat_category, 0, topmost_parent );
}
}

Expand All @@ -1503,15 +1515,15 @@ void inventory_selector::add_contained_ebooks( item_location &container )
}
}

void inventory_selector::add_character_items( Character &character, bool include_hidden )
void inventory_selector::add_character_items( Character &character )
{
character.visit_items( [ this, &character, &include_hidden ]( item * it, item * ) {
character.visit_items( [ this, &character ]( item * it, item * ) {
if( it == &character.get_wielded_item() ) {
add_item( own_gear_column, item_location( character, it ),
&item_category_id( "WEAPON_HELD" ).obj(), include_hidden );
&item_category_id( "WEAPON_HELD" ).obj() );
} else if( character.is_worn( *it ) ) {
add_item( own_gear_column, item_location( character, it ),
&item_category_id( "ITEMS_WORN" ).obj(), include_hidden );
&item_category_id( "ITEMS_WORN" ).obj() );
}
return VisitResponse::NEXT;
} );
Expand All @@ -1524,7 +1536,7 @@ void inventory_selector::add_character_items( Character &character, bool include
for( item &it_elem : *elem ) {
item_location parent( character, &it_elem );
add_contained_items( parent, own_inv_column,
&item_category_id( "ITEMS_WORN" ).obj() );
&item_category_id( "ITEMS_WORN" ).obj(), get_topmost_parent( nullptr, parent, preset ) );
}
}
// this is a little trick; we want the default behavior for contained items to be in own_inv_column
Expand All @@ -1547,7 +1559,7 @@ void inventory_selector::add_map_items( const tripoint &target )

for( item &it_elem : items ) {
item_location parent( map_cursor( target ), &it_elem );
add_contained_items( parent, map_column, &map_cat );
add_contained_items( parent, map_column, &map_cat, get_topmost_parent( nullptr, parent, preset ) );
}
}
}
Expand All @@ -1573,7 +1585,8 @@ void inventory_selector::add_vehicle_items( const tripoint &target )

for( item &it_elem : items ) {
item_location parent( vehicle_cursor( *veh, part ), &it_elem );
add_contained_items( parent, map_column, &vehicle_cat );
add_contained_items( parent, map_column, &vehicle_cat, get_topmost_parent( nullptr, parent,
preset ) );
}
}

Expand Down Expand Up @@ -2196,6 +2209,9 @@ void inventory_selector::on_input( const inventory_input &input )
}
if( input.action == "HIDE_CONTENTS" || input.action == "SHOW_CONTENTS" ) {
shared_ptr_fast<ui_adaptor> current_ui = ui.lock();
for( auto const &col : columns ) {
col->invalidate_paging();
}
if( current_ui ) {
std::vector<item_location> inv = get_selected().locations;
current_ui->mark_resize();
Expand Down Expand Up @@ -2295,7 +2311,7 @@ void inventory_selector::toggle_categorize_contained()
}
add_entry( own_inv_column, std::move( entry->locations ),
/*custom_category=*/custom_category,
/*chosen_count=*/entry->chosen_count );
/*chosen_count=*/entry->chosen_count, entry->topmost_parent );
} else {
replacement_column.add_entry( *entry );
}
Expand All @@ -2322,7 +2338,7 @@ void inventory_selector::toggle_categorize_contained()
}
add_entry( own_gear_column, std::move( entry->locations ),
/*custom_category=*/custom_category,
/*chosen_count=*/entry->chosen_count );
/*chosen_count=*/entry->chosen_count, entry->topmost_parent );
}
own_gear_column.order_by_parent();
own_inv_column.clear();
Expand Down
14 changes: 10 additions & 4 deletions src/inventory_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ class inventory_entry
bool highlight_as_parent = false;
bool highlight_as_child = false;
bool collapsed = false;
// topmost visible parent, used for visibility checks
item *topmost_parent = nullptr;

private:
const item_category *custom_category = nullptr;
Expand Down Expand Up @@ -395,6 +397,10 @@ class inventory_column
indent_entries_override = entry_override;
}

void invalidate_paging() {
paging_is_valid = false;
}

protected:
struct entry_cell_cache_t {
bool assigned = false;
Expand Down Expand Up @@ -510,9 +516,9 @@ class inventory_selector
/** These functions add items from map / vehicles. */
void add_contained_items( item_location &container );
void add_contained_items( item_location &container, inventory_column &column,
const item_category *custom_category = nullptr );
const item_category *custom_category = nullptr, item *topmost_parent = nullptr );
void add_contained_ebooks( item_location &container );
void add_character_items( Character &character, const bool include_hidden = true );
void add_character_items( Character &character );
void add_map_items( const tripoint &target );
void add_vehicle_items( const tripoint &target );
void add_nearby_items( int radius = 1 );
Expand Down Expand Up @@ -559,12 +565,12 @@ class inventory_selector
void add_entry( inventory_column &target_column,
std::vector<item_location> &&locations,
const item_category *custom_category = nullptr,
size_t chosen_count = 0 );
size_t chosen_count = 0, item *topmost_parent = nullptr );

void add_item( inventory_column &target_column,
item_location &&location,
const item_category *custom_category = nullptr,
const bool include_hidden = true );
item *topmost_parent = nullptr );

void add_items( inventory_column &target_column,
const std::function<item_location( item * )> &locator,
Expand Down

0 comments on commit 6db9695

Please sign in to comment.