Skip to content

Commit

Permalink
Allow toggling categories in pickup_selector
Browse files Browse the repository at this point in the history
  • Loading branch information
IndecisionTree committed Jul 2, 2022
1 parent 9c10b23 commit 12d80fe
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 29 deletions.
92 changes: 63 additions & 29 deletions src/inventory_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,16 @@ bool always_yes( const inventory_entry & )
return true;
}

bool return_item( const inventory_entry& entry )
bool return_item( const inventory_entry &entry )
{
return entry.is_item();
}

bool is_container( const item_location &loc )
{
return loc.where() == item_location::type::container;
}

} // namespace

bool is_worn_ablative( item_location const &container, item_location const &child )
Expand Down Expand Up @@ -176,7 +181,7 @@ struct container_data {

static int contained_offset( const item_location &loc )
{
if( loc.where() != item_location::type::container ) {
if( !is_container( loc ) ) {
return 0;
}
return 2 + contained_offset( loc.parent_item() );
Expand Down Expand Up @@ -559,8 +564,7 @@ bool inventory_holster_preset::is_shown( const item_location &contained ) const
if( contained.eventually_contains( holster ) || holster.eventually_contains( contained ) ) {
return false;
}
if( contained.where() != item_location::type::container
&& contained->made_of( phase_id::LIQUID ) ) {
if( !is_container( contained ) && contained->made_of( phase_id::LIQUID ) ) {
// spilt liquid cannot be picked up
return false;
}
Expand Down Expand Up @@ -2453,45 +2457,49 @@ bool inventory_selector::is_overflown( size_t client_width ) const

void inventory_selector::_categorize( inventory_column &col )
{
inventory_column replacement_column;
// Remove custom category and allow entries to categorize by their item's category
for( inventory_entry *entry : col.get_entries( return_item, true ) ) {
inventory_entry *ret =
add_entry( replacement_column, std::move( entry->locations ), nullptr,
entry->chosen_count, entry->topmost_parent, entry->chevron );
ret->generation = entry->generation;
const item_location loc = entry->any_item();
const item_category *custom_category = nullptr;

// ensure top-level equipped entries don't lose their special categories
if( &*loc == &u.get_wielded_item() ) {
custom_category = &item_category_WEAPON_HELD.obj();
} else if( u.is_worn( *loc ) ) {
custom_category = &item_category_ITEMS_WORN.obj();
}

entry->set_custom_category( custom_category );
}
col.clear();
replacement_column.move_entries_to( col );
col.set_indent_entries_override( false );
col.invalidate_paging();
}

void inventory_selector::_uncategorize( inventory_column &col )
{
inventory_column replacement_column;
for( inventory_entry *entry : col.get_entries( return_item, true ) ) {
item_location loc = entry->any_item();
item_location ancestor = loc;
// find the topmost parent of the entry's item and categorize it by that
// to form the hierarchy
item_location ancestor = entry->any_item();
while( ancestor.has_parent() ) {
ancestor = ancestor.parent_item();
}

const item_category *custom_category = nullptr;
if( ancestor.where() != item_location::type::character ) {
const std::string name = to_upper_case( remove_color_tags( ancestor.describe() ) );
const item_category map_cat( name, no_translation( name ), 100 );
custom_category = naturalize_category( map_cat, loc.position() );
custom_category = naturalize_category( map_cat, ancestor.position() );
} else if( &*ancestor == &u.get_wielded_item() ) {
custom_category = &item_category_WEAPON_HELD.obj();
} else if( u.is_worn( *ancestor ) ) {
custom_category = &item_category_ITEMS_WORN.obj();
}
inventory_entry *ret =
add_entry( replacement_column, std::move( entry->locations ), custom_category,
entry->chosen_count, entry->topmost_parent, entry->chevron );
ret->generation = entry->generation;

entry->set_custom_category( custom_category );
}
col.clear();
replacement_column.move_entries_to( col );
col.clear_indent_entries_override();
col.invalidate_paging();
}

void inventory_selector::toggle_categorize_contained()
Expand All @@ -2500,37 +2508,47 @@ void inventory_selector::toggle_categorize_contained()
if( get_highlighted().is_item() ) {
highlighted = get_highlighted().locations;
}

if( _uimode == uimode::hierarchy ) {
inventory_column replacement_column;

// split entries into either worn/held gear or contained items
for( inventory_entry *entry : own_gear_column.get_entries( return_item, true ) ) {
item_location const loc = entry->locations.front();
if( entry->any_item().where() == item_location::type::container &&
!is_worn_ablative( loc.parent_item(), loc ) ) {
own_inv_column.add_entry( *entry );
} else {
replacement_column.add_entry( *entry );
}
const item_location loc = entry->any_item();
inventory_column *col = is_container( loc ) && !is_worn_ablative( loc.parent_item(), loc ) ?
&own_inv_column : &replacement_column;
col->add_entry( *entry );
}
own_gear_column.clear();
replacement_column.move_entries_to( own_gear_column );

for( inventory_column *col : columns ) {
_categorize( *col );
}
_uimode = uimode::categories;
} else {
// move all entries into one big gear column and turn into hierarchy
own_inv_column.move_entries_to( own_gear_column );
for( inventory_column *col : columns ) {
_uncategorize( *col );
}
_uimode = uimode::hierarchy;
}

if( !highlighted.empty() ) {
highlight_one_of( highlighted );
}

// needs to be called now so that new invlets can be assigned
// and subclasses w/ selection columns can then re-populate entries
// using the new invlets
prepare_layout();

// invalidate, but dont mark resize, to avoid re-calling prepare_layout()
// and as a consequence reassign_custom_invlets()
shared_ptr_fast<ui_adaptor> current_ui = ui.lock();
if( current_ui ) {
current_ui->mark_resize();
current_ui->invalidate_ui();
}
}

Expand Down Expand Up @@ -3001,6 +3019,20 @@ void inventory_multiselector::deselect_contained_items()
}
}

void inventory_multiselector::toggle_categorize_contained()
{
selection_col->clear();
inventory_selector::toggle_categorize_contained();

for( inventory_column *col : get_all_columns() ) {
for( inventory_entry *entry : col->get_entries( return_item, true ) ) {
if( entry->chosen_count > 0 ) {
toggle_entry( *entry, entry->chosen_count );
}
}
}
}

void inventory_multiselector::on_input( const inventory_input &input )
{
bool const noMarkCountBound = ctxt.keys_bound_to( "MARK_WITH_COUNT" ).empty();
Expand Down Expand Up @@ -3030,6 +3062,8 @@ void inventory_multiselector::on_input( const inventory_input &input )
? count < max ? count + 1 : max
: count > 1 ? count - 1 : 0;
toggle_entry( entry, newcount );
} else if( input.action == "VIEW_CATEGORY_MODE" ) {
toggle_categorize_contained();
} else {
inventory_selector::on_input( input );
}
Expand Down
5 changes: 5 additions & 0 deletions src/inventory_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ class inventory_entry
size_t generation = 0;
bool chevron = false;

void set_custom_category( const item_category *category ) {
custom_category = category;
}

private:
const item_category *custom_category = nullptr;
bool enabled = true;
Expand Down Expand Up @@ -897,6 +901,7 @@ class inventory_multiselector : public inventory_selector
void on_input( const inventory_input &input );
int count = 0;
stats get_raw_stats() const override;
void toggle_categorize_contained();
private:
std::unique_ptr<inventory_column> selection_col;
GetStats get_stats;
Expand Down

0 comments on commit 12d80fe

Please sign in to comment.