Skip to content

Commit

Permalink
Merge pull request #56630 from andrei8l/inv_ui-declutter
Browse files Browse the repository at this point in the history
Declutter inventory UIs
  • Loading branch information
kevingranade authored Apr 20, 2022
2 parents ec992e2 + f017c13 commit 500e264
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 101 deletions.
20 changes: 6 additions & 14 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1719,23 +1719,17 @@ static hint_rating rate_action_eat( const avatar &you, const item &it )

static hint_rating rate_action_collapse( const item &it )
{
if( it.is_container() ) {
for( const item_pocket *pocket : it.get_all_contained_pockets().value() ) {
if( !pocket->settings.is_collapsed() ) {
return hint_rating::good;
}
for( const item_pocket *pocket : it.get_all_standard_pockets().value() ) {
if( !pocket->settings.is_collapsed() ) {
return hint_rating::good;
}
return hint_rating::cant;
}
return hint_rating::cant;
}

static hint_rating rate_action_expand( const item &it )
{
if( !it.is_container() ) {
return hint_rating::cant;
}
for( const item_pocket *pocket : it.get_all_contained_pockets().value() ) {
for( const item_pocket *pocket : it.get_all_standard_pockets().value() ) {
if( pocket->settings.is_collapsed() ) {
return hint_rating::good;
}
Expand Down Expand Up @@ -2141,10 +2135,8 @@ int game::inventory_item_menu( item_location locThisItem,
break;
case '<':
case '>':
if( oThisItem.is_container() ) {
for( item_pocket *pocket : oThisItem.get_all_contained_pockets().value() ) {
pocket->settings.set_collapse( cMenu == '>' );
}
for( item_pocket *pocket : oThisItem.get_all_standard_pockets().value() ) {
pocket->settings.set_collapse( cMenu == '>' );
}
break;
default:
Expand Down
4 changes: 3 additions & 1 deletion src/game_inventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,9 @@ class pickup_inventory_preset : public inventory_selector_preset
public:
explicit pickup_inventory_preset( const Character &you,
bool skip_wield_check = false ) : you( you ),
skip_wield_check( skip_wield_check ) {}
skip_wield_check( skip_wield_check ) {
_pk_type = item_pocket::pocket_type::LAST;
}

std::string get_denial( const item_location &loc ) const override {
if( !you.has_item( *loc ) ) {
Expand Down
115 changes: 59 additions & 56 deletions src/inventory_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -873,11 +873,9 @@ void inventory_column::set_collapsed( inventory_entry &entry, const bool collaps

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 );
collapsed = true;
}
for( item_pocket *pocket : loc->get_all_standard_pockets().value() ) {
pocket->settings.set_collapse( collapse );
collapsed = true;
}
}

Expand Down Expand Up @@ -934,13 +932,14 @@ void inventory_column::on_change( const inventory_entry &/* entry */ )
// stub
}

void inventory_column::add_entry( const inventory_entry &entry )
inventory_entry *inventory_column::add_entry( const inventory_entry &entry )
{
if( std::find( entries.begin(), entries.end(), entry ) != entries.end() ) {
debugmsg( "Tried to add a duplicate entry." );
return;
return nullptr;
}
bool has_loc = false;
entries_cell_cache.clear();
paging_is_valid = false;
if( entry.is_item() ) {
item_location entry_item = entry.locations.front();

Expand All @@ -956,24 +955,23 @@ void inventory_column::add_entry( const inventory_entry &entry )
( ( !entry_item.has_parent() and !found_entry_item.has_parent() ) ||
( entry_item.has_parent() and found_entry_item.has_parent() and
entry_item.parent_item() == found_entry_item.parent_item() ) ) and
entry_item->is_collapsed() == found_entry_item->is_collapsed() and
entry_item->display_stacked_with( *found_entry_item, preset.get_checking_components() );
} );
if( entry_with_loc != entries.end() ) {
has_loc = true;
std::vector<item_location> locations = entry_with_loc->locations;
locations.insert( locations.end(), entry.locations.begin(), entry.locations.end() );
inventory_entry nentry( locations, entry.get_category_ptr() );
nentry.topmost_parent = entry_with_loc->topmost_parent;
nentry.generation = entry_with_loc->generation;
nentry.collapsed = entry_with_loc->collapsed;
entries.erase( entry_with_loc );
add_entry( nentry );
return add_entry( nentry );
}
}
if( !has_loc ) {
entries.emplace_back( entry );
}
entries_cell_cache.clear();
paging_is_valid = false;

entries.emplace_back( entry );
return &entries.back();
}

void inventory_column::_move_entries_to( entries_t const &ent, inventory_column &dest )
Expand Down Expand Up @@ -1075,7 +1073,7 @@ void inventory_column::prepare_paging( const std::string &filter )
std::stable_sort( entries.begin(), entries.end(),
[this]( const inventory_entry & lhs, const inventory_entry & rhs ) {
if( *lhs.get_category_ptr() == *rhs.get_category_ptr() ) {
if( preset.indent_entries() ) {
if( indent_entries() ) {
return indented_sort_compare( lhs, rhs );
}

Expand Down Expand Up @@ -1273,8 +1271,9 @@ void inventory_column::draw( const catacurses::window &win, const point &p,
text_width; // Align either to the left or to the right

const std::string &hl_option = get_option<std::string>( "INVENTORY_HIGHLIGHT" );
if( entry.collapsed && cell_index == 0 ) {
trim_and_print( win, point( text_x - 1, yy ), 1, c_dark_gray, "<" );
if( cell_index == 0 and entry.chevron ) {
trim_and_print( win, point( text_x - 1, yy ), 1, c_dark_gray,
entry.collapsed ? "" : "" );
}
if( entry.is_item() && ( selected || !entry.is_selectable() ) ) {
trim_and_print( win, point( text_x, yy ), text_width, selected ? h_white : c_dark_gray,
Expand Down Expand Up @@ -1445,13 +1444,13 @@ const item_category *inventory_selector::naturalize_category( const item_categor
return &categories.back();
}

void inventory_selector::add_entry( inventory_column &target_column,
std::vector<item_location> &&locations,
const item_category *custom_category,
const size_t chosen_count, item *topmost_parent )
inventory_entry *inventory_selector::add_entry( inventory_column &target_column,
std::vector<item_location> &&locations,
const item_category *custom_category,
const size_t chosen_count, item *topmost_parent )
{
if( !preset.is_shown( locations.front() ) ) {
return;
return nullptr;
}

is_empty = false;
Expand All @@ -1462,38 +1461,63 @@ void inventory_selector::add_entry( inventory_column &target_column,
entry.collapsed = locations.front()->is_collapsed();
entry.topmost_parent = topmost_parent;
entry.generation = entry_generation_number++;
target_column.add_entry( entry );
inventory_entry *const ret = target_column.add_entry( entry );

shared_ptr_fast<ui_adaptor> current_ui = ui.lock();
if( current_ui ) {
current_ui->mark_resize();
}

return ret;
}

bool inventory_selector::add_entry_rec( inventory_column &entry_column,
inventory_column &children_column, item_location &loc,
item_category const *entry_category,
item_category const *children_category,
item *topmost_parent )
{
bool const vis_contents =
add_contained_items( loc, children_column, children_category,
get_topmost_parent( topmost_parent, loc, preset ) );
inventory_entry *const nentry = add_entry( entry_column, std::vector<item_location>( 1, loc ),
entry_category, 0, topmost_parent );
if( nentry != nullptr ) {
nentry->chevron = vis_contents;
return true;
}
return vis_contents;
}

void inventory_selector::add_contained_items( item_location &container )
bool inventory_selector::add_contained_items( item_location &container )
{
add_contained_items( container, own_inv_column );
return add_contained_items( container, own_inv_column );
}

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

for( item *it : container->all_items_top( item_pocket::pocket_type::CONTAINER ) ) {
std::list<item *> const items = preset.get_pocket_type() == item_pocket::pocket_type::LAST
? container->all_items_top()
: container->all_items_top( preset.get_pocket_type() );

bool vis_top = false;
for( item *it : items ) {
item_location child( container, it );
item_category const *hacked_cat = custom_category;
inventory_column *hacked_col = &column;
if( is_worn_ablative( container, child ) ) {
hacked_cat = &item_category_ITEMS_WORN.obj();
hacked_col = &own_gear_column;
}
add_entry( *hacked_col, std::vector<item_location>( 1, child ), hacked_cat, 0, topmost_parent );
add_contained_items( child, column, custom_category, get_topmost_parent( topmost_parent, child,
preset ) );
vis_top |= add_entry_rec( *hacked_col, column, child, hacked_cat, custom_category,
topmost_parent );
}
return vis_top;
}

void inventory_selector::add_contained_ebooks( item_location &container )
Expand All @@ -1513,14 +1537,10 @@ void inventory_selector::add_character_items( Character &character )
item &weapon = character.get_wielded_item();
if( !weapon.is_null() ) {
item_location loc( character, &weapon );
add_entry( own_gear_column, std::vector<item_location>( 1, loc ),
&item_category_WEAPON_HELD.obj() );
add_contained_items( loc, own_inv_column, nullptr, &*loc );
add_entry_rec( own_gear_column, own_inv_column, loc, &item_category_WEAPON_HELD.obj() );
}
for( item_location &worn_item : character.top_items_loc() ) {
add_entry( own_gear_column, std::vector<item_location>( 1, worn_item ),
&item_category_ITEMS_WORN.obj() );
add_contained_items( worn_item, own_inv_column, nullptr, &*worn_item );
add_entry_rec( own_gear_column, own_inv_column, worn_item, &item_category_ITEMS_WORN.obj() );
}
own_inv_column.set_indent_entries_override( false );
}
Expand Down Expand Up @@ -1564,8 +1584,7 @@ void inventory_selector::_add_map_items( tripoint const &target, item_category c

for( item &it : items ) {
item_location loc = floc( it );
add_entry( *col, std::vector<item_location>( 1, loc ), custom_cat );
add_contained_items( loc, *col, custom_cat, &*loc );
add_entry_rec( *col, *col, loc, custom_cat, custom_cat );
}
}

Expand Down Expand Up @@ -3147,11 +3166,6 @@ bool inventory_examiner::check_parent_item()

int inventory_examiner::cleanup()
{
if( parent_was_collapsed ) {
for( item_pocket *pocket : parent_item->get_all_contained_pockets().value() ) {
pocket->settings.set_collapse( true );
}
}
if( changes_made ) {
return EXAMINED_CONTENTS_WITH_CHANGES;
} else {
Expand Down Expand Up @@ -3185,17 +3199,6 @@ int inventory_examiner::execute()
return NO_CONTENTS_TO_EXAMINE;
}

if( parent_item->is_collapsed() ) {
parent_was_collapsed = true;
/*This is based on inventory_column::set_collapsed(), but very deliberately only goes one layer deep.
If it went deeper, we would need to remember the status of each nested item.
*/
for( item_pocket *pocket : parent_item->get_all_contained_pockets().value() ) {
pocket->settings.set_collapse( false );
}
set_title( parent_item->display_name() ); //Update the title to reflect that things aren't hidden
}

//Account for the indentation from the fact we're looking into a container
get_visible_columns().front()->set_parent_indentation( contained_offset( parent_item ) + 2 );

Expand Down
27 changes: 20 additions & 7 deletions src/inventory_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "input.h"
#include "item_category.h"
#include "item_location.h"
#include "item_pocket.h"
#include "memory_fast.h"
#include "optional.h"
#include "pimpl.h"
Expand Down Expand Up @@ -159,6 +160,7 @@ class inventory_entry
// topmost visible parent, used for visibility checks
item *topmost_parent = nullptr;
size_t generation = 0;
bool chevron = false;

private:
const item_category *custom_category = nullptr;
Expand Down Expand Up @@ -207,6 +209,10 @@ class inventory_selector_preset
return check_components;
}

item_pocket::pocket_type get_pocket_type() const {
return _pk_type;
}

virtual std::function<bool( const inventory_entry & )> get_filter( const std::string &filter )
const;

Expand Down Expand Up @@ -234,6 +240,8 @@ class inventory_selector_preset
// whether to indent contained entries in the menu
bool _indent_entries = true;

item_pocket::pocket_type _pk_type = item_pocket::pocket_type::CONTAINER;

private:
class cell_t
{
Expand Down Expand Up @@ -336,7 +344,7 @@ class inventory_column
void draw( const catacurses::window &win, const point &p,
std::vector< std::pair<inclusive_rectangle<point>, inventory_entry *>> &rect_entry_map );

void add_entry( const inventory_entry &entry );
inventory_entry *add_entry( const inventory_entry &entry );
void move_entries_to( inventory_column &dest );
void clear();
void set_stack_favorite( std::vector<item_location> &locations, bool favorite );
Expand Down Expand Up @@ -553,8 +561,8 @@ class inventory_selector
const inventory_selector_preset &preset = default_preset );
virtual ~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,
bool add_contained_items( item_location &container );
bool add_contained_items( item_location &container, inventory_column &column,
const item_category *custom_category = nullptr, item *topmost_parent = nullptr );
void add_contained_ebooks( item_location &container );
void add_character_items( Character &character );
Expand Down Expand Up @@ -625,10 +633,15 @@ class inventory_selector
const item_category *naturalize_category( const item_category &category,
const tripoint &pos );

void add_entry( inventory_column &target_column,
std::vector<item_location> &&locations,
const item_category *custom_category = nullptr,
size_t chosen_count = 0, item *topmost_parent = nullptr );
inventory_entry *add_entry( inventory_column &target_column,
std::vector<item_location> &&locations,
const item_category *custom_category = nullptr,
size_t chosen_count = 0, item *topmost_parent = nullptr );

bool add_entry_rec( inventory_column &entry_column, inventory_column &children_column,
item_location &loc, item_category const *entry_category = nullptr,
item_category const *children_category = nullptr,
item *topmost_parent = nullptr );

inventory_input get_input();
inventory_input process_input( const std::string &action, int ch );
Expand Down
Loading

0 comments on commit 500e264

Please sign in to comment.