add functions to convert positions of listbox column

This commit is contained in:
Jinhao 2016-12-10 08:50:05 +08:00
parent c1cfd283e2
commit 8e10f743e1
3 changed files with 119 additions and 46 deletions

View File

@ -33,6 +33,9 @@ namespace nana
{ {
namespace listbox namespace listbox
{ {
using size_type = std::size_t;
using native_string_type = ::nana::detail::native_string_type;
/// An interface of column operations /// An interface of column operations
class column_interface class column_interface
{ {
@ -56,6 +59,22 @@ namespace nana
*/ */
virtual void width(unsigned minimum, unsigned maximum) = 0; 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 /// Sets alignment of column text
/** /**
* @param align Alignment * @param align Alignment
@ -619,8 +638,6 @@ namespace nana
std::unique_ptr<container_interface> container_ptr_; std::unique_ptr<container_interface> 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 /// usefull for both absolute and display (sorted) positions
struct index_pair struct index_pair
@ -830,10 +847,18 @@ namespace nana
size_type columns() const; size_type columns() const;
item_proxy& text(size_type col, cell); /// Converts a position of column between display position and absolute position
item_proxy& text(size_type col, std::string); /**
item_proxy& text(size_type col, const std::wstring&); * @param col The display position or absolute position.
std::string text(size_type col) const; * @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&); void icon(const nana::paint::image&);
@ -1367,18 +1392,20 @@ the nana::detail::basic_window member pointer scheme
/// Access a column at specified position /// Access a column at specified position
/** /**
* @param pos Position of column * @param pos Position of column
* @param disp_order Indicates whether the pos is display position or absolute position.
* @return Reference to the requested column * @return Reference to the requested column
* @except std::out_of_range if !(pos < columns()) * @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 /// Access a column at specified position
/** /**
* @param pos Position of column * @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 * @return Constant reference to the requested column
* @except std::out_of_range if !(pos < columns()) * @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 /// Returns the number of columns
size_type column_size() const; 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. /// Returns an index of item which contains the specified point.
index_pair cast(const point & pos) const; 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); size_type column_from_pos(const point & pos);
void checkable(bool); void checkable(bool);

View File

@ -318,6 +318,7 @@ namespace nana
data_impl_->realizer = &realizer; data_impl_->realizer = &realizer;
realizer._m_reset_overrided(); realizer._m_reset_overrided();
realizer.attached(wd, graphics); realizer.attached(wd, graphics);
realizer.typeface_changed(graphics);
} }
drawer_trigger* drawer::detached() drawer_trigger* drawer::detached()

View File

@ -122,12 +122,12 @@ namespace nana
struct column struct column
: public column_interface : public column_interface
{ {
native_string_type text; native_string_type caption;
unsigned width_px; unsigned width_px;
std::pair<unsigned, unsigned> range_width_px; std::pair<unsigned, unsigned> range_width_px;
bool visible_state{ true }; bool visible_state{ true };
/// Position of column when it was creating /// Absolute position of column when it was creating
size_type index; size_type index;
nana::align alignment{ nana::align::left }; nana::align alignment{ nana::align::left };
@ -144,7 +144,7 @@ namespace nana
{ {
if (this != &other) if (this != &other)
{ {
text = other.text; caption = other.caption;
width_px = other.width_px; width_px = other.width_px;
range_width_px = other.range_width_px; range_width_px = other.range_width_px;
visible_state = other.visible_state; visible_state = other.visible_state;
@ -157,7 +157,7 @@ namespace nana
} }
column(column&& other): column(column&& other):
text(std::move(other.text)), caption(std::move(other.caption)),
width_px(other.width_px), width_px(other.width_px),
range_width_px(other.range_width_px), range_width_px(other.range_width_px),
visible_state(other.visible_state), visible_state(other.visible_state),
@ -172,7 +172,7 @@ namespace nana
{ {
if (this != &other) if (this != &other)
{ {
text = std::move(other.text); caption = std::move(other.caption);
width_px = other.width_px; width_px = other.width_px;
range_width_px = other.range_width_px; range_width_px = other.range_width_px;
visible_state = other.visible_state; visible_state = other.visible_state;
@ -184,7 +184,7 @@ namespace nana
} }
column(essence* ess, native_string_type&& text, unsigned px, size_type pos) : column(essence* ess, native_string_type&& text, unsigned px, size_type pos) :
text(std::move(text)), caption(std::move(text)),
width_px(px), width_px(px),
index(pos), index(pos),
ess_(ess) 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 void text_align(::nana::align align) noexcept override
{ {
if (alignment != align) if (alignment != align)
@ -279,7 +292,7 @@ namespace nana
first=false; first=false;
else else
head_str += exp_opt.sep; 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; return head_str;
} }
@ -419,25 +432,47 @@ namespace nana
return cont_; return cont_;
} }
/// find and return a ref to the column that originaly was at position "pos" previous to any list reorganization. size_type cast(size_type pos, bool disp_order) const
column& at(size_type pos)
{ {
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) 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 (pos >= cont_.size())
{ throw std::out_of_range("listbox: invalid header index.");
if (m.index == pos)
return m; if (!disp_order)
} pos = this->cast(pos, false);
throw std::out_of_range("Nana.GUI.Listbox: invalid header index.");
return cont_[pos];
} }
/// Returns the position(original index when it is creating) of the current column at point x /// 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); 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<cell> model_cells; std::vector<cell> model_cells;
@ -1330,16 +1365,16 @@ namespace nana
auto & cells = (cat->model_ptr ? model_cells : *(cat->items[pos].cells)); 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); cells[abs_col] = std::move(cl);
if (sorted_index_ == col) if (sorted_index_ == abs_col)
sort(); sort();
} }
else else
{ //If the index of specified sub item is over the number of sub items that item contained, { //If the index of specified sub item is over the number of sub items that item contained,
//it fills the non-exist items. //it fills the non-exist items.
cells.resize(col); cells.resize(abs_col);
cells.emplace_back(std::move(cl)); 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<cell> model_cells; std::vector<cell> model_cells;
@ -1363,16 +1398,16 @@ namespace nana
auto & cells = (cat->model_ptr ? model_cells : *(cat->items[pos].cells)); 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); cells[abs_col].text.swap(str);
if (sorted_index_ == col) if (sorted_index_ == abs_col)
sort(); sort();
} }
else else
{ //If the index of specified sub item is over the number of sub items that item contained, { //If the index of specified sub item is over the number of sub items that item contained,
//it fills the non-exist items. //it fills the non-exist items.
cells.resize(col); cells.resize(abs_col);
cells.emplace_back(std::move(str)); cells.emplace_back(std::move(str));
} }
@ -2986,6 +3021,11 @@ namespace nana
API::refresh_window(ess_->lister.wd_ptr()->handle()); 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 void es_header::column::fit_content(unsigned maximize) noexcept
{ {
auto content_px = ess_->lister.column_content_pixels(index); auto content_px = ess_->lister.column_content_pixels(index);
@ -3529,7 +3569,7 @@ namespace nana
else if (align::center == column.alignment) else if (align::center == column.alignment)
text_margin = 0; 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()) if (column.index == essence_->lister.sort_index())
@ -4061,7 +4101,6 @@ namespace nana
essence_->listbox_ptr = static_cast<nana::listbox*>(&widget); essence_->listbox_ptr = static_cast<nana::listbox*>(&widget);
essence_->scheme_ptr = static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget)); essence_->scheme_ptr = static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget));
essence_->graph = &graph; essence_->graph = &graph;
typeface_changed(graph);
essence_->lister.bind(essence_, widget); essence_->lister.bind(essence_, widget);
widget.bgcolor(colors::white); widget.bgcolor(colors::white);
@ -4638,6 +4677,12 @@ namespace nana
return ess_->header.cont().size(); 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) item_proxy& item_proxy::text(size_type col, cell cl)
{ {
ess_->lister.text(cat_, pos_.item, col, std::move(cl), columns()); ess_->lister.text(cat_, pos_.item, col, std::move(cl), columns());
@ -5419,14 +5464,14 @@ namespace nana
return item_pos; 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 auto listbox::column_size() const ->size_type