From 9b91d3b55ff88fa3f1ddc75b34e2ace980269277 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 13 Jul 2016 23:00:03 +0800 Subject: [PATCH] listbox and place code refined --- source/gui/place.cpp | 37 +++++---------------- source/gui/widgets/listbox.cpp | 61 +++++++++++++++------------------- 2 files changed, 34 insertions(+), 64 deletions(-) diff --git a/source/gui/place.cpp b/source/gui/place.cpp index bfa0e658..a10246f9 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -503,7 +503,7 @@ namespace nana static event_handle erase_element(std::vector& elements, window handle) { - for (auto i = elements.begin(), end = elements.end(); i != end; ++i) + for (auto i = elements.begin(); i != elements.end(); ++i) { if (i->handle == handle) { @@ -515,26 +515,16 @@ namespace nana return nullptr; } private: - //The defintion is moved after the definition of class division - template - void _m_for_each(division*, Function); - //Listen to destroy of a window //It will delete the element and recollocate when the window destroyed. event_handle _m_make_destroy(window wd) { return API::events(wd).destroy.connect([this, wd](const arg_destroy&) { - for (auto i = elements.begin(), end = elements.end(); i != end; ++i) + if (erase_element(elements, wd)) { - if (i->handle == wd) - { - elements.erase(i); - - if (!API::is_destroying(API::get_parent_window(wd))) - place_ptr_->collocate(); - break; - } + if (!API::is_destroying(API::get_parent_window(wd))) + place_ptr_->collocate(); } }); } @@ -613,10 +603,7 @@ namespace nana division(kind k, std::string&& n) : kind_of_division(k), - name(std::move(n)), - field(nullptr), - div_next(nullptr), - div_owner(nullptr) + name(std::move(n)) {} virtual ~division() @@ -754,7 +741,6 @@ namespace nana //Collocate the division and its children divisions, //The window parameter is specified for the window which the place object binded. virtual void collocate(window) = 0; - public: kind kind_of_division; bool display{ true }; @@ -769,18 +755,11 @@ namespace nana place_parts::margin margin; place_parts::repeated_array gap; - field_gather * field; - division * div_next, *div_owner; + field_gather * field{ nullptr }; + division * div_next{ nullptr }; + division * div_owner{ nullptr }; };//end class division - template - void place::implement::field_gather::_m_for_each(division * div, Function fn) - { - for (auto & up : div->children) //The element of children is unique_ptr - fn(up.get()); - } - - class place::implement::div_arrange : public division { diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 332f9fce..5295a1e7 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -547,8 +547,6 @@ namespace nana }; - struct essence; - struct item_data { using container = std::vector; @@ -719,7 +717,7 @@ namespace nana if (allocate_if_empty) { - std::make_unique().swap(item.anyobj); + item.anyobj.reset(new any); return item.anyobj.get(); } } @@ -1044,8 +1042,8 @@ namespace nana { auto i = categories_.cbegin(); std::advance(i, pos.cat); - if (i->model_ptr && i->model_ptr->container()->immutable()) - throw std::runtime_error("nana::listbox disallow the operation because of immutable modal"); + + throw_if_immutable_model(i->model_ptr.get()); } } @@ -1057,8 +1055,7 @@ namespace nana std::advance(i, pos.cat); if (i->model_ptr) { - if (i->model_ptr->container()->immutable()) - throw std::runtime_error("nana::listbox disallow to modify the item because of immutable model"); + throw_if_immutable_model(i->model_ptr.get()); i->model_ptr->container()->assign(pos.item, cells); } @@ -1874,7 +1871,7 @@ namespace nana { return index_pair{ absolute(first()) }; } - + bool good(size_type cat) const { return (cat < categories_.size()); @@ -1884,6 +1881,7 @@ namespace nana { 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(index_pair pos, index_pair& item) const { @@ -1951,6 +1949,7 @@ namespace nana return npos; } + index_pair relative_pair(const index_pair& pos) const { //Returns an empty pos if item is npos @@ -2251,19 +2250,14 @@ namespace nana adjust_scroll_life(); // call adjust_scroll_value(); //adjust_scroll_value(); // again? } - void trace_item_abs( index_pair abs_pos ) - { - if( abs_pos.item == npos - && abs_pos.cat == scroll.offset_y_abs.cat - && scroll.offset_y_abs.item == npos ) // if item==off y and is a cat - return; - - trace_item_dpl( lister.relative_pair(abs_pos)) ; // ??? scroll_y_dpl_refresh() ; - } - void trace_last_selected_item( ) { - trace_item_abs(lister.last_selected_abs); + if (lister.last_selected_abs.item == npos && + lister.last_selected_abs.cat == scroll.offset_y_abs.cat && + scroll.offset_y_abs.item == npos) // if item==off y and is a cat + return; + + trace_item_dpl(lister.relative_pair(lister.last_selected_abs)); // ??? scroll_y_dpl_refresh() ; } void update() @@ -3040,7 +3034,7 @@ namespace nana { auto& cat = *get(pos.cat); - if ((pos.item != ::nana::npos) && (pos.item >= cat.items.size())) + if ((pos.item != nana::npos) && (pos.item >= cat.items.size())) throw std::invalid_argument("listbox: invalid pos to scroll"); if (!cat.expand) @@ -3069,12 +3063,12 @@ namespace nana if (categories_.back().expand) { if (categories_.back().items.empty()) - last.item = npos; + last.item = nana::npos; else last.item = categories_.back().items.size() - 1; } else - last.item = ::nana::npos; + last.item = nana::npos; backward(last, view_items, start_pos); } @@ -3204,19 +3198,18 @@ namespace nana std::vector model_cells; + auto const pcell = (cat.model_ptr ? &model_cells : nullptr); + for (auto i : cat.sorted) { auto& item = cat.items[i]; if (item.flags.selected || !exp_opt.only_selected_items) { //Test if the category have a model set. - if (cat.model_ptr) - { + if (pcell) cat.model_ptr->container()->to_cells(i).swap(model_cells); - list_str += (item.to_string(exp_opt, &model_cells) + exp_opt.endl); - } - else - list_str += (item.to_string(exp_opt, nullptr) + exp_opt.endl); + + list_str += (item.to_string(exp_opt, pcell) + exp_opt.endl); } } } @@ -3473,15 +3466,16 @@ namespace nana { const auto & col = essence_->header.at(essence_->pointer_where.second); - nana::paint::graphics ext_graph({ col.width_px, essence_->scheme_ptr->header_height }); - ext_graph.typeface(essence_->graph->typeface()); + paint::graphics fl_graph({ col.width_px, essence_->scheme_ptr->header_height }); + + fl_graph.typeface(essence_->graph->typeface()); int text_top = (essence_->scheme_ptr->header_height - essence_->scheme_ptr->text_height) / 2; - _m_draw_header_item(ext_graph, rectangle{ext_graph.size()}, text_top, colors::white, col, item_state::floated); + _m_draw_header_item(fl_graph, rectangle{ fl_graph.size()}, text_top, colors::white, col, item_state::floated); auto xpos = essence_->header.position(col.index, nullptr) + pos.x - grabs_.start_pos; - ext_graph.blend(rectangle{ ext_graph.size() }, *(essence_->graph), point{xpos - static_cast(essence_->scroll.x_offset()) + rect.x, rect.y}, 0.5); + fl_graph.blend(rectangle{ fl_graph.size() }, *(essence_->graph), point{xpos - static_cast(essence_->scroll.x_offset()) + rect.x, rect.y}, 0.5); } private: @@ -5084,9 +5078,6 @@ namespace nana API::refresh_window(ess_->listbox_ptr->handle()); } } - - //class cat_proxy - //end class cat_proxy } }//end namespace drawerbase