fix some bugs of listbox box selection
This commit is contained in:
parent
40cfe5f404
commit
8044cb0b34
@ -1517,22 +1517,20 @@ namespace nana
|
|||||||
|
|
||||||
if (to_dpl.is_category())
|
if (to_dpl.is_category())
|
||||||
{
|
{
|
||||||
auto size = this->size_item(to_dpl.cat);
|
//Search backward until a last item of a category is found.
|
||||||
if (0 == size)
|
while (true)
|
||||||
{
|
{
|
||||||
while (to_dpl.cat > 0)
|
auto msize = this->size_item(to_dpl.cat);
|
||||||
|
if (0 != msize)
|
||||||
{
|
{
|
||||||
size = this->size_item(--to_dpl.cat);
|
to_dpl.item = msize - 1;
|
||||||
if (size > 0)
|
|
||||||
{
|
|
||||||
to_dpl.item = size - 1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
if (fr_dpl.cat == to_dpl.cat)
|
||||||
else if (size > 0)
|
break;
|
||||||
{
|
|
||||||
to_dpl.item = size - 1;
|
--(to_dpl.cat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1546,7 +1544,7 @@ namespace nana
|
|||||||
//pair second: indicates whether the index is selected before selection.
|
//pair second: indicates whether the index is selected before selection.
|
||||||
std::vector<std::pair<index_pair, bool>> pairs;
|
std::vector<std::pair<index_pair, bool>> pairs;
|
||||||
|
|
||||||
for (; fr_dpl != to_dpl; fr_dpl = advance(fr_dpl, 1))
|
for (; !(fr_dpl > to_dpl); fr_dpl = advance(fr_dpl, 1)) //fr_dpl <= to_dpl
|
||||||
{
|
{
|
||||||
if (fr_dpl.is_category())
|
if (fr_dpl.is_category())
|
||||||
{
|
{
|
||||||
@ -1578,33 +1576,6 @@ namespace nana
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
item_proxy m(ess_, abs_pos);
|
|
||||||
pairs.emplace_back(abs_pos, m.selected());
|
|
||||||
|
|
||||||
if (pred(abs_pos))
|
|
||||||
m.select(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unselect_others)
|
if (unselect_others)
|
||||||
{
|
{
|
||||||
//Unselects the already selected which is out of range [begin, last]
|
//Unselects the already selected which is out of range [begin, last]
|
||||||
@ -1638,9 +1609,9 @@ namespace nana
|
|||||||
this->emit_cs(pos, true);
|
this->emit_cs(pos, true);
|
||||||
|
|
||||||
if (m.flags.selected)
|
if (m.flags.selected)
|
||||||
last_selected_abs = pos;
|
latest_selected_abs = pos;
|
||||||
else if (last_selected_abs == pos)
|
else if (latest_selected_abs == pos)
|
||||||
last_selected_abs.set_both(npos); //make empty
|
latest_selected_abs.set_both(npos); //make empty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++pos.item;
|
++pos.item;
|
||||||
@ -1879,8 +1850,13 @@ namespace nana
|
|||||||
else
|
else
|
||||||
i.item = npos;
|
i.item = npos;
|
||||||
}
|
}
|
||||||
else if (i.item)
|
else
|
||||||
|
{
|
||||||
|
if (i.item)
|
||||||
--i.item;
|
--i.item;
|
||||||
|
else
|
||||||
|
return index_pair{ npos, npos };
|
||||||
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -1888,9 +1864,14 @@ namespace nana
|
|||||||
/// can be used as the absolute position of the first absolute item, or as the display pos of the first displayed item
|
/// can be used as the absolute position of the first absolute item, or as the display pos of the first displayed item
|
||||||
index_pair first() const noexcept
|
index_pair first() const noexcept
|
||||||
{
|
{
|
||||||
index_pair fst{0,npos};
|
auto i = categories_.cbegin();
|
||||||
good_item(fst,fst);
|
if (i->items.size())
|
||||||
return fst;
|
return index_pair{ 0, 0 };
|
||||||
|
|
||||||
|
if (categories_.size() > 1)
|
||||||
|
return index_pair{ 1, npos };
|
||||||
|
|
||||||
|
return index_pair{ npos, npos };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool good(size_type cat) const noexcept
|
bool good(size_type cat) const noexcept
|
||||||
@ -1903,36 +1884,6 @@ namespace nana
|
|||||||
return ((pos.cat < categories_.size()) && (pos.item < size_item(pos.cat)));
|
return ((pos.cat < categories_.size()) && (pos.item < size_item(pos.cat)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// if good return the same item (in arg item), or just the next cat and true, but If fail return false
|
|
||||||
bool good_item(const index_pair& pos, index_pair& item) const noexcept
|
|
||||||
{
|
|
||||||
if (!good(pos.cat))
|
|
||||||
return false; // cat out of range
|
|
||||||
|
|
||||||
if (pos.is_category())
|
|
||||||
{
|
|
||||||
item = pos; // return the cat self
|
|
||||||
if (0 == pos.cat) // but for cat 0 return first item
|
|
||||||
item.item = 0; // let check this is good
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto i = get(pos.cat); // pos is not a cat and i point to it cat
|
|
||||||
if (pos.item < i->items.size())
|
|
||||||
{
|
|
||||||
item = pos; // good item, return it
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (++i == categories_.cend()) // item out of range and no more cat
|
|
||||||
return false;
|
|
||||||
|
|
||||||
item.cat = pos.cat + 1; // select the next cat
|
|
||||||
item.item = npos;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// categories iterator
|
/// categories iterator
|
||||||
container::iterator get(size_type pos)
|
container::iterator get(size_type pos)
|
||||||
{
|
{
|
||||||
@ -1952,7 +1903,7 @@ namespace nana
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
index_pair last_selected_abs;
|
index_pair latest_selected_abs; //Stands for the latest selected item that selected by last operation. Invalid if it is empty.
|
||||||
private:
|
private:
|
||||||
essence * ess_{nullptr};
|
essence * ess_{nullptr};
|
||||||
nana::listbox * widget_{nullptr};
|
nana::listbox * widget_{nullptr};
|
||||||
@ -2932,7 +2883,7 @@ namespace nana
|
|||||||
|
|
||||||
void es_lister::move_select(bool upwards, bool unselect_previous, bool /*trace_selected*/) noexcept
|
void es_lister::move_select(bool upwards, bool unselect_previous, bool /*trace_selected*/) noexcept
|
||||||
{
|
{
|
||||||
auto next_selected_dpl = index_cast_noexcpt(last_selected_abs, false); //convert absolute position to display position
|
auto next_selected_dpl = index_cast_noexcpt(latest_selected_abs, false); //convert absolute position to display position
|
||||||
|
|
||||||
if (next_selected_dpl.empty()) // has no cat ? (cat == npos) => beging from first cat
|
if (next_selected_dpl.empty()) // has no cat ? (cat == npos) => beging from first cat
|
||||||
{
|
{
|
||||||
@ -3053,8 +3004,8 @@ namespace nana
|
|||||||
for (item_proxy &it : cpx)
|
for (item_proxy &it : cpx)
|
||||||
it.select(value);
|
it.select(value);
|
||||||
|
|
||||||
last_selected_abs.cat = pos;
|
latest_selected_abs.cat = pos;
|
||||||
last_selected_abs.item = npos;
|
latest_selected_abs.item = npos;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -4124,18 +4075,18 @@ namespace nana
|
|||||||
if (arg.shift)
|
if (arg.shift)
|
||||||
{
|
{
|
||||||
//Set the first item as the begin of selected item if there
|
//Set the first item as the begin of selected item if there
|
||||||
//is not a last selected item.(#154 reported by RenaudAlpes)
|
//is not a latest selected item.(#154 reported by RenaudAlpes)
|
||||||
if (lister.last_selected_abs.empty() || lister.last_selected_abs.is_category())
|
if (lister.latest_selected_abs.empty() || lister.latest_selected_abs.is_category())
|
||||||
lister.last_selected_abs.set_both(0);
|
lister.latest_selected_abs.set_both(0);
|
||||||
|
|
||||||
auto before = lister.last_selected_abs;
|
auto before = lister.latest_selected_abs;
|
||||||
|
|
||||||
lister.select_display_range_if(lister.last_selected_abs, item_pos, true, [](const index_pair&)
|
lister.select_display_range_if(lister.latest_selected_abs, item_pos, true, [](const index_pair&)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
lister.last_selected_abs = before;
|
lister.latest_selected_abs = before;
|
||||||
}
|
}
|
||||||
else if (arg.ctrl)
|
else if (arg.ctrl)
|
||||||
{
|
{
|
||||||
@ -4176,10 +4127,10 @@ namespace nana
|
|||||||
if (item_ptr->flags.selected)
|
if (item_ptr->flags.selected)
|
||||||
{
|
{
|
||||||
lister.cancel_others_if_single_enabled(true, abs_item_pos);
|
lister.cancel_others_if_single_enabled(true, abs_item_pos);
|
||||||
essence_->lister.last_selected_abs = abs_item_pos;
|
essence_->lister.latest_selected_abs = abs_item_pos;
|
||||||
}
|
}
|
||||||
else if (essence_->lister.last_selected_abs == abs_item_pos)
|
else if (essence_->lister.latest_selected_abs == abs_item_pos)
|
||||||
essence_->lister.last_selected_abs.set_both(npos);
|
essence_->lister.latest_selected_abs.set_both(npos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -4350,17 +4301,18 @@ namespace nana
|
|||||||
|
|
||||||
void trigger::key_press(graph_reference graph, const arg_keyboard& arg)
|
void trigger::key_press(graph_reference graph, const arg_keyboard& arg)
|
||||||
{
|
{
|
||||||
bool up = false;
|
// Exit if list is empty
|
||||||
|
if (essence_->lister.first().empty())
|
||||||
|
return;
|
||||||
|
|
||||||
if (essence_->lister.cat_container().size() == 1 && essence_->lister.size_item(0)==0)
|
bool upward = false;
|
||||||
return ;
|
|
||||||
|
|
||||||
switch(arg.key)
|
switch(arg.key)
|
||||||
{
|
{
|
||||||
case keyboard::os_arrow_up:
|
case keyboard::os_arrow_up:
|
||||||
up = true;
|
upward = true;
|
||||||
case keyboard::os_arrow_down:
|
case keyboard::os_arrow_down:
|
||||||
essence_->lister.move_select(up, !arg.shift, true);
|
essence_->lister.move_select(upward, !arg.shift, true);
|
||||||
break;
|
break;
|
||||||
case L' ':
|
case L' ':
|
||||||
{
|
{
|
||||||
@ -4371,18 +4323,18 @@ namespace nana
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case keyboard::os_pageup :
|
case keyboard::os_pageup :
|
||||||
up = true;
|
upward = true;
|
||||||
case keyboard::os_pagedown:
|
case keyboard::os_pagedown:
|
||||||
{
|
{
|
||||||
//Turns page, then returns if no change occurs
|
//Turns page, then returns if no change occurs
|
||||||
if (!essence_->content_view->turn_page(!up, false))
|
if (!essence_->content_view->turn_page(!upward, false))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
essence_->lister.select_for_all(false);
|
essence_->lister.select_for_all(false);
|
||||||
|
|
||||||
auto idx = essence_->first_display();
|
auto idx = essence_->first_display();
|
||||||
|
|
||||||
if (!up)
|
if (!upward)
|
||||||
idx = essence_->lister.advance(idx, static_cast<int>(essence_->count_of_exposed(false)) - 1);
|
idx = essence_->lister.advance(idx, static_cast<int>(essence_->count_of_exposed(false)) - 1);
|
||||||
|
|
||||||
if (!idx.is_category())
|
if (!idx.is_category())
|
||||||
@ -4393,20 +4345,59 @@ namespace nana
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case keyboard::os_home:
|
case keyboard::os_home:
|
||||||
|
case keyboard::os_end:
|
||||||
{
|
{
|
||||||
essence_->lister.select_for_all(false);
|
essence_->lister.select_for_all(false);
|
||||||
|
|
||||||
index_pair frst{essence_->lister.first()};
|
auto pos = (keyboard::os_home == arg.key ? essence_->lister.first() : essence_->lister.last());
|
||||||
if (! frst.is_category())
|
if (!pos.empty())
|
||||||
item_proxy::from_display(essence_, frst).select(true);
|
{
|
||||||
else if (!essence_->lister.single_status(true)) //not selected
|
//When the pos indicates an empty category, then search forwards/backwards(depending on arg.key whether it is Home or End) for a non empty category.
|
||||||
essence_->lister.cat_status(frst.cat, true, true);
|
//When a non-empty category is found, assign the pos to the first/last item of the category if the category is expanded.
|
||||||
|
if (pos.is_category())
|
||||||
|
{
|
||||||
|
if (keyboard::os_home == arg.key)
|
||||||
|
{
|
||||||
|
while (0 == essence_->lister.size_item(pos.cat))
|
||||||
|
{
|
||||||
|
if (++pos.cat >= essence_->lister.cat_container().size())
|
||||||
|
{
|
||||||
|
pos = index_pair{ npos, npos };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case keyboard::os_end:
|
}
|
||||||
essence_->lister.select_for_all(false);
|
}
|
||||||
item_proxy::from_display(essence_, essence_->lister.last()).select(true);
|
else
|
||||||
|
{
|
||||||
|
while (0 == essence_->lister.size_item(pos.cat))
|
||||||
|
{
|
||||||
|
if (pos.cat-- == 0)
|
||||||
|
{
|
||||||
|
pos = index_pair{ npos, npos };
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pos.empty())
|
||||||
|
{
|
||||||
|
if (essence_->lister.expand(pos.cat))
|
||||||
|
pos.item = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pos.empty())
|
||||||
|
{
|
||||||
|
if (pos.is_category())
|
||||||
|
{
|
||||||
|
if (!essence_->lister.single_status(true)) //multiple selection is not enabled
|
||||||
|
essence_->lister.cat_status(pos.cat, true, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
item_proxy::from_display(essence_, pos).select(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
@ -4531,10 +4522,10 @@ namespace nana
|
|||||||
if (m.flags.selected)
|
if (m.flags.selected)
|
||||||
{
|
{
|
||||||
ess_->lister.cancel_others_if_single_enabled(true, pos_); //Cancel all selections except pos_ if single_selection is enabled.
|
ess_->lister.cancel_others_if_single_enabled(true, pos_); //Cancel all selections except pos_ if single_selection is enabled.
|
||||||
ess_->lister.last_selected_abs = pos_;
|
ess_->lister.latest_selected_abs = pos_;
|
||||||
}
|
}
|
||||||
else if (ess_->lister.last_selected_abs == pos_)
|
else if (ess_->lister.latest_selected_abs == pos_)
|
||||||
ess_->lister.last_selected_abs.set_both(npos);
|
ess_->lister.latest_selected_abs.set_both(npos);
|
||||||
|
|
||||||
if (scroll_view)
|
if (scroll_view)
|
||||||
{
|
{
|
||||||
@ -4808,7 +4799,7 @@ namespace nana
|
|||||||
for (item_proxy &it : *this )
|
for (item_proxy &it : *this )
|
||||||
it.select(sel);
|
it.select(sel);
|
||||||
|
|
||||||
ess_->lister.last_selected_abs = index_pair {this->pos_, npos};
|
ess_->lister.latest_selected_abs = index_pair {this->pos_, npos};
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -5432,7 +5423,6 @@ namespace nana
|
|||||||
{
|
{
|
||||||
auto & ess = _m_ess();
|
auto & ess = _m_ess();
|
||||||
ess.lister.erase();
|
ess.lister.erase();
|
||||||
//ess.first_display(ess.lister.first());
|
|
||||||
ess.calc_content_size();
|
ess.calc_content_size();
|
||||||
ess.update();
|
ess.update();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user