fix bug that listbox would crash when selects category by box selection
This commit is contained in:
parent
93514186d5
commit
40cfe5f404
@ -1507,14 +1507,38 @@ namespace nana
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Pred>
|
template<typename Pred>
|
||||||
std::vector<std::pair<index_pair, bool>> select_display_range_if(index_pair fr_abs, index_pair to_dpl, bool unselect_others, Pred pred)
|
std::vector<std::pair<index_pair, bool>> select_display_range_if(const index_pair& fr_abs, index_pair to_dpl, bool unselect_others, Pred pred)
|
||||||
{
|
{
|
||||||
const auto already_selected = this->pick_items(true);
|
const auto already_selected = this->pick_items(true);
|
||||||
|
|
||||||
auto fr_dpl = this->index_cast(fr_abs, false); //Converts an absolute position to display position
|
auto fr_dpl = (fr_abs.is_category() ? fr_abs : this->index_cast(fr_abs, false)); //Converts an absolute position to display position
|
||||||
if (fr_dpl > to_dpl)
|
if (fr_dpl > to_dpl)
|
||||||
std::swap(fr_dpl, to_dpl);
|
std::swap(fr_dpl, to_dpl);
|
||||||
|
|
||||||
|
if (to_dpl.is_category())
|
||||||
|
{
|
||||||
|
auto size = this->size_item(to_dpl.cat);
|
||||||
|
if (0 == size)
|
||||||
|
{
|
||||||
|
while (to_dpl.cat > 0)
|
||||||
|
{
|
||||||
|
size = this->size_item(--to_dpl.cat);
|
||||||
|
if (size > 0)
|
||||||
|
{
|
||||||
|
to_dpl.item = size - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (size > 0)
|
||||||
|
{
|
||||||
|
to_dpl.item = size - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->good(to_dpl))
|
||||||
|
to_dpl = this->last();
|
||||||
|
|
||||||
const auto begin = fr_dpl;
|
const auto begin = fr_dpl;
|
||||||
const auto last = to_dpl;
|
const auto last = to_dpl;
|
||||||
|
|
||||||
@ -1524,7 +1548,26 @@ namespace nana
|
|||||||
|
|
||||||
for (; fr_dpl != to_dpl; fr_dpl = advance(fr_dpl, 1))
|
for (; fr_dpl != to_dpl; fr_dpl = advance(fr_dpl, 1))
|
||||||
{
|
{
|
||||||
if (!fr_dpl.is_category())
|
if (fr_dpl.is_category())
|
||||||
|
{
|
||||||
|
if (!expand(fr_dpl.cat))
|
||||||
|
{
|
||||||
|
auto size = size_item(fr_dpl.cat);
|
||||||
|
for (std::size_t i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
index_pair abs_pos{ fr_dpl.cat, i };
|
||||||
|
item_proxy m{ ess_, abs_pos };
|
||||||
|
pairs.emplace_back(abs_pos, m.selected());
|
||||||
|
|
||||||
|
if (pred(abs_pos))
|
||||||
|
m.select(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fr_dpl.cat == to_dpl.cat)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
auto abs_pos = index_cast(fr_dpl, true); //convert display position to absolute position
|
auto abs_pos = index_cast(fr_dpl, true); //convert display position to absolute position
|
||||||
item_proxy m{ ess_, abs_pos };
|
item_proxy m{ ess_, abs_pos };
|
||||||
@ -1535,7 +1578,23 @@ namespace nana
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!to_dpl.is_category())
|
if (to_dpl.is_category())
|
||||||
|
{
|
||||||
|
if (!expand(to_dpl.cat))
|
||||||
|
{
|
||||||
|
auto size = size_item(to_dpl.cat);
|
||||||
|
for (std::size_t i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
index_pair abs_pos{ fr_dpl.cat, i };
|
||||||
|
item_proxy m{ ess_, abs_pos };
|
||||||
|
pairs.emplace_back(abs_pos, m.selected());
|
||||||
|
|
||||||
|
if (pred(abs_pos))
|
||||||
|
m.select(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
auto abs_pos = index_cast(to_dpl, true); //convert display position to absolute position
|
auto abs_pos = index_cast(to_dpl, true); //convert display position to absolute position
|
||||||
|
|
||||||
@ -2088,18 +2147,21 @@ namespace nana
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto begin_off = (std::max)((std::min)(mouse_selection.begin_position.y, mouse_selection.end_position.y), 0) / item_height();
|
auto const begin_off = (std::max)((std::min)(mouse_selection.begin_position.y, mouse_selection.end_position.y), 0) / item_height();
|
||||||
auto last_off = (std::max)(mouse_selection.begin_position.y, mouse_selection.end_position.y) / item_height();
|
|
||||||
|
|
||||||
auto begin = lister.advance(lister.first(), begin_off);
|
auto begin = lister.advance(lister.first(), begin_off);
|
||||||
|
if (begin.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<std::pair<index_pair, bool>> selections;
|
||||||
|
|
||||||
|
if ((mouse_selection.end_position.y < 0) || (lister.distance(lister.first(), begin) == begin_off))
|
||||||
|
{
|
||||||
|
//The range [begin_off, last_off] is a range of box selection
|
||||||
|
auto last_off = (std::max)(mouse_selection.begin_position.y, mouse_selection.end_position.y) / item_height();
|
||||||
auto last = lister.advance(lister.first(), last_off);
|
auto last = lister.advance(lister.first(), last_off);
|
||||||
|
|
||||||
if (!lister.good(last))
|
selections = lister.select_display_range_if(begin, last, false, [this](const index_pair& abs_pos) {
|
||||||
last = lister.last();
|
|
||||||
|
|
||||||
if (lister.good(begin) && ((mouse_selection.end_position.y < 0) || (lister.distance(lister.first(), begin) == begin_off)))
|
|
||||||
{
|
|
||||||
auto selections = lister.select_display_range_if(begin, last, false, [this](const index_pair& abs_pos) {
|
|
||||||
if (this->mouse_selection.reverse_selection)
|
if (this->mouse_selection.reverse_selection)
|
||||||
{
|
{
|
||||||
if(mouse_selection.already_selected.cend() != std::find(mouse_selection.already_selected.cbegin(), mouse_selection.already_selected.cend(), abs_pos))
|
if(mouse_selection.already_selected.cend() != std::find(mouse_selection.already_selected.cbegin(), mouse_selection.already_selected.cend(), abs_pos))
|
||||||
@ -2139,16 +2201,6 @@ namespace nana
|
|||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mouse_selection.reverse_selection)
|
|
||||||
{
|
|
||||||
for (auto & abs_pos : mouse_selection.already_selected)
|
|
||||||
{
|
|
||||||
if (selections.cend() == std::find_if(selections.cbegin(), selections.cend(), pred_mouse_selection{abs_pos}))
|
|
||||||
{
|
|
||||||
item_proxy{ this, abs_pos }.select(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2158,10 +2210,13 @@ namespace nana
|
|||||||
}
|
}
|
||||||
|
|
||||||
mouse_selection.selections.clear();
|
mouse_selection.selections.clear();
|
||||||
|
}
|
||||||
|
|
||||||
if (mouse_selection.reverse_selection)
|
if (mouse_selection.reverse_selection)
|
||||||
{
|
{
|
||||||
for (auto & abs_pos : mouse_selection.already_selected)
|
for (auto & abs_pos : mouse_selection.already_selected)
|
||||||
|
{
|
||||||
|
if (selections.empty() || (selections.cend() == std::find_if(selections.cbegin(), selections.cend(), pred_mouse_selection{ abs_pos })))
|
||||||
{
|
{
|
||||||
item_proxy{ this, abs_pos }.select(true);
|
item_proxy{ this, abs_pos }.select(true);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user