add a param to listbox::item_proxy's check/select

this new parameter is used to indicate whether to scroll the view to the
item if the item is not displayed on screen.
This commit is contained in:
Jinhao
2016-10-03 09:07:37 +08:00
parent fb27eece33
commit 7f45ae4342
2 changed files with 70 additions and 15 deletions

View File

@@ -800,12 +800,31 @@ namespace nana
/// posible use: last_selected_display = last_selected.to_display().item; use with caution, it get invalidated after a sort()
index_pair to_display() const;
/// Determines whether the item is displayed on the screen
bool displayed() const;
bool empty() const;
item_proxy & check(bool ck);
/// Checks/unchecks the item
/**
* @param chk Indicates whether to check or uncheck the item
* @param scroll_view Indicates whether to scroll the view to the item. It is ignored if the item is displayed.
* @return the reference of *this.
*/
item_proxy & check(bool chk, bool scroll_view = false);
/// Determines whether the item is checked
bool checked() const;
item_proxy & select(bool);
/// Selects/unselects the item
/**
* @param sel Indicates whether to select or unselect the item
* @param scroll_view Indicates whether to scroll the view to the item. It is ignored if the item is displayed.
* @return the reference of *this.
*/
item_proxy & select(bool sel, bool scroll_view = false);
/// Determines whether he item is selected
bool selected() const;
item_proxy & bgcolor(const nana::color&);

View File

@@ -4506,12 +4506,28 @@ namespace nana
return ess_->lister.relative_pair(pos_);
}
bool item_proxy::displayed() const
{
if (!ess_->lister.get(pos_.cat)->expand)
return false;
auto pos = to_display();
if (ess_->scroll.offset_y_dpl > pos)
return false;
auto size = ess_->number_of_lister_items(false);
auto last = ess_->lister.advance(ess_->scroll.offset_y_dpl, size);
return (last > pos || last == pos);
}
bool item_proxy::empty() const
{
return !ess_;
}
item_proxy & item_proxy::check(bool ck)
item_proxy & item_proxy::check(bool ck, bool scroll_view)
{
internal_scope_guard lock;
auto & m = cat_->items.at(pos_.item);
@@ -4520,6 +4536,15 @@ namespace nana
m.flags.checked = ck;
ess_->lister.emit_checked(pos_);
if (scroll_view)
{
if (ess_->lister.get(pos_.cat)->expand)
ess_->lister.get(pos_.cat)->expand = false;
if (!this->displayed())
ess_->lister.scroll(pos_, !(ess_->scroll.offset_y_dpl > this->to_display()));
}
ess_->update();
}
return *this;
@@ -4531,14 +4556,15 @@ namespace nana
}
/// is ignored if no change (maybe set last_selected anyway??), but if change emit event, deselect others if need ans set/unset last_selected
item_proxy & item_proxy::select(bool s)
item_proxy & item_proxy::select(bool sel, bool scroll_view)
{
internal_scope_guard lock;
//pos_ never represents a category if this item_proxy is available.
auto & m = cat_->items.at(pos_.item); // a ref to the real item
if(m.flags.selected == s) return *this; // ignore if no change
m.flags.selected = s; // actually change selection
if (m.flags.selected != sel)
{
m.flags.selected = sel; // actually change selection
ess_->lister.emit_selected(this->pos_);
@@ -4550,7 +4576,17 @@ namespace nana
else if (ess_->lister.last_selected_abs == pos_)
ess_->lister.last_selected_abs.set_both(npos);
if (scroll_view)
{
if (ess_->lister.get(pos_.cat)->expand)
ess_->lister.get(pos_.cat)->expand = false;
if (!this->displayed())
ess_->lister.scroll(pos_, !(ess_->scroll.offset_y_dpl > this->to_display()));
}
ess_->update();
}
return *this;
}