add new features to listbox

a method to enable/disable the number of items
methods about expanding category
methods about category icons
This commit is contained in:
Jinhao
2017-07-22 23:04:43 +08:00
parent 0cfd06b23f
commit a4f7d46eee
2 changed files with 110 additions and 17 deletions

View File

@@ -1052,6 +1052,19 @@ namespace nana
cat_proxy & select(bool);
bool selected() const;
/// Enables/disables the number of items in the category to be displayed behind the category title
cat_proxy& display_number(bool display);
/// Determines whether the category is expanded.
bool expanded() const;
/// Expands/collapses the category
/**
* @param expand Indicates whether to expand or collapse the category. If this parameter is true, it expands the category. If the parameter is false, it collapses the category.
* @return the reference of *this.
*/
cat_proxy& expanded(bool expand);
/// Behavior of a container
void push_back(std::string text_utf8);
@@ -1484,6 +1497,22 @@ the nana::detail::basic_window member pointer scheme
void enable_single(bool for_selection, bool category_limited);
void disable_single(bool for_selection);
export_options& def_export_options();
/// Sets a renderer for category icon
/**
* @param icon_renderer The renderer of category icon
* @return the reference of *this.
*/
listbox& category_icon(std::function<void(paint::graphics& graph, const rectangle& rt_icon, bool expanded)> icon_renderer);
/// Sets category icons
/**
* @param img_expanded An icon displayed in front of category title when the category is expanded.
* @param img_collapsed An icon displayed in front of category title when the category is collapsed.
* @return the reference of *this.
*/
listbox& category_icon(const paint::image& img_expanded, const paint::image&& img_collapsed);
private:
drawerbase::listbox::essence & _m_ess() const;
nana::any* _m_anyobj(size_type cat, size_type index, bool allocate_if_empty) const override;

View File

@@ -659,7 +659,8 @@ namespace nana
std::unique_ptr<model_interface> model_ptr;
bool expand{true};
bool expand{ true };
bool display_number{ true };
//A cat may have a key object to identify the category
std::shared_ptr<nana::detail::key_interface> key_ptr;
@@ -1938,6 +1939,8 @@ namespace nana
std::unique_ptr<widgets::skeletons::content_view> content_view;
std::function<void(paint::graphics&, const rectangle&, bool)> ctg_icon_renderer; ///< Renderer for the category icon
struct mouse_selection_part
{
bool started{ false };
@@ -3544,27 +3547,36 @@ namespace nana
color txt_color{ static_cast<color_rgb>(0x3399) };
facade<element::arrow> arrow("double");
arrow.direction(categ.expand ? ::nana::direction::north : ::nana::direction::south);
arrow.draw( *graph, {}, txt_color,
{ x + 5, y + static_cast<int>(item_height - 16) / 2, 16, 16 },
element_state::normal);
//Area of category icon
rectangle rt_ctg_icon{ x + 5, y + static_cast<int>(item_height - 16) / 2, 16, 16 };
if (essence_->ctg_icon_renderer)
{
essence_->ctg_icon_renderer(*graph, rt_ctg_icon, categ.expand);
}
else
{
facade<element::arrow> arrow("double");
arrow.direction(categ.expand ? ::nana::direction::south : ::nana::direction::east);
arrow.draw(*graph, {}, txt_color, rt_ctg_icon, element_state::normal);
}
graph->string({ x + 20, y + txtoff }, categ.text, txt_color);
native_string_type str = to_nstring('(' + std::to_string(categ.items.size()) + ')');
auto text_s = graph->text_extent_size(categ.text).width;
auto extend_text_w = text_s + graph->text_extent_size(str).width;
graph->string({ x + 25 + static_cast<int>(text_s), y + txtoff }, str);
if (35 + extend_text_w < width)
auto text_px = graph->text_extent_size(categ.text).width;
if (categ.display_number)
{
::nana::point pos{ x + 30 + static_cast<int>(extend_text_w), y + static_cast<int>(item_height) / 2 };
//Display the number of items in the category
native_string_type str = to_nstring('(' + std::to_string(categ.items.size()) + ')');
graph->string({ x + 25 + static_cast<int>(text_px), y + txtoff }, str);
text_px += graph->text_extent_size(str).width;
}
graph->line(pos, { x + static_cast<int>(width) - 5, pos.y },
txt_color);
if (35 + text_px < width)
{
::nana::point pos{ x + 30 + static_cast<int>(text_px), y + static_cast<int>(item_height) / 2 };
graph->line(pos, { x + static_cast<int>(width) - 5, pos.y }, txt_color);
}
//Draw selecting inner rectangle
@@ -4814,6 +4826,32 @@ namespace nana
return true;
}
cat_proxy& cat_proxy::display_number(bool display)
{
if (cat_->display_number != display)
{
cat_->display_number = display;
ess_->update();
}
return *this;
}
bool cat_proxy::expanded() const
{
return cat_->expand;
}
cat_proxy& cat_proxy::expanded(bool expand)
{
//The first category isn't allowed to be collapsed
if ((expand != cat_->expand) && pos_)
{
cat_->expand = expand;
ess_->update();
}
return *this;
}
auto cat_proxy::columns() const -> size_type
{
return ess_->header.cont().size();
@@ -5585,6 +5623,32 @@ namespace nana
return _m_ess().def_exp_options;
}
listbox& listbox::category_icon(std::function<void(paint::graphics& graph, const rectangle& rt_icon, bool expanded)> icon_renderer)
{
_m_ess().ctg_icon_renderer.swap(icon_renderer);
_m_ess().update();
return *this;
}
listbox& listbox::category_icon(const paint::image& img_expanded, const paint::image&& img_collapsed)
{
_m_ess().ctg_icon_renderer = [img_expanded, img_collapsed](paint::graphics& graph, const rectangle& rt_icon, bool expanded)
{
if (expanded)
{
img_expanded.stretch(rectangle{ img_expanded.size() }, graph, rt_icon);
}
else
{
img_collapsed.stretch(rectangle{ img_collapsed.size() }, graph, rt_icon);
}
};
_m_ess().update();
return *this;
}
drawerbase::listbox::essence & listbox::_m_ess() const
{
return get_drawer_trigger().ess();