Select the correct item in a filtered and sorted generator (#4585)
In the load-game dialog, this makes deleting a file select the next visible game save, thus it fixes #4125. Credit and many thanks to DisherProject for the inspiration and hard work of debugging where to fix this.
This commit is contained in:
parent
e50fd80d53
commit
63ebe48d64
2 changed files with 37 additions and 30 deletions
|
@ -35,13 +35,30 @@ void one_item::set_item_shown(const unsigned index, const bool show)
|
|||
do_select_item(index);
|
||||
} else if(!show && is_selected(index)) {
|
||||
do_deselect_item(index);
|
||||
|
||||
for(unsigned i = 1; i < get_item_count(); ++i) {
|
||||
unsigned new_index = (index + i) % get_item_count();
|
||||
if(get_item_shown(new_index)) {
|
||||
do_select_item(new_index);
|
||||
break;
|
||||
if(get_selected_item_count() == 0) {
|
||||
bool found_new_item = false;
|
||||
const unsigned item_count = get_item_count();
|
||||
const unsigned ordered_index = get_ordered_index(index);
|
||||
// find the next shown item
|
||||
for(unsigned i = ordered_index + 1; i < item_count; ++i) {
|
||||
unsigned new_index = get_item_at_ordered(i);
|
||||
if(get_item_shown(new_index)) {
|
||||
do_select_item(new_index);
|
||||
found_new_item = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// fall back to finding the previous shown item
|
||||
if(!found_new_item) {
|
||||
for(signed i = static_cast<signed>(ordered_index) - 1; i >= 0; --i) {
|
||||
unsigned new_index = get_item_at_ordered(static_cast<unsigned>(i));
|
||||
if(get_item_shown(new_index)) {
|
||||
do_select_item(new_index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if neither search found a new item, accept that there are zero items selected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,28 +82,8 @@ bool one_item::deselect_item(const unsigned index)
|
|||
|
||||
void one_item::delete_item(const unsigned index)
|
||||
{
|
||||
/** @todo do_select_item needs to test for shown flag. */
|
||||
|
||||
if(is_selected(index)) {
|
||||
do_deselect_item(index);
|
||||
|
||||
if(get_selected_item_count() == 0) {
|
||||
// Are there items left?
|
||||
const unsigned item_count = get_item_count();
|
||||
const unsigned visible_index = get_ordered_index(index);
|
||||
|
||||
if(item_count > 1) {
|
||||
// Is the last item deselected?
|
||||
if(visible_index == item_count - 1) {
|
||||
// Select the second last.
|
||||
do_select_item(get_item_at_ordered(visible_index - 1));
|
||||
} else {
|
||||
// Select the next item.
|
||||
do_select_item(get_item_at_ordered(visible_index + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// this needs the same logic for ensuring that at least one item is selected
|
||||
set_item_shown(index, false);
|
||||
}
|
||||
|
||||
void no_item::set_item_shown(const unsigned index, const bool show)
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
/**
|
||||
* Create a new generator.
|
||||
*
|
||||
* @param has_minimum Does one item need to be selected.
|
||||
* @param has_minimum Does one item need to be selected?
|
||||
* @param has_maximum Is one the maximum number of items that can
|
||||
* be selected?
|
||||
* @param placement The placement of the grids, see tplacement
|
||||
|
@ -105,7 +105,9 @@ public:
|
|||
/**
|
||||
* Shows or hides an item.
|
||||
*
|
||||
* The caller is responsible for reformatting the grid.
|
||||
* The caller is responsible for reformatting the grid. If a selected item
|
||||
* is hidden then it will be automatically deselected; if no items are
|
||||
* shown then no items will be selected, even if has_minimum was requested.
|
||||
*
|
||||
* @param index The item to show or hide.
|
||||
* @param show If true shows the item, else hides it.
|
||||
|
@ -372,8 +374,16 @@ protected:
|
|||
virtual const grid& item_ordered(const unsigned index) const = 0;
|
||||
|
||||
public:
|
||||
/**
|
||||
* If a sort-order is being applied, maps from unsorted to sorted indicies.
|
||||
* This does not take account of whether each object is shown or not.
|
||||
*/
|
||||
virtual unsigned get_ordered_index(unsigned index) const = 0;
|
||||
|
||||
/**
|
||||
* If a sort-order is being applied, maps from sorted to unsorted indicies.
|
||||
* This does not take account of whether each object is shown or not.
|
||||
*/
|
||||
virtual unsigned get_item_at_ordered(unsigned index_ordered) const = 0;
|
||||
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue