diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index d334e8fd..f9acd043 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -33,6 +33,9 @@ namespace nana { namespace listbox { + using size_type = std::size_t; + using native_string_type = ::nana::detail::native_string_type; + /// An interface of column operations class column_interface { @@ -56,6 +59,22 @@ namespace nana */ virtual void width(unsigned minimum, unsigned maximum) = 0; + /// Returns the position of the column + /** + * @param disp_order Indicates whether the display position or absolute position to be returned + * @return the position of the column. + */ + virtual size_type position(bool disp_order) const noexcept = 0; + + /// Returns the caption of column + virtual std::string text() const noexcept = 0; + + /// Sets the caption of column + /** + * @param text_utf8 A UTF-8 string for the caption. + */ + virtual void text(std::string text_utf8) = 0; + /// Sets alignment of column text /** * @param align Alignment @@ -619,8 +638,6 @@ namespace nana std::unique_ptr container_ptr_; }; - using size_type = std::size_t; - using native_string_type = ::nana::detail::native_string_type; /// usefull for both absolute and display (sorted) positions struct index_pair @@ -830,10 +847,18 @@ namespace nana size_type columns() const; - item_proxy& text(size_type col, cell); - item_proxy& text(size_type col, std::string); - item_proxy& text(size_type col, const std::wstring&); - std::string text(size_type col) const; + /// Converts a position of column between display position and absolute position + /** + * @param col The display position or absolute position. + * @param disp_order Indicates whether the col is a display position or absolute position. If this parameter is true, the col is display position + * @return absolute position if disp_order is false, display position otherwise. + */ + size_type column_cast(size_type col, bool disp_order) const; + + item_proxy& text(size_type abs_col, cell); + item_proxy& text(size_type abs_col, std::string); + item_proxy& text(size_type abs_col, const std::wstring&); + std::string text(size_type abs_col) const; void icon(const nana::paint::image&); @@ -1367,18 +1392,20 @@ the nana::detail::basic_window member pointer scheme /// Access a column at specified position /** * @param pos Position of column + * @param disp_order Indicates whether the pos is display position or absolute position. * @return Reference to the requested column * @except std::out_of_range if !(pos < columns()) */ - column_interface & column_at(size_type pos); + column_interface & column_at(size_type pos, bool disp_order = false); /// Access a column at specified position /** * @param pos Position of column + * @param disp_order Indicates whether the pos is display position or absolute position. * @return Constant reference to the requested column * @except std::out_of_range if !(pos < columns()) */ - const column_interface & column_at(size_type pos) const; + const column_interface & column_at(size_type pos, bool disp_order = false) const; /// Returns the number of columns size_type column_size() const; @@ -1408,7 +1435,7 @@ the nana::detail::basic_window member pointer scheme /// Returns an index of item which contains the specified point. index_pair cast(const point & pos) const; - /// Returns the column which contains the specified point. + /// Returns the absolute position of column which contains the specified point. size_type column_from_pos(const point & pos); void checkable(bool); diff --git a/source/gui/detail/drawer.cpp b/source/gui/detail/drawer.cpp index 0c69bee3..48ded14c 100644 --- a/source/gui/detail/drawer.cpp +++ b/source/gui/detail/drawer.cpp @@ -318,6 +318,7 @@ namespace nana data_impl_->realizer = &realizer; realizer._m_reset_overrided(); realizer.attached(wd, graphics); + realizer.typeface_changed(graphics); } drawer_trigger* drawer::detached() diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index ddbaec45..596bf6be 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -122,12 +122,12 @@ namespace nana struct column : public column_interface { - native_string_type text; + native_string_type caption; unsigned width_px; std::pair range_width_px; bool visible_state{ true }; - /// Position of column when it was creating + /// Absolute position of column when it was creating size_type index; nana::align alignment{ nana::align::left }; @@ -144,7 +144,7 @@ namespace nana { if (this != &other) { - text = other.text; + caption = other.caption; width_px = other.width_px; range_width_px = other.range_width_px; visible_state = other.visible_state; @@ -157,7 +157,7 @@ namespace nana } column(column&& other): - text(std::move(other.text)), + caption(std::move(other.caption)), width_px(other.width_px), range_width_px(other.range_width_px), visible_state(other.visible_state), @@ -172,7 +172,7 @@ namespace nana { if (this != &other) { - text = std::move(other.text); + caption = std::move(other.caption); width_px = other.width_px; range_width_px = other.range_width_px; visible_state = other.visible_state; @@ -184,7 +184,7 @@ namespace nana } column(essence* ess, native_string_type&& text, unsigned px, size_type pos) : - text(std::move(text)), + caption(std::move(text)), width_px(px), index(pos), ess_(ess) @@ -232,6 +232,19 @@ namespace nana } } + size_type position(bool disp_order) const noexcept override; //The definition is provided after essence + + std::string text() const noexcept override + { + return to_utf8(caption); + } + + void text(std::string text_utf8) override + { + caption = to_nstring(std::move(text_utf8)); + _m_refresh(); + } + void text_align(::nana::align align) noexcept override { if (alignment != align) @@ -279,7 +292,7 @@ namespace nana first=false; else head_str += exp_opt.sep; - head_str += to_utf8(at(exp_opt.columns_order[idx]).text); + head_str += this->at(exp_opt.columns_order[idx]).text(); } return head_str; } @@ -419,25 +432,47 @@ namespace nana return cont_; } - /// find and return a ref to the column that originaly was at position "pos" previous to any list reorganization. - column& at(size_type pos) + size_type cast(size_type pos, bool disp_order) const { - for(auto & m : cont_) + if (pos >= cont_.size()) + throw std::out_of_range("listbox: invalid header index."); + + if (disp_order) + return cont_[pos].index; + + size_type order = 0; + for (auto & m : cont_) { if (m.index == pos) - return m; + return order; + + ++order; } - throw std::out_of_range("Nana.GUI.Listbox: invalid header index."); + + throw std::invalid_argument("listbox: invalid header index"); } - const column& at(size_type pos) const + /// find and return a ref to the column that originaly was at position "pos" previous to any list reorganization. + column& at(size_type pos, bool disp_order = false) + { + if(pos >= cont_.size()) + throw std::out_of_range("listbox: invalid header index."); + + if (!disp_order) + pos = this->cast(pos, false); + + return cont_[pos]; + } + + const column& at(size_type pos, bool disp_order = false) const { - for(const auto & m : cont_) - { - if (m.index == pos) - return m; - } - throw std::out_of_range("Nana.GUI.Listbox: invalid header index."); + if (pos >= cont_.size()) + throw std::out_of_range("listbox: invalid header index."); + + if (!disp_order) + pos = this->cast(pos, false); + + return cont_[pos]; } /// Returns the position(original index when it is creating) of the current column at point x @@ -1315,9 +1350,9 @@ namespace nana return *(cat->items.at(pos).cells); } - void text(category_t* cat, size_type pos, size_type col, cell&& cl, size_type columns) + void text(category_t* cat, size_type pos, size_type abs_col, cell&& cl, size_type columns) { - if ((col < columns) && (pos < cat->items.size())) + if ((abs_col < columns) && (pos < cat->items.size())) { std::vector model_cells; @@ -1330,16 +1365,16 @@ namespace nana auto & cells = (cat->model_ptr ? model_cells : *(cat->items[pos].cells)); - if (col < cells.size()) + if (abs_col < cells.size()) { - cells[col] = std::move(cl); - if (sorted_index_ == col) + cells[abs_col] = std::move(cl); + if (sorted_index_ == abs_col) sort(); } else { //If the index of specified sub item is over the number of sub items that item contained, //it fills the non-exist items. - cells.resize(col); + cells.resize(abs_col); cells.emplace_back(std::move(cl)); } @@ -1348,9 +1383,9 @@ namespace nana } } - void text(category_t* cat, size_type pos, size_type col, std::string&& str, size_type columns) + void text(category_t* cat, size_type pos, size_type abs_col, std::string&& str, size_type columns) { - if ((col < columns) && (pos < cat->items.size())) + if ((abs_col < columns) && (pos < cat->items.size())) { std::vector model_cells; @@ -1363,16 +1398,16 @@ namespace nana auto & cells = (cat->model_ptr ? model_cells : *(cat->items[pos].cells)); - if (col < cells.size()) + if (abs_col < cells.size()) { - cells[col].text.swap(str); - if (sorted_index_ == col) + cells[abs_col].text.swap(str); + if (sorted_index_ == abs_col) sort(); } else { //If the index of specified sub item is over the number of sub items that item contained, //it fills the non-exist items. - cells.resize(col); + cells.resize(abs_col); cells.emplace_back(std::move(str)); } @@ -2986,6 +3021,11 @@ namespace nana API::refresh_window(ess_->lister.wd_ptr()->handle()); } + size_type es_header::column::position(bool disp_order) const noexcept + { + return (disp_order ? ess_->header.cast(index, false) : index); + } + void es_header::column::fit_content(unsigned maximize) noexcept { auto content_px = ess_->lister.column_content_pixels(index); @@ -3529,7 +3569,7 @@ namespace nana else if (align::center == column.alignment) text_margin = 0; - text_aligner.draw(column.text, text_pos, column_r.width - text_margin); + text_aligner.draw(column.caption, text_pos, column_r.width - text_margin); } if (column.index == essence_->lister.sort_index()) @@ -4061,7 +4101,6 @@ namespace nana essence_->listbox_ptr = static_cast(&widget); essence_->scheme_ptr = static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget)); essence_->graph = &graph; - typeface_changed(graph); essence_->lister.bind(essence_, widget); widget.bgcolor(colors::white); @@ -4638,6 +4677,12 @@ 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); + } + item_proxy& item_proxy::text(size_type col, cell cl) { ess_->lister.text(cat_, pos_.item, col, std::move(cl), columns()); @@ -5419,14 +5464,14 @@ namespace nana return item_pos; } - auto listbox::column_at(size_type pos) -> column_interface& + auto listbox::column_at(size_type pos, bool disp_order) -> column_interface& { - return _m_ess().header.at(pos); + return _m_ess().header.at(pos, disp_order); } - auto listbox::column_at(size_type pos) const -> const column_interface& + auto listbox::column_at(size_type pos, bool disp_order) const -> const column_interface& { - return _m_ess().header.at(pos); + return _m_ess().header.at(pos, disp_order); } auto listbox::column_size() const ->size_type