From 1174f2f6332e9399fc261fe90e3efdfe89bd5041 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 24 Mar 2017 06:34:51 +0800 Subject: [PATCH] code refine --- source/gui/widgets/listbox.cpp | 181 +++++++----------- source/gui/widgets/skeletons/content_view.cpp | 65 +++++-- source/gui/widgets/skeletons/content_view.hpp | 20 +- 3 files changed, 130 insertions(+), 136 deletions(-) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 9feac440..4830508d 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -1229,38 +1229,71 @@ namespace nana clear(i); } - index_pair advance(const index_pair& from, size_type offset) const + index_pair advance(const index_pair& pos, int n) const { const auto cat_size = categories_.size(); index_pair dpos{ npos, npos }; - if (from.cat >= cat_size || (from.item != npos && from.item >= size_item(from.cat))) + + if (pos.cat >= cat_size || (pos.item != npos && pos.item >= size_item(pos.cat))) return dpos; - if ((0 == from.cat && npos == from.item) || (!expand(from.cat) && (npos != from.item))) + if ((0 == pos.cat && npos == pos.item) || (!expand(pos.cat) && (npos != pos.item))) return dpos; - if (0 == offset) - return from; + if (0 == n) + return pos; - dpos = from; - std::size_t pos = (npos == from.item ? 0 : 1); - - while (offset) + dpos = pos; + if (0 < n) { - std::size_t end = 1; - if (expand(dpos.cat)) - end += size_item(dpos.cat); + //Forward + std::size_t index = (npos == pos.item ? 0 : pos.item + 1); - if (offset < end - pos) + while (n) { - return index_pair{ dpos.cat, pos + offset - 1 }; - } + std::size_t end = 1; + if (expand(dpos.cat)) + end += size_item(dpos.cat); - offset -= (end - pos); - pos = 0; - ++dpos.cat; + if (n < static_cast(end - index)) + return index_pair{ dpos.cat, index + n - 1 }; + + ++dpos.cat; + if (cat_size == dpos.cat) + return index_pair{ npos, npos }; + + n -= static_cast(end - index); + index = 0; + } + return index_pair{ dpos.cat, npos }; } - return index_pair{ dpos.cat, npos }; + + //Backward + dpos = pos; + if (good(dpos.cat)) + { + auto count = static_cast(dpos.is_category() ? 1 : pos.item + 2); + auto i = get(pos.cat); + while (true) + { + if (count > n) + { + count -= n; + dpos.item = (count == 1 ? npos : count - 2); + return dpos; + } + + n -= count; + + if (i == categories_.cbegin()) + break; + + --i; + --dpos.cat; + count = static_cast(i->expand ? i->items.size() : 0) + 1; + } + } + return index_pair{npos, npos}; } /// change to index arg @@ -1494,7 +1527,7 @@ namespace nana //pair second: indicates whether the index is selected before selection. std::vector> pairs; - for (; fr_dpl != to_dpl; forward(fr_dpl, 1, fr_dpl)) + for (; fr_dpl != to_dpl; fr_dpl = advance(fr_dpl, 1)) { if (!fr_dpl.is_category()) { @@ -1846,78 +1879,6 @@ namespace nana return true; } - /// 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 noexcept - { - if (!good_item(from, from)) - return false; - - auto cat = get(from.cat); - - auto items_left = (cat->expand ? cat->items.size() : 0); - - if (from.is_category()) - items_left += 1; //add 1 category bar - else if (items_left >= from.item) - items_left -= from.item; - else - return false; //invalid argument - - while (offs) - { - if (items_left > offs) - { - item.cat = from.cat; - item.item = (npos == from.item ? offs - 1 : from.item + offs); - return true; - } - - offs -= items_left; - if (++cat == categories_.cend()) - return false; - - ++from.cat; - from.item = npos; - items_left = (cat->expand ? cat->items.size() + 1 : 1); - } - - item = from; - return true; - } - - /// all arg are relative to display order, or all are absolute, but not mixed - bool backward(index_pair from, size_type offs, index_pair& item) const noexcept - { - if(offs == 0) - item = from; - - if(good(from.cat)) - { - size_type n = (from.is_category() ? 1 : from.item + 2); - auto i = get(from.cat); - while(true) - { - if (n > offs) - { - n -= offs; - item.cat = from.cat; - item.item = (n == 1 ? npos : n - 2); - return true; - } - - offs -= n; - - if (i == categories_.cbegin()) - break; - - --i; - --from.cat; - n = (i->expand ? i->items.size() : 0) + 1; - } - } - return false; - } - /// categories iterator container::iterator get(size_type pos) { @@ -2354,9 +2315,7 @@ namespace nana graph->line({ ctt_area.right(), ctt_area.y }, { ctt_area.right(), ctt_area.bottom() - 1 }); } - auto r = this->content_view->corner(); - if (!r.empty()) - graph->rectangle(r, true, colors::button_face); + this->content_view->draw_corner(*graph); } rectangle content_area() const @@ -3391,7 +3350,9 @@ namespace nana //if where == lister || where == checker, 'second' indicates the offset to the relative display-order pos of the scroll offset_y which stands for the first item to be displayed in lister. if ((ptr_where.first == parts::list || ptr_where.first == parts::checker) && ptr_where.second != npos) - lister.forward(first_disp, ptr_where.second, hoverred_pos); + { + hoverred_pos = lister.advance(first_disp, static_cast(ptr_where.second)); + } auto subitems = essence_->header_seq(rect.width); @@ -4005,9 +3966,9 @@ namespace nana } else if(ptr_where.first == parts::list || ptr_where.first == parts::checker) { - index_pair item_pos; + index_pair item_pos = lister.advance(essence_->first_display(), static_cast(ptr_where.second)); - if ((essence_->column_from_pos(arg.pos.x) != npos) && lister.forward(essence_->first_display(), ptr_where.second, item_pos)) + if ((essence_->column_from_pos(arg.pos.x) != npos) && !item_pos.empty()) { auto * item_ptr = (item_pos.is_category() ? nullptr : &lister.at(item_pos)); @@ -4218,13 +4179,11 @@ namespace nana if (parts::list != essence_->pointer_where.first) return; - index_pair item_pos; - - auto offset_y = essence_->first_display(); - auto & lister = essence_->lister; //Get the item which the mouse is placed. - if (lister.forward(offset_y, essence_->pointer_where.second, item_pos)) + + auto item_pos = lister.advance(essence_->first_display(), static_cast(essence_->pointer_where.second)); + if (!item_pos.empty()) { if (!item_pos.is_category()) //being the npos of item.second is a category return; @@ -4239,9 +4198,8 @@ namespace nana if(false == do_expand) { - auto last = lister.last(); - size_type n = essence_->count_of_exposed(false); - if (lister.backward(last, n, last)) + auto last = lister.advance(lister.last(), -static_cast(essence_->count_of_exposed(false))); + if (!last.empty()) { auto px = lister.distance(lister.first(), last) * essence_->item_height(); essence_->content_view->change_position(static_cast(px), true, false); @@ -4299,7 +4257,7 @@ namespace nana auto idx = essence_->first_display(); if (!up) - essence_->lister.forward(idx, essence_->count_of_exposed(false) - 1, idx); + idx = essence_->lister.advance(idx, static_cast(essence_->count_of_exposed(false)) - 1); if (!idx.is_category()) item_proxy::from_display(essence_, idx).select(true); @@ -4390,7 +4348,7 @@ namespace nana if (ess_->first_display() > pos) return false; - auto last = ess_->lister.advance(ess_->first_display(), ess_->count_of_exposed(false)); + auto last = ess_->lister.advance(ess_->first_display(), static_cast(ess_->count_of_exposed(false))); return (last > pos || last == pos); } @@ -4496,7 +4454,6 @@ namespace nana return ess_->header.cont().size(); } - size_type item_proxy::column_cast(size_type pos, bool disp_order) const { return ess_->header.cast(pos, disp_order); @@ -5248,12 +5205,10 @@ namespace nana auto & ess=_m_ess(); auto _where = ess.where(pos); - index_pair item_pos{npos,npos}; - if (drawerbase::listbox::essence::parts::list == _where.first) - ess.lister.forward(ess.first_display(), _where.second, item_pos); + return ess.lister.advance(ess.first_display(), static_cast(_where.second)); - return item_pos; + return index_pair{ npos, npos }; } auto listbox::column_at(size_type pos, bool disp_order) -> column_interface& diff --git a/source/gui/widgets/skeletons/content_view.cpp b/source/gui/widgets/skeletons/content_view.cpp index c75dcac7..f3becf9a 100644 --- a/source/gui/widgets/skeletons/content_view.cpp +++ b/source/gui/widgets/skeletons/content_view.cpp @@ -89,17 +89,27 @@ namespace nana { } }); - API::events(handle).mouse_move.connect_unignorable([this](const arg_mouse& arg) + auto mouse_evt = [this](const arg_mouse& arg) { - if (!arg.is_left_button()) - return; - - if (this->drive(arg.pos)) + if (event_code::mouse_move == arg.evt_code) { - tmr.interval(16); - tmr.start(); + if (!arg.is_left_button()) + return; + + if (this->drive(arg.pos)) + { + tmr.interval(16); + tmr.start(); + } } - }); + else if (event_code::mouse_up == arg.evt_code) + { + tmr.stop(); + } + }; + + API::events(handle).mouse_move.connect_unignorable(mouse_evt); + API::events(handle).mouse_up.connect_unignorable(mouse_evt); tmr.elapse([this](const arg_elapse&) { @@ -168,10 +178,11 @@ namespace nana { else origin.x = static_cast(this->horz.value()); + if (this->events.scrolled) + this->events.scrolled(); + if (this->enable_update) - { API::refresh_window(this->window_handle); - } }; this->enable_update = try_update; @@ -182,13 +193,14 @@ namespace nana { { vert.create(window_handle); vert.events().value_changed.connect_unignorable(event_fn); + API::take_active(vert, false, window_handle); this->enable_update = false; } - + vert.move({ disp_area.x + static_cast(imd_area.width) + skew_vert.x, disp_area.y + skew_vert.y, - _m_extra_px(), + space(), imd_area.height + extra_px.height }); @@ -205,6 +217,7 @@ namespace nana { { horz.create(window_handle); horz.events().value_changed.connect_unignorable(event_fn); + API::take_active(horz, false, window_handle); this->enable_update = false; } @@ -212,7 +225,7 @@ namespace nana { disp_area.x + skew_horz.x, disp_area.y + static_cast(imd_area.height) + skew_horz.y, imd_area.width + extra_px.width, - _m_extra_px() + space() }); horz.amount(content_size.width); @@ -299,6 +312,11 @@ namespace nana { impl_->size_changed(try_update); } + const size& content_view::content_size() const + { + return impl_->content_size; + } + const point& content_view::origin() const { return impl_->origin; @@ -314,11 +332,11 @@ namespace nana { r.y = impl_->disp_area.y + static_cast(imd_area.height) + impl_->skew_horz.y; - unsigned extra_horz = (impl_->disp_area.width < impl_->content_size.width ? _m_extra_px() : 0); - unsigned extra_vert = (impl_->disp_area.height < impl_->content_size.height + extra_horz ? _m_extra_px() : 0); + unsigned extra_horz = (impl_->disp_area.width < impl_->content_size.width ? space() : 0); + unsigned extra_vert = (impl_->disp_area.height < impl_->content_size.height + extra_horz ? space() : 0); if ((0 == extra_horz) && extra_vert) - extra_horz = (impl_->disp_area.width < impl_->content_size.width + extra_vert ? _m_extra_px() : 0); + extra_horz = (impl_->disp_area.width < impl_->content_size.width + extra_vert ? space() : 0); r.width = extra_horz; r.height = extra_vert; @@ -326,13 +344,20 @@ namespace nana { return r; } + void content_view::draw_corner(graph_reference graph) + { + auto r = corner(); + if(!r.empty()) + graph.rectangle(r, true, colors::button_face); + } + rectangle content_view::view_area() const { - unsigned extra_horz = (impl_->disp_area.width < impl_->content_size.width ? _m_extra_px() : 0); - unsigned extra_vert = (impl_->disp_area.height < impl_->content_size.height + extra_horz ? _m_extra_px() : 0); + unsigned extra_horz = (impl_->disp_area.width < impl_->content_size.width ? space() : 0); + unsigned extra_vert = (impl_->disp_area.height < impl_->content_size.height + extra_horz ? space() : 0); if ((0 == extra_horz) && extra_vert) - extra_horz = (impl_->disp_area.width < impl_->content_size.width + extra_vert ? _m_extra_px() : 0); + extra_horz = (impl_->disp_area.width < impl_->content_size.width + extra_vert ? space() : 0); return rectangle{ impl_->disp_area.position(), @@ -345,7 +370,7 @@ namespace nana { unsigned content_view::extra_space(bool horz) const { - return ((horz ? impl_->horz.empty() : impl_->vert.empty()) ? 0 : _m_extra_px()); + return ((horz ? impl_->horz.empty() : impl_->vert.empty()) ? 0 : space()); } void content_view::change_position(int pos, bool aligned, bool horz) diff --git a/source/gui/widgets/skeletons/content_view.hpp b/source/gui/widgets/skeletons/content_view.hpp index 310e4535..2b96c589 100644 --- a/source/gui/widgets/skeletons/content_view.hpp +++ b/source/gui/widgets/skeletons/content_view.hpp @@ -17,6 +17,14 @@ #include #include +namespace nana +{ + namespace paint + { + class graphics; + } +} + namespace nana { namespace widgets { namespace skeletons { @@ -30,9 +38,12 @@ namespace skeletons content_view(content_view&&) = delete; content_view& operator=(content_view&&) = delete; public: + using graph_reference = paint::graphics&; + struct events_type { - std::function hover_outside; + ::std::function hover_outside; + ::std::function scrolled; }; content_view(window handle); @@ -47,8 +58,11 @@ namespace skeletons void disp_area(const rectangle& da, const point& skew_horz, const point& skew_vert, const size& extra_px, bool try_update = true); void content_size(const size& sz, bool try_update = true); + const size& content_size() const; + const point& origin() const; rectangle corner() const; + void draw_corner(graph_reference); rectangle view_area() const; @@ -63,8 +77,8 @@ namespace skeletons void pursue(const point& cursor); void set_wheel_speed(std::function fn); - private: - static constexpr unsigned _m_extra_px() + + static constexpr unsigned space() { return 16; }