From 19339c52399aabcf749265146b9dcc1ca8eba7ce Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 13 Mar 2015 14:39:57 +0800 Subject: [PATCH 01/13] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 3546c151..c9676580 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ Nana is licensed under the [Boost Software License]. The best way to get help with Nana library is by visiting http://nanapro.org/help.htm +## Sending a Pull Request ? + +This project is encourage you to contribute it through sending a pull request! There is a simple rule, please don't directly commit your contributions to the master branch. According to your commits, please choose the hotfixes branch or the develop branch. Thank you! + ## Introduction to the Repository There are two main branches with an infinite lifetime: From 02facbd4cc8618f4a99d42e82c58b2892502d59f Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 13 Mar 2015 14:41:45 +0800 Subject: [PATCH 02/13] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c9676580..8b85b0c2 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The best way to get help with Nana library is by visiting http://nanapro.org/hel ## Sending a Pull Request ? -This project is encourage you to contribute it through sending a pull request! There is a simple rule, please don't directly commit your contributions to the master branch. According to your commits, please choose the hotfixes branch or the develop branch. Thank you! +This project is encourage you to contribute it through sending a pull request! There is a simple rule, please **don't** directly commit your contributions to the **master** branch. According to your commits, please choose the **hotfixes** branch or the **develop** branch. Thank you! ## Introduction to the Repository From 52d040a95d2a5136f1a79d7aa25f3fc5a2637bda Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 5 May 2015 13:50:30 +0200 Subject: [PATCH 03/13] FIX: trace the whole cat when selected, not just the last item --- source/gui/widgets/listbox.cpp | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 53ee6eff..a44d7d47 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1595,26 +1595,21 @@ namespace nana bool categ_selected(size_type cat, bool sel) { bool changed = false; - auto & items = _m_at(cat)->items; - index_pair pos(cat, 0); - for(auto & m : items) + cat_proxy cpx{ess_,cat}; + for (item_proxy &it : cpx ) { - if(m.flags.selected != sel) - { - m.flags.selected = sel; - - arg_listbox arg{ item_proxy(ess_, pos), sel }; - wd_ptr()->events().selected.emit(arg); + if (it.selected() != sel) changed = true; + it.select(sel); if (sel) // not check for single_selection_ - last_selected_abs = pos; - else if (last_selected_abs == pos) + last_selected_abs = it->pos(); + + else if (last_selected_abs == it->pos()) last_selected_abs.set_both(npos); } - ++pos.item; - } + last_selected_abs = index_pair{cat,npos}; return changed; } From 31639cb34d88609c562ce1f0ce116873465b2b72 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 5 May 2015 13:53:27 +0200 Subject: [PATCH 04/13] to find the first item or cat --- source/gui/widgets/listbox.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index a44d7d47..2de8d4c2 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1639,7 +1639,20 @@ namespace nana /// absolute position of the last displayed item index_pair last_displ() const { - return absolute ( last_displ() ); + return absolute ( last() ); + } + + /// 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 + { + index_pair fst{0,npos}; + good_item(fst,fst); + return fst; + } + /// absolute position of the first displayed item + index_pair first_displ() const + { + return absolute ( first() ); } bool good(size_type cat) const From 65ebdccd907d81e84a92b87b59052ab04e4f4132 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 5 May 2015 13:54:37 +0200 Subject: [PATCH 05/13] FIX: let check this 0,0 is good --- source/gui/widgets/listbox.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 2de8d4c2..de1a04ce 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1664,32 +1664,32 @@ namespace nana { return ((pos.cat < list_.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(index_pair pos, index_pair& item) const { if (!good(pos.cat)) - return false; + return false; // cat out of range if (pos.is_category()) { - item = pos; - if (0 == pos.cat) - item.item = 0; - + 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 = _m_at(pos.cat); + auto i = _m_at(pos.cat); // pos is not a cat and i point to it cat if (pos.item < i->items.size()) { - item = pos; + item = pos; // good item, return it return true; } - if (++i == list_.end()) + if (++i == list_.end()) // item out of range and no more cat return false; - item.cat = pos.cat + 1; + item.cat = pos.cat + 1; // select the next cat item.item = npos; return true; } From bcb2d5b6fc002d326e56a7269dd5b5b5d0b451bc Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 5 May 2015 13:55:57 +0200 Subject: [PATCH 06/13] FIX: crash if finding pos of cat --- source/gui/widgets/listbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index de1a04ce..6fc0bdd9 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1697,7 +1697,7 @@ namespace nana ///Translate relative position (position in display) into absolute position (original data order) size_type absolute(const index_pair& display_pos) const { - if(sorted_index_ == npos) + if(sorted_index_ == npos || display_pos.item == npos) return display_pos.item ; auto & catobj = *_m_at(display_pos.cat); From d4d1a79af89fbf4a3cbd390ff3cd3ee52a8b5d90 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 5 May 2015 13:57:44 +0200 Subject: [PATCH 07/13] FIX: a +1 error during navigation of listbox with categories --- include/nana/gui/widgets/listbox.hpp | 1 + source/gui/widgets/listbox.cpp | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 8a2f1938..fc487460 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -366,6 +366,7 @@ namespace nana return iter; } + /// Append an item at abs end of the category, using the strins to set the columns (cells) of the new item. void append(std::initializer_list); size_type columns() const; diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 6fc0bdd9..8618d4c0 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1747,13 +1747,12 @@ namespace nana return true; } - if(list_.size() <= from.cat) return false; - if(from.is_category()) { // this is a category, so... // and offs is not 0, this category would not be candidated. // the algorithm above to calc the offset item is always starting with a item. + // we can not select, navigate or highlight begining from a cat? --offs; from.item = 0; } @@ -1762,7 +1761,7 @@ namespace nana if(icat->expand) { - std::size_t item_left_in_this_cat = icat->items.size() -1- from.item; + std::size_t item_left_in_this_cat = icat->items.size()- from.item -1; if(offs <= item_left_in_this_cat ) { item = from; @@ -1771,14 +1770,15 @@ namespace nana } else { - offs -= item_left_in_this_cat ; + offs -= (item_left_in_this_cat+1) ; item = from; - item.item += item_left_in_this_cat ; + item.item += item_left_in_this_cat ;// select the last item } } ++from.cat; ++icat; + for(; icat != list_.end(); ++icat, ++from.cat) { item.cat = from.cat; @@ -2203,7 +2203,7 @@ namespace nana } else { - new_where.second = (y - header_visible_px() + 1) / item_size; + new_where.second = ((y + 1) - header_visible_px()) / item_size; // y>1 ! new_where.first = parts::lister; if(checkable) { @@ -3444,7 +3444,7 @@ namespace nana { auto i = ess_->lister.cat_container().begin(); std::advance(i, pos.cat); - cat_ = &(*i); + cat_ = &(*i); // what is pos is a cat? } } @@ -3489,7 +3489,7 @@ 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) { - auto & m = cat_->items.at(pos_.item); // a ref to the real item + auto & m = cat_->items.at(pos_.item); // a ref to the real item // what is pos is a cat? if(m.flags.selected == s) return *this; // ignore if no change m.flags.selected = s; // actually change selection From 7863dcdba63c82b7d60122ac8c6a58537460a618 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 5 May 2015 13:59:59 +0200 Subject: [PATCH 08/13] FIX: crash in page down and home of a listbox with categories, trying to create an item_proxy {cat, npos} and select it --- source/gui/widgets/listbox.cpp | 48 ++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 8618d4c0..176b335a 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1598,17 +1598,17 @@ namespace nana cat_proxy cpx{ess_,cat}; for (item_proxy &it : cpx ) - { + { if (it.selected() != sel) - changed = true; + changed = true; it.select(sel); - if (sel) // not check for single_selection_ + if (sel) // not check for single_selection_ last_selected_abs = it->pos(); else if (last_selected_abs == it->pos()) - last_selected_abs.set_both(npos); - } + last_selected_abs.set_both(npos); + } last_selected_abs = index_pair{cat,npos}; return changed; } @@ -1653,7 +1653,7 @@ namespace nana index_pair first_displ() const { return absolute ( first() ); - } + } bool good(size_type cat) const { @@ -1676,7 +1676,7 @@ namespace nana if (0 == pos.cat) // but for cat 0 return first item item.item = 0; // let check this is good else - return true; + return true; } auto i = _m_at(pos.cat); // pos is not a cat and i point to it cat @@ -1738,7 +1738,7 @@ namespace nana /// all arg are relative to display order, or all are absolute, but not mixed bool forward(index_pair from, size_type offs, index_pair& item) const { - if(!good_item(from, from)) + if(!good_item(from, from)) return false; if(offs == 0) @@ -1771,7 +1771,7 @@ namespace nana else { offs -= (item_left_in_this_cat+1) ; - item = from; + item = from; item.item += item_left_in_this_cat ;// select the last item } } @@ -3378,21 +3378,35 @@ namespace nana if (! scrl.make_page_scroll(!up)) return; essence_->lister.select_for_all(false); - if (up) - item_proxy {essence_, essence_->scroll_y_abs()}.select(true); - else - { - index_pair idx{essence_->scroll_y_dpl()}; + + index_pair idx{essence_->scroll_y_dpl()}; + if (!up) essence_->lister.forward(idx, scrl.range()-1, idx); - item_proxy::from_display(essence_,idx).select(true); - } + + if (idx.is_item()) + item_proxy::from_display(essence_, idx).select(true); + else + if(!essence_->lister.single_selection()) + essence_->lister.categ_selected(idx.cat, true); + + essence_->trace_last_selected_item (); + break; } case keyboard::os_home: + { essence_->lister.select_for_all(false); - item_proxy::from_display(essence_, {0,0}).select(true); + + index_pair frst{essence_->lister.first()}; + if (frst.is_item()) + item_proxy::from_display(essence_, frst).select(true); + else + if(!essence_->lister.single_selection()) + essence_->lister.categ_selected(frst.cat, true); + essence_->trace_last_selected_item (); break; + } case keyboard::os_end: essence_->lister.select_for_all(false); item_proxy::from_display(essence_, essence_->lister.last()).select(true); From 6fd15140a927e4a6a8bef4d7a1f108e9b7ab5cf0 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Tue, 5 May 2015 14:56:15 +0200 Subject: [PATCH 09/13] introduce cat_proxy::select(bool sel) --- include/nana/gui/widgets/listbox.hpp | 3 ++ source/gui/widgets/listbox.cpp | 57 ++++++++++++++++++---------- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index fc487460..0e7d76b1 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -374,6 +374,9 @@ namespace nana cat_proxy& text(nana::string); nana::string text() const; + cat_proxy & select(bool); + bool selected() const; + /// Behavior of a container void push_back(nana::string); diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 176b335a..9e63f0f6 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1592,26 +1592,7 @@ namespace nana } /// set all items in cat to selection sel, emiting events, actualizing last_selected_abs, but not check for single_selection_ - bool categ_selected(size_type cat, bool sel) - { - bool changed = false; - - cat_proxy cpx{ess_,cat}; - for (item_proxy &it : cpx ) - { - if (it.selected() != sel) - changed = true; - it.select(sel); - - if (sel) // not check for single_selection_ - last_selected_abs = it->pos(); - - else if (last_selected_abs == it->pos()) - last_selected_abs.set_both(npos); - } - last_selected_abs = index_pair{cat,npos}; - return changed; - } + bool categ_selected(size_type cat, bool sel); void reverse_categ_selected(size_type categ) { @@ -2458,7 +2439,7 @@ namespace nana } } - nana::string es_lister::to_string(const export_options& exp_opt) const + nana::string es_lister::to_string(const export_options& exp_opt) const { nana::string list_str; bool first{true}; @@ -2479,6 +2460,22 @@ namespace nana return list_str ; } + bool es_lister::categ_selected(size_type cat, bool sel) + { + bool changed = false; // we need this?? + + cat_proxy cpx{ess_,cat}; + for (item_proxy &it : cpx ) + { + if (it.selected() != sel) + changed = true; + it.select(sel); + } + + last_selected_abs = last_selected_dpl = index_pair {cat, npos}; + + return changed; // we need this?? + } class drawer_header_impl { @@ -3737,6 +3734,24 @@ namespace nana } } + cat_proxy & cat_proxy::select(bool sel) + { + for (item_proxy &it : *this ) + it.select(sel); + + ess_->lister.last_selected_abs = + ess_->lister.last_selected_dpl = index_pair {this->pos_, npos}; + + return *this; + } + bool cat_proxy::selected() const + { + for (item_proxy &it : *this ) + if (!it.selected()) + return false; + return true; + } + auto cat_proxy::columns() const -> size_type { return ess_->header.cont().size(); From df22696e25a5736559fb0e14f397a0eb8f639dac Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 7 May 2015 22:42:04 +0200 Subject: [PATCH 10/13] comments... --- include/nana/gui/widgets/listbox.hpp | 65 +++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 7 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 0e7d76b1..01fe6ae4 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -163,9 +163,9 @@ namespace nana typedef std::vector selection; - //struct essence_t - //@brief: this struct gives many data for listbox, - // the state of the struct does not effect on member funcions, therefore all data members are public. + /// struct essence_t + ///@brief: this struct gives many data for listbox, + /// the state of the struct does not effect on member funcions, therefore all data members are public. struct essence_t; struct category_t; @@ -366,7 +366,7 @@ namespace nana return iter; } - /// Append an item at abs end of the category, using the strins to set the columns (cells) of the new item. + /// Appends one item at the end of this category with the specifies text in the column fields void append(std::initializer_list); size_type columns() const; @@ -481,12 +481,63 @@ namespace nana } }//end namespace drawerbase -/*! \brief A rectangle containing a list of strings from which the user can select. This widget contain a list of \a categories, with in turn contain a list of \a items. +/*! \class listbox +\brief A rectangle containing a list of strings from which the user can select. This widget contain a list of \a categories, with in turn contain a list of \a items. A category is a text with can be \a selected, \a checked and \a expanded to show the items. An item is formed by \a column-fields, each corresponding to one of the \a headers. An item can be \a selected and \a checked. -The user can \a drag the header to \a reisize it or to \a reorganize it. -By \a clicking on a header the list get \a reordered, first up, and then down alternatively. +The user can \a drag the header to \a resize it or to \a reorganize it. +By \a clicking on one header the list get \a reordered, first up, and then down alternatively. + +1. The resolver is used to resolute an object of the specified type for a listbox item. +2. The any_objective of listbox have a 2-Dimension indexing. The first dimension is for the category, and the second one is for the item of the specified category. + int main() + { + using namespace nana::gui; + form fm; + listbox lb(fm, nana::rectangle(10, 10, 280, 120)); + lb.append_header(STR("Header"), 200); + lb.append_item(STR("int")); + lb.append_item(STR("double")); + lb.anyobj(0, 0, 10); + lb.anyobj(0, 1, 0.1); + int * pi = lb.anyobj(0, 0); // it returns a nullptr if there is not an int object specified. + double * pd = lb.anyobj(0, 1); // it returns a nullptr if there is not an double object specified. + fm.show(); + exec(); + } +3. nana::listbox creates the category 0 by default. The member functions without the categ parameter operate the items that belong to category 0. +4. A sort compare is used for sorting the items. It is a strict weak ordering comparer that must meet the requirement: + Irreflexivity (comp(x, x) returns false) + and + antisymmetry(comp(a, b) != comp(b, a) returns true) + A simple example. + bool sort_compare( const nana::string& s1, nana::any*, + const nana::string& s2, nana::any*, bool reverse) + { + return (reverse ? s1 > s2 : s1 < s2); + } + listbox.set_sort_compare(0, sort_compare); + The listbox supports attaching a customer's object for each item, therefore the items can be + sorted by comparing these customer's object. + bool sort_compare( const nana::string&, nana::any* o1, + const nana::string&, nana::any* o2, bool reverse) + { + if(o1 && o2) //some items may not attach a customer object. + { + int * i1 = o1->get(); + int * i2 = o2->get(); + return (i1 && i2 && (reverse ? *i1 > *i2 : *i1 < *i2)); + ;//some types may not be int. + } + return false; + } + listbox.anyobj(0, 0, 10); //the type of customer's object is int. + listbox.anyobj(0, 0, 20); +\todo doc: actualize this example listbox.at(0)... +\see nana::drawerbase::listbox::cat_proxy +\see nana::drawerbase::listbox::item_proxy +\example listbox_Resolver.cpp */ class listbox : public widget_object, From 444449dfaa24172b6e8f609eea96bdcdc176cf53 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 7 May 2015 22:48:20 +0200 Subject: [PATCH 11/13] let listbox append_header return the pos of the new header --- include/nana/gui/widgets/listbox.hpp | 3 ++- source/gui/widgets/listbox.cpp | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 01fe6ae4..34046a6f 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -561,9 +561,10 @@ By \a clicking on one header the list get \a reordered, first up, and then down void auto_draw(bool); ///); ///(cont_.size())); + return cont_.back().index; } void item_width(size_type pos, unsigned width) { - if (pos >= cont_.size()) - return; - for(auto & m : cont_) - { if(m.index == pos) + { m.pixels = width; + return; } } @@ -3994,11 +3993,12 @@ namespace nana _m_ess().set_auto_draw(ad); } - void listbox::append_header(nana::string text, unsigned width) + listbox::size_type listbox::append_header(nana::string text, unsigned width) { auto & ess = _m_ess(); - ess.header.create(std::move(text), width); + listbox::size_type index = ess.header.create(std::move(text), width); ess.update(); + return index; } listbox& listbox::header_width(size_type pos, unsigned pixels) From 371633f23f7fabf0dc7c263bc230d5f2787ee3c4 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Thu, 7 May 2015 22:50:26 +0200 Subject: [PATCH 12/13] listbox auto_width set the column width to fit the current longest text --- include/nana/gui/widgets/listbox.hpp | 14 ++++++++------ source/gui/widgets/listbox.cpp | 20 +++++++++++++++++++- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 34046a6f..ca4bb8ed 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -367,7 +367,7 @@ namespace nana } /// Appends one item at the end of this category with the specifies text in the column fields - void append(std::initializer_list); + void append(std::initializer_list); size_type columns() const; @@ -559,15 +559,17 @@ By \a clicking on one header the list get \a reordered, first up, and then down listbox(window, bool visible); listbox(window, const rectangle& = {}, bool visible = true); - void auto_draw(bool); ///); ///); ///< Appends categories at the end cat_proxy insert(cat_proxy, nana::string); cat_proxy at(size_type pos) const; diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 8a979678..3588576f 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -412,7 +412,7 @@ namespace nana { m.pixels = width; return; - } + } } unsigned item_width(size_type pos) const @@ -4008,6 +4008,24 @@ namespace nana ess.update(); return *this; } + unsigned listbox::auto_width(size_type pos, unsigned max) + { + unsigned max_w{0}; + auto & ess = _m_ess(); + for (const auto &cat : ess.lister.cat_container()) + for (const auto &it : cat.items ) + { + if (pos >= it.cells.size()) continue; + // precalcule text geometry + unsigned ts = static_cast ( ess.graph->text_extent_size(it.cells[pos].text).width); + if (max_w < ts) + max_w = ts; + } + if (!max_w) return 0; + header_width(pos, max_w < max ? max_w : max); + ess.update(); + return max_w; + } unsigned listbox::header_width(size_type pos) const { From e696fff7791f1dcf3f92cdaff0ae30d88f8b7bc3 Mon Sep 17 00:00:00 2001 From: qPCR4vir Date: Fri, 8 May 2015 00:31:32 +0200 Subject: [PATCH 13/13] implement double click to auto resize a column in listbox --- include/nana/gui/widgets/listbox.hpp | 19 ++--------- source/gui/widgets/listbox.cpp | 47 +++++++++++++++++++--------- 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index ca4bb8ed..87309008 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -477,6 +477,9 @@ namespace nana color_proxy header_grabbed{ static_cast(0x8BD6F6)}; color_proxy header_floated{ static_cast(0xBABBBC)}; color_proxy item_selected{ static_cast(0xD5EFFC) }; + + unsigned max_header_width{3000}, /// \todo how to implement some geometrical parameters ?? + ext_w = 5; }; } }//end namespace drawerbase @@ -490,22 +493,6 @@ The user can \a drag the header to \a resize it or to \a reorganize it. By \a clicking on one header the list get \a reordered, first up, and then down alternatively. 1. The resolver is used to resolute an object of the specified type for a listbox item. -2. The any_objective of listbox have a 2-Dimension indexing. The first dimension is for the category, and the second one is for the item of the specified category. - int main() - { - using namespace nana::gui; - form fm; - listbox lb(fm, nana::rectangle(10, 10, 280, 120)); - lb.append_header(STR("Header"), 200); - lb.append_item(STR("int")); - lb.append_item(STR("double")); - lb.anyobj(0, 0, 10); - lb.anyobj(0, 1, 0.1); - int * pi = lb.anyobj(0, 0); // it returns a nullptr if there is not an int object specified. - double * pd = lb.anyobj(0, 1); // it returns a nullptr if there is not an double object specified. - fm.show(); - exec(); - } 3. nana::listbox creates the category 0 by default. The member functions without the categ parameter operate the items that belong to category 0. 4. A sort compare is used for sorting the items. It is a strict weak ordering comparer that must meet the requirement: Irreflexivity (comp(x, x) returns false) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 3588576f..9c8eccf7 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2304,7 +2304,29 @@ namespace nana break; } } - private: + + unsigned auto_width(size_type pos, unsigned max=3000) /// \todo introduce parametr max_header_width + { + unsigned max_w{0} ; + for (const auto &cat : lister.cat_container()) + for (const auto &it : cat.items ) + { + if (pos >= it.cells.size()) continue; + // precalcule text geometry + unsigned ts = static_cast ( graph->text_extent_size(it.cells[pos].text).width); + if (max_w < ts) + max_w = ts; + } + if (!max_w) return 0; + + unsigned ext_w = scheme_ptr->ext_w ; + if( pos == 0 && checkable) // only before the first column (display_order=0 ?) + ext_w += 18; + header.item_width(pos, max_w + ext_w + 1 < max ? max_w + ext_w + 1 : max); + return max_w; + } + + private: void _m_answer_scroll(const arg_mouse& arg) { if(arg.evt_code == event_code::mouse_move && arg.left_button == false) return; @@ -2907,7 +2929,7 @@ namespace nana cell_txtcolor = m_cell.custom_format->fgcolor; } - int ext_w = 5; + int ext_w = essence_->scheme_ptr->ext_w; if(first && essence_->checkable) // draw the checkbox if need, only before the first column (display_order=0 ?) { ext_w += 18; @@ -3306,6 +3328,14 @@ namespace nana void trigger::dbl_click(graph_reference graph, const arg_mouse&) { + if (essence_->pointer_where.first == essence_t::parts::header) + if (cursor::size_we == essence_->lister.wd_ptr()->cursor()) + { + if (essence(). auto_width(drawer_header_->item_spliter() )) // ? in order + essence().update(); + return; + } + if (essence_->pointer_where.first != essence_t::parts::lister) return; @@ -4010,19 +4040,8 @@ namespace nana } unsigned listbox::auto_width(size_type pos, unsigned max) { - unsigned max_w{0}; auto & ess = _m_ess(); - for (const auto &cat : ess.lister.cat_container()) - for (const auto &it : cat.items ) - { - if (pos >= it.cells.size()) continue; - // precalcule text geometry - unsigned ts = static_cast ( ess.graph->text_extent_size(it.cells[pos].text).width); - if (max_w < ts) - max_w = ts; - } - if (!max_w) return 0; - header_width(pos, max_w < max ? max_w : max); + unsigned max_w = ess.auto_width(pos, max); ess.update(); return max_w; }