fix 2 listbox issues

inline widget modifies a wrong item when the listbox is sorted
a crash issue when erasing the last item if the listbox is sorted
This commit is contained in:
Jinhao 2015-09-30 17:09:55 +08:00
parent 6ca50a7cb4
commit 7cb27951e0

View File

@ -438,14 +438,6 @@ namespace nana
return pixels; return pixels;
} }
/*
/// return the original order or index previous to any list reorganization of the current column "n".
size_type index(size_type n) const //deprecated
{
return (n < cont_.size() ? cont_[n].index : npos);
}
*/
const container& cont() const const container& cont() const
{ {
return cont_; return cont_;
@ -565,19 +557,6 @@ namespace nana
return; return;
} }
} }
/*
auto i = std::find_if(cont_.begin(), cont_.end(), [index](container::value_type& m){return (index == m.index);}); //deprecated
if (i == cont_.end())
return;
column_t from = std::move(*i); //move
cont_.erase(i);
i = std::find_if(cont_.begin(), cont_.end(), [to](const container::value_type& m)->bool{ return (to == m.index); } );
if(i != cont_.end())
cont_.insert((front ? i : ++i), from);
*/
} }
private: private:
bool visible_{true}; bool visible_{true};
@ -961,6 +940,11 @@ namespace nana
return *(_m_at(cat_pos)); return *(_m_at(cat_pos));
} }
category_t::container::value_type& at_abs(const index_pair& pos)
{
return _m_at(pos.cat)->items.at(pos.item);
}
/// return a ref to the real item object at display!!! position pos using current sorting only if it is active, and at absolute position if no sorting is currently active. /// return a ref to the real item object at display!!! position pos using current sorting only if it is active, and at absolute position if no sorting is currently active.
category_t::container::value_type& at(const index_pair& pos) category_t::container::value_type& at(const index_pair& pos)
{ {
@ -1142,16 +1126,7 @@ namespace nana
} }
} }
void erase(const index_pair& pos) void erase(const index_pair& pos);
{
auto & catobj = *_m_at(pos.cat);
if(pos.item < catobj.items.size())
{
catobj.items.erase(catobj.items.begin() + pos.item);
catobj.sorted.erase(std::find(catobj.sorted.begin(), catobj.sorted.end(), catobj.items.size()));
sort();
}
}
void erase(size_type cat) void erase(size_type cat)
{ {
@ -1709,14 +1684,16 @@ namespace nana
auto & catobj = *_m_at(display_pos.cat); auto & catobj = *_m_at(display_pos.cat);
if(catobj.items.size()==0) if(catobj.items.empty())
return (display_pos == index_pair{0,0} ? 0 : npos); return (display_pos == index_pair{0,0} ? 0 : npos);
return catobj.sorted[display_pos.item] ; return (display_pos.item < catobj.sorted.size() ? catobj.sorted[display_pos.item] : npos);
} }
index_pair absolute_pair(const index_pair& display_pos) const index_pair absolute_pair(const index_pair& display_pos) const
{ {
return {display_pos.cat, absolute( display_pos )}; //Returns an empty pos if item pos npos
auto item_pos = absolute(display_pos);
return {item_pos != npos ? display_pos.cat : npos, item_pos};
} }
///Translate absolute position (original data order) into relative position (position in display) ///Translate absolute position (original data order) into relative position (position in display)
@ -1731,15 +1708,16 @@ namespace nana
if (pos.item == catobj.sorted[i]) if (pos.item == catobj.sorted[i])
return i; return i;
if (pos == index_pair{0,0} ) if (catobj.items.empty() && (pos == index_pair{ 0, 0 }))
if(catobj.items.size()==0)
return 0; return 0;
return npos; return npos;
} }
index_pair relative_pair(const index_pair& pos) const index_pair relative_pair(const index_pair& pos) const
{ {
return {pos.cat, relative( pos )}; //Returns an empty pos if item is npos
auto item_pos = relative(pos);
return {(item_pos != npos ? pos.cat : npos), item_pos};
} }
/// all arg are relative to display order, or all are absolute, but not mixed /// all arg are relative to display order, or all are absolute, but not mixed
@ -1971,16 +1949,14 @@ namespace nana
{ {
scroll_y_abs(lister.relative_pair(pos_rel) ); scroll_y_abs(lister.relative_pair(pos_rel) );
} }
void set_scroll_y_abs(const index_pair& pos_abs)
{
scroll.offset_y_abs=pos_abs;
scroll_y_dpl_refresh() ;
}
/// directly set a tested relative display pos /// directly set a tested relative display pos
void set_scroll_y_dpl(const index_pair& pos_dpl) void set_scroll_y_dpl(const index_pair& pos_dpl)
{ {
scroll.offset_y_dpl = pos_dpl; scroll.offset_y_dpl = pos_dpl;
scroll.offset_y_abs = lister.absolute_pair(pos_dpl); scroll.offset_y_abs = lister.absolute_pair(pos_dpl);
if (scroll.offset_y_abs.empty())
throw std::invalid_argument("nana.listbox.set_scroll_y_dpl's exception is due to invalid item, please report a bug");
} }
@ -2038,15 +2014,6 @@ namespace nana
trace_item_abs(lister.last_selected_abs); trace_item_abs(lister.last_selected_abs);
} }
/*
void trace_first_selected_item() //deprecated
{
auto fs=lister.find_first_selected();
if( ! fs.empty() )
trace_item_abs( fs );
}
*/
void update() void update()
{ {
if(auto_draw && lister.wd_ptr()) if(auto_draw && lister.wd_ptr())
@ -2374,6 +2341,7 @@ namespace nana
auto ptr = pane_ptr.get(); auto ptr = pane_ptr.get();
inline_table[factory].emplace_back(std::move(pane_ptr)); inline_table[factory].emplace_back(std::move(pane_ptr));
ptr->inline_ptr->whether_to_draw();
return ptr; return ptr;
} }
}; };
@ -2396,13 +2364,16 @@ namespace nana
void modify(index_type pos, const value_type& value) const override void modify(index_type pos, const value_type& value) const override
{ {
auto & cells = ess_->lister.at(pos).cells; auto & cells = ess_->lister.at_abs(pos).cells;
if (cells.size() <= column_pos_) if (cells.size() <= column_pos_)
cells.resize(column_pos_ + 1); cells.resize(column_pos_ + 1);
if (cells[column_pos_].text != value)
{
cells[column_pos_].text = value; cells[column_pos_].text = value;
ess_->update(); ess_->update();
} }
}
void selected(index_type pos) override void selected(index_type pos) override
{ {
@ -2428,6 +2399,18 @@ namespace nana
const std::size_t column_pos_; const std::size_t column_pos_;
}; };
void es_lister::erase(const index_pair& pos)
{
auto & catobj = *_m_at(pos.cat);
if (pos.item < catobj.items.size())
{
catobj.items.erase(catobj.items.begin() + pos.item);
catobj.sorted.erase(std::find(catobj.sorted.begin(), catobj.sorted.end(), catobj.items.size()));
sort();
}
}
void es_lister::scroll_refresh() void es_lister::scroll_refresh()
{ {
ess_->scroll_y_dpl_refresh(); ess_->scroll_y_dpl_refresh();
@ -2639,8 +2622,6 @@ namespace nana
void draw(const nana::rectangle& r) void draw(const nana::rectangle& r)
{ {
//_m_draw(essence_->header.cont(), r); //deprecated
graph_reference graph = *(essence_->graph); graph_reference graph = *(essence_->graph);
int text_top = (r.height - essence_->text_height) / 2 + r.y; int text_top = (r.height - essence_->text_height) / 2 + r.y;
@ -2716,44 +2697,6 @@ namespace nana
} }
return npos; return npos;
} }
/*
template<typename Container>
void _m_draw(const Container& cont, const nana::rectangle& rect) //deprecated
{
graph_reference graph = *(essence_->graph);
int txtop = (rect.height - essence_->text_height) / 2 + rect.y;
auto txtcolor = essence_->lister.wd_ptr()->fgcolor();
auto state = item_state::normal;
//check whether grabing an item, if item_spliter_ != npos, that indicates the grab item is a spliter.
if(essence_->pointer_where.first == parts::header && (item_spliter_ == npos))
state = essence_->ptr_state;
const unsigned height = rect.height - 1;
const int bottom_y = rect.bottom() - 2;
int x = rect.x - essence_->scroll.offset_x;
for(auto & i: cont)
{
if(i.visible)
{
int next_x = x + static_cast<int>(i.pixels);
if(next_x > rect.x)
{
_m_draw_header_item(graph, x, rect.y, height, txtop, txtcolor, i, (i.index == essence_->pointer_where.second ? state : item_state::normal));
graph.line({ next_x - 1, rect.y }, { next_x - 1, bottom_y }, _m_border_color());
}
x = next_x;
if (x > rect.right())
break;
}
}
if (x < rect.right())
graph.rectangle({ x, rect.y, static_cast<unsigned>(rect.right() - x), height }, true, essence_->scheme_ptr->header_bgcolor);
}
*/
template<typename Item> template<typename Item>
void _m_draw_header_item(graph_reference graph, int x, int y, unsigned height, int txtop, const ::nana::color& fgcolor, const Item& item, item_state state) void _m_draw_header_item(graph_reference graph, int x, int y, unsigned height, int txtop, const ::nana::color& fgcolor, const Item& item, item_state state)
@ -3226,13 +3169,6 @@ namespace nana
delete essence_; delete essence_;
} }
/*
essence_t& trigger::essence() //deprecated
{
return *essence_;
}
*/
essence_t& trigger::essence() const essence_t& trigger::essence() const
{ {
return *essence_; return *essence_;
@ -4411,8 +4347,12 @@ namespace nana
auto * ess = ip._m_ess(); auto * ess = ip._m_ess();
auto _where = ip.pos(); auto _where = ip.pos();
auto pos_before = ess->scroll_y_dpl();
ess->lister.erase(_where); ess->lister.erase(_where);
auto pos = ess->scroll_y_dpl(); auto pos = ess->scroll_y_dpl();
if (!pos.empty())
{
if ((pos.cat == _where.cat) && (_where.item <= pos.item)) if ((pos.cat == _where.cat) && (_where.item <= pos.item))
{ {
if (pos.item == 0) if (pos.item == 0)
@ -4424,6 +4364,13 @@ namespace nana
--pos.item; --pos.item;
ess->set_scroll_y_dpl(pos); ess->set_scroll_y_dpl(pos);
} }
}
else
{
if (pos_before.item)
--pos_before.item;
ess->set_scroll_y_dpl(pos_before);
}
ess->update(); ess->update();
if(_where.item < ess->lister.size_item(_where.cat)) if(_where.item < ess->lister.size_item(_where.cat))
return ip; return ip;